@stephen-netu/design-system 0.2.2 → 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 (229) hide show
  1. package/dist/d0-data-viz/BarChart.test.js +53 -0
  2. package/dist/d0-data-viz/CheckpointBar.test.js +83 -0
  3. package/dist/d0-data-viz/CheckpointPill.svelte +1 -1
  4. package/dist/d0-data-viz/CheckpointPill.test.js +78 -0
  5. package/dist/d0-data-viz/ConnectionHealth.test.js +70 -0
  6. package/dist/d0-data-viz/MetricCard.test.js +57 -0
  7. package/dist/d0-data-viz/SparkLine.test.js +47 -0
  8. package/dist/d0-data-viz/StorageMap.test.js +63 -0
  9. package/dist/d0-data-viz/Timeline.test.js +62 -0
  10. package/dist/d0-data-viz/WorldLineTimeline.test.js +99 -0
  11. package/dist/d0-data-viz/checkpoint-types.js +1 -1
  12. package/dist/d0-data-viz/storage-map-types.d.ts.map +1 -1
  13. package/dist/d0-data-viz/storage-map-types.js +6 -3
  14. package/dist/d0-data-viz/theme-integration.js +1 -1
  15. package/dist/demos/AmbientPrimitivesDemo.svelte +103 -0
  16. package/dist/demos/AmbientPrimitivesDemo.svelte.d.ts +5 -0
  17. package/dist/demos/AmbientPrimitivesDemo.svelte.d.ts.map +1 -0
  18. package/dist/demos/NodepadBlocksShowcase.svelte +2 -1
  19. package/dist/demos/NodepadBlocksShowcase.svelte.d.ts.map +1 -1
  20. package/dist/demos/index.d.ts +1 -0
  21. package/dist/demos/index.d.ts.map +1 -1
  22. package/dist/demos/index.js +1 -0
  23. package/dist/editor/CodeEditor.svelte +83 -26
  24. package/dist/editor/CodeEditor.svelte.d.ts +0 -1
  25. package/dist/editor/CodeEditor.svelte.d.ts.map +1 -1
  26. package/dist/editor/ExternalChangeDialog.svelte +117 -0
  27. package/dist/editor/ExternalChangeDialog.svelte.d.ts +13 -0
  28. package/dist/editor/ExternalChangeDialog.svelte.d.ts.map +1 -0
  29. package/dist/editor/MarkdownEditor.svelte +104 -617
  30. package/dist/editor/MarkdownEditor.svelte.d.ts +1 -1
  31. package/dist/editor/MarkdownEditor.svelte.d.ts.map +1 -1
  32. package/dist/editor/codemirror-config.d.ts +36 -0
  33. package/dist/editor/codemirror-config.d.ts.map +1 -0
  34. package/dist/editor/codemirror-config.js +87 -0
  35. package/dist/editor/components/CorrectionTooltip.svelte +180 -159
  36. package/dist/editor/components/CorrectionTooltip.svelte.d.ts +7 -23
  37. package/dist/editor/components/CorrectionTooltip.svelte.d.ts.map +1 -1
  38. package/dist/editor/extensions/autocomplete.d.ts +2 -2
  39. package/dist/editor/extensions/autocomplete.d.ts.map +1 -1
  40. package/dist/editor/extensions/autocomplete.test.js +121 -0
  41. package/dist/editor/extensions/spellcheck.d.ts +21 -3
  42. package/dist/editor/extensions/spellcheck.d.ts.map +1 -1
  43. package/dist/editor/extensions/spellcheck.js +51 -9
  44. package/dist/editor/extensions/spellcheck.test.js +168 -0
  45. package/dist/editor/extensions/types.d.ts +2 -1
  46. package/dist/editor/extensions/types.d.ts.map +1 -1
  47. package/dist/editor/index.d.ts +2 -1
  48. package/dist/editor/index.d.ts.map +1 -1
  49. package/dist/editor/index.js +1 -0
  50. package/dist/editor/markdown-preview.d.ts +9 -0
  51. package/dist/editor/markdown-preview.d.ts.map +1 -0
  52. package/dist/editor/markdown-preview.js +19 -0
  53. package/dist/editor/markdown-preview.test.js +38 -0
  54. package/dist/editor/useCodeMirror.d.ts +23 -0
  55. package/dist/editor/useCodeMirror.d.ts.map +1 -0
  56. package/dist/editor/useCodeMirror.js +40 -0
  57. package/dist/editor/useFilePersistence.d.ts +32 -0
  58. package/dist/editor/useFilePersistence.d.ts.map +1 -0
  59. package/dist/editor/useFilePersistence.js +117 -0
  60. package/dist/fabric/ai/ChatPanel.svelte +61 -62
  61. package/dist/fabric/ai/ChatPanel.svelte.d.ts.map +1 -1
  62. package/dist/fabric/ai/ResearchPanel.svelte +31 -24
  63. package/dist/fabric/data/FileTree.svelte +195 -0
  64. package/dist/fabric/data/FileTree.svelte.d.ts +19 -0
  65. package/dist/fabric/data/FileTree.svelte.d.ts.map +1 -0
  66. package/dist/fabric/data/FileTree.test.js +127 -0
  67. package/dist/fabric/data/index.d.ts +5 -9
  68. package/dist/fabric/data/index.d.ts.map +1 -1
  69. package/dist/fabric/data/index.js +4 -1
  70. package/dist/fabric/index.d.ts +1 -0
  71. package/dist/fabric/index.d.ts.map +1 -1
  72. package/dist/fabric/index.js +2 -0
  73. package/dist/fabric/input/KeyboardShortcuts.svelte +23 -21
  74. package/dist/fabric/layout/CollapsiblePanel.svelte +8 -10
  75. package/dist/fabric/navigation/ActivityRail.svelte +3 -5
  76. package/dist/fabric/navigation/ActivityRail.svelte.d.ts.map +1 -1
  77. package/dist/g0-generative/components/Text.svelte +38 -0
  78. package/dist/g0-generative/components/Text.svelte.d.ts +9 -0
  79. package/dist/g0-generative/components/Text.svelte.d.ts.map +1 -0
  80. package/dist/g0-generative/index.d.ts +1 -0
  81. package/dist/g0-generative/index.d.ts.map +1 -1
  82. package/dist/g0-generative/index.js +1 -0
  83. package/dist/g0-generative/library/ComponentLibrary.d.ts +4 -0
  84. package/dist/g0-generative/library/ComponentLibrary.d.ts.map +1 -1
  85. package/dist/g0-generative/library/ComponentLibrary.js +10 -0
  86. package/dist/g0-generative/library/ComponentLibrary.test.js +135 -0
  87. package/dist/g0-generative/renderer/OpenUIRenderer.svelte +16 -56
  88. package/dist/g0-generative/renderer/OpenUIRenderer.svelte.d.ts.map +1 -1
  89. package/dist/g0-generative/renderer/OpenUIRenderer.test.js +143 -0
  90. package/dist/g0-geo/SovereignMap.svelte +13 -13
  91. package/dist/g0-geo/SovereignMap.svelte.d.ts.map +1 -1
  92. package/dist/index.d.ts +0 -1
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +3 -1
  95. package/dist/l0-layout/block-writer/BlockContent.svelte +23 -22
  96. package/dist/l0-layout/block-writer/BlockContent.svelte.d.ts.map +1 -1
  97. package/dist/l0-layout/block-writer/BlockContent.test.js +47 -0
  98. package/dist/l0-layout/block-writer/markdown.js +11 -11
  99. package/dist/l0-layout/block-writer/markdown.test.js +81 -0
  100. package/dist/l0-layout/card/StackedCard.svelte +87 -0
  101. package/dist/l0-layout/card/StackedCard.svelte.d.ts +9 -0
  102. package/dist/l0-layout/card/StackedCard.svelte.d.ts.map +1 -0
  103. package/dist/l0-layout/card/StackedCard.test.js +29 -0
  104. package/dist/l0-layout/index.d.ts +1 -0
  105. package/dist/l0-layout/index.d.ts.map +1 -1
  106. package/dist/l0-layout/index.js +1 -0
  107. package/dist/l0-layout/kanban/KanbanBoard.svelte +1 -1
  108. package/dist/l0-layout/kanban/KanbanColumn.svelte +1 -1
  109. package/dist/n1-flow-canvas/FlowCanvas.svelte +50 -6
  110. package/dist/n1-flow-canvas/FlowCanvas.svelte.d.ts.map +1 -1
  111. package/dist/n1-flow-canvas/index.d.ts +2 -0
  112. package/dist/n1-flow-canvas/index.d.ts.map +1 -1
  113. package/dist/n1-flow-canvas/index.js +1 -0
  114. package/dist/n1-flow-canvas/pipeline-adapter.d.ts +37 -0
  115. package/dist/n1-flow-canvas/pipeline-adapter.d.ts.map +1 -0
  116. package/dist/n1-flow-canvas/pipeline-adapter.js +160 -0
  117. package/dist/n2-manifold-disk/ManifoldDisk.svelte +62 -35
  118. package/dist/n2-manifold-disk/ManifoldDisk.svelte.d.ts.map +1 -1
  119. package/dist/n4-adaptive-manifold/AdaptiveManifold.svelte +23 -19
  120. package/dist/n4-adaptive-manifold/AdaptiveManifold.svelte.d.ts.map +1 -1
  121. package/dist/n4-adaptive-manifold/types.d.ts +3 -0
  122. package/dist/n4-adaptive-manifold/types.d.ts.map +1 -1
  123. package/dist/p0-primitives/ThemeProvider.svelte +28 -7
  124. package/dist/p0-primitives/ThemeProvider.svelte.d.ts +5 -0
  125. package/dist/p0-primitives/ThemeProvider.svelte.d.ts.map +1 -1
  126. package/dist/p0-primitives/canvas-theme.d.ts +21 -1
  127. package/dist/p0-primitives/canvas-theme.d.ts.map +1 -1
  128. package/dist/p0-primitives/canvas-theme.js +78 -23
  129. package/dist/p0-primitives/debug.d.ts +6 -0
  130. package/dist/p0-primitives/debug.d.ts.map +1 -0
  131. package/dist/p0-primitives/debug.js +21 -0
  132. package/dist/p0-primitives/theme.d.ts.map +1 -1
  133. package/dist/p0-primitives/theme.js +11 -31
  134. package/dist/p0-primitives/tokens/ambient.css +76 -0
  135. package/dist/p0-primitives/tokens/tokens.css +124 -29
  136. package/dist/p0-primitives/utils/index.d.ts +2 -0
  137. package/dist/p0-primitives/utils/index.d.ts.map +1 -1
  138. package/dist/p0-primitives/utils/index.js +1 -0
  139. package/dist/p0-primitives/utils/reveal.d.ts +15 -0
  140. package/dist/p0-primitives/utils/reveal.d.ts.map +1 -0
  141. package/dist/p0-primitives/utils/reveal.js +29 -0
  142. package/dist/p0-primitives/utils/reveal.test.js +95 -0
  143. package/dist/s0-state/SyncStatus.svelte +1 -1
  144. package/dist/s0-state/index.d.ts +2 -1
  145. package/dist/s0-state/index.d.ts.map +1 -1
  146. package/dist/s0-state/index.js +2 -0
  147. package/dist/s0-state/modal-stack-store.svelte.d.ts +3 -3
  148. package/dist/s0-state/modal-stack-store.svelte.js +2 -2
  149. package/dist/spatial/ForceSimulation.svelte.js +1 -1
  150. package/dist/spatial/ParticleAssembleMark.svelte +285 -0
  151. package/dist/spatial/ParticleAssembleMark.svelte.d.ts +24 -0
  152. package/dist/spatial/ParticleAssembleMark.svelte.d.ts.map +1 -0
  153. package/dist/spatial/ZoneTiler.test.js +90 -0
  154. package/dist/spatial/index.js +1 -0
  155. package/dist/spatial/particle-assemble-math.d.ts +22 -0
  156. package/dist/spatial/particle-assemble-math.d.ts.map +1 -0
  157. package/dist/spatial/particle-assemble-math.js +26 -0
  158. package/dist/spatial/particle-assemble-math.test.js +56 -0
  159. package/dist/t0-transport/substrate.svelte.d.ts.map +1 -1
  160. package/dist/t0-transport/substrate.svelte.js +10 -4
  161. package/dist/u0-primitives/LockIndicator.svelte +16 -14
  162. package/dist/u0-primitives/VerticalToolbar.svelte +24 -21
  163. package/dist/u0-primitives/accordion/Accordion.svelte +8 -7
  164. package/dist/u0-primitives/animated-icon/AnimatedIcon.svelte +3 -3
  165. package/dist/u0-primitives/animated-icon/AnimatedIcon.test.js +82 -0
  166. package/dist/u0-primitives/avatar/Avatar.svelte +14 -14
  167. package/dist/u0-primitives/avatar/Avatar.test.js +81 -0
  168. package/dist/u0-primitives/badge/Badge.svelte +6 -4
  169. package/dist/u0-primitives/badge/ValidityBadge.svelte +4 -27
  170. package/dist/u0-primitives/button/Button.svelte +15 -12
  171. package/dist/u0-primitives/card/Card.svelte +37 -15
  172. package/dist/u0-primitives/card/Card.test.js +86 -0
  173. package/dist/u0-primitives/command-palette/CommandPalette.svelte +48 -43
  174. package/dist/u0-primitives/command-palette/CommandPalette.test.js +202 -0
  175. package/dist/u0-primitives/dropdown/Dropdown.svelte +20 -25
  176. package/dist/u0-primitives/grant-badge/GrantStatusBadge.svelte +2 -2
  177. package/dist/u0-primitives/index.d.ts +6 -0
  178. package/dist/u0-primitives/index.d.ts.map +1 -1
  179. package/dist/u0-primitives/index.js +8 -0
  180. package/dist/u0-primitives/input/Input.svelte +77 -24
  181. package/dist/u0-primitives/input/Input.svelte.d.ts +2 -10
  182. package/dist/u0-primitives/input/Input.svelte.d.ts.map +1 -1
  183. package/dist/u0-primitives/input/Input.test.js +81 -1
  184. package/dist/u0-primitives/live-dot/LiveDot.svelte +56 -0
  185. package/dist/u0-primitives/live-dot/LiveDot.svelte.d.ts +11 -0
  186. package/dist/u0-primitives/live-dot/LiveDot.svelte.d.ts.map +1 -0
  187. package/dist/u0-primitives/live-dot/LiveDot.test.js +41 -0
  188. package/dist/u0-primitives/live-dot/index.d.ts +3 -0
  189. package/dist/u0-primitives/live-dot/index.d.ts.map +1 -0
  190. package/dist/u0-primitives/live-dot/index.js +1 -0
  191. package/dist/u0-primitives/modal/Modal.svelte +22 -19
  192. package/dist/u0-primitives/modal/Modal.test.js +1 -1
  193. package/dist/u0-primitives/spinner/Spinner.svelte +11 -79
  194. package/dist/u0-primitives/spinner/Spinner.svelte.d.ts.map +1 -1
  195. package/dist/u0-primitives/steps/Steps.svelte +18 -19
  196. package/dist/u0-primitives/surface-state/SurfaceState.svelte +7 -7
  197. package/dist/u0-primitives/tabs/Tabs.svelte +13 -11
  198. package/dist/u0-primitives/theme-swatch-group/ThemeSwatchGroup.svelte +94 -0
  199. package/dist/u0-primitives/theme-swatch-group/ThemeSwatchGroup.svelte.d.ts +16 -0
  200. package/dist/u0-primitives/theme-swatch-group/ThemeSwatchGroup.svelte.d.ts.map +1 -0
  201. package/dist/u0-primitives/theme-swatch-group/ThemeSwatchGroup.test.js +48 -0
  202. package/dist/u0-primitives/theme-swatch-group/index.d.ts +3 -0
  203. package/dist/u0-primitives/theme-swatch-group/index.d.ts.map +1 -0
  204. package/dist/u0-primitives/theme-swatch-group/index.js +1 -0
  205. package/dist/u0-primitives/toggle/Toggle.svelte +10 -11
  206. package/dist/u0-primitives/tooltip/Tooltip.svelte +9 -9
  207. package/dist/u0-primitives/web-components/button-component.d.ts +5 -1
  208. package/dist/u0-primitives/web-components/button-component.d.ts.map +1 -1
  209. package/dist/u0-primitives/web-components/button-component.js +72 -33
  210. package/dist/u0-primitives/web-components/index.d.ts +3 -0
  211. package/dist/u0-primitives/web-components/index.d.ts.map +1 -0
  212. package/dist/u0-primitives/web-components/index.js +2 -0
  213. package/dist/u0-primitives/web-components/input-component.d.ts +5 -1
  214. package/dist/u0-primitives/web-components/input-component.d.ts.map +1 -1
  215. package/dist/u0-primitives/web-components/input-component.js +56 -39
  216. package/dist/u0-primitives/web-components/web-components.test.js +96 -0
  217. package/dist/u0-primitives/window-frame/WindowFrame.svelte +87 -0
  218. package/dist/u0-primitives/window-frame/WindowFrame.svelte.d.ts +10 -0
  219. package/dist/u0-primitives/window-frame/WindowFrame.svelte.d.ts.map +1 -0
  220. package/dist/u0-primitives/window-frame/WindowFrame.test.js +31 -0
  221. package/dist/u0-primitives/window-frame/index.d.ts +3 -0
  222. package/dist/u0-primitives/window-frame/index.d.ts.map +1 -0
  223. package/dist/u0-primitives/window-frame/index.js +1 -0
  224. package/dist/x0-enchanted-blocks/components/NodepadBlock.svelte +11 -2
  225. package/dist/x0-enchanted-blocks/components/NodepadBlock.svelte.d.ts.map +1 -1
  226. package/package.json +44 -28
  227. package/src/p0-primitives/tokens/ambient.css +76 -0
  228. package/src/p0-primitives/tokens/tokens.css +124 -29
  229. package/src/p0-primitives/tokens/tokens.json +42 -24
