├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── config.yml
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
├── renovate.json5
├── repository-social-media.png
├── storybook-django-logo.svg
├── storybook-django-screenshot.png
└── workflows
│ └── ci.yml
├── .gitignore
├── .nvmrc
├── .prettierignore
├── .prettierrc.toml
├── CHANGELOG.md
├── LICENSE
├── Procfile
├── README.md
├── demo
├── __init__.py
├── core
│ ├── jinja
│ │ └── patterns_jinja
│ │ │ └── jinja_components
│ │ │ └── quote_block
│ │ │ ├── quote_block.html
│ │ │ └── quote_block.yaml
│ ├── templates
│ │ └── patterns
│ │ │ ├── base.html
│ │ │ ├── components
│ │ │ ├── InfoBox
│ │ │ │ ├── InfoBox.scss
│ │ │ │ ├── InfoBox.stories.js
│ │ │ │ └── InfoBox.tsx
│ │ │ ├── LoadingIndicator
│ │ │ │ ├── LoadingIndicator.scss
│ │ │ │ ├── LoadingIndicator.stories.js
│ │ │ │ └── LoadingIndicator.tsx
│ │ │ ├── accordion
│ │ │ │ ├── accordion.html
│ │ │ │ ├── accordion.js
│ │ │ │ ├── accordion.scss
│ │ │ │ ├── accordion.stories.tsx
│ │ │ │ ├── accordion.test.ts
│ │ │ │ ├── accordion.yaml
│ │ │ │ ├── accordion_section.html
│ │ │ │ └── accordion_section.yaml
│ │ │ ├── banner
│ │ │ │ ├── home_banner.html
│ │ │ │ ├── home_banner.stories.tsx
│ │ │ │ ├── home_banner.yaml
│ │ │ │ ├── split_banner.html
│ │ │ │ ├── split_banner.scss
│ │ │ │ ├── split_banner.stories.js
│ │ │ │ └── split_banner.yaml
│ │ │ ├── button
│ │ │ │ ├── Button.stories.js
│ │ │ │ ├── Button.tsx
│ │ │ │ ├── button.html
│ │ │ │ ├── button.scss
│ │ │ │ └── button.yaml
│ │ │ ├── cta
│ │ │ │ ├── call_to_action.html
│ │ │ │ ├── call_to_action.scss
│ │ │ │ ├── call_to_action.yaml
│ │ │ │ ├── cta_section.html
│ │ │ │ ├── cta_section.scss
│ │ │ │ └── cta_section.yaml
│ │ │ ├── customers
│ │ │ │ ├── customer-detail.html
│ │ │ │ ├── customer-detail.scss
│ │ │ │ ├── customer-detail.yaml
│ │ │ │ ├── customers-header.html
│ │ │ │ ├── customers-header.scss
│ │ │ │ ├── customers-header.stories.js
│ │ │ │ ├── customers-table.html
│ │ │ │ ├── customers-table.scss
│ │ │ │ ├── customers-table.stories.js
│ │ │ │ └── customers-table.yaml
│ │ │ ├── icon
│ │ │ │ ├── Icon.stories.js
│ │ │ │ ├── Icon.test.js
│ │ │ │ ├── Icon.tsx
│ │ │ │ ├── icon.html
│ │ │ │ └── icon.scss
│ │ │ ├── pagination
│ │ │ │ ├── next_stage_link.html
│ │ │ │ ├── next_stage_link.scss
│ │ │ │ ├── next_stage_link.yaml
│ │ │ │ ├── pagination.html
│ │ │ │ └── pagination.yaml
│ │ │ └── streamfield
│ │ │ │ ├── call_to_action_block.html
│ │ │ │ ├── call_to_action_block.yaml
│ │ │ │ ├── casestudy_teaser_block.html
│ │ │ │ ├── casestudy_teaser_block.scss
│ │ │ │ ├── casestudy_teaser_block.yaml
│ │ │ │ ├── heading_block.html
│ │ │ │ ├── heading_block.stories.js
│ │ │ │ ├── heading_block.yaml
│ │ │ │ ├── pop
│ │ │ │ ├── related_link.html
│ │ │ │ ├── related_link.yaml
│ │ │ │ ├── related_links.html
│ │ │ │ └── related_links.yaml
│ │ │ │ ├── quote_block.html
│ │ │ │ ├── quote_block.md
│ │ │ │ ├── quote_block.scss
│ │ │ │ ├── quote_block.stories.js
│ │ │ │ └── quote_block.yaml
│ │ │ └── sprites
│ │ │ └── sprites.html
│ └── templatetags
│ │ ├── wagtailcore_tags.py
│ │ └── wagtailimages_tags.py
├── jinja2.py
├── public
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon.png
│ ├── favicon.ico
│ ├── safari-pinned-tab.svg
│ └── site.webmanifest
├── settings.py
├── static_src
│ ├── main.js
│ ├── main.scss
│ ├── sass
│ │ ├── abstracts
│ │ │ ├── _functions.scss
│ │ │ ├── _mixins.scss
│ │ │ └── _variables.scss
│ │ ├── base
│ │ │ ├── _base.scss
│ │ │ ├── _section.scss
│ │ │ ├── _typography.scss
│ │ │ └── _wrapper.scss
│ │ ├── utilities
│ │ │ └── _utilities.scss
│ │ └── vendor
│ │ │ └── _normalize.scss
│ └── tests
│ │ ├── __image_snapshots__
│ │ └── .gitignore
│ │ ├── __snapshots__
│ │ └── storyshots-snapshot.test.js.snap
│ │ ├── assetMock.js
│ │ ├── environment.js
│ │ ├── setupTests.js
│ │ ├── storyshots-axe.test.js
│ │ ├── storyshots-image-snapshot.test.js
│ │ └── storyshots-snapshot.test.js
├── storybook
│ ├── Welcome.stories.mdx
│ ├── __init__.py
│ ├── main.js
│ ├── manager.js
│ ├── middleware.js
│ ├── preview-head.html
│ ├── preview.js
│ ├── stories.d.ts
│ ├── theme.js
│ ├── urls.py
│ └── yaml.stories.js
├── urls.py
└── wsgi.py
├── docs
├── CODE_OF_CONDUCT.md
└── CONTRIBUTING.md
├── jest.config.js
├── manage.py
├── package-lock.json
├── package.json
├── requirements.txt
├── src
├── middleware.js
├── react.js
└── storybook-django.js
├── tests
└── storybook-django.test.js
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
10 | [*.md]
11 | trim_trailing_whitespace = false
12 |
13 | [*.{js,ts,tsx,json,yml,yaml,md,css,scss}]
14 | indent_size = 2
15 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | static_compiled
4 | storybook_compiled
5 | venv
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // See https://github.com/torchbox/eslint-config-torchbox for rules.
3 | extends: ['torchbox/typescript', 'plugin:react/jsx-runtime'],
4 | rules: {
5 | 'import/no-extraneous-dependencies': [
6 | 2,
7 | {
8 | devDependencies: true,
9 | optionalDependencies: false,
10 | },
11 | ],
12 | },
13 | overrides: [
14 | {
15 | files: ['*.stories.*', 'storybook'],
16 | rules: {
17 | 'react/jsx-props-no-spreading': 'off',
18 | },
19 | },
20 | ],
21 | };
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: '🐞 Bug report'
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 | ---
8 |
9 |
18 |
19 | ### Describe the bug
20 |
21 | (Write your answer here.)
22 |
23 | ### Which terms did you search for in the documentation and issue tracker?
24 |
25 |
31 |
32 | (Write your answer here if relevant.)
33 |
34 | ### Environment
35 |
36 |
40 |
41 | (Write your answer here if relevant.)
42 |
43 | ### Steps to reproduce
44 |
45 |
49 |
50 | (Write your steps here:)
51 |
52 | 1. First,
53 | 2. Then,
54 | 3. Finally,
55 |
56 | ### Expected behavior
57 |
58 |
63 |
64 | (Write what you thought would happen.)
65 |
66 | ### Actual behavior
67 |
68 |
73 |
74 | (Write what happened. Please add screenshots!)
75 |
76 | ### Reproducible demo
77 |
78 |
92 |
93 | (Paste the link to an example project and exact instructions to reproduce the issue.)
94 |
95 |
107 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | contact_links:
2 | - name: '❓ Questions'
3 | url: https://github.com/torchbox/storybook-django/discussions
4 | about: Use GitHub Discussions to get help with this project.
5 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: '🚀 Feature request'
3 | about: Suggest an idea for improving this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 | ---
8 |
9 | ### Is your proposal related to a problem?
10 |
11 |
15 |
16 | (Write your answer here.)
17 |
18 | ### Describe the solution you’d like
19 |
20 |
23 |
24 | (Describe your proposed solution here.)
25 |
26 | ### Describe alternatives you’ve considered
27 |
28 |
31 |
32 | (Write your answer here.)
33 |
34 | ### Additional context
35 |
36 |
40 |
41 | (Write your answer here.)
42 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Here, please add a description of your pull request and instructions for the reviewer to verify your work. Pull requests without an adequate description will not be reviewed until one is added.
4 |
5 |
6 |
7 | ---
8 |
9 |
10 |
11 | - [ ] Stay on point and keep it small so it can be easily reviewed. For example, try to apply any general refactoring separately outside of the PR.
12 | - [ ] Consider adding unit tests, especially for bug fixes. If you don't, tell us why.
13 | - [ ] All new and existing tests pass.
14 | - [ ] Linting passes.
15 | - [ ] Consider updating documentation. If you don't, tell us why.
16 | - [ ] List the environments / platforms in which you tested your changes.
17 |
--------------------------------------------------------------------------------
/.github/renovate.json5:
--------------------------------------------------------------------------------
1 | {
2 | extends: ['config:base'],
3 | // https://renovatebot.com/docs/configuration-options/#commitbodytable
4 | commitBodyTable: true,
5 | // https://renovatebot.com/docs/configuration-options/#ignoredeps
6 | ignoreDeps: [],
7 | // https://renovatebot.com/docs/configuration-options/#labels
8 | labels: ['enhancement'],
9 | // https://renovatebot.com/docs/configuration-options/#prcreation
10 | prCreation: 'not-pending',
11 | // https://renovatebot.com/docs/configuration-options/#semanticcommits
12 | semanticCommits: false,
13 | // Use shorter commit messages to account for long dependency names.
14 | // https://docs.renovatebot.com/configuration-options/#commitmessagetopic
15 | commitMessageTopic: '{{depName}}',
16 | // https://renovatebot.com/docs/configuration-options/#prbodydefinitions
17 | prBodyDefinitions: {},
18 | // https://renovatebot.com/docs/configuration-options/#prbodycolumns
19 | prBodyColumns: ['Package', 'Update', 'Type', 'Change'],
20 | // https://renovatebot.com/docs/configuration-options/#rebasestaleprs
21 | rebaseStalePrs: true,
22 | // https://renovatebot.com/docs/configuration-options/#schedule
23 | schedule: ['every weekend'],
24 | node: {
25 | major: {
26 | enabled: true,
27 | },
28 | // https://renovatebot.com/docs/node/#configuring-support-policy
29 | supportPolicy: ['current'],
30 | },
31 | packageRules: [
32 | {
33 | packageNames: ['prettier'],
34 | groupName: 'prettier',
35 | automerge: true,
36 | },
37 | ],
38 | }
39 |
--------------------------------------------------------------------------------
/.github/repository-social-media.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/storybook-django/0b9314eb9711cbb782b4682e6d7fb5fe73e8cc62/.github/repository-social-media.png
--------------------------------------------------------------------------------
/.github/storybook-django-logo.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/.github/storybook-django-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/torchbox/storybook-django/0b9314eb9711cbb782b4682e6d7fb5fe73e8cc62/.github/storybook-django-screenshot.png
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - 'renovate/**'
8 | pull_request:
9 |
10 | jobs:
11 | test_python:
12 | runs-on: ubuntu-latest
13 | env:
14 | DJANGO_SETTINGS_MODULE: demo.settings
15 | steps:
16 | - uses: actions/checkout@v3
17 | - uses: actions/setup-python@v2
18 | with:
19 | python-version: '3.10'
20 | - id: pip-cache
21 | uses: actions/cache@v2
22 | with:
23 | path: .venv
24 | key: ${{ runner.os }}-pip-v2-${{ hashFiles('**/runtime.txt') }}-${{ hashFiles('**/requirements.txt') }}
25 | - if: steps.pip-cache.outputs.cache-hit != 'true'
26 | run: python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
27 | - run: source .venv/bin/activate && flake8 demo
28 | - run: source .venv/bin/activate && black demo --check
29 | - run: source .venv/bin/activate && python manage.py check
30 | - run: source .venv/bin/activate && python manage.py render_patterns
31 | test_node:
32 | runs-on: ubuntu-latest
33 | steps:
34 | - uses: actions/checkout@v3
35 | - uses: actions/setup-node@v3
36 | with:
37 | node-version-file: '.nvmrc'
38 | - id: node-cache
39 | uses: actions/cache@v2
40 | with:
41 | path: node_modules
42 | key: ${{ runner.os }}-node-${{ hashFiles('**/.nvmrc') }}-${{ hashFiles('**/package-lock.json') }}
43 | - if: steps.node-cache.outputs.cache-hit != 'true'
44 | run: npm ci --no-audit
45 | - run: npm run lint:js
46 | - run: npm run lint:format
47 | - run: npm run build
48 | - uses: actions/upload-artifact@v3
49 | with:
50 | name: storybook_compiled
51 | path: demo/storybook_compiled
52 | retention-days: 1
53 | test_storyshots:
54 | runs-on: ubuntu-latest
55 | needs: [test_python, test_node]
56 | steps:
57 | - uses: actions/checkout@v3
58 | - uses: actions/setup-node@v3
59 | with:
60 | node-version-file: '.nvmrc'
61 | - uses: actions/setup-python@v2
62 | with:
63 | python-version: '3.10'
64 | - id: node-cache
65 | uses: actions/cache@v2
66 | with:
67 | path: node_modules
68 | key: ${{ runner.os }}-node-${{ hashFiles('**/.nvmrc') }}-${{ hashFiles('**/package-lock.json') }}
69 | - id: pip-cache
70 | uses: actions/cache@v2
71 | with:
72 | path: .venv
73 | key: ${{ runner.os }}-pip-v2-${{ hashFiles('**/runtime.txt') }}-${{ hashFiles('**/requirements.txt') }}
74 | - uses: actions/download-artifact@v3
75 | with:
76 | name: storybook_compiled
77 | path: demo/storybook_compiled
78 | - run: source .venv/bin/activate && python manage.py runserver 0:8001 &
79 | - run: npm run test
80 | - uses: actions/upload-artifact@v3
81 | with:
82 | name: image_snapshots
83 | path: demo/static_src/tests/__image_snapshots__
84 | retention-days: 30
85 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # -------------------------------------------------
4 | # OS files
5 | # -------------------------------------------------
6 | .DS_Store
7 | .DS_Store?
8 | ._*
9 | .Spotlight-V100
10 | .Trashes
11 | ehthumbs.db
12 | Thumbs.db
13 |
14 | # -------------------------------------------------
15 | # Logs and databases
16 | # -------------------------------------------------
17 | logs
18 | *.log
19 | npm-debug.log*
20 | *.sql
21 | *.sqlite3
22 |
23 | # -------------------------------------------------
24 | # Runtime data and caches
25 | # -------------------------------------------------
26 | pids
27 | *.pid
28 | *.seed
29 | *.pyc
30 | *.pyo
31 | *.pot
32 |
33 | # -------------------------------------------------
34 | # Instrumentation and tooling
35 | # -------------------------------------------------
36 | lib-cov
37 | coverage
38 | .coverage
39 | coverage_html_report
40 | .grunt
41 | .bundle
42 | webpack-stats.json
43 | webpack-stats.html
44 |
45 | # -------------------------------------------------
46 | # Dependency directories
47 | # -------------------------------------------------
48 | node_modules*
49 | python_modules*
50 | bower_components
51 | .venv
52 | venv
53 | .tox
54 | $virtualenv.tar.gz
55 | $node_modules.tar.gz
56 |
57 | # -------------------------------------------------
58 | # Users Environment
59 | # -------------------------------------------------
60 | .lock-wscript
61 | .idea
62 | .installed.cfg
63 | .vagrant
64 | .anaconda
65 | Vagrantfile.local
66 | .env
67 | /local
68 | local.py
69 | *.sublime-project
70 | *.sublime-workspace
71 | .vscode
72 |
73 | # -------------------------------------------------
74 | # Generated files
75 | # -------------------------------------------------
76 | dist
77 | build
78 | /var/static/
79 | /var/media/
80 | /docs/_build/
81 | develop-eggs
82 | *.egg-info
83 | downloads
84 | media
85 | eggs
86 | parts
87 | lib64
88 | .sass-cache
89 | .mypy_cache
90 |
91 | # -------------------------------------------------
92 | # Your own project's ignores
93 | # -------------------------------------------------
94 | storybook_compiled
95 | static_compiled
96 | dpl-rendered-patterns
97 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 22
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | static_compiled
2 | storybook_compiled
3 | *.html
4 | coverage
5 | venv
6 | .venv
7 | backstop_data
8 |
--------------------------------------------------------------------------------
/.prettierrc.toml:
--------------------------------------------------------------------------------
1 | # See https://prettier.io/docs/en/options.html.
2 | # Prettier also reads .editorconfig.
3 | printWidth = 80
4 | singleQuote = true
5 | quoteProps = 'consistent'
6 | trailingComma = 'all'
7 | arrowParens = 'always'
8 | proseWrap = 'preserve'
9 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | > All notable changes to this project are documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4 |
5 | ## Unreleased
6 |
7 | ### Changed
8 |
9 | - Upgrade to http-proxy-middleware v3
10 |
11 | ## [[v1.0.0]](https://github.com/torchbox/storybook-django/releases/tag/v1.0.0) (2024-07-27)
12 |
13 | ### Added
14 |
15 | - Pattern library API requests done with the `fetch` API now [include credentials](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#including_credentials) for same-origin requests. Thank you to [@jkevingutierrez](https://github.com/jkevingutierrez) ([#12](https://github.com/torchbox/storybook-django/pull/12)).
16 |
17 | ## [[v0.5.1]](https://github.com/torchbox/storybook-django/releases/tag/v0.5.1) (2022-04-06)
18 |
19 | ### Fixed
20 |
21 | - Fix comment expansion being too greedy
22 |
23 | ## [[v0.5.0]](https://github.com/torchbox/storybook-django/releases/tag/v0.5.0) (2022-04-06)
24 |
25 | ### Fixed
26 |
27 | - Change path imports for middleware and React code rather than using Node `exports` mapping.
28 |
29 | ### Added
30 |
31 | - Add JSDoc-based TypeScript typing for the public API.
32 | - Add a `data-testid="storybook-django"` attribute to facilitate automated testing.
33 | - Add a `data-state="empty|loading|loaded"` attribute to run code once templates are loaded.
34 | - Add a `data-template="path/to/template/component.html"` attribute to simplify troubleshooting.
35 |
36 | ## [[v0.4.1]](https://github.com/torchbox/storybook-django/releases/tag/v0.4.1) (2022-04-05)
37 |
38 | ### Fixed
39 |
40 | - Use Node [exports](https://nodejs.org/api/packages.html#subpath-exports) to export correct paths in published package.
41 |
42 | ## [[v0.4.0]](https://github.com/torchbox/storybook-django/releases/tag/v0.4.0) (2022-04-05)
43 |
44 | ### Added
45 |
46 | - Documentation for project basic setup and usage, and optional Webpack integrations.
47 | - Documentation for advanced usage: TypeScript, Storyshots.
48 | - Add new optional React API as `storybook-django/src/react` module.
49 | - Document expected usage with Vue (WIP).
50 | - Add experimental documentation generation capabilities.
51 |
52 | ### Fixed
53 |
54 | - Fix API client forcing tags to explicit null
55 |
56 | ## [[v0.3.0]](https://github.com/torchbox/storybook-django/releases/tag/v0.3.0) (2022-02-16)
57 |
58 | ### Changed
59 |
60 | - Move `http-proxy-middleware` to be a dependency of this package.
61 | - Change public API to be completely framework-agnostic.
62 |
63 | ## [[v0.2.0]](https://github.com/torchbox/storybook-django/releases/tag/v0.2.0) (2020-03-12)
64 |
65 | ### Added
66 |
67 | - Add basic error handling for TemplatePattern
68 | - Support defining pattern library API path globally instead of per-component
69 | - Add simpler stories definition API
70 |
71 | ### Changed
72 |
73 | - Rewrite library code to be consumable without a React compilation step
74 |
75 | ## [[v0.1.0]](https://github.com/torchbox/storybook-django/releases/tag/v0.1.0) (2020-02-21)
76 |
77 | First (barely) usable release!
78 |
79 | ---
80 |
81 | Template from http://keepachangelog.com/
82 |
83 | ## [[vx.y.z]](https://github.com/torchbox/storybook-django/releases/tag/vx.y.z)
84 |
85 | ### Added
86 |
87 | - Something was added to the API / a new feature was introduced.
88 |
89 | ### Changed
90 |
91 | ### Fixed
92 |
93 | ### Removed
94 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2020-current Torchbox Ltd
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: gunicorn demo.wsgi
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Storybook for Django
2 |
3 | [](https://www.npmjs.com/package/storybook-django) [](https://github.com/torchbox/storybook-django/actions)
4 |
5 | Storybook for Django is an experimental UI development environment for Django components. It allows you to implement, document, and test UI components in isolation from your Django views.
6 |
7 | 
8 |
9 | ## How it works
10 |
11 | Server-side, this uses [django-pattern-library](https://github.com/torchbox/django-pattern-library) to mock template context and template tags. Client-side, we use [Storybook](https://storybook.js.org/) to create stories from our templates.
12 |
13 | ## Getting started
14 |
15 | Let’s get you set up. There are two requirements:
16 |
17 | 1. First, start by setting up [django-pattern-library](https://github.com/torchbox/django-pattern-library), v0.7.0 and up. Have a look at our [demo settings.py](https://github.com/torchbox/storybook-django/blob/main/demo/settings.py) as an example.
18 | 2. Then, set up [Storybook](https://storybook.js.org/). We expect `storybook-django` to work with any framework supported by Storybook, and provide built-in support for React (Vue in progress).
19 |
20 | Next, install our package:
21 |
22 | ```sh
23 | npm install --save-dev storybook-django
24 | ```
25 |
26 | ### Middleware
27 |
28 | Add a `middleware.js` inside your Storybook configuration folder (`.storybook` by default):
29 |
30 | ```js
31 | const {
32 | createDjangoAPIMiddleware,
33 | } = require('storybook-django/src/middleware');
34 |
35 | module.exports = createDjangoAPIMiddleware({
36 | // Point this at your Django runserver instance, with the correct port number.
37 | origin: 'http://localhost:8001',
38 | apiPath: ['/pattern-library/'],
39 | });
40 | ```
41 |
42 | This will forward pattern library API requests to Django. You may optionally add more API path patterns to `apiPath` to make other requests to your Django backend.
43 |
44 | ### Optional Webpack configuration
45 |
46 | This is optional but highly recommended. To leverage Storybook’s live-reloading and documentation capabilities, we need to configure it to load our templates. Edit your Storybook `main.js` file to customise the `webpackFinal` option:
47 |
48 | ```js
49 | module.exports = {
50 | webpackFinal: (config) => {
51 | config.module.rules = config.module.rules.concat([
52 | {
53 | test: /\.html$/,
54 | // Webpack 5:
55 | type: 'asset/source',
56 | // Webpack 4 (make sure to also install the raw-loader package):
57 | // use: 'raw-loader',
58 | },
59 | ]);
60 |
61 | return config;
62 | }
63 | ```
64 |
65 | ### React usage
66 |
67 | Here is the most basic story for a Django template:
68 |
69 | ```js
70 | import { Pattern } from 'storybook-django/src/react';
71 |
72 | export default {};
73 |
74 | export const Base = () => (
75 |
79 | );
80 | ```
81 |
82 | `Pattern` uses a hard-coded `endpoint` of `/pattern-library/api/v1/render-pattern` by default. To change this, pass a different value. For example,
83 |
84 | ```js
85 |
86 | ```
87 |
88 | If this is a necessity for your project, consider creating your own wrapper for the `Pattern` component rather than having to define the `endpoint` in all stories.
89 |
90 | #### With auto-generated template paths
91 |
92 | Our `Pattern` component has to be told which `template` to render, Alternatively, we can use [Webpack’s `__filename`](https://webpack.js.org/api/module-variables/#__filename-nodejs) support to auto-generate the template path. First, configure Webpack:
93 |
94 | ```js
95 | config.node = {
96 | __filename: true,
97 | };
98 | ```
99 |
100 | Then, use the `filename` prop instead of `template`:
101 |
102 | ```js
103 |
104 | ```
105 |
106 | This `filename` prop assumes the template is in the same folder as the template, with the same file name except for the extension (replaces `.stories.(js|tsx)` with `.html`).
107 |
108 | #### With Storybook features
109 |
110 | And here is a more advanced examples, showcasing different Storybook features:
111 |
112 | - Setting a custom title for the story.
113 | - Loading Markdown files to use as documentation.
114 | - Loading the component’s template to display alongside the docs, and for live-reloading.
115 | - Setting up [controls](https://storybook.js.org/docs/react/essentials/controls).
116 | - Having multiple stories with different data.
117 |
118 | ```js
119 | import { Pattern } from 'storybook-django/src/react';
120 |
121 | import docs from './quote_block.md';
122 | import template from './quote_block.html';
123 |
124 | export default {
125 | title: 'Components / quote_block',
126 | parameters: {
127 | docs: {
128 | source: { code: template },
129 | extractComponentDescription: () => docs,
130 | },
131 | },
132 | argTypes: {
133 | quote: {
134 | control: { type: 'text' },
135 | description: 'Will be displayed first',
136 | },
137 | attribution: {
138 | control: { type: 'text' },
139 | description: 'Underneath the quote (optional)',
140 | },
141 | },
142 | };
143 |
144 | export const Base = (args) => (
145 |
146 | );
147 |
148 | Base.args = {
149 | quote: 'Someone believed in me once and now it’s time for me to do the same.',
150 | attribution: 'Young person',
151 | };
152 |
153 | export const NoAttribution = Base.bind({});
154 |
155 | NoAttribution.args = {
156 | quote: Base.args.quote,
157 | attribution: null,
158 | };
159 | ```
160 |
161 | #### Making the most of React
162 |
163 | The point of using React is to be able to fully customise the context within which our Django components are displayed. Here is an example, with a simple SVG icon template:
164 |
165 | ```js
166 | const IconPattern = (props) => (
167 |
172 | );
173 |
174 | export const ReactDemoStory = () => (
175 |
176 |
177 | View our complete guide
178 |
179 |
180 | );
181 | ```
182 |
183 | ### Vue usage
184 |
185 | We are working on Vue support. Please refer to [Usage with Vue #7](https://github.com/torchbox/storybook-django/issues/7) in the meantime, and provide feedback.
186 |
187 | ### Usage with other frameworks
188 |
189 | storybook-django’s implementation is largely framework-agnostic, and should work equally as well with Storybook’s HTML and Web Components support.
190 |
191 | You will need to directly import the imperative APIs:
192 |
193 | ```js
194 | import {
195 | renderPattern,
196 | simulateLoading,
197 | insertHTMLWithScripts,
198 | } from 'storybook-django';
199 | ```
200 |
201 | - `renderPattern` calls the django-pattern-library API rendering endpoint.
202 | - `simulateLoading` includes `insertHTMLWithScripts`, and fires a `DOMContentLoaded` event.
203 | - `insertHTMLWithScripts` is like `.innerHTML`, but additionally executing any `
32 |