daisy-cotton 0.1.0__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.
Files changed (91) hide show
  1. daisy_cotton-0.1.0/.gitignore +63 -0
  2. daisy_cotton-0.1.0/LICENSE +21 -0
  3. daisy_cotton-0.1.0/PKG-INFO +159 -0
  4. daisy_cotton-0.1.0/README.md +131 -0
  5. daisy_cotton-0.1.0/daisy_cotton/__init__.py +3 -0
  6. daisy_cotton-0.1.0/daisy_cotton/apps.py +12 -0
  7. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/accordion.html +7 -0
  8. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/alert.html +23 -0
  9. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/avatar/group.html +5 -0
  10. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/avatar/index.html +29 -0
  11. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/badge.html +13 -0
  12. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/breadcrumbs/index.html +19 -0
  13. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/breadcrumbs/item.html +13 -0
  14. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/button.html +46 -0
  15. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/card/index.html +26 -0
  16. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/carousel/index.html +20 -0
  17. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/carousel/item.html +6 -0
  18. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/chat.html +20 -0
  19. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/collapse.html +13 -0
  20. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/countdown.html +10 -0
  21. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/diff.html +16 -0
  22. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/divider.html +15 -0
  23. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/dock/index.html +10 -0
  24. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/dock/item.html +31 -0
  25. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/drawer/button.html +7 -0
  26. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/drawer/index.html +20 -0
  27. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/dropdown/index.html +27 -0
  28. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/fab.html +23 -0
  29. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/footer/index.html +10 -0
  30. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/footer/nav.html +11 -0
  31. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/calendar.html +12 -0
  32. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/checkbox.html +9 -0
  33. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/fieldset.html +14 -0
  34. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/file_input.html +10 -0
  35. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/filter.html +18 -0
  36. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/input.html +15 -0
  37. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/label.html +9 -0
  38. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/otp.html +16 -0
  39. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/radio.html +9 -0
  40. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/range.html +12 -0
  41. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/rating.html +21 -0
  42. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/select.html +15 -0
  43. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/textarea.html +11 -0
  44. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/form/toggle.html +9 -0
  45. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/hero.html +11 -0
  46. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/hover_3d.html +11 -0
  47. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/hover_gallery.html +5 -0
  48. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/icon.html +9 -0
  49. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/indicator/index.html +12 -0
  50. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/indicator/item.html +11 -0
  51. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/join.html +16 -0
  52. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/kbd.html +8 -0
  53. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/link.html +16 -0
  54. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/list/index.html +5 -0
  55. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/list/row.html +5 -0
  56. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/loading.html +15 -0
  57. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/mask.html +17 -0
  58. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/megamenu/index.html +19 -0
  59. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/megamenu/item.html +9 -0
  60. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/menu/index.html +10 -0
  61. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/menu/item.html +26 -0
  62. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/menu/submenu.html +13 -0
  63. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/menu/title.html +6 -0
  64. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/mockup/browser.html +12 -0
  65. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/mockup/code/index.html +6 -0
  66. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/mockup/code/line.html +7 -0
  67. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/mockup/phone.html +8 -0
  68. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/mockup/window.html +7 -0
  69. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/modal.html +40 -0
  70. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/navbar.html +20 -0
  71. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/progress.html +11 -0
  72. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/radial_progress.html +11 -0
  73. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/skeleton.html +6 -0
  74. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/stack.html +7 -0
  75. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/stat/group.html +8 -0
  76. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/stat/index.html +20 -0
  77. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/status.html +8 -0
  78. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/steps/index.html +9 -0
  79. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/steps/step.html +17 -0
  80. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/swap.html +39 -0
  81. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/table.html +24 -0
  82. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/tabs/index.html +13 -0
  83. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/tabs/tab.html +31 -0
  84. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/text_rotate.html +11 -0
  85. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/timeline/index.html +11 -0
  86. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/timeline/item.html +17 -0
  87. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/toast.html +9 -0
  88. daisy_cotton-0.1.0/daisy_cotton/templates/cotton/tooltip.html +18 -0
  89. daisy_cotton-0.1.0/daisy_cotton/templatetags/__init__.py +1 -0
  90. daisy_cotton-0.1.0/daisy_cotton/templatetags/daisy_cotton.py +229 -0
  91. daisy_cotton-0.1.0/pyproject.toml +219 -0