@@ -204,14 +204,14 @@
204
204
 
205
205
  .ds-dropdown-menu {
206
206
  position: absolute;
207
- top: calc(100% + var(--space-2));
207
+ top: calc(100% + 2px);
208
208
  background: var(--color-bg-panel-elevated);
209
209
  border: 1px solid var(--border-default);
210
- border-radius: var(--radius-md);
211
- box-shadow: var(--shadow-lg), 0 0 0 1px rgba(0,0,0,0.3);
212
- padding: var(--space-1);
210
+ border-radius: 0;
211
+ box-shadow: none;
212
+ padding: 0;
213
213
  z-index: 1000;
214
- animation: ds-scale-in var(--transition-fast) transform-origin;
214
+ animation: ds-fade-in var(--transition-fast) linear;
215
215
  }
216
216
 
217
217
  /* Alignments */
@@ -223,18 +223,22 @@
223
223
  display: flex;
224
224
  align-items: center;
225
225
  width: 100%;
226
- padding: var(--space-2) var(--space-3);
226
+ height: var(--ui-row-h);
227
+ padding: 0 var(--ui-pad-x);
227
228
  border: none;
229
+ border-bottom: 1px solid var(--border-default);
228
230
  background: transparent;
229
- border-radius: var(--radius-sm);
231
+ border-radius: 0;
230
232
  color: var(--color-text-primary);
