@stephen-netu/design-system 0.2.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/dist/b0-app-shell/clarification-overlay/ClarificationOverlay.svelte +10 -2
  2. package/dist/b0-app-shell/clarification-overlay/ClarificationOverlay.svelte.d.ts.map +1 -1
  3. package/dist/b0-app-shell/{command-bar/CommandBar.svelte → global-command-bar/GlobalCommandBar.svelte} +75 -75
  4. package/dist/b0-app-shell/{command-bar/CommandBar.svelte.d.ts → global-command-bar/GlobalCommandBar.svelte.d.ts} +6 -6
  5. package/dist/b0-app-shell/global-command-bar/GlobalCommandBar.svelte.d.ts.map +1 -0
  6. package/dist/b0-app-shell/index.d.ts +1 -1
  7. package/dist/b0-app-shell/index.d.ts.map +1 -1
  8. package/dist/b0-app-shell/index.js +1 -1
  9. package/dist/d0-data-viz/BarChart.test.js +53 -0
  10. package/dist/d0-data-viz/CheckpointBar.test.js +83 -0
  11. package/dist/d0-data-viz/CheckpointPill.svelte +8 -3
  12. package/dist/d0-data-viz/CheckpointPill.svelte.d.ts.map +1 -1
  13. package/dist/d0-data-viz/CheckpointPill.test.js +78 -0
  14. package/dist/d0-data-viz/ConnectionHealth.test.js +70 -0
  15. package/dist/d0-data-viz/MetricCard.test.js +57 -0
  16. package/dist/d0-data-viz/SparkLine.test.js +47 -0
  17. package/dist/d0-data-viz/StorageMap.test.js +63 -0
  18. package/dist/d0-data-viz/Timeline.test.js +62 -0
  19. package/dist/d0-data-viz/WorldLineTimeline.test.js +99 -0
  20. package/dist/d0-data-viz/checkpoint-types.js +1 -1
  21. package/dist/d0-data-viz/storage-map-types.d.ts.map +1 -1
  22. package/dist/d0-data-viz/storage-map-types.js +6 -3
  23. package/dist/d0-data-viz/theme-integration.d.ts +3 -3
  24. package/dist/d0-data-viz/theme-integration.js +4 -4
  25. package/dist/d0-data-viz/theme-integration.test.js +41 -0
  26. package/dist/demos/AmbientPrimitivesDemo.svelte +103 -0
  27. package/dist/demos/AmbientPrimitivesDemo.svelte.d.ts +5 -0
  28. package/dist/demos/AmbientPrimitivesDemo.svelte.d.ts.map +1 -0
  29. package/dist/demos/BspSizingInfographic.svelte +3 -32
  30. package/dist/demos/NodepadBlocksShowcase.svelte +2 -1
  31. package/dist/demos/NodepadBlocksShowcase.svelte.d.ts.map +1 -1
  32. package/dist/demos/index.d.ts +1 -0
  33. package/dist/demos/index.d.ts.map +1 -1
  34. package/dist/demos/index.js +1 -0
  35. package/dist/editor/CodeEditor.svelte +83 -26
  36. package/dist/editor/CodeEditor.svelte.d.ts +0 -1
  37. package/dist/editor/CodeEditor.svelte.d.ts.map +1 -1
  38. package/dist/editor/CodeEditor.test.js +38 -0
  39. package/dist/editor/ExternalChangeDialog.svelte +117 -0
  40. package/dist/editor/ExternalChangeDialog.svelte.d.ts +13 -0
  41. package/dist/editor/ExternalChangeDialog.svelte.d.ts.map +1 -0
  42. package/dist/editor/FindReplaceDialog.svelte +32 -32
  43. package/dist/editor/MarkdownEditor.svelte +105 -605
  44. package/dist/editor/MarkdownEditor.svelte.d.ts +1 -1
  45. package/dist/editor/MarkdownEditor.svelte.d.ts.map +1 -1
  46. package/dist/editor/MarkdownEditor.test.js +38 -0
  47. package/dist/editor/codemirror-config.d.ts +36 -0
  48. package/dist/editor/codemirror-config.d.ts.map +1 -0
  49. package/dist/editor/codemirror-config.js +87 -0
  50. package/dist/editor/components/CorrectionTooltip.svelte +180 -160
  51. package/dist/editor/components/CorrectionTooltip.svelte.d.ts +7 -23
  52. package/dist/editor/components/CorrectionTooltip.svelte.d.ts.map +1 -1
  53. package/dist/editor/extensions/autocomplete.d.ts +2 -2
  54. package/dist/editor/extensions/autocomplete.d.ts.map +1 -1
  55. package/dist/editor/extensions/autocomplete.test.js +121 -0
  56. package/dist/editor/extensions/spellcheck.d.ts +21 -3
  57. package/dist/editor/extensions/spellcheck.d.ts.map +1 -1
  58. package/dist/editor/extensions/spellcheck.js +51 -9
  59. package/dist/editor/extensions/spellcheck.test.js +168 -0
  60. package/dist/editor/extensions/types.d.ts +2 -1
  61. package/dist/editor/extensions/types.d.ts.map +1 -1
  62. package/dist/editor/index.d.ts +2 -1
  63. package/dist/editor/index.d.ts.map +1 -1
  64. package/dist/editor/index.js +1 -0
  65. package/dist/editor/markdown-preview.d.ts +9 -0
  66. package/dist/editor/markdown-preview.d.ts.map +1 -0
  67. package/dist/editor/markdown-preview.js +19 -0
  68. package/dist/editor/markdown-preview.test.js +38 -0
  69. package/dist/editor/useCodeMirror.d.ts +23 -0
  70. package/dist/editor/useCodeMirror.d.ts.map +1 -0
  71. package/dist/editor/useCodeMirror.js +40 -0
  72. package/dist/editor/useFilePersistence.d.ts +32 -0
  73. package/dist/editor/useFilePersistence.d.ts.map +1 -0
  74. package/dist/editor/useFilePersistence.js +117 -0
  75. package/dist/entity-graph-view/WorldView.svelte +1 -1
  76. package/dist/fabric/ai/ChatPanel.svelte +84 -85
  77. package/dist/fabric/ai/ChatPanel.svelte.d.ts.map +1 -1
  78. package/dist/fabric/ai/ResearchPanel.svelte +35 -25
  79. package/dist/fabric/ai/ResearchPanel.svelte.d.ts.map +1 -1
  80. package/dist/fabric/data/FileTree.svelte +195 -0
  81. package/dist/fabric/data/FileTree.svelte.d.ts +19 -0
  82. package/dist/fabric/data/FileTree.svelte.d.ts.map +1 -0
  83. package/dist/fabric/data/FileTree.test.js +127 -0
  84. package/dist/fabric/data/index.d.ts +5 -9
  85. package/dist/fabric/data/index.d.ts.map +1 -1
  86. package/dist/fabric/data/index.js +4 -1
  87. package/dist/fabric/index.d.ts +5 -5
  88. package/dist/fabric/index.d.ts.map +1 -1
  89. package/dist/fabric/index.js +5 -3
  90. package/dist/fabric/input/{CommandBar.svelte → AppHeaderBar.svelte} +13 -13
  91. package/dist/fabric/input/{CommandBar.svelte.d.ts → AppHeaderBar.svelte.d.ts} +5 -5
  92. package/dist/fabric/input/AppHeaderBar.svelte.d.ts.map +1 -0
  93. package/dist/fabric/input/{CommandBar.test.js → AppHeaderBar.test.js} +9 -9
  94. package/dist/fabric/input/KeyboardShortcuts.svelte +23 -21
  95. package/dist/fabric/input/index.d.ts +2 -2
  96. package/dist/fabric/input/index.d.ts.map +1 -1
  97. package/dist/fabric/input/index.js +1 -1
  98. package/dist/fabric/layout/CollapsiblePanel.svelte +8 -10
  99. package/dist/fabric/layout/KanbanBoard.svelte +25 -155
  100. package/dist/fabric/layout/KanbanBoard.svelte.d.ts +2 -26
  101. package/dist/fabric/layout/KanbanBoard.svelte.d.ts.map +1 -1
  102. package/dist/fabric/layout/KanbanBoard.test.js +125 -10
  103. package/dist/fabric/layout/KanbanCard.svelte +27 -223
  104. package/dist/fabric/layout/KanbanCard.svelte.d.ts +2 -19
  105. package/dist/fabric/layout/KanbanCard.svelte.d.ts.map +1 -1
  106. package/dist/fabric/layout/KanbanColumn.svelte +41 -275
  107. package/dist/fabric/layout/KanbanColumn.svelte.d.ts +2 -22
  108. package/dist/fabric/layout/KanbanColumn.svelte.d.ts.map +1 -1
  109. package/dist/fabric/layout/index.d.ts +2 -5
  110. package/dist/fabric/layout/index.d.ts.map +1 -1
  111. package/dist/fabric/layout/index.js +1 -1
  112. package/dist/fabric/navigation/ActivityRail.svelte +3 -5
  113. package/dist/fabric/navigation/ActivityRail.svelte.d.ts.map +1 -1
  114. package/dist/g0-generative/components/Text.svelte +38 -0
  115. package/dist/g0-generative/components/Text.svelte.d.ts +9 -0
  116. package/dist/g0-generative/components/Text.svelte.d.ts.map +1 -0
  117. package/dist/g0-generative/index.d.ts +1 -0
  118. package/dist/g0-generative/index.d.ts.map +1 -1
  119. package/dist/g0-generative/index.js +1 -0
  120. package/dist/g0-generative/library/ComponentLibrary.d.ts +4 -0
  121. package/dist/g0-generative/library/ComponentLibrary.d.ts.map +1 -1
  122. package/dist/g0-generative/library/ComponentLibrary.js +10 -0
  123. package/dist/g0-generative/library/ComponentLibrary.test.js +135 -0
  124. package/dist/g0-generative/renderer/OpenUIRenderer.svelte +16 -56
  125. package/dist/g0-generative/renderer/OpenUIRenderer.svelte.d.ts.map +1 -1
  126. package/dist/g0-generative/renderer/OpenUIRenderer.test.js +143 -0
  127. package/dist/g0-geo/SovereignMap.svelte +13 -13
  128. package/dist/g0-geo/SovereignMap.svelte.d.ts.map +1 -1
  129. package/dist/index.d.ts +0 -1
  130. package/dist/index.d.ts.map +1 -1
  131. package/dist/index.js +7 -3
  132. package/dist/l0-layout/SectionSplitter.svelte +5 -5
  133. package/dist/l0-layout/block-writer/BlockContent.svelte +23 -22
  134. package/dist/l0-layout/block-writer/BlockContent.svelte.d.ts.map +1 -1
  135. package/dist/l0-layout/block-writer/BlockContent.test.js +47 -0
  136. package/dist/l0-layout/block-writer/BlockItem.svelte +6 -4
  137. package/dist/l0-layout/block-writer/markdown.js +11 -11
  138. package/dist/l0-layout/block-writer/markdown.test.js +81 -0
  139. package/dist/l0-layout/card/CompactCard.svelte +4 -3
  140. package/dist/l0-layout/card/StackedCard.svelte +87 -0
  141. package/dist/l0-layout/card/StackedCard.svelte.d.ts +9 -0
  142. package/dist/l0-layout/card/StackedCard.svelte.d.ts.map +1 -0
  143. package/dist/l0-layout/card/StackedCard.test.js +29 -0
  144. package/dist/l0-layout/grant/GrantCard.svelte +15 -5
  145. package/dist/l0-layout/grant/GrantCard.svelte.d.ts.map +1 -1
  146. package/dist/l0-layout/index.d.ts +3 -0
  147. package/dist/l0-layout/index.d.ts.map +1 -1
  148. package/dist/l0-layout/index.js +2 -0
  149. package/dist/l0-layout/kanban/KanbanBoard.svelte +246 -29
  150. package/dist/l0-layout/kanban/KanbanBoard.svelte.d.ts +28 -2
  151. package/dist/l0-layout/kanban/KanbanBoard.svelte.d.ts.map +1 -1
  152. package/dist/l0-layout/kanban/KanbanCard.svelte +175 -150
  153. package/dist/l0-layout/kanban/KanbanCard.svelte.d.ts +16 -18
  154. package/dist/l0-layout/kanban/KanbanCard.svelte.d.ts.map +1 -1
  155. package/dist/l0-layout/kanban/KanbanColumn.svelte +152 -78
  156. package/dist/l0-layout/kanban/KanbanColumn.svelte.d.ts +28 -7
  157. package/dist/l0-layout/kanban/KanbanColumn.svelte.d.ts.map +1 -1
  158. package/dist/l0-layout/kanban/index.d.ts +6 -0
  159. package/dist/l0-layout/kanban/index.d.ts.map +1 -0
  160. package/dist/l0-layout/kanban/index.js +3 -0
  161. package/dist/n0-node-graph/Node.svelte +2 -2
  162. package/dist/n0-node-graph/NodePalette.svelte +2 -2
  163. package/dist/n1-flow-canvas/FlowCanvas.svelte +50 -6
  164. package/dist/n1-flow-canvas/FlowCanvas.svelte.d.ts.map +1 -1
  165. package/dist/n1-flow-canvas/graph-state.test.js +69 -0
  166. package/dist/n1-flow-canvas/index.d.ts +2 -0
  167. package/dist/n1-flow-canvas/index.d.ts.map +1 -1
  168. package/dist/n1-flow-canvas/index.js +1 -0
  169. package/dist/n1-flow-canvas/pipeline-adapter.d.ts +37 -0
  170. package/dist/n1-flow-canvas/pipeline-adapter.d.ts.map +1 -0
  171. package/dist/n1-flow-canvas/pipeline-adapter.js +160 -0
  172. package/dist/n1-flow-canvas/utils.test.js +116 -0
  173. package/dist/n2-manifold-disk/ManifoldDisk.svelte +62 -35
  174. package/dist/n2-manifold-disk/ManifoldDisk.svelte.d.ts.map +1 -1
  175. package/dist/n3-force-graph/GraphTooltip.svelte +2 -2
  176. package/dist/n4-adaptive-manifold/AdaptiveManifold.svelte +34 -29
  177. package/dist/n4-adaptive-manifold/AdaptiveManifold.svelte.d.ts.map +1 -1
  178. package/dist/n4-adaptive-manifold/classifier.test.js +104 -0
  179. package/dist/n4-adaptive-manifold/n4-tokens.css +2 -2
  180. package/dist/n4-adaptive-manifold/types.d.ts +3 -0
  181. package/dist/n4-adaptive-manifold/types.d.ts.map +1 -1
  182. package/dist/p0-primitives/ThemeProvider.svelte +38 -18
  183. package/dist/p0-primitives/ThemeProvider.svelte.d.ts +6 -1
  184. package/dist/p0-primitives/ThemeProvider.svelte.d.ts.map +1 -1
  185. package/dist/p0-primitives/canvas-theme.d.ts +33 -1
  186. package/dist/p0-primitives/canvas-theme.d.ts.map +1 -1
  187. package/dist/p0-primitives/canvas-theme.js +82 -17
  188. package/dist/p0-primitives/debug.d.ts +6 -0
  189. package/dist/p0-primitives/debug.d.ts.map +1 -0
  190. package/dist/p0-primitives/debug.js +21 -0
  191. package/dist/p0-primitives/index.d.ts +2 -1
  192. package/dist/p0-primitives/index.d.ts.map +1 -1
  193. package/dist/p0-primitives/index.js +1 -0
  194. package/dist/p0-primitives/theme-context.d.ts +9 -0
  195. package/dist/p0-primitives/theme-context.d.ts.map +1 -0
  196. package/dist/p0-primitives/theme-context.js +8 -0
  197. package/dist/p0-primitives/theme.d.ts.map +1 -1
  198. package/dist/p0-primitives/theme.js +11 -31
  199. package/dist/p0-primitives/tokens/ambient.css +76 -0
  200. package/dist/p0-primitives/tokens/tokens.css +140 -34
  201. package/dist/p0-primitives/utils/index.d.ts +4 -2
  202. package/dist/p0-primitives/utils/index.d.ts.map +1 -1
  203. package/dist/p0-primitives/utils/index.js +1 -0
  204. package/dist/p0-primitives/utils/reveal.d.ts +15 -0
  205. package/dist/p0-primitives/utils/reveal.d.ts.map +1 -0
  206. package/dist/p0-primitives/utils/reveal.js +29 -0
  207. package/dist/p0-primitives/utils/reveal.test.js +95 -0
  208. package/dist/s0-state/SyncStatus.svelte +2 -2
  209. package/dist/s0-state/ThemeStore.svelte.d.ts +3 -2
  210. package/dist/s0-state/ThemeStore.svelte.d.ts.map +1 -1
  211. package/dist/s0-state/ThemeStore.svelte.js +20 -1
  212. package/dist/s0-state/index.d.ts +2 -2
  213. package/dist/s0-state/index.d.ts.map +1 -1
  214. package/dist/s0-state/index.js +3 -0
  215. package/dist/s0-state/modal-stack-store.svelte.d.ts +27 -2
  216. package/dist/s0-state/modal-stack-store.svelte.d.ts.map +1 -1
  217. package/dist/s0-state/modal-stack-store.svelte.js +21 -2
  218. package/dist/showcase/Showcase.svelte +43 -34
  219. package/dist/showcase/Showcase.svelte.d.ts.map +1 -1
  220. package/dist/spatial/BspTilingCanvas.svelte +5 -5
  221. package/dist/spatial/BspTilingSimulation.test.js +88 -0
  222. package/dist/spatial/CameraController.test.js +120 -0
  223. package/dist/spatial/ForceCanvas.svelte +18 -13
  224. package/dist/spatial/ForceCanvas.svelte.d.ts.map +1 -1
  225. package/dist/spatial/ForceSimulation.svelte.d.ts.map +1 -1
  226. package/dist/spatial/ForceSimulation.svelte.js +33 -22
  227. package/dist/spatial/LodRenderer.svelte +14 -1
  228. package/dist/spatial/LodRenderer.svelte.d.ts.map +1 -1
  229. package/dist/spatial/ParticleAssembleMark.svelte +285 -0
  230. package/dist/spatial/ParticleAssembleMark.svelte.d.ts +24 -0
  231. package/dist/spatial/ParticleAssembleMark.svelte.d.ts.map +1 -0
  232. package/dist/spatial/SnapZoomCamera.svelte +23 -13
  233. package/dist/spatial/SnapZoomCamera.svelte.d.ts.map +1 -1
  234. package/dist/spatial/ZoneTiler.svelte +3 -2
  235. package/dist/spatial/ZoneTiler.test.js +90 -0
  236. package/dist/spatial/d3-types.d.ts +31 -0
  237. package/dist/spatial/d3-types.d.ts.map +1 -0
  238. package/dist/spatial/d3-types.js +19 -0
  239. package/dist/spatial/index.js +1 -0
  240. package/dist/spatial/particle-assemble-math.d.ts +22 -0
  241. package/dist/spatial/particle-assemble-math.d.ts.map +1 -0
  242. package/dist/spatial/particle-assemble-math.js +26 -0
  243. package/dist/spatial/particle-assemble-math.test.js +56 -0
  244. package/dist/ssr-import-clean.test.js +37 -0
  245. package/dist/t0-transport/fs.d.ts +12 -0
  246. package/dist/t0-transport/fs.d.ts.map +1 -0
  247. package/dist/t0-transport/fs.js +55 -0
  248. package/dist/t0-transport/index.d.ts +1 -0
  249. package/dist/t0-transport/index.d.ts.map +1 -1
  250. package/dist/t0-transport/index.js +1 -0
  251. package/dist/t0-transport/invoke.d.ts.map +1 -1
  252. package/dist/t0-transport/invoke.js +5 -2
  253. package/dist/t0-transport/quality.d.ts +12 -3
  254. package/dist/t0-transport/quality.d.ts.map +1 -1
  255. package/dist/t0-transport/quality.js +17 -4
  256. package/dist/t0-transport/substrate.svelte.d.ts +27 -0
  257. package/dist/t0-transport/substrate.svelte.d.ts.map +1 -0
  258. package/dist/t0-transport/substrate.svelte.js +55 -0
  259. package/dist/u0-primitives/LockIndicator.svelte +17 -15
  260. package/dist/u0-primitives/VerticalToolbar.svelte +25 -22
  261. package/dist/u0-primitives/accordion/Accordion.svelte +14 -12
  262. package/dist/u0-primitives/accordion/Accordion.svelte.d.ts +0 -7
  263. package/dist/u0-primitives/accordion/Accordion.svelte.d.ts.map +1 -1
  264. package/dist/u0-primitives/accordion/Accordion.test.js +5 -5
  265. package/dist/u0-primitives/animated-icon/AnimatedIcon.svelte +3 -3
  266. package/dist/u0-primitives/animated-icon/AnimatedIcon.test.js +82 -0
  267. package/dist/u0-primitives/avatar/Avatar.svelte +14 -14
  268. package/dist/u0-primitives/avatar/Avatar.test.js +81 -0
  269. package/dist/u0-primitives/badge/Badge.svelte +6 -4
  270. package/dist/u0-primitives/badge/Badge.test.js +10 -10
  271. package/dist/u0-primitives/badge/ValidityBadge.svelte +4 -27
  272. package/dist/u0-primitives/badge/ValidityBadge.test.js +9 -9
  273. package/dist/u0-primitives/button/Button.svelte +18 -13
  274. package/dist/u0-primitives/button/Button.svelte.d.ts +1 -0
  275. package/dist/u0-primitives/button/Button.svelte.d.ts.map +1 -1
  276. package/dist/u0-primitives/button/Button.test.js +11 -11
  277. package/dist/u0-primitives/card/Card.svelte +60 -32
  278. package/dist/u0-primitives/card/Card.svelte.d.ts.map +1 -1
  279. package/dist/u0-primitives/card/Card.test.js +86 -0
  280. package/dist/u0-primitives/command-palette/CommandPalette.svelte +75 -43
  281. package/dist/u0-primitives/command-palette/CommandPalette.svelte.d.ts.map +1 -1
  282. package/dist/u0-primitives/command-palette/CommandPalette.test.js +202 -0
  283. package/dist/u0-primitives/command-palette/commandStore.svelte.d.ts.map +1 -1
  284. package/dist/u0-primitives/command-palette/commandStore.svelte.js +2 -1
  285. package/dist/u0-primitives/dropdown/Dropdown.svelte +20 -25
  286. package/dist/u0-primitives/dropdown/Dropdown.test.js +1 -1
  287. package/dist/u0-primitives/grant-badge/GrantStatusBadge.svelte +2 -2
  288. package/dist/u0-primitives/index.d.ts +8 -0
  289. package/dist/u0-primitives/index.d.ts.map +1 -1
  290. package/dist/u0-primitives/index.js +9 -0
  291. package/dist/u0-primitives/input/Input.svelte +85 -23
  292. package/dist/u0-primitives/input/Input.svelte.d.ts +2 -10
  293. package/dist/u0-primitives/input/Input.svelte.d.ts.map +1 -1
  294. package/dist/u0-primitives/input/Input.test.js +82 -2
  295. package/dist/u0-primitives/live-dot/LiveDot.svelte +56 -0
  296. package/dist/u0-primitives/live-dot/LiveDot.svelte.d.ts +11 -0
  297. package/dist/u0-primitives/live-dot/LiveDot.svelte.d.ts.map +1 -0
  298. package/dist/u0-primitives/live-dot/LiveDot.test.js +41 -0
  299. package/dist/u0-primitives/live-dot/index.d.ts +3 -0
  300. package/dist/u0-primitives/live-dot/index.d.ts.map +1 -0
  301. package/dist/u0-primitives/live-dot/index.js +1 -0
  302. package/dist/u0-primitives/modal/Modal.svelte +64 -38
  303. package/dist/u0-primitives/modal/Modal.svelte.d.ts.map +1 -1
  304. package/dist/u0-primitives/modal/Modal.test.js +63 -15
  305. package/dist/u0-primitives/rsvp/RsvpReader.svelte +8 -8
  306. package/dist/u0-primitives/rsvp/RsvpReader.svelte.d.ts.map +1 -1
  307. package/dist/u0-primitives/spinner/Spinner.svelte +11 -79
  308. package/dist/u0-primitives/spinner/Spinner.svelte.d.ts.map +1 -1
  309. package/dist/u0-primitives/steps/Steps.svelte +20 -21
  310. package/dist/u0-primitives/surface-state/SurfaceState.svelte +190 -0
  311. package/dist/u0-primitives/surface-state/SurfaceState.svelte.d.ts +15 -0
  312. package/dist/u0-primitives/surface-state/SurfaceState.svelte.d.ts.map +1 -0
  313. package/dist/u0-primitives/tabs/Tabs.svelte +13 -11
  314. package/dist/u0-primitives/theme-swatch-group/ThemeSwatchGroup.svelte +94 -0
  315. package/dist/u0-primitives/theme-swatch-group/ThemeSwatchGroup.svelte.d.ts +16 -0
  316. package/dist/u0-primitives/theme-swatch-group/ThemeSwatchGroup.svelte.d.ts.map +1 -0
  317. package/dist/u0-primitives/theme-swatch-group/ThemeSwatchGroup.test.js +48 -0
  318. package/dist/u0-primitives/theme-swatch-group/index.d.ts +3 -0
  319. package/dist/u0-primitives/theme-swatch-group/index.d.ts.map +1 -0
  320. package/dist/u0-primitives/theme-swatch-group/index.js +1 -0
  321. package/dist/u0-primitives/toggle/Toggle.svelte +22 -13
  322. package/dist/u0-primitives/tooltip/Tooltip.svelte +9 -9
  323. package/dist/u0-primitives/tooltip/Tooltip.test.js +12 -12
  324. package/dist/u0-primitives/web-components/button-component.d.ts +5 -1
  325. package/dist/u0-primitives/web-components/button-component.d.ts.map +1 -1
  326. package/dist/u0-primitives/web-components/button-component.js +72 -33
  327. package/dist/u0-primitives/web-components/index.d.ts +3 -0
  328. package/dist/u0-primitives/web-components/index.d.ts.map +1 -0
  329. package/dist/u0-primitives/web-components/index.js +2 -0
  330. package/dist/u0-primitives/web-components/input-component.d.ts +5 -1
  331. package/dist/u0-primitives/web-components/input-component.d.ts.map +1 -1
  332. package/dist/u0-primitives/web-components/input-component.js +56 -39
  333. package/dist/u0-primitives/web-components/web-components.test.js +96 -0
  334. package/dist/u0-primitives/window-frame/WindowFrame.svelte +87 -0
  335. package/dist/u0-primitives/window-frame/WindowFrame.svelte.d.ts +10 -0
  336. package/dist/u0-primitives/window-frame/WindowFrame.svelte.d.ts.map +1 -0
  337. package/dist/u0-primitives/window-frame/WindowFrame.test.js +31 -0
  338. package/dist/u0-primitives/window-frame/index.d.ts +3 -0
  339. package/dist/u0-primitives/window-frame/index.d.ts.map +1 -0
  340. package/dist/u0-primitives/window-frame/index.js +1 -0
  341. package/dist/v0-diagrams/MarkmapDiagram.test.js +49 -0
  342. package/dist/v0-diagrams/MermaidDiagram.svelte +21 -9
  343. package/dist/v0-diagrams/MermaidDiagram.svelte.d.ts.map +1 -1
  344. package/dist/v0-diagrams/MermaidDiagram.test.js +40 -0
  345. package/dist/x0-enchanted-blocks/components/NodepadBlock.svelte +11 -2
  346. package/dist/x0-enchanted-blocks/components/NodepadBlock.svelte.d.ts.map +1 -1
  347. package/package.json +57 -15
  348. package/src/n4-adaptive-manifold/n4-tokens.css +2 -2
  349. package/src/p0-primitives/tokens/ambient.css +76 -0
  350. package/src/p0-primitives/tokens/tokens.css +140 -34
  351. package/src/p0-primitives/tokens/tokens.json +55 -26
  352. package/dist/b0-app-shell/command-bar/CommandBar.svelte.d.ts.map +0 -1
  353. package/dist/fabric/input/CommandBar.svelte.d.ts.map +0 -1
  354. package/dist/stores/vaultStore.svelte +0 -14
  355. package/dist/stores/vaultStore.svelte.d.ts +0 -24
  356. package/dist/stores/vaultStore.svelte.d.ts.map +0 -1
  357. package/dist/tauri/index.d.ts +0 -3
  358. package/dist/tauri/index.d.ts.map +0 -1
  359. package/dist/tauri/index.js +0 -11