@@ -0,0 +1,63 @@
1
+ # Temporary and binary files
2
+ *~
3
+ *.ruff_cache
4
+ *.mypy_cache
5
+ *.py[cod]
6
+ *.so
7
+ *.cfg
8
+ !.isort.cfg
9
+ !setup.cfg
10
+ *.orig
11
+ *.log
12
+ *.pot
13
+ **/__pycache__
14
+ .cache/*
15
+ .*.swp
16
+ */.ipynb_checkpoints/*
17
+ .DS_Store
18
+ .vscode/
19
+ .github/instructions/
20
+ docs/api/
21
+
22
+ # Unittest and coverage
23
+ htmlcov
24
+ .coverage
25
+ .coverage.*
26
+ .tox
27
+ junit*.xml
28
+ coverage.xml
29
+ .pytest_cache/
30
+
31
+ # Build and docs folder/files
32
+ build/*
33
+ dist/*
34
+ sdist/*
35
+ docs/_rst/*
36
+ docs/_build/*
37
+ cover/*
38
+ MANIFEST
39
+
40
+ # Per-project virtualenvs
41
+ .venv*/
42
+ .conda*/
43
+ .python-version
44
+
45
+ # Django stuff:
46
+ *.log
47
+ local_settings.py
48
+ db.sqlite3
49
+ db.sqlite3-journal
50
+ media/
51
+ /static/
52
+ /*.sqlite3
53
+
54
+ # Environments
55
+ .env
56
+ .venv
57
+ env/
58
+ venv/
59
+ ENV/
60
+ env.bak/
61
+ venv.bak/
62
+
63
+ dist
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Samuel Jennings
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,159 @@
1
+ Metadata-Version: 2.5
2
+ Name: daisy-cotton
3
+ Version: 0.1.0
4
+ Summary: Base daisyUI-styled django-cotton components: buttons, inputs, cards, alerts and the rest of an application's furniture
5
+ Project-URL: Homepage, https://github.com/SamuelJennings/daisy-cotton
6
+ Project-URL: Repository, https://github.com/SamuelJennings/daisy-cotton
7
+ Project-URL: Issues, https://github.com/SamuelJennings/daisy-cotton/issues
8
+ Author-email: Samuel Jennings <samuel.scott.jennings@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: components,cotton,daisyui,django,tailwind
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Web Environment
14
+ Classifier: Framework :: Django
15
+ Classifier: Framework :: Django :: 5.2
16
+ Classifier: Framework :: Django :: 6.0
17
+ Classifier: Framework :: Django :: 6.1
18
+ Classifier: Intended Audience :: Developers
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Classifier: Natural Language :: English
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
24
+ Requires-Python: <4.0,>=3.12
25
+ Requires-Dist: django-cotton>=2.6
26
+ Requires-Dist: django>=5.2
27
+ Description-Content-Type: text/markdown
28
+
29
+ # daisy-cotton
30
+
31
+ [![Tests](https://github.com/SamuelJennings/daisy-cotton/actions/workflows/tests.yml/badge.svg)](https://github.com/SamuelJennings/daisy-cotton/actions/workflows/tests.yml) [![Coverage](https://codecov.io/gh/SamuelJennings/daisy-cotton/branch/main/graph/badge.svg)](https://codecov.io/gh/SamuelJennings/daisy-cotton) ![Python 3.12 | 3.13](https://img.shields.io/badge/python-3.12%20%7C%203.13-blue) ![Django 5.2 | 6.0 | 6.1](https://img.shields.io/badge/django-5.2%20%7C%206.0%20%7C%206.1-blue) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](https://github.com/SamuelJennings/daisy-cotton/blob/main/LICENSE)
32
+
33
+ Base daisyUI-styled django-cotton components: buttons, inputs, cards, alerts and the rest of an application's furniture
34
+
35
+ Built on [daisyUI](https://daisyui.com/) and [django-cotton](https://django-cotton.com/). A project that wants daisyUI-styled Cotton components depends on this package directly: install it, add it to `INSTALLED_APPS`, and each `<c-name>` tag is ready to use. It carries no settings, no menus, no icon registry and no views of its own — see [Scope & philosophy](https://github.com/SamuelJennings/daisy-cotton#scope--philosophy).
36
+
37
+ ## Status
38
+
39
+ Version 0.0.1, pre-1.0: names, attributes and the set of classes a component emits can change between minor versions. The [CHANGELOG](https://github.com/SamuelJennings/daisy-cotton/blob/main/CHANGELOG.md) is how a project finds out what has landed.
40
+
41
+ Eighty-two components are built so far: `accordion`, `alert`, `avatar`, `badge`, `breadcrumbs`, `button`, `card`, `carousel`, `chat`, `collapse`, `countdown`, `diff`, `divider`, `dock`, `drawer`, `dropdown`, `fab`, `footer`, `form.calendar`, `form.checkbox`, `form.fieldset`, `form.file-input`, `form.filter`, `form.input`, `form.label`, `form.otp`, `form.radio`, `form.range`, `form.rating`, `form.select`, `form.textarea`, `form.toggle`, `hero`, `hover-3d`, `hover-gallery`, `icon`, `indicator`, `join`, `kbd`, `link`, `list`, `loading`, `mask`, `megamenu`, `menu`, `modal`, `navbar`, `progress`, `radial-progress`, `skeleton`, `stack`, `stat`, `status`, `steps`, `swap`, `table`, `tabs`, `text-rotate`, `timeline`, `toast`, `tooltip` and `mockup.*`. Pagination has no component: daisyUI builds it from `join` and `btn` and gives it no class of its own, so write it with those two. Aura has no component either: it only decorates another element, so wrap the component to highlight in a `<div class="aura">` with daisyUI's style and size classes. Each one is documented live in the component gallery (`python manage.py runserver` from a checkout). More land as the need arises.
42
+
43
+ `<c-icon>` renders `name` as a literal CSS class string and resolves nothing itself — a project wanting name-based icon resolution provides its own override (see [docs/adr/0001](https://github.com/SamuelJennings/daisy-cotton/blob/main/docs/adr/0001-icon-is-an-extension-point.md)).
44
+
45
+ `<c-alert>` takes `variant` (info, success, warning, error), `soft`/`outline`/`dash` for style, and `horizontal`/`vertical` for direction, each accepting a breakpoint such as `sm`; a caller-given `role` replaces the default `role="alert"`, so `role="status"` gives a polite announcement instead of an interruption. Its icon and dismiss button are drawn by `<c-icon>` and `<c-button>`; the dismiss button's accessible name is the translatable "Dismiss" with its glyph hidden from assistive technology. `dismissible` and `delay` need [Alpine.js](https://alpinejs.dev/) on the page — this package doesn't ship or load it. Without Alpine, the alert still renders and reads fine, but the dismiss button does nothing and `delay` never fires.
46
+
47
+ `<c-toast>` pins its content to a corner or edge of the screen and has no role or live region of its own, so put alerts inside it and each keeps its own. A project rendering Django's messages framework writes:
48
+
49
+ ```django
50
+ <c-toast placement="top end">
51
+ {% for message in messages %}
52
+ <c-alert variant="{{ message.level_tag }}" dismissible>{{ message }}</c-alert>
53
+ {% endfor %}
54
+ </c-toast>
55
+ ```
56
+
57
+ Django's `debug` level tag has no matching alert colour, so a debug message falls back to the plain alert.
58
+
59
+ ## Requirements
60
+
61
+ - Python 3.12+
62
+ - Django 5.2, 6.0 or 6.1
63
+ - django-cotton 2.6+
64
+ - daisyUI 5, loaded by the project
65
+
66
+ daisyUI is a hard requirement and this package does not ship it. Any project already running daisyUI satisfies it, through whatever Tailwind build the project already has.
67
+
68
+ ## Install
69
+
70
+ ```bash
71
+ pip install daisy-cotton
72
+ ```
73
+
74
+ Add it to `INSTALLED_APPS`:
75
+
76
+ ```python
77
+ INSTALLED_APPS = [
78
+ ...,
79
+ "django_cotton",
80
+ "daisy_cotton",
81
+ ]
82
+ ```
83
+
84
+ ## Usage
85
+
86
+ Each component is a Cotton tag named after its daisyUI component, configured through attributes that use daisyUI's own modifier names:
87
+
88
+ ```html
89
+ <c-card title="Storage" border>
90
+ Almost full.
91
+ <c-slot name="actions">
92
+ <c-button variant="primary" size="sm" text="Upgrade" />
93
+ </c-slot>
94
+ </c-card>
95
+ ```
96
+
97
+ Classes passed with `class` are added to the component's own, and any other attribute passes through to its root element.
98
+
99
+ ## Calendar
100
+
101
+ `<c-form.calendar>` writes Cally's `<calendar-date>` element, or `<calendar-range>` with `range`, carrying daisyUI's `cally` class. It shows nothing until the project loads Cally, and this package does not. Add the module script to the page's head, pinning the version you have tested or hosting the file yourself:
102
+
103
+ ```html
104
+ <script type="module" src="https://unpkg.com/cally@0.9.2"></script>
105
+ ```
106
+
107
+ Cally's own attributes (`value`, `min`, `max`, `locale`, `first-day-of-week`) go on the tag and reach the calendar unchanged, `months="2"` shows two months side by side, and `class` is added to the calendar's own. The previous and next buttons hold an icon drawn by `<c-icon>` and a visually hidden name, so pass icon classes through `previous_icon` and `next_icon` unless your project's `<c-icon>` resolves names:
108
+
109
+ ```html
110
+ <c-form.calendar id="delivery-calendar" min="2026-09-01" previous_icon="bi bi-chevron-left" next_icon="bi bi-chevron-right" />
111
+ <input type="hidden" name="delivery_date" id="delivery-date">
112
+ ```
113
+
114
+ Cally does not write to a form itself. Its `change` event carries the chosen date in the calendar's `value`, so a few lines of script copy it into the hidden input:
115
+
116
+ ```html
117
+ <script>
118
+ document.getElementById("delivery-calendar").addEventListener("change", (event) => {
119
+ document.getElementById("delivery-date").value = event.target.value;
120
+ });
121
+ </script>
122
+ ```
123
+
124
+ For a range the same `value` is the two dates joined with a slash, such as `2026-09-01/2026-09-07`.
125
+
126
+ ## Scope & philosophy
127
+
128
+ **What this is.** One Cotton component for each base daisyUI component, and nothing else. A component that daisyUI builds out of other components, or a class that only modifies another component, gets no Cotton component of its own. The validator is one such class: add it to a control through its `class`, or to the OTP's input through `input_class`. Everything here is presentation: templates configured through attributes and themed by whatever daisyUI theme the project runs.
129
+
130
+ **What this deliberately is not.**
131
+
132
+ - **Not an application shell.** No settings, no menu system, no icon registry, no views.
133
+ - **Not page-level layout.** The `hero` container ships, but composed hero sections (the heading, copy and calls to action inside it) and other page sections stay with the project, built from these components.
134
+ - **Not a CSS framework.** daisyUI, its themes and Tailwind's preflight come from the project.
135
+ - **Not a JavaScript layer.** The package ships no scripts. A project that wants behaviour daisyUI's CSS doesn't give, such as smarter dropdown placement, adds it by overriding the component. The calendar is the one component that needs a script to show anything: it is drawn by [Cally](https://github.com/WickyNilliams/cally), which the project loads itself (see [Calendar](#calendar)).
136
+ - **Not coupled to Django objects.** Components take plain values. Wiring one up to a form, a paginator or the messages framework is the project's job.
137
+ - **Not shaped for any particular project.** Nothing here exists because one adopter needed it.
138
+
139
+ **Tie-breaks.** When two of these pull against each other:
140
+
141
+ 1. Following daisyUI beats convenience. A component's attributes use daisyUI's own names for its modifiers rather than a friendlier parallel vocabulary.
142
+ 2. Leaving it to the project beats doing it here. If only some adopters need it, they get it by overriding the component.
143
+ 3. Fewer attributes beat more. Anything a component doesn't need to decide passes straight through to the markup.
144
+
145
+ ## Prior art
146
+
147
+ [labbhq/labb](https://github.com/labbhq/labb) is an actively maintained django-cotton + daisyUI 5 component library covering similar ground. It is a batteries-included framework — its own CLI, reactivity layer, icon system and project scaffolder — rather than a thin base layer, and daisy-cotton's purpose here is narrower: a dependency-free set of base primitives a project drops in alongside its own choices. See [docs/brainstorm.md](https://github.com/SamuelJennings/daisy-cotton/blob/main/docs/brainstorm.md) for the fuller reasoning.
148
+
149
+ ## Contributing
150
+
151
+ To set up a checkout, open the component gallery, run the checks or add a component, see [CONTRIBUTING](https://github.com/SamuelJennings/daisy-cotton/blob/main/CONTRIBUTING.md).
152
+
153
+ ## Changelog
154
+
155
+ See [CHANGELOG.md](https://github.com/SamuelJennings/daisy-cotton/blob/main/CHANGELOG.md).
156
+
157
+ ## License
158
+
159
+ MIT. See [LICENSE](https://github.com/SamuelJennings/daisy-cotton/blob/main/LICENSE).
@@ -0,0 +1,131 @@
1
+ # daisy-cotton
2
+
3
+ [![Tests](https://github.com/SamuelJennings/daisy-cotton/actions/workflows/tests.yml/badge.svg)](https://github.com/SamuelJennings/daisy-cotton/actions/workflows/tests.yml) [![Coverage](https://codecov.io/gh/SamuelJennings/daisy-cotton/branch/main/graph/badge.svg)](https://codecov.io/gh/SamuelJennings/daisy-cotton) ![Python 3.12 | 3.13](https://img.shields.io/badge/python-3.12%20%7C%203.13-blue) ![Django 5.2 | 6.0 | 6.1](https://img.shields.io/badge/django-5.2%20%7C%206.0%20%7C%206.1-blue) [![License: MIT](https://img.shields.io/badge/license-MIT-green)](https://github.com/SamuelJennings/daisy-cotton/blob/main/LICENSE)
4
+
5
+ Base daisyUI-styled django-cotton components: buttons, inputs, cards, alerts and the rest of an application's furniture
6
+
7
+ Built on [daisyUI](https://daisyui.com/) and [django-cotton](https://django-cotton.com/). A project that wants daisyUI-styled Cotton components depends on this package directly: install it, add it to `INSTALLED_APPS`, and each `<c-name>` tag is ready to use. It carries no settings, no menus, no icon registry and no views of its own — see [Scope & philosophy](https://github.com/SamuelJennings/daisy-cotton#scope--philosophy).
8
+
9
+ ## Status
10
+
11
+ Version 0.0.1, pre-1.0: names, attributes and the set of classes a component emits can change between minor versions. The [CHANGELOG](https://github.com/SamuelJennings/daisy-cotton/blob/main/CHANGELOG.md) is how a project finds out what has landed.
12
+
13
+ Eighty-two components are built so far: `accordion`, `alert`, `avatar`, `badge`, `breadcrumbs`, `button`, `card`, `carousel`, `chat`, `collapse`, `countdown`, `diff`, `divider`, `dock`, `drawer`, `dropdown`, `fab`, `footer`, `form.calendar`, `form.checkbox`, `form.fieldset`, `form.file-input`, `form.filter`, `form.input`, `form.label`, `form.otp`, `form.radio`, `form.range`, `form.rating`, `form.select`, `form.textarea`, `form.toggle`, `hero`, `hover-3d`, `hover-gallery`, `icon`, `indicator`, `join`, `kbd`, `link`, `list`, `loading`, `mask`, `megamenu`, `menu`, `modal`, `navbar`, `progress`, `radial-progress`, `skeleton`, `stack`, `stat`, `status`, `steps`, `swap`, `table`, `tabs`, `text-rotate`, `timeline`, `toast`, `tooltip` and `mockup.*`. Pagination has no component: daisyUI builds it from `join` and `btn` and gives it no class of its own, so write it with those two. Aura has no component either: it only decorates another element, so wrap the component to highlight in a `<div class="aura">` with daisyUI's style and size classes. Each one is documented live in the component gallery (`python manage.py runserver` from a checkout). More land as the need arises.
14
+
15
+ `<c-icon>` renders `name` as a literal CSS class string and resolves nothing itself — a project wanting name-based icon resolution provides its own override (see [docs/adr/0001](https://github.com/SamuelJennings/daisy-cotton/blob/main/docs/adr/0001-icon-is-an-extension-point.md)).
16
+
17
+ `<c-alert>` takes `variant` (info, success, warning, error), `soft`/`outline`/`dash` for style, and `horizontal`/`vertical` for direction, each accepting a breakpoint such as `sm`; a caller-given `role` replaces the default `role="alert"`, so `role="status"` gives a polite announcement instead of an interruption. Its icon and dismiss button are drawn by `<c-icon>` and `<c-button>`; the dismiss button's accessible name is the translatable "Dismiss" with its glyph hidden from assistive technology. `dismissible` and `delay` need [Alpine.js](https://alpinejs.dev/) on the page — this package doesn't ship or load it. Without Alpine, the alert still renders and reads fine, but the dismiss button does nothing and `delay` never fires.
18
+
19
+ `<c-toast>` pins its content to a corner or edge of the screen and has no role or live region of its own, so put alerts inside it and each keeps its own. A project rendering Django's messages framework writes:
20
+
21
+ ```django
22
+ <c-toast placement="top end">
23
+ {% for message in messages %}
24
+ <c-alert variant="{{ message.level_tag }}" dismissible>{{ message }}</c-alert>
25
+ {% endfor %}
26
+ </c-toast>
27
+ ```
28
+
29
+ Django's `debug` level tag has no matching alert colour, so a debug message falls back to the plain alert.
30
+
31
+ ## Requirements
32
+
33
+ - Python 3.12+
34
+ - Django 5.2, 6.0 or 6.1
35
+ - django-cotton 2.6+
36
+ - daisyUI 5, loaded by the project
37
+
38
+ daisyUI is a hard requirement and this package does not ship it. Any project already running daisyUI satisfies it, through whatever Tailwind build the project already has.
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ pip install daisy-cotton
44
+ ```
45
+
46
+ Add it to `INSTALLED_APPS`:
47
+
48
+ ```python
49
+ INSTALLED_APPS = [
50
+ ...,
51
+ "django_cotton",
52
+ "daisy_cotton",
53
+ ]
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ Each component is a Cotton tag named after its daisyUI component, configured through attributes that use daisyUI's own modifier names:
59
+
60
+ ```html
61
+ <c-card title="Storage" border>
62
+ Almost full.
63
+ <c-slot name="actions">
64
+ <c-button variant="primary" size="sm" text="Upgrade" />
65
+ </c-slot>
66
+ </c-card>
67
+ ```
68
+
69
+ Classes passed with `class` are added to the component's own, and any other attribute passes through to its root element.
70
+
71
+ ## Calendar
72
+
73
+ `<c-form.calendar>` writes Cally's `<calendar-date>` element, or `<calendar-range>` with `range`, carrying daisyUI's `cally` class. It shows nothing until the project loads Cally, and this package does not. Add the module script to the page's head, pinning the version you have tested or hosting the file yourself:
74
+
75
+ ```html
76
+ <script type="module" src="https://unpkg.com/cally@0.9.2"></script>
77
+ ```
78
+
79
+ Cally's own attributes (`value`, `min`, `max`, `locale`, `first-day-of-week`) go on the tag and reach the calendar unchanged, `months="2"` shows two months side by side, and `class` is added to the calendar's own. The previous and next buttons hold an icon drawn by `<c-icon>` and a visually hidden name, so pass icon classes through `previous_icon` and `next_icon` unless your project's `<c-icon>` resolves names:
80
+
81
+ ```html
82
+ <c-form.calendar id="delivery-calendar" min="2026-09-01" previous_icon="bi bi-chevron-left" next_icon="bi bi-chevron-right" />
83
+ <input type="hidden" name="delivery_date" id="delivery-date">
84
+ ```
85
+
86
+ Cally does not write to a form itself. Its `change` event carries the chosen date in the calendar's `value`, so a few lines of script copy it into the hidden input:
87
+
88
+ ```html
89
+ <script>
90
+ document.getElementById("delivery-calendar").addEventListener("change", (event) => {
91
+ document.getElementById("delivery-date").value = event.target.value;
92
+ });
93
+ </script>
94
+ ```
95
+
96
+ For a range the same `value` is the two dates joined with a slash, such as `2026-09-01/2026-09-07`.
97
+
98
+ ## Scope & philosophy
99
+
100
+ **What this is.** One Cotton component for each base daisyUI component, and nothing else. A component that daisyUI builds out of other components, or a class that only modifies another component, gets no Cotton component of its own. The validator is one such class: add it to a control through its `class`, or to the OTP's input through `input_class`. Everything here is presentation: templates configured through attributes and themed by whatever daisyUI theme the project runs.
101
+
102
+ **What this deliberately is not.**
103
+
104
+ - **Not an application shell.** No settings, no menu system, no icon registry, no views.
105
+ - **Not page-level layout.** The `hero` container ships, but composed hero sections (the heading, copy and calls to action inside it) and other page sections stay with the project, built from these components.
106
+ - **Not a CSS framework.** daisyUI, its themes and Tailwind's preflight come from the project.
107
+ - **Not a JavaScript layer.** The package ships no scripts. A project that wants behaviour daisyUI's CSS doesn't give, such as smarter dropdown placement, adds it by overriding the component. The calendar is the one component that needs a script to show anything: it is drawn by [Cally](https://github.com/WickyNilliams/cally), which the project loads itself (see [Calendar](#calendar)).
108
+ - **Not coupled to Django objects.** Components take plain values. Wiring one up to a form, a paginator or the messages framework is the project's job.
109
+ - **Not shaped for any particular project.** Nothing here exists because one adopter needed it.
110
+
111
+ **Tie-breaks.** When two of these pull against each other:
112
+
113
+ 1. Following daisyUI beats convenience. A component's attributes use daisyUI's own names for its modifiers rather than a friendlier parallel vocabulary.
114
+ 2. Leaving it to the project beats doing it here. If only some adopters need it, they get it by overriding the component.
115
+ 3. Fewer attributes beat more. Anything a component doesn't need to decide passes straight through to the markup.
116
+
117
+ ## Prior art
118
+
119
+ [labbhq/labb](https://github.com/labbhq/labb) is an actively maintained django-cotton + daisyUI 5 component library covering similar ground. It is a batteries-included framework — its own CLI, reactivity layer, icon system and project scaffolder — rather than a thin base layer, and daisy-cotton's purpose here is narrower: a dependency-free set of base primitives a project drops in alongside its own choices. See [docs/brainstorm.md](https://github.com/SamuelJennings/daisy-cotton/blob/main/docs/brainstorm.md) for the fuller reasoning.
120
+
121
+ ## Contributing
122
+
123
+ To set up a checkout, open the component gallery, run the checks or add a component, see [CONTRIBUTING](https://github.com/SamuelJennings/daisy-cotton/blob/main/CONTRIBUTING.md).
124
+
125
+ ## Changelog
126
+
127
+ See [CHANGELOG.md](https://github.com/SamuelJennings/daisy-cotton/blob/main/CHANGELOG.md).
128
+
129
+ ## License
130
+
131
+ MIT. See [LICENSE](https://github.com/SamuelJennings/daisy-cotton/blob/main/LICENSE).
@@ -0,0 +1,3 @@
1
+ """Base daisyUI-styled django-cotton components."""
2
+
3
+ __version__ = "0.0.1"
@@ -0,0 +1,12 @@
1
+ """App configuration for daisy-cotton."""
2
+
3
+ from django.apps import AppConfig
4
+ from django.utils.translation import gettext_lazy as _
5
+
6
+
7
+ class DaisyCottonConfig(AppConfig):
8
+ """Django app config for the daisy-cotton component library."""
9
+
10
+ name = "daisy_cotton"
11
+ label = "daisy_cotton"
12
+ verbose_name = _("Daisy Cotton components")
@@ -0,0 +1,7 @@
1
+ {# @description A collapse used as an accordion item: items sharing a name form one group where opening one closes the others. In a browser without grouped <details> support, more than one item can stay open; give at most one item per group open. Accepts every collapse attribute and slot (arrow, plus, open, class, the title slot). See the card's gallery entry for a working group. #}
2
+ {# @prop name:text | required | description:"Group name. Items sharing one form an exclusive group; an item given no name is not part of a group." #}
3
+ {# @prop title:text | description:"Heading text, re-passed as the collapse's title slot. A title is expected: leaving both this and the title slot empty renders an unnamed control, an empty summary. Fill the title slot instead for rich content." #}
4
+ {# @slot A short answer. — The item's content, forwarded to the collapse. #}
5
+ {# @slot:title — A heading in place of the title attribute, for rich content such as an icon or badge. #}
6
+ <c-vars name="" title="" />
7
+ <c-collapse name="{{ name }}" :attrs="attrs">{% if title %}<c-slot name="title">{{ title }}</c-slot>{% endif %}{{ slot }}</c-collapse>
@@ -0,0 +1,23 @@
1
+ {# @description A message banner for the result of an action, with an optional icon and an optional dismiss button. dismissible and delay both need Alpine.js on the page. Avoid delay on errors or on anything the reader must act on — the message can disappear before they've read it. See the toast entry for an alert shown with an icon and a dismissible alert. #}
2
+ {# @prop variant:select['info','success','warning','error'] | description:"Colour variant. Also picks the icon when none is given." #}
3
+ {# @prop icon:text | description:"Icon shown before the message, passed as the name of the icon component. Defaults to an icon named after variant." #}
4
+ {# @prop soft:boolean | description:"Use the soft style." #}
5
+ {# @prop outline:boolean | description:"Draw the alert as an outline." #}
6
+ {# @prop dash:boolean | description:"Use a dashed border." #}
7
+ {# @prop horizontal:select['sm','md','lg','xl','2xl'] | description:"Lay the alert out horizontally. The bare attribute applies it at every width, which this select cannot set." #}
8
+ {# @prop vertical:select['sm','md','lg','xl','2xl'] | description:"Stack the alert vertically. The bare attribute applies it at every width, which this select cannot set." #}
9
+ {# @prop dismissible:boolean | description:"Add a dismiss button that hides the alert." #}
10
+ {# @prop delay:number | description:"Milliseconds before a dismissible alert hides itself." #}
11
+ {# @prop role:text | default:"alert" | description:"Interrupts a screen reader by default. Pass role=\"status\" for a message that should be announced politely." #}
12
+ {# @prop class:text | description:"Extra classes added to the alert." #}
13
+ {# @slot Saved. — The alert message. #}
14
+ {% load i18n daisy_cotton %}
15
+ <c-vars variant="" icon="" soft="" outline="" dash="" horizontal="" vertical="" dismissible="" delay="" role="alert" class="" />
16
+ {% trans "Dismiss" as dismiss_label %}
17
+ {# djlint:off #}
18
+ <div role="{{ role }}" class="alert {% variation variant "alert" "info,success,warning,error" %}{% if soft %} alert-soft{% endif %}{% if outline %} alert-outline{% endif %}{% if dash %} alert-dash{% endif %} {% responsive horizontal "alert-horizontal" %} {% responsive vertical "alert-vertical" %} {{ class }}"{% if dismissible %} x-data="{ show: true }" x-show="show" x-transition{% with ms=delay|add:0 %}{% if ms != "" %} x-init="setTimeout(() => show = false, {{ ms }})"{% endif %}{% endwith %}{% endif %} {{ attrs }}>
19
+ {% if icon %}<c-icon name="{{ icon }}" class="" aria-hidden="true" />{% elif variant %}<c-icon name="{{ variant }}" class="" aria-hidden="true" />{% endif %}
20
+ {{ slot }}
21
+ {% if dismissible %}<c-button type="button" ghost size="xs" circle x-on:click="show = false" aria-label="{{ dismiss_label }}"><span aria-hidden="true">✕</span></c-button>{% endif %}
22
+ </div>
23
+ {# djlint:on #}
@@ -0,0 +1,5 @@
1
+ {# @description A row of overlapping avatars. #}
2
+ {# @prop class:text | description:"Extra classes added to the group, such as the overlap (for example -space-x-6, as daisyUI's examples use). This is Tailwind's own class, so it needs the project's Tailwind build to see it, like any class a caller writes." #}
3
+ {# @slot <c-avatar src="..." alt="Ada Lovelace" content_class="w-12 rounded-full" /><c-avatar placeholder="BM" content_class="w-16 rounded-xl" /><c-avatar content_class="w-10 rounded" /> — Several avatar widths and shapes: one photo, one placeholder, one silhouette. #}
4
+ <c-vars class="" />
5
+ <div class="avatar-group {{ class }}" {{ attrs }}>{{ slot }}</div>
@@ -0,0 +1,29 @@
1
+ {# @description daisyUI's avatar: a photo, initials, or a silhouette when neither is given, with an optional online or offline indicator. Give alt when the avatar is the only thing identifying the person — beside a name it is usually noise. Width, shape and placeholder colour go through content_class, not a size or variant attribute. #}
2
+ {# @prop src:text | description:"URL of a profile photo. Falls back to placeholder text, then to a silhouette. This package resolves no URL itself; pass the resolved URL in." #}
3
+ {# @prop alt:text | description:"Alt text of the photo. Leave empty unless the avatar is the only thing identifying the person." #}
4
+ {# @prop placeholder:text | description:"Initials or short text shown when there is no src." #}
5
+ {# @prop online:boolean | description:"Presence indicator: avatar-online." #}
6
+ {# @prop offline:boolean | description:"Presence indicator: avatar-offline." #}
7
+ {# @prop content_class:text | description:"Extra classes for the image frame, replacing the w-12 rounded-full default (plus bg-neutral text-neutral-content with no src) entirely. Sets the avatar's width and shape." #}
8
+ {# @prop class:text | description:"Extra classes added to the avatar." #}
9
+ <c-vars src="" alt="" placeholder="" online="" offline="" content_class="" class="" />
10
+ <div class="avatar{% if not src %} avatar-placeholder{% endif %}{% if online %} avatar-online{% endif %}{% if offline %} avatar-offline{% endif %} {{ class }}"
11
+ {{ attrs }}>
12
+ <div class="{% if content_class %}{{ content_class }}{% else %}w-12 rounded-full{% if not src %} bg-neutral text-neutral-content{% endif %}{% endif %}">
13
+ {% if src %}
14
+ <img src="{{ src }}" alt="{{ alt }}" />
15
+ {% elif placeholder %}
16
+ <span>{{ placeholder }}</span>
17
+ {% else %}
18
+ <svg xmlns="http://www.w3.org/2000/svg"
19
+ width="80%"
20
+ height="80%"
21
+ fill="currentColor"
22
+ viewBox="0 0 16 16"
23
+ aria-hidden="true"
24
+ focusable="false">
25
+ <path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6" />
26
+ </svg>
27
+ {% endif %}
28
+ </div>
29
+ </div>
@@ -0,0 +1,13 @@
1
+ {# @description A small label, usually a status, a count or a tag. Shows text, then the default slot. #}
2
+ {# @prop text:text | description:"Badge text, shown before the default slot." #}
3
+ {# @prop variant:select['neutral','primary','secondary','accent','info','success','warning','error'] | description:"Colour variant. Leave empty for the default colour." #}
4
+ {# @prop size:select['xs','sm','md','lg','xl'] | description:"Badge size." #}
5
+ {# @prop outline:boolean | description:"Draw the badge as an outline." #}
6
+ {# @prop dash:boolean | description:"Draw the badge with a dashed border." #}
7
+ {# @prop soft:boolean | description:"Use the soft style." #}
8
+ {# @prop ghost:boolean | description:"Draw the badge without a background." #}
9
+ {# @prop class:text | description:"Extra classes added to the badge." #}
10
+ {# @slot New — Content shown after the text. #}
11
+ {% load daisy_cotton %}
12
+ <c-vars text="" variant="" size="" outline="" dash="" soft="" ghost="" class="" />
13
+ <span class="badge {% variation variant "badge" "neutral,primary,secondary,accent,info,success,warning,error" %} {% variation size "badge" "xs,sm,md,lg,xl" %}{% if outline %} badge-outline{% endif %}{% if dash %} badge-dash{% endif %}{% if soft %} badge-soft{% endif %}{% if ghost %} badge-ghost{% endif %} {{ class }}" {{ attrs }}>{{ text }}{{ slot }}</span>
@@ -0,0 +1,19 @@
1
+ {# @description A breadcrumb trail. Pass items to build it from data, or fill the default slot with breadcrumbs.item components; each item is one step of the trail. #}
2
+ {# @prop items:text | description:"A list of dictionaries, each holding the attributes of one breadcrumbs.item (text, href, class). When given, the default slot is not shown." #}
3
+ {# @prop class:text | description:"Extra classes added to the trail." #}
4
+ {# @prop aria-label:text | description:"Accessible name of the trail. Defaults to a translated Breadcrumbs." #}
5
+ {# @slot — The trail's steps, as breadcrumbs.item components. Shown when no items are passed. #}
6
+ {% load i18n %}
7
+ <c-vars items class aria-label />
8
+ {# `only` is load-bearing: a Cotton child reads a prop it wasn't given (here `class`) from the parent, so every <li> would get the trail's class (#3). #}
9
+ <nav class="breadcrumbs {{ class }}"
10
+ aria-label="{% if aria_label %}{{ aria_label }}{% else %}{% trans "Breadcrumbs" %}{% endif %}"
11
+ {{ attrs }}>
12
+ <ul>
13
+ {% if items %}
14
+ {% for item in items %}<c-breadcrumbs.item :attrs="item" only />{% endfor %}
15
+ {% else %}
16
+ {{ slot }}
17
+ {% endif %}
18
+ </ul>
19
+ </nav>
@@ -0,0 +1,13 @@
1
+ {# @description One step of a breadcrumb trail, used inside breadcrumbs. Renders as a link when an href is given, and as the current page otherwise. Attributes other than the ones below land on the list item. #}
2
+ {# @prop text:text | description:"The step's label." #}
3
+ {# @prop class:text | description:"Extra classes added to the list item." #}
4
+ {# @prop href:text | description:"Link address. Without it the step is the current page and not a link." #}
5
+ {# @slot — Extra content shown after the label. #}
6
+ <c-vars text class href />
7
+ <li class="{{ class }}" {{ attrs }}>
8
+ {% if href %}
9
+ <a href="{{ href }}">{{ text }}{{ slot }}</a>
10
+ {% else %}
11
+ <span aria-current="page">{{ text }}{{ slot }}</span>
12
+ {% endif %}
13
+ </li>
@@ -0,0 +1,46 @@
1
+ {# @description A button, or a link styled as one when an href is passed. Shows an optional icon and text, then the default slot. An icon-only button has no accessible name of its own — give it one with aria-label. #}
2
+ {# @prop href:text | description:"When given, the button renders as a link with this href instead of a <button>." #}
3
+ {# @prop text:text | description:"Button label, shown in a span after the icon and before the default slot." #}
4
+ {# @prop icon:text | description:"Icon shown before the text, passed as the name of the icon component. Always hidden from assistive technology." #}
5
+ {# @prop variant:select['neutral','primary','secondary','accent','info','success','warning','error'] | description:"Colour variant. Leave empty for the default colour." #}
6
+ {# @prop size:select['xs','sm','md','lg','xl'] | description:"Button size." #}
7
+ {# @prop outline:boolean | description:"Draw the button as an outline." #}
8
+ {# @prop dash:boolean | description:"Draw the button with a dashed outline." #}
9
+ {# @prop soft:boolean | description:"Draw the button with a soft, tinted background." #}
10
+ {# @prop ghost:boolean | description:"Draw the button with no background until hovered." #}
11
+ {# @prop link:boolean | description:"Draw the button styled as a plain link." #}
12
+ {# @prop active:boolean | description:"Force the button's active (pressed) state." #}
13
+ {# @prop disabled:boolean | description:"Disable the button. On a link this adds btn-disabled, aria-disabled, role=button and tabindex=-1 instead of the native attribute." #}
14
+ {# @prop wide:boolean | description:"Widen the button." #}
15
+ {# @prop block:boolean | description:"Stretch the button to the full width of its container." #}
16
+ {# @prop square:boolean | description:"Make the button a fixed-size square, for a single icon." #}
17
+ {# @prop circle:boolean | description:"Make the button a fixed-size circle, for a single icon." #}
18
+ {# @prop class:text | description:"Extra classes added to the button." #}
19
+ {# @slot Save — Content shown after the icon and text. #}
20
+ {% load daisy_cotton %}
21
+ <c-vars href=""
22
+ text=""
23
+ icon=""
24
+ variant=""
25
+ size=""
26
+ outline=""
27
+ dash=""
28
+ soft=""
29
+ ghost=""
30
+ link=""
31
+ active=""
32
+ disabled=""
33
+ wide=""
34
+ block=""
35
+ square=""
36
+ circle=""
37
+ class="" />
38
+ {# djlint:off #}
39
+ {% with element=href|yesno:"a,button" %}
40
+ <{{ element }}{% if href %} href="{{ href }}"{% endif %} class="btn {% variation variant "btn" "neutral,primary,secondary,accent,info,success,warning,error" %} {% variation size "btn" "xs,sm,md,lg,xl" %}{% if outline %} btn-outline{% endif %}{% if dash %} btn-dash{% endif %}{% if soft %} btn-soft{% endif %}{% if ghost %} btn-ghost{% endif %}{% if link %} btn-link{% endif %}{% if active %} btn-active{% endif %}{% if wide %} btn-wide{% endif %}{% if block %} btn-block{% endif %}{% if square %} btn-square{% endif %}{% if circle %} btn-circle{% endif %}{% if disabled and href %} btn-disabled{% endif %} {{ class }}"{% if disabled %}{% if href %} aria-disabled="true" role="button" tabindex="-1"{% else %} disabled{% endif %}{% endif %} {{ attrs }}>
41
+ {% if icon %}<c-icon name="{{ icon }}" aria-hidden="true" />{% endif %}
42
+ {% if text %}<span>{{ text }}</span>{% endif %}
43
+ {{ slot }}
44
+ </{{ element }}>
45
+ {# djlint:on #}
46
+ {% endwith %}
@@ -0,0 +1,26 @@
1
+ {# @description daisyUI's card: an optional figure, a body and an optional title and actions row. Every part is optional; it renders only what it is given. #}
2
+ {# @prop title:text | description:"Heading text, shown as the card-title. Fill the title slot instead for an icon or badge alongside it." #}
3
+ {# @prop figure:text | description:"Content shown in a <figure> before the body, usually an image. Fill the figure slot for markup." #}
4
+ {# @prop actions:text | description:"Content shown in a card-actions row at the foot of the body, usually buttons. Fill the actions slot for markup." #}
5
+ {# @prop size:select['xs','sm','md','lg','xl'] | description:"Card size." #}
6
+ {# @prop border:boolean | description:"Draw the card with a border instead of a shadow." #}
7
+ {# @prop dash:boolean | description:"Draw the card with a dashed border." #}
8
+ {# @prop side:select['sm','md','lg','xl','2xl'] | description:"Lay the figure beside the body instead of above it. The bare attribute applies it at every width, which this select cannot set." #}
9
+ {# @prop image-full:boolean | description:"Let the figure fill the card and place the body over it." #}
10
+ {# @prop content_class:text | description:"Extra classes added to the card body." #}
11
+ {# @prop class:text | description:"Extra classes added to the card surface." #}
12
+ {# @slot <c-accordion name="shipping" title="Do you ship internationally?">Yes, to most countries.</c-accordion><c-accordion name="shipping" title="How long does delivery take?">Three to five business days.</c-accordion><c-accordion name="returns" class="bg-base-100 border border-base-300" title="What is your return policy?">Items can be returned within 30 days.</c-accordion><c-accordion name="returns" class="bg-base-100 border border-base-300" title="Do you offer refunds?">Yes, to the original payment method.</c-accordion> — An FAQ: two accordion groups, one plain and one bordered. #}
13
+ {# @slot:title — A heading with card-title, in place of the title attribute. An icon-only title needs an accessible name of its own. #}
14
+ {# @slot:figure <c-hover_gallery><img src="https://img.daisyui.com/images/stock/daisyui-hat-1.webp" alt="A brimmed felt hat"><img src="https://img.daisyui.com/images/stock/daisyui-hat-2.webp" alt="A knit beanie"><img src="https://img.daisyui.com/images/stock/daisyui-hat-3.webp" alt="A straw sun hat"><img src="https://img.daisyui.com/images/stock/daisyui-hat-4.webp" alt="A baseball cap"></c-hover_gallery> — Content in a <figure> before the body, here a gallery of four images. #}
15
+ {# @slot:actions <c-button text="Cart "><c-badge variant="secondary">3</c-badge></c-button> — Content in a card-actions row at the foot of the body. #}
16
+ {% load daisy_cotton %}
17
+ <c-vars title="" figure="" actions="" size="" border="" dash="" side="" image-full="" content_class="" class="" />
18
+ <div class="card {% variation size "card" "xs,sm,md,lg,xl" %}{% if border %} card-border{% endif %}{% if dash %} card-dash{% endif %} {% responsive side "card-side" %}{% if image_full %} image-full{% endif %} {{ class }}"
19
+ {{ attrs }}>
20
+ {% if figure %}<figure>{{ figure }}</figure>{% endif %}
21
+ <div class="card-body {{ content_class }}">
22
+ {% if title %}<h2 class="card-title">{{ title }}</h2>{% endif %}
23
+ {{ slot }}
24
+ {% if actions %}<div class="card-actions">{{ actions }}</div>{% endif %}
25
+ </div>
26
+ </div>
@@ -0,0 +1,20 @@
1
+ {# @description daisyUI's carousel: a scrollable, snapping row or column of slides. With no controls of its own it is a focusable, named region, so keyboard users can tab to it and scroll it with the arrow keys, and screen readers announce it as a carousel of slides. Fill the default slot with carousel.item components. See the mockup.browser entry for a named carousel with previous/next and indicator controls. #}
2
+ {# @prop snap:select['start','center','end'] | description:"Where the slides snap to." #}
3
+ {# @prop horizontal:select['sm','md','lg','xl','2xl'] | description:"Scroll horizontally. The bare attribute applies it at every width, which this select cannot set." #}
4
+ {# @prop vertical:select['sm','md','lg','xl','2xl'] | description:"Scroll vertically. The bare attribute applies it at every width, which this select cannot set." #}
5
+ {# @prop aria-label:text | description:"Accessible name of the carousel. No default: the component cannot invent one, so give it one or the region is unnamed." #}
6
+ {# @prop class:text | description:"Extra classes added to the carousel." #}
7
+ {# @slot <c-carousel.item id="gallery-slide-1" class="relative w-full"><img class="w-full" src="https://img.daisyui.com/images/stock/photo-1625726411847-8cbb60cc71e6.webp" alt="A city skyline at dusk"><div class="absolute flex -translate-y-1/2 transform justify-between left-5 right-5 top-1/2"><c-button href="#gallery-slide-4" circle aria-label="Previous slide" text="❮" /><c-button href="#gallery-slide-2" circle aria-label="Next slide" text="❯" /></div></c-carousel.item><c-carousel.item id="gallery-slide-2" class="relative w-full"><img class="w-full" src="https://img.daisyui.com/images/stock/photo-1609621838510-5ad474b7d25d.webp" alt="A mountain trail in autumn"><div class="absolute flex -translate-y-1/2 transform justify-between left-5 right-5 top-1/2"><c-button href="#gallery-slide-1" circle aria-label="Previous slide" text="❮" /><c-button href="#gallery-slide-3" circle aria-label="Next slide" text="❯" /></div></c-carousel.item><c-carousel.item id="gallery-slide-3" class="relative w-full"><img class="w-full" src="https://img.daisyui.com/images/stock/photo-1414694762283-acccc27bca85.webp" alt="A row of colourful houses"><div class="absolute flex -translate-y-1/2 transform justify-between left-5 right-5 top-1/2"><c-button href="#gallery-slide-2" circle aria-label="Previous slide" text="❮" /><c-button href="#gallery-slide-4" circle aria-label="Next slide" text="❯" /></div></c-carousel.item><c-carousel.item id="gallery-slide-4" class="relative w-full"><img class="w-full" src="https://img.daisyui.com/images/stock/photo-1665553365602-b2fb8e5d1707.webp" alt="Ocean waves at sunset"><div class="absolute flex -translate-y-1/2 transform justify-between left-5 right-5 top-1/2"><c-button href="#gallery-slide-3" circle aria-label="Previous slide" text="❮" /><c-button href="#gallery-slide-1" circle aria-label="Next slide" text="❯" /></div></c-carousel.item> — Four full-width slides with daisyUI's previous/next pattern: each slide's controls are c-button href links to a neighbouring slide's id, drawn over the image. #}
8
+ {% comment %}
9
+ Previous/next and indicator links to a slide's id sit beside the carousel,
10
+ not in it, and following one also scrolls the page to the carousel. The
11
+ gallery's inline preview cannot follow them; use this entry's raw view.
12
+ {% endcomment %}
13
+ {% load i18n daisy_cotton %}
14
+ <c-vars snap="" horizontal="" vertical="" aria-label="" class="" />
15
+ <div class="carousel {% variation snap "carousel" "start,center,end" %} {% responsive horizontal "carousel-horizontal" %} {% responsive vertical "carousel-vertical" %} {{ class }}"
16
+ role="region"
17
+ tabindex="0"
18
+ aria-roledescription="{% trans "carousel" %}"
19
+ {% if aria_label %}aria-label="{{ aria_label }}"{% endif %}
20
+ {{ attrs }}>{{ slot }}</div>