compote-ui 0.80.0 → 0.81.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.
Files changed (33) hide show
  1. package/dist/components/data-table-v9/column-filter-kind.d.ts +10 -1
  2. package/dist/components/data-table-v9/column-filter-kind.js +7 -0
  3. package/dist/components/data-table-v9/data-table-head.svelte +230 -230
  4. package/dist/components/data-table-v9/data-table.svelte +154 -154
  5. package/dist/components/data-table-v9/filter-editors/boolean-filter-editor.svelte +45 -45
  6. package/dist/components/data-table-v9/filter-editors/column-filter-editor.svelte +39 -33
  7. package/dist/components/data-table-v9/filter-editors/column-filter-editor.svelte.d.ts +7 -2
  8. package/dist/components/data-table-v9/filter-editors/date-range-filter-editor.svelte +52 -52
  9. package/dist/components/data-table-v9/filter-editors/range-filter-editor.svelte +51 -51
  10. package/dist/components/data-table-v9/filter-editors/select-filter-editor.svelte +59 -59
  11. package/dist/components/data-table-v9/filter-editors/text-filter-editor.svelte +20 -20
  12. package/dist/components/data-table-v9/header/column-header-filter.svelte +66 -66
  13. package/dist/components/data-table-v9/index.d.ts +9 -1
  14. package/dist/components/data-table-v9/index.js +7 -0
  15. package/dist/components/data-table-v9/toolbar/data-table-column-filter.svelte +203 -203
  16. package/dist/components/data-table-v9/toolbar/data-table-toolbar.svelte +4 -1
  17. package/dist/components/data-table-v9/types.d.ts +3 -1
  18. package/dist/components/data-table-v9/virtual/data-table-virtualized.svelte +82 -82
  19. package/dist/components/data-table-v9/virtual/index.d.ts +2 -2
  20. package/dist/components/data-table-v9/virtual/index.js +1 -1
  21. package/dist/components/dialog/alert-dialog.svelte +73 -73
  22. package/dist/components/dialog/dialog-root.svelte +45 -45
  23. package/dist/components/drawer/drawer-content.svelte +213 -213
  24. package/dist/components/popover/popover-content.svelte +97 -97
  25. package/dist/components/popover/popover-description.svelte +19 -19
  26. package/dist/components/popover/popover-root.svelte +27 -27
  27. package/dist/components/popover/popover-title.svelte +19 -19
  28. package/dist/icons/PhFunnelFill.svelte +19 -19
  29. package/package.json +1 -1
  30. package/skills/component-usage/references/overlays-and-floating-ui.md +278 -278
  31. package/skills/data-table/SKILL.md +362 -314
  32. package/skills/data-table/references/column-options.md +175 -175
  33. package/skills/data-table/references/table-state-and-reactivity.md +65 -65