231
233
  font-family: var(--font-sans);
232
- font-size: var(--text-sm);
234
+ font-size: var(--ui-font);
233
235
  text-align: left;
234
236
  cursor: pointer;
235
- transition: background var(--transition-fast), color var(--transition-fast);
237
+ transition: background var(--transition-fast) linear;
236
238
  }
237
239
 
240
+ .ds-dropdown-item:last-child { border-bottom: 0; }
241
+
238
242
  .ds-dropdown-item:hover,
239
243
  .ds-dropdown-item:focus {
240
244
  background: var(--color-bg-panel);
@@ -242,7 +246,8 @@
242
246
  }
243
247
 
244
248
  .ds-dropdown-item:focus-visible {
245
- background: var(--color-accent-muted); /* Suble brass focus */
249
+ background: var(--color-accent-subtle);
250
+ box-shadow: inset 2px 0 0 var(--color-accent);
246
251
  }
247
252
 
248
253
  .ds-dropdown-item:disabled {
@@ -284,25 +289,15 @@
284
289
  .ds-dropdown-shortcut {
285
290
  margin-left: var(--space-4);
286
291
  font-family: var(--font-mono);
287
- font-size: var(--text-xs);
292
+ font-size: var(--ui-label);
288
293
  color: var(--color-text-muted);
289
294
  background: var(--color-bg-app);
290
- padding: 2px 6px;
291
- border-radius: var(--radius-sm, 4px);
295
+ padding: 1px 5px;
292
296
  border: 1px solid var(--border-subtle);
293
297
  }
294
298
 
295
- @keyframes ds-scale-in {
296
- from { opacity: 0; transform: scale(0.95); }
297
- to { opacity: 1; transform: scale(1); }
298
- }
299
-
300
- .align-center {
301
- animation-name: ds-scale-in-center;
302
- }
303
-
304
- @keyframes ds-scale-in-center {
305
- from { opacity: 0; transform: translateX(-50%) scale(0.95); }
306
- to { opacity: 1; transform: translateX(-50%) scale(1); }
299
+ @keyframes ds-fade-in {
300
+ from { opacity: 0; }
301
+ to { opacity: 1; }
307
302
  }
308
303
  </style>
@@ -44,10 +44,10 @@
44
44
  display: inline-flex;
45
45
  align-items: center;
46
46
  gap: var(--space-1);
47
- font-family: var(--font-sans);
47
+ font-family: var(--font-mono);
48
48
  font-weight: 600;
49
49
  white-space: nowrap;
50
- border-radius: var(--radius-full);
50
+ border-radius: 0;
51
51
  }
52
52
 
53
53
  .ds-grant-status-dot {
@@ -3,6 +3,9 @@ export { default as Input } from './input/Input.svelte';
3
3
  export { default as Card } from './card/Card.svelte';
4
4
  export { default as Badge } from './badge/Badge.svelte';
5
5
  export { default as ValidityBadge } from './badge/ValidityBadge.svelte';
6
+ export { default as LiveDot } from './live-dot/LiveDot.svelte';
7
+ export { default as ThemeSwatchGroup } from './theme-swatch-group/ThemeSwatchGroup.svelte';
8
+ export { default as WindowFrame } from './window-frame/WindowFrame.svelte';
6
9
  export { default as Avatar } from './avatar/Avatar.svelte';
7
10
  export { default as Toggle } from './toggle/Toggle.svelte';
8
11
  export { default as Tooltip } from './tooltip/Tooltip.svelte';
@@ -26,4 +29,7 @@ export * from './rsvp/rsvp-utils';
26
29
  export { CommandPalette, commandStore } from './command-palette';
27
30
  export type { CommandSchema, CommandParameter, CommandResult, CommandContext, InvocationContext, CommandUIState, ActiveCommandSession, } from './command-palette';
28
31
  export { default as GrantStatusBadge } from './grant-badge/GrantStatusBadge.svelte';
32
+ export { default as AllayGauge } from './allay-gauge/AllayGauge.svelte';
33
+ export { KosButton } from './web-components/button-component';
34
+ export { KosInput } from './web-components/input-component';
29
35
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/u0-primitives/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAC9E,YAAY,EAAE,gBAAgB,EAAE,KAAK,IAAI,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxG,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAC9E,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGhF,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGlE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACjE,cAAc,mBAAmB,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjE,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,uCAAuC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/u0-primitives/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAC3F,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAC9E,YAAY,EAAE,gBAAgB,EAAE,KAAK,IAAI,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxG,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAC9E,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGhF,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGlE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACjE,cAAc,mBAAmB,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjE,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAGpF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAGxE,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC"}
@@ -4,6 +4,9 @@ export { default as Input } from './input/Input.svelte';
4
4
  export { default as Card } from './card/Card.svelte';
5
5
  export { default as Badge } from './badge/Badge.svelte';
6
6
  export { default as ValidityBadge } from './badge/ValidityBadge.svelte';
7
+ export { default as LiveDot } from './live-dot/LiveDot.svelte';
8
+ export { default as ThemeSwatchGroup } from './theme-swatch-group/ThemeSwatchGroup.svelte';
9
+ export { default as WindowFrame } from './window-frame/WindowFrame.svelte';
7
10
  export { default as Avatar } from './avatar/Avatar.svelte';
8
11
  export { default as Toggle } from './toggle/Toggle.svelte';
9
12
  export { default as Tooltip } from './tooltip/Tooltip.svelte';
@@ -24,3 +27,8 @@ export * from './rsvp/rsvp-utils';
24
27
  export { CommandPalette, commandStore } from './command-palette';
25
28
  // Grant Status Badge — Grant lifecycle status indicator
26
29
  export { default as GrantStatusBadge } from './grant-badge/GrantStatusBadge.svelte';
30
+ // Allay Gauge — Allay-pipeline stage + confidence indicator
31
+ export { default as AllayGauge } from './allay-gauge/AllayGauge.svelte';
32
+ // Web Component wrappers for non-Svelte consumers
33
+ export { KosButton } from './web-components/button-component';
34
+ export { KosInput } from './web-components/input-component';
@@ -1,12 +1,11 @@
1
1
  <script lang="ts">
2
+ import { onDestroy } from 'svelte';
3
+ import { EditorState } from '@codemirror/state';
2
4
  import type { Snippet } from 'svelte';
3
-
4
- export interface AutocompleteResult {
5
- completions: Array<{ label: string; type?: string; detail?: string }>;
6
- }
5
+ import type { Completion, CompletionSource } from '../../editor/extensions/types';
7
6
 
8
7
  export interface AutocompleteConfig {
9
- source: { complete: (query: string) => Promise<AutocompleteResult> | AutocompleteResult };
8
+ source: CompletionSource;
10
9
  maxVisible?: number;
11
10
  minChars?: number;
12
11
  }
@@ -25,6 +24,8 @@
25
24
  autocomplete?: AutocompleteConfig;
26
25
  }
27
26
 
27
+ type CompletionItem = Pick<Completion, 'label' | 'type' | 'detail'>;
28
+
28
29
  let {
29
30
  value = $bindable(''),
30
31
  type = 'text',
@@ -41,33 +42,84 @@
41
42
 
42
43
  let isFocused = $state(false);
43
44
  let showPassword = $state(false);
44
- let completions = $state<Array<{ label: string; type?: string; detail?: string }>>([]);
45
+ let completions = $state<CompletionItem[]>([]);
45
46
  let showCompletions = $state(false);
46
47
  let selectedIndex = $state(0);
48
+ let fetchSeq = $state(0);
49
+ let completionFrom = $state(0);
50
+ let completionTo = $state(0);
51
+
52
+ onDestroy(() => {
53
+ fetchSeq += 1;
54
+ });
47
55
 
48
56
  let currentType = $derived(type === 'password' && showPassword ? 'text' : type);
49
57
  let maxVisible = $derived(autocomplete?.maxVisible ?? 8);
50
58
  let minChars = $derived(autocomplete?.minChars ?? 1);
51
59
 
60
+ function createCompletionContext(query: string): Parameters<CompletionSource>[0] {
61
+ const state = EditorState.create({ doc: query });
62
+
63
+ return {
64
+ state,
65
+ pos: query.length,
66
+ explicit: true,
67
+ matchBefore: (regexp) => {
68
+ const match = query.match(regexp);
69
+
70
+ if (!match || match.index === undefined) {
71
+ return null;
72
+ }
73
+
74
+ return {
75
+ from: match.index,
76
+ to: match.index + match[0].length,
77
+ text: match[0],
78
+ };
79
+ },
80
+ } as Parameters<CompletionSource>[0];
81
+ }
82
+
52
83
  async function fetchCompletions(query: string) {
53
- if (!autocomplete || query.length < minChars) {
84
+ if (!autocomplete || disabled || query.length < minChars) {
54
85
  completions = [];
55
86
  showCompletions = false;
56
87
  return;
57
88
  }
58
- const result = await autocomplete.source.complete(query);
59
- completions = result.completions.slice(0, maxVisible);
60
- selectedIndex = 0;
61
- showCompletions = completions.length > 0;
89
+
90
+ const seq = fetchSeq;
91
+
92
+ try {
93
+ const result = await autocomplete.source(createCompletionContext(query));
94
+
95
+ if (seq !== fetchSeq) return;
96
+
97
+ const options = result?.options ?? [];
98
+
99
+ completionFrom = result?.from ?? 0;
100
+ completionTo = result?.to ?? query.length;
101
+
102
+ completions = options.slice(0, maxVisible).map((completion) => ({
103
+ label: completion.label,
104
+ type: completion.type,
105
+ detail: completion.detail,
106
+ }));
107
+ selectedIndex = 0;
108
+ showCompletions = completions.length > 0;
109
+ } catch {
110
+ if (seq !== fetchSeq) return;
111
+ completions = [];
112
+ showCompletions = false;
113
+ }
62
114
  }
63
115
 
64
- function applyCompletion(completion: { label: string }) {
65
- value = completion.label;
116
+ function applyCompletion(completion: CompletionItem) {
117
+ value = value.slice(0, completionFrom) + completion.label + value.slice(completionTo);
66
118
  completions = [];
67
119
  showCompletions = false;
68
120
  }
69
121
 
70
- function handleCompletionKeydown(e: KeyboardEvent, completion: { label: string }) {
122
+ function handleCompletionKeydown(e: KeyboardEvent, completion: CompletionItem) {
71
123
  if (e.key === 'Enter' || e.key === ' ') {
72
124
  e.preventDefault();
73
125
  applyCompletion(completion);
@@ -138,6 +190,7 @@
138
190
  aria-invalid={error ? 'true' : undefined}
139
191
  aria-disabled={disabled ? 'true' : undefined}
140
192
  aria-autocomplete={autocomplete ? 'list' : undefined}
193
+ aria-controls={showCompletions ? 'autocomplete-list' : undefined}
141
194
  aria-expanded={showCompletions ? 'true' : 'false'}
142
195
  aria-activedescendant={showCompletions ? `autocomplete-option-${selectedIndex}` : undefined}
143
196
  autocomplete="off"
@@ -250,14 +303,14 @@
250
303
  .ds-input-element {
251
304
  flex: 1;
252
305
  width: 100%;
253
- height: 2.25rem;
254
- padding: 0 var(--space-3);
306
+ height: var(--ui-control-h);
307
+ padding: 0 var(--ui-pad-x);
255
308
  background: transparent;
256
309
  border: none;
257
310
  outline: none;
258
311
  color: var(--color-text-primary);
259
312
  font-family: var(--font-sans);
260
- font-size: var(--text-sm);
313
+ font-size: var(--ui-font);
261
314
  }
262
315
 
263
316
  .ds-input-wrapper.has-leading .ds-input-element {
@@ -325,12 +378,12 @@
325
378
  bottom: 0;
326
379
  left: 0;
327
380
  width: 100%;
328
- height: 1px;
381
+ height: 2px;
329
382
  background: var(--color-accent);
330
383
  transform: scaleX(0);
331
384
  transform-origin: center;
332
385
  transition: transform var(--transition-normal);
333
- box-shadow: 0 -1px 4px var(--color-accent-glow);
386
+ /* crisp accent live-edge on focus — no glow halo (depth by edge, not blur) */
334
387
  }
335
388
 
336
389
  .ds-input-wrapper.is-focused .ds-input-glow {
@@ -377,8 +430,9 @@
377
430
 
378
431
  .ds-input-autocomplete__item:hover,
379
432
  .ds-input-autocomplete__item.selected {
380
- background: var(--color-accent, #b87333);
381
- color: #fff;
433
+ background: var(--color-accent-subtle);
434
+ color: var(--color-text-primary);
435
+ box-shadow: inset 2px 0 0 var(--color-accent);
382
436
  }
383
437
 
384
438
  .ds-input-autocomplete__type {
@@ -394,8 +448,7 @@
394
448
 
395
449
  .ds-input-autocomplete__item:hover .ds-input-autocomplete__type,
396
450
  .ds-input-autocomplete__item.selected .ds-input-autocomplete__type {
397
- background: rgba(255, 255, 255, 0.15);
398
- color: rgba(255, 255, 255, 0.8);
451
+ color: var(--color-text-secondary);
399
452
  }
400
453
 
401
454
  .ds-input-autocomplete__label {
@@ -414,6 +467,6 @@
414
467
 
415
468
  .ds-input-autocomplete__item:hover .ds-input-autocomplete__detail,
416
469
  .ds-input-autocomplete__item.selected .ds-input-autocomplete__detail {
417
- color: rgba(255, 255, 255, 0.7);
470
+ color: var(--color-text-tertiary);
418
471
  }
419
472
  </style>
@@ -1,15 +1,7 @@
1
1
  import type { Snippet } from 'svelte';
2
- export interface AutocompleteResult {
3
- completions: Array<{
4
- label: string;
5
- type?: string;
6
- detail?: string;
7
- }>;
8
- }
2
+ import type { CompletionSource } from '../../editor/extensions/types';
9
3
  export interface AutocompleteConfig {
10
- source: {
11
- complete: (query: string) => Promise<AutocompleteResult> | AutocompleteResult;
12
- };
4
+ source: CompletionSource;
13
5
  maxVisible?: number;
14
6
  minChars?: number;
15
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Input.svelte.d.ts","sourceRoot":"","sources":["../../../src/u0-primitives/input/Input.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGpC,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE;QAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAA;KAAE,CAAC;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAsJH,QAAA,MAAM,KAAK,gDAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Input.svelte.d.ts","sourceRoot":"","sources":["../../../src/u0-primitives/input/Input.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAc,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGhF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AA8MH,QAAA,MAAM,KAAK,gDAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
@@ -1,6 +1,18 @@
1
1
  import { afterEach, describe, it, expect } from 'vitest';
2
- import { cleanup, render } from '@testing-library/svelte';
2
+ import { cleanup, render, fireEvent, waitFor } from '@testing-library/svelte';
3
3
  import Input from './Input.svelte';
4
+ function createSource(completions) {
5
+ return async (context) => {
6
+ const match = context.matchBefore(/\w+$/);
7
+ if (!match)
8
+ return null;
9
+ return {
10
+ from: match.from,
11
+ to: match.to,
12
+ options: completions,
13
+ };
14
+ };
15
+ }
4
16
  describe('Input', () => {
5
17
  afterEach(() => cleanup());
6
18
  it('renders an <input> element', () => {
@@ -61,4 +73,72 @@ describe('Input', () => {
61
73
  const { container } = render(Input, {});
62
74
  expect(container.querySelector('input')?.getAttribute('aria-invalid')).toBeNull();
63
75
  });
76
+ it('does not render autocomplete controls without autocomplete prop', () => {
77
+ const { container } = render(Input);
78
+ expect(container.querySelector('[aria-autocomplete="list"]')).toBeNull();
79
+ expect(container.querySelector('.ds-input-autocomplete')).toBeNull();
80
+ });
81
+ it('renders autocomplete suggestions when autocomplete prop is provided', async () => {
82
+ const source = createSource([
83
+ { label: 'apple', type: 'word' },
84
+ { label: 'application', type: 'word', detail: 'common' },
85
+ ]);
86
+ const { container } = render(Input, { autocomplete: { source } });
87
+ const input = container.querySelector('input');
88
+ await fireEvent.input(input, { target: { value: 'app' } });
89
+ await waitFor(() => {
90
+ expect(container.querySelector('.ds-input-autocomplete')).not.toBeNull();
91
+ });
92
+ expect(container.querySelectorAll('[role="option"]').length).toBe(2);
93
+ expect(container.querySelector('.ds-input-autocomplete__label')?.textContent).toBe('apple');
94
+ expect(container.querySelector('.ds-input-autocomplete__detail')?.textContent).toBe('common');
95
+ });
96
+ it('applies the selected autocomplete suggestion with Enter', async () => {
97
+ const source = createSource([
98
+ { label: 'apple', type: 'word' },
99
+ { label: 'application', type: 'word' },
100
+ ]);
101
+ const { container } = render(Input, { autocomplete: { source } });
102
+ const input = container.querySelector('input');
103
+ await fireEvent.input(input, { target: { value: 'app' } });
104
+ await waitFor(() => {
105
+ expect(container.querySelector('.ds-input-autocomplete')).not.toBeNull();
106
+ });
107
+ await fireEvent.keyDown(input, { key: 'ArrowDown' });
108
+ await fireEvent.keyDown(input, { key: 'Enter' });
109
+ expect(input.value).toBe('application');
110
+ expect(container.querySelector('.ds-input-autocomplete')).toBeNull();
111
+ });
112
+ it('dismisses autocomplete suggestions with Escape', async () => {
113
+ const source = createSource([{ label: 'apple', type: 'word' }]);
114
+ const { container } = render(Input, { autocomplete: { source } });
115
+ const input = container.querySelector('input');
116
+ await fireEvent.input(input, { target: { value: 'app' } });
117
+ await waitFor(() => {
118
+ expect(container.querySelector('.ds-input-autocomplete')).not.toBeNull();
119
+ });
120
+ await fireEvent.keyDown(input, { key: 'Escape' });
121
+ expect(container.querySelector('.ds-input-autocomplete')).toBeNull();
122
+ });
123
+ it('replaces only the current token, preserving prefix and suffix', async () => {
124
+ const source = createSource([
125
+ { label: 'project', type: 'word' },
126
+ ]);
127
+ const { container } = render(Input, { autocomplete: { source } });
128
+ const input = container.querySelector('input');
129
+ await fireEvent.input(input, { target: { value: 'create a p' } });
130
+ await waitFor(() => {
131
+ expect(container.querySelector('.ds-input-autocomplete')).not.toBeNull();
132
+ });
133
+ await fireEvent.keyDown(input, { key: 'Enter' });
134
+ expect(input.value).toBe('create a project');
135
+ expect(container.querySelector('.ds-input-autocomplete')).toBeNull();
136
+ });
137
+ it('respects minChars before fetching autocomplete suggestions', async () => {
138
+ const source = createSource([{ label: 'apple', type: 'word' }]);
139
+ const { container } = render(Input, { autocomplete: { source, minChars: 3 } });
140
+ const input = container.querySelector('input');
141
+ await fireEvent.input(input, { target: { value: 'ap' } });
142
+ expect(container.querySelector('.ds-input-autocomplete')).toBeNull();
143
+ });
64
144
  });
@@ -0,0 +1,56 @@
1
+ <script lang="ts">
2
+ export interface Props {
3
+ variant?: 'cleared' | 'blocked' | 'pending' | 'degraded';
4
+ size?: 'sm' | 'md' | 'lg';
5
+ pulse?: boolean;
6
+ class?: string;
7
+ 'aria-label'?: string;
8
+ }
9
+
10
+ let {
11
+ variant = 'cleared',
12
+ size = 'md',
13
+ pulse = true,
14
+ class: className = '',
15
+ 'aria-label': ariaLabel
16
+ }: Props = $props();
17
+ </script>
18
+
19
+ <span
20
+ class="ds-live-dot variant-{variant} size-{size} {className}"
21
+ class:is-pulsing={pulse}
22
+ role="status"
23
+ aria-label={ariaLabel ?? variant}
24
+ ></span>
25
+
26
+ <style>
27
+ .ds-live-dot {
28
+ display: inline-block;
29
+ flex-shrink: 0;
30
+ border-radius: var(--radius-full);
31
+ }
32
+
33
+ .size-sm { width: 0.375rem; height: 0.375rem; }
34
+ .size-md { width: 0.5rem; height: 0.5rem; }
35
+ .size-lg { width: 0.625rem; height: 0.625rem; }
36
+
37
+ .variant-cleared { background: var(--epistemic-cleared); }
38
+ .variant-blocked { background: var(--epistemic-blocked); }
39
+ .variant-pending { background: var(--epistemic-pending); }
40
+ .variant-degraded { background: var(--epistemic-degraded); }
41
+
42
+ .is-pulsing.variant-cleared { animation: ds-live-dot-pulse 2s ease-out infinite; --pulse-glow: var(--epistemic-cleared-glow); }
43
+ .is-pulsing.variant-blocked { animation: ds-live-dot-pulse 2s ease-out infinite; --pulse-glow: var(--epistemic-blocked-glow); }
44
+ .is-pulsing.variant-pending { animation: ds-live-dot-pulse 2s ease-out infinite; --pulse-glow: var(--epistemic-pending-glow); }
45
+ .is-pulsing.variant-degraded { animation: ds-live-dot-pulse 2s ease-out infinite; --pulse-glow: var(--epistemic-degraded-glow); }
46
+
47
+ @keyframes ds-live-dot-pulse {
48
+ 0% { box-shadow: 0 0 0 0 var(--pulse-glow); }
49
+ 70% { box-shadow: 0 0 0 6px transparent; }
50
+ 100% { box-shadow: 0 0 0 0 transparent; }
51
+ }
52
+
53
+ @media (prefers-reduced-motion: reduce) {
54
+ .is-pulsing { animation: none; }
55
+ }
56
+ </style>
@@ -0,0 +1,11 @@
1
+ export interface Props {
2
+ variant?: 'cleared' | 'blocked' | 'pending' | 'degraded';
3
+ size?: 'sm' | 'md' | 'lg';
4
+ pulse?: boolean;
5
+ class?: string;
6
+ 'aria-label'?: string;
7
+ }
8
+ declare const LiveDot: import("svelte").Component<Props, {}, "">;
9
+ type LiveDot = ReturnType<typeof LiveDot>;
10
+ export default LiveDot;
11
+ //# sourceMappingURL=LiveDot.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveDot.svelte.d.ts","sourceRoot":"","sources":["../../../src/u0-primitives/live-dot/LiveDot.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,WAAW,KAAK;IACpB,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IACzD,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAmBH,QAAA,MAAM,OAAO,2CAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { afterEach, describe, it, expect } from 'vitest';
2
+ import { cleanup, render, screen } from '@testing-library/svelte';
3
+ import LiveDot from './LiveDot.svelte';
4
+ describe('LiveDot', () => {
5
+ afterEach(() => cleanup());
6
+ it('renders with role="status"', () => {
7
+ render(LiveDot);
8
+ expect(screen.getByRole('status')).toBeDefined();
9
+ });
10
+ it('defaults to the cleared variant', () => {
11
+ const { container } = render(LiveDot);
12
+ expect(container.querySelector('.variant-cleared')).not.toBeNull();
13
+ });
14
+ it('applies each variant class', () => {
15
+ for (const variant of ['cleared', 'blocked', 'pending', 'degraded']) {
16
+ const { container, unmount } = render(LiveDot, { variant });
17
+ expect(container.querySelector(`.variant-${variant}`)).not.toBeNull();
18
+ unmount();
19
+ }
20
+ });
21
+ it('applies size class', () => {
22
+ const { container } = render(LiveDot, { size: 'lg' });
23
+ expect(container.querySelector('.size-lg')).not.toBeNull();
24
+ });
25
+ it('pulses by default', () => {
26
+ const { container } = render(LiveDot);
27
+ expect(container.querySelector('.is-pulsing')).not.toBeNull();
28
+ });
29
+ it('does not pulse when pulse is false', () => {
30
+ const { container } = render(LiveDot, { pulse: false });
31
+ expect(container.querySelector('.is-pulsing')).toBeNull();
32
+ });
33
+ it('falls back to the variant name as aria-label', () => {
34
+ render(LiveDot, { variant: 'blocked' });
35
+ expect(screen.getByRole('status').getAttribute('aria-label')).toBe('blocked');
36
+ });
37
+ it('uses an explicit aria-label when provided', () => {
38
+ render(LiveDot, { 'aria-label': 'Connection live' });
39
+ expect(screen.getByRole('status').getAttribute('aria-label')).toBe('Connection live');
40
+ });
41
+ });
@@ -0,0 +1,3 @@
1
+ export { default as LiveDot } from './LiveDot.svelte';
2
+ export type { Props } from './LiveDot.svelte';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/u0-primitives/live-dot/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ export { default as LiveDot } from './LiveDot.svelte';