django-brickwork 1.0.0rc1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_brickwork-1.0.0rc1/LICENSE +21 -0
- django_brickwork-1.0.0rc1/NOTICE +62 -0
- django_brickwork-1.0.0rc1/PKG-INFO +193 -0
- django_brickwork-1.0.0rc1/README.md +157 -0
- django_brickwork-1.0.0rc1/pyproject.toml +128 -0
- django_brickwork-1.0.0rc1/setup.cfg +4 -0
- django_brickwork-1.0.0rc1/src/brickwork/__init__.py +20 -0
- django_brickwork-1.0.0rc1/src/brickwork/apps.py +25 -0
- django_brickwork-1.0.0rc1/src/brickwork/conf.py +65 -0
- django_brickwork-1.0.0rc1/src/brickwork/context_processors.py +66 -0
- django_brickwork-1.0.0rc1/src/brickwork/exceptions.py +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/__init__.py +52 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/registry.py +176 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/arrow-down.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/arrow-up-down.svg +18 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/arrow-up.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/bell.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/calendar.svg +18 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/check.svg +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/chevron-down.svg +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/chevron-left.svg +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/chevron-right.svg +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/chevron-up.svg +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/circle-alert.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/circle-check.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/circle-help.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/circle-x.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/copy.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/download.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/ellipsis-vertical.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/ellipsis.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/external-link.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/eye-off.svg +18 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/eye.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/file-text.svg +19 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/filter.svg +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/folder.svg +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/home.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/info.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/loader-circle.svg +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/lock.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/log-in.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/log-out.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/menu.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/minus.svg +15 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/panel-left.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/pencil.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/plus.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/save.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/search.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/settings.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/square-pen.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/trash-2.svg +19 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/triangle-alert.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/upload.svg +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/user.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/users.svg +18 -0
- django_brickwork-1.0.0rc1/src/brickwork/icons/vendor/lucide/x.svg +16 -0
- django_brickwork-1.0.0rc1/src/brickwork/models.py +156 -0
- django_brickwork-1.0.0rc1/src/brickwork/py.typed +0 -0
- django_brickwork-1.0.0rc1/src/brickwork/services/__init__.py +6 -0
- django_brickwork-1.0.0rc1/src/brickwork/services/brand_css.py +195 -0
- django_brickwork-1.0.0rc1/src/brickwork/services/forms.py +61 -0
- django_brickwork-1.0.0rc1/src/brickwork/services/navigation.py +169 -0
- django_brickwork-1.0.0rc1/src/brickwork/services/token_manifest.py +79 -0
- django_brickwork-1.0.0rc1/src/brickwork/services/tokens.py +99 -0
- django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/brickwork.css +1 -0
- django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/brickwork.js +1 -0
- django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/tailwind-theme.css +95 -0
- django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/token-manifest.json +301 -0
- django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/tokens.css +507 -0
- django_brickwork-1.0.0rc1/src/brickwork/static/brickwork/dist/tokens.js +304 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_account_menu.html +44 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_alert.html +34 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_badge.html +26 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_breadcrumbs.html +30 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_bulk_actions_bar.html +71 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_button.html +25 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_card.html +57 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_combobox.html +182 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_data_table.html +196 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_disclosure.html +47 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_dropdown.html +61 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_dropzone.html +53 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_empty_state.html +26 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_filter_bar.html +44 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_modal.html +133 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_page_header.html +19 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_pagination.html +46 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_progress.html +54 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_skeleton.html +29 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_slide_over.html +150 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_spinner.html +10 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_stat.html +66 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_stepper.html +71 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_tabs.html +98 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_tag_input.html +78 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_toast.html +59 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_toast_region.html +47 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_toggle.html +40 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/components/_tooltip.html +62 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/forms/_field.html +41 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/forms/_form.html +71 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/forms/_form_errors.html +19 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/nav/_nav.html +54 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/_table_card.html +12 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/dashboard.html +39 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/detail.html +39 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/list.html +50 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/patterns/wizard.html +73 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/shell/app.html +129 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/shell/auth.html +23 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/shell/base.html +72 -0
- django_brickwork-1.0.0rc1/src/brickwork/templates/brickwork/shell/centred.html +17 -0
- django_brickwork-1.0.0rc1/src/brickwork/templatetags/__init__.py +1 -0
- django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_components.py +168 -0
- django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_forms.py +222 -0
- django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_icons.py +109 -0
- django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_interactions.py +487 -0
- django_brickwork-1.0.0rc1/src/brickwork/templatetags/brickwork_nav.py +138 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/__init__.py +21 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/source/component.tokens.json +226 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/source/density.comfortable.tokens.json +39 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/source/density.compact.tokens.json +39 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/source/density.spacious.tokens.json +39 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/source/motion.tokens.json +39 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/source/primitive.tokens.json +120 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/source/semantic.dark.tokens.json +453 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/source/semantic.light.tokens.json +463 -0
- django_brickwork-1.0.0rc1/src/brickwork/tokens/source/typography.tokens.json +90 -0
- django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/PKG-INFO +193 -0
- django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/SOURCES.txt +171 -0
- django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/dependency_links.txt +1 -0
- django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/requires.txt +12 -0
- django_brickwork-1.0.0rc1/src/django_brickwork.egg-info/top_level.txt +1 -0
- django_brickwork-1.0.0rc1/tests/test_account_menu.py +79 -0
- django_brickwork-1.0.0rc1/tests/test_brand_css.py +116 -0
- django_brickwork-1.0.0rc1/tests/test_brand_hook.py +181 -0
- django_brickwork-1.0.0rc1/tests/test_breadcrumbs.py +66 -0
- django_brickwork-1.0.0rc1/tests/test_card.py +172 -0
- django_brickwork-1.0.0rc1/tests/test_combobox.py +252 -0
- django_brickwork-1.0.0rc1/tests/test_components.py +164 -0
- django_brickwork-1.0.0rc1/tests/test_consumer_smoke.py +204 -0
- django_brickwork-1.0.0rc1/tests/test_context_processors.py +61 -0
- django_brickwork-1.0.0rc1/tests/test_data_table.py +203 -0
- django_brickwork-1.0.0rc1/tests/test_disclosure.py +104 -0
- django_brickwork-1.0.0rc1/tests/test_dropdown.py +181 -0
- django_brickwork-1.0.0rc1/tests/test_feedback.py +206 -0
- django_brickwork-1.0.0rc1/tests/test_filter_bar.py +76 -0
- django_brickwork-1.0.0rc1/tests/test_forms.py +317 -0
- django_brickwork-1.0.0rc1/tests/test_icons.py +173 -0
- django_brickwork-1.0.0rc1/tests/test_inputs.py +354 -0
- django_brickwork-1.0.0rc1/tests/test_integration.py +432 -0
- django_brickwork-1.0.0rc1/tests/test_modal.py +148 -0
- django_brickwork-1.0.0rc1/tests/test_nav_slot.py +105 -0
- django_brickwork-1.0.0rc1/tests/test_nav_tag.py +237 -0
- django_brickwork-1.0.0rc1/tests/test_navigation.py +280 -0
- django_brickwork-1.0.0rc1/tests/test_patterns.py +229 -0
- django_brickwork-1.0.0rc1/tests/test_shell.py +170 -0
- django_brickwork-1.0.0rc1/tests/test_slide_over.py +169 -0
- django_brickwork-1.0.0rc1/tests/test_smoke.py +41 -0
- django_brickwork-1.0.0rc1/tests/test_stat.py +187 -0
- django_brickwork-1.0.0rc1/tests/test_stepper.py +124 -0
- django_brickwork-1.0.0rc1/tests/test_table_selection.py +207 -0
- django_brickwork-1.0.0rc1/tests/test_tabs.py +205 -0
- django_brickwork-1.0.0rc1/tests/test_tailwind_projection.py +176 -0
- django_brickwork-1.0.0rc1/tests/test_theme.py +63 -0
- django_brickwork-1.0.0rc1/tests/test_tiers.py +123 -0
- django_brickwork-1.0.0rc1/tests/test_toast.py +203 -0
- django_brickwork-1.0.0rc1/tests/test_token_derivations.py +204 -0
- django_brickwork-1.0.0rc1/tests/test_token_manifest.py +125 -0
- django_brickwork-1.0.0rc1/tests/test_tokens.py +261 -0
- django_brickwork-1.0.0rc1/tests/test_wizard.py +105 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nigel Copley
|
|
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.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
django-brickwork
|
|
2
|
+
Copyright (c) 2026 Nigel Copley
|
|
3
|
+
|
|
4
|
+
This product is licensed under the MIT License (see LICENSE).
|
|
5
|
+
|
|
6
|
+
It includes third-party material under the terms below. These notices cover the
|
|
7
|
+
vendored icon artwork seeded into the brickwork icon registry
|
|
8
|
+
(src/brickwork/icons/vendor/). The icon *names* are brickwork's own versioned
|
|
9
|
+
public contract; the vendored artwork is a pinned, swappable implementation
|
|
10
|
+
detail behind those names.
|
|
11
|
+
|
|
12
|
+
--------------------------------------------------------------------------------
|
|
13
|
+
Lucide (https://lucide.dev)
|
|
14
|
+
--------------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
The curated icon subset in src/brickwork/icons/vendor/lucide/ is taken from the
|
|
17
|
+
`lucide-static` package (v1.28.0) and is used under the ISC License.
|
|
18
|
+
|
|
19
|
+
ISC License
|
|
20
|
+
|
|
21
|
+
Copyright (c) 2020, Lucide Contributors
|
|
22
|
+
|
|
23
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
24
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
25
|
+
copyright notice and this permission notice appear in all copies.
|
|
26
|
+
|
|
27
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
28
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
29
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
30
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
31
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
32
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
33
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
34
|
+
|
|
35
|
+
--------------------------------------------------------------------------------
|
|
36
|
+
Feather (https://feathericons.com)
|
|
37
|
+
--------------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
A subset of the Lucide icons above derive from Feather, which is distributed
|
|
40
|
+
under the MIT License. That subset is therefore additionally covered by:
|
|
41
|
+
|
|
42
|
+
The MIT License (MIT)
|
|
43
|
+
|
|
44
|
+
Copyright (c) 2013-2023 Cole Bemis
|
|
45
|
+
|
|
46
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
47
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
48
|
+
in the Software without restriction, including without limitation the rights
|
|
49
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
50
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
51
|
+
furnished to do so, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
The above copyright notice and this permission notice shall be included in all
|
|
54
|
+
copies or substantial portions of the Software.
|
|
55
|
+
|
|
56
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
57
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
58
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
59
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
60
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
61
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
62
|
+
SOFTWARE.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-brickwork
|
|
3
|
+
Version: 1.0.0rc1
|
|
4
|
+
Summary: Brand-agnostic, app-facing professional UI substrate for server-rendered Django (Tailwind 4, Alpine 3, HTMX 2). Accessible by construction; not a Django-admin skin.
|
|
5
|
+
Author: Nigel Copley
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/icvoss/django-brickwork
|
|
8
|
+
Project-URL: Documentation, https://github.com/icvoss/django-brickwork
|
|
9
|
+
Project-URL: Changelog, https://github.com/icvoss/django-brickwork/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issue Tracker, https://github.com/icvoss/django-brickwork/issues
|
|
11
|
+
Project-URL: Source Code, https://github.com/icvoss/django-brickwork
|
|
12
|
+
Keywords: django,ui,design-system,tailwind,alpine,htmx,accessibility,wcag,components
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Web Environment
|
|
15
|
+
Classifier: Framework :: Django
|
|
16
|
+
Classifier: Framework :: Django :: 6.0
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: User Interfaces
|
|
21
|
+
Requires-Python: >=3.12
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
License-File: NOTICE
|
|
25
|
+
Requires-Dist: Django>=6.0
|
|
26
|
+
Provides-Extra: htmx
|
|
27
|
+
Requires-Dist: django-htmx>=1.28; extra == "htmx"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-django>=4.8; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
32
|
+
Requires-Dist: django-htmx>=1.28; extra == "dev"
|
|
33
|
+
Requires-Dist: ruff>=0.5.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# brickwork
|
|
38
|
+
|
|
39
|
+
A brand-agnostic, app-facing professional UI substrate for server-rendered
|
|
40
|
+
Django, on the ecosystem stack: Tailwind 4 (CSS-first), Alpine 3, HTMX 2,
|
|
41
|
+
Django 6.0. It provides the application shell, navigation and active-route
|
|
42
|
+
resolution, an accessible form-field renderer, and interaction primitives
|
|
43
|
+
(modal, toast, dropdown, combobox, tabs, disclosure) wrapped behind stable
|
|
44
|
+
Django components.
|
|
45
|
+
|
|
46
|
+
**This is not a Django-admin skin.** Its value is the professional baseline:
|
|
47
|
+
WCAG 2.2 AA as a *tested* guarantee (axe-core in CI, not a claim), RTL via
|
|
48
|
+
logical properties, a real themeable dark-mode system, and four composable
|
|
49
|
+
theme axes (brand x theme x density x direction). Applications provide data,
|
|
50
|
+
permissions and business behaviour; the substrate provides structure,
|
|
51
|
+
presentation and interaction conventions.
|
|
52
|
+
|
|
53
|
+
> Status: **0.16.0, graduating to public PyPI.** The five semver-governed
|
|
54
|
+
> public-API contracts (token, template, navigation, interaction, JavaScript)
|
|
55
|
+
> are live, and every component passes two hard gates: is it accessible
|
|
56
|
+
> (axe-core WCAG 2.2 AA in CI) and is it beautiful by default. The surface is
|
|
57
|
+
> complete: the application shell and nav, the beautiful-by-default token system
|
|
58
|
+
> (elevation, state overlays, type roles, motion, borders, with fine colours
|
|
59
|
+
> derived live from a small load-bearing brand set via `color-mix()`), the
|
|
60
|
+
> interaction set (modal, toast, dropdown, combobox, tabs, disclosure, tooltip,
|
|
61
|
+
> slide-over), forms with the whole-form renderer and the HTMX 422 loop, the
|
|
62
|
+
> data table with sortable and selectable modes, the feedback and input-chrome
|
|
63
|
+
> primitives, the wizard/stepper, and a machine-readable token contract with a
|
|
64
|
+
> per-tenant brand-CSS emitter. The design of record is the spec and brief in
|
|
65
|
+
> the icvoss/oss umbrella:
|
|
66
|
+
> - Spec: `docs/specs/django-brickwork/` (the five versioned public-API contracts).
|
|
67
|
+
> - Design + branding + integration: `docs/DESIGN.md`, `docs/BRANDING.md`,
|
|
68
|
+
> `docs/INTEGRATION.md`, `docs/ADOPTION.md`.
|
|
69
|
+
> - Changelog: `CHANGELOG.md` (0.1.0 through 0.16.0).
|
|
70
|
+
|
|
71
|
+
## Documentation
|
|
72
|
+
|
|
73
|
+
- [docs/DESIGN.md](docs/DESIGN.md): the canonical token reference; every
|
|
74
|
+
`--bw-*` name, default value, and derivation rule.
|
|
75
|
+
- [docs/BRANDING.md](docs/BRANDING.md): how a consuming app brands brickwork
|
|
76
|
+
(the load-bearing token minimum, dark mode, the four axes, the fg-on-accent
|
|
77
|
+
contrast trap, and dynamic per-tenant / per-user theming recipes).
|
|
78
|
+
- [docs/INTEGRATION.md](docs/INTEGRATION.md): the greenfield integration
|
|
79
|
+
cookbook, the seams a consuming app wires end to end (settings and static, nav
|
|
80
|
+
config, context processor, a worked HTMX 422 form, the chrome/body boundary).
|
|
81
|
+
- [docs/ADOPTION.md](docs/ADOPTION.md): the strangle guide for migrating an
|
|
82
|
+
existing app onto brickwork cluster by cluster (multi-host, asset coexistence,
|
|
83
|
+
the htmx floor).
|
|
84
|
+
- [frontend/README.md](frontend/README.md): the in-repo build that compiles
|
|
85
|
+
the shipped static assets.
|
|
86
|
+
|
|
87
|
+
## Install
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
pip install django-brickwork # from pypi.icvoss.com (private index)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
INSTALLED_APPS = [
|
|
95
|
+
"brickwork",
|
|
96
|
+
# ...
|
|
97
|
+
]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The compiled CSS and JS ship inside the package and are referenced with plain
|
|
101
|
+
`{% static %}`; no build-tool dependency (django-vite / django-tailwind) is
|
|
102
|
+
imposed on consumers. Consumers provide their own Alpine 3 +
|
|
103
|
+
`@alpinejs/focus` (and optionally htmx 2) via their own frontend build; brickwork
|
|
104
|
+
registers behaviour onto the host Alpine instance and never calls
|
|
105
|
+
`Alpine.start()`.
|
|
106
|
+
|
|
107
|
+
### htmx floor: htmx >= 2.0
|
|
108
|
+
|
|
109
|
+
brickwork's interaction contracts (the HTMX 422 form-swap loop, toast delivery
|
|
110
|
+
via `hx-swap-oob`, modal dismissal via the `HX-Trigger: bw:modal:close` response
|
|
111
|
+
header, combobox server filtering) are built and CI-gated on **htmx >= 2.0**
|
|
112
|
+
only. htmx 1.9 is out of contract (BR-BW-HTMX-010): htmx 2 changed default
|
|
113
|
+
response handling in ways the 422 loop relies on, and the interaction suites only
|
|
114
|
+
ever exercise htmx 2. A brownfield app on htmx 1.9 should upgrade htmx to 2.x as a
|
|
115
|
+
prerequisite before adopting brickwork's interaction primitives; see
|
|
116
|
+
[docs/ADOPTION.md](docs/ADOPTION.md).
|
|
117
|
+
|
|
118
|
+
## Contracts
|
|
119
|
+
|
|
120
|
+
brickwork's public API is five versioned contracts (see the spec): **token**,
|
|
121
|
+
**template**, **navigation**, **interaction (HTMX)**, and **JavaScript
|
|
122
|
+
(Alpine)**. Template block names, HTMX target IDs, Alpine component names,
|
|
123
|
+
event names and token names are semver-governed.
|
|
124
|
+
|
|
125
|
+
## Usage
|
|
126
|
+
|
|
127
|
+
### Tags vs includes
|
|
128
|
+
|
|
129
|
+
Some components are consumed as **template tags**, others via `{% include %}`.
|
|
130
|
+
This is deliberate: a component that carries logic (variant validation, a11y
|
|
131
|
+
enforcement, icon resolution) ships as a tag so that logic is not duplicated at
|
|
132
|
+
every call site; a purely structural component is an include the consumer fills
|
|
133
|
+
with context.
|
|
134
|
+
|
|
135
|
+
- **Tags** (load the library first): `{% bw_icon %}`, `{% bw_button %}`,
|
|
136
|
+
`{% bw_badge %}`, `{% bw_alert %}`, `{% bw_nav %}`, `{% bw_field_widget %}`.
|
|
137
|
+
|
|
138
|
+
```django
|
|
139
|
+
{% load brickwork_components brickwork_icons brickwork_nav %}
|
|
140
|
+
{% bw_button label="Save" variant="primary" %}
|
|
141
|
+
{% bw_badge label="New" variant="info" %}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The `_button.html` / `_badge.html` / `_alert.html` template files exist but are
|
|
145
|
+
the tags' own render targets, **not** a consumer-facing `{% include %}` API.
|
|
146
|
+
Call the tag, not the partial.
|
|
147
|
+
|
|
148
|
+
- **Includes** (structure you fill with context): `_page_header.html`,
|
|
149
|
+
`_data_table.html`, `_pagination.html`, `_empty_state.html`,
|
|
150
|
+
`_filter_bar.html`, `_spinner.html`, and the form partials `forms/_field.html`
|
|
151
|
+
/ `forms/_form_errors.html`.
|
|
152
|
+
|
|
153
|
+
```django
|
|
154
|
+
{% include "brickwork/components/_data_table.html" with table_id="gadgets" columns=columns rows=rows %}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Icons: decorative or labelled, always
|
|
158
|
+
|
|
159
|
+
`{% bw_icon %}` **requires** exactly one of `decorative=True` or `label="..."`,
|
|
160
|
+
and raises `TemplateSyntaxError` if given neither or both. This is intentional
|
|
161
|
+
(ICO-007, WCAG 4.1.2): an icon is either purely presentational (aria-hidden) or
|
|
162
|
+
carries meaning (an accessible name), never ambiguous.
|
|
163
|
+
|
|
164
|
+
```django
|
|
165
|
+
{% bw_icon "search" decorative=True %} {# beside a visible label #}
|
|
166
|
+
{% bw_icon "trash" label="Delete item" %} {# standalone, meaningful #}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
You rarely call `bw_icon` directly for the icon *inside* a `bw_button` or
|
|
170
|
+
`bw_nav` item: those tags take an `icon="..."` argument and handle the a11y
|
|
171
|
+
pairing for you. Reach for `bw_icon` directly only for a standalone icon in your
|
|
172
|
+
own markup, where this rule applies.
|
|
173
|
+
|
|
174
|
+
## Development
|
|
175
|
+
|
|
176
|
+
Python package:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
pip install -e ".[dev]"
|
|
180
|
+
pytest
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Frontend build (compiles tokens + component assets into the package's static
|
|
184
|
+
dir; see `frontend/README.md`):
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
npm install
|
|
188
|
+
npm run build
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Licence
|
|
192
|
+
|
|
193
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# brickwork
|
|
2
|
+
|
|
3
|
+
A brand-agnostic, app-facing professional UI substrate for server-rendered
|
|
4
|
+
Django, on the ecosystem stack: Tailwind 4 (CSS-first), Alpine 3, HTMX 2,
|
|
5
|
+
Django 6.0. It provides the application shell, navigation and active-route
|
|
6
|
+
resolution, an accessible form-field renderer, and interaction primitives
|
|
7
|
+
(modal, toast, dropdown, combobox, tabs, disclosure) wrapped behind stable
|
|
8
|
+
Django components.
|
|
9
|
+
|
|
10
|
+
**This is not a Django-admin skin.** Its value is the professional baseline:
|
|
11
|
+
WCAG 2.2 AA as a *tested* guarantee (axe-core in CI, not a claim), RTL via
|
|
12
|
+
logical properties, a real themeable dark-mode system, and four composable
|
|
13
|
+
theme axes (brand x theme x density x direction). Applications provide data,
|
|
14
|
+
permissions and business behaviour; the substrate provides structure,
|
|
15
|
+
presentation and interaction conventions.
|
|
16
|
+
|
|
17
|
+
> Status: **0.16.0, graduating to public PyPI.** The five semver-governed
|
|
18
|
+
> public-API contracts (token, template, navigation, interaction, JavaScript)
|
|
19
|
+
> are live, and every component passes two hard gates: is it accessible
|
|
20
|
+
> (axe-core WCAG 2.2 AA in CI) and is it beautiful by default. The surface is
|
|
21
|
+
> complete: the application shell and nav, the beautiful-by-default token system
|
|
22
|
+
> (elevation, state overlays, type roles, motion, borders, with fine colours
|
|
23
|
+
> derived live from a small load-bearing brand set via `color-mix()`), the
|
|
24
|
+
> interaction set (modal, toast, dropdown, combobox, tabs, disclosure, tooltip,
|
|
25
|
+
> slide-over), forms with the whole-form renderer and the HTMX 422 loop, the
|
|
26
|
+
> data table with sortable and selectable modes, the feedback and input-chrome
|
|
27
|
+
> primitives, the wizard/stepper, and a machine-readable token contract with a
|
|
28
|
+
> per-tenant brand-CSS emitter. The design of record is the spec and brief in
|
|
29
|
+
> the icvoss/oss umbrella:
|
|
30
|
+
> - Spec: `docs/specs/django-brickwork/` (the five versioned public-API contracts).
|
|
31
|
+
> - Design + branding + integration: `docs/DESIGN.md`, `docs/BRANDING.md`,
|
|
32
|
+
> `docs/INTEGRATION.md`, `docs/ADOPTION.md`.
|
|
33
|
+
> - Changelog: `CHANGELOG.md` (0.1.0 through 0.16.0).
|
|
34
|
+
|
|
35
|
+
## Documentation
|
|
36
|
+
|
|
37
|
+
- [docs/DESIGN.md](docs/DESIGN.md): the canonical token reference; every
|
|
38
|
+
`--bw-*` name, default value, and derivation rule.
|
|
39
|
+
- [docs/BRANDING.md](docs/BRANDING.md): how a consuming app brands brickwork
|
|
40
|
+
(the load-bearing token minimum, dark mode, the four axes, the fg-on-accent
|
|
41
|
+
contrast trap, and dynamic per-tenant / per-user theming recipes).
|
|
42
|
+
- [docs/INTEGRATION.md](docs/INTEGRATION.md): the greenfield integration
|
|
43
|
+
cookbook, the seams a consuming app wires end to end (settings and static, nav
|
|
44
|
+
config, context processor, a worked HTMX 422 form, the chrome/body boundary).
|
|
45
|
+
- [docs/ADOPTION.md](docs/ADOPTION.md): the strangle guide for migrating an
|
|
46
|
+
existing app onto brickwork cluster by cluster (multi-host, asset coexistence,
|
|
47
|
+
the htmx floor).
|
|
48
|
+
- [frontend/README.md](frontend/README.md): the in-repo build that compiles
|
|
49
|
+
the shipped static assets.
|
|
50
|
+
|
|
51
|
+
## Install
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
pip install django-brickwork # from pypi.icvoss.com (private index)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
INSTALLED_APPS = [
|
|
59
|
+
"brickwork",
|
|
60
|
+
# ...
|
|
61
|
+
]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The compiled CSS and JS ship inside the package and are referenced with plain
|
|
65
|
+
`{% static %}`; no build-tool dependency (django-vite / django-tailwind) is
|
|
66
|
+
imposed on consumers. Consumers provide their own Alpine 3 +
|
|
67
|
+
`@alpinejs/focus` (and optionally htmx 2) via their own frontend build; brickwork
|
|
68
|
+
registers behaviour onto the host Alpine instance and never calls
|
|
69
|
+
`Alpine.start()`.
|
|
70
|
+
|
|
71
|
+
### htmx floor: htmx >= 2.0
|
|
72
|
+
|
|
73
|
+
brickwork's interaction contracts (the HTMX 422 form-swap loop, toast delivery
|
|
74
|
+
via `hx-swap-oob`, modal dismissal via the `HX-Trigger: bw:modal:close` response
|
|
75
|
+
header, combobox server filtering) are built and CI-gated on **htmx >= 2.0**
|
|
76
|
+
only. htmx 1.9 is out of contract (BR-BW-HTMX-010): htmx 2 changed default
|
|
77
|
+
response handling in ways the 422 loop relies on, and the interaction suites only
|
|
78
|
+
ever exercise htmx 2. A brownfield app on htmx 1.9 should upgrade htmx to 2.x as a
|
|
79
|
+
prerequisite before adopting brickwork's interaction primitives; see
|
|
80
|
+
[docs/ADOPTION.md](docs/ADOPTION.md).
|
|
81
|
+
|
|
82
|
+
## Contracts
|
|
83
|
+
|
|
84
|
+
brickwork's public API is five versioned contracts (see the spec): **token**,
|
|
85
|
+
**template**, **navigation**, **interaction (HTMX)**, and **JavaScript
|
|
86
|
+
(Alpine)**. Template block names, HTMX target IDs, Alpine component names,
|
|
87
|
+
event names and token names are semver-governed.
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
### Tags vs includes
|
|
92
|
+
|
|
93
|
+
Some components are consumed as **template tags**, others via `{% include %}`.
|
|
94
|
+
This is deliberate: a component that carries logic (variant validation, a11y
|
|
95
|
+
enforcement, icon resolution) ships as a tag so that logic is not duplicated at
|
|
96
|
+
every call site; a purely structural component is an include the consumer fills
|
|
97
|
+
with context.
|
|
98
|
+
|
|
99
|
+
- **Tags** (load the library first): `{% bw_icon %}`, `{% bw_button %}`,
|
|
100
|
+
`{% bw_badge %}`, `{% bw_alert %}`, `{% bw_nav %}`, `{% bw_field_widget %}`.
|
|
101
|
+
|
|
102
|
+
```django
|
|
103
|
+
{% load brickwork_components brickwork_icons brickwork_nav %}
|
|
104
|
+
{% bw_button label="Save" variant="primary" %}
|
|
105
|
+
{% bw_badge label="New" variant="info" %}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The `_button.html` / `_badge.html` / `_alert.html` template files exist but are
|
|
109
|
+
the tags' own render targets, **not** a consumer-facing `{% include %}` API.
|
|
110
|
+
Call the tag, not the partial.
|
|
111
|
+
|
|
112
|
+
- **Includes** (structure you fill with context): `_page_header.html`,
|
|
113
|
+
`_data_table.html`, `_pagination.html`, `_empty_state.html`,
|
|
114
|
+
`_filter_bar.html`, `_spinner.html`, and the form partials `forms/_field.html`
|
|
115
|
+
/ `forms/_form_errors.html`.
|
|
116
|
+
|
|
117
|
+
```django
|
|
118
|
+
{% include "brickwork/components/_data_table.html" with table_id="gadgets" columns=columns rows=rows %}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Icons: decorative or labelled, always
|
|
122
|
+
|
|
123
|
+
`{% bw_icon %}` **requires** exactly one of `decorative=True` or `label="..."`,
|
|
124
|
+
and raises `TemplateSyntaxError` if given neither or both. This is intentional
|
|
125
|
+
(ICO-007, WCAG 4.1.2): an icon is either purely presentational (aria-hidden) or
|
|
126
|
+
carries meaning (an accessible name), never ambiguous.
|
|
127
|
+
|
|
128
|
+
```django
|
|
129
|
+
{% bw_icon "search" decorative=True %} {# beside a visible label #}
|
|
130
|
+
{% bw_icon "trash" label="Delete item" %} {# standalone, meaningful #}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
You rarely call `bw_icon` directly for the icon *inside* a `bw_button` or
|
|
134
|
+
`bw_nav` item: those tags take an `icon="..."` argument and handle the a11y
|
|
135
|
+
pairing for you. Reach for `bw_icon` directly only for a standalone icon in your
|
|
136
|
+
own markup, where this rule applies.
|
|
137
|
+
|
|
138
|
+
## Development
|
|
139
|
+
|
|
140
|
+
Python package:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
pip install -e ".[dev]"
|
|
144
|
+
pytest
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Frontend build (compiles tokens + component assets into the package's static
|
|
148
|
+
dir; see `frontend/README.md`):
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
npm install
|
|
152
|
+
npm run build
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Licence
|
|
156
|
+
|
|
157
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "django-brickwork"
|
|
7
|
+
version = "1.0.0rc1"
|
|
8
|
+
description = "Brand-agnostic, app-facing professional UI substrate for server-rendered Django (Tailwind 4, Alpine 3, HTMX 2). Accessible by construction; not a Django-admin skin."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.12"
|
|
12
|
+
authors = [{name = "Nigel Copley"}]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 4 - Beta",
|
|
15
|
+
"Environment :: Web Environment",
|
|
16
|
+
"Framework :: Django",
|
|
17
|
+
"Framework :: Django :: 6.0",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Topic :: Software Development :: User Interfaces",
|
|
22
|
+
]
|
|
23
|
+
keywords = [
|
|
24
|
+
"django",
|
|
25
|
+
"ui",
|
|
26
|
+
"design-system",
|
|
27
|
+
"tailwind",
|
|
28
|
+
"alpine",
|
|
29
|
+
"htmx",
|
|
30
|
+
"accessibility",
|
|
31
|
+
"wcag",
|
|
32
|
+
"components",
|
|
33
|
+
]
|
|
34
|
+
# Django 6.0 floor: the package uses core template partials
|
|
35
|
+
# ({% partialdef %} / render(request, "t#partial")) with no compat shim.
|
|
36
|
+
#
|
|
37
|
+
# Django is the ONLY hard runtime dependency. Deliberately NOT depended on
|
|
38
|
+
# (build-tool research 2026-07-30, a library inherits every dep five times):
|
|
39
|
+
# - django-htmx: brickwork's own need is one boolean (HX-Request header). It
|
|
40
|
+
# inlines that check and duck-types request.htmx when a consumer already
|
|
41
|
+
# runs django-htmx. Offered as the optional [htmx] extra, never forced.
|
|
42
|
+
# - django-vite: unnecessary. brickwork ships STABLE (non-hashed) asset
|
|
43
|
+
# filenames referenced by plain {% static %}; there is no Vite manifest to
|
|
44
|
+
# resolve. (Also stale: no Django 5.x/6.x support.)
|
|
45
|
+
# - django-tailwind / -cli: irrelevant. They manage a Tailwind build inside a
|
|
46
|
+
# live Django project; brickwork compiles its CSS in its OWN repo (Vite +
|
|
47
|
+
# @tailwindcss/vite) and ships the precompiled artefact.
|
|
48
|
+
# Tailwind/Alpine/HTMX are FRONTEND runtime (loaded via <link>/<script> against
|
|
49
|
+
# the shipped static assets), not Python packages. @alpinejs/ui + @alpinejs/focus
|
|
50
|
+
# are host-owned peer deps delivered by the consumer's own Vite/npm build.
|
|
51
|
+
dependencies = [
|
|
52
|
+
"Django>=6.0",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[project.urls]
|
|
56
|
+
Homepage = "https://github.com/icvoss/django-brickwork"
|
|
57
|
+
Documentation = "https://github.com/icvoss/django-brickwork"
|
|
58
|
+
Changelog = "https://github.com/icvoss/django-brickwork/blob/main/CHANGELOG.md"
|
|
59
|
+
"Issue Tracker" = "https://github.com/icvoss/django-brickwork/issues"
|
|
60
|
+
"Source Code" = "https://github.com/icvoss/django-brickwork"
|
|
61
|
+
|
|
62
|
+
[project.optional-dependencies]
|
|
63
|
+
# Optional: consumers already running django-htmx get brickwork's HTMX-aware
|
|
64
|
+
# helpers using the richer request.htmx surface. brickwork's core never imports
|
|
65
|
+
# it (it inlines the HX-Request header check + duck-types request.htmx), so
|
|
66
|
+
# consumers without this extra are unaffected.
|
|
67
|
+
htmx = ["django-htmx>=1.28"]
|
|
68
|
+
dev = [
|
|
69
|
+
"pytest>=8.0",
|
|
70
|
+
"pytest-django>=4.8",
|
|
71
|
+
"pytest-cov>=5.0",
|
|
72
|
+
"django-htmx>=1.28",
|
|
73
|
+
"ruff>=0.5.0",
|
|
74
|
+
"mypy>=1.10",
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
[tool.setuptools.packages.find]
|
|
78
|
+
where = ["src"]
|
|
79
|
+
|
|
80
|
+
[tool.setuptools.package-data]
|
|
81
|
+
# Ship templates, the compiled CSS/JS/token artefacts (built by the frontend
|
|
82
|
+
# pipeline into static/brickwork/dist), the vendored icon artwork the registry
|
|
83
|
+
# loads at import, the DTCG token source, and the PEP 561 typed marker.
|
|
84
|
+
brickwork = [
|
|
85
|
+
"py.typed",
|
|
86
|
+
"templates/**/*.html",
|
|
87
|
+
"static/**/*",
|
|
88
|
+
"icons/vendor/**/*.svg",
|
|
89
|
+
"tokens/source/**/*.json",
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
[tool.pytest.ini_options]
|
|
93
|
+
DJANGO_SETTINGS_MODULE = "tests.settings"
|
|
94
|
+
# "." (repo root) so `tests.settings` resolves as a package; "src" for the
|
|
95
|
+
# package. NOT "tests" itself: that would put tests/'s contents at top level and
|
|
96
|
+
# shadow the `tests` package, breaking the `tests.settings` import (CI-caught).
|
|
97
|
+
# The seams leg additionally needs `brickwork_testapp` importable; its CI step
|
|
98
|
+
# and the a11y fixtures set PYTHONPATH=src:.:tests for that.
|
|
99
|
+
pythonpath = ["src", "."]
|
|
100
|
+
testpaths = ["tests"]
|
|
101
|
+
|
|
102
|
+
[tool.ruff]
|
|
103
|
+
target-version = "py312"
|
|
104
|
+
line-length = 120
|
|
105
|
+
src = ["src"]
|
|
106
|
+
|
|
107
|
+
[tool.ruff.lint]
|
|
108
|
+
select = ["E", "W", "F", "I", "B", "UP", "N", "SIM"]
|
|
109
|
+
ignore = ["E501", "SIM105"]
|
|
110
|
+
|
|
111
|
+
[tool.ruff.lint.isort]
|
|
112
|
+
known-first-party = ["brickwork"]
|
|
113
|
+
|
|
114
|
+
[tool.ruff.format]
|
|
115
|
+
quote-style = "double"
|
|
116
|
+
|
|
117
|
+
[tool.mypy]
|
|
118
|
+
python_version = "3.12"
|
|
119
|
+
strict = false
|
|
120
|
+
|
|
121
|
+
[tool.coverage.run]
|
|
122
|
+
source = ["src"]
|
|
123
|
+
omit = ["*/tests/*"]
|
|
124
|
+
|
|
125
|
+
[tool.coverage.report]
|
|
126
|
+
fail_under = 90
|
|
127
|
+
show_missing = true
|
|
128
|
+
exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:", "if __name__ =="]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""brickwork: a brand-agnostic, app-facing professional UI substrate for Django.
|
|
2
|
+
|
|
3
|
+
Provides the application shell, navigation and active-route resolution, an
|
|
4
|
+
accessible form-field renderer, and interaction primitives (modal, toast,
|
|
5
|
+
dropdown, combobox, tabs, disclosure) wrapped behind stable Django components,
|
|
6
|
+
on the ecosystem stack (Tailwind 4 CSS-first, Alpine 3, HTMX 2, Django 6.0).
|
|
7
|
+
|
|
8
|
+
This is NOT a Django-admin skin. Its value is the professional baseline:
|
|
9
|
+
WCAG 2.2 AA as a tested guarantee, RTL via logical properties, a real themeable
|
|
10
|
+
dark-mode system, and four composable theme axes (brand x theme x density x
|
|
11
|
+
direction). See docs/specs/django-brickwork/ in the icvoss/oss umbrella for the five
|
|
12
|
+
versioned public-API contracts (token, template, navigation, interaction,
|
|
13
|
+
JavaScript).
|
|
14
|
+
|
|
15
|
+
The design-token layer lives in the framework-neutral ``brickwork.tokens``
|
|
16
|
+
sub-module; a separate ``brickwork_tokens`` package is deferred until a
|
|
17
|
+
non-Django consumer earns the split.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
__version__ = "1.0.0rc1"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Django app configuration for brickwork.
|
|
2
|
+
|
|
3
|
+
The ``AppConfig.ready()`` hook is where any system checks for the token/template
|
|
4
|
+
contracts are registered. Navigation duplicate-key validation is enforced by the
|
|
5
|
+
consuming project calling ``validate_nav_config()`` at import time
|
|
6
|
+
(BR-BW-NAV-002), not from ``ready()``, since brickwork ships no nav config of its
|
|
7
|
+
own. Kept minimal in the scaffold; populated as the check subsystem lands in
|
|
8
|
+
Phase 0.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from django.apps import AppConfig
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BrickworkConfig(AppConfig):
|
|
17
|
+
name = "brickwork"
|
|
18
|
+
verbose_name = "brickwork UI substrate"
|
|
19
|
+
default_auto_field = "django.db.models.BigAutoField"
|
|
20
|
+
|
|
21
|
+
def ready(self) -> None:
|
|
22
|
+
# Phase 0: register system checks (token/template/nav contract guards)
|
|
23
|
+
# here. Intentionally empty until the check subsystem lands; an install
|
|
24
|
+
# imports cleanly with no models.
|
|
25
|
+
pass
|