@@ -1 +1 @@
1
- {"version":3,"file":"ForceCanvas.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/ForceCanvas.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAOxF,UAAU,KAAK;IACb,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IACxD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAyIvC,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ForceCanvas.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/ForceCanvas.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAOxF,UAAU,KAAK;IACb,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IACxD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC;AA8IvC,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ForceSimulation.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/ForceSimulation.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAC5F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAKvF,qBAAa,eAAgB,YAAW,SAAS;IAE/C,SAAS,EAAE,YAAY,EAAE,CAAc;IAEvC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;gBAEX,KAAK,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,EAAE,iBAAiB;IAO1D,SAAS,CAAC,IAAI,EAAE,iBAAiB,GAAG,eAAe;IAWnD,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAQhC,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;YAYlB,cAAc;IAuD5B,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,SAAS;IAiBjB,IAAI,IAAI,IAAI;CACb"}
1
+ {"version":3,"file":"ForceSimulation.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/ForceSimulation.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAC5F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,iBAAiB,EAAa,MAAM,sBAAsB,CAAC;AAOlG,qBAAa,eAAgB,YAAW,SAAS;IAE/C,SAAS,EAAE,YAAY,EAAE,CAAc;IAEvC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,UAAU,CAAK;gBAEX,KAAK,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,EAAE,iBAAiB;IAO1D,SAAS,CAAC,IAAI,EAAE,iBAAiB,GAAG,eAAe;IAWnD,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;IAQhC,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI;YAYlB,cAAc;IAkE5B,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,SAAS;IAiBjB,IAAI,IAAI,IAAI;CACb"}
@@ -4,6 +4,7 @@
4
4
  //
