@dryui/ui 0.1.5 → 0.1.7
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.
- package/dist/backdrop/backdrop.svelte +1 -1
- package/dist/carousel/carousel-viewport.svelte +1 -1
- package/dist/date-field/date-field-root.svelte +0 -1
- package/dist/date-field/date-field-segment.svelte +1 -1
- package/dist/date-picker/datepicker-calendar.svelte +0 -1
- package/dist/date-range-picker/date-range-picker-calendar.svelte +44 -26
- package/dist/date-time-input/date-time-input.svelte +12 -33
- package/dist/notification-center/notification-center-group.svelte +2 -2
- package/dist/notification-center/notification-center-item.svelte +2 -1
- package/dist/notification-center/notification-center-panel.svelte +21 -2
- package/dist/notification-center/notification-center-root.svelte +1 -1
- package/dist/notification-center/notification-center-trigger.svelte +3 -5
- package/dist/select/select-root.svelte +0 -1
- package/dist/select/select-trigger.svelte +2 -0
- package/dist/time-input/index.d.ts +8 -1
- package/dist/time-input/time-input.svelte +118 -74
- package/package.json +1181 -440
- package/skills/dryui/SKILL.md +111 -221
- package/skills/dryui/rules/composition.md +280 -291
package/skills/dryui/SKILL.md
CHANGED
|
@@ -5,288 +5,178 @@ description: 'Use when building UIs with DryUI (@dryui/ui) Svelte 5 components.
|
|
|
5
5
|
|
|
6
6
|
# DryUI
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Zero-dependency Svelte 5 components. All imports from `@dryui/ui`. Requires a theme CSS import. Svelte 5 runes only.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
**Tradeoff:** These rules bias toward correctness over speed. For throwaway prototypes, use judgment.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## 1. Look Up Before You Write
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
- Requires theme: `import '@dryui/ui/themes/default.css'` (or `dark.css`)
|
|
16
|
-
- Prefer `<html class="theme-auto">` as the default theme mode; only set `data-theme="light|dark"` for explicit overrides
|
|
17
|
-
- No external runtime dependencies
|
|
14
|
+
**Never guess a component API. Always verify first.**
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
- Call `info` or `compose` before using any component for the first time
|
|
17
|
+
- Component APIs vary — `bind:value`, `bind:open`, `bind:checked` are NOT interchangeable
|
|
18
|
+
- Compound vs simple, required parts, available props — all differ per component
|
|
19
|
+
- If you skip the lookup, you'll write plausible-looking code that silently breaks
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
step-by-step plan:
|
|
21
|
+
The test: can you point to an `info` or `compose` call for every component in your output?
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
npx -y @dryui/cli install --json
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Execute each `"pending"` step in the returned JSON (install package, edit/create
|
|
29
|
-
files). Then verify:
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
npx -y @dryui/cli detect --json
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The output should show `"status": "ready"`.
|
|
36
|
-
|
|
37
|
-
### Manual setup (if you prefer)
|
|
38
|
-
|
|
39
|
-
1. `bun add @dryui/ui` (or npm/pnpm/yarn equivalent)
|
|
40
|
-
2. In `src/app.html`, add `class="theme-auto"` to the `<html>` tag (preserving
|
|
41
|
-
existing attributes like `lang="en"`)
|
|
42
|
-
3. In your root layout (`src/routes/+layout.svelte`), add theme imports to the
|
|
43
|
-
existing `<script>` block — do not create a second `<script>`:
|
|
44
|
-
```svelte
|
|
45
|
-
<script>
|
|
46
|
-
import '@dryui/ui/themes/default.css';
|
|
47
|
-
import '@dryui/ui/themes/dark.css';
|
|
48
|
-
</script>
|
|
49
|
-
```
|
|
50
|
-
4. Import `app.css` AFTER theme CSS if you have custom styles
|
|
51
|
-
5. (Optional) Override semantic tokens in `app.css` — use the layered token system documented in `rules/theming.md`
|
|
23
|
+
## 2. Everything is Compound Until Proven Otherwise
|
|
52
24
|
|
|
53
|
-
|
|
54
|
-
> `cd /path/to/dryui/packages/ui && bun link && cd /your/project && bun link @dryui/ui`
|
|
25
|
+
**Use `.Root`. Always check.**
|
|
55
26
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
### Rule 1: Compound components MUST use .Root
|
|
27
|
+
Most DryUI components are compound — they require `<Card.Root>`, not `<Card>`. The bare name silently fails or renders wrong. Assume compound; verify with `info`.
|
|
59
28
|
|
|
60
29
|
```svelte
|
|
61
|
-
<!--
|
|
62
|
-
<Card>content</Card>
|
|
63
|
-
|
|
64
|
-
<!-- Correct -->
|
|
65
|
-
<Card.Root>content</Card.Root>
|
|
30
|
+
<!-- Wrong --> <Card>content</Card>
|
|
31
|
+
<!-- Right --> <Card.Root>content</Card.Root>
|
|
66
32
|
```
|
|
67
33
|
|
|
68
|
-
|
|
34
|
+
The test: every compound component in your markup uses `.Root`, and its parts are wrapped inside it. See `rules/compound-components.md` for the full list and parts reference.
|
|
69
35
|
|
|
70
|
-
|
|
36
|
+
## 3. Let the Theme Do Its Job
|
|
71
37
|
|
|
72
|
-
|
|
73
|
-
<script>
|
|
74
|
-
import '@dryui/ui/themes/default.css';
|
|
75
|
-
import '@dryui/ui/themes/dark.css';
|
|
76
|
-
import { Button } from '@dryui/ui';
|
|
77
|
-
</script>
|
|
78
|
-
```
|
|
38
|
+
**Import it. Use its tokens. Don't fight it.**
|
|
79
39
|
|
|
80
|
-
|
|
40
|
+
- Import `@dryui/ui/themes/default.css` (and `dark.css`) before any component use
|
|
41
|
+
- Use `--dry-color-*` and `--dry-space-*` tokens — never hardcoded colors or spacing
|
|
42
|
+
- Don't add decorative CSS (gradients, shadows, colored borders) — the theme handles appearance
|
|
43
|
+
- Override semantic tokens (Tier 2) in `:root`, not component tokens (Tier 3)
|
|
44
|
+
- Prefer `<html class="theme-auto">` — use `data-theme="light|dark"` only for explicit overrides
|
|
81
45
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
```svelte
|
|
87
|
-
<!-- Incorrect -->
|
|
88
|
-
<Input value={email} />
|
|
89
|
-
<Popover.Root bind:value={open} />
|
|
90
|
-
<!-- wrong prop -->
|
|
46
|
+
```css
|
|
47
|
+
/* Wrong */
|
|
48
|
+
.card { background: #6366f1; color: white; }
|
|
91
49
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<Popover.Root bind:open />
|
|
50
|
+
/* Right */
|
|
51
|
+
.card { background: var(--dry-color-fill-brand); color: var(--dry-color-text-strong); }
|
|
95
52
|
```
|
|
96
53
|
|
|
97
|
-
|
|
54
|
+
The test: does your CSS contain zero hex colors, zero `rgb()` values, and zero inline styles?
|
|
98
55
|
|
|
99
|
-
|
|
100
|
-
- `bind:checked` — Checkbox, Switch
|
|
101
|
-
- `bind:pressed` — Toggle
|
|
102
|
-
- `bind:open` — Popover, Dialog, Drawer, AlertDialog, DropdownMenu, ContextMenu, Select, Combobox, CommandPalette, FloatButton, DatePicker, Collapsible
|
|
103
|
-
- `bind:active` — Tour (not `bind:open`)
|
|
104
|
-
- `bind:files` — FileUpload
|
|
105
|
-
- `bind:page` — Pagination
|
|
106
|
-
- `bind:activeStep` — Stepper
|
|
107
|
-
- `bind:sizes` — Splitter
|
|
56
|
+
## 4. Grid for Layout. Container for Width. @container for Responsive.
|
|
108
57
|
|
|
109
|
-
|
|
58
|
+
**Nothing else.**
|
|
110
59
|
|
|
111
|
-
|
|
60
|
+
- All layout is `display: grid` with `--dry-space-*` tokens in scoped `<style>`
|
|
61
|
+
- `Container` (simple component, no `.Root`) for constrained content width
|
|
62
|
+
- Use `@container` queries for responsive sizing — never `@media` for layout breakpoints
|
|
63
|
+
- No flexbox. No inline styles. No `width`/`min-width`/`max-width` properties
|
|
112
64
|
|
|
113
65
|
```svelte
|
|
114
|
-
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
<Flex gap="md">...</Flex>
|
|
66
|
+
<div class="layout">...</div>
|
|
67
|
+
<style>
|
|
68
|
+
.layout { display: grid; gap: var(--dry-space-4); }
|
|
69
|
+
</style>
|
|
119
70
|
```
|
|
120
71
|
|
|
121
|
-
|
|
72
|
+
The test: grep your output for `display: flex`, `style=`, `@media` — all should return nothing.
|
|
73
|
+
|
|
74
|
+
## 5. Every Input Gets a Field.Root
|
|
122
75
|
|
|
123
|
-
|
|
76
|
+
**Accessibility isn't optional.**
|
|
77
|
+
|
|
78
|
+
- Wrap every form input in `Field.Root` with a `Label`
|
|
79
|
+
- Use `AlertDialog` (not `Dialog`) for destructive confirmations
|
|
80
|
+
- Add `aria-label` to every icon-only button
|
|
81
|
+
- Use `type="submit"` on primary form action buttons
|
|
124
82
|
|
|
125
83
|
```svelte
|
|
126
|
-
<!--
|
|
84
|
+
<!-- Wrong -->
|
|
127
85
|
<label>Email</label>
|
|
128
86
|
<Input bind:value={email} />
|
|
129
87
|
|
|
130
|
-
<!--
|
|
88
|
+
<!-- Right -->
|
|
131
89
|
<Field.Root>
|
|
132
|
-
|
|
133
|
-
|
|
90
|
+
<Label>Email</Label>
|
|
91
|
+
<Input bind:value={email} />
|
|
134
92
|
</Field.Root>
|
|
135
93
|
```
|
|
136
94
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
### Rule 6: Use --dry-\* CSS variables, not hardcoded colors
|
|
95
|
+
The test: every `<Input>`, `<Select.Root>`, `<Textarea>` is inside a `Field.Root` with a `Label` sibling.
|
|
140
96
|
|
|
141
|
-
|
|
142
|
-
/* Incorrect */
|
|
143
|
-
.card {
|
|
144
|
-
background: #6366f1;
|
|
145
|
-
color: white;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/* Correct */
|
|
149
|
-
.card {
|
|
150
|
-
background: var(--dry-color-fill-brand);
|
|
151
|
-
color: var(--dry-color-text-strong);
|
|
152
|
-
}
|
|
153
|
-
```
|
|
97
|
+
## 6. Prefer DryUI Over Native HTML
|
|
154
98
|
|
|
155
|
-
|
|
99
|
+
**If a DryUI component exists for it, use it.**
|
|
156
100
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
```svelte
|
|
160
|
-
<!-- Incorrect -->
|
|
161
|
-
<input type="date" bind:value={date} />
|
|
162
|
-
<select bind:value={choice}><option>...</option></select>
|
|
163
|
-
<dialog>...</dialog>
|
|
164
|
-
|
|
165
|
-
<!-- Correct -->
|
|
166
|
-
<DatePicker.Root bind:value={date}>
|
|
167
|
-
<DatePicker.Trigger>Pick a date</DatePicker.Trigger>
|
|
168
|
-
<DatePicker.Content>
|
|
169
|
-
<DatePicker.Calendar />
|
|
170
|
-
</DatePicker.Content>
|
|
171
|
-
</DatePicker.Root>
|
|
172
|
-
|
|
173
|
-
<Select.Root bind:value={choice}>
|
|
174
|
-
<Select.Trigger />
|
|
175
|
-
<Select.Content>
|
|
176
|
-
<Select.Item value="a">Option A</Select.Item>
|
|
177
|
-
</Select.Content>
|
|
178
|
-
</Select.Root>
|
|
179
|
-
|
|
180
|
-
<Dialog.Root>
|
|
181
|
-
<Dialog.Trigger>Open</Dialog.Trigger>
|
|
182
|
-
<Dialog.Content>...</Dialog.Content>
|
|
183
|
-
</Dialog.Root>
|
|
184
|
-
```
|
|
101
|
+
`DatePicker` not `<input type="date">`. `Select.Root` not `<select>`. `Dialog.Root` not `<dialog>`. `Separator` not `<hr>`. `Button` not `<button>`. DryUI components handle theming and accessibility automatically — native elements don't.
|
|
185
102
|
|
|
186
|
-
|
|
103
|
+
The test: search your markup for raw `<input`, `<select>`, `<dialog>`, `<button>`, `<hr>`, `<table>` — each should be a DryUI component instead.
|
|
187
104
|
|
|
188
|
-
|
|
105
|
+
## Quick Start
|
|
189
106
|
|
|
190
|
-
|
|
107
|
+
Run the install planner — it detects the project and returns a tailored step-by-step plan:
|
|
191
108
|
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
<div
|
|
195
|
-
style="background: linear-gradient(135deg, #667eea, #764ba2); border-radius: 1rem; box-shadow: 0 4px 12px rgba(0,0,0,0.15);"
|
|
196
|
-
>
|
|
197
|
-
<Card.Root>...</Card.Root>
|
|
198
|
-
</div>
|
|
199
|
-
|
|
200
|
-
<!-- Incorrect: wrapper with decorative class -->
|
|
201
|
-
<div class="fancy-card">
|
|
202
|
-
<Card.Root>...</Card.Root>
|
|
203
|
-
</div>
|
|
204
|
-
|
|
205
|
-
<!-- Correct: just the component -->
|
|
206
|
-
<Card.Root>
|
|
207
|
-
<Card.Content>
|
|
208
|
-
<Text>Clean output</Text>
|
|
209
|
-
</Card.Content>
|
|
210
|
-
</Card.Root>
|
|
211
|
-
|
|
212
|
-
<style>
|
|
213
|
-
.fancy-card {
|
|
214
|
-
background: radial-gradient(circle at top right, rgba(99, 102, 241, 0.18), transparent);
|
|
215
|
-
border-left: 3px solid var(--dry-color-stroke-brand);
|
|
216
|
-
}
|
|
217
|
-
</style>
|
|
109
|
+
```
|
|
110
|
+
npx -y @dryui/cli install --toon
|
|
218
111
|
```
|
|
219
112
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
### Rule 9: Check composition before writing UI
|
|
223
|
-
|
|
224
|
-
Before generating any DryUI layout or component composition, call `compose` with a description of what you're building. This ensures you use the correct components and avoid anti-patterns.
|
|
225
|
-
|
|
226
|
-
Workflow:
|
|
227
|
-
|
|
228
|
-
1. Identify each distinct UI element you need (date input, image placeholder, progress stepper, etc.)
|
|
229
|
-
2. Call `compose` for each one — MCP: `compose({ query: "date input" })`, CLI: `bunx @dryui/cli compose "date input"`
|
|
230
|
-
3. Use the top-ranked component from the result
|
|
231
|
-
4. Follow the snippet patterns exactly
|
|
232
|
-
5. After writing, call `review` to validate
|
|
233
|
-
|
|
234
|
-
Never skip this step. The compose tool exists because component selection mistakes (like using `<Input type="date">` instead of `DatePicker`) are invisible until someone sees the broken output.
|
|
113
|
+
Execute each `"pending"` step. Then verify: `npx -y @dryui/cli detect --toon` — output should show `project: ready`.
|
|
235
114
|
|
|
236
|
-
###
|
|
115
|
+
### Manual setup
|
|
237
116
|
|
|
238
|
-
|
|
117
|
+
1. `bun add @dryui/ui`
|
|
118
|
+
2. Add `class="theme-auto"` to `<html>` in `src/app.html`
|
|
119
|
+
3. In root layout (`src/routes/+layout.svelte`), import themes:
|
|
120
|
+
```svelte
|
|
121
|
+
<script>
|
|
122
|
+
import '@dryui/ui/themes/default.css';
|
|
123
|
+
import '@dryui/ui/themes/dark.css';
|
|
124
|
+
</script>
|
|
125
|
+
```
|
|
126
|
+
4. Import `app.css` AFTER theme CSS if you have custom styles
|
|
239
127
|
|
|
240
|
-
##
|
|
128
|
+
## Bindable Props — Common Confusion
|
|
241
129
|
|
|
242
|
-
|
|
130
|
+
Always verify with `info`, but these are the most common mistakes:
|
|
243
131
|
|
|
244
|
-
|
|
132
|
+
- `bind:value` (Input, Select, Tabs...) vs `bind:checked` (Checkbox, Switch) vs `bind:pressed` (Toggle) vs `bind:open` (Dialog, Popover, Drawer...)
|
|
133
|
+
- Select and Combobox support both `bind:value` and `bind:open`
|
|
134
|
+
- ColorPicker also exposes `bind:alpha`; Transfer uses `bind:sourceItems` / `bind:targetItems`
|
|
135
|
+
- Tour uses `bind:active`, not `bind:open`
|
|
245
136
|
|
|
246
|
-
|
|
137
|
+
## Tools
|
|
247
138
|
|
|
248
|
-
|
|
249
|
-
- Lookup and composition: `info`, `get`, `list`, `compose`
|
|
250
|
-
- Validation and theme checks: `review`, `diagnose`
|
|
251
|
-
- Repo audit: `doctor`, `lint`
|
|
139
|
+
Use these to look up APIs, discover components, plan setup, and validate code.
|
|
252
140
|
|
|
253
|
-
|
|
141
|
+
### MCP tools (preferred)
|
|
254
142
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
plan_install
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
143
|
+
| Workflow | Tools |
|
|
144
|
+
|----------|-------|
|
|
145
|
+
| Project setup | `detect_project`, `plan_install`, `plan_add` |
|
|
146
|
+
| Lookup & composition | `info`, `get`, `list`, `compose` |
|
|
147
|
+
| Validation | `review`, `diagnose` |
|
|
148
|
+
| Audit | `doctor`, `lint` |
|
|
261
149
|
|
|
262
|
-
### CLI fallback
|
|
150
|
+
### CLI fallback
|
|
263
151
|
|
|
264
|
-
|
|
152
|
+
All commands support `--toon` for token-optimized agent output and `--full` to disable truncation.
|
|
265
153
|
|
|
266
154
|
```bash
|
|
267
|
-
bunx @dryui/cli
|
|
268
|
-
bunx @dryui/cli
|
|
269
|
-
bunx @dryui/cli
|
|
270
|
-
bunx @dryui/cli
|
|
271
|
-
bunx @dryui/cli
|
|
272
|
-
bunx @dryui/cli
|
|
273
|
-
bunx @dryui/cli
|
|
274
|
-
bunx @dryui/cli
|
|
275
|
-
bunx @dryui/cli
|
|
276
|
-
bunx @dryui/cli doctor [path] # Audit workspace health
|
|
277
|
-
bunx @dryui/cli lint [path] # Print deterministic workspace findings
|
|
155
|
+
bunx @dryui/cli info <component> --toon # Look up component API
|
|
156
|
+
bunx @dryui/cli compose "date input" --toon # Composition guidance
|
|
157
|
+
bunx @dryui/cli detect [path] --toon # Check project setup
|
|
158
|
+
bunx @dryui/cli install [path] --toon # Print install plan
|
|
159
|
+
bunx @dryui/cli review <file.svelte> --toon # Validate component
|
|
160
|
+
bunx @dryui/cli diagnose <file.css> --toon # Validate theme CSS
|
|
161
|
+
bunx @dryui/cli doctor [path] --toon # Audit workspace
|
|
162
|
+
bunx @dryui/cli lint [path] --toon # Deterministic findings
|
|
163
|
+
bunx @dryui/cli list --toon # List components
|
|
278
164
|
```
|
|
279
165
|
|
|
280
166
|
Categories: action, input, form, layout, navigation, overlay, display, feedback, interaction, utility
|
|
281
167
|
|
|
282
|
-
## Rule
|
|
168
|
+
## Rule Files
|
|
283
169
|
|
|
284
|
-
Read these
|
|
170
|
+
Read these when you need deeper guidance:
|
|
171
|
+
|
|
172
|
+
- **`rules/compound-components.md`** — Parts lists, component selection table, common mistakes
|
|
173
|
+
- **`rules/theming.md`** — Three-tier token system, dark mode, palette customization
|
|
174
|
+
- **`rules/composition.md`** — Form patterns, page layouts, composition recipes
|
|
175
|
+
- **`rules/accessibility.md`** — Field.Root, ARIA, focus management, pre-ship checklist
|
|
176
|
+
- **`rules/svelte.md`** — Runes, snippets, native browser APIs, styling rules
|
|
177
|
+
- **`rules/design.md`** — Minimal code, no premature abstraction, naming conventions
|
|
178
|
+
- **`rules/native-web-transitions.md`** — View Transition API, scroll animations, reduced-motion
|
|
179
|
+
|
|
180
|
+
---
|
|
285
181
|
|
|
286
|
-
|
|
287
|
-
- **`rules/theming.md`** -- Read when setting up themes, customizing component styles, or fixing invisible/unstyled components.
|
|
288
|
-
- **`rules/composition.md`** -- Read when building page layouts or forms. Contains layout patterns and form composition recipes.
|
|
289
|
-
- **`rules/accessibility.md`** -- Read when handling form validation, focus management, ARIA attributes, or dialog patterns.
|
|
290
|
-
- **`rules/svelte.md`** -- Read when writing Svelte 5 components. Covers rune usage, snippets, compound components, native browser APIs, and styling rules.
|
|
291
|
-
- **`rules/design.md`** -- Read when writing or reviewing code. Enforces minimal, readable, correct code with no unnecessary abstractions.
|
|
292
|
-
- **`rules/native-web-transitions.md`** -- Read when adding animations or transitions. Covers View Transition API, scroll-driven animations, reduced-motion handling, and progressive enhancement.
|
|
182
|
+
**These rules are working if:** every component traces to a lookup, diffs contain zero hardcoded colors, and the reviewer finds nothing.
|