@joewinke/jatui 0.1.31 → 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 (239) hide show
  1. package/CLAUDE.md +22 -0
  2. package/dist/actions/attention.d.ts +24 -0
  3. package/dist/actions/attention.js +94 -0
  4. package/dist/actions/collapse.js +29 -15
  5. package/dist/actions/floating.d.ts +53 -0
  6. package/dist/actions/floating.js +158 -0
  7. package/dist/actions/listNav.js +137 -108
  8. package/dist/actions/railNav.js +89 -72
  9. package/dist/actions/staggerEntrance.d.ts +28 -0
  10. package/dist/actions/staggerEntrance.js +71 -0
  11. package/dist/actions/tooltip.d.ts +28 -0
  12. package/dist/actions/tooltip.js +186 -0
  13. package/dist/assets/sounds/README.md +47 -0
  14. package/dist/assets/sounds/error.d.ts +1 -0
  15. package/dist/assets/sounds/error.js +4 -0
  16. package/dist/assets/sounds/notify.d.ts +1 -0
  17. package/dist/assets/sounds/notify.js +4 -0
  18. package/dist/assets/sounds/pop.d.ts +1 -0
  19. package/dist/assets/sounds/pop.js +4 -0
  20. package/dist/assets/sounds/send.d.ts +1 -0
  21. package/dist/assets/sounds/send.js +4 -0
  22. package/dist/assets/sounds/success.d.ts +1 -0
  23. package/dist/assets/sounds/success.js +4 -0
  24. package/dist/assets/sounds/toggle.d.ts +1 -0
  25. package/dist/assets/sounds/toggle.js +4 -0
  26. package/dist/components/AnimatedNumber.svelte +112 -0
  27. package/dist/components/AnimatedNumber.svelte.d.ts +8 -0
  28. package/dist/components/Badge.svelte +75 -4
  29. package/dist/components/Badge.svelte.d.ts +6 -1
  30. package/dist/components/Button.svelte +196 -21
  31. package/dist/components/Button.svelte.d.ts +10 -1
  32. package/dist/components/Carousel.svelte +265 -0
  33. package/dist/components/Carousel.svelte.d.ts +21 -0
  34. package/dist/components/ChipInput.svelte +63 -3
  35. package/dist/components/Collapse.svelte +70 -14
  36. package/dist/components/Collapse.svelte.d.ts +11 -0
  37. package/dist/components/ColorSelector.svelte +21 -24
  38. package/dist/components/CommandPalette.svelte +475 -0
  39. package/dist/components/CommandPalette.svelte.d.ts +3 -0
  40. package/dist/components/ContextMenu.svelte +9 -73
  41. package/dist/components/CopyButton.svelte +156 -0
  42. package/dist/components/CopyButton.svelte.d.ts +12 -0
  43. package/dist/components/HoldToConfirm.svelte +183 -0
  44. package/dist/components/HoldToConfirm.svelte.d.ts +11 -0
  45. package/dist/components/KeyboardShortcutsOverlay.svelte +54 -8
  46. package/dist/components/KeyboardShortcutsOverlay.svelte.d.ts +3 -0
  47. package/dist/components/PasswordMeter.svelte +87 -0
  48. package/dist/components/PasswordMeter.svelte.d.ts +8 -0
  49. package/dist/components/PinInput.svelte +186 -0
  50. package/dist/components/PinInput.svelte.d.ts +13 -0
  51. package/dist/components/QuantityStepper.svelte +185 -0
  52. package/dist/components/QuantityStepper.svelte.d.ts +12 -0
  53. package/dist/components/Skeleton.svelte +123 -0
  54. package/dist/components/Skeleton.svelte.d.ts +12 -0
  55. package/dist/components/SpeechForm.svelte +37 -0
  56. package/dist/components/StatusBadge.svelte +31 -3
  57. package/dist/components/StatusBadge.svelte.d.ts +0 -5
  58. package/dist/components/Tabs.svelte +270 -0
  59. package/dist/components/Tabs.svelte.d.ts +15 -0
  60. package/dist/components/TextInput.svelte +138 -38
  61. package/dist/components/TextInput.svelte.d.ts +9 -1
  62. package/dist/components/VoicePlayer.svelte +51 -0
  63. package/dist/components/basic/Alert.svelte +36 -0
  64. package/dist/components/basic/Alert.svelte.d.ts +9 -0
  65. package/dist/components/basic/Breadcrumb.svelte +27 -0
  66. package/dist/components/basic/Breadcrumb.svelte.d.ts +11 -0
  67. package/dist/components/basic/ButtonGroup.svelte +15 -0
  68. package/dist/components/basic/ButtonGroup.svelte.d.ts +8 -0
  69. package/dist/components/basic/Checkbox.svelte +85 -0
  70. package/dist/components/basic/Checkbox.svelte.d.ts +15 -0
  71. package/dist/components/basic/Empty.svelte +17 -0
  72. package/dist/components/basic/Empty.svelte.d.ts +8 -0
  73. package/dist/components/basic/Kbd.svelte +16 -0
  74. package/dist/components/basic/Kbd.svelte.d.ts +8 -0
  75. package/dist/components/basic/Pagination.svelte +104 -0
  76. package/dist/components/basic/Pagination.svelte.d.ts +12 -0
  77. package/dist/components/basic/RadioGroup.svelte +71 -0
  78. package/dist/components/basic/RadioGroup.svelte.d.ts +18 -0
  79. package/dist/components/basic/Separator.svelte +19 -0
  80. package/dist/components/basic/Separator.svelte.d.ts +8 -0
  81. package/dist/components/basic/Slider.svelte +72 -0
  82. package/dist/components/basic/Slider.svelte.d.ts +17 -0
  83. package/dist/components/basic/Switch.svelte +88 -0
  84. package/dist/components/basic/Switch.svelte.d.ts +14 -0
  85. package/dist/components/basic/Toggle.svelte +43 -0
  86. package/dist/components/basic/Toggle.svelte.d.ts +14 -0
  87. package/dist/components/graph/GraphCanvas.svelte +103 -0
  88. package/dist/components/graph/GraphCanvas.svelte.d.ts +22 -0
  89. package/dist/components/graph/JatuiNode.svelte +128 -0
  90. package/dist/components/graph/JatuiNode.svelte.d.ts +14 -0
  91. package/dist/components/graph/theme.d.ts +27 -0
  92. package/dist/components/graph/theme.js +136 -0
  93. package/dist/components/markup.js +62 -59
  94. package/dist/components/messaging/MessageItem.svelte +92 -0
  95. package/dist/components/messaging/MessageItem.svelte.d.ts +5 -0
  96. package/dist/components/messaging/TypingIndicator.svelte +63 -0
  97. package/dist/components/messaging/TypingIndicator.svelte.d.ts +7 -0
  98. package/dist/components/pipeline/PipelineColumn.svelte +44 -3
  99. package/dist/components/progress/ProgressBar.svelte +189 -0
  100. package/dist/components/progress/ProgressBar.svelte.d.ts +17 -0
  101. package/dist/components/progress/ProgressRing.svelte +138 -0
  102. package/dist/components/progress/ProgressRing.svelte.d.ts +12 -0
  103. package/dist/components/progress/Steps.svelte +195 -0
  104. package/dist/components/progress/Steps.svelte.d.ts +14 -0
  105. package/dist/components/session-nav/transcriptModel.js +66 -49
  106. package/dist/components/shell/NavigationMenu.svelte +422 -0
  107. package/dist/components/shell/NavigationMenu.svelte.d.ts +43 -0
  108. package/dist/components/shell/Sidebar.svelte +276 -0
  109. package/dist/components/shell/Sidebar.svelte.d.ts +32 -0
  110. package/dist/components/shell/SidebarGroup.svelte +180 -0
  111. package/dist/components/shell/SidebarGroup.svelte.d.ts +19 -0
  112. package/dist/components/shell/SidebarItem.svelte +170 -0
  113. package/dist/components/shell/SidebarItem.svelte.d.ts +24 -0
  114. package/dist/components/shell/shell.d.ts +30 -0
  115. package/dist/components/shell/shell.js +65 -0
  116. package/dist/components/table/DataTable.svelte +364 -0
  117. package/dist/components/table/DataTable.svelte.d.ts +4 -0
  118. package/dist/components/table/flexRender.d.ts +31 -0
  119. package/dist/components/table/flexRender.js +32 -0
  120. package/dist/components/table/types.d.ts +28 -0
  121. package/dist/components/table/types.js +1 -0
  122. package/dist/components/toast/ToastHost.svelte +21 -0
  123. package/dist/components/toast/ToastHost.svelte.d.ts +3 -0
  124. package/dist/components/toast/ToastItem.svelte +287 -0
  125. package/dist/components/toast/ToastItem.svelte.d.ts +9 -0
  126. package/dist/data/emojis.js +4 -4
  127. package/dist/dnd/autoScroll.js +12 -10
  128. package/dist/dnd/createDndBoard.svelte.js +110 -76
  129. package/dist/dnd/createDndBoard.test.js +161 -85
  130. package/dist/dnd/draggable.js +23 -15
  131. package/dist/dnd/dropTarget.js +29 -15
  132. package/dist/dnd/index.d.ts +0 -1
  133. package/dist/dnd/index.js +0 -1
  134. package/dist/dnd/types.d.ts +0 -9
  135. package/dist/dnd/types.js +14 -2
  136. package/dist/index.d.ts +60 -6
  137. package/dist/index.js +73 -6
  138. package/dist/showcase/AnimatedBeam.svelte +183 -0
  139. package/dist/showcase/AnimatedBeam.svelte.d.ts +26 -0
  140. package/dist/showcase/AuroraDrift.svelte +74 -0
  141. package/dist/showcase/AuroraDrift.svelte.d.ts +9 -0
  142. package/dist/showcase/BentoCard.svelte +50 -0
  143. package/dist/showcase/BentoCard.svelte.d.ts +14 -0
  144. package/dist/showcase/BentoGrid.svelte +43 -0
  145. package/dist/showcase/BentoGrid.svelte.d.ts +12 -0
  146. package/dist/showcase/BorderBeam.svelte +79 -0
  147. package/dist/showcase/BorderBeam.svelte.d.ts +12 -0
  148. package/dist/showcase/ClipWipe.svelte +82 -0
  149. package/dist/showcase/ClipWipe.svelte.d.ts +12 -0
  150. package/dist/showcase/Confetti.svelte +71 -0
  151. package/dist/showcase/Confetti.svelte.d.ts +10 -0
  152. package/dist/showcase/CursorSpotlight.svelte +85 -0
  153. package/dist/showcase/CursorSpotlight.svelte.d.ts +9 -0
  154. package/dist/showcase/DeviceMock.svelte +186 -0
  155. package/dist/showcase/DeviceMock.svelte.d.ts +11 -0
  156. package/dist/showcase/Dock.svelte +123 -0
  157. package/dist/showcase/Dock.svelte.d.ts +17 -0
  158. package/dist/showcase/FlipCard.svelte +103 -0
  159. package/dist/showcase/FlipCard.svelte.d.ts +10 -0
  160. package/dist/showcase/FocusReveal.svelte +83 -0
  161. package/dist/showcase/FocusReveal.svelte.d.ts +11 -0
  162. package/dist/showcase/Globe.svelte +202 -0
  163. package/dist/showcase/Globe.svelte.d.ts +16 -0
  164. package/dist/showcase/KenBurns.svelte +105 -0
  165. package/dist/showcase/KenBurns.svelte.d.ts +13 -0
  166. package/dist/showcase/Marquee.svelte +89 -0
  167. package/dist/showcase/Marquee.svelte.d.ts +9 -0
  168. package/dist/showcase/ParallaxTilt.svelte +98 -0
  169. package/dist/showcase/ParallaxTilt.svelte.d.ts +10 -0
  170. package/dist/showcase/ScrambleText.svelte +98 -0
  171. package/dist/showcase/ScrambleText.svelte.d.ts +11 -0
  172. package/dist/showcase/ShineSweep.svelte +81 -0
  173. package/dist/showcase/ShineSweep.svelte.d.ts +9 -0
  174. package/dist/showcase/Terminal.svelte +230 -0
  175. package/dist/showcase/Terminal.svelte.d.ts +18 -0
  176. package/dist/showcase/TextSplitReveal.svelte +146 -0
  177. package/dist/showcase/TextSplitReveal.svelte.d.ts +13 -0
  178. package/dist/showcase/TextWave.svelte +55 -0
  179. package/dist/showcase/TextWave.svelte.d.ts +8 -0
  180. package/dist/showcase/TypewriterText.svelte +130 -0
  181. package/dist/showcase/TypewriterText.svelte.d.ts +9 -0
  182. package/dist/showcase/backdrop/GrainGradient.svelte +126 -0
  183. package/dist/showcase/backdrop/GrainGradient.svelte.d.ts +23 -0
  184. package/dist/showcase/backdrop/MeshGradient.svelte +104 -0
  185. package/dist/showcase/backdrop/MeshGradient.svelte.d.ts +20 -0
  186. package/dist/showcase/backdrop/Metaballs.svelte +116 -0
  187. package/dist/showcase/backdrop/Metaballs.svelte.d.ts +18 -0
  188. package/dist/showcase/backdrop/NeuroNoise.svelte +115 -0
  189. package/dist/showcase/backdrop/NeuroNoise.svelte.d.ts +20 -0
  190. package/dist/showcase/backdrop/ShowcaseBackdrop.svelte +48 -0
  191. package/dist/showcase/backdrop/ShowcaseBackdrop.svelte.d.ts +12 -0
  192. package/dist/showcase/generative/GenerativeBackdrop.svelte +234 -0
  193. package/dist/showcase/generative/GenerativeBackdrop.svelte.d.ts +9 -0
  194. package/dist/showcase/generative/intent.d.ts +7 -0
  195. package/dist/showcase/generative/intent.js +67 -0
  196. package/dist/showcase/generative/manifest.d.ts +9 -0
  197. package/dist/showcase/generative/manifest.js +97 -0
  198. package/dist/showcase/generative/types.d.ts +48 -0
  199. package/dist/showcase/generative/types.js +8 -0
  200. package/dist/showcase/index.d.ts +36 -0
  201. package/dist/showcase/index.js +46 -0
  202. package/dist/showcase/scroll/SmoothScroll.svelte +49 -0
  203. package/dist/showcase/scroll/SmoothScroll.svelte.d.ts +12 -0
  204. package/dist/showcase/scroll/scrollProgress.d.ts +24 -0
  205. package/dist/showcase/scroll/scrollProgress.js +65 -0
  206. package/dist/showcase/scroll/scrollReveal.d.ts +30 -0
  207. package/dist/showcase/scroll/scrollReveal.js +70 -0
  208. package/dist/stores/commandPalette.svelte.d.ts +24 -0
  209. package/dist/stores/commandPalette.svelte.js +82 -0
  210. package/dist/stores/confirmDialog.svelte.js +5 -5
  211. package/dist/stores/inputDialog.svelte.js +5 -5
  212. package/dist/stores/toast.svelte.d.ts +28 -0
  213. package/dist/stores/toast.svelte.js +33 -0
  214. package/dist/styles/motion.css +46 -0
  215. package/dist/styles/tokens.css +31 -0
  216. package/dist/transitions/glide.d.ts +31 -0
  217. package/dist/transitions/glide.js +58 -0
  218. package/dist/types/booking.js +4 -4
  219. package/dist/types/comments.js +2 -2
  220. package/dist/types/messaging.js +3 -3
  221. package/dist/types/pipeline.js +2 -2
  222. package/dist/utils/currency.js +4 -2
  223. package/dist/utils/daisyuiColors.js +27 -25
  224. package/dist/utils/dateFormatters.d.ts +20 -0
  225. package/dist/utils/dateFormatters.js +65 -44
  226. package/dist/utils/googleMapsLoader.js +100 -46
  227. package/dist/utils/mentionParser.js +30 -30
  228. package/dist/utils/phone.js +27 -21
  229. package/dist/utils/phoneFormat.js +9 -9
  230. package/dist/utils/sound.d.ts +6 -0
  231. package/dist/utils/sound.js +113 -0
  232. package/dist/utils/splitText.d.ts +25 -0
  233. package/dist/utils/splitText.js +94 -0
  234. package/dist/utils/taskUtils.js +1 -1
  235. package/dist/utils/themeWipe.d.ts +21 -0
  236. package/dist/utils/themeWipe.js +94 -0
  237. package/dist/utils/viewTransition.d.ts +23 -0
  238. package/dist/utils/viewTransition.js +75 -0
  239. package/package.json +56 -4
