@delightstack/components 0.1.0

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 (195) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +136 -0
  3. package/SKILL.md +149 -0
  4. package/bin/agents.js +63 -0
  5. package/dist/actions/Alert.svelte +202 -0
  6. package/dist/actions/Alert.svelte.d.ts +36 -0
  7. package/dist/actions/Alert.svelte.d.ts.map +1 -0
  8. package/dist/actions/Button.svelte +1450 -0
  9. package/dist/actions/Button.svelte.d.ts +56 -0
  10. package/dist/actions/Button.svelte.d.ts.map +1 -0
  11. package/dist/actions/ButtonGroup.svelte +111 -0
  12. package/dist/actions/ButtonGroup.svelte.d.ts +41 -0
  13. package/dist/actions/ButtonGroup.svelte.d.ts.map +1 -0
  14. package/dist/actions/CommandPalette.svelte +939 -0
  15. package/dist/actions/CommandPalette.svelte.d.ts +37 -0
  16. package/dist/actions/CommandPalette.svelte.d.ts.map +1 -0
  17. package/dist/actions/ContextMenu.svelte +138 -0
  18. package/dist/actions/ContextMenu.svelte.d.ts +54 -0
  19. package/dist/actions/ContextMenu.svelte.d.ts.map +1 -0
  20. package/dist/actions/Modal.svelte +474 -0
  21. package/dist/actions/Modal.svelte.d.ts +28 -0
  22. package/dist/actions/Modal.svelte.d.ts.map +1 -0
  23. package/dist/actions/Popover.svelte +1214 -0
  24. package/dist/actions/Popover.svelte.d.ts +31 -0
  25. package/dist/actions/Popover.svelte.d.ts.map +1 -0
  26. package/dist/actions/Portal.svelte +80 -0
  27. package/dist/actions/Portal.svelte.d.ts +17 -0
  28. package/dist/actions/Portal.svelte.d.ts.map +1 -0
  29. package/dist/actions/ThemeToggle.svelte +345 -0
  30. package/dist/actions/ThemeToggle.svelte.d.ts +15 -0
  31. package/dist/actions/ThemeToggle.svelte.d.ts.map +1 -0
  32. package/dist/actions/index.d.ts +13 -0
  33. package/dist/actions/index.d.ts.map +1 -0
  34. package/dist/actions/index.js +10 -0
  35. package/dist/actions/scrollbar.d.ts +48 -0
  36. package/dist/actions/scrollbar.d.ts.map +1 -0
  37. package/dist/actions/scrollbar.js +404 -0
  38. package/dist/display/Accordion.svelte +586 -0
  39. package/dist/display/Accordion.svelte.d.ts +41 -0
  40. package/dist/display/Accordion.svelte.d.ts.map +1 -0
  41. package/dist/display/Avatar.svelte +527 -0
  42. package/dist/display/Avatar.svelte.d.ts +22 -0
  43. package/dist/display/Avatar.svelte.d.ts.map +1 -0
  44. package/dist/display/AvatarGroup.svelte +298 -0
  45. package/dist/display/AvatarGroup.svelte.d.ts +31 -0
  46. package/dist/display/AvatarGroup.svelte.d.ts.map +1 -0
  47. package/dist/display/Calendar.svelte +1366 -0
  48. package/dist/display/Calendar.svelte.d.ts +58 -0
  49. package/dist/display/Calendar.svelte.d.ts.map +1 -0
  50. package/dist/display/Chart.svelte +1426 -0
  51. package/dist/display/Chart.svelte.d.ts +35 -0
  52. package/dist/display/Chart.svelte.d.ts.map +1 -0
  53. package/dist/display/Code.svelte +780 -0
  54. package/dist/display/Code.svelte.d.ts +19 -0
  55. package/dist/display/Code.svelte.d.ts.map +1 -0
  56. package/dist/display/Comparison.svelte +686 -0
  57. package/dist/display/Comparison.svelte.d.ts +22 -0
  58. package/dist/display/Comparison.svelte.d.ts.map +1 -0
  59. package/dist/display/Counter.svelte +285 -0
  60. package/dist/display/Counter.svelte.d.ts +21 -0
  61. package/dist/display/Counter.svelte.d.ts.map +1 -0
  62. package/dist/display/Expand.svelte +48 -0
  63. package/dist/display/Expand.svelte.d.ts +9 -0
  64. package/dist/display/Expand.svelte.d.ts.map +1 -0
  65. package/dist/display/List.svelte +294 -0
  66. package/dist/display/List.svelte.d.ts +40 -0
  67. package/dist/display/List.svelte.d.ts.map +1 -0
  68. package/dist/display/ListContextReset.svelte +19 -0
  69. package/dist/display/ListContextReset.svelte.d.ts +7 -0
  70. package/dist/display/ListContextReset.svelte.d.ts.map +1 -0
  71. package/dist/display/ListItem.svelte +834 -0
  72. package/dist/display/ListItem.svelte.d.ts +22 -0
  73. package/dist/display/ListItem.svelte.d.ts.map +1 -0
  74. package/dist/display/QR.svelte +1193 -0
  75. package/dist/display/QR.svelte.d.ts +23 -0
  76. package/dist/display/QR.svelte.d.ts.map +1 -0
  77. package/dist/display/SplitPane.svelte +744 -0
  78. package/dist/display/SplitPane.svelte.d.ts +25 -0
  79. package/dist/display/SplitPane.svelte.d.ts.map +1 -0
  80. package/dist/display/Stat.svelte +439 -0
  81. package/dist/display/Stat.svelte.d.ts +24 -0
  82. package/dist/display/Stat.svelte.d.ts.map +1 -0
  83. package/dist/display/Table.svelte +4654 -0
  84. package/dist/display/Table.svelte.d.ts +249 -0
  85. package/dist/display/Table.svelte.d.ts.map +1 -0
  86. package/dist/display/TableCellEditor.svelte +935 -0
  87. package/dist/display/TableCellEditor.svelte.d.ts +58 -0
  88. package/dist/display/TableCellEditor.svelte.d.ts.map +1 -0
  89. package/dist/display/Timeline.svelte +1258 -0
  90. package/dist/display/Timeline.svelte.d.ts +43 -0
  91. package/dist/display/Timeline.svelte.d.ts.map +1 -0
  92. package/dist/display/Tree.svelte +1740 -0
  93. package/dist/display/Tree.svelte.d.ts +74 -0
  94. package/dist/display/Tree.svelte.d.ts.map +1 -0
  95. package/dist/display/Typewriter.svelte +338 -0
  96. package/dist/display/Typewriter.svelte.d.ts +22 -0
  97. package/dist/display/Typewriter.svelte.d.ts.map +1 -0
  98. package/dist/display/index.d.ts +24 -0
  99. package/dist/display/index.d.ts.map +1 -0
  100. package/dist/display/index.js +18 -0
  101. package/dist/feedback/Callout.svelte +529 -0
  102. package/dist/feedback/Callout.svelte.d.ts +24 -0
  103. package/dist/feedback/Callout.svelte.d.ts.map +1 -0
  104. package/dist/feedback/Confetti.svelte +631 -0
  105. package/dist/feedback/Confetti.svelte.d.ts +90 -0
  106. package/dist/feedback/Confetti.svelte.d.ts.map +1 -0
  107. package/dist/feedback/Progress.svelte +382 -0
  108. package/dist/feedback/Progress.svelte.d.ts +25 -0
  109. package/dist/feedback/Progress.svelte.d.ts.map +1 -0
  110. package/dist/feedback/Toast.svelte +967 -0
  111. package/dist/feedback/Toast.svelte.d.ts +54 -0
  112. package/dist/feedback/Toast.svelte.d.ts.map +1 -0
  113. package/dist/feedback/index.d.ts +7 -0
  114. package/dist/feedback/index.d.ts.map +1 -0
  115. package/dist/feedback/index.js +4 -0
  116. package/dist/form/Checkbox.svelte +449 -0
  117. package/dist/form/Checkbox.svelte.d.ts +27 -0
  118. package/dist/form/Checkbox.svelte.d.ts.map +1 -0
  119. package/dist/form/Fieldset.svelte +410 -0
  120. package/dist/form/Fieldset.svelte.d.ts +22 -0
  121. package/dist/form/Fieldset.svelte.d.ts.map +1 -0
  122. package/dist/form/FileUpload.svelte +934 -0
  123. package/dist/form/FileUpload.svelte.d.ts +41 -0
  124. package/dist/form/FileUpload.svelte.d.ts.map +1 -0
  125. package/dist/form/Form.svelte +530 -0
  126. package/dist/form/Form.svelte.d.ts +120 -0
  127. package/dist/form/Form.svelte.d.ts.map +1 -0
  128. package/dist/form/Input.svelte +2858 -0
  129. package/dist/form/Input.svelte.d.ts +66 -0
  130. package/dist/form/Input.svelte.d.ts.map +1 -0
  131. package/dist/form/Radio.svelte +507 -0
  132. package/dist/form/Radio.svelte.d.ts +39 -0
  133. package/dist/form/Radio.svelte.d.ts.map +1 -0
  134. package/dist/form/Range.svelte +912 -0
  135. package/dist/form/Range.svelte.d.ts +33 -0
  136. package/dist/form/Range.svelte.d.ts.map +1 -0
  137. package/dist/form/Rating.svelte +429 -0
  138. package/dist/form/Rating.svelte.d.ts +28 -0
  139. package/dist/form/Rating.svelte.d.ts.map +1 -0
  140. package/dist/form/Select.svelte +1933 -0
  141. package/dist/form/Select.svelte.d.ts +54 -0
  142. package/dist/form/Select.svelte.d.ts.map +1 -0
  143. package/dist/form/Toggle.svelte +645 -0
  144. package/dist/form/Toggle.svelte.d.ts +50 -0
  145. package/dist/form/Toggle.svelte.d.ts.map +1 -0
  146. package/dist/form/index.d.ts +15 -0
  147. package/dist/form/index.d.ts.map +1 -0
  148. package/dist/form/index.js +10 -0
  149. package/dist/index.d.ts +7 -0
  150. package/dist/index.d.ts.map +1 -0
  151. package/dist/index.js +6 -0
  152. package/dist/layout/README.md +172 -0
  153. package/dist/media/Carousel.svelte +2424 -0
  154. package/dist/media/Carousel.svelte.d.ts +47 -0
  155. package/dist/media/Carousel.svelte.d.ts.map +1 -0
  156. package/dist/media/Gallery.svelte +2881 -0
  157. package/dist/media/Gallery.svelte.d.ts +82 -0
  158. package/dist/media/Gallery.svelte.d.ts.map +1 -0
  159. package/dist/media/Image.svelte +389 -0
  160. package/dist/media/Image.svelte.d.ts +33 -0
  161. package/dist/media/Image.svelte.d.ts.map +1 -0
  162. package/dist/media/PDF.svelte +1793 -0
  163. package/dist/media/PDF.svelte.d.ts +44 -0
  164. package/dist/media/PDF.svelte.d.ts.map +1 -0
  165. package/dist/media/Panorama.svelte +1391 -0
  166. package/dist/media/Panorama.svelte.d.ts +47 -0
  167. package/dist/media/Panorama.svelte.d.ts.map +1 -0
  168. package/dist/media/Video.svelte +2501 -0
  169. package/dist/media/Video.svelte.d.ts +58 -0
  170. package/dist/media/Video.svelte.d.ts.map +1 -0
  171. package/dist/media/carousel.d.ts +211 -0
  172. package/dist/media/carousel.d.ts.map +1 -0
  173. package/dist/media/carousel.js +408 -0
  174. package/dist/media/index.d.ts +11 -0
  175. package/dist/media/index.d.ts.map +1 -0
  176. package/dist/media/index.js +5 -0
  177. package/dist/navigation/BottomSheet.svelte +636 -0
  178. package/dist/navigation/BottomSheet.svelte.d.ts +27 -0
  179. package/dist/navigation/BottomSheet.svelte.d.ts.map +1 -0
  180. package/dist/navigation/Breadcrumbs.svelte +611 -0
  181. package/dist/navigation/Breadcrumbs.svelte.d.ts +28 -0
  182. package/dist/navigation/Breadcrumbs.svelte.d.ts.map +1 -0
  183. package/dist/navigation/Pagination.svelte +641 -0
  184. package/dist/navigation/Pagination.svelte.d.ts +27 -0
  185. package/dist/navigation/Pagination.svelte.d.ts.map +1 -0
  186. package/dist/navigation/Steps.svelte +965 -0
  187. package/dist/navigation/Steps.svelte.d.ts +43 -0
  188. package/dist/navigation/Steps.svelte.d.ts.map +1 -0
  189. package/dist/navigation/Tabs.svelte +698 -0
  190. package/dist/navigation/Tabs.svelte.d.ts +41 -0
  191. package/dist/navigation/Tabs.svelte.d.ts.map +1 -0
  192. package/dist/navigation/index.d.ts +8 -0
  193. package/dist/navigation/index.d.ts.map +1 -0
  194. package/dist/navigation/index.js +5 -0
  195. package/package.json +139 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brian Schwabauer
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.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # @delightstack/components
2
+
3
+ A polished, opinionated [Svelte 5](https://svelte.dev) component library focused on delightful
4
+ user experiences — 50+ accessible, themeable components built on runes, with motion and
5
+ micro-interactions designed in from the start.
6
+
7
+ **Docs:** [docs.thedelight.co](https://docs.thedelight.co) ·
8
+ **Live demo:** [docs.thedelight.co/demo](https://docs.thedelight.co/demo/)
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pnpm add @delightstack/components @delightstack/styles
14
+ ```
15
+
16
+ Import the design tokens once at the root of your app (e.g. `src/routes/+layout.svelte`):
17
+
18
+ ```ts
19
+ import '@delightstack/styles';
20
+ ```
21
+
22
+ Requires Svelte `^5.36.0`. Works with SvelteKit and standalone Vite + Svelte projects.
23
+
24
+ ## Usage
25
+
26
+ All components are available from a single import — unused ones are tree-shaken:
27
+
28
+ ```svelte
29
+ <script>
30
+ import { Button, Input, BottomSheet } from '@delightstack/components';
31
+
32
+ let name = $state('');
33
+ let open = $state(false);
34
+
35
+ async function save() {
36
+ await fetch('/api/user', { method: 'POST', body: JSON.stringify({ name }) });
37
+ }
38
+ </script>
39
+
40
+ <Input label="Name" bind:value={name} />
41
+ <!-- Promise-returning callbacks show a loading state automatically -->
42
+ <Button onclick={save}>Save</Button>
43
+ <Button outline onclick={() => (open = true)}>Filters</Button>
44
+
45
+ <BottomSheet bind:open snap_points={[0.5, 0.92]}>
46
+ <p>Slide me around.</p>
47
+ </BottomSheet>
48
+ ```
49
+
50
+ ### Conventions
51
+
52
+ - **Props are snake_case, callbacks are camelCase** — `snap_points`, `full_width` vs `onclick`,
53
+ `onchange`. The visual distinction between data and behavior is intentional.
54
+ - **Callback props, not dispatched events.** Callbacks that return a Promise put the component
55
+ into a loading state until they settle.
56
+ - **Two-way binding** with `bind:value`, plus component-specific bindables like `bind:open`,
57
+ `bind:snap`, and `bind:page`.
58
+ - **Svelte 5 snippets** for named content areas (`{#snippet header()}…{/snippet}`).
59
+
60
+ ## Components
61
+
62
+ | Category | Components |
63
+ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
64
+ | **Actions** | Button, ButtonGroup, Modal, Alert, Popover, ContextMenu, Portal, CommandPalette, ThemeToggle |
65
+ | **Display** | Accordion, Avatar, AvatarGroup, Calendar, Chart, Code, Comparison, Counter, Expand, List, ListItem, QR, SplitPane, Stat, Table, Timeline, Tree, Typewriter |
66
+ | **Feedback** | Callout, Confetti, Progress, Toaster (`toast()`) |
67
+ | **Form** | Checkbox, Fieldset, FileUpload, Form, Input, Radio, RadioGroup, Range, Rating, Select, Toggle |
68
+ | **Media** | Carousel, Gallery, Image, Panorama, PDF, Video |
69
+ | **Navigation** | BottomSheet, Breadcrumbs, Pagination, Steps, Tabs |
70
+
71
+ Every component has a docs page with live examples and full Props / Events / CSS Variables /
72
+ Accessibility tables: [docs.thedelight.co/components/overview](https://docs.thedelight.co/components/overview/).
73
+
74
+ ## Theming
75
+
76
+ Components read every color, size, and motion value from CSS custom properties shipped by
77
+ [`@delightstack/styles`](https://www.npmjs.com/package/@delightstack/styles), with light and dark
78
+ values built in. Re-theme by overriding the brand seed or any individual token:
79
+
80
+ ```css
81
+ :root {
82
+ /* Re-derives the whole palette from one brand color */
83
+ --color-primary: #2563eb;
84
+
85
+ /* …or override individual semantic tokens outright */
86
+ --color-action: light-dark(#2563eb, #3b82f6);
87
+ --radius-md: 0.5rem;
88
+ }
89
+ ```
90
+
91
+ See the [Theming](https://docs.thedelight.co/guides/theming/) and
92
+ [Design Tokens](https://docs.thedelight.co/guides/design-tokens/) guides.
93
+
94
+ ## Optional peer dependencies
95
+
96
+ A few media components dynamically import heavier libraries — install them only if you use the
97
+ component, and import these two from their dedicated subpaths:
98
+
99
+ | Component | Peer dependency | Import from |
100
+ | ---------- | --------------- | ------------------------------------ |
101
+ | `Panorama` | `three` | `@delightstack/components/panorama` |
102
+ | `PDF` | `pdfjs-dist` | `@delightstack/components/pdf` |
103
+ | `Video` | `hls.js` (only for HLS sources) | `@delightstack/components` |
104
+
105
+ In Vite dev, add the ones you use to `optimizeDeps.include` so they are not stubbed as absent
106
+ optional dependencies.
107
+
108
+ ## TypeScript
109
+
110
+ Types are included — no `@types/*` packages needed. Data-structure types ship from the main
111
+ entry point:
112
+
113
+ ```ts
114
+ import type { SelectOption, TableColumn, TreeNode, CalendarEvent } from '@delightstack/components';
115
+ ```
116
+
117
+ The package also ships its full `.svelte` sources in `dist/`, so editors (and AI agents) get
118
+ JSDoc descriptions for every prop.
119
+
120
+ ## AI coding agents
121
+
122
+ Set up Claude Code, Cursor, Codex, and friends to use this library correctly in one command from
123
+ your project root:
124
+
125
+ ```bash
126
+ pnpm exec delightstack-agents
127
+ ```
128
+
129
+ This installs a ready-made skill (`.claude/skills/delightstack/SKILL.md`) and points your
130
+ `AGENTS.md` at it. Docs are also published as plain markdown — append `.md` to any docs page URL,
131
+ or start from [docs.thedelight.co/llms.txt](https://docs.thedelight.co/llms.txt). See the
132
+ [AI Agents guide](https://docs.thedelight.co/guides/ai-agents/).
133
+
134
+ ## License
135
+
136
+ MIT
package/SKILL.md ADDED
@@ -0,0 +1,149 @@
1
+ ---
2
+ name: delightstack
3
+ description: Use DelightStack (@delightstack/components) when building UI in this project — a Svelte 5 component library with 50+ accessible, themeable components. Consult this skill when adding, styling, or wiring up any UI component, form, dialog, media viewer, or navigation element.
4
+ ---
5
+
6
+ # DelightStack components
7
+
8
+ DelightStack is this project's component library: 50+ Svelte 5 components built on
9
+ runes, with theming via CSS design tokens. Prefer a DelightStack component over
10
+ hand-rolling UI or adding another UI dependency.
11
+
12
+ ## Setup (skip if already installed)
13
+
14
+ ```bash
15
+ pnpm add @delightstack/components @delightstack/styles
16
+ ```
17
+
18
+ Import the design tokens once at the app root (e.g. the root `+layout.svelte`):
19
+
20
+ ```ts
21
+ import '@delightstack/styles';
22
+ ```
23
+
24
+ ## Core conventions
25
+
26
+ - **Single import point:** `import { Button, Input, Modal } from '@delightstack/components';`
27
+ Unused components are tree-shaken; there is no need for sub-path imports — with two
28
+ exceptions: `PDF` imports from `@delightstack/components/pdf` and `Panorama` from
29
+ `@delightstack/components/panorama` (they have heavy optional peer deps).
30
+ - **Props are snake_case, callbacks are camelCase:** `snap_points`, `max_width`,
31
+ `morph_percent` vs `onclick`, `onchange`, `onsubmit`. This is intentional — do not
32
+ "fix" it.
33
+ - **Callback props, not dispatched events.** When a callback returns a Promise, the
34
+ component automatically shows a loading state (e.g. `<Button onclick={save}>` spins
35
+ until `save()` resolves).
36
+ - **Two-way binding** with `bind:value` on form components, plus component-specific
37
+ bindables like `bind:open` (Modal, BottomSheet), `bind:snap`, `bind:page`.
38
+ - **Entity-backed forms:** when the data lives in a `Database.table()` (from
39
+ `@delightstack/database`), pass the entity to the Form and spread its field props —
40
+ `<Form entity={person}><Input {...person.form.field.email} /></Form>`. No
41
+ `bind:value`, no schema, no submit handler: values flow through the form context
42
+ (a field with a `name` and no `value`/`checked` prop is context-driven), each
43
+ field validates via its spread `parse`, and submit normalizes the draft then calls
44
+ `entity.save()` (`onsaved` fires on success; submit Buttons auto-disable while
45
+ saving). Works for create (`db.entity('person')`, no id) and edit. Boolean fields
46
+ spread onto `Checkbox` or `Toggle`, enum fields onto `Select` (the spread includes
47
+ ready-made `options`). Optional non-defaulted booleans are tri-state: unanswered
48
+ (`null`) displays as indeterminate — Checkbox resolves to checked on click (native
49
+ behavior) while Toggle gets a three-stop track the user can cycle back to the
50
+ middle; defaulted booleans display (and save) their default when unanswered. Standalone (no Form), `Input`/`Select` run `parse` on blur/close and
51
+ show the message below the field. Full guide:
52
+ https://docs.thedelight.co/guides/forms.md
53
+ - **Svelte 5 snippets** (`{#snippet header()}…{/snippet}`), not slots, for named
54
+ content areas.
55
+ - **Theming:** components read CSS custom properties from `@delightstack/styles`.
56
+ Re-theme by overriding `--color-primary` (re-derives the palette) or individual
57
+ tokens (`--color-action`, `--radius-md`, …) in your own CSS. Dark mode is built in
58
+ via `light-dark()` token values — never hardcode colors next to components.
59
+ - **Optional peer deps:** `three` (Panorama) and `pdfjs-dist` (PDF) must be installed
60
+ by the consuming app. They are dynamically imported; in Vite dev, add them to
61
+ `optimizeDeps.include` so they are not stubbed as absent.
62
+ - **TypeScript:** prop and data types ship with the package —
63
+ `import type { SelectOption, TableColumn, TreeNode, … } from '@delightstack/components';`
64
+
65
+ ## Looking up a component's full API
66
+
67
+ Every docs page is available as plain markdown. Fetch
68
+ `https://docs.thedelight.co/<docs path>` from the index below — each page includes
69
+ usage examples plus complete Props / Events / CSS Variables / Accessibility tables.
70
+ Also available: `https://docs.thedelight.co/llms.txt` (index) and `/llms-full.txt`
71
+ (all docs in one file). When in doubt about a prop name or type, check the docs page,
72
+ or read the component source shipped in `node_modules/@delightstack/components/dist/`
73
+ — the `.svelte` files there carry full JSDoc on every prop, and the `.d.ts` files
74
+ have the exact types. Do not guess prop names.
75
+
76
+ ## Component index
77
+
78
+ ### Actions
79
+ - `Button` — Polished button with ripple, promise-aware loading, dropdown menus, confirmation flows (docs: /components/actions/button.md)
80
+ - `ButtonGroup` — Groups related buttons with shared borders and context-driven prop inheritance (docs: /components/actions/button-group.md)
81
+ - `Modal` — Dialog overlay with animations, focus trapping, backdrop blur, crossfade transitions (docs: /components/actions/modal.md)
82
+ - `Alert` — Confirmation dialog built on Modal; programmatic yes/no `alert()` API (docs: /components/actions/alert.md)
83
+ - `Popover` — Floating container with Floating UI positioning, trigger modes, hover-safe diagonal movement (docs: /components/actions/popover.md)
84
+ - `ContextMenu` — Right-click menu via `{@attach contextMenu()}` attachment (docs: /components/actions/context-menu.md)
85
+ - `Portal` — Renders children elsewhere in the DOM, escaping overflow and stacking contexts (docs: /components/actions/portal.md)
86
+ - `CommandPalette` — Keyboard command interface with fuzzy search, recents, categories (docs: /components/actions/command-palette.md)
87
+ - `ThemeToggle` — Light/dark/auto theme switcher with animated sun-moon morph (docs: /components/actions/theme-toggle.md)
88
+
89
+ ### Display
90
+ - `Accordion` / `AccordionItem` — Stacked collapsible sections; default/`filled`/`outline` variants, optional `separated` mode where the open item splits the surface into rounded pieces (docs: /components/display/accordion.md)
91
+ - `Avatar` — Profile image with initials fallback, status indicators, deterministic colors (docs: /components/display/avatar.md)
92
+ - `AvatarGroup` — Stacked overlapping avatars with overflow indicator (docs: /components/display/avatar-group.md)
93
+ - `Calendar` — Date display/selection with single, range, and multiple modes (docs: /components/display/calendar.md)
94
+ - `Chart` — Data visualization: line, area, bar, horizontal bar, pie, donut (docs: /components/display/chart.md)
95
+ - `Code` — Syntax-highlighted code block with line numbers, copy, diff display (docs: /components/display/code.md)
96
+ - `Comparison` — Before/after image slider using CSS clip-path reveal (docs: /components/display/comparison.md)
97
+ - `Counter` — Animated count-up/down number with scroll-into-view trigger (docs: /components/display/counter.md)
98
+ - `Expand` — Animated expand/collapse container (docs: /components/display/expand.md)
99
+ - `List` / `ListItem` — Selection-aware list; items act as buttons, radios, checkboxes, submenus (docs: /components/display/list.md, /components/display/list-item.md)
100
+ - `QR` — QR code generator rendering crisp SVGs with colors, logo overlay, download (docs: /components/display/qr.md)
101
+ - `SplitPane` — Resizable two-pane split with drag, keyboard, snap, collapse (docs: /components/display/split-pane.md)
102
+ - `Stat` — Key metric display with labels, icons, change indicators (docs: /components/display/stat.md)
103
+ - `Table` — Data table: sorting, pagination, selection, inline editing, CSV/JSON export (docs: /components/display/table.md)
104
+ - `Timeline` / `TimelineItem` — Chronological events, vertical/horizontal, scroll-reveal (docs: /components/display/timeline.md)
105
+ - `Tree` — Hierarchical data with expand/collapse, checkboxes, drag-and-drop, lazy loading, search (docs: /components/display/tree.md)
106
+ - `Typewriter` — Character-by-character typing animation with text cycling (docs: /components/display/typewriter.md)
107
+
108
+ ### Feedback
109
+ - `Callout` — Highlighted information block; inline callouts or full-width banners (docs: /components/feedback/callout.md)
110
+ - `Confetti` — Canvas confetti celebration; programmatic `confetti()` or declarative component (docs: /components/feedback/confetti.md)
111
+ - `Progress` — Unified loading indicator: circular spinners, linear bars, overlays (docs: /components/feedback/progress.md)
112
+ - `Toaster` — Toast container; notifications created programmatically via `toast()` (docs: /components/feedback/toast.md)
113
+
114
+ ### Form
115
+ - `Checkbox` — Styled checkbox with animated checkmark and indeterminate state (docs: /components/form/checkbox.md)
116
+ - `Fieldset` — Semantic form-field grouping with optional border, grid layout, collapsible sections (docs: /components/form/fieldset.md)
117
+ - `FileUpload` — Drag-and-drop file upload with previews; dropzone, compact, avatar variants (docs: /components/form/file-upload.md)
118
+ - `Form` — Form container with Standard Schema validation, field-level validators, promise-aware submit, error auto-focus (docs: /components/form/form.md)
119
+ - `Input` — 13 input types with floating labels, autocomplete, chips, masking, password strength, `parse` validation (docs: /components/form/input.md)
120
+ - `Radio` / `RadioGroup` — Styled radio buttons, standalone or grouped (docs: /components/form/radio.md)
121
+ - `Range` — Slider with two-thumb range mode, tick marks, value tooltips (docs: /components/form/range.md)
122
+ - `Rating` — Star rating input with half-star precision, custom icons, read-only mode (docs: /components/form/rating.md)
123
+ - `Select` — Dropdown with search, multi-select chips, groups, async loading, virtual scrolling (docs: /components/form/select.md)
124
+ - `Toggle` — On/off switch with slide animation, three-state mode, `parse` validation (docs: /components/form/toggle.md)
125
+
126
+ ### Media
127
+ - `Gallery` — Media gallery with seven display modes plus headless lightbox (docs: /components/media/gallery.md)
128
+ - `Carousel` — Low-level media viewport behind Gallery: swipe, pinch-zoom, mixed media (docs: /components/media/carousel.md)
129
+ - `Image` — Optimized image with lazy loading, blur-up placeholder, skeleton shimmer (docs: /components/media/image.md)
130
+ - `Panorama` — Three.js 360° viewer; import from `@delightstack/components/panorama` (docs: /components/media/panorama.md)
131
+ - `PDF` — Full PDF viewer; import from `@delightstack/components/pdf` (docs: /components/media/pdf.md)
132
+ - `Video` — Custom video player with HLS quality switching, captions, PiP (docs: /components/media/video.md)
133
+
134
+ ### Navigation
135
+ - `BottomSheet` — Mobile slide-up panel with snap points, spring gestures, pull-to-dismiss (docs: /components/navigation/bottom-sheet.md)
136
+ - `Breadcrumbs` — Navigation trail with auto home icon and SSR-safe collapsing (docs: /components/navigation/breadcrumbs.md)
137
+ - `Pagination` — Page navigation with ellipsis algorithm and page size selector (docs: /components/navigation/pagination.md)
138
+ - `Steps` / `Step` — Multi-step progress indicator with animated wizard mode, error states, and horizontal overflow paging (docs: /components/navigation/steps.md)
139
+ - `Tabs` — Data-driven tabbed navigation (`tabs={[{ label, badge, disabled, content }]}` + `bind:tab` index); spring sliding indicator; underline / pills / boxed (segmented) variants; vertical orientation; ripple feedback; fade/slide content transitions (docs: /components/navigation/tabs.md)
140
+
141
+ ## Beyond components
142
+
143
+ DelightStack also ships a Cloudflare-native backend stack (`@delightstack/auth`,
144
+ `database`, `websocket`, `presence`, `ai`, `stripe`, `images`, `rate-limiter`). Overview:
145
+ https://docs.thedelight.co/stack/overview.md
146
+
147
+ `@delightstack/presence` adds real-time presence (live cursors, online roster, cursor
148
+ chat, reactions, field presence) on a swappable transport/identity. Docs:
149
+ https://docs.thedelight.co/packages/presence.md
package/bin/agents.js ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `delightstack-agents` — sets up AI coding agents to use DelightStack well.
4
+ *
5
+ * - Installs the DelightStack skill at .claude/skills/delightstack/SKILL.md
6
+ * (picked up automatically by Claude Code)
7
+ * - Appends a short pointer section to AGENTS.md (read by most coding agents;
8
+ * created if missing) referencing the skill and the markdown docs
9
+ *
10
+ * Run from your project root: `pnpm exec delightstack-agents`
11
+ * Pass `--print` to write the skill to stdout instead of touching any files.
12
+ */
13
+ import {
14
+ copyFileSync,
15
+ existsSync,
16
+ mkdirSync,
17
+ readFileSync,
18
+ appendFileSync,
19
+ } from 'node:fs';
20
+ import { join, dirname } from 'node:path';
21
+ import { fileURLToPath } from 'node:url';
22
+
23
+ const skillSource = join(dirname(fileURLToPath(import.meta.url)), '..', 'SKILL.md');
24
+
25
+ if (process.argv.includes('--print')) {
26
+ process.stdout.write(readFileSync(skillSource, 'utf-8'));
27
+ process.exit(0);
28
+ }
29
+
30
+ const root = process.cwd();
31
+ if (!existsSync(join(root, 'package.json'))) {
32
+ console.error('No package.json found — run this from your project root.');
33
+ process.exit(1);
34
+ }
35
+
36
+ // 1. Install the skill for Claude Code (and any agent that reads .claude/skills)
37
+ const skillDir = join(root, '.claude', 'skills', 'delightstack');
38
+ mkdirSync(skillDir, { recursive: true });
39
+ copyFileSync(skillSource, join(skillDir, 'SKILL.md'));
40
+ console.log('✓ Installed .claude/skills/delightstack/SKILL.md');
41
+
42
+ // 2. Point AGENTS.md at the skill (idempotent via marker comment)
43
+ const MARKER = '<!-- delightstack-agents -->';
44
+ const SECTION = `\n${MARKER}\n## UI components: DelightStack\n\nThis project uses DelightStack (\`@delightstack/components\`) for UI. Before building\nor changing UI, read \`.claude/skills/delightstack/SKILL.md\` (also at\n\`node_modules/@delightstack/components/SKILL.md\`) — it has the component index and\nconventions. Full docs as markdown: https://docs.thedelight.co/llms.txt (append \`.md\`\nto any docs page URL).\n`;
45
+
46
+ const agentsFile = join(root, 'AGENTS.md');
47
+ const existing = existsSync(agentsFile) ? readFileSync(agentsFile, 'utf-8') : '';
48
+ if (existing.includes(MARKER)) {
49
+ console.log('✓ AGENTS.md already references DelightStack — left unchanged');
50
+ } else {
51
+ appendFileSync(
52
+ agentsFile,
53
+ (existing && !existing.endsWith('\n') ? '\n' : '') + SECTION,
54
+ );
55
+ console.log(
56
+ `✓ ${existing ? 'Updated' : 'Created'} AGENTS.md with a DelightStack section`,
57
+ );
58
+ }
59
+
60
+ console.log('\nAgents in this project now know how to use DelightStack.');
61
+ console.log(
62
+ 'Tip: if you use CLAUDE.md instead of AGENTS.md, move the appended section there.',
63
+ );
@@ -0,0 +1,202 @@
1
+ <script lang="ts" module>
2
+ import type { Component } from 'svelte';
3
+
4
+ export interface AlertOptions {
5
+ /** The title text shown at the top of the dialog */
6
+ title?: string;
7
+ /** The main message text of the dialog */
8
+ message: string;
9
+ /** Label for the cancel button */
10
+ cancel_text?: string;
11
+ /** Label for the confirm button */
12
+ continue_text?: string;
13
+ /** Whether the confirm action is destructive (styles the confirm button as an error/danger action) */
14
+ destructive?: boolean;
15
+ /** Icon component shown alongside the message */
16
+ icon?: Component<Record<string, never>>;
17
+ }
18
+
19
+ /**
20
+ * Programmatic API: creates an Alert dialog imperatively and returns a Promise
21
+ * resolving to `true` (confirmed) or `false` (cancelled).
22
+ */
23
+ export async function alert(options: AlertOptions): Promise<boolean> {
24
+ const { mount, unmount } = await import('svelte');
25
+ const mod = await import('./Alert.svelte');
26
+ const AlertComponent = mod.default;
27
+
28
+ return new Promise((resolve) => {
29
+ let container = document.querySelector('.portals');
30
+ if (!container) {
31
+ container = document.createElement('div');
32
+ container.classList.add('portals');
33
+ document.body.appendChild(container);
34
+ }
35
+ const wrapper = document.createElement('div');
36
+ container.appendChild(wrapper);
37
+
38
+ let instance: Record<string, unknown>;
39
+
40
+ const props = $state({
41
+ open: false,
42
+ title: options.title || 'Confirm',
43
+ message: options.message,
44
+ cancel_text: options.cancel_text || 'Cancel',
45
+ continue_text: options.continue_text || 'Continue',
46
+ destructive: options.destructive || false,
47
+ icon: options.icon,
48
+ oncancel: () => cleanup(false),
49
+ oncontinue: () => cleanup(true),
50
+ });
51
+
52
+ function cleanup(result: boolean) {
53
+ resolve(result);
54
+ try {
55
+ unmount(instance);
56
+ } catch {
57
+ // already unmounted
58
+ }
59
+ wrapper.remove();
60
+ }
61
+
62
+ instance = mount(AlertComponent, {
63
+ target: wrapper,
64
+ props,
65
+ });
66
+
67
+ // Flip open on next frame so the Modal sees the false→true transition and animates in
68
+ requestAnimationFrame(() => {
69
+ props.open = true;
70
+ });
71
+ });
72
+ }
73
+ </script>
74
+
75
+ <script lang="ts">
76
+ import Modal from './Modal.svelte';
77
+ import Button from './Button.svelte';
78
+
79
+ const propId = $props.id();
80
+ let {
81
+ /** Controls visibility */
82
+ open = $bindable(false) as boolean,
83
+
84
+ /** Alert title */
85
+ title = 'Confirm',
86
+
87
+ /** Alert message / question */
88
+ message = '',
89
+
90
+ /** Cancel button label */
91
+ cancel_text = 'Cancel',
92
+
93
+ /** Confirm button label */
94
+ continue_text = 'Continue',
95
+
96
+ /** Style confirm button with error color */
97
+ destructive = false,
98
+
99
+ /** Optional icon displayed above the title */
100
+ icon: Icon = undefined as Component<Record<string, never>> | undefined,
101
+
102
+ /** Element ID */
103
+ id = propId,
104
+
105
+ /** Additional CSS classes */
106
+ class: class_name = '',
107
+
108
+ /** Called when Cancel is clicked */
109
+ oncancel = undefined as (() => void) | undefined,
110
+
111
+ /** Called when Confirm is clicked; promise-aware */
112
+ oncontinue = undefined as (() => void | Promise<void>) | undefined,
113
+ } = $props();
114
+
115
+ function handleCancel() {
116
+ open = false;
117
+ oncancel?.();
118
+ }
119
+
120
+ function handleBackdropClick() {
121
+ handleCancel();
122
+ }
123
+
124
+ function handleClose() {
125
+ handleCancel();
126
+ return true;
127
+ }
128
+ </script>
129
+
130
+ <Modal
131
+ bind:open
132
+ title=""
133
+ closable
134
+ disable_close_icon
135
+ width="400px"
136
+ max_width="calc(100vw - 2rem)"
137
+ onclose={handleClose}
138
+ onbackdropclick={handleBackdropClick}
139
+ {id}
140
+ class="alert-modal {class_name}">
141
+ <div class="alert">
142
+ {#if Icon}
143
+ <div class="icon" class:destructive>
144
+ <Icon />
145
+ </div>
146
+ {/if}
147
+ {#if title}
148
+ <h3>{title}</h3>
149
+ {/if}
150
+ {#if message}
151
+ <p>{message}</p>
152
+ {/if}
153
+ <div class="actions">
154
+ <Button error={destructive} full_width onclick={oncontinue}>
155
+ {continue_text}
156
+ </Button>
157
+ <Button translucent full_width onclick={handleCancel}>
158
+ {cancel_text}
159
+ </Button>
160
+ </div>
161
+ </div>
162
+ </Modal>
163
+
164
+ <style>
165
+ .alert {
166
+ text-align: center;
167
+ padding: 0.5rem 0;
168
+ }
169
+
170
+ .icon {
171
+ display: flex;
172
+ justify-content: center;
173
+ margin-bottom: 0.75rem;
174
+ color: var(--color-text-muted);
175
+ font-size: 2rem;
176
+
177
+ &.destructive {
178
+ color: var(--color-error);
179
+ }
180
+ }
181
+
182
+ h3 {
183
+ font-size: var(--text-lg, 1.125rem);
184
+ font-weight: var(--font-weight-semibold, 600);
185
+ color: var(--color-text);
186
+ margin: 0 0 0.5rem;
187
+ }
188
+
189
+ p {
190
+ font-size: var(--text-base, 1rem);
191
+ color: var(--color-text-muted);
192
+ line-height: var(--leading-relaxed, 1.75);
193
+ margin: 0;
194
+ }
195
+
196
+ .actions {
197
+ display: flex;
198
+ flex-direction: column;
199
+ gap: 0.5rem;
200
+ padding-top: 1.5rem;
201
+ }
202
+ </style>
@@ -0,0 +1,36 @@
1
+ import type { Component } from 'svelte';
2
+ export interface AlertOptions {
3
+ /** The title text shown at the top of the dialog */
4
+ title?: string;
5
+ /** The main message text of the dialog */
6
+ message: string;
7
+ /** Label for the cancel button */
8
+ cancel_text?: string;
9
+ /** Label for the confirm button */
10
+ continue_text?: string;
11
+ /** Whether the confirm action is destructive (styles the confirm button as an error/danger action) */
12
+ destructive?: boolean;
13
+ /** Icon component shown alongside the message */
14
+ icon?: Component<Record<string, never>>;
15
+ }
16
+ /**
17
+ * Programmatic API: creates an Alert dialog imperatively and returns a Promise
18
+ * resolving to `true` (confirmed) or `false` (cancelled).
19
+ */
20
+ export declare function alert(options: AlertOptions): Promise<boolean>;
21
+ declare const Alert: Component<{
22
+ open?: boolean;
23
+ title?: string;
24
+ message?: string;
25
+ cancel_text?: string;
26
+ continue_text?: string;
27
+ destructive?: boolean;
28
+ icon?: Component<Record<string, never>> | undefined;
29
+ id?: string;
30
+ class?: string;
31
+ oncancel?: (() => void) | undefined;
32
+ oncontinue?: (() => void | Promise<void>) | undefined;
33
+ }, {}, "open">;
34
+ type Alert = ReturnType<typeof Alert>;
35
+ export default Alert;
36
+ //# sourceMappingURL=Alert.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Alert.svelte.d.ts","sourceRoot":"","sources":["../../src/actions/Alert.svelte.ts"],"names":[],"mappings":"AAGC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,WAAW,YAAY;IAC5B,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sGAAsG;IACtG,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iDAAiD;IACjD,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAiDnE;AA2FF,QAAA,MAAM,KAAK;WAjFqE,OAAO;YAAU,MAAM;cAAY,MAAM;kBAAgB,MAAM;oBAAkB,MAAM;kBAAgB,OAAO;WAAS,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,GAAG,SAAS;;YAA8B,MAAM;eAAa,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;iBAAe,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS;cAiFhU,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}