@svgrid/ui 0.2.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 (77) hide show
  1. package/LICENSE +46 -0
  2. package/README.md +53 -0
  3. package/index.mjs +303 -0
  4. package/package.json +49 -0
  5. package/recipes/buttons/button-group.svelte +18 -0
  6. package/recipes/buttons/button.svelte +17 -0
  7. package/recipes/buttons/check-box.svelte +10 -0
  8. package/recipes/buttons/radio-group.svelte +18 -0
  9. package/recipes/buttons/rating.svelte +8 -0
  10. package/recipes/buttons/repeat-button.svelte +10 -0
  11. package/recipes/buttons/switch-button.svelte +12 -0
  12. package/recipes/buttons/toggle-button.svelte +8 -0
  13. package/recipes/date-time/calendar.svelte +15 -0
  14. package/recipes/date-time/date-range-input.svelte +15 -0
  15. package/recipes/date-time/date-time-picker.svelte +16 -0
  16. package/recipes/date-time/time-picker.svelte +15 -0
  17. package/recipes/feedback/alert.svelte +11 -0
  18. package/recipes/feedback/avatar-group.svelte +11 -0
  19. package/recipes/feedback/avatar.svelte +8 -0
  20. package/recipes/feedback/badge.svelte +8 -0
  21. package/recipes/feedback/carousel.svelte +10 -0
  22. package/recipes/feedback/chip.svelte +10 -0
  23. package/recipes/feedback/empty-state.svelte +8 -0
  24. package/recipes/feedback/skeleton.svelte +8 -0
  25. package/recipes/feedback/timeline.svelte +10 -0
  26. package/recipes/inputs/color-input.svelte +8 -0
  27. package/recipes/inputs/duration-input.svelte +9 -0
  28. package/recipes/inputs/masked-input.svelte +14 -0
  29. package/recipes/inputs/number-input.svelte +17 -0
  30. package/recipes/inputs/otp-input.svelte +13 -0
  31. package/recipes/inputs/password-input.svelte +14 -0
  32. package/recipes/inputs/phone-input.svelte +8 -0
  33. package/recipes/inputs/tags-input.svelte +8 -0
  34. package/recipes/inputs/text-area.svelte +15 -0
  35. package/recipes/inputs/text-input.svelte +14 -0
  36. package/recipes/layout/accordion.svelte +17 -0
  37. package/recipes/layout/card.svelte +9 -0
  38. package/recipes/layout/divider.svelte +9 -0
  39. package/recipes/layout/dock-layout.svelte +22 -0
  40. package/recipes/layout/dock-manager.svelte +24 -0
  41. package/recipes/layout/field.svelte +15 -0
  42. package/recipes/layout/file-upload.svelte +16 -0
  43. package/recipes/layout/form.svelte +14 -0
  44. package/recipes/layout/grid-chart.svelte +16 -0
  45. package/recipes/layout/scroll-area.svelte +10 -0
  46. package/recipes/layout/splitter.svelte +13 -0
  47. package/recipes/layout/tabs.svelte +17 -0
  48. package/recipes/navigation/breadcrumb.svelte +12 -0
  49. package/recipes/navigation/command.svelte +12 -0
  50. package/recipes/navigation/nav-pane.svelte +14 -0
  51. package/recipes/navigation/pagination.svelte +13 -0
  52. package/recipes/navigation/rich-text.svelte +8 -0
  53. package/recipes/navigation/stepper.svelte +13 -0
  54. package/recipes/navigation/tour.svelte +14 -0
  55. package/recipes/navigation/tree.svelte +14 -0
  56. package/recipes/overlays/context-menu.svelte +15 -0
  57. package/recipes/overlays/drawer.svelte +13 -0
  58. package/recipes/overlays/menu.svelte +15 -0
  59. package/recipes/overlays/modal.svelte +13 -0
  60. package/recipes/overlays/popover.svelte +9 -0
  61. package/recipes/overlays/toaster.svelte +9 -0
  62. package/recipes/overlays/tooltip.svelte +8 -0
  63. package/recipes/range/circular-progress.svelte +9 -0
  64. package/recipes/range/gauge.svelte +16 -0
  65. package/recipes/range/progress.svelte +10 -0
  66. package/recipes/range/slider.svelte +19 -0
  67. package/recipes/range/sparkline.svelte +9 -0
  68. package/recipes/range/stat.svelte +9 -0
  69. package/recipes/registry.json +1462 -0
  70. package/recipes/selection/auto-complete.svelte +10 -0
  71. package/recipes/selection/combo-box.svelte +13 -0
  72. package/recipes/selection/country-input.svelte +8 -0
  73. package/recipes/selection/drop-down-list.svelte +13 -0
  74. package/recipes/selection/grid-select.svelte +17 -0
  75. package/recipes/selection/list-box.svelte +13 -0
  76. package/recipes/selection/multi-select.svelte +13 -0
  77. package/recipes/selection/tree-select.svelte +15 -0
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ // SvBadge - a small status pill or count label. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-badge
3
+ import { SvBadge } from '@svgrid/grid'
4
+ </script>
5
+
6
+ <SvBadge variant="success">Active</SvBadge>
7
+ <SvBadge variant="warning">Pending</SvBadge>
8
+ <SvBadge variant="danger" dot>Failed</SvBadge>
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ // SvCarousel - a sliding slideshow with arrows, dots, and autoplay. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-carousel
3
+ import { SvCarousel } from '@svgrid/grid'
4
+
5
+ const imgs = ['/a.jpg', '/b.jpg', '/c.jpg']
6
+ </script>
7
+
8
+ <SvCarousel count={imgs.length} autoplay={4000}>
9
+ {#snippet slide(i)}<img src={imgs[i]} alt="" />{/snippet}
10
+ </SvCarousel>
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ // SvChip - a compact interactive pill for tags and filter tokens. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-chip
3
+ import { SvChip } from '@svgrid/grid'
4
+
5
+ let tags = $state(['design', 'urgent'])
6
+ </script>
7
+
8
+ {#each tags as tag (tag)}
9
+ <SvChip removable onRemove={() => (tags = tags.filter((t) => t !== tag))}>{tag}</SvChip>
10
+ {/each}
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ // SvEmptyState - a centered placeholder for empty or no-results screens. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-empty-state
3
+ import { SvEmptyState, SvButton } from '@svgrid/grid'
4
+ </script>
5
+
6
+ <SvEmptyState title="No orders yet" description="Create your first order to get going.">
7
+ <SvButton variant="primary">New order</SvButton>
8
+ </SvEmptyState>
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ // SvSkeleton - a shimmering loading placeholder. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-skeleton
3
+ import { SvSkeleton } from '@svgrid/grid'
4
+ </script>
5
+
6
+ <SvSkeleton variant="text" lines={3} />
7
+ <SvSkeleton variant="circle" width="40px" height="40px" />
8
+ <SvSkeleton variant="rect" height="160px" />
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ // SvTimeline - a vertical activity or history feed. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-timeline
3
+ import { SvTimeline } from '@svgrid/grid'
4
+ </script>
5
+
6
+ <SvTimeline items={[
7
+ { title: 'Order placed', time: '09:12', color: '#16a34a', icon: '✓' },
8
+ { title: 'Shipped', time: '14:40', description: 'Left the warehouse' },
9
+ { title: 'Out for delivery', time: '08:05' },
10
+ ]} />
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ // SvColorInput - color swatch with a hex field, native picker and presets. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-color-input
3
+ import { SvColorInput } from '@svgrid/grid'
4
+
5
+ let color = $state('#3b82f6')
6
+ </script>
7
+
8
+ <SvColorInput label="Brand color" value={color} onChange={(hex) => (color = hex)} />
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ // SvDurationInput - minute-valued field that accepts 1h 30m, 1:30 or 90. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-duration-input
3
+ import { SvDurationInput } from '@svgrid/grid'
4
+
5
+ let minutes = $state<number | null>(90)
6
+ </script>
7
+
8
+ <SvDurationInput label="Task estimate" bind:value={minutes} style="units" />
9
+ <p>Stored as {minutes} minutes</p>
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ // SvMaskedInput - pattern-masked text that formats as you type. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-masked-input
3
+ import { SvMaskedInput } from '@svgrid/grid'
4
+
5
+ let card = $state('')
6
+ let complete = $state(false)
7
+ </script>
8
+
9
+ <SvMaskedInput
10
+ label="Card number"
11
+ mask="#### #### #### ####"
12
+ value={card}
13
+ onChange={(masked, raw, done) => { card = masked; complete = done }}
14
+ />
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ // SvNumberInput - numeric field with min/max/step, grouping and prefix/suffix. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-number-input
3
+ import { SvNumberInput } from '@svgrid/grid'
4
+
5
+ let price = $state<number | null>(1299.5)
6
+ </script>
7
+
8
+ <SvNumberInput
9
+ label="Price"
10
+ value={price}
11
+ onChange={(v) => (price = v)}
12
+ min={0}
13
+ step={0.5}
14
+ precision={2}
15
+ grouping
16
+ prefix="$"
17
+ />
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ // SvOtpInput - segmented one-time-code / PIN entry that auto-advances. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-otp-input
3
+ import { SvOtpInput } from '@svgrid/grid'
4
+
5
+ let code = $state('')
6
+ </script>
7
+
8
+ <SvOtpInput
9
+ label="Verification code"
10
+ length={6}
11
+ bind:value={code}
12
+ onComplete={(v) => console.log('verify', v)}
13
+ />
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ // SvPasswordInput - password field with a reveal toggle and strength meter. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-password-input
3
+ import { SvPasswordInput } from '@svgrid/grid'
4
+
5
+ let pw = $state('')
6
+ </script>
7
+
8
+ <SvPasswordInput
9
+ label="Password"
10
+ value={pw}
11
+ onChange={(v) => (pw = v)}
12
+ showStrength
13
+ autocomplete="new-password"
14
+ />
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ // SvPhoneInput - country dial-code selector plus a national number field. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-phone-input
3
+ import { SvPhoneInput } from '@svgrid/grid'
4
+
5
+ let phone = $state('')
6
+ </script>
7
+
8
+ <SvPhoneInput label="Mobile" country="US" value={phone} onChange={(v) => (phone = v)} />
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ // SvTagsInput - editable token / chips input backed by a string[]. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-tags-input
3
+ import { SvTagsInput } from '@svgrid/grid'
4
+
5
+ let skills = $state(['Svelte', 'TypeScript'])
6
+ </script>
7
+
8
+ <SvTagsInput label="Skills" value={skills} onChange={(t) => (skills = t)} placeholder="Add a skill" />
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ // SvTextArea - multi-line text field with auto-grow and a character counter. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-text-area
3
+ import { SvTextArea } from '@svgrid/grid'
4
+
5
+ let notes = $state('')
6
+ </script>
7
+
8
+ <SvTextArea
9
+ label="Notes"
10
+ placeholder="Anything the team should know…"
11
+ bind:value={notes}
12
+ autoGrow
13
+ maxlength={280}
14
+ showCount
15
+ />
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ // SvTextInput - single-line text field for the whole editor kit. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-text-input
3
+ import { SvTextInput } from '@svgrid/grid'
4
+
5
+ let email = $state('')
6
+ </script>
7
+
8
+ <SvTextInput
9
+ label="Work email"
10
+ type="email"
11
+ placeholder="you@company.com"
12
+ bind:value={email}
13
+ clearable
14
+ />
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ // SvAccordion - collapsible WAI-ARIA sections, single or multi expand. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-accordion
3
+ import { SvAccordion, type AccordionItem } from '@svgrid/grid'
4
+
5
+ const items: AccordionItem[] = [
6
+ { id: 'ship', label: 'Shipping' },
7
+ { id: 'pay', label: 'Payment' },
8
+ { id: 'gift', label: 'Gift options' },
9
+ ]
10
+ let expanded = $state(['ship'])
11
+ </script>
12
+
13
+ <SvAccordion {items} {expanded} onChange={(ids) => (expanded = ids)}>
14
+ {#snippet panel(item)}
15
+ <p>Details for {item.label}.</p>
16
+ {/snippet}
17
+ </SvAccordion>
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ // SvCard - themed surface with header, body and footer. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-card
3
+ import { SvCard } from '@svgrid/grid'
4
+ </script>
5
+
6
+ <SvCard title="Revenue" subtitle="Last 30 days">
7
+ <p>$42,180</p>
8
+ {#snippet footer()}<a href="/reports">View report</a>{/snippet}
9
+ </SvCard>
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ // SvDivider - themed separator line, horizontal or vertical, with optional label. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-divider
3
+ import { SvDivider } from '@svgrid/grid'
4
+ </script>
5
+
6
+ <p>Above</p>
7
+ <SvDivider />
8
+ <SvDivider label="OR" />
9
+ <p>Below</p>
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ // SvDockLayout - nested resizable splits + tabbed leaves with drag-to-dock. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-dock-layout
3
+ import { SvDockLayout, dockGroup, dockTabs, dockPane, type DockNode } from '@svgrid/grid'
4
+
5
+ let layout = $state<DockNode>(
6
+ dockGroup('row', [
7
+ dockTabs([dockPane('explorer', 'Explorer')]),
8
+ dockGroup('column', [
9
+ dockTabs([dockPane('editor', 'index.ts'), dockPane('readme', 'README.md')]),
10
+ dockTabs([dockPane('terminal', 'Terminal')]),
11
+ ], [0.7, 0.3]),
12
+ ], [0.25, 0.75]),
13
+ )
14
+ </script>
15
+
16
+ <div style="height: 480px">
17
+ <SvDockLayout bind:layout>
18
+ {#snippet pane(p)}
19
+ <div style="padding: 12px">{p.title}</div>
20
+ {/snippet}
21
+ </SvDockLayout>
22
+ </div>
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ // SvDockManager - docking with floating windows, reorder and auto-hide. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-dock-manager
3
+ import { SvDockManager, dockGroup, dockTabs, dockPane, type DockManagerState } from '@svgrid/grid'
4
+
5
+ let workspace = $state<DockManagerState>({
6
+ main: dockGroup('row', [
7
+ dockTabs([dockPane('explorer', 'Explorer')]),
8
+ dockGroup('column', [
9
+ dockTabs([dockPane('editor', 'index.ts'), dockPane('readme', 'README.md')]),
10
+ dockTabs([dockPane('terminal', 'Terminal')]),
11
+ ], [0.7, 0.3]),
12
+ ], [0.22, 0.78]),
13
+ floating: [],
14
+ autoHide: [],
15
+ })
16
+ </script>
17
+
18
+ <div style="height: 520px">
19
+ <SvDockManager bind:workspace>
20
+ {#snippet pane(p)}
21
+ <div style="padding: 12px">{p.title}</div>
22
+ {/snippet}
23
+ </SvDockManager>
24
+ </div>
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ // SvField - shared label / hint / error chrome for any control. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-field
3
+ import { SvField } from '@svgrid/grid'
4
+
5
+ let role = $state('')
6
+ const err = $derived(role ? undefined : 'Pick a role')
7
+ </script>
8
+
9
+ <SvField id="role" label="Role" hint="Sets the default permissions" error={err} required block>
10
+ <select id="role" bind:value={role}>
11
+ <option value="">Choose...</option>
12
+ <option value="admin">Admin</option>
13
+ <option value="member">Member</option>
14
+ </select>
15
+ </SvField>
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ // SvFileUpload - drag-and-drop file field with accept / size / count validation. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-file-upload
3
+ import { SvFileUpload, type FileRejection } from '@svgrid/grid'
4
+
5
+ let files = $state<File[]>([])
6
+ </script>
7
+
8
+ <SvFileUpload
9
+ {files}
10
+ label="Attachments"
11
+ accept="image/*,.pdf"
12
+ multiple
13
+ maxSize={5 * 1024 * 1024}
14
+ onChange={(f) => (files = f)}
15
+ onReject={(r: FileRejection[]) => console.warn(r)}
16
+ />
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ // SvForm - schema-driven form from a FormField[] with validation. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-form
3
+ import { SvForm, type FormField } from '@svgrid/grid'
4
+
5
+ const fields: FormField[] = [
6
+ { name: 'name', label: 'Full name', required: true },
7
+ { name: 'email', label: 'Email', type: 'email', required: true },
8
+ { name: 'plan', label: 'Plan', type: 'select',
9
+ options: [{ value: 'free', label: 'Free' }, { value: 'pro', label: 'Pro' }] },
10
+ { name: 'agree', label: 'I accept the terms', type: 'checkbox' },
11
+ ]
12
+ </script>
13
+
14
+ <SvForm {fields} columns={2} onSubmit={(values) => console.log(values)} />
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ // SvGridChart - inline-SVG chart from a ChartSpec, no charting dependency. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-grid-chart
3
+ import { SvGridChart, rowsToChartSpec, type ChartSpec } from '@svgrid/grid'
4
+
5
+ const rows = [
6
+ { region: 'North', revenue: 4200 },
7
+ { region: 'South', revenue: 3100 },
8
+ { region: 'East', revenue: 5300 },
9
+ { region: 'West', revenue: 2800 },
10
+ ]
11
+ const spec = $derived<ChartSpec>(
12
+ rowsToChartSpec(rows, { type: 'bar', category: 'region', value: 'revenue', reduce: 'sum' }),
13
+ )
14
+ </script>
15
+
16
+ <SvGridChart {spec} formatValue={(v) => '$' + v.toLocaleString()} />
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ // SvScrollArea - scroll container with the kit's themed scrollbars. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-scroll-area
3
+ import { SvScrollArea } from '@svgrid/grid'
4
+
5
+ const rows = Array.from({ length: 40 }, (_, i) => `Item ${i + 1}`)
6
+ </script>
7
+
8
+ <SvScrollArea maxHeight="240px">
9
+ {#each rows as row}<div style="padding: 6px 12px">{row}</div>{/each}
10
+ </SvScrollArea>
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ // SvSplitter - two resizable panes with a draggable separator. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-splitter
3
+ import { SvSplitter } from '@svgrid/grid'
4
+
5
+ let fraction = $state(0.3)
6
+ </script>
7
+
8
+ <div style="height: 320px">
9
+ <SvSplitter {fraction} onChange={(f) => (fraction = f)} ariaLabel="Sidebar width">
10
+ {#snippet start()}<nav style="padding: 12px">Sidebar</nav>{/snippet}
11
+ {#snippet end()}<main style="padding: 12px">Content</main>{/snippet}
12
+ </SvSplitter>
13
+ </div>
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ // SvTabs - WAI-ARIA tab strip with roving arrow-key nav. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-tabs
3
+ import { SvTabs, type TabItem } from '@svgrid/grid'
4
+
5
+ const tabs: TabItem[] = [
6
+ { id: 'overview', label: 'Overview' },
7
+ { id: 'activity', label: 'Activity' },
8
+ { id: 'settings', label: 'Settings' },
9
+ ]
10
+ let tab = $state('overview')
11
+ </script>
12
+
13
+ <SvTabs {tabs} value={tab} onChange={(id) => (tab = id)} variant="line">
14
+ {#snippet panel(active)}
15
+ <p>Content for the {active} tab.</p>
16
+ {/snippet}
17
+ </SvTabs>
@@ -0,0 +1,12 @@
1
+ <script lang="ts">
2
+ // SvBreadcrumb - a navigation trail to the current page. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-breadcrumb
3
+ import { SvBreadcrumb } from '@svgrid/grid'
4
+
5
+ const items = [
6
+ { label: 'Home', href: '/' },
7
+ { label: 'Orders', href: '/orders' },
8
+ { label: '#1024' },
9
+ ]
10
+ </script>
11
+
12
+ <SvBreadcrumb {items} separator="›" maxItems={4} />
@@ -0,0 +1,12 @@
1
+ <script lang="ts">
2
+ // SvCommand - a Cmd+K fuzzy command palette. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-command
3
+ import { SvCommand, type CommandItem } from '@svgrid/grid'
4
+
5
+ const commands: CommandItem[] = [
6
+ { id: 'new', label: 'New record', group: 'Actions', shortcut: '⌘N', onRun: () => console.log('new') },
7
+ { id: 'export', label: 'Export CSV', group: 'Actions', onRun: () => console.log('export') },
8
+ ]
9
+ </script>
10
+
11
+ <!-- Cmd/Ctrl+K opens it -->
12
+ <SvCommand {commands} onRun={(c) => console.log(c.id)} />
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ // SvNavPane - an Outlook-style app-shell navigation sidebar. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-nav-pane
3
+ import { SvNavPane, type NavSection } from '@svgrid/grid'
4
+
5
+ let value = $state<string | null>('inbox')
6
+ const sections: NavSection[] = [
7
+ { id: 'mail', label: 'Mail', items: [
8
+ { id: 'inbox', label: 'Inbox', badge: 12 },
9
+ { id: 'sent', label: 'Sent' },
10
+ ] },
11
+ ]
12
+ </script>
13
+
14
+ <SvNavPane {sections} bind:value onSelect={(id) => console.log(id)} />
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ // SvPagination - a standalone pager with prev/next and page numbers. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-pagination
3
+ import { SvPagination } from '@svgrid/grid'
4
+
5
+ let page = $state(1)
6
+ </script>
7
+
8
+ <SvPagination
9
+ {page}
10
+ pageCount={20}
11
+ showFirstLast
12
+ onChange={(n) => (page = n)}
13
+ />
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ // SvRichText - a lightweight WYSIWYG editor emitting HTML. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-rich-text
3
+ import { SvRichText } from '@svgrid/grid'
4
+
5
+ let html = $state('<p>Hello</p>')
6
+ </script>
7
+
8
+ <SvRichText bind:value={html} placeholder="Write something…" />
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ // SvStepper - a progress stepper for wizards and multi-step forms. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-stepper
3
+ import { SvStepper } from '@svgrid/grid'
4
+
5
+ let current = $state(0)
6
+ const steps = [
7
+ { label: 'Cart' },
8
+ { label: 'Shipping', description: 'Where to send it' },
9
+ { label: 'Payment', optional: true },
10
+ ]
11
+ </script>
12
+
13
+ <SvStepper {steps} {current} onChange={(n) => (current = n)} />
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ // SvTour - a guided, spotlighted product tour overlay. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-tour
3
+ import { SvTour, SvButton } from '@svgrid/grid'
4
+
5
+ let open = $state(false)
6
+ const steps = [
7
+ { target: '#new-btn', title: 'Create', content: 'Start a record here.' },
8
+ { target: '.grid', title: 'Your data', content: 'It shows up in the grid.' },
9
+ ]
10
+ </script>
11
+
12
+ <SvButton onclick={() => (open = true)}>Take the tour</SvButton>
13
+
14
+ <SvTour bind:open {steps} />
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ // SvTree - a WAI-ARIA tree view with expand/select/checkboxes. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-tree
3
+ import { SvTree, type SvTreeNode } from '@svgrid/grid'
4
+
5
+ let selected = $state<string | null>(null)
6
+ const nodes: SvTreeNode[] = [
7
+ { id: 'src', label: 'src', children: [
8
+ { id: 'app', label: 'App.svelte' },
9
+ { id: 'main', label: 'main.ts' },
10
+ ] },
11
+ ]
12
+ </script>
13
+
14
+ <SvTree {nodes} {selected} onSelect={(id) => (selected = id)} />
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ // SvContextMenu - opens a menu at the pointer on right-click. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-context-menu
3
+ import { SvContextMenu, type MenuItem } from '@svgrid/grid'
4
+
5
+ const items: MenuItem[] = [
6
+ { label: 'Copy', shortcut: 'Ctrl+C', onSelect: () => {} },
7
+ { label: 'Duplicate', onSelect: () => {} },
8
+ { separator: true },
9
+ { label: 'Delete', onSelect: () => {} },
10
+ ]
11
+ </script>
12
+
13
+ <SvContextMenu {items} onSelect={(i) => console.log(i.label)}>
14
+ <div class="drop-zone">Right-click me</div>
15
+ </SvContextMenu>
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ // SvDrawer - an edge-anchored side sheet with backdrop. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-drawer
3
+ import { SvDrawer, SvButton } from '@svgrid/grid'
4
+
5
+ let open = $state(false)
6
+ </script>
7
+
8
+ <SvButton onclick={() => (open = true)}>Filters</SvButton>
9
+
10
+ <SvDrawer bind:open side="right" title="Filters">
11
+ <p>Body content.</p>
12
+ {#snippet footer()}<SvButton variant="primary" onclick={() => (open = false)}>Apply</SvButton>{/snippet}
13
+ </SvDrawer>
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ // SvMenu - a trigger-opened dropdown / actions menu. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-menu
3
+ import { SvMenu, SvButton, type MenuItem } from '@svgrid/grid'
4
+
5
+ const items: MenuItem[] = [
6
+ { label: 'New', shortcut: 'Ctrl+N', onSelect: () => {} },
7
+ { label: 'Duplicate', onSelect: () => {} },
8
+ { separator: true },
9
+ { label: 'Delete', onSelect: () => {} },
10
+ ]
11
+ </script>
12
+
13
+ <SvMenu {items} onSelect={(i) => console.log(i.label)}>
14
+ {#snippet anchor()}<SvButton>Actions</SvButton>{/snippet}
15
+ </SvMenu>
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ // SvModal - an accessible modal dialog with focus trap. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-modal
3
+ import { SvModal, SvButton } from '@svgrid/grid'
4
+
5
+ let open = $state(false)
6
+ </script>
7
+
8
+ <SvButton onclick={() => (open = true)}>Edit row</SvButton>
9
+
10
+ <SvModal bind:open title="Edit row">
11
+ <p>Body content.</p>
12
+ {#snippet footer()}<SvButton variant="primary" onclick={() => (open = false)}>Save</SvButton>{/snippet}
13
+ </SvModal>
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ // SvPopover - a floating panel anchored to a trigger. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-popover
3
+ import { SvPopover, SvButton } from '@svgrid/grid'
4
+ </script>
5
+
6
+ <SvPopover>
7
+ {#snippet anchor()}<SvButton>Open</SvButton>{/snippet}
8
+ <p>Panel content, portalled out of any scroll container.</p>
9
+ </SvPopover>
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ // SvToaster - host that renders the shared toast queue. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-toaster
3
+ import { SvToaster, SvButton, toast } from '@svgrid/grid'
4
+ </script>
5
+
6
+ <!-- Mount once, near the app root -->
7
+ <SvToaster position="bottom-right" />
8
+
9
+ <SvButton onclick={() => toast.success('Saved')}>Save</SvButton>
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ // SvTooltip - a hover and focus tooltip anchored to its child. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-tooltip
3
+ import { SvTooltip, SvButton } from '@svgrid/grid'
4
+ </script>
5
+
6
+ <SvTooltip text="Delete row">
7
+ <SvButton ariaLabel="Delete">🗑</SvButton>
8
+ </SvTooltip>
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ // SvCircularProgress - ring progress indicator. Your copy, edit freely. Docs: https://www.svgrid.com/docs/help/ui-components/sv-circular-progress
3
+ import { SvCircularProgress } from '@svgrid/grid'
4
+
5
+ let value = $state(72)
6
+ </script>
7
+
8
+ <SvCircularProgress {value} size={72} thickness={7} showLabel />
9
+ <SvCircularProgress indeterminate size={28} color="accent" />