daisyui 2.0.2 → 2.1.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +140 -21
- data/README.md +156 -20
- data/data/daisyui/tailwind_manifest.json +2278 -0
- data/exe/daisyui-tailwind +6 -0
- data/lib/daisy_ui/base.rb +45 -9
- data/lib/daisy_ui/class_merge/configuration.rb +18 -3
- data/lib/daisy_ui/class_merge/daisy_groups.rb +8 -5
- data/lib/daisy_ui/class_merge/tailwind_config.rb +8 -18
- data/lib/daisy_ui/class_merge/validators.rb +4 -0
- data/lib/daisy_ui/class_merge.rb +23 -12
- data/lib/daisy_ui/configurable/report_log.rb +36 -0
- data/lib/daisy_ui/configurable.rb +81 -16
- data/lib/daisy_ui/engine.rb +7 -0
- data/lib/daisy_ui/mcp_server.rb +1 -0
- data/lib/daisy_ui/shareable.rb +56 -0
- data/lib/daisy_ui/store.rb +71 -0
- data/lib/daisy_ui/tailwind/candidate.rb +44 -0
- data/lib/daisy_ui/tailwind/command.rb +85 -0
- data/lib/daisy_ui/tailwind/lexer.rb +31 -0
- data/lib/daisy_ui/tailwind/manifest.rb +59 -0
- data/lib/daisy_ui/tailwind/manifest_builder.rb +86 -0
- data/lib/daisy_ui/tailwind/sources.rb +103 -0
- data/lib/daisy_ui/tailwind/unknown_component_error.rb +17 -0
- data/lib/daisy_ui/tailwind/usage.rb +72 -0
- data/lib/daisy_ui/tailwind.rb +47 -0
- data/lib/daisy_ui/updated_at.rb +1 -1
- data/lib/daisy_ui/version.rb +1 -1
- metadata +16 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 75952f05719457c52d7085643cfeebc3b0dd2f72e4ddfc768d1ba7468431c161
|
|
4
|
+
data.tar.gz: 9029feca27ce0d586ad608c23170afcb7bafc1f17998af22793a2b39ce8c1ce3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 206f1d5f22c5ac7d41df14f1984fedfa70056b5128aa97ff3affb1bb5607cb6cfe1e7c92899c469b70e763976f5fa1c300fa9dcd18f3c10fd9dd10e41734af98
|
|
7
|
+
data.tar.gz: b65a346205a5fe198a858b3de5e191f20ee909fbe86c565e3d8aee87680ac9a1c2bf5ee681d6fdf698700063e271534ad766ac1afecfdf63ceb43557d03922b5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,78 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
### Tailwind sources for only the components an app uses
|
|
4
|
+
|
|
5
|
+
`bundle exec daisyui-tailwind app -o app/assets/stylesheets/generated/daisyui.css`
|
|
6
|
+
writes the Tailwind sources for the DaisyUI components an app's Ruby and
|
|
7
|
+
templates reference, plus the components those render (Dropdown renders
|
|
8
|
+
Button and Menu): one `@source inline("…")` per component, for the Tailwind
|
|
9
|
+
entry to `@import`. See the README's "Tailwind sources".
|
|
10
|
+
|
|
11
|
+
- Smaller: pointing `@source` at the whole gem hands Tailwind every class of
|
|
12
|
+
every component and ClassMerge's catalogue of Tailwind utilities. On an app
|
|
13
|
+
using 33 of the 77 components the gem's share of the CSS went from 210 KB to
|
|
14
|
+
126 KB (32 → 19 KB gzipped).
|
|
15
|
+
- More complete: Tailwind v4 drops Ruby comments when it scans a `.rb` file
|
|
16
|
+
and cannot see a Symbol component class (`self.component_class = :navbar`),
|
|
17
|
+
so a whole-gem scan generated no `.navbar`, `.card` or `.drawer` rule, nor
|
|
18
|
+
the rules daisyUI nests under them (`indicator-item`, `stack-top`), unless
|
|
19
|
+
the app spelled the class out itself. The generated sources carry them.
|
|
20
|
+
- No path in the output, so it is the same on every machine; `--output`
|
|
21
|
+
rewrites the file only when its content changes, so a CSS watcher does not
|
|
22
|
+
loop on it.
|
|
23
|
+
- `--format json` gives a build script the components, their classes and
|
|
24
|
+
their absolute files. From Ruby, `DaisyUI::Tailwind.sources(scan: ["app"])`
|
|
25
|
+
returns the CSS (`format: :json` for the JSON), and
|
|
26
|
+
`DaisyUI::Tailwind.used_components(scan: ["app"])` the component names.
|
|
27
|
+
- `--responsive sm,md,lg` adds breakpoint variants of each component class and
|
|
28
|
+
modifier, for apps that render `responsive:` modifiers (off by default: it
|
|
29
|
+
multiplies the CSS). `--prefix` matches `DaisyUI.configuration.prefix`,
|
|
30
|
+
which `DaisyUI::Tailwind.sources` uses by default.
|
|
31
|
+
- The manifest behind it, `data/daisyui/tailwind_manifest.json`, lists every
|
|
32
|
+
component's class, daisyUI name, file, the components it renders and its
|
|
33
|
+
classes. It is built from the components (`rake tailwind:manifest`) and a
|
|
34
|
+
spec fails when it is stale. It lives in the gem's data dir, not `lib/`:
|
|
35
|
+
an app that keeps scanning the gem's `lib/` builds the same CSS as before.
|
|
36
|
+
|
|
37
|
+
## [2.1.0] - 2026-10-15
|
|
38
|
+
|
|
39
|
+
### DaisyUI finalizes itself at boot: class merging in any Ractor (#58)
|
|
40
|
+
|
|
41
|
+
At boot DaisyUI now freezes its configuration and every component's
|
|
42
|
+
registries, so a non-main Ractor can read them. `DaisyUI::ClassMerge.merge`
|
|
43
|
+
then works in any Ractor; each Ractor builds its own merger and LRU.
|
|
44
|
+
|
|
45
|
+
- Automatic: `DaisyUI.configure` finalizes at its end, and the Rails engine
|
|
46
|
+
finalizes again in `after_initialize`, with no app code. A Rails-less app
|
|
47
|
+
that never calls `configure` calls `DaisyUI.finalize!` at the end of boot.
|
|
48
|
+
- **The configuration is frozen after `DaisyUI.configure` (and, in a Rails
|
|
49
|
+
app, after boot).** Writing to `DaisyUI.configuration` directly now raises
|
|
50
|
+
`FrozenError`, e.g. `DaisyUI.configuration.unknown_modifiers = :ignore` in a
|
|
51
|
+
spec: use `DaisyUI.configure { |config| config.unknown_modifiers = :ignore }`.
|
|
52
|
+
`DaisyUI.configure` can be called again at any time: it yields a writable
|
|
53
|
+
copy and publishes it once that is finalized, so no reader ever meets a
|
|
54
|
+
half-changed configuration, and a block that raises changes nothing. A
|
|
55
|
+
Ractor that already built its merger rebuilds it from the new
|
|
56
|
+
configuration.
|
|
57
|
+
- Finalizing never raises. A configured value that cannot be made shareable
|
|
58
|
+
is kept as it is, unfrozen, and the configuration is then readable on the
|
|
59
|
+
main Ractor only: a callable `unknown_modifiers` or a raw `class_merge`
|
|
60
|
+
validator that closes over app state (such as
|
|
61
|
+
`->(error) { Appsignal.report_error(error) }` in an initializer), or an
|
|
62
|
+
object that holds a logger.
|
|
63
|
+
- Component registries (`register_modifiers`, `register_flags`,
|
|
64
|
+
`self.component_class =`) are frozen as they are written, so a component
|
|
65
|
+
that loads after boot (lazy loading in development) is readable from any
|
|
66
|
+
Ractor too. Writers now replace them instead of mutating them, and
|
|
67
|
+
mutating one in place raises `FrozenError`.
|
|
68
|
+
- Thread safety: the Tailwind class groups behind `ClassMerge` were built
|
|
69
|
+
with an unguarded `||=` (8 threads built them 8 times); they are now built
|
|
70
|
+
once per Ractor.
|
|
71
|
+
- Rendering components inside a Ractor waits on Phlex
|
|
72
|
+
([yippee-fun/phlex#1055](https://github.com/yippee-fun/phlex/pull/1055)).
|
|
73
|
+
|
|
74
|
+
## [2.0.2] - 2026-10-11
|
|
75
|
+
|
|
3
76
|
### Unknown modifiers are reported (#54)
|
|
4
77
|
|
|
5
78
|
A positional or responsive modifier a component does not know used to render
|
|
@@ -32,6 +105,30 @@ end
|
|
|
32
105
|
(`DaisyUI::Chat#bubble has no modifier :primray`).
|
|
33
106
|
- Keyword booleans are not validated: unknown keywords stay HTML attributes.
|
|
34
107
|
|
|
108
|
+
### Changed
|
|
109
|
+
|
|
110
|
+
- The gem ships minified Stimulus controllers with linked sourcemaps, and the
|
|
111
|
+
importmap pins them without preloading, so with the lazy registration the
|
|
112
|
+
README shows (`lazyLoadControllersFrom`) a page that never uses one never
|
|
113
|
+
fetches it. `daisy_dropdown_controller` 6.1 KB → 2.8 KB (2.4 → 1.3 KB gzipped),
|
|
114
|
+
`daisy_tooltip_controller` 8.8 KB → 5.2 KB (2.4 → 1.8 KB gzipped). The
|
|
115
|
+
`daisy_ui/controllers/*` specifiers and the bundler import paths are unchanged.
|
|
116
|
+
|
|
117
|
+
### Fixed
|
|
118
|
+
|
|
119
|
+
- Modifiers added with `config.modifiers.add(component: X)` now apply to
|
|
120
|
+
subclasses of `X` too; the closest class wins.
|
|
121
|
+
|
|
122
|
+
## [2.0.1] - 2026-10-09
|
|
123
|
+
|
|
124
|
+
### Fixed
|
|
125
|
+
|
|
126
|
+
- Button renders the `disabled` attribute on `button`/`input` elements when given
|
|
127
|
+
`:disabled` or `disabled: true`, so a disabled submit button no longer submits
|
|
128
|
+
its form from the keyboard (#52).
|
|
129
|
+
|
|
130
|
+
## [2.0.0] - 2026-09-30
|
|
131
|
+
|
|
35
132
|
### Upgrading to 2.0
|
|
36
133
|
|
|
37
134
|
Components now merge their classes: when two classes conflict, the later one
|
|
@@ -73,6 +170,35 @@ wins. `Button(:sm, class: "btn-lg")` renders `btn btn-lg` (1.x rendered
|
|
|
73
170
|
app components subclassing `DaisyUI::Base` can do the same.
|
|
74
171
|
`config.modifiers.add` takes `group:` to join one.
|
|
75
172
|
|
|
173
|
+
### Changed
|
|
174
|
+
|
|
175
|
+
- Maintainers cut releases with `bin/release` (`list`, `--dry-run`, `patch`/`minor`/`major`/`X.Y.Z`), which checks the lockfiles for gems that do not accept the new version yet and then drives `rake release`.
|
|
176
|
+
|
|
177
|
+
## [1.3.1] - 2026-08-31
|
|
178
|
+
|
|
179
|
+
### Fixed
|
|
180
|
+
|
|
181
|
+
- Popover tooltips no longer clip arrows that extend beyond the tooltip card.
|
|
182
|
+
|
|
183
|
+
## [1.3.0] - 2026-08-30
|
|
184
|
+
|
|
185
|
+
### Added
|
|
186
|
+
|
|
187
|
+
- `Tooltip` `:popover` modifier for collision-aware tooltips. It renders real
|
|
188
|
+
tooltip content in the browser top layer, opens on hover or focus, flips and
|
|
189
|
+
shifts within the visual viewport, follows scroll/resize while open, and
|
|
190
|
+
exposes `role="tooltip"`/`aria-describedby` semantics. The bundled
|
|
191
|
+
`daisy-tooltip` Stimulus controller is auto-pinned for importmap-rails apps
|
|
192
|
+
and supports a custom controller identifier via `stimulus:`.
|
|
193
|
+
|
|
194
|
+
## [1.2.1] - 2026-07-03
|
|
195
|
+
|
|
196
|
+
- No changes to the gem; this release shipped documentation-site and deploy changes only.
|
|
197
|
+
|
|
198
|
+
## [1.2.0] - 2026-06-26
|
|
199
|
+
|
|
200
|
+
### Added
|
|
201
|
+
|
|
76
202
|
- Aura component (DaisyUI 5.6) with style variants (dual, rainbow, holo, gold, silver, glow) and sizes
|
|
77
203
|
- Megamenu component (DaisyUI 5.6) with wide, full, vertical modifiers, sizes, and active_indicator sub-component
|
|
78
204
|
- OTP component (DaisyUI 5.6) for one-time password inputs with configurable digit count, joined modifier, sizes, and color variants
|
|
@@ -90,34 +216,27 @@ wins. `Button(:sm, class: "btn-lg")` renders `btn btn-lg` (1.x rendered
|
|
|
90
216
|
positioning fallback (Safari < 26, Firefox < 147) and optional roving
|
|
91
217
|
keyboard navigation. The default `:popover` dropdown remains zero-JS, and the
|
|
92
218
|
gem stays a plain Phlex library when Rails is absent.
|
|
93
|
-
- `Tooltip` `:popover` modifier for collision-aware tooltips. It renders real
|
|
94
|
-
tooltip content in the browser top layer, opens on hover or focus, flips and
|
|
95
|
-
shifts within the visual viewport, follows scroll/resize while open, and
|
|
96
|
-
exposes `role="tooltip"`/`aria-describedby` semantics. The bundled
|
|
97
|
-
`daisy-tooltip` Stimulus controller is auto-pinned for importmap-rails apps
|
|
98
|
-
and supports a custom controller identifier via `stimulus:`.
|
|
99
219
|
|
|
100
220
|
### Changed
|
|
101
221
|
|
|
102
|
-
- The gem ships minified Stimulus controllers with linked sourcemaps, and the
|
|
103
|
-
importmap pins them without preloading, so with the lazy registration the
|
|
104
|
-
README shows (`lazyLoadControllersFrom`) a page that never uses one never
|
|
105
|
-
fetches it. `daisy_dropdown_controller` 6.1 KB → 2.8 KB (2.4 → 1.3 KB gzipped),
|
|
106
|
-
`daisy_tooltip_controller` 8.8 KB → 5.2 KB (2.4 → 1.8 KB gzipped). The
|
|
107
|
-
`daisy_ui/controllers/*` specifiers and the bundler import paths are unchanged.
|
|
108
|
-
- Maintainers cut releases with `bin/release` (`list`, `--dry-run`, `patch`/`minor`/`major`/`X.Y.Z`), which checks the lockfiles for gems that do not accept the new version yet and then drives `rake release`.
|
|
109
|
-
|
|
110
222
|
- Range component: added range-vertical modifier for vertical orientation (DaisyUI 5.6)
|
|
111
223
|
- Tooltip component: added alignment modifiers (tooltip-start, tooltip-center, tooltip-end) and tooltip-content sub-component (DaisyUI 5.6)
|
|
112
224
|
|
|
113
|
-
|
|
225
|
+
## [1.1.1] - 2026-04-05
|
|
114
226
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
227
|
+
### Changed
|
|
228
|
+
|
|
229
|
+
- The gem packages only `exe/`, `lib/`, `CHANGELOG.md`, `LICENSE.txt` and
|
|
230
|
+
`README.md`, listed with `git ls-files` (#14).
|
|
231
|
+
|
|
232
|
+
## [1.1.0] - 2026-04-05
|
|
233
|
+
|
|
234
|
+
### Changed
|
|
235
|
+
|
|
236
|
+
- Components aligned with DaisyUI 5 (#13): new `Hover3d` and `TextRotate`
|
|
237
|
+
components; `Link` sets the `link` class; `MenuItem` uses
|
|
238
|
+
`menu-disabled`/`menu-active`/`menu-focus`; Button's `no_animation` and
|
|
239
|
+
`glass`, Mask's `parallelogram` shapes and Menu's color modifiers are removed.
|
|
121
240
|
|
|
122
241
|
## [0.1.0] - 2024-08-02
|
|
123
242
|
|
data/README.md
CHANGED
|
@@ -92,33 +92,130 @@ Consider not including DaisyUI in ApplicationComponent if:
|
|
|
92
92
|
|
|
93
93
|
In this scenario, including both DaisyUI and your own component library in `ApplicationComponent` will lead to naming conflicts.
|
|
94
94
|
|
|
95
|
-
3.
|
|
95
|
+
3. Tell Tailwind which classes the gem renders: see [Tailwind sources](#tailwind-sources).
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
## Tailwind sources
|
|
98
|
+
|
|
99
|
+
The gem renders daisyUI class names from Ruby, so Tailwind has to be told
|
|
100
|
+
which ones to generate CSS for. Give it the classes of just the components your
|
|
101
|
+
app uses: `daisyui-tailwind` finds the components your Ruby and templates
|
|
102
|
+
reference, adds the components those render (Dropdown renders Button and Menu,
|
|
103
|
+
Menu renders MenuItem), and writes one `@source inline(...)` per component for
|
|
104
|
+
your Tailwind entry to import.
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
bundle exec daisyui-tailwind app -o app/assets/stylesheets/generated/daisyui.css
|
|
107
108
|
```
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
```css
|
|
111
|
+
/* app/assets/stylesheets/application.tailwind.css */
|
|
112
|
+
@import "tailwindcss";
|
|
113
|
+
@plugin "daisyui";
|
|
114
|
+
|
|
115
|
+
@source "../../views"; /* your own classes, as before */
|
|
116
|
+
@import "./generated/daisyui.css"; /* the DaisyUI components you use */
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Run it before Tailwind in your CSS build (it rewrites the file only when its
|
|
120
|
+
content changes, so a watcher does not loop on it). The output names no path,
|
|
121
|
+
so it is the same on every machine: commit it, or generate it on every build.
|
|
122
|
+
|
|
123
|
+
**From a Node build script**, spawn the command, or read JSON:
|
|
110
124
|
|
|
111
125
|
```js
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
],
|
|
119
|
-
};
|
|
126
|
+
// build-css.js (bun)
|
|
127
|
+
Bun.spawnSync(["bundle", "exec", "daisyui-tailwind", "app", "-o", "app/assets/stylesheets/generated/daisyui.css"])
|
|
128
|
+
|
|
129
|
+
// or per bundle, as JSON: { components, classes, files, shared, daisyui }
|
|
130
|
+
const out = Bun.spawnSync(["bundle", "exec", "daisyui-tailwind", "app/views/admin", "--format", "json"])
|
|
131
|
+
const { components, classes, files } = JSON.parse(out.stdout.toString())
|
|
120
132
|
```
|
|
121
133
|
|
|
134
|
+
**From Ruby** (a rake task, a build script):
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
DaisyUI::Tailwind.used_components(scan: ["app"]) # => ["Button", "Menu", "MenuItem", ...]
|
|
138
|
+
DaisyUI::Tailwind.sources(scan: ["app"]) # => the CSS partial
|
|
139
|
+
DaisyUI::Tailwind.sources(components: %w[Navbar], format: :json)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
| Option | |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `PATH...` | Directories (every `.rb`, `.erb`, `.haml`, `.slim` below) or files to scan. A path that does not exist is an error. |
|
|
145
|
+
| `-c, --component Button,Navbar` | Components to include whether or not a path references them (repeatable). |
|
|
146
|
+
| `-f, --format css\|json` | `css` (default) is the partial to import; `json` is for build scripts. |
|
|
147
|
+
| `-o, --output FILE` | Write to FILE instead of stdout, only when its content changes. |
|
|
148
|
+
| `--responsive sm,md,lg` | Add those breakpoint variants of each component class and modifier, for apps that render `responsive:` modifiers. Off by default: they multiply each component's CSS (sm,md,lg made the sample below 3.7 times larger). |
|
|
149
|
+
| `--prefix d-` | Prefix the classes the way an app that sets `DaisyUI.configuration.prefix` renders them. `DaisyUI::Tailwind.sources` uses the configured prefix by default. |
|
|
150
|
+
|
|
151
|
+
What counts as a use: a kit call with or without parentheses (`Button(:primary)`,
|
|
152
|
+
`Badge :primary do`, `Button variant do`, `Hero do`), an instance (`Card.new`)
|
|
153
|
+
or the constant (`DaisyUI::Navbar`, `class AppNavbar < DaisyUI::Navbar`).
|
|
154
|
+
Comments do not count (`#` lines in Ruby, `<%# %>` in ERB, `-#` in HAML, `/` in
|
|
155
|
+
Slim), nor does a name starting a sentence in a string ("Join thousands of…").
|
|
156
|
+
Matching is textual and errs on the side of including a component: a false hit
|
|
157
|
+
costs a little CSS, a miss would leave a component unstyled. A gem that renders DaisyUI components for you (phlex-forms wraps
|
|
158
|
+
Input, Select, Range...) is scanned like your app:
|
|
159
|
+
`daisyui-tailwind app "$(bundle info phlex-forms --path)/lib"`; the classes it
|
|
160
|
+
writes in its own Ruby still need its own `@source`. Classes your code builds
|
|
161
|
+
by interpolation (`"badge-#{color}"`) are invisible to Tailwind either way:
|
|
162
|
+
spell them out.
|
|
163
|
+
|
|
164
|
+
**The size win.** Measured on [cosmos](https://github.com/zoolutions/cosmos)
|
|
165
|
+
(33 of the gem's 77 components), the CSS the gem's classes add to a bundle
|
|
166
|
+
(Tailwind 4.3.2, daisyUI 5.6.13, minified):
|
|
167
|
+
|
|
168
|
+
| Sources | CSS | gzip |
|
|
169
|
+
|---|---|---|
|
|
170
|
+
| `@source` the gem's whole `lib/` | 210.1 KB | 31.9 KB |
|
|
171
|
+
| `daisyui-tailwind` | 125.7 KB | 19.1 KB |
|
|
172
|
+
| `daisyui-tailwind --responsive sm,md,lg` | 466.5 KB | 64.3 KB |
|
|
173
|
+
|
|
174
|
+
It is also more complete. Tailwind v4 drops Ruby comments when it scans a `.rb`
|
|
175
|
+
file and cannot see a Symbol component class (`self.component_class = :navbar`),
|
|
176
|
+
so the whole-gem scan generated no `.navbar`, `.card`, `.drawer`... rule (the app
|
|
177
|
+
only got them by spelling the class itself) and none of the sub-rules daisyUI
|
|
178
|
+
nests under them (`indicator-item`, `stack-top`). The manifest carries both.
|
|
179
|
+
|
|
180
|
+
**Scanning the whole gem still works** as it did:
|
|
181
|
+
|
|
182
|
+
```css
|
|
183
|
+
/* bundle info daisyui --path, resolved by your build script */
|
|
184
|
+
@source "/path/to/gems/daisyui-x.y.z/lib";
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### The manifest
|
|
188
|
+
|
|
189
|
+
The command reads `data/daisyui/tailwind_manifest.json` in the gem, built from
|
|
190
|
+
the components themselves and checked in (`bundle exec rake tailwind:manifest`
|
|
191
|
+
in this repo). It sits outside `lib/`, so an `@source` on the gem's `lib/` or
|
|
192
|
+
its `**/*.rb` never sees it. A build script in another
|
|
193
|
+
language can read it directly from `$(bundle info daisyui --path)`:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"schema": 1,
|
|
198
|
+
"shared": { "files": ["lib/daisy_ui/base.rb"], "classes": ["bg-primary", "skeleton", "..."] },
|
|
199
|
+
"components": {
|
|
200
|
+
"Dropdown": {
|
|
201
|
+
"class": "DaisyUI::Dropdown",
|
|
202
|
+
"name": "dropdown",
|
|
203
|
+
"files": ["lib/daisy_ui/dropdown.rb"],
|
|
204
|
+
"depends_on": ["Button", "Menu"],
|
|
205
|
+
"modifiers": ["dropdown-end", "dropdown-top", "..."],
|
|
206
|
+
"classes": ["dropdown", "dropdown-content", "dropdown-end", "..."]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
- `name`: the daisyUI component class (`null` where it depends on the modifiers, as for Label).
|
|
213
|
+
- `files`: relative to the gem root, for a literal `@source` instead of `inline()`.
|
|
214
|
+
- `depends_on`: the components it renders; resolve them transitively.
|
|
215
|
+
- `modifiers`: the classes `responsive:` can prefix (with `name`).
|
|
216
|
+
- `classes`: everything it can render: `name`, the modifiers and the class words in its Ruby. Words that are not classes cost nothing.
|
|
217
|
+
- `shared`: base.rb's classes, which every component can render (`:skeleton`, the colour modifiers). Include them with any component.
|
|
218
|
+
|
|
122
219
|
## Class merging
|
|
123
220
|
|
|
124
221
|
Components merge their classes so the last conflicting class wins, for Tailwind
|
|
@@ -209,6 +306,45 @@ end
|
|
|
209
306
|
Keyword arguments are not validated: `Toggle(primray: true)` renders a
|
|
210
307
|
`primray` attribute, because unknown keywords are HTML attributes.
|
|
211
308
|
|
|
309
|
+
## Threads, fibers and Ractors
|
|
310
|
+
|
|
311
|
+
Components and `DaisyUI::ClassMerge` are safe to share between threads (Puma)
|
|
312
|
+
and fibers (Falcon). For Ractors, DaisyUI finalizes itself at boot: it freezes
|
|
313
|
+
the configuration and every component's registries, so
|
|
314
|
+
`DaisyUI::ClassMerge.merge` runs in any Ractor (as long as the configuration
|
|
315
|
+
is shareable, see below), each Ractor with a merger of its own.
|
|
316
|
+
`DaisyUI.configure` finalizes at its end and the Rails engine
|
|
317
|
+
finalizes again once the app has booted, so there is nothing to call. A
|
|
318
|
+
Rails-less app that never calls `configure` calls `DaisyUI.finalize!` at the
|
|
319
|
+
end of boot.
|
|
320
|
+
|
|
321
|
+
After that the configuration is frozen: writing to `DaisyUI.configuration`
|
|
322
|
+
directly raises `FrozenError`. `DaisyUI.configure` keeps working at any time:
|
|
323
|
+
it yields a writable copy and publishes it once that is finalized, and a
|
|
324
|
+
Ractor that already built its merger rebuilds it from the new configuration.
|
|
325
|
+
A test that changes a setting goes through it too:
|
|
326
|
+
|
|
327
|
+
```ruby
|
|
328
|
+
around do |example|
|
|
329
|
+
DaisyUI.configure { |config| config.unknown_modifiers = :ignore }
|
|
330
|
+
example.run
|
|
331
|
+
ensure
|
|
332
|
+
DaisyUI.configure { |config| config.unknown_modifiers = :raise }
|
|
333
|
+
end
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Finalizing never raises. A configured value that cannot be made shareable is
|
|
337
|
+
kept as it is, and the configuration is then readable on the main Ractor only:
|
|
338
|
+
a callable `unknown_modifiers` or a raw `class_merge` validator that closes
|
|
339
|
+
over app state (`->(error) { Appsignal.report_error(error) }` in an
|
|
340
|
+
initializer), or an object that holds a logger. A lambda is shareable when it
|
|
341
|
+
captures no local variables and is defined inside a module, or made with
|
|
342
|
+
`Ractor.shareable_lambda` on Ruby 4.0. A component that loads after boot (lazy
|
|
343
|
+
loading in development) freezes its registries as it writes them, so any
|
|
344
|
+
Ractor can read it; a Ractor that already built its merger picks up its groups
|
|
345
|
+
after the next `configure`. Rendering components inside a Ractor waits on Phlex
|
|
346
|
+
([yippee-fun/phlex#1055](https://github.com/yippee-fun/phlex/pull/1055)).
|
|
347
|
+
|
|
212
348
|
# Compatibility Notes
|
|
213
349
|
|
|
214
350
|
## @tailwindcss/forms plugin
|