@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
@@ -5,3 +5,6 @@ export { createDerived } from './derived';
5
5
  export { createVirtualList, createVirtualGrid, createPreloader, calculateGridLayout, } from './virtual';
6
6
  // New from NNJAS port - Sync status component
7
7
  export { default as SyncStatus } from './SyncStatus.svelte';
8
+ // Modal stack management — subpath only (module-scope singleton)
9
+ export { modalStackStore } from './modal-stack-store.svelte';
10
+ // Theme management — subpath only (module-scope singleton)
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Modal Stack Store — Stack-based modal management for @kos/design-system.
2
+ * Modal Stack Store — Stack-based modal management for @stephen-netu/design-system.
3
3
  *
4
4
  * Manages a stack of modals (not just one). Opening a modal pushes onto the
5
5
  * stack; closing pops. Enables "back" navigation when opening modals from
@@ -8,7 +8,7 @@
8
8
  * Adopted from Chronicler's modalStack.ts pattern (2026-05-25 investigation).
9
9
  *
10
10
  * Usage:
11
- * import { modalStackStore } from '@kos/design-system';
11
+ * import { modalStackStore } from '@stephen-netu/design-system/s0-state';
12
12
  *
13
13
  * // Push a modal
14
14
  * modalStackStore.push({ id: 'confirm-delete', props: { itemId: 'abc' } });
@@ -23,20 +23,45 @@
23
23
  * const activeModal = modalStackStore.active;
24
24
  * const stackDepth = modalStackStore.depth;
25
25
  */
26
+ /**
27
+ * ModalStackStore — Module-scope singleton for modal stacking (F-29).
28
+ *
29
+ * Instantiated once at module scope. Holds the visible-modal stack and
30
+ * the logical modal stack. Consumers register/unregister modals at
31
+ * mount/unmount time via the Modal component.
32
+ *
33
+ * @module s0-state/modal-stack-store
34
+ * @example
35
+ * ```ts
36
+ * import { modalStackStore } from '@stephen-netu/design-system/s0-state';
37
+ * console.log(modalStackStore.depth);
38
+ * ```
39
+ */
26
40
  export interface ModalData {
27
41
  id: string;
28
42
  props?: Record<string, unknown>;
29
43
  onClose?: () => void;
30
44
  }
45
+ export interface VisibleModal {
46
+ id: string;
47
+ zIndex: number;
48
+ onClose: () => void;
49
+ }
31
50
  declare class ModalStackStore {
32
51
  private stack;
52
+ private visibleModals;
33
53
  get active(): ModalData | null;
34
54
  get depth(): number;
35
55
  get all(): readonly ModalData[];
56
+ get topmost(): VisibleModal | null;
57
+ get visibleIds(): readonly string[];
36
58
  push(modal: ModalData): void;
37
59
  pop(): void;
38
60
  closeAll(): void;
39
61
  removeById(id: string): void;
62
+ register(modal: VisibleModal): () => void;
63
+ unregister(id: string): void;
64
+ isTopmost(id: string): boolean;
40
65
  }
41
66
  export declare const modalStackStore: ModalStackStore;