@@ -1,278 +1,278 @@
1
- # Overlays And Floating UI
2
-
3
- `Dialog`, `Drawer`, `Menu`, `Popover`, `HoverCard`, `Tooltip`, and `Toast` are namespace exports.
4
- `AlertDialog` is a single component, not a namespace.
5
-
6
- ## Dialog
7
-
8
- ```svelte
9
- <script lang="ts">
10
- let open = $state(false);
11
- </script>
12
-
13
- <Dialog.Root bind:open>
14
- <Dialog.Title>Confirm Action</Dialog.Title>
15
- <Dialog.Description>This cannot be undone.</Dialog.Description>
16
- <Dialog.Footer>
17
- <Dialog.CloseTrigger>Cancel</Dialog.CloseTrigger>
18
- <Button onclick={() => (open = false)}>Confirm</Button>
19
- </Dialog.Footer>
20
- <Dialog.CloseTrigger />
21
- </Dialog.Root>
22
- ```
23
-
24
- Use `onOpenChange`, not `onClose` — `Dialog` has no `onClose` prop:
25
-
26
- ```svelte
27
- <Dialog.Root
28
- bind:open
29
- onOpenChange={(details) => {
30
- if (!details.open) handleClose();
31
- }}
32
- >
33
- <Dialog.Title>Title</Dialog.Title>
34
- </Dialog.Root>
35
- ```
36
-
37
- `Dialog.CloseTrigger` with no children renders an absolute-positioned X icon in the corner
38
- automatically — no separate placement needed. With children, it renders as an inline button (for
39
- `Dialog.Footer`). `contentClass` sets dialog width (e.g. `contentClass="max-w-4xl"`).
40
-
41
- **Stacking:** z-index defaults to `50`. Set the `--layer-index` CSS variable on the dialog's
42
- container to offset it (e.g. `style="--layer-index: 10"` → z-index 60) — use this when a dialog
43
- must appear above another fixed element like a drawer.
44
-
45
- ## Drawer
46
-
47
- Slide-in panel anchored to a viewport edge, with swipe-to-dismiss and snap points.
48
- `Drawer.Content` renders the backdrop and positioner internally — compose only
49
- `Header`/`Body`/`Footer`.
50
-
51
- ```svelte
52
- <Drawer.Root bind:open>
53
- <Drawer.Content>
54
- <Drawer.CloseTrigger />
55
- <Drawer.Header>
56
- <Drawer.Title>Edit Record</Drawer.Title>
57
- </Drawer.Header>
58
- <Drawer.Body>Scrollable content</Drawer.Body>
59
- <Drawer.Footer>
60
- <Button variant="ghost" onclick={() => (open = false)}>Cancel</Button>
61
- <Button>Save</Button>
62
- </Drawer.Footer>
63
- </Drawer.Content>
64
- </Drawer.Root>
65
- ```
66
-
67
- `swipeDirection?: 'up' | 'down' | 'start' | 'end'` (default `'down'`) controls which edge it slides
68
- from: `'down'` = bottom sheet (default), `'up'` = top, `'start'` = left (LTR), `'end'` = right
69
- (LTR). `Drawer.Body` scrolls internally via `ScrollArea` — no fixed height needed. Safe to open a
70
- `Dialog` from inside a `Drawer` (it portals above it, same z-index, stacked by DOM order).
71
-
72
- Sizing and styling overrides:
73
-
74
- ```svelte
75
- <!-- Custom height (bottom/top drawers, default 96svh) -->
76
- <Drawer.Content maxHeight="50vh">...</Drawer.Content>
77
-
78
- <!-- Custom width (side drawers, default 25rem) -->
79
- <Drawer.Content maxWidth="32rem">...</Drawer.Content>
80
-
81
- <!-- Custom backdrop/positioner classes (power users) -->
82
- <Drawer.Content backdropClass="bg-black/80" positionerClass="items-center">...</Drawer.Content>
83
- ```
84
-
85
- `Drawer.Grabber`/`Drawer.GrabberIndicator` render a drag handle (top edge for bottom/top drawers,
86
- open edge for side drawers) — repositions automatically per `swipeDirection`.
87
-
88
- ## AlertDialog
89
-
90
- For confirmations — built-in confirm/cancel buttons, no custom body.
91
-
92
- ```svelte
93
- <AlertDialog
94
- bind:open={deleteOpen}
95
- title="Delete item?"
96
- description="This action cannot be undone."
97
- variant="destructive"
98
- confirmLabel="Delete"
99
- onConfirm={handleDelete}
100
- />
101
- ```
102
-
103
- Props: `open` (bindable), `title`, `description?: string | string[]`,
104
- `variant?: 'default' | 'destructive'`, `confirmLabel?`, `cancelLabel?`, `onConfirm?`, `onCancel?`.
105
-
106
- ## Menu
107
-
108
- Composable dropdown with items, groups, checkboxes, radio items, context trigger, and submenus.
109
-
110
- ```svelte
111
- <Menu.Root>
112
- <Menu.Trigger variant="outline">
113
- Options
114
- <Menu.Indicator />
115
- </Menu.Trigger>
116
- <Menu.Content>
117
- <Menu.Item value="new">New File</Menu.Item>
118
- <Menu.Item value="save">Save</Menu.Item>
119
- <Menu.Separator />
120
- <Menu.Item value="quit" disabled>Quit</Menu.Item>
121
- </Menu.Content>
122
- </Menu.Root>
123
- ```
124
-
125
- Groups, checkboxes, and radio items:
126
-
127
- ```svelte
128
- <Menu.Content>
129
- <Menu.ItemGroup>
130
- <Menu.ItemGroupLabel>View</Menu.ItemGroupLabel>
131
- <Menu.CheckboxItem value="sidebar" checked={sidebar} onCheckedChange={(v) => (sidebar = v)}>
132
- Show Sidebar
133
- </Menu.CheckboxItem>
134
- </Menu.ItemGroup>
135
- <Menu.RadioItemGroup value={theme} onValueChange={(d) => (theme = d.value)}>
136
- <Menu.RadioItem value="light">Light</Menu.RadioItem>
137
- <Menu.RadioItem value="dark">Dark</Menu.RadioItem>
138
- </Menu.RadioItemGroup>
139
- </Menu.Content>
140
- ```
141
-
142
- Right-click context menu — use `Menu.ContextTrigger` instead of `Menu.Trigger`:
143
-
144
- ```svelte
145
- <Menu.Root>
146
- <Menu.ContextTrigger>
147
- <div class="rounded border p-8 text-center">Right-click here</div>
148
- </Menu.ContextTrigger>
149
- <Menu.Content>
150
- <Menu.Item value="copy">Copy</Menu.Item>
151
- </Menu.Content>
152
- </Menu.Root>
153
- ```
154
-
155
- Submenu — nest a `Menu.Root` after a `Menu.TriggerItem`:
156
-
157
- ```svelte
158
- <Menu.Content>
159
- <Menu.TriggerItem>Export as...</Menu.TriggerItem>
160
- <Menu.Root>
161
- <Menu.Content>
162
- <Menu.Item value="pdf">PDF</Menu.Item>
163
- <Menu.Item value="csv">CSV</Menu.Item>
164
- </Menu.Content>
165
- </Menu.Root>
166
- </Menu.Content>
167
- ```
168
-
169
- ## Popover
170
-
171
- Composable floating panel anchored to a trigger.
172
-
173
- ```svelte
174
- <Popover.Root>
175
- <Popover.Trigger>
176
- <Button>Open Popover</Button>
177
- </Popover.Trigger>
178
- <Popover.Content>
179
- <Popover.Title>Popover Title</Popover.Title>
180
- <Popover.Description>Content here.</Popover.Description>
181
- <Popover.CloseTrigger />
182
- </Popover.Content>
183
- </Popover.Root>
184
- ```
185
-
186
- `Popover.Content` accepts `showArrow?: boolean` (default `true`) and forwards other props to Ark's
187
- `Popover.Content`. Control placement via `<Popover.Root positioning={{ placement: 'right' }}>`.
188
-
189
- The dialog is labelled automatically: while a `Popover.Title` / `Popover.Description` is rendered
190
- inside, `Popover.Content` gets `aria-labelledby` / `aria-describedby` pointing at it — no `ids` or
191
- manual `aria-*` needed (Zag alone misses them because content mounts lazily). An explicit
192
- `aria-labelledby` / `aria-describedby` (or `aria-label`, for the title) on `Popover.Content` wins.
193
-
194
- ## HoverCard
195
-
196
- Floating card that opens on **hover**, not click — key difference from `Popover`. Use `asChild` on
197
- the trigger to render any element (e.g. a link) instead of the default button.
198
-
199
- ```svelte
200
- <HoverCard.Root>
201
- <p>
202
- Liked by
203
- <HoverCard.Trigger>
204
- {#snippet asChild(props)}
205
- <a href="/profile" {...props()} class="font-medium text-primary underline"> @sarah_chen </a>
206
- {/snippet}
207
- </HoverCard.Trigger>
208
- </p>
209
- <HoverCard.Content>
210
- <p class="text-sm text-ink">Bio text here.</p>
211
- </HoverCard.Content>
212
- </HoverCard.Root>
213
- ```
214
-
215
- `openDelay?: number` (default `600`), `closeDelay?: number` (default `300`) on `HoverCard.Root`.
216
-
217
- ## Tooltip
218
-
219
- Namespace export wrapping Ark UI Tooltip — short text hint shown on hover/focus.
220
-
221
- ```svelte
222
- <Tooltip.Root>
223
- <Tooltip.Trigger>
224
- <Button variant="ghost" size="icon" aria-label="Info"><PhInfo /></Button>
225
- </Tooltip.Trigger>
226
- <Tooltip.Content>More information</Tooltip.Content>
227
- </Tooltip.Root>
228
- ```
229
-
230
- Prefer `Tooltip` over `HoverCard` for a single line of supplementary text; use `HoverCard` for
231
- richer content (profile previews, formatted descriptions).
232
-
233
- ## Toast
234
-
235
- Toaster setup belongs once in the root layout:
236
-
237
- ```svelte
238
- <!-- +layout.svelte -->
239
- <Toast.Toaster />
240
- {@render children()}
241
- ```
242
-
243
- Then fire toasts anywhere:
244
-
245
- ```ts
246
- import { toast } from 'compote-ui';
247
-
248
- toast.success('Saved');
249
- toast.error('Save failed', { description: 'Please try again.' });
250
- toast.promise(saveData(), {
251
- loading: { title: 'Saving…' },
252
- success: { title: 'Saved' },
253
- error: { title: 'Save failed' }
254
- });
255
- ```
256
-
257
- Shorthand helpers: `toast.info()`, `toast.success()`, `toast.warning()`, `toast.error()`,
258
- `toast.loading()` — first arg is the title, second an optional options object; each returns the
259
- toast `id` usable with `toast.update(id, options)` / `toast.dismiss(id)`. `loading` shows a
260
- spinner and does not auto-dismiss. `toast.create(options)` remains available for full control.
261
-
262
- Action button (e.g. Undo):
263
-
264
- ```ts
265
- toast.create({
266
- title: 'File deleted',
267
- type: 'info',
268
- action: { label: 'Undo', onClick: () => restore() }
269
- });
270
- ```
271
-
272
- `toast.create()` options: `title: string`, `description?: string`,
273
- `type?: 'info' | 'success' | 'error' | 'warning' | 'loading'`, `duration?: number` (ms, overrides
274
- the toaster default for this toast), `action?: { label: string; onClick: () => void }`.
275
-
276
- `Toast.Toaster` props: `class?: ClassValue`, `toaster?: CreateToasterReturn` (a custom instance
277
- from `createToaster()` for a different `placement`/`max`/`duration` — defaults to the shared
278
- `toast` singleton). Default placement is `bottom-end`; timers pause while the tab is hidden.
1
+ # Overlays And Floating UI
2
+
3
+ `Dialog`, `Drawer`, `Menu`, `Popover`, `HoverCard`, `Tooltip`, and `Toast` are namespace exports.
4
+ `AlertDialog` is a single component, not a namespace.
5
+
6
+ ## Dialog
7
+
8
+ ```svelte
9
+ <script lang="ts">
10
+ let open = $state(false);
11
+ </script>
12
+
13
+ <Dialog.Root bind:open>
14
+ <Dialog.Title>Confirm Action</Dialog.Title>
15
+ <Dialog.Description>This cannot be undone.</Dialog.Description>
16
+ <Dialog.Footer>
17
+ <Dialog.CloseTrigger>Cancel</Dialog.CloseTrigger>
18
+ <Button onclick={() => (open = false)}>Confirm</Button>
19
+ </Dialog.Footer>
20
+ <Dialog.CloseTrigger />
21
+ </Dialog.Root>
22
+ ```
23
+
24
+ Use `onOpenChange`, not `onClose` — `Dialog` has no `onClose` prop:
25
+
26
+ ```svelte
27
+ <Dialog.Root
28
+ bind:open
29
+ onOpenChange={(details) => {
30
+ if (!details.open) handleClose();
31
+ }}
32
+ >
33
+ <Dialog.Title>Title</Dialog.Title>
34
+ </Dialog.Root>
35
+ ```
36
+
37
+ `Dialog.CloseTrigger` with no children renders an absolute-positioned X icon in the corner
38
+ automatically — no separate placement needed. With children, it renders as an inline button (for
39
+ `Dialog.Footer`). `contentClass` sets dialog width (e.g. `contentClass="max-w-4xl"`).
40
+
41
+ **Stacking:** z-index defaults to `50`. Set the `--layer-index` CSS variable on the dialog's
42
+ container to offset it (e.g. `style="--layer-index: 10"` → z-index 60) — use this when a dialog
43
+ must appear above another fixed element like a drawer.
44
+
45
+ ## Drawer
46
+
47
+ Slide-in panel anchored to a viewport edge, with swipe-to-dismiss and snap points.
48
+ `Drawer.Content` renders the backdrop and positioner internally — compose only
49
+ `Header`/`Body`/`Footer`.
50
+
51
+ ```svelte
52
+ <Drawer.Root bind:open>
53
+ <Drawer.Content>
54
+ <Drawer.CloseTrigger />
55
+ <Drawer.Header>
56
+ <Drawer.Title>Edit Record</Drawer.Title>
57
+ </Drawer.Header>
58
+ <Drawer.Body>Scrollable content</Drawer.Body>
59
+ <Drawer.Footer>
60
+ <Button variant="ghost" onclick={() => (open = false)}>Cancel</Button>
61
+ <Button>Save</Button>
62
+ </Drawer.Footer>
63
+ </Drawer.Content>
64
+ </Drawer.Root>
65
+ ```
66
+
67
+ `swipeDirection?: 'up' | 'down' | 'start' | 'end'` (default `'down'`) controls which edge it slides
68
+ from: `'down'` = bottom sheet (default), `'up'` = top, `'start'` = left (LTR), `'end'` = right
69
+ (LTR). `Drawer.Body` scrolls internally via `ScrollArea` — no fixed height needed. Safe to open a
70
+ `Dialog` from inside a `Drawer` (it portals above it, same z-index, stacked by DOM order).
71
+
72
+ Sizing and styling overrides:
73
+
74
+ ```svelte
75
+ <!-- Custom height (bottom/top drawers, default 96svh) -->
76
+ <Drawer.Content maxHeight="50vh">...</Drawer.Content>
77
+
78
+ <!-- Custom width (side drawers, default 25rem) -->
79
+ <Drawer.Content maxWidth="32rem">...</Drawer.Content>
80
+
81
+ <!-- Custom backdrop/positioner classes (power users) -->
82
+ <Drawer.Content backdropClass="bg-black/80" positionerClass="items-center">...</Drawer.Content>
83
+ ```
84
+
85
+ `Drawer.Grabber`/`Drawer.GrabberIndicator` render a drag handle (top edge for bottom/top drawers,
86
+ open edge for side drawers) — repositions automatically per `swipeDirection`.
87
+
88
+ ## AlertDialog
89
+
90
+ For confirmations — built-in confirm/cancel buttons, no custom body.
91
+
92
+ ```svelte
93
+ <AlertDialog
94
+ bind:open={deleteOpen}
95
+ title="Delete item?"
96
+ description="This action cannot be undone."
97
+ variant="destructive"
98
+ confirmLabel="Delete"
99
+ onConfirm={handleDelete}
100
+ />
101
+ ```
102
+
103
+ Props: `open` (bindable), `title`, `description?: string | string[]`,
104
+ `variant?: 'default' | 'destructive'`, `confirmLabel?`, `cancelLabel?`, `onConfirm?`, `onCancel?`.
105
+
106
+ ## Menu
107
+
108
+ Composable dropdown with items, groups, checkboxes, radio items, context trigger, and submenus.
109
+
110
+ ```svelte
111
+ <Menu.Root>
112
+ <Menu.Trigger variant="outline">
113
+ Options
114
+ <Menu.Indicator />
115
+ </Menu.Trigger>
116
+ <Menu.Content>
117
+ <Menu.Item value="new">New File</Menu.Item>
118
+ <Menu.Item value="save">Save</Menu.Item>
119
+ <Menu.Separator />
120
+ <Menu.Item value="quit" disabled>Quit</Menu.Item>
121
+ </Menu.Content>
122
+ </Menu.Root>
123
+ ```
124
+
125
+ Groups, checkboxes, and radio items:
126
+
127
+ ```svelte
128
+ <Menu.Content>
129
+ <Menu.ItemGroup>
130
+ <Menu.ItemGroupLabel>View</Menu.ItemGroupLabel>
131
+ <Menu.CheckboxItem value="sidebar" checked={sidebar} onCheckedChange={(v) => (sidebar = v)}>
132
+ Show Sidebar
133
+ </Menu.CheckboxItem>
134
+ </Menu.ItemGroup>
135
+ <Menu.RadioItemGroup value={theme} onValueChange={(d) => (theme = d.value)}>
136
+ <Menu.RadioItem value="light">Light</Menu.RadioItem>
137
+ <Menu.RadioItem value="dark">Dark</Menu.RadioItem>
138
+ </Menu.RadioItemGroup>
139
+ </Menu.Content>
140
+ ```
141
+
142
+ Right-click context menu — use `Menu.ContextTrigger` instead of `Menu.Trigger`:
143
+
144
+ ```svelte
145
+ <Menu.Root>
146
+ <Menu.ContextTrigger>
147
+ <div class="rounded border p-8 text-center">Right-click here</div>
148
+ </Menu.ContextTrigger>
149
+ <Menu.Content>
150
+ <Menu.Item value="copy">Copy</Menu.Item>
151
+ </Menu.Content>
152
+ </Menu.Root>
153
+ ```
154
+
155
+ Submenu — nest a `Menu.Root` after a `Menu.TriggerItem`:
156
+
157
+ ```svelte
158
+ <Menu.Content>
159
+ <Menu.TriggerItem>Export as...</Menu.TriggerItem>
160
+ <Menu.Root>
161
+ <Menu.Content>
162
+ <Menu.Item value="pdf">PDF</Menu.Item>
163
+ <Menu.Item value="csv">CSV</Menu.Item>
164
+ </Menu.Content>
165
+ </Menu.Root>
166
+ </Menu.Content>
167
+ ```
168
+
169
+ ## Popover
170
+
171
+ Composable floating panel anchored to a trigger.
172
+
173
+ ```svelte
174
+ <Popover.Root>
175
+ <Popover.Trigger>
176
+ <Button>Open Popover</Button>
177
+ </Popover.Trigger>
178
+ <Popover.Content>
179
+ <Popover.Title>Popover Title</Popover.Title>
180
+ <Popover.Description>Content here.</Popover.Description>
181
+ <Popover.CloseTrigger />
182
+ </Popover.Content>
183
+ </Popover.Root>
184
+ ```
185
+
186
+ `Popover.Content` accepts `showArrow?: boolean` (default `true`) and forwards other props to Ark's
187
+ `Popover.Content`. Control placement via `<Popover.Root positioning={{ placement: 'right' }}>`.
188
+
189
+ The dialog is labelled automatically: while a `Popover.Title` / `Popover.Description` is rendered
190
+ inside, `Popover.Content` gets `aria-labelledby` / `aria-describedby` pointing at it — no `ids` or
191
+ manual `aria-*` needed (Zag alone misses them because content mounts lazily). An explicit
192
+ `aria-labelledby` / `aria-describedby` (or `aria-label`, for the title) on `Popover.Content` wins.
193
+
194
+ ## HoverCard
195
+
196
+ Floating card that opens on **hover**, not click — key difference from `Popover`. Use `asChild` on
197
+ the trigger to render any element (e.g. a link) instead of the default button.
198
+
199
+ ```svelte
200
+ <HoverCard.Root>
201
+ <p>
202
+ Liked by
203
+ <HoverCard.Trigger>
204
+ {#snippet asChild(props)}
205
+ <a href="/profile" {...props()} class="font-medium text-primary underline"> @sarah_chen </a>
206
+ {/snippet}
207
+ </HoverCard.Trigger>
208
+ </p>
209
+ <HoverCard.Content>
210
+ <p class="text-sm text-ink">Bio text here.</p>
211
+ </HoverCard.Content>
212
+ </HoverCard.Root>
213
+ ```
214
+
215
+ `openDelay?: number` (default `600`), `closeDelay?: number` (default `300`) on `HoverCard.Root`.
216
+
217
+ ## Tooltip
218
+
219
+ Namespace export wrapping Ark UI Tooltip — short text hint shown on hover/focus.
220
+
221
+ ```svelte
222
+ <Tooltip.Root>
223
+ <Tooltip.Trigger>
224
+ <Button variant="ghost" size="icon" aria-label="Info"><PhInfo /></Button>
225
+ </Tooltip.Trigger>
226
+ <Tooltip.Content>More information</Tooltip.Content>
227
+ </Tooltip.Root>
228
+ ```
229
+
230
+ Prefer `Tooltip` over `HoverCard` for a single line of supplementary text; use `HoverCard` for
231
+ richer content (profile previews, formatted descriptions).
232
+
233
+ ## Toast
234
+
235
+ Toaster setup belongs once in the root layout:
236
+
237
+ ```svelte
238
+ <!-- +layout.svelte -->
239
+ <Toast.Toaster />
240
+ {@render children()}
241
+ ```
242
+
243
+ Then fire toasts anywhere:
244
+
245
+ ```ts
246
+ import { toast } from 'compote-ui';
247
+
248
+ toast.success('Saved');
249
+ toast.error('Save failed', { description: 'Please try again.' });
250
+ toast.promise(saveData(), {
251
+ loading: { title: 'Saving…' },
252
+ success: { title: 'Saved' },
253
+ error: { title: 'Save failed' }
254
+ });
255
+ ```
256
+
257
+ Shorthand helpers: `toast.info()`, `toast.success()`, `toast.warning()`, `toast.error()`,
258
+ `toast.loading()` — first arg is the title, second an optional options object; each returns the
259
+ toast `id` usable with `toast.update(id, options)` / `toast.dismiss(id)`. `loading` shows a
260
+ spinner and does not auto-dismiss. `toast.create(options)` remains available for full control.
261
+
262
+ Action button (e.g. Undo):
263
+
264
+ ```ts
265
+ toast.create({
266
+ title: 'File deleted',
267
+ type: 'info',
268
+ action: { label: 'Undo', onClick: () => restore() }
269
+ });
270
+ ```
271
+
272
+ `toast.create()` options: `title: string`, `description?: string`,
273
+ `type?: 'info' | 'success' | 'error' | 'warning' | 'loading'`, `duration?: number` (ms, overrides
274
+ the toaster default for this toast), `action?: { label: string; onClick: () => void }`.
275
+
276
+ `Toast.Toaster` props: `class?: ClassValue`, `toaster?: CreateToasterReturn` (a custom instance
277
+ from `createToaster()` for a different `placement`/`max`/`duration` — defaults to the shared
278
+ `toast` singleton). Default placement is `bottom-end`; timers pause while the tab is hidden.