@hyvnt/hyvui 0.3.0 → 0.4.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 (170) hide show
  1. package/README.md +37 -7
  2. package/dist/components/ambient/ArcaneVein.svelte +151 -0
  3. package/dist/components/ambient/ArcaneVein.svelte.d.ts +31 -0
  4. package/dist/components/ambient/BrassFiligree.svelte +109 -0
  5. package/dist/components/ambient/BrassFiligree.svelte.d.ts +20 -0
  6. package/dist/components/ambient/CornerBrackets.svelte +8 -0
  7. package/dist/components/ambient/CornerBrackets.svelte.d.ts +8 -0
  8. package/dist/components/ambient/CrystalShard.svelte +151 -0
  9. package/dist/components/ambient/CrystalShard.svelte.d.ts +19 -0
  10. package/dist/components/ambient/DataStream.svelte +7 -1
  11. package/dist/components/ambient/DataStream.svelte.d.ts +6 -0
  12. package/dist/components/ambient/EnergyArc.svelte +189 -0
  13. package/dist/components/ambient/EnergyArc.svelte.d.ts +32 -0
  14. package/dist/components/ambient/GlyphMark.svelte +6 -0
  15. package/dist/components/ambient/GlyphMark.svelte.d.ts +6 -0
  16. package/dist/components/ambient/GridOverlay.svelte +8 -0
  17. package/dist/components/ambient/GridOverlay.svelte.d.ts +8 -0
  18. package/dist/components/ambient/HexGrid.svelte +119 -0
  19. package/dist/components/ambient/HexGrid.svelte.d.ts +21 -0
  20. package/dist/components/ambient/ParallaxLayer.svelte +9 -1
  21. package/dist/components/ambient/ParallaxLayer.svelte.d.ts +7 -0
  22. package/dist/components/ambient/ScanBand.svelte +8 -0
  23. package/dist/components/ambient/ScanBand.svelte.d.ts +8 -0
  24. package/dist/components/ambient/ShimmerCloud.svelte +180 -0
  25. package/dist/components/ambient/ShimmerCloud.svelte.d.ts +21 -0
  26. package/dist/components/ambient/SignalRing.svelte +7 -1
  27. package/dist/components/ambient/SignalRing.svelte.d.ts +6 -0
  28. package/dist/components/ambient/ThreadLine.svelte +7 -0
  29. package/dist/components/ambient/ThreadLine.svelte.d.ts +7 -0
  30. package/dist/components/ambient/Vignette.svelte +6 -0
  31. package/dist/components/ambient/Vignette.svelte.d.ts +6 -0
  32. package/dist/components/depth/DepthLayer.svelte +8 -0
  33. package/dist/components/depth/DepthLayer.svelte.d.ts +8 -0
  34. package/dist/components/depth/DepthStage.svelte +8 -4
  35. package/dist/components/depth/DepthStage.svelte.d.ts +8 -0
  36. package/dist/components/depth/FloatCard.svelte +17 -1
  37. package/dist/components/depth/FloatCard.svelte.d.ts +8 -0
  38. package/dist/components/depth/HorizonGrid.svelte +25 -0
  39. package/dist/components/depth/HorizonGrid.svelte.d.ts +9 -0
  40. package/dist/components/depth/Plinth.svelte +10 -0
  41. package/dist/components/depth/Plinth.svelte.d.ts +10 -0
  42. package/dist/components/display/Avatar.svelte +5 -0
  43. package/dist/components/display/Avatar.svelte.d.ts +5 -0
  44. package/dist/components/display/Badge.svelte +16 -0
  45. package/dist/components/display/Badge.svelte.d.ts +6 -0
  46. package/dist/components/display/Blockquote.svelte +4 -0
  47. package/dist/components/display/Blockquote.svelte.d.ts +4 -0
  48. package/dist/components/display/CodeBlock.svelte +5 -0
  49. package/dist/components/display/CodeBlock.svelte.d.ts +5 -0
  50. package/dist/components/display/MetricCard.svelte +23 -0
  51. package/dist/components/display/MetricCard.svelte.d.ts +6 -0
  52. package/dist/components/display/Table.svelte +7 -0
  53. package/dist/components/display/Table.svelte.d.ts +7 -0
  54. package/dist/components/feedback/Alert.svelte +24 -0
  55. package/dist/components/feedback/Alert.svelte.d.ts +6 -0
  56. package/dist/components/feedback/EmptyState.svelte +7 -0
  57. package/dist/components/feedback/EmptyState.svelte.d.ts +7 -0
  58. package/dist/components/feedback/ErrorState.svelte +5 -0
  59. package/dist/components/feedback/ErrorState.svelte.d.ts +5 -0
  60. package/dist/components/feedback/Skeleton.svelte +6 -0
  61. package/dist/components/feedback/Skeleton.svelte.d.ts +6 -0
  62. package/dist/components/feedback/StatusDot.svelte +36 -1
  63. package/dist/components/feedback/StatusDot.svelte.d.ts +6 -0
  64. package/dist/components/feedback/StatusLine.svelte +8 -2
  65. package/dist/components/feedback/StatusLine.svelte.d.ts +6 -0
  66. package/dist/components/feedback/Toast.svelte +16 -2
  67. package/dist/components/feedback/Toast.svelte.d.ts +10 -0
  68. package/dist/components/inputs/Button.svelte +74 -4
  69. package/dist/components/inputs/Button.svelte.d.ts +8 -0
  70. package/dist/components/inputs/Checkbox.svelte +5 -0
  71. package/dist/components/inputs/Checkbox.svelte.d.ts +5 -0
  72. package/dist/components/inputs/FileUpload.svelte +5 -0
  73. package/dist/components/inputs/FileUpload.svelte.d.ts +5 -0
  74. package/dist/components/inputs/Input.svelte +10 -2
  75. package/dist/components/inputs/Input.svelte.d.ts +7 -0
  76. package/dist/components/inputs/Select.svelte +8 -0
  77. package/dist/components/inputs/Select.svelte.d.ts +8 -0
  78. package/dist/components/inputs/Textarea.svelte +9 -2
  79. package/dist/components/inputs/Textarea.svelte.d.ts +6 -0
  80. package/dist/components/inputs/Toggle.svelte +6 -1
  81. package/dist/components/inputs/Toggle.svelte.d.ts +5 -0
  82. package/dist/components/layout/Card.svelte +11 -0
  83. package/dist/components/layout/Card.svelte.d.ts +11 -0
  84. package/dist/components/layout/Drawer.svelte +7 -0
  85. package/dist/components/layout/Drawer.svelte.d.ts +6 -0
  86. package/dist/components/layout/Grid.svelte +10 -0
  87. package/dist/components/layout/Grid.svelte.d.ts +10 -0
  88. package/dist/components/layout/Modal.svelte +15 -0
  89. package/dist/components/layout/Modal.svelte.d.ts +10 -0
  90. package/dist/components/layout/Panel.svelte +9 -0
  91. package/dist/components/layout/Panel.svelte.d.ts +9 -0
  92. package/dist/components/layout/Popover.svelte +10 -0
  93. package/dist/components/layout/Popover.svelte.d.ts +9 -0
  94. package/dist/components/layout/Stack.svelte +12 -0
  95. package/dist/components/layout/Stack.svelte.d.ts +12 -0
  96. package/dist/components/navigation/Breadcrumb.svelte +8 -0
  97. package/dist/components/navigation/Breadcrumb.svelte.d.ts +8 -0
  98. package/dist/components/navigation/DropdownMenu.svelte +12 -0
  99. package/dist/components/navigation/DropdownMenu.svelte.d.ts +12 -0
  100. package/dist/components/navigation/SidebarNav.svelte +10 -0
  101. package/dist/components/navigation/SidebarNav.svelte.d.ts +9 -0
  102. package/dist/components/navigation/Tabs.svelte +26 -1
  103. package/dist/components/navigation/Tabs.svelte.d.ts +8 -0
  104. package/dist/components/navigation/Topbar.svelte +9 -0
  105. package/dist/components/navigation/Topbar.svelte.d.ts +9 -0
  106. package/dist/components/patterns/ActionBar.svelte +11 -0
  107. package/dist/components/patterns/ActionBar.svelte.d.ts +10 -0
  108. package/dist/components/patterns/ChapterMark.svelte +152 -0
  109. package/dist/components/patterns/ChapterMark.svelte.d.ts +19 -0
  110. package/dist/components/patterns/ConfirmDialog.svelte +12 -0
  111. package/dist/components/patterns/ConfirmDialog.svelte.d.ts +12 -0
  112. package/dist/components/patterns/DepthPortal.svelte +123 -0
  113. package/dist/components/patterns/DepthPortal.svelte.d.ts +24 -0
  114. package/dist/components/patterns/Manifesto.svelte +171 -0
  115. package/dist/components/patterns/Manifesto.svelte.d.ts +25 -0
  116. package/dist/components/patterns/PageHeader.svelte +8 -0
  117. package/dist/components/patterns/PageHeader.svelte.d.ts +8 -0
  118. package/dist/components/patterns/PullQuote.svelte +145 -0
  119. package/dist/components/patterns/PullQuote.svelte.d.ts +23 -0
  120. package/dist/components/patterns/RegisterSwitcher.svelte +132 -0
  121. package/dist/components/patterns/RegisterSwitcher.svelte.d.ts +21 -0
  122. package/dist/components/patterns/SearchBar.svelte +5 -0
  123. package/dist/components/patterns/SearchBar.svelte.d.ts +5 -0
  124. package/dist/components/patterns/ShowcaseFrame.svelte +117 -0
  125. package/dist/components/patterns/ShowcaseFrame.svelte.d.ts +28 -0
  126. package/dist/components/patterns/TerminalBoot.svelte +15 -1
  127. package/dist/components/patterns/TerminalBoot.svelte.d.ts +12 -0
  128. package/dist/components/primitives/Divider.svelte +30 -0
  129. package/dist/components/primitives/Divider.svelte.d.ts +5 -0
  130. package/dist/components/primitives/Icon.svelte +9 -0
  131. package/dist/components/primitives/Icon.svelte.d.ts +9 -0
  132. package/dist/components/primitives/Label.svelte +6 -0
  133. package/dist/components/primitives/Label.svelte.d.ts +6 -0
  134. package/dist/components/primitives/Surface.svelte +67 -2
  135. package/dist/components/primitives/Surface.svelte.d.ts +7 -0
  136. package/dist/components/primitives/Text.svelte +32 -0
  137. package/dist/components/primitives/Text.svelte.d.ts +7 -0
  138. package/dist/components/scenes/ArchiveScene.svelte +10 -0
  139. package/dist/components/scenes/ArchiveScene.svelte.d.ts +10 -0
  140. package/dist/components/scenes/DepthScene.svelte +128 -0
  141. package/dist/components/scenes/DepthScene.svelte.d.ts +36 -0
  142. package/dist/components/scenes/LogScene.svelte +14 -0
  143. package/dist/components/scenes/LogScene.svelte.d.ts +14 -0
  144. package/dist/components/scenes/NarrativeScene.svelte +9 -0
  145. package/dist/components/scenes/NarrativeScene.svelte.d.ts +9 -0
  146. package/dist/components/scenes/ReadoutScene.svelte +11 -0
  147. package/dist/components/scenes/ReadoutScene.svelte.d.ts +11 -0
  148. package/dist/components/scenes/StageScene.svelte +14 -0
  149. package/dist/components/scenes/StageScene.svelte.d.ts +14 -0
  150. package/dist/components/system/AppShell.svelte +62 -0
  151. package/dist/components/system/AppShell.svelte.d.ts +32 -0
  152. package/dist/examples/ArcaneShard.svelte +364 -0
  153. package/dist/examples/ArcaneShard.svelte.d.ts +3 -0
  154. package/dist/examples/HextechForge.svelte +324 -0
  155. package/dist/examples/HextechForge.svelte.d.ts +3 -0
  156. package/dist/index.d.ts +15 -1
  157. package/dist/index.js +16 -1
  158. package/dist/styles.css +2 -0
  159. package/dist/system/actions/echo.js +13 -4
  160. package/dist/system/actions/resolve.js +20 -6
  161. package/dist/system/actions/reveal.js +1 -1
  162. package/dist/system/actions/surface.js +1 -3
  163. package/dist/system/register.d.ts +1 -1
  164. package/dist/system/register.js +5 -1
  165. package/dist/tokens/arcane.css +96 -0
  166. package/dist/tokens/hextech.css +96 -0
  167. package/dist/tokens/tokens.css +6 -4
  168. package/dist/tokens/tokens.d.ts +41 -0
  169. package/dist/tokens/tokens.js +41 -0
  170. package/package.json +6 -2