5
5
  // S-02: No Math.random — initial positions seeded by node index.
6
6
  // S-05: alphaDecay bounds simulation convergence; RAF cancelled on destroy.
7
+ import { toD3Node, toD3Link } from './d3-types';
7
8
  import { weightToRadius, cosineSimilarity, semanticSpringLength } from './force-canvas-types';
8
9
  const MIN_ZONE_PAD = 40;
9
10
  export class ForceSimulation {
@@ -40,7 +41,7 @@ export class ForceSimulation {
40
41
  render(ctx) {
41
42
  for (const pos of this.positions) {
42
43
  const r = pos.radius;
43
- ctx.drawRect({ x: pos.x - r, y: pos.y - r, width: r * 2, height: r * 2 }, '#b87333');
44
+ ctx.drawRect({ x: pos.x - r, y: pos.y - r, width: r * 2, height: r * 2 }, 'var(--color-accent, #888)');
44
45
  }
45
46
  }
46
47
  // ── Internal ─────────────────────────────────────────────────────────────
@@ -51,9 +52,9 @@ export class ForceSimulation {
51
52
  this.positions = [];
52
53
  return;
53
54
  }
54
- const d3 = await import('d3-force');
55
+ const d3Mod = await import('d3-force');
55
56
  if (gen !== this.generation)
56
- return; // superseded by a newer layout call
57
+ return;
57
58
  const cfg = this.config;
58
59
  const w = this.boundsWidth;
59
60
  const h = this.boundsHeight;
@@ -66,33 +67,43 @@ export class ForceSimulation {
66
67
  const velocityDecay = cfg?.velocityDecay ?? 0.4;
67
68
  const cx = w / 2;
68
69
  const cy = h / 2;
69
- for (const cell of this.cells) {
70
+ const nodes = this.cells.map((cell, i) => {
70
71
  if (cell.x === undefined) {
71
- // Deterministic initial placement: spiral by index
72
- cell.x = cx + (cell.index ?? 0) * 3;
73
- cell.y = cy + (cell.index ?? 0) * 2;
72
+ cell.x = cx + (cell.index ?? i) * 3;
73
+ cell.y = cy + (cell.index ?? i) * 2;
74
74
  }
75
- }
76
- const links = this.buildLinks();
77
- this.simulation = d3
78
- .forceSimulation(this.cells)
75
+ return toD3Node(cell);
76
+ });
77
+ const links = this.buildLinks().map(toD3Link);
78
+ const sim = d3Mod.forceSimulation(nodes)
79
79
  .alphaDecay(0.02)
80
80
  .velocityDecay(velocityDecay)
81
- .force('charge', d3.forceManyBody().strength(chargeStrength))
82
- .force('collision', d3.forceCollide().radius((d) => weightToRadius(d.weight) + collisionPadding))
83
- .force('link', d3.forceLink(links).id((d) => d.id)
84
- .distance((l) => semanticSpringLength(1 - l.distance, minSpring, maxSpring))
81
+ .force('charge', d3Mod.forceManyBody().strength(chargeStrength))
82
+ .force('collision', d3Mod.forceCollide().radius((d) => {
83
+ const cell = this.cells.find((c) => c.id === d.id);
84
+ return cell ? weightToRadius(cell.weight) + collisionPadding : collisionPadding + 8;
85
+ }))
86
+ .force('link', d3Mod.forceLink(links).id((d) => d.id)
87
+ .distance((l) => semanticSpringLength(1 - (l.distance ?? 0.5), minSpring, maxSpring))
85
88
  .strength(0.5))
86
- .force('center', d3.forceCenter(cx, cy).strength(0.03))
89
+ .force('center', d3Mod.forceCenter(cx, cy).strength(0.03))
87
90
  .force('wall', this.wallForce(w, h, wallMargin, wallStrength))
88
91
  .on('tick', () => {
89
- this.positions = this.cells.map((c) => ({
90
- x: c.x ?? cx,
91
- y: c.y ?? cy,
92
- radius: weightToRadius(c.weight),
93
- cell: c,
94
- }));
92
+ this.positions = nodes.map((n) => {
93
+ const cell = this.cells.find((c) => c.id === n.id);
94
+ return {
95
+ x: n.x ?? cx,
96
+ y: n.y ?? cy,
97
+ radius: weightToRadius(cell.weight),
98
+ cell,
99
+ };
100
+ });
95
101
  });
102
+ if (gen !== this.generation) {
103
+ sim.stop();
104
+ return;
105
+ }
106
+ this.simulation = sim;
96
107
  }
97
108
  buildLinks() {
98
109
  const links = [];
@@ -209,12 +209,25 @@
209
209
  {@const state = getLodState(pos.cell.id)}
210
210
  {@const isTransitioning = state?.transitionProgress !== null && state?.transitionProgress !== undefined}
211
211
 
212
+ {@const cellAttrs = onCellClick ? {
213
+ role: 'button',
214
+ tabindex: 0,
215
+ 'aria-label': 'Open cell at current level of detail',
216
+ onclick: () => onCellClick?.(pos.cell.id, currentLod),
217
+ onkeydown: (e: KeyboardEvent) => {
218
+ if (e.key === 'Enter' || e.key === ' ') {
219
+ e.preventDefault();
220
+ onCellClick?.(pos.cell.id, currentLod);
221
+ }
222
+ }
223
+ } : {}}
224
+
212
225
  <!-- svelte-ignore a11y_no_static_element_interactions -->
213
226
  <div
214
227
  class="lod-cell"
215
228
  style:left="{pos.x - pos.radius}px"
216
229
  style:top="{pos.y - pos.radius}px"
217
- onclick={() => onCellClick?.(pos.cell.id, currentLod)}
230
+ {...cellAttrs}
218
231
  data-lod={currentLod}
219
232
  data-cell-id={pos.cell.id}
220
233
  >
@@ -1 +1 @@
1
- {"version":3,"file":"LodRenderer.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/LodRenderer.svelte.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAgB,MAAM,gBAAgB,CAAC;AAQ9E,UAAU,KAAK;IACb,sCAAsC;IACtC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAI3B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C;8DAC0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAE7C,sDAAsD;IACtD,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CACzD;AAED,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAsNvC,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"LodRenderer.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/LodRenderer.svelte.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAgB,MAAM,gBAAgB,CAAC;AAQ9E,UAAU,KAAK;IACb,sCAAsC;IACtC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAI3B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C;8DAC0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAE7C,sDAAsD;IACtD,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CACzD;AAED,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAmOvC,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -0,0 +1,285 @@
1
+ <script lang="ts">
2
+ // ParticleAssembleMark — animates a canvas particle field converging into
3
+ // an arbitrary set of SVG-authored polygons (a logomark, glyph, or any
4
+ // flat-fill shape). Generalizes the "form the mark from particles" hero
5
+ // moment pattern.
6
+ //
7
+ // NOTE: Heavy stateful component (canvas + RAF loop). Use {#if} to fully
8
+ // mount/unmount — visibility:hidden would keep the rAF loop running.
9
+ //
10
+ // S-05: the assembly RAF loop is bounded — it terminates once particles
11
+ // settle and switches to a single static draw; it does not run forever.
12
+ // Per-particle start edge/position/delay are cosmetically randomized for
13
+ // visual variety only (no business logic depends on this), so
14
+ // Math.random() here does not carry the S-02 determinism concern that
15
+ // applies to kernel/backend computation.
16
+
17
+ import { onMount, onDestroy } from 'svelte';
18
+ import { fitScale, easeOutCubic, particleFrame } from './particle-assemble-math.js';
19
+
20
+ export interface ParticleShape {
21
+ /** Polygon points in the coordinate space of viewBoxWidth/viewBoxHeight. */
22
+ points: [number, number][];
23
+ /** 'primary' (gradient fill) or 'secondary' (solid accent fill). Defaults to 'primary'. */
24
+ tone?: 'primary' | 'secondary';
25
+ }
26
+
27
+ export interface Props {
28
+ shapes: ParticleShape[];
29
+ viewBoxWidth: number;
30
+ viewBoxHeight: number;
31
+ width?: number;
32
+ height?: number;
33
+ primaryColor?: string;
34
+ primaryColor2?: string;
35
+ secondaryColor?: string;
36
+ durationMs?: number;
37
+ active?: boolean;
38
+ class?: string;
39
+ 'aria-label'?: string;
40
+ }
41
+
42
+ let {
43
+ shapes,
44
+ viewBoxWidth,
45
+ viewBoxHeight,
46
+ width = 200,
47
+ height = 200,
48
+ primaryColor = 'currentColor',
49
+ primaryColor2,
50
+ secondaryColor = 'currentColor',
51
+ durationMs = 900,
52
+ active = true,
53
+ class: className = '',
54
+ 'aria-label': ariaLabel
55
+ }: Props = $props();
56
+
57
+ interface Particle {
58
+ x: number;
59
+ y: number;
60
+ tx: number;
61
+ ty: number;
62
+ color: string;
63
+ r: number;
64
+ delay: number;
65
+ }
66
+
67
+ let canvas: HTMLCanvasElement | undefined = $state();
68
+ let settled = $state(false);
69
+ let rafId: number | null = null;
70
+ let particles: Particle[] = [];
71
+ let observer: IntersectionObserver | null = null;
72
+ let lastDx = 0;
73
+ let lastDy = 0;
74
+ let lastScale = 1;
75
+ const dpr = typeof window !== 'undefined' ? Math.min(window.devicePixelRatio || 1, 3) : 1;
76
+
77
+ // Canvas fillStyle cannot parse CSS custom properties or `currentColor` —
78
+ // it isn't part of the CSSOM cascade. Resolve those to a concrete color
79
+ // via the canvas element's computed style before handing them to canvas.
80
+ function resolveColor(value: string): string {
81
+ if (!canvas) return value;
82
+ const trimmed = value.trim();
83
+ const varMatch = trimmed.match(/^var\((--[\w-]+)(?:\s*,\s*(.+))?\)$/);
84
+ if (varMatch) {
85
+ const resolved = getComputedStyle(canvas).getPropertyValue(varMatch[1]).trim();
86
+ return resolved || varMatch[2] || trimmed;
87
+ }
88
+ if (trimmed === 'currentColor') {
89
+ return getComputedStyle(canvas).color;
90
+ }
91
+ return trimmed;
92
+ }
93
+
94
+ function drawShapes(
95
+ ctx: CanvasRenderingContext2D,
96
+ dx: number,
97
+ dy: number,
98
+ scale: number
99
+ ) {
100
+ const resolvedPrimary = resolveColor(primaryColor);
101
+ const resolvedPrimary2 = resolveColor(primaryColor2 || primaryColor);
102
+ const resolvedSecondary = resolveColor(secondaryColor);
103
+
104
+ const gradient = ctx.createLinearGradient(dx, dy, dx + viewBoxWidth * scale, dy + viewBoxHeight * scale);
105
+ gradient.addColorStop(0, resolvedPrimary);
106
+ gradient.addColorStop(1, resolvedPrimary2);
107
+
108
+ for (const shape of shapes) {
109
+ ctx.fillStyle = shape.tone === 'secondary' ? resolvedSecondary : gradient;
110
+ ctx.beginPath();
111
+ shape.points.forEach(([px, py], i) => {
112
+ const x = dx + px * scale;
113
+ const y = dy + py * scale;
114
+ if (i === 0) ctx.moveTo(x, y);
115
+ else ctx.lineTo(x, y);
116
+ });
117
+ ctx.closePath();
118
+ ctx.fill();
119
+ }
120
+ }
121
+
122
+ function buildTargets(): { x: number; y: number; r: number; g: number; b: number }[] {
123
+ if (!canvas) return [];
124
+ const cssW = canvas.clientWidth || width;
125
+ const cssH = canvas.clientHeight || height;
126
+ canvas.width = cssW * dpr;
127
+ canvas.height = cssH * dpr;
128
+
129
+ const off = document.createElement('canvas');
130
+ off.width = canvas.width;
131
+ off.height = canvas.height;
132
+ const offCtx = off.getContext('2d');
133
+ if (!offCtx) return [];
134
+
135
+ const { scale, dx, dy } = fitScale(viewBoxWidth, viewBoxHeight, canvas.width, canvas.height);
136
+
137
+ drawShapes(offCtx, dx, dy, scale);
138
+ lastDx = dx;
139
+ lastDy = dy;
140
+ lastScale = scale;
141
+
142
+ const data = offCtx.getImageData(0, 0, off.width, off.height).data;
143
+ const step = Math.max(1, Math.floor(dpr * 1.15));
144
+ const pts: { x: number; y: number; r: number; g: number; b: number }[] = [];
145
+ for (let y = 0; y < off.height; y += step) {
146
+ for (let x = 0; x < off.width; x += step) {
147
+ const idx = (y * off.width + x) * 4;
148
+ const alpha = data[idx + 3];
149
+ if (alpha > 100) {
150
+ pts.push({ x, y, r: data[idx], g: data[idx + 1], b: data[idx + 2] });
151
+ }
152
+ }
153
+ }
154
+ return pts;
155
+ }
156
+
157
+ function initParticles() {
158
+ const pts = buildTargets();
159
+ if (!canvas) return;
160
+ const cw = canvas.width;
161
+ const ch = canvas.height;
162
+ particles = pts.map((p) => {
163
+ const edge = Math.floor(Math.random() * 4);
164
+ let sx: number;
165
+ let sy: number;
166
+ if (edge === 0) { sx = -40; sy = Math.random() * ch; }
167
+ else if (edge === 1) { sx = cw + 40; sy = Math.random() * ch; }
168
+ else if (edge === 2) { sx = Math.random() * cw; sy = -40; }
169
+ else { sx = Math.random() * cw; sy = ch + 40; }
170
+ return {
171
+ x: sx,
172
+ y: sy,
173
+ tx: p.x,
174
+ ty: p.y,
175
+ color: `rgb(${p.r},${p.g},${p.b})`,
176
+ r: (Math.random() * 1.0 + 1.3) * dpr,
177
+ delay: Math.random() * 300
178
+ };
179
+ });
180
+ }
181
+
182
+ function renderFinalMark() {
183
+ const ctx = canvas?.getContext('2d');
184
+ if (!ctx || !canvas) return;
185
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
186
+ drawShapes(ctx, lastDx, lastDy, lastScale);
187
+ }
188
+
189
+ function animate(now: number, startTime: number) {
190
+ const ctx = canvas?.getContext('2d');
191
+ if (!ctx || !canvas) return;
192
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
193
+ let allDone = true;
194
+ for (const p of particles) {
195
+ const t = now - startTime - p.delay;
196
+ if (t < 0) { allDone = false; continue; }
197
+ const progress = t / durationMs;
198
+ const eased = easeOutCubic(progress);
199
+ if (progress < 1) allDone = false;
200
+ const frame = particleFrame(p, eased);
201
+ ctx.globalAlpha = frame.alpha;
202
+ ctx.fillStyle = p.color;
203
+ ctx.beginPath();
204
+ ctx.arc(frame.x, frame.y, p.r, 0, Math.PI * 2);
205
+ ctx.fill();
206
+ }
207
+ ctx.globalAlpha = 1;
208
+ if (!allDone) {
209
+ rafId = requestAnimationFrame((n) => animate(n, startTime));
210
+ } else {
211
+ renderFinalMark();
212
+ settled = true;
213
+ rafId = null;
214
+ }
215
+ }
216
+
217
+ function start() {
218
+ if (!canvas) return;
219
+ const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
220
+ initParticles();
221
+ if (reduceMotion) {
222
+ renderFinalMark();
223
+ settled = true;
224
+ return;
225
+ }
226
+ settled = false;
227
+ const now = performance.now();
228
+ rafId = requestAnimationFrame((n) => animate(n, n));
229
+ }
230
+
231
+ function replay() {
232
+ if (rafId !== null) cancelAnimationFrame(rafId);
233
+ rafId = null;
234
+ start();
235
+ }
236
+
237
+ // Re-run assembly when colors change (e.g. an accent-seed picker swap),
238
+ // mirroring the settled-mark retheme behavior — only after first settle,
239
+ // so this never fires during the initial mount's own assembly.
240
+ $effect(() => {
241
+ primaryColor; primaryColor2; secondaryColor;
242
+ if (settled) replay();
243
+ });
244
+
245
+ onMount(() => {
246
+ if (!active || !canvas) return;
247
+ if ('IntersectionObserver' in window) {
248
+ observer = new IntersectionObserver(
249
+ (entries) => {
250
+ for (const entry of entries) {
251
+ if (entry.isIntersecting) {
252
+ start();
253
+ observer?.disconnect();
254
+ }
255
+ }
256
+ },
257
+ { threshold: 0.3 }
258
+ );
259
+ observer.observe(canvas);
260
+ } else {
261
+ start();
262
+ }
263
+ });
264
+
265
+ onDestroy(() => {
266
+ if (rafId !== null) cancelAnimationFrame(rafId);
267
+ observer?.disconnect();
268
+ });
269
+ </script>
270
+
271
+ <canvas
272
+ bind:this={canvas}
273
+ class="ds-particle-assemble-mark {className}"
274
+ style:width="{width}px"
275
+ style:height="{height}px"
276
+ aria-hidden={ariaLabel ? undefined : 'true'}
277
+ aria-label={ariaLabel}
278
+ role={ariaLabel ? 'img' : undefined}
279
+ ></canvas>
280
+
281
+ <style>
282
+ .ds-particle-assemble-mark {
283
+ display: block;
284
+ }
285
+ </style>
@@ -0,0 +1,24 @@
1
+ export interface ParticleShape {
2
+ /** Polygon points in the coordinate space of viewBoxWidth/viewBoxHeight. */
3
+ points: [number, number][];
4
+ /** 'primary' (gradient fill) or 'secondary' (solid accent fill). Defaults to 'primary'. */
5
+ tone?: 'primary' | 'secondary';
6
+ }
7
+ export interface Props {
8
+ shapes: ParticleShape[];
9
+ viewBoxWidth: number;
10
+ viewBoxHeight: number;
11
+ width?: number;
12
+ height?: number;
13
+ primaryColor?: string;
14
+ primaryColor2?: string;
15
+ secondaryColor?: string;
16
+ durationMs?: number;
17
+ active?: boolean;
18
+ class?: string;
19
+ 'aria-label'?: string;
20
+ }
21
+ declare const ParticleAssembleMark: import("svelte").Component<Props, {}, "">;
22
+ type ParticleAssembleMark = ReturnType<typeof ParticleAssembleMark>;
23
+ export default ParticleAssembleMark;
24
+ //# sourceMappingURL=ParticleAssembleMark.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParticleAssembleMark.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/ParticleAssembleMark.svelte.ts"],"names":[],"mappings":"AAqBE,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC3B,2FAA2F;IAC3F,IAAI,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;CAChC;AAED,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAkQH,QAAA,MAAM,oBAAoB,2CAAwC,CAAC;AACnE,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACpE,eAAe,oBAAoB,CAAC"}
@@ -4,7 +4,7 @@
4
4
  // Renders via CSS transforms on a wrapper div
5
5
 
6
6
  import type { Snippet } from 'svelte';
7
- import { onMount, onDestroy } from 'svelte';
7
+ import { onMount, onDestroy, untrack } from 'svelte';
8
8
  import { CameraController } from './CameraController.svelte.js';
9
9
  import type { CameraState, SnapZoomTarget, CameraConfig } from './camera-types.js';
10
10
  import type { InteractionContext } from '../s0-lifecycle/InteractionContext.js';
@@ -27,8 +27,21 @@
27
27
  onCameraChange,
28
28
  }: Props = $props();
29
29
 
30
- const controller = $state(new CameraController(width, height, config));
31
- const cameraState: CameraState = $derived(controller.getCameraState());
30
+ let controller = $state<CameraController | null>(null);
31
+ const cameraState: CameraState = $derived(controller?.getCameraState() ?? { zoom: 1, panX: 0, panY: 0 });
32
+ const panX = $derived(controller?.panX ?? 0);
33
+ const panY = $derived(controller?.panY ?? 0);
34
+ const zoom = $derived(controller?.zoom ?? 1);
35
+
36
+ $effect(() => {
37
+ void width;
38
+ void height;
39
+ void config;
40
+ untrack(() => {
41
+ controller = new CameraController(width, height, config);
42
+ runPhases();
43
+ });
44
+ });
32
45
 
33
46
  $effect(() => {
34
47
  onCameraChange?.(cameraState);
@@ -37,6 +50,7 @@
37
50
  // ── Contexts for lifecycle phases ─────────────────────────────────────────
38
51
 
39
52
  function runPhases(): void {
53
+ if (!controller) return;
40
54
  controller.constrain({
41
55
  available: {
42
56
  width: { min: width, preferred: width, max: width },
@@ -61,17 +75,13 @@
61
75
  });
62
76
  }
63
77
 
64
- onMount(() => {
65
- runPhases();
66
- });
67
-
68
78
  // ── Interaction forwarding ────────────────────────────────────────────────
69
79
 
70
80
  let wheelRafId: number | null = null;
71
81
  let pendingWheelEvent: WheelEvent | null = null;
72
82
 
73
83
  onDestroy(() => {
74
- controller.stop();
84
+ controller?.stop();
75
85
  if (wheelRafId !== null) cancelAnimationFrame(wheelRafId);
76
86
  });
77
87
 
@@ -120,14 +130,14 @@
120
130
  pendingWheelEvent = null;
121
131
  if (evt) {
122
132
  const ctx = makeInteractionContext(evt);
123
- controller.interact(ctx);
133
+ controller?.interact(ctx);
124
134
  }
125
135
  });
126
136
  }
127
137
 
128
138
  function handlePointerDown(e: PointerEvent) {
129
139
  const ctx = makeInteractionContext(e);
130
- const outcome = controller.interact(ctx);
140
+ const outcome = controller?.interact(ctx);
131
141
  if (outcome === 'consumed') {
132
142
  (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
133
143
  }
@@ -135,12 +145,12 @@
135
145
 
136
146
  function handlePointerMove(e: PointerEvent) {
137
147
  const ctx = makeInteractionContext(e);
138
- controller.interact(ctx);
148
+ controller?.interact(ctx);
139
149
  }
140
150
 
141
151
  function handlePointerUp(e: PointerEvent) {
142
152
  const ctx = makeInteractionContext(e);
143
- controller.interact(ctx);
153
+ controller?.interact(ctx);
144
154
  }
145
155
  </script>
146
156
 
@@ -157,7 +167,7 @@
157
167
  >
158
168
  <div
159
169
  class="camera-viewport"
160
- style:transform="translate({controller.panX}px, {controller.panY}px) scale({controller.zoom})"
170
+ style:transform="translate({panX}px, {panY}px) scale({zoom})"
161
171
  style:transform-origin="0 0"
162
172
  >
163
173
  {@render children(cameraState)}
@@ -1 +1 @@
1
- {"version":3,"file":"SnapZoomCamera.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/SnapZoomCamera.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,WAAW,EAAkB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjF,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAsJ1C,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"SnapZoomCamera.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/SnapZoomCamera.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,WAAW,EAAkB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjF,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAgK1C,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -204,7 +204,7 @@
204
204
  style:height="{height}px"
205
205
  onkeydown={handleKeydown}
206
206
  tabindex="0"
207
- role="application"
207
+ role="grid"
208
208
  aria-label="Zone tiler — use h/j/k/l to navigate zones"
209
209
  >
210
210
  <!-- Zone panes -->
@@ -219,7 +219,8 @@
219
219
  style:width="{zone.width}px"
220
220
  style:height="{zone.height}px"
221
221
  tabindex="0"
222
- role="region"
222
+ role="button"
223
+ aria-pressed={zone.id === focusedZoneId}
223
224
  aria-label={zone.zone.label}
224
225
  data-zone-id={zone.id}
225
226
  onclick={() => handleZoneClick(zone.id)}
@@ -0,0 +1,90 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { createDefaultBsp, splitZone, flattenBsp, findZone, serializeBsp, deserializeBsp, } from './zone-tiler-types';
3
+ const dt = 6;
4
+ describe('zone-tiler-types', () => {
5
+ it('createDefaultBsp produces a single leaf node', () => {
6
+ const tree = createDefaultBsp('main', 'Main Zone');
7
+ expect(tree.kind).toBe('leaf');
8
+ expect(tree.id).toBe('main');
9
+ expect(tree.label).toBe('Main Zone');
10
+ expect(tree.privacyState).toBe('ouvert');
11
+ });
12
+ it('splitZone replaces a leaf with a split node', () => {
13
+ const tree = createDefaultBsp('z1', 'Zone 1');
14
+ const newZone = { kind: 'leaf', id: 'z2', label: 'Zone 2', privacyState: 'ouvert' };
15
+ const result = splitZone(tree, 'z1', 'horizontal', newZone, 0.5);
16
+ expect(result.kind).toBe('split');
17
+ if (result.kind === 'split') {
18
+ expect(result.direction).toBe('horizontal');
19
+ expect(result.ratio).toBe(0.5);
20
+ expect(result.first.id).toBe('z1');
21
+ expect(result.second.id).toBe('z2');
22
+ }
23
+ });
24
+ it('flattenBsp returns one zone for a single leaf', () => {
25
+ const tree = createDefaultBsp('leaf1', 'Leaf');
26
+ const result = flattenBsp(tree, 0, 0, 800, 600, dt);
27
+ expect(result.zones.length).toBe(1);
28
+ expect(result.zones[0].id).toBe('leaf1');
29
+ expect(result.zones[0].x).toBe(0);
30
+ expect(result.zones[0].y).toBe(0);
31
+ expect(result.zones[0].width).toBe(800);
32
+ expect(result.zones[0].height).toBe(600);
33
+ expect(result.dividers.length).toBe(0);
34
+ });
35
+ it('flattenBsp produces two zones and one divider for a horizontal split', () => {
36
+ const tree = createDefaultBsp('z1', 'A');
37
+ const newZone = { kind: 'leaf', id: 'z2', label: 'B', privacyState: 'ouvert' };
38
+ const split = splitZone(tree, 'z1', 'horizontal', newZone, 0.5);
39
+ const result = flattenBsp(split, 0, 0, 800, 600, dt);
40
+ expect(result.zones.length).toBe(2);
41
+ expect(result.dividers.length).toBe(1);
42
+ expect(result.dividers[0].direction).toBe('horizontal');
43
+ });
44
+ it('flattenBsp zones do not overlap', () => {
45
+ const tree = createDefaultBsp('z1', 'A');
46
+ const z2 = { kind: 'leaf', id: 'z2', label: 'B', privacyState: 'ouvert' };
47
+ const split = splitZone(tree, 'z1', 'vertical', z2, 0.5);
48
+ const result = flattenBsp(split, 0, 0, 800, 600, dt);
49
+ const a = result.zones[0];
50
+ const b = result.zones[1];
51
+ const overlapX = a.x < b.x + b.width && a.x + a.width > b.x;
52
+ const overlapY = a.y < b.y + b.height && a.y + a.height > b.y;
53
+ expect(overlapX && overlapY).toBe(false);
54
+ });
55
+ it('findZone locates a leaf by id', () => {
56
+ const tree = createDefaultBsp('target', 'Target');
57
+ const found = findZone(tree, 'target');
58
+ expect(found).not.toBeNull();
59
+ expect(found.id).toBe('target');
60
+ });
61
+ it('findZone returns null for nonexistent id', () => {
62
+ const tree = createDefaultBsp('only', 'Only');
63
+ expect(findZone(tree, 'missing')).toBeNull();
64
+ });
65
+ it('findZone searches nested splits', () => {
66
+ const tree = createDefaultBsp('root', 'Root');
67
+ const child = { kind: 'leaf', id: 'child', label: 'Child', privacyState: 'ouvert' };
68
+ const split = splitZone(tree, 'root', 'horizontal', child);
69
+ const found = findZone(split, 'child');
70
+ expect(found).not.toBeNull();
71
+ expect(found.id).toBe('child');
72
+ });
73
+ it('serializeBsp and deserializeBsp round-trip', () => {
74
+ const tree = createDefaultBsp('rt', 'RoundTrip');
75
+ const child = { kind: 'leaf', id: 'c', label: 'C', privacyState: 'ouvert' };
76
+ const split = splitZone(tree, 'rt', 'vertical', child, 0.7);
77
+ const json = serializeBsp(split);
78
+ const restored = deserializeBsp(json);
79
+ expect(restored.kind).toBe('split');
80
+ if (restored.kind === 'split') {
81
+ expect(restored.ratio).toBe(0.7);
82
+ }
83
+ });
84
+ it('flattenBsp with nested splits produces correct zone count', () => {
85
+ let tree = createDefaultBsp('z1', 'A');
86
+ tree = splitZone(tree, 'z1', 'horizontal', { kind: 'leaf', id: 'z2', label: 'B', privacyState: 'ouvert' });
87
+ const result = flattenBsp(tree, 0, 0, 800, 600, dt);
88
+ expect(result.zones.length).toBe(2);
89
+ });
90
+ });