package/dist/index.js CHANGED
@@ -82,7 +82,7 @@ export { default as AvailabilityModal } from './components/AvailabilityModal.sve
82
82
  export { default as BookingForm } from './components/BookingForm.svelte';
83
83
  export { DAYS_OF_WEEK, DAYS_SHORT, LOCATION_LABELS, LOCATION_ICONS } from './types/booking';
84
84
  // Utilities — date formatting
85
- export { normalizeTimestamp, parseTimestamp, formatRelativeTime, formatFullDate, formatShortDate, formatLastActivity, formatDate, getTimeSinceMs, getTimeSinceMinutes, isWithinMinutes, formatDateTime, taskAge, } from './utils/dateFormatters';
85
+ export { normalizeTimestamp, parseTimestamp, formatRelativeTime, formatFullDate, formatShortDate, formatLastActivity, formatDate, getTimeSinceMs, getTimeSinceMinutes, isWithinMinutes, formatDateTime, taskAge, pacingColor, } from './utils/dateFormatters';
86
86
  // Utilities — task display helpers
87
87
  export { statusColor, priorityColor, typeIcon, statusLabel, } from './utils/taskUtils';
88
88
  // Utilities — phone formatting (legacy US-only)
@@ -141,8 +141,75 @@ export { default as LocationMap } from './components/LocationMap.svelte';
141
141
  export { default as GPSTracker } from './components/GPSTracker.svelte';