@@ -17,6 +17,15 @@
17
17
  const _fui = [autoUpdate, computePosition, flip, fuiOffset, shift, fuiSize];
18
18
  void _fui;
19
19
 
20
+ /**
21
+ * Typically used via DropdownMenu. Use directly only when you need full positioning control.
22
+ * Requires an `anchor` HTMLElement ref and a controlled `open` boolean.
23
+ * @example
24
+ * <button bind:this={anchorEl} onclick={() => open = true}>open</button>
25
+ * <Popover {open} anchor={anchorEl} placement="bottom-start" onclose={() => open = false}>
26
+ * <Text variant="caption">popover content</Text>
27
+ * </Popover>
28
+ */
20
29
  interface Props {
21
30
  /** Controls popover visibility. */
22
31
  open?: boolean;
@@ -144,6 +153,7 @@
144
153
  z-index: var(--z-overlay);
145
154
  left: 0;
146
155
  top: 0;
156
+ backface-visibility: hidden;
147
157
  animation: popover-in 0.2s cubic-bezier(0.22, 1, 0.36, 1);
148
158
  max-inline-size: min(90dvw, 28rem);
149
159
  }
@@ -1,5 +1,14 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import { type Placement } from '@floating-ui/dom';
3
+ /**
4
+ * Typically used via DropdownMenu. Use directly only when you need full positioning control.
5
+ * Requires an `anchor` HTMLElement ref and a controlled `open` boolean.
6
+ * @example
7
+ * <button bind:this={anchorEl} onclick={() => open = true}>open</button>
8
+ * <Popover {open} anchor={anchorEl} placement="bottom-start" onclose={() => open = false}>
9
+ * <Text variant="caption">popover content</Text>
10
+ * </Popover>
11
+ */
3
12
  interface Props {
4
13
  /** Controls popover visibility. */
5
14
  open?: boolean;
@@ -2,6 +2,18 @@
2
2
  import { cn } from '../../utils/cn.js';
3
3
  import type { Snippet } from 'svelte';
4
4
 
5
+ /**
6
+ * @see surface — add `use:surface` on Stack for an entrance animation on mount.
7
+ * @example
8
+ * <Stack gap="var(--space-lg)">
9
+ * <Text variant="heading">title</Text>
10
+ * <Text>body text here.</Text>
11
+ * </Stack>
12
+ * <Stack direction="horizontal" align="center" gap="0.75rem">
13
+ * <Button variant="primary">confirm</Button>
14
+ * <Button variant="ghost">cancel</Button>
15
+ * </Stack>
16
+ */
5
17
  interface Props {
6
18
  /** Stack direction. */
7
19
  direction?: 'vertical' | 'horizontal';
@@ -1,4 +1,16 @@
1
1
  import type { Snippet } from 'svelte';
2
+ /**
3
+ * @see surface — add `use:surface` on Stack for an entrance animation on mount.
4
+ * @example
5
+ * <Stack gap="var(--space-lg)">
6
+ * <Text variant="heading">title</Text>
7
+ * <Text>body text here.</Text>
8
+ * </Stack>
9
+ * <Stack direction="horizontal" align="center" gap="0.75rem">
10
+ * <Button variant="primary">confirm</Button>
11
+ * <Button variant="ghost">cancel</Button>
12
+ * </Stack>
13
+ */
2
14
  interface Props {
3
15
  /** Stack direction. */
4
16
  direction?: 'vertical' | 'horizontal';
@@ -6,6 +6,14 @@
6
6
  href?: string;
7
7
  }
8
8
 
9
+ /**
10
+ * @example
11
+ * <Breadcrumb items={[
12
+ * { label: 'home', href: '/' },
13
+ * { label: 'projects', href: '/projects' },
14
+ * { label: 'alpha' }
15
+ * ]} />
16
+ */
9
17
  interface Props {
10
18
  /** Breadcrumb trail items. */
11
19
  items?: BreadcrumbItem[];
@@ -2,6 +2,14 @@ interface BreadcrumbItem {
2
2
  label: string;
3
3
  href?: string;
4
4
  }
5
+ /**
6
+ * @example
7
+ * <Breadcrumb items={[
8
+ * { label: 'home', href: '/' },
9
+ * { label: 'projects', href: '/projects' },
10
+ * { label: 'alpha' }
11
+ * ]} />
12
+ */
5
13
  interface Props {
6
14
  /** Breadcrumb trail items. */
7
15
  items?: BreadcrumbItem[];
@@ -11,6 +11,18 @@
11
11
  destructive?: boolean;
12
12
  }
13
13
 
14
+ /**
15
+ * @example
16
+ * <DropdownMenu
17
+ * items={[
18
+ * { label: 'edit', value: 'edit' },
19
+ * { label: 'delete', value: 'delete', destructive: true }
20
+ * ]}
21
+ * onselect={(val) => handleAction(val)}
22
+ * >
23
+ * {#snippet trigger()}<Button variant="ghost" size="sm">actions</Button>{/snippet}
24
+ * </DropdownMenu>
25
+ */
14
26
  interface Props {
15
27
  /** Menu items. */
16
28
  items?: MenuItem[];
@@ -6,6 +6,18 @@ interface MenuItem {
6
6
  disabled?: boolean;
7
7
  destructive?: boolean;
8
8
  }
9
+ /**
10
+ * @example
11
+ * <DropdownMenu
12
+ * items={[
13
+ * { label: 'edit', value: 'edit' },
14
+ * { label: 'delete', value: 'delete', destructive: true }
15
+ * ]}
16
+ * onselect={(val) => handleAction(val)}
17
+ * >
18
+ * {#snippet trigger()}<Button variant="ghost" size="sm">actions</Button>{/snippet}
19
+ * </DropdownMenu>
20
+ */
9
21
  interface Props {
10
22
  /** Menu items. */
11
23
  items?: MenuItem[];
@@ -7,6 +7,15 @@
7
7
  active?: boolean;
8
8
  }
9
9
 
10
+ /**
11
+ * @see reveal — add `use:reveal={{ target: '.badge' }}` on items for hover metadata.
12
+ * @example
13
+ * <SidebarNav items={[
14
+ * { label: 'overview', href: '/', active: true },
15
+ * { label: 'settings', href: '/settings' },
16
+ * { label: 'archive', href: '/archive' }
17
+ * ]} />
18
+ */
10
19
  interface Props {
11
20
  /** Navigation items. */
12
21
  items?: NavItem[];
@@ -65,6 +74,7 @@
65
74
  .hyvui-sidebar-link:hover {
66
75
  color: var(--text-soft);
67
76
  background: linear-gradient(90deg, rgba(199, 156, 87, 0.08), transparent 76%);
77
+ transform: translateX(2px);
68
78
  }
69
79
 
70
80
  .hyvui-sidebar-link-active {
@@ -3,6 +3,15 @@ interface NavItem {
3
3
  href: string;
4
4
  active?: boolean;
5
5
  }
6
+ /**
7
+ * @see reveal — add `use:reveal={{ target: '.badge' }}` on items for hover metadata.
8
+ * @example
9
+ * <SidebarNav items={[
10
+ * { label: 'overview', href: '/', active: true },
11
+ * { label: 'settings', href: '/settings' },
12
+ * { label: 'archive', href: '/archive' }
13
+ * ]} />
14
+ */
6
15
  interface Props {
7
16
  /** Navigation items. */
8
17
  items?: NavItem[];
@@ -6,6 +6,14 @@
6
6
  label: string;
7
7
  }
8
8
 
9
+ /**
10
+ * @example
11
+ * <Tabs
12
+ * tabs={[{ id: 'data', label: 'data' }, { id: 'logs', label: 'logs' }]}
13
+ * active={activeTab}
14
+ * onchange={(id) => activeTab = id}
15
+ * />
16
+ */
9
17
  interface Props {
10
18
  /** Available tabs. */
11
19
  tabs?: TabItem[];
@@ -18,16 +26,33 @@
18
26
  }
19
27
 
20
28
  let { tabs = [], active = '', class: className = '', onchange }: Props = $props();
29
+
30
+ let tabEls: HTMLButtonElement[] = [];
31
+
32
+ function handleKeyDown(e: KeyboardEvent, idx: number) {
33
+ let next = -1;
34
+ if (e.key === 'ArrowRight') next = (idx + 1) % tabs.length;
35
+ else if (e.key === 'ArrowLeft') next = (idx - 1 + tabs.length) % tabs.length;
36
+ else if (e.key === 'Home') next = 0;
37
+ else if (e.key === 'End') next = tabs.length - 1;
38
+ if (next === -1) return;
39
+ e.preventDefault();
40
+ onchange?.(tabs[next].id);
41
+ tabEls[next]?.focus();
42
+ }
21
43
  </script>
22
44
 
23
45
  <div class={cn('hyvui-tabs', className)} role="tablist">
24
- {#each tabs as tab}
46
+ {#each tabs as tab, i}
25
47
  <button
48
+ bind:this={tabEls[i]}
26
49
  type="button"
27
50
  role="tab"
28
51
  aria-selected={tab.id === active}
52
+ tabindex={tab.id === active ? 0 : -1}
29
53
  class={cn('hyvui-tab', tab.id === active && 'hyvui-tab-active')}
30
54
  onclick={() => onchange?.(tab.id)}
55
+ onkeydown={(e) => handleKeyDown(e, i)}
31
56
  >
32
57
  {tab.label}
33
58
  </button>
@@ -2,6 +2,14 @@ interface TabItem {
2
2
  id: string;
3
3
  label: string;
4
4
  }
5
+ /**
6
+ * @example
7
+ * <Tabs
8
+ * tabs={[{ id: 'data', label: 'data' }, { id: 'logs', label: 'logs' }]}
9
+ * active={activeTab}
10
+ * onchange={(id) => activeTab = id}
11
+ * />
12
+ */
5
13
  interface Props {
6
14
  /** Available tabs. */
7
15
  tabs?: TabItem[];
@@ -2,6 +2,15 @@
2
2
  import { cn } from '../../utils/cn.js';
3
3
  import type { Snippet } from 'svelte';
4
4
 
5
+ /**
6
+ * @example
7
+ * <Topbar>
8
+ * {#snippet left()}<Text variant="caption" color="accent">hyvui</Text>{/snippet}
9
+ * {#snippet right()}
10
+ * <Button variant="ghost" size="sm">sign in</Button>
11
+ * {/snippet}
12
+ * </Topbar>
13
+ */
5
14
  interface Props {
6
15
  /** Additional CSS classes. */
7
16
  class?: string;
@@ -1,4 +1,13 @@
1
1
  import type { Snippet } from 'svelte';
2
+ /**
3
+ * @example
4
+ * <Topbar>
5
+ * {#snippet left()}<Text variant="caption" color="accent">hyvui</Text>{/snippet}
6
+ * {#snippet right()}
7
+ * <Button variant="ghost" size="sm">sign in</Button>
8
+ * {/snippet}
9
+ * </Topbar>
10
+ */
2
11
  interface Props {
3
12
  /** Additional CSS classes. */
4
13
  class?: string;
@@ -4,6 +4,16 @@
4
4
  import Label from '../primitives/Label.svelte';
5
5
  import type { Snippet } from 'svelte';
6
6
 
7
+ /**
8
+ * @remarks Use on any multi-select list or table. Fixed, bottom-center. Renders nothing when count is 0.
9
+ * @example
10
+ * <ActionBar count={selected.length} onclear={() => selected = []}>
11
+ * {#snippet actions()}
12
+ * <Button variant="ghost" size="sm" onclick={exportSelected}>export</Button>
13
+ * <Button variant="destructive" size="sm" onclick={deleteSelected}>delete</Button>
14
+ * {/snippet}
15
+ * </ActionBar>
16
+ */
7
17
  interface Props {
8
18
  /** Number of selected items. Bar is visible when count > 0. */
9
19
  count?: number;
@@ -44,6 +54,7 @@
44
54
  border: 1px solid rgba(255, 255, 255, 0.05);
45
55
  box-shadow: var(--shadow-veil);
46
56
  padding: 0.625rem 1.25rem;
57
+ backface-visibility: hidden;
47
58
  animation: actionbar-in 0.35s cubic-bezier(0.22, 1, 0.36, 1);
48
59
  }
49
60
 
@@ -1,4 +1,14 @@
1
1
  import type { Snippet } from 'svelte';
2
+ /**
3
+ * @remarks Use on any multi-select list or table. Fixed, bottom-center. Renders nothing when count is 0.
4
+ * @example
5
+ * <ActionBar count={selected.length} onclear={() => selected = []}>
6
+ * {#snippet actions()}
7
+ * <Button variant="ghost" size="sm" onclick={exportSelected}>export</Button>
8
+ * <Button variant="destructive" size="sm" onclick={deleteSelected}>delete</Button>
9
+ * {/snippet}
10
+ * </ActionBar>
11
+ */
2
12
  interface Props {
3
13
  /** Number of selected items. Bar is visible when count > 0. */
4
14
  count?: number;
@@ -0,0 +1,152 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+
4
+ /**
5
+ * @remarks Architectural section header. Creates structural rhythm without a container.
6
+ * Use for section openers in long-form pages, portfolios, documentation.
7
+ * @example
8
+ * <ChapterMark index="01" title="signal architecture" descriptor="how the system speaks" />
9
+ */
10
+ interface Props {
11
+ /** Chapter index — a number, roman numeral, or label. */
12
+ index?: string | number;
13
+ /** Chapter title. */
14
+ title: string;
15
+ /** Optional descriptor rendered in readout style below the title. */
16
+ descriptor?: string;
17
+ /** Additional CSS classes. */
18
+ class?: string;
19
+ }
20
+
21
+ let { index, title, descriptor, class: className = '' }: Props = $props();
22
+ </script>
23
+
24
+ <header class={cn('hyvui-chapter-mark', className)}>
25
+ <div class="hyvui-chapter-mark-rule" aria-hidden="true"></div>
26
+ <div class="hyvui-chapter-mark-body">
27
+ {#if index !== undefined}
28
+ <div class="hyvui-chapter-mark-index" aria-hidden="true">
29
+ <span class="hyvui-chapter-mark-index-text">{index}</span>
30
+ <span class="hyvui-chapter-mark-index-line"></span>
31
+ </div>
32
+ {/if}
33
+ <div class="hyvui-chapter-mark-text">
34
+ <h2 class="hyvui-chapter-mark-title">{title}</h2>
35
+ {#if descriptor}
36
+ <p class="hyvui-chapter-mark-descriptor">{descriptor}</p>
37
+ {/if}
38
+ </div>
39
+ </div>
40
+ </header>
41
+
42
+ <style>
43
+ .hyvui-chapter-mark {
44
+ display: flex;
45
+ flex-direction: column;
46
+ gap: calc(1.25rem * var(--reg-spacing-scale, 1));
47
+ }
48
+
49
+ .hyvui-chapter-mark-rule {
50
+ position: relative;
51
+ overflow: hidden;
52
+ width: 100%;
53
+ height: 1px;
54
+ background: var(--line);
55
+ }
56
+
57
+ .hyvui-chapter-mark-rule::after {
58
+ content: '';
59
+ position: absolute;
60
+ inset: 0;
61
+ background: var(--bg);
62
+ transform-origin: right;
63
+ animation: chapter-rule-wipe 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
64
+ }
65
+
66
+ @keyframes chapter-rule-wipe {
67
+ from {
68
+ transform: scaleX(1);
69
+ }
70
+ to {
71
+ transform: scaleX(0);
72
+ }
73
+ }
74
+
75
+ @media (prefers-reduced-motion: reduce) {
76
+ .hyvui-chapter-mark-rule::after {
77
+ animation: none;
78
+ display: none;
79
+ }
80
+ }
81
+
82
+ .hyvui-chapter-mark-body {
83
+ display: flex;
84
+ gap: calc(1.5rem * var(--reg-spacing-scale, 1));
85
+ align-items: baseline;
86
+ }
87
+
88
+ .hyvui-chapter-mark-index {
89
+ display: flex;
90
+ align-items: center;
91
+ gap: 0.6rem;
92
+ flex-shrink: 0;
93
+ padding-top: 0.3em;
94
+ }
95
+
96
+ .hyvui-chapter-mark-index-text {
97
+ font-family: var(--font-mono);
98
+ font-size: 0.62rem;
99
+ letter-spacing: 0.22em;
100
+ text-transform: uppercase;
101
+ color: var(--muted-strong);
102
+ line-height: 1;
103
+ }
104
+
105
+ .hyvui-chapter-mark-index-line {
106
+ display: block;
107
+ width: 2.5rem;
108
+ height: 1px;
109
+ background: var(--line);
110
+ }
111
+
112
+ .hyvui-chapter-mark-text {
113
+ display: flex;
114
+ flex-direction: column;
115
+ gap: calc(0.5rem * var(--reg-spacing-scale, 1));
116
+ }
117
+
118
+ .hyvui-chapter-mark-title {
119
+ margin: 0;
120
+ font-family: var(--font-body);
121
+ font-weight: 400;
122
+ font-size: clamp(1.8rem, 4vw, 3rem);
123
+ letter-spacing: -0.03em;
124
+ line-height: 1.05;
125
+ color: var(--text);
126
+ animation: chapter-title-in 0.45s cubic-bezier(0.22, 1, 0.36, 1) 0.15s both;
127
+ }
128
+
129
+ @keyframes chapter-title-in {
130
+ from {
131
+ opacity: 0;
132
+ }
133
+ to {
134
+ opacity: 1;
135
+ }
136
+ }
137
+
138
+ @media (prefers-reduced-motion: reduce) {
139
+ .hyvui-chapter-mark-title {
140
+ animation: none;
141
+ }
142
+ }
143
+
144
+ .hyvui-chapter-mark-descriptor {
145
+ margin: 0;
146
+ font-family: var(--font-mono);
147
+ font-size: 0.82rem;
148
+ letter-spacing: 0.06em;
149
+ color: var(--muted);
150
+ line-height: 1.6;
151
+ }
152
+ </style>
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @remarks Architectural section header. Creates structural rhythm without a container.
3
+ * Use for section openers in long-form pages, portfolios, documentation.
4
+ * @example
5
+ * <ChapterMark index="01" title="signal architecture" descriptor="how the system speaks" />
6
+ */
7
+ interface Props {
8
+ /** Chapter index — a number, roman numeral, or label. */
9
+ index?: string | number;
10
+ /** Chapter title. */
11
+ title: string;
12
+ /** Optional descriptor rendered in readout style below the title. */
13
+ descriptor?: string;
14
+ /** Additional CSS classes. */
15
+ class?: string;
16
+ }
17
+ declare const ChapterMark: import("svelte").Component<Props, {}, "">;
18
+ type ChapterMark = ReturnType<typeof ChapterMark>;
19
+ export default ChapterMark;
@@ -4,6 +4,18 @@
4
4
  import Stack from '../layout/Stack.svelte';
5
5
  import type { Snippet } from 'svelte';
6
6
 
7
+ /**
8
+ * @remarks Use instead of building Modal + Button manually for any irreversible or destructive action.
9
+ * @example
10
+ * <ConfirmDialog
11
+ * open={showConfirm}
12
+ * title="delete report"
13
+ * description="this action cannot be undone."
14
+ * destructive
15
+ * onconfirm={deleteReport}
16
+ * oncancel={() => showConfirm = false}
17
+ * />
18
+ */
7
19
  interface Props {
8
20
  /** Controls dialog visibility. */
9
21
  open?: boolean;
@@ -1,3 +1,15 @@
1
+ /**
2
+ * @remarks Use instead of building Modal + Button manually for any irreversible or destructive action.
3
+ * @example
4
+ * <ConfirmDialog
5
+ * open={showConfirm}
6
+ * title="delete report"
7
+ * description="this action cannot be undone."
8
+ * destructive
9
+ * onconfirm={deleteReport}
10
+ * oncancel={() => showConfirm = false}
11
+ * />
12
+ */
1
13
  interface Props {
2
14
  /** Controls dialog visibility. */
3
15
  open?: boolean;
@@ -0,0 +1,123 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../utils/cn.js';
3
+ import CornerBrackets from '../ambient/CornerBrackets.svelte';
4
+ import ScanBand from '../ambient/ScanBand.svelte';
5
+ import DepthStage from '../depth/DepthStage.svelte';
6
+ import DepthLayer from '../depth/DepthLayer.svelte';
7
+ import HorizonGrid from '../depth/HorizonGrid.svelte';
8
+ import type { Snippet } from 'svelte';
9
+
10
+ /**
11
+ * @remarks A framed spatial window — a card alternative where content lives in depth, not on a surface.
12
+ * Use in place of Card when you want content to feel embedded in space.
13
+ * @example
14
+ * <DepthPortal label="sensor array / 004" active={scanning}>
15
+ * <Text variant="heading">deep signal</Text>
16
+ * </DepthPortal>
17
+ */
18
+ interface Props {
19
+ /** Readout label at bottom-left. */
20
+ label?: string;
21
+ /** When true, a ScanBand sweeps through to signal activity. */
22
+ active?: boolean;
23
+ /** CSS aspect-ratio value. */
24
+ aspect?: string;
25
+ /** Additional CSS classes. */
26
+ class?: string;
27
+ /** Content rendered at foreground depth level. */
28
+ children?: Snippet;
29
+ }
30
+
31
+ let {
32
+ label,
33
+ active = false,
34
+ aspect = '4/3',
35
+ class: className = '',
36
+ children
37
+ }: Props = $props();
38
+ </script>
39
+
40
+ <div class={cn('hyvui-depth-portal', className)} style:aspect-ratio={aspect}>
41
+ <HorizonGrid class="hyvui-depth-portal-grid" animated={false} vanishY={0.42} rows={10} cols={8} />
42
+
43
+ <div class="hyvui-depth-portal-brackets" aria-hidden="true" style:opacity="var(--reg-ornament-opacity)">
44
+ <CornerBrackets size={14} />
45
+ </div>
46
+
47
+ <div class="hyvui-depth-portal-scan" aria-hidden="true" class:hyvui-depth-portal-scan--active={active}>
48
+ <ScanBand axis="y" size="12%" duration="2.8s" />
49
+ </div>
50
+
51
+ <DepthStage perspective="near" class="hyvui-depth-portal-stage">
52
+ <DepthLayer level="foreground" class="hyvui-depth-portal-layer">
53
+ {#if children}{@render children()}{/if}
54
+ </DepthLayer>
55
+ </DepthStage>
56
+
57
+ {#if label}
58
+ <div class="hyvui-depth-portal-label" aria-hidden="true">{label}</div>
59
+ {/if}
60
+ </div>
61
+
62
+ <style>
63
+ .hyvui-depth-portal {
64
+ position: relative;
65
+ overflow: hidden;
66
+ border: 1px solid var(--line);
67
+ }
68
+
69
+ :global(.hyvui-depth-portal-grid) {
70
+ position: absolute;
71
+ inset: 0;
72
+ }
73
+
74
+ .hyvui-depth-portal-brackets {
75
+ position: absolute;
76
+ inset: 0.75rem;
77
+ pointer-events: none;
78
+ }
79
+
80
+ .hyvui-depth-portal-scan {
81
+ position: absolute;
82
+ inset: 0;
83
+ pointer-events: none;
84
+ opacity: 0;
85
+ transition: opacity 0.4s var(--ease-fast);
86
+ }
87
+
88
+ .hyvui-depth-portal-scan--active {
89
+ opacity: 1;
90
+ }
91
+
92
+ :global(.hyvui-depth-portal-stage) {
93
+ position: absolute;
94
+ inset: 0;
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ }
99
+
100
+ :global(.hyvui-depth-portal-layer) {
101
+ display: flex;
102
+ align-items: center;
103
+ justify-content: center;
104
+ }
105
+
106
+ .hyvui-depth-portal-label {
107
+ position: absolute;
108
+ bottom: 0.65rem;
109
+ left: 0.8rem;
110
+ font-family: var(--font-mono);
111
+ font-size: 0.82rem;
112
+ letter-spacing: 0.06em;
113
+ color: var(--muted);
114
+ line-height: 1.6;
115
+ pointer-events: none;
116
+ }
117
+
118
+ @media (prefers-reduced-motion: reduce) {
119
+ .hyvui-depth-portal-scan {
120
+ display: none;
121
+ }
122
+ }
123
+ </style>
@@ -0,0 +1,24 @@
1
+ import type { Snippet } from 'svelte';
2
+ /**
3
+ * @remarks A framed spatial window — a card alternative where content lives in depth, not on a surface.
4
+ * Use in place of Card when you want content to feel embedded in space.
5
+ * @example
6
+ * <DepthPortal label="sensor array / 004" active={scanning}>
7
+ * <Text variant="heading">deep signal</Text>
8
+ * </DepthPortal>
9
+ */
10
+ interface Props {
11
+ /** Readout label at bottom-left. */
12
+ label?: string;
13
+ /** When true, a ScanBand sweeps through to signal activity. */
14
+ active?: boolean;
15
+ /** CSS aspect-ratio value. */
16
+ aspect?: string;
17
+ /** Additional CSS classes. */
18
+ class?: string;
19
+ /** Content rendered at foreground depth level. */
20
+ children?: Snippet;
21
+ }
22
+ declare const DepthPortal: import("svelte").Component<Props, {}, "">;
23
+ type DepthPortal = ReturnType<typeof DepthPortal>;
24
+ export default DepthPortal;