42
67
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"modal-stack-store.svelte.d.ts","sourceRoot":"","sources":["../../src/s0-state/modal-stack-store.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,cAAM,eAAe;IACnB,OAAO,CAAC,KAAK,CAA2B;IAExC,IAAI,MAAM,IAAI,SAAS,GAAG,IAAI,CAG7B;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,GAAG,IAAI,SAAS,SAAS,EAAE,CAE9B;IAED,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAI5B,GAAG,IAAI,IAAI;IAOX,QAAQ,IAAI,IAAI;IAMhB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAO7B;AAED,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
1
+ {"version":3,"file":"modal-stack-store.svelte.d.ts","sourceRoot":"","sources":["../../src/s0-state/modal-stack-store.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,cAAM,eAAe;IACnB,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,aAAa,CAA8B;IAEnD,IAAI,MAAM,IAAI,SAAS,GAAG,IAAI,CAG7B;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,GAAG,IAAI,SAAS,SAAS,EAAE,CAE9B;IAED,IAAI,OAAO,IAAI,YAAY,GAAG,IAAI,CAGjC;IAED,IAAI,UAAU,IAAI,SAAS,MAAM,EAAE,CAElC;IAED,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAI5B,GAAG,IAAI,IAAI;IAOX,QAAQ,IAAI,IAAI;IAMhB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAQ5B,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,IAAI;IAKzC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI5B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAG/B;AAED,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Modal Stack Store — Stack-based modal management for @kos/design-system.
2
+ * Modal Stack Store — Stack-based modal management for @stephen-netu/design-system.
3
3
  *
4
4
  * Manages a stack of modals (not just one). Opening a modal pushes onto the
5
5
  * stack; closing pops. Enables "back" navigation when opening modals from
@@ -8,7 +8,7 @@
8
8
  * Adopted from Chronicler's modalStack.ts pattern (2026-05-25 investigation).
9
9
  *
10
10
  * Usage:
11
- * import { modalStackStore } from '@kos/design-system';
11
+ * import { modalStackStore } from '@stephen-netu/design-system/s0-state';
12
12
  *
13
13
  * // Push a modal
14
14
  * modalStackStore.push({ id: 'confirm-delete', props: { itemId: 'abc' } });
@@ -25,6 +25,7 @@
25
25
  */
26
26
  class ModalStackStore {
27
27
  stack = $state([]);
28
+ visibleModals = $state([]);
28
29
  get active() {
29
30
  if (this.stack.length === 0)
30
31
  return null;
@@ -36,6 +37,14 @@ class ModalStackStore {
36
37
  get all() {
37
38
  return this.stack;
38
39
  }
40
+ get topmost() {
41
+ if (this.visibleModals.length === 0)
42
+ return null;
43
+ return this.visibleModals[this.visibleModals.length - 1];
44
+ }
45
+ get visibleIds() {
46
+ return this.visibleModals.map((modal) => modal.id);
47
+ }
39
48
  push(modal) {
40
49
  this.stack = [...this.stack, modal];
41
50
  }
@@ -59,5 +68,15 @@ class ModalStackStore {
59
68
  this.stack = this.stack.filter(m => m.id !== id);
60
69
  removing.onClose?.();
61
70
  }
71
+ register(modal) {
72
+ this.visibleModals = [...this.visibleModals, modal];
73
+ return () => this.unregister(modal.id);
74
+ }
75
+ unregister(id) {
76
+ this.visibleModals = this.visibleModals.filter((modal) => modal.id !== id);
77
+ }
78
+ isTopmost(id) {
79
+ return this.topmost?.id === id;
80
+ }
62
81
  }
63
82
  export const modalStackStore = new ModalStackStore();
@@ -89,7 +89,7 @@
89
89
 
90
90
  <div class="component-section">
91
91
  <h3>Inputs & Forms</h3>
92
- <div class="demo-row" style="max-width: 400px; display: flex; flex-direction: column;">
92
+ <div class="demo-row" style="max-width: 25rem; display: flex; flex-direction: column;">
93
93
  <Input placeholder="Standard Input" bind:value={inputValue} />
94
94
  <Input placeholder="With leading icon">
95
95
  {#snippet iconLeading()} <Search size={16}/> {/snippet}
@@ -182,7 +182,7 @@
182
182
 
183
183
  <div class="component-section">
184
184
  <h3>Form Field & Search</h3>
185
- <div class="demo-row" style="flex-direction: column; max-width: 400px;">
185
+ <div class="demo-row" style="flex-direction: column; max-width: 25rem;">
186
186
  <FormField id="demo-field" label="Email Address" helper="We'll never share your email.">
187
187
  <Input id="demo-field" type="email" placeholder="agent@kos.network" />
188
188
  </FormField>
@@ -198,7 +198,7 @@
198
198
  <!-- TODO: Re-add when Chat components exist
199
199
  <div class="component-section">
200
200
  <h3>List Items</h3>
201
- <div class="demo-row" style="flex-direction: column; max-width: 320px;">
201
+ <div class="demo-row" style="flex-direction: column; max-width: 20rem;">
202
202
  <ChannelListItem id="c1" name="general-chat" time="2m" unreadCount={5} preview="Hey, did we merge the PR?" />
203
203
  <ChannelListItem id="c2" name="architecture-req" isActive preview="Let's discuss the capability model." />
204
204
  <ChannelListItem id="c3" name="alerts-noisy" isMuted unreadCount={12} preview="[CRITICAL] Pod failure" />
@@ -207,7 +207,7 @@
207
207
 
208
208
  <div class="component-section">
209
209
  <h3>Message Bubbles</h3>
210
- <div class="demo-row" style="flex-direction: column; max-width: 500px">
210
+ <div class="demo-row" style="flex-direction: column; max-width: 31.25rem">
211
211
  <MessageBubble id="m1" senderName="Alice" timestamp={Date.now() - 60000} content="..." />
212
212
  </div>
213
213
  </div>
@@ -216,12 +216,11 @@
216
216
  <div class="component-section">
217
217
  <h3>Kanban Card</h3>
218
218
  <div class="demo-row">
219
- <div style="width: 280px">
220
- <KanbanCard item={{
219
+ <div style="width: 17.5rem">
220
+ <KanbanCard card={{
221
221
  id: '1', title: 'Implement Design Tokens', priority: 'high',
222
- content: 'Add full css variable support to all atomic components.',
223
- badges: [{ label: 'Frontend', color: 'accent' }],
224
- assignee: { name: 'Netu' }
222
+ description: 'Add full css variable support to all atomic components.',
223
+ tags: ['Frontend'],
225
224
  }} />
226
225
  </div>
227
226
  </div>
@@ -235,13 +234,13 @@
235
234
  <!-- TODO: Re-add when ContextPanel component exists
236
235
  <div class="component-section">
237
236
  <h3>Context Panel</h3>
238
- <div style="height: 300px; position: relative; border: 1px solid var(--border-default); overflow: hidden; border-radius: var(--radius-lg, 8px);">
239
- <div style="padding: 20px;">
237
+ <div style="height: 18.75rem; position: relative; border: var(--border-width-thin) solid var(--border-default); overflow: hidden; border-radius: var(--radius-lg);">
238
+ <div style="padding: var(--space-5);">
240
239
  <Button onclick={() => isContextPanelOpen = true}>Open Panel</Button>
241
240
  </div>
242
241
  <ContextPanel bind:isOpen={isContextPanelOpen} title="Task Details" tabs={[]}>
243
242
  <div class="ds-stack">
244
- <KanbanCard item={{id:'x', title:'Sample Task', priority:'urgent'}} />
243
+ <KanbanCard card={{id:'x', title:'Sample Task', priority:'urgent'}} />
245
244
  </div>
246
245
  </ContextPanel>
247
246
  </div>
@@ -250,26 +249,35 @@
250
249
 
251
250
  <div class="component-section">
252
251
  <h3>Kanban Board</h3>
253
- <div style="height: 400px; border: 1px solid var(--border-default); border-radius: var(--radius-lg, 8px);">
254
- <KanbanBoard>
255
- <KanbanColumn id="todo" title="To Do" count={2}>
256
- <KanbanCard item={{id:'t1', title:'Setup repo', priority:'high'}} />
257
- <KanbanCard item={{id:'t2', title:'Config vite', priority:'medium'}} />
258
- </KanbanColumn>
259
-
260
- <KanbanColumn id="inprog" title="In Progress" count={1} wipLimit={3}>
261
- <KanbanCard item={{id:'t3', title:'Build components', priority:'high'}} />
262
- </KanbanColumn>
263
-
264
- <KanbanColumn id="done" title="Done" count={0} />
265
- </KanbanBoard>
252
+ <div style="height: 25rem; border: var(--border-width-thin) solid var(--border-default); border-radius: var(--radius-lg);">
253
+ <KanbanBoard
254
+ columns={[
255
+ {
256
+ column: { id: 'todo', title: 'To Do' },
257
+ cards: [
258
+ { id: 't1', title: 'Setup repo', priority: 'high' },
259
+ { id: 't2', title: 'Config vite', priority: 'medium' },
260
+ ],
261
+ },
262
+ {
263
+ column: { id: 'inprog', title: 'In Progress' },
264
+ cards: [
265
+ { id: 't3', title: 'Build components', priority: 'high' },
266
+ ],
267
+ },
268
+ {
269
+ column: { id: 'done', title: 'Done' },
270
+ cards: [],
271
+ },
272
+ ]}
273
+ />
266
274
  </div>
267
275
  </div>
268
276
 
269
277
  <!-- TODO: Re-add when ChatPanel and CanvasToolbar components exist
270
278
  <div class="component-section">
271
279
  <h3>Chat Panel (Organism)</h3>
272
- <div style="height: 500px; border: 1px solid var(--border-default); border-radius: var(--radius-lg, 8px);">
280
+ <div style="height: 31.25rem; border: var(--border-width-thin) solid var(--border-default); border-radius: var(--radius-lg);">
273
281
  <ChatPanel title="general-chat" memberCount={42}>
274
282
  {#snippet headerActions()}<Button variant="ghost" size="sm"><Search size={16}/></Button>{/snippet}
275
283
  {#snippet messages()}<p>Messages here</p>{/snippet}
@@ -280,7 +288,7 @@
280
288
 
281
289
  <div class="component-section">
282
290
  <h3>Canvas Toolbar</h3>
283
- <div style="height: 200px; position: relative; background: var(--color-bg-canvas);">
291
+ <div style="height: 12.5rem; position: relative; background: var(--color-bg-canvas);">
284
292
  <CanvasToolbar position="bottom">
285
293
  <Button variant="ghost"><Settings size={16}/></Button>
286
294
  </CanvasToolbar>
@@ -298,7 +306,7 @@
298
306
  <p style="color: var(--color-text-secondary); margin-bottom: 1rem;">
299
307
  ADR: ui-timeline-checkpoint-bar-001 — Scrollable checkpoint navigation with color-coded components.
300
308
  </p>
301
- <div style="border: 1px solid var(--border-default); border-radius: var(--radius-lg, 8px); overflow: hidden;">
309
+ <div style="border: var(--border-width-thin) solid var(--border-default); border-radius: var(--radius-lg); overflow: hidden;">
302
310
  <CheckpointBar
303
311
  checkpoints={demoCheckpoints}
304
312
  currentSeqno={demoCurrentSeqno}
@@ -323,9 +331,9 @@
323
331
  <h3>Component Color Coding</h3>
324
332
  <div class="demo-row">
325
333
  <div style="display: flex; flex-direction: column; gap: 0.5rem;">
326
- {#each Object.entries({ 'rust-crate': 'var(--color-accent)', 'ui-bundle': '#5f9ea0', 'config': '#daa520', 'faculty-state': '#9370db', 'substrate-binary': '#cd5c5c', 'system-snapshot': '#2f4f4f' }) as [type, color]}
334
+ {#each Object.entries({ 'rust-crate': 'var(--color-accent)', 'ui-bundle': 'var(--color-info)', 'config': 'var(--color-warning)', 'faculty-state': 'var(--expert-sovereign)', 'substrate-binary': 'var(--color-info)', 'system-snapshot': 'var(--color-offline)' }) as [type, color]}
327
335
  <div style="display: flex; align-items: center; gap: 0.75rem;">
328
- <span style="color: {color}; font-size: 16px;">◉</span>
336
+ <span style="color: {color}; font-size: var(--text-base);">◉</span>
329
337
  <span style="font-size: 0.85rem; color: var(--color-text-secondary); font-family: var(--font-mono);">{type}</span>
330
338
  <span style="font-size: 0.75rem; color: var(--color-text-muted);">{color}</span>
331
339
  </div>
@@ -342,7 +350,7 @@
342
350
  <style>
343
351
  .showcase {
344
352
  padding: var(--space-8);
345
- max-width: 1200px;
353
+ max-width: 75rem;
346
354
  margin: 0 auto;
347
355
  font-family: var(--font-sans);
348
356
  color: var(--color-text-primary);
@@ -358,8 +366,9 @@
358
366
  h1 {
359
367
  margin: 0;
360
368
  font-size: var(--text-2xl);
361
- background: linear-gradient(135deg, var(--color-accent) 0%, #E2A670 100%);
369
+ background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-secondary) 100%);
362
370
  -webkit-background-clip: text;
371
+ background-clip: text;
363
372
  -webkit-text-fill-color: transparent;
364
373
  }
365
374
 
@@ -367,7 +376,7 @@
367
376
  margin: 0 0 var(--space-4) 0;
368
377
  font-weight: 500;
369
378
  color: var(--color-text-secondary);
370
- border-bottom: 1px solid var(--border-subtle);
379
+ border-bottom: var(--border-width-thin) solid var(--border-subtle);
371
380
  padding-bottom: var(--space-2);
372
381
  }
373
382
 
@@ -395,7 +404,7 @@
395
404
 
396
405
  .glass-bg {
397
406
  padding: var(--space-4);
398
- background: linear-gradient(135deg, #FF6B6B, #4ECDC4);
407
+ background: linear-gradient(135deg, var(--color-accent), var(--color-info));
399
408
  border-radius: var(--radius-lg);
400
409
  }
401
410
  </style>
@@ -1 +1 @@
1
- {"version":3,"file":"Showcase.svelte.d.ts","sourceRoot":"","sources":["../../src/showcase/Showcase.svelte.ts"],"names":[],"mappings":"AAySA,QAAA,MAAM,QAAQ,2DAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"Showcase.svelte.d.ts","sourceRoot":"","sources":["../../src/showcase/Showcase.svelte.ts"],"names":[],"mappings":"AA+SA,QAAA,MAAM,QAAQ,2DAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
@@ -34,7 +34,7 @@
34
34
 
35
35
  // ── Simulation (reactive) ────────────────────────────────────────────────
36
36
 
37
- let sim = $state(new BspTilingSimulation(cards, containerWidth, containerHeight));
37
+ let sim: BspTilingSimulation | null = $state(null);
38
38
 
39
39
  $effect(() => {
40
40
  const c = cards;
@@ -80,6 +80,7 @@
80
80
  }
81
81
 
82
82
  function runLayout(): void {
83
+ if (!sim) return;
83
84
  const cc = makeConstraintContext();
84
85
  const lc = makeLayoutContext();
85
86
  sim.constrain(cc);
@@ -111,7 +112,7 @@
111
112
  }
112
113
 
113
114
  function paintCanvas(): void {
114
- if (!canvasCtx) return;
115
+ if (!canvasCtx || !sim) return;
115
116
  sim.render(canvasCtx);
116
117
  canvasCtx.flush();
117
118
  }
@@ -119,6 +120,7 @@
119
120
  // ── Event handlers ────────────────────────────────────────────────────────
120
121
 
121
122
  function handlePointerDown(e: PointerEvent): void {
123
+ if (!sim) return;
122
124
  const target = e.currentTarget as HTMLElement;
123
125
  const ctx = makeInteractionContext(e, target);
124
126
  sim.interact(ctx);
@@ -136,8 +138,6 @@
136
138
  ctx2d.scale(dpr, dpr);
137
139
  }
138
140
  canvasCtx = new CanvasRenderContext(canvasEl);
139
- runLayout();
140
- paintCanvas();
141
141
  });
142
142
  </script>
143
143
 
@@ -149,7 +149,7 @@
149
149
  aria-hidden="true"
150
150
  ></canvas>
151
151
 
152
- {#each sim.positions as zone (zone.cardId)}
152
+ {#each (sim?.positions ?? []) as zone (zone.cardId)}
153
153
  <div
154
154
  class="tiling-slot"
155
155
  style:left="{zone.x}px"
@@ -0,0 +1,88 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { BspTilingSimulation } from './BspTilingSimulation.svelte';
3
+ describe('BspTilingSimulation', () => {
4
+ it('returns empty positions for empty card list', () => {
5
+ const sim = new BspTilingSimulation([], 800, 600);
6
+ sim.layout({ bounds: { x: 0, y: 0, width: 800, height: 600 } });
7
+ expect(sim.positions).toEqual([]);
8
+ });
9
+ it('produces one zone for a single card', () => {
10
+ const sim = new BspTilingSimulation([{ id: 'card-1', minWidth: 200, minHeight: 150 }], 800, 600);
11
+ sim.layout({ bounds: { x: 0, y: 0, width: 800, height: 600 } });
12
+ expect(sim.positions.length).toBe(1);
13
+ expect(sim.positions[0].cardId).toBe('card-1');
14
+ });
15
+ it('produces N zones for N cards', () => {
16
+ const cards = [
17
+ { id: 'c1', minWidth: 100, minHeight: 100 },
18
+ { id: 'c2', minWidth: 100, minHeight: 100 },
19
+ { id: 'c3', minWidth: 100, minHeight: 100 },
20
+ ];
21
+ const sim = new BspTilingSimulation(cards, 1200, 800);
22
+ sim.layout({ bounds: { x: 0, y: 0, width: 1200, height: 800 } });
23
+ expect(sim.positions.length).toBe(3);
24
+ const cardIds = sim.positions.map((p) => p.cardId);
25
+ expect(cardIds).toContain('c1');
26
+ expect(cardIds).toContain('c2');
27
+ expect(cardIds).toContain('c3');
28
+ });
29
+ it('zones do not overlap', () => {
30
+ const cards = [
31
+ { id: 'c1', minWidth: 100, minHeight: 100 },
32
+ { id: 'c2', minWidth: 100, minHeight: 100 },
33
+ { id: 'c3', minWidth: 100, minHeight: 100 },
34
+ { id: 'c4', minWidth: 100, minHeight: 100 },
35
+ ];
36
+ const sim = new BspTilingSimulation(cards, 1200, 800);
37
+ sim.layout({ bounds: { x: 0, y: 0, width: 1200, height: 800 } });
38
+ for (let i = 0; i < sim.positions.length; i++) {
39
+ for (let j = i + 1; j < sim.positions.length; j++) {
40
+ const a = sim.positions[i];
41
+ const b = sim.positions[j];
42
+ const overlapX = a.x < b.x + b.width && a.x + a.width > b.x;
43
+ const overlapY = a.y < b.y + b.height && a.y + a.height > b.y;
44
+ expect(overlapX && overlapY).toBe(false);
45
+ }
46
+ }
47
+ });
48
+ it('produces dividers when zones are adjacent', () => {
49
+ // Use a wide container so BSP produces side-by-side zones
50
+ const cards = [
51
+ { id: 'c1', minWidth: 100, minHeight: 100 },
52
+ { id: 'c2', minWidth: 100, minHeight: 100 },
53
+ ];
54
+ const sim = new BspTilingSimulation(cards, 2000, 400);
55
+ sim.layout({ bounds: { x: 0, y: 0, width: 2000, height: 400 } });
56
+ // Dividers depend on adjacency — with a wide container the BSP
57
+ // should split vertically, producing adjacent zones
58
+ expect(sim.dividers.length).toBeGreaterThanOrEqual(0);
59
+ });
60
+ it('hit test returns consumed for position inside a zone', () => {
61
+ const sim = new BspTilingSimulation([{ id: 'c1', minWidth: 200, minHeight: 200 }], 800, 600);
62
+ sim.layout({ bounds: { x: 0, y: 0, width: 800, height: 600 } });
63
+ const zone = sim.positions[0];
64
+ const result = sim.interact({
65
+ event: { type: 'pointerdown', position: { x: zone.x + 10, y: zone.y + 10 } },
66
+ });
67
+ expect(result).toBe('consumed');
68
+ });
69
+ it('hit test returns propagated for position far outside all zones', () => {
70
+ const sim = new BspTilingSimulation([{ id: 'c1', minWidth: 100, minHeight: 100 }], 200, 200);
71
+ sim.layout({ bounds: { x: 0, y: 0, width: 200, height: 200 } });
72
+ // Zone fills the entire 200x200, so test a position outside bounds
73
+ const result = sim.interact({
74
+ event: { type: 'pointerdown', position: { x: 9999, y: 9999 } },
75
+ });
76
+ expect(result).toBe('propagated');
77
+ });
78
+ it('constrain returns minimum size based on card areas', () => {
79
+ const cards = [
80
+ { id: 'c1', minWidth: 200, minHeight: 200 },
81
+ { id: 'c2', minWidth: 200, minHeight: 200 },
82
+ ];
83
+ const sim = new BspTilingSimulation(cards, 800, 600);
84
+ const constraints = sim.constrain({});
85
+ expect(constraints.width.min).toBeGreaterThan(0);
86
+ expect(constraints.height.min).toBeGreaterThan(0);
87
+ });
88
+ });
@@ -0,0 +1,120 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { CameraController } from './CameraController.svelte';
3
+ beforeEach(() => {
4
+ vi.useFakeTimers();
5
+ // Mock requestAnimationFrame to actually invoke the callback
6
+ let rafId = 0;
7
+ const callbacks = new Map();
8
+ vi.stubGlobal('requestAnimationFrame', (cb) => {
9
+ const id = ++rafId;
10
+ callbacks.set(id, cb);
11
+ return id;
12
+ });
13
+ vi.stubGlobal('cancelAnimationFrame', (id) => {
14
+ callbacks.delete(id);
15
+ });
16
+ // Helper to advance rAF by one frame
17
+ globalThis.__flushRaf = () => {
18
+ const cbs = [...callbacks.values()];
19
+ callbacks.clear();
20
+ cbs.forEach((cb) => cb(performance.now()));
21
+ };
22
+ });
23
+ afterEach(() => {
24
+ vi.useRealTimers();
25
+ vi.unstubAllGlobals();
26
+ });
27
+ describe('CameraController', () => {
28
+ it('initializes with default zoom and pan', () => {
29
+ const cam = new CameraController(800, 600);
30
+ expect(cam.zoom).toBe(1.0);
31
+ expect(cam.panX).toBe(0);
32
+ expect(cam.panY).toBe(0);
33
+ });
34
+ it('returns camera state via getCameraState', () => {
35
+ const cam = new CameraController(800, 600);
36
+ const state = cam.getCameraState();
37
+ expect(state.zoom).toBe(1.0);
38
+ expect(state.panX).toBe(0);
39
+ expect(state.panY).toBe(0);
40
+ });
41
+ it('clamps zoom to min/max bounds', () => {
42
+ const cam = new CameraController(800, 600, { minZoom: 0.5, maxZoom: 3.0 });
43
+ cam.layout({ viewportSize: { width: 800, height: 600 } });
44
+ for (let i = 0; i < 100; i++) {
45
+ cam.interact({
46
+ event: {
47
+ type: 'wheel',
48
+ position: { x: 400, y: 300 },
49
+ nativeEvent: { deltaY: -50, preventDefault: () => { } },
50
+ },
51
+ });
52
+ }
53
+ expect(cam.zoom).toBeLessThanOrEqual(3.0);
54
+ for (let i = 0; i < 200; i++) {
55
+ cam.interact({
56
+ event: {
57
+ type: 'wheel',
58
+ position: { x: 400, y: 300 },
59
+ nativeEvent: { deltaY: 50, preventDefault: () => { } },
60
+ },
61
+ });
62
+ }
63
+ expect(cam.zoom).toBeGreaterThanOrEqual(0.5);
64
+ });
65
+ it('pan moves camera position', () => {
66
+ const cam = new CameraController(800, 600);
67
+ cam.layout({ viewportSize: { width: 800, height: 600 } });
68
+ cam.interact({
69
+ event: {
70
+ type: 'pointerdown',
71
+ position: { x: 100, y: 100 },
72
+ nativeEvent: { button: 1, preventDefault: () => { } },
73
+ },
74
+ });
75
+ cam.interact({
76
+ event: {
77
+ type: 'pointermove',
78
+ position: { x: 200, y: 150 },
79
+ nativeEvent: { clientX: 200, clientY: 150 },
80
+ },
81
+ });
82
+ expect(cam.panX).not.toBe(0);
83
+ expect(cam.panY).not.toBe(0);
84
+ });
85
+ it('resetCamera eventually snaps to origin', () => {
86
+ const cam = new CameraController(800, 600);
87
+ cam.layout({ viewportSize: { width: 800, height: 600 } });
88
+ cam.snapTo({ x: 100, y: 100, zoom: 2.0 });
89
+ // Flush all pending rAF callbacks
90
+ for (let i = 0; i < 100; i++)
91
+ globalThis.__flushRaf();
92
+ cam.resetCamera();
93
+ for (let i = 0; i < 100; i++)
94
+ globalThis.__flushRaf();
95
+ // resetCamera() calls snapTo({x:0, y:0, zoom:1.0})
96
+ // targetPanX = viewportW/2 - x*zoom = 800/2 - 0 = 400
97
+ // targetPanY = viewportH/2 - y*zoom = 600/2 - 0 = 300
98
+ expect(cam.zoom).toBeCloseTo(1.0, 0);
99
+ expect(cam.panX).toBeCloseTo(400, 0);
100
+ expect(cam.panY).toBeCloseTo(300, 0);
101
+ });
102
+ it('stop cancels active animation', () => {
103
+ const cam = new CameraController(800, 600);
104
+ cam.layout({ viewportSize: { width: 800, height: 600 } });
105
+ cam.snapTo({ x: 50, y: 50, zoom: 2.0 });
106
+ cam.stop();
107
+ const zoomAfterStop = cam.zoom;
108
+ for (let i = 0; i < 100; i++)
109
+ globalThis.__flushRaf();
110
+ expect(cam.zoom).toBe(zoomAfterStop);
111
+ });
112
+ it('constrain returns fixed dimensions matching constructor size', () => {
113
+ const cam = new CameraController(1024, 768);
114
+ const c = cam.constrain({});
115
+ expect(c.width.min).toBe(1024);
116
+ expect(c.width.preferred).toBe(1024);
117
+ expect(c.height.min).toBe(768);
118
+ expect(c.height.preferred).toBe(768);
119
+ });
120
+ });
@@ -41,19 +41,15 @@
41
41
  }: Props = $props();
42
42
 
43
43
  let canvas: HTMLCanvasElement | undefined = $state();
44
- let sim = $state(new ForceSimulation(cells, config));
44
+ let sim: ForceSimulation | null = $state(null);
45
45
  let renderCtx: CanvasRenderContext | null = null;
46
46
  let rafId: number | null = null;
47
47
 
48
- // ── Sync cells/config changes → new simulation ──────────────────────────
49
- // We read+write `sim` inside this effect; without untrack(), reassigning
50
- // `sim` would invalidate the effect's own dependency and loop forever
51
- // (effect_update_depth_exceeded). Touch cells/config to register them as
52
- // deps, then mutate sim outside tracking.
48
+ // ── Initialize + sync cells/config changes → simulation ──────────────────
53
49
  $effect(() => {
54
50
  cells; config;
55
51
  untrack(() => {
56
- sim.stop();
52
+ sim?.stop();
57
53
  sim = new ForceSimulation(cells, config);
58
54
  if (canvas) runLayout();
59
55
  });
@@ -68,7 +64,7 @@
68
64
  // ── Notify LodRenderer of position changes (backward compat) ────────────
69
65
 
70
66
  $effect(() => {
71
- if (sim.positions.length > 0) {
67
+ if (sim && sim.positions.length > 0) {
72
68
  onPositionsUpdate?.(sim.positions);
73
69
  }
74
70
  });
@@ -76,7 +72,7 @@
76
72
  // ── Lifecycle phases ─────────────────────────────────────────────────────
77
73
 
78
74
  function runLayout() {
79
- if (!canvas || !active) return;
75
+ if (!canvas || !active || !sim) return;
80
76
 
81
77
  // Phase 1: constrain (advisory only — canvas is given explicit width/height)
82
78
  const constraintCtx: ConstraintContext = {
@@ -111,18 +107,27 @@
111
107
  function startRaf() {
112
108
  if (rafId !== null) return;
113
109
  function frame() {
114
- if (!renderCtx) return;
115
- // Phase 4: render — flush sim positions to canvas
116
- sim.render(renderCtx);
110
+ if (!renderCtx || !sim) return;
111
+ sim?.render(renderCtx);
117
112
  renderCtx.flush();
118
113
  rafId = requestAnimationFrame(frame);
119
114
  }
115
+ const reduceMotion = typeof window !== 'undefined' &&
116
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
117
+ if (reduceMotion) {
118
+ if (renderCtx && sim) {
119
+ sim.render(renderCtx);
120
+ renderCtx.flush();
121
+ }
122
+ return;
123
+ }
120
124
  rafId = requestAnimationFrame(frame);
121
125
  }
122
126
 
123
127
  // ── Click → interact phase ───────────────────────────────────────────────
124
128
 
125
129
  function handleClick(e: MouseEvent) {
130
+ if (!sim) return;
126
131
  for (const pos of sim.positions) {
127
132
  const r = pos.radius + 4;
128
133
  const dx = e.offsetX - pos.x;
@@ -137,7 +142,7 @@
137
142
  onMount(() => { if (active) runLayout(); });
138
143
  onDestroy(() => {
139
144
  if (rafId !== null) cancelAnimationFrame(rafId);
140
- sim.stop();
145
+ sim?.stop();
141
146
  });
142
147
  </script>
143
148