142
142
  // Utilities — Google Maps loader
143
143
  export { loadGoogleMapsAPI, isGoogleMapsLoaded, isPlacesLoaded, isGeometryLoaded, } from './utils/googleMapsLoader';
144
- // DnD — pragmatic-drag-and-drop wrappers (peerDep: @atlaskit/pragmatic-drag-and-drop*)
145
- export { draggable, dropTarget, autoScroll, announce, cleanupAnnouncements, monitorForElements, attachClosestEdge, extractClosestEdge, } from './dnd/index';
146
- export { createDndBoard } from './dnd/createDndBoard.svelte';
147
- export { default as DropIndicator } from './dnd/DropIndicator.svelte';
148
- export { makeItemData, isItemData } from './dnd/types';
144
+ // DnD — pragmatic-drag-and-drop wrappers live behind the `@joewinke/jatui/dnd`
145
+ // subpath export, NOT this barrel. Re-exporting them here forced every barrel
146
+ // consumer to install the optional @atlaskit/pragmatic-drag-and-drop* peer deps
147
+ // (and broke bundlers that stub the unresolved optional peer). Import DnD via:
148
+ // import { draggable, DropIndicator } from '@joewinke/jatui/dnd';
149
+ // ============================================================
150
+ // Wave 1+2 (jatui-pk6jz / jatui-x2hyv) — kinetics motion port,
151
+ // research-verified gap fills, generative-pipeline era exports.
152
+ // ============================================================
153
+ // Motion primitives
154
+ export { tooltip } from './actions/tooltip';
155
+ export { staggerEntrance } from './actions/staggerEntrance';
156
+ export { attention } from './actions/attention';
157
+ export { floating, makeVirtualAnchor } from './actions/floating';
158
+ export { glide } from './transitions/glide';
159
+ // View Transitions kit
160
+ export { themeWipe } from './utils/themeWipe';
161
+ export { viewTransition } from './utils/viewTransition';
162
+ // Sound kit (functional feedback, opt-in)
163
+ export { play as playSound, registerSound, isSoundEnabled, setSoundEnabled } from './utils/sound';
164
+ // Text utilities
165
+ export { splitText } from './utils/splitText';
166
+ // Toast system
167
+ export { default as ToastHost } from './components/toast/ToastHost.svelte';
168
+ export { showToast, dismissToast, getToasts } from './stores/toast.svelte';
169
+ // Loading & progress family
170
+ export { default as Skeleton } from './components/Skeleton.svelte';
171
+ export { default as ProgressBar } from './components/progress/ProgressBar.svelte';
172
+ export { default as ProgressRing } from './components/progress/ProgressRing.svelte';
173
+ export { default as Steps } from './components/progress/Steps.svelte';
174
+ // Navigation & overlays
175
+ export { default as Tabs } from './components/Tabs.svelte';
176
+ export { default as CommandPalette } from './components/CommandPalette.svelte';
177
+ export { commandPalette } from './stores/commandPalette.svelte';
178
+ // Micro primitives
179
+ export { default as AnimatedNumber } from './components/AnimatedNumber.svelte';
180
+ export { default as CopyButton } from './components/CopyButton.svelte';
181
+ export { default as HoldToConfirm } from './components/HoldToConfirm.svelte';
182
+ // Form gaps
183
+ export { default as PinInput } from './components/PinInput.svelte';
184
+ export { default as PasswordMeter } from './components/PasswordMeter.svelte';
185
+ export { default as QuantityStepper } from './components/QuantityStepper.svelte';
186
+ // Messaging
187
+ export { default as TypingIndicator } from './components/messaging/TypingIndicator.svelte';
188
+ // Data table
189
+ export { default as DataTable } from './components/table/DataTable.svelte';
190
+ export { flexRender } from './components/table/flexRender';
191
+ // Graph canvas (Svelte Flow)
192
+ export { default as GraphCanvas } from './components/graph/GraphCanvas.svelte';
193
+ export { default as JatuiNode } from './components/graph/JatuiNode.svelte';
194
+ export { getStatusColor, applyXyflowTheme, watchAndApplyTheme } from './components/graph/theme';
195
+ // App shell
196
+ export { default as Sidebar } from './components/shell/Sidebar.svelte';
197
+ export { default as SidebarGroup } from './components/shell/SidebarGroup.svelte';
198
+ export { default as SidebarItem } from './components/shell/SidebarItem.svelte';
199
+ export { default as NavigationMenu } from './components/shell/NavigationMenu.svelte';
200
+ export { createSidebarState } from './components/shell/shell';
201
+ // Carousel
202
+ export { default as Carousel } from './components/Carousel.svelte';
203
+ // Basic primitives (thin DaisyUI wraps — layering policy)
204
+ export { default as Kbd } from './components/basic/Kbd.svelte';
205
+ export { default as Empty } from './components/basic/Empty.svelte';
206
+ export { default as Breadcrumb } from './components/basic/Breadcrumb.svelte';
207
+ export { default as Alert } from './components/basic/Alert.svelte';
208
+ export { default as ButtonGroup } from './components/basic/ButtonGroup.svelte';
209
+ export { default as Switch } from './components/basic/Switch.svelte';
210
+ export { default as Checkbox } from './components/basic/Checkbox.svelte';
211
+ export { default as RadioGroup } from './components/basic/RadioGroup.svelte';
212
+ export { default as Toggle } from './components/basic/Toggle.svelte';
213
+ export { default as Separator } from './components/basic/Separator.svelte';
214
+ export { default as Slider } from './components/basic/Slider.svelte';
215
+ export { default as Pagination } from './components/basic/Pagination.svelte';
@@ -0,0 +1,183 @@
1
+ <script lang="ts">
2
+ // pattern after magicui.design (MIT)
3
+ import { onMount, onDestroy } from 'svelte';
4
+
5
+ interface Props {
6
+ /** ID of the start element */
7
+ fromId: string;
8
+ /** ID of the end element */
9
+ toId: string;
10
+ /** Containing element for coordinate calculations (defaults to document.body) */
11
+ containerId?: string;
12
+ /** Gradient start color */
13
+ colorFrom?: string;
14
+ /** Gradient end color */
15
+ colorTo?: string;
16
+ /** Stroke width */
17
+ strokeWidth?: number;
18
+ /** Beam sweep duration in seconds */
19
+ duration?: number;
20
+ /** Dash length as fraction of path (0–1) */
21
+ dashLength?: number;
22
+ /** Curvature 0–1 (0 = straight, 1 = very curved) */
23
+ curvature?: number;
24
+ /** Reverse beam direction */
25
+ reverse?: boolean;
26
+ class?: string;
27
+ }
28
+
29
+ let {
30
+ fromId,
31
+ toId,
32
+ containerId,
33
+ colorFrom = 'oklch(var(--p))',
34
+ colorTo = 'oklch(var(--a))',
35
+ strokeWidth = 2,
36
+ duration = 3,
37
+ dashLength = 0.25,
38
+ curvature = 0.5,
39
+ reverse = false,
40
+ class: className = ''
41
+ }: Props = $props();
42
+
43
+ let svgEl: SVGSVGElement | undefined = $state();
44
+ let pathD = $state('');
45
+ let pathLength = $state(0);
46
+ let reducedMotion = $state(false);
47
+
48
+ const uid = Math.random().toString(36).slice(2, 8);
49
+ const gradId = `beam-grad-${uid}`;
50
+ const pathId = `beam-path-${uid}`;
51
+
52
+ function getCenter(el: Element, container: Element): { x: number; y: number } {
53
+ const elR = el.getBoundingClientRect();
54
+ const cR = container.getBoundingClientRect();
55
+ return {
56
+ x: elR.left + elR.width / 2 - cR.left,
57
+ y: elR.top + elR.height / 2 - cR.top
58
+ };
59
+ }
60
+
61
+ function updatePath() {
62
+ const root = containerId ? document.getElementById(containerId) : svgEl?.parentElement;
63
+ if (!root || !svgEl) return;
64
+
65
+ const fromEl = document.getElementById(fromId);
66
+ const toEl = document.getElementById(toId);
67
+ if (!fromEl || !toEl) return;
68
+
69
+ const from = getCenter(fromEl, root);
70
+ const to = getCenter(toEl, root);
71
+
72
+ // Resize SVG to container
73
+ const rr = root.getBoundingClientRect();
74
+ svgEl.style.width = rr.width + 'px';
75
+ svgEl.style.height = rr.height + 'px';
76
+
77
+ // Cubic bezier: control points offset vertically by curvature
78
+ const dy = Math.abs(to.y - from.y) * curvature;
79
+ const cx1 = from.x;
80
+ const cy1 = from.y - dy;
81
+ const cx2 = to.x;
82
+ const cy2 = to.y + dy;
83
+
84
+ const d = `M ${from.x},${from.y} C ${cx1},${cy1} ${cx2},${cy2} ${to.x},${to.y}`;
85
+ pathD = d;
86
+
87
+ // Measure path length after DOM update
88
+ requestAnimationFrame(() => {
89
+ const pathEl = svgEl?.querySelector(`#${pathId}`) as SVGPathElement | null;
90
+ if (pathEl) pathLength = pathEl.getTotalLength();
91
+ });
92
+ }
93
+
94
+ let resizeObs: ResizeObserver | undefined;
95
+
96
+ onMount(() => {
97
+ reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
98
+ updatePath();
99
+
100
+ const root = containerId ? document.getElementById(containerId) : svgEl?.parentElement;
101
+ if (root) {
102
+ resizeObs = new ResizeObserver(updatePath);
103
+ resizeObs.observe(root);
104
+ }
105
+ });
106
+
107
+ onDestroy(() => {
108
+ resizeObs?.disconnect();
109
+ });
110
+
111
+ const dashArr = $derived(
112
+ pathLength > 0 ? `${pathLength * dashLength} ${pathLength * (1 - dashLength)}` : '0 1'
113
+ );
114
+ const dashOffset = $derived(pathLength > 0 ? (reverse ? -pathLength : pathLength) : 0);
115
+ </script>
116
+
117
+ <!-- svelte-ignore a11y_aria_hidden_on_focusable -->
118
+ <svg
119
+ bind:this={svgEl}
120
+ class="animated-beam {className}"
121
+ xmlns="http://www.w3.org/2000/svg"
122
+ style="pointer-events:none; position:absolute; inset:0; overflow:visible;"
123
+ aria-hidden="true"
124
+ >
125
+ <defs>
126
+ <linearGradient id={gradId} gradientUnits="userSpaceOnUse">
127
+ <stop offset="0%" stop-color={colorFrom} stop-opacity="0" />
128
+ <stop offset="20%" stop-color={colorFrom} />
129
+ <stop offset="80%" stop-color={colorTo} />
130
+ <stop offset="100%" stop-color={colorTo} stop-opacity="0" />
131
+ </linearGradient>
132
+ </defs>
133
+
134
+ <!-- Static base line -->
135
+ {#if pathD}
136
+ <path d={pathD} stroke="oklch(var(--bc) / 0.08)" stroke-width={strokeWidth} fill="none" />
137
+
138
+ <!-- Animated beam -->
139
+ {#if !reducedMotion}
140
+ <path
141
+ id={pathId}
142
+ d={pathD}
143
+ stroke="url(#{gradId})"
144
+ stroke-width={strokeWidth}
145
+ fill="none"
146
+ stroke-linecap="round"
147
+ stroke-dasharray={dashArr}
148
+ stroke-dashoffset="0"
149
+ style="animation: beam-sweep-{uid} {duration}s linear infinite var(--motion-glide);"
150
+ />
151
+ {:else}
152
+ <!-- Reduced motion: static gradient line -->
153
+ <path
154
+ id={pathId}
155
+ d={pathD}
156
+ stroke="url(#{gradId})"
157
+ stroke-width={strokeWidth}
158
+ fill="none"
159
+ stroke-linecap="round"
160
+ opacity="0.6"
161
+ />
162
+ {/if}
163
+ {/if}
164
+ </svg>
165
+
166
+ <style>
167
+ .animated-beam {
168
+ position: absolute;
169
+ inset: 0;
170
+ overflow: visible;
171
+ pointer-events: none;
172
+ }
173
+ </style>
174
+
175
+ <!-- Keyframes injected per-instance via a style tag to use the dynamic dashOffset -->
176
+ {#if pathLength > 0 && !reducedMotion}
177
+ {@html `<style>
178
+ @keyframes beam-sweep-${uid} {
179
+ 0% { stroke-dashoffset: ${dashOffset}; }
180
+ 100% { stroke-dashoffset: ${-dashOffset}; }
181
+ }
182
+ </style>`}
183
+ {/if}
@@ -0,0 +1,26 @@
1
+ interface Props {
2
+ /** ID of the start element */
3
+ fromId: string;
4
+ /** ID of the end element */
5
+ toId: string;
6
+ /** Containing element for coordinate calculations (defaults to document.body) */
7
+ containerId?: string;
8
+ /** Gradient start color */
9
+ colorFrom?: string;
10
+ /** Gradient end color */
11
+ colorTo?: string;
12
+ /** Stroke width */
13
+ strokeWidth?: number;
14
+ /** Beam sweep duration in seconds */
15
+ duration?: number;
16
+ /** Dash length as fraction of path (0–1) */
17
+ dashLength?: number;
18
+ /** Curvature 0–1 (0 = straight, 1 = very curved) */
19
+ curvature?: number;
20
+ /** Reverse beam direction */
21
+ reverse?: boolean;
22
+ class?: string;
23
+ }
24
+ declare const AnimatedBeam: import("svelte").Component<Props, {}, "">;
25
+ type AnimatedBeam = ReturnType<typeof AnimatedBeam>;
26
+ export default AnimatedBeam;
@@ -0,0 +1,74 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ duration?: number;
6
+ class?: string;
7
+ children?: Snippet;
8
+ }
9
+
10
+ let { duration = 12, class: className = '', children }: Props = $props();
11
+ </script>
12
+
13
+ <div
14
+ class="aurora-drift-root {className}"
15
+ style="--aurora-duration: {duration}s;"
16
+ >
17
+ <div class="aurora-drift-backdrop" aria-hidden="true"></div>
18
+ <div class="aurora-drift-content">
19
+ {#if children}
20
+ {@render children()}
21
+ {/if}
22
+ </div>
23
+ </div>
24
+
25
+ <style>
26
+ .aurora-drift-root {
27
+ position: relative;
28
+ overflow: hidden;
29
+ }
30
+
31
+ .aurora-drift-backdrop {
32
+ position: absolute;
33
+ inset: -40%;
34
+ background:
35
+ radial-gradient(
36
+ 40% 50% at 30% 38%,
37
+ color-mix(in srgb, oklch(var(--p)) 30%, transparent),
38
+ transparent 60%
39
+ ),
40
+ radial-gradient(
41
+ 45% 55% at 72% 62%,
42
+ color-mix(in srgb, oklch(var(--s)) 30%, transparent),
43
+ transparent 60%
44
+ ),
45
+ radial-gradient(
46
+ 40% 50% at 50% 82%,
47
+ color-mix(in srgb, oklch(var(--a)) 25%, transparent),
48
+ transparent 60%
49
+ );
50
+ filter: blur(16px);
51
+ pointer-events: none;
52
+ animation: aurora-drift var(--aurora-duration) ease-in-out infinite alternate;
53
+ }
54
+
55
+ .aurora-drift-content {
56
+ position: relative;
57
+ z-index: 1;
58
+ }
59
+
60
+ @keyframes aurora-drift {
61
+ 0% {
62
+ transform: translate(-6%, -4%) rotate(0deg) scale(1.1);
63
+ }
64
+ 100% {
65
+ transform: translate(6%, 4%) rotate(8deg) scale(1.3);
66
+ }
67
+ }
68
+
69
+ @media (prefers-reduced-motion: reduce) {
70
+ .aurora-drift-backdrop {
71
+ animation: none;
72
+ }
73
+ }
74
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ duration?: number;
4
+ class?: string;
5
+ children?: Snippet;
6
+ }
7
+ declare const AuroraDrift: import("svelte").Component<Props, {}, "">;
8
+ type AuroraDrift = ReturnType<typeof AuroraDrift>;
9
+ export default AuroraDrift;
@@ -0,0 +1,50 @@
1
+ <script lang="ts">
2
+ // pattern after magicui.design (MIT)
3
+ import type { Snippet } from 'svelte';
4
+
5
+ interface Props {
6
+ /** Column span (default 1) */
7
+ colSpan?: number;
8
+ /** Row span (default 1) */
9
+ rowSpan?: number;
10
+ /** Hover tint color (CSS color). No tint if omitted (house rule: no shadows). */
11
+ hoverTint?: string;
12
+ class?: string;
13
+ children: Snippet;
14
+ }
15
+
16
+ let { colSpan = 1, rowSpan = 1, hoverTint, class: className = '', children }: Props = $props();
17
+ </script>
18
+
19
+ <div
20
+ class="bento-card {className}"
21
+ role="listitem"
22
+ style="
23
+ grid-column: span {colSpan};
24
+ grid-row: span {rowSpan};
25
+ {hoverTint ? `--bento-tint: ${hoverTint};` : ''}
26
+ "
27
+ >
28
+ {@render children()}
29
+ </div>
30
+
31
+ <style>
32
+ .bento-card {
33
+ position: relative;
34
+ border-radius: var(--jatui-radius-box);
35
+ border: var(--jatui-border-w) solid oklch(var(--bc) / 0.1);
36
+ background: oklch(var(--b1));
37
+ overflow: hidden;
38
+ transition: background var(--motion-fast) var(--motion-glide);
39
+ }
40
+
41
+ .bento-card:hover {
42
+ background: var(--bento-tint, oklch(var(--b2, var(--b1))));
43
+ }
44
+
45
+ @media (prefers-reduced-motion: reduce) {
46
+ .bento-card {
47
+ transition: none;
48
+ }
49
+ }
50
+ </style>
@@ -0,0 +1,14 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ /** Column span (default 1) */
4
+ colSpan?: number;
5
+ /** Row span (default 1) */
6
+ rowSpan?: number;
7
+ /** Hover tint color (CSS color). No tint if omitted (house rule: no shadows). */
8
+ hoverTint?: string;
9
+ class?: string;
10
+ children: Snippet;
11
+ }
12
+ declare const BentoCard: import("svelte").Component<Props, {}, "">;
13
+ type BentoCard = ReturnType<typeof BentoCard>;
14
+ export default BentoCard;
@@ -0,0 +1,43 @@
1
+ <script lang="ts">
2
+ // pattern after magicui.design (MIT)
3
+ import type { Snippet } from 'svelte';
4
+
5
+ interface Props {
6
+ /** Number of columns in the grid (default 3) */
7
+ cols?: number;
8
+ /** Gap between cells */
9
+ gap?: string;
10
+ class?: string;
11
+ children: Snippet;
12
+ }
13
+
14
+ let { cols = 3, gap = '1rem', class: className = '', children }: Props = $props();
15
+ </script>
16
+
17
+ <div
18
+ class="bento-grid {className}"
19
+ style="--bento-cols: {cols}; --bento-gap: {gap};"
20
+ role="list"
21
+ >
22
+ {@render children()}
23
+ </div>
24
+
25
+ <style>
26
+ .bento-grid {
27
+ display: grid;
28
+ grid-template-columns: repeat(var(--bento-cols), 1fr);
29
+ gap: var(--bento-gap);
30
+ }
31
+
32
+ @media (max-width: 768px) {
33
+ .bento-grid {
34
+ grid-template-columns: 1fr;
35
+ }
36
+ }
37
+
38
+ @media (min-width: 769px) and (max-width: 1024px) {
39
+ .bento-grid {
40
+ grid-template-columns: repeat(min(var(--bento-cols), 2), 1fr);
41
+ }
42
+ }
43
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ /** Number of columns in the grid (default 3) */
4
+ cols?: number;
5
+ /** Gap between cells */
6
+ gap?: string;
7
+ class?: string;
8
+ children: Snippet;
9
+ }
10
+ declare const BentoGrid: import("svelte").Component<Props, {}, "">;
11
+ type BentoGrid = ReturnType<typeof BentoGrid>;
12
+ export default BentoGrid;
@@ -0,0 +1,79 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ duration?: number;
6
+ colorFrom?: string;
7
+ colorTo?: string;
8
+ borderRadius?: string;
9
+ class?: string;
10
+ children?: Snippet;
11
+ }
12
+
13
+ let {
14
+ duration = 3,
15
+ colorFrom = 'oklch(var(--p))',
16
+ colorTo = 'oklch(var(--a))',
17
+ borderRadius = '0.75rem',
18
+ class: className = '',
19
+ children
20
+ }: Props = $props();
21
+ </script>
22
+
23
+ <div
24
+ class="border-beam-root {className}"
25
+ style="--beam-duration: {duration}s; --beam-color-from: {colorFrom}; --beam-color-to: {colorTo}; --beam-radius: {borderRadius};"
26
+ >
27
+ <div class="border-beam-inner">
28
+ {#if children}
29
+ {@render children()}
30
+ {/if}
31
+ </div>
32
+ </div>
33
+
34
+ <style>
35
+ .border-beam-root {
36
+ position: relative;
37
+ padding: 1.5px;
38
+ overflow: hidden;
39
+ border-radius: var(--beam-radius);
40
+ }
41
+
42
+ .border-beam-root::before {
43
+ content: '';
44
+ position: absolute;
45
+ top: 50%;
46
+ left: 50%;
47
+ width: 200%;
48
+ height: 200%;
49
+ transform: translate(-50%, -50%);
50
+ background: conic-gradient(
51
+ from 0deg,
52
+ transparent 0 72%,
53
+ var(--beam-color-from) 84%,
54
+ var(--beam-color-to) 90%,
55
+ transparent 96% 100%
56
+ );
57
+ animation: beam-spin var(--beam-duration) linear infinite;
58
+ }
59
+
60
+ .border-beam-inner {
61
+ position: relative;
62
+ z-index: 1;
63
+ width: 100%;
64
+ height: 100%;
65
+ border-radius: calc(var(--beam-radius) - 1.5px);
66
+ }
67
+
68
+ @keyframes beam-spin {
69
+ to {
70
+ transform: translate(-50%, -50%) rotate(1turn);
71
+ }
72
+ }
73
+
74
+ @media (prefers-reduced-motion: reduce) {
75
+ .border-beam-root::before {
76
+ animation: none;
77
+ }
78
+ }
79
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ duration?: number;
4
+ colorFrom?: string;
5
+ colorTo?: string;
6
+ borderRadius?: string;
7
+ class?: string;
8
+ children?: Snippet;
9
+ }
10
+ declare const BorderBeam: import("svelte").Component<Props, {}, "">;
11
+ type BorderBeam = ReturnType<typeof BorderBeam>;
12
+ export default BorderBeam;
@@ -0,0 +1,82 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+
4
+ type Direction = 'left' | 'right' | 'top' | 'bottom';
5
+ type TriggerMode = 'mount' | 'intersect';
6
+
7
+ interface Props {
8
+ direction?: Direction;
9
+ triggerMode?: TriggerMode;
10
+ duration?: number;
11
+ class?: string;
12
+ children: import('svelte').Snippet;
13
+ }
14
+
15
+ let {
16
+ direction = 'left',
17
+ triggerMode = 'mount',
18
+ duration = 500,
19
+ class: className = '',
20
+ children,
21
+ }: Props = $props();
22
+
23
+ const startClip: Record<Direction, string> = {
24
+ left: 'inset(0 100% 0 0)',
25
+ right: 'inset(0 0 0 100%)',
26
+ top: 'inset(100% 0 0 0)',
27
+ bottom: 'inset(0 0 100% 0)',
28
+ };
29
+
30
+ const endClip = 'inset(0 0 0 0)';
31
+
32
+ let prefersReducedMotion = false;
33
+ let revealed = $state(false);
34
+ let el: HTMLDivElement | undefined = $state();
35
+
36
+ function trigger() {
37
+ revealed = true;
38
+ }
39
+
40
+ onMount(() => {
41
+ prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
42
+
43
+ if (prefersReducedMotion) {
44
+ revealed = true;
45
+ return;
46
+ }
47
+
48
+ if (triggerMode === 'mount') {
49
+ // Defer one frame so the initial clip-path is painted before transitioning
50
+ requestAnimationFrame(() => {
51
+ trigger();
52
+ });
53
+ } else {
54
+ const observer = new IntersectionObserver(
55
+ (entries) => {
56
+ for (const entry of entries) {
57
+ if (entry.intersectionRatio >= 0.5) {
58
+ trigger();
59
+ observer.disconnect();
60
+ }
61
+ }
62
+ },
63
+ { threshold: 0.5 }
64
+ );
65
+
66
+ if (el) {
67
+ observer.observe(el);
68
+ }
69
+
70
+ return () => observer.disconnect();
71
+ }
72
+ });
73
+ </script>
74
+
75
+ <div
76
+ bind:this={el}
77
+ class={className}
78
+ style:clip-path={prefersReducedMotion ? endClip : revealed ? endClip : startClip[direction]}
79
+ style:transition={prefersReducedMotion ? 'none' : `clip-path ${duration}ms var(--motion-glide)`}
80
+ >
81
+ {@render children()}
82
+ </div>