@kitn.ai/ui 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-tooling/construct/public.d.ts +15 -0
  3. package/dist/agent-tooling/construct/schema.d.ts +111 -0
  4. package/dist/construct-cli.es.js +3 -3
  5. package/dist/construct.d.ts +5 -0
  6. package/dist/construct.js +327 -0
  7. package/dist/core-C8fzo39E.js +1 -12
  8. package/dist/engine-javascript-C1x7zo1_.js +1 -141
  9. package/dist/mcp.es.js +1 -1
  10. package/package.json +16 -16
  11. package/bin/route.test.js +0 -58
  12. package/src/agent-tooling/README.md +0 -192
  13. package/src/agent-tooling/archetypes.ts +0 -205
  14. package/src/agent-tooling/catalog/README.md +0 -676
  15. package/src/agent-tooling/catalog/catalog-types.ts +0 -231
  16. package/src/agent-tooling/catalog/fabrications.ts +0 -96
  17. package/src/agent-tooling/catalog/invariants.ts +0 -284
  18. package/src/agent-tooling/catalog/labs-titles.ts +0 -114
  19. package/src/agent-tooling/catalog/scenarios.ts +0 -87
  20. package/src/agent-tooling/catalog/surfaces.ts +0 -347
  21. package/src/agent-tooling/construct/cli-entry.ts +0 -8
  22. package/src/agent-tooling/construct/cli.ts +0 -147
  23. package/src/agent-tooling/construct/codegen.ts +0 -1635
  24. package/src/agent-tooling/construct/construct.v1.schema.json +0 -319
  25. package/src/agent-tooling/construct/dev.ts +0 -148
  26. package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +0 -7
  27. package/src/agent-tooling/construct/fixtures/ops-console.construct.json +0 -44
  28. package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +0 -32
  29. package/src/agent-tooling/construct/schema.ts +0 -452
  30. package/src/agent-tooling/integrations/anthropic.ts +0 -442
  31. package/src/agent-tooling/integrations/cloudflare.ts +0 -218
  32. package/src/agent-tooling/integrations/langgraph.ts +0 -133
  33. package/src/agent-tooling/integrations/mastra.ts +0 -182
  34. package/src/agent-tooling/integrations/mock.ts +0 -148
  35. package/src/agent-tooling/integrations/ollama.ts +0 -97
  36. package/src/agent-tooling/integrations/openai.ts +0 -95
  37. package/src/agent-tooling/integrations/openrouter.ts +0 -82
  38. package/src/agent-tooling/integrations/pi.ts +0 -176
  39. package/src/agent-tooling/integrations/pydantic-ai.ts +0 -108
  40. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +0 -398
  41. package/src/agent-tooling/mcp/css-raw.d.ts +0 -12
  42. package/src/agent-tooling/mcp/manifest.ts +0 -422
  43. package/src/agent-tooling/mcp/server.ts +0 -116
  44. package/src/agent-tooling/mcp/stdio.ts +0 -18
  45. package/src/agent-tooling/mcp/tools/construct.ts +0 -130
  46. package/src/agent-tooling/mcp/tools/debug.ts +0 -621
  47. package/src/agent-tooling/mcp/tools/reference.ts +0 -980
  48. package/src/agent-tooling/mcp/tools/scaffold.ts +0 -6708
  49. package/src/agent-tooling/mcp/tools/theme.ts +0 -456
  50. package/src/agent-tooling/mcp/tools/types.ts +0 -14
  51. package/src/agent-tooling/mcp/validate-args.ts +0 -141
  52. package/src/agent-tooling/recipes/composed-thread.ts +0 -714
  53. package/src/agent-tooling/recipes/index.ts +0 -22
  54. package/src/agent-tooling/recipes/types.ts +0 -32
  55. package/src/agent-tooling/registry.ts +0 -132
  56. package/src/agent-tooling/route-emit.ts +0 -305
  57. package/src/agent-tooling/types.ts +0 -390
  58. package/src/components/artifact-card.tsx +0 -120
  59. package/src/components/artifact.tsx +0 -914
  60. package/src/components/attachment-types.ts +0 -66
  61. package/src/components/attachments.tsx +0 -536
  62. package/src/components/audio-visualizer/audio-visualizer.voice-fixture.ts +0 -257
  63. package/src/components/audio-visualizer/aurora.glsl.ts +0 -330
  64. package/src/components/audio-visualizer/fit-scale.ts +0 -112
  65. package/src/components/audio-visualizer/index.tsx +0 -528
  66. package/src/components/audio-visualizer/labs/lab-choreography.ts +0 -187
  67. package/src/components/audio-visualizer/labs/lab-shaders.ts +0 -363
  68. package/src/components/audio-visualizer/labs/lab-visualizer.tsx +0 -102
  69. package/src/components/audio-visualizer/shader-canvas.tsx +0 -876
  70. package/src/components/audio-visualizer/sizes.ts +0 -54
  71. package/src/components/audio-visualizer/variant-aurora.tsx +0 -305
  72. package/src/components/audio-visualizer/variant-bar.tsx +0 -175
  73. package/src/components/audio-visualizer/variant-custom.tsx +0 -344
  74. package/src/components/audio-visualizer/variant-grid.tsx +0 -175
  75. package/src/components/audio-visualizer/variant-radial.tsx +0 -163
  76. package/src/components/audio-visualizer/variant-wave.tsx +0 -130
  77. package/src/components/audio-visualizer/wave.glsl.ts +0 -130
  78. package/src/components/card-fallback.tsx +0 -60
  79. package/src/components/card-renderer.tsx +0 -220
  80. package/src/components/card.tsx +0 -212
  81. package/src/components/chain-of-thought.tsx +0 -348
  82. package/src/components/chat-container.tsx +0 -89
  83. package/src/components/chat-scope-picker.tsx +0 -57
  84. package/src/components/chat-thread.tsx +0 -1014
  85. package/src/components/checkpoint.tsx +0 -88
  86. package/src/components/choice-card.tsx +0 -743
  87. package/src/components/coachmark.tsx +0 -249
  88. package/src/components/code-block.tsx +0 -181
  89. package/src/components/composer-dom.ts +0 -159
  90. package/src/components/composer-highlight.ts +0 -242
  91. package/src/components/composer-history.ts +0 -82
  92. package/src/components/composer.tsx +0 -1075
  93. package/src/components/confirm-card.tsx +0 -402
  94. package/src/components/context.tsx +0 -377
  95. package/src/components/conversation-item.tsx +0 -241
  96. package/src/components/conversation-list.tsx +0 -429
  97. package/src/components/conversation-panel.tsx +0 -118
  98. package/src/components/dismissed-stub.tsx +0 -80
  99. package/src/components/embed.tsx +0 -200
  100. package/src/components/empty.tsx +0 -177
  101. package/src/components/feedback-bar.tsx +0 -166
  102. package/src/components/file-tree.tsx +0 -530
  103. package/src/components/file-upload.tsx +0 -167
  104. package/src/components/form-widgets.tsx +0 -525
  105. package/src/components/form.tsx +0 -1296
  106. package/src/components/home-panel.tsx +0 -159
  107. package/src/components/image.tsx +0 -65
  108. package/src/components/link-preview.tsx +0 -195
  109. package/src/components/loader.tsx +0 -367
  110. package/src/components/markdown.tsx +0 -162
  111. package/src/components/message-skills.tsx +0 -40
  112. package/src/components/message.tsx +0 -765
  113. package/src/components/model-switcher.tsx +0 -132
  114. package/src/components/prompt-input.tsx +0 -188
  115. package/src/components/prompt-suggestion.tsx +0 -150
  116. package/src/components/reasoning.tsx +0 -293
  117. package/src/components/response-compare-types.ts +0 -152
  118. package/src/components/response-compare.tsx +0 -455
  119. package/src/components/response-stream.tsx +0 -109
  120. package/src/components/screen.tsx +0 -181
  121. package/src/components/scroll-button.tsx +0 -93
  122. package/src/components/source.tsx +0 -192
  123. package/src/components/tasks-card.tsx +0 -801
  124. package/src/components/text-shimmer.tsx +0 -37
  125. package/src/components/thinking-bar.tsx +0 -50
  126. package/src/components/thread.tsx +0 -228
  127. package/src/components/toast.tsx +0 -503
  128. package/src/components/tool-classify.ts +0 -26
  129. package/src/components/tool-types.ts +0 -49
  130. package/src/components/tool.tsx +0 -190
  131. package/src/components/use-card-resolution.ts +0 -44
  132. package/src/components/voice-input.tsx +0 -222
  133. package/src/components/voice-output.tsx +0 -242
  134. package/src/components/widget-tab-bar.tsx +0 -73
  135. package/src/components/workspace-shell.tsx +0 -285
  136. package/src/diagnostics/hook.ts +0 -352
  137. package/src/diagnostics/index.ts +0 -82
  138. package/src/diagnostics/report-request.ts +0 -296
  139. package/src/elements/agent-card.tsx +0 -67
  140. package/src/elements/artifact.tsx +0 -194
  141. package/src/elements/attachments.tsx +0 -140
  142. package/src/elements/audio-visualizer.tsx +0 -227
  143. package/src/elements/autoloader.ts +0 -89
  144. package/src/elements/avatar.tsx +0 -33
  145. package/src/elements/badge.tsx +0 -32
  146. package/src/elements/button.tsx +0 -149
  147. package/src/elements/card.tsx +0 -133
  148. package/src/elements/cards.tsx +0 -266
  149. package/src/elements/chain-of-thought.tsx +0 -141
  150. package/src/elements/chat-scope-picker.tsx +0 -65
  151. package/src/elements/chat-types.ts +0 -102
  152. package/src/elements/chat-workspace.tsx +0 -188
  153. package/src/elements/chat.tsx +0 -304
  154. package/src/elements/checkbox-group.tsx +0 -164
  155. package/src/elements/checkbox.tsx +0 -134
  156. package/src/elements/checkpoint.tsx +0 -47
  157. package/src/elements/choice.tsx +0 -100
  158. package/src/elements/coachmark.tsx +0 -90
  159. package/src/elements/code-block.tsx +0 -60
  160. package/src/elements/command.tsx +0 -197
  161. package/src/elements/compare.tsx +0 -111
  162. package/src/elements/compiled.css +0 -2
  163. package/src/elements/composer.tsx +0 -162
  164. package/src/elements/confirm-card.tsx +0 -76
  165. package/src/elements/context-meter.tsx +0 -107
  166. package/src/elements/conversation-item.tsx +0 -120
  167. package/src/elements/conversation-list.tsx +0 -203
  168. package/src/elements/css.ts +0 -5
  169. package/src/elements/default-input.tsx +0 -392
  170. package/src/elements/define-entry.ts +0 -12
  171. package/src/elements/define.tsx +0 -563
  172. package/src/elements/diagnostic-events.ts +0 -114
  173. package/src/elements/dialog.tsx +0 -145
  174. package/src/elements/disclosure.ts +0 -95
  175. package/src/elements/dock.tsx +0 -215
  176. package/src/elements/dropdown.tsx +0 -123
  177. package/src/elements/editable-label.tsx +0 -140
  178. package/src/elements/element-data-types.ts +0 -152
  179. package/src/elements/element-diagnostics.ts +0 -392
  180. package/src/elements/element-manifest.json +0 -354
  181. package/src/elements/element-nonscalar.json +0 -187
  182. package/src/elements/element-types.d.ts +0 -4353
  183. package/src/elements/embed.tsx +0 -35
  184. package/src/elements/empty.tsx +0 -29
  185. package/src/elements/feedback-bar.tsx +0 -66
  186. package/src/elements/file-tree.tsx +0 -62
  187. package/src/elements/file-upload.tsx +0 -44
  188. package/src/elements/form.tsx +0 -94
  189. package/src/elements/hover-card.tsx +0 -80
  190. package/src/elements/icon.tsx +0 -41
  191. package/src/elements/image.tsx +0 -32
  192. package/src/elements/input.tsx +0 -492
  193. package/src/elements/kbd.tsx +0 -45
  194. package/src/elements/link-preview.tsx +0 -34
  195. package/src/elements/loader.tsx +0 -25
  196. package/src/elements/markdown.tsx +0 -38
  197. package/src/elements/menu.tsx +0 -241
  198. package/src/elements/message-skills.tsx +0 -83
  199. package/src/elements/message.tsx +0 -361
  200. package/src/elements/model-switcher.tsx +0 -121
  201. package/src/elements/nav.tsx +0 -87
  202. package/src/elements/notice.tsx +0 -53
  203. package/src/elements/pane-grid.tsx +0 -111
  204. package/src/elements/pane-group.tsx +0 -119
  205. package/src/elements/pane.tsx +0 -129
  206. package/src/elements/popover.tsx +0 -81
  207. package/src/elements/progress-bar.tsx +0 -39
  208. package/src/elements/prompt-dock.tsx +0 -82
  209. package/src/elements/prompt-input.tsx +0 -240
  210. package/src/elements/prompt-suggestions.tsx +0 -113
  211. package/src/elements/radio-group.tsx +0 -129
  212. package/src/elements/reasoning.tsx +0 -71
  213. package/src/elements/register-impl.ts +0 -148
  214. package/src/elements/register.ts +0 -76
  215. package/src/elements/remote.tsx +0 -225
  216. package/src/elements/resizable.globals.d.ts +0 -36
  217. package/src/elements/resizable.tsx +0 -704
  218. package/src/elements/response-stream.tsx +0 -40
  219. package/src/elements/screen.tsx +0 -90
  220. package/src/elements/scroll-area.tsx +0 -33
  221. package/src/elements/scroll-button.tsx +0 -179
  222. package/src/elements/search.tsx +0 -185
  223. package/src/elements/segmented.tsx +0 -129
  224. package/src/elements/select.tsx +0 -165
  225. package/src/elements/separator.tsx +0 -36
  226. package/src/elements/setting-item.tsx +0 -50
  227. package/src/elements/settings-group.tsx +0 -37
  228. package/src/elements/skeleton.tsx +0 -45
  229. package/src/elements/slider.tsx +0 -171
  230. package/src/elements/slot-text.ts +0 -73
  231. package/src/elements/slots.ts +0 -787
  232. package/src/elements/source.tsx +0 -126
  233. package/src/elements/status.tsx +0 -42
  234. package/src/elements/styles.css +0 -328
  235. package/src/elements/switch.tsx +0 -118
  236. package/src/elements/tabs.tsx +0 -95
  237. package/src/elements/tasks.tsx +0 -103
  238. package/src/elements/text-shimmer.tsx +0 -28
  239. package/src/elements/thinking-bar.tsx +0 -43
  240. package/src/elements/thread.tsx +0 -139
  241. package/src/elements/toast.tsx +0 -106
  242. package/src/elements/tool.tsx +0 -78
  243. package/src/elements/tooltip.tsx +0 -85
  244. package/src/elements/validate-messages.ts +0 -76
  245. package/src/elements/voice-input.tsx +0 -100
  246. package/src/elements/voice-output.tsx +0 -82
  247. package/src/index.ts +0 -430
  248. package/src/primitives/audio-bands.ts +0 -174
  249. package/src/primitives/card-component-types.ts +0 -63
  250. package/src/primitives/card-contract.ts +0 -80
  251. package/src/primitives/card-data-types.ts +0 -361
  252. package/src/primitives/card-host.tsx +0 -37
  253. package/src/primitives/card-recovery.ts +0 -160
  254. package/src/primitives/card-registry.tsx +0 -78
  255. package/src/primitives/card-resolution.ts +0 -36
  256. package/src/primitives/card-routing.ts +0 -85
  257. package/src/primitives/card-schemas/artifact.schema.json +0 -92
  258. package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
  259. package/src/primitives/card-schemas/card-event.schema.json +0 -12
  260. package/src/primitives/card-schemas/choice.schema.json +0 -75
  261. package/src/primitives/card-schemas/confirm.schema.json +0 -65
  262. package/src/primitives/card-schemas/embed.schema.json +0 -63
  263. package/src/primitives/card-schemas/form.result.schema.json +0 -7
  264. package/src/primitives/card-schemas/form.schema.json +0 -53
  265. package/src/primitives/card-schemas/link.schema.json +0 -54
  266. package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
  267. package/src/primitives/card-schemas/tasks.schema.json +0 -83
  268. package/src/primitives/card-tags.ts +0 -61
  269. package/src/primitives/card-validate-cards.ts +0 -255
  270. package/src/primitives/card-validate-schemas.ts +0 -58
  271. package/src/primitives/card-validate.ts +0 -131
  272. package/src/primitives/chat-config.tsx +0 -103
  273. package/src/primitives/composer-model.ts +0 -49
  274. package/src/primitives/composer-triggers.ts +0 -35
  275. package/src/primitives/controllable.ts +0 -21
  276. package/src/primitives/conversation-store.ts +0 -248
  277. package/src/primitives/create-kai-chat.ts +0 -66
  278. package/src/primitives/create-tween.ts +0 -266
  279. package/src/primitives/embed-providers.ts +0 -254
  280. package/src/primitives/field-mask.ts +0 -256
  281. package/src/primitives/field-semantics.ts +0 -115
  282. package/src/primitives/highlighter.ts +0 -157
  283. package/src/primitives/input-mask.ts +0 -853
  284. package/src/primitives/link-preview.ts +0 -87
  285. package/src/primitives/message-feedback.ts +0 -124
  286. package/src/primitives/pdf-preview.ts +0 -121
  287. package/src/primitives/toast-store.ts +0 -338
  288. package/src/primitives/url-scheme-policy.ts +0 -70
  289. package/src/primitives/use-audio-analysis.ts +0 -340
  290. package/src/primitives/use-auto-resize.ts +0 -31
  291. package/src/primitives/use-resize-observer.ts +0 -45
  292. package/src/primitives/use-sequencer.ts +0 -72
  293. package/src/primitives/use-speech-recognition.ts +0 -146
  294. package/src/primitives/use-stick-to-bottom.ts +0 -75
  295. package/src/primitives/use-text-stream.ts +0 -143
  296. package/src/primitives/use-voice-recorder.ts +0 -62
  297. package/src/primitives/visualizer-sequences.ts +0 -350
  298. package/src/remote/host-embed.ts +0 -345
  299. package/src/remote/index.ts +0 -2
  300. package/src/remote/origin.ts +0 -30
  301. package/src/remote/provider-runtime.ts +0 -262
  302. package/src/remote/provider.ts +0 -2
  303. package/src/remote/validate.ts +0 -22
  304. package/src/remote/version.ts +0 -12
  305. package/src/remote/wire.ts +0 -48
  306. package/src/schemas/from-tool-call.ts +0 -151
  307. package/src/schemas/index.ts +0 -341
  308. package/src/schemas/provider-subsets.ts +0 -538
  309. package/src/schemas/registry.ts +0 -355
  310. package/src/schemas/tool-defs.ts +0 -793
  311. package/src/solid.ts +0 -173
  312. package/src/state/index.ts +0 -44
  313. package/src/state/messages.ts +0 -53
  314. package/src/state/mock.ts +0 -297
  315. package/src/state/parts.ts +0 -295
  316. package/src/state/persistence.ts +0 -180
  317. package/src/state/stream.ts +0 -246
  318. package/src/state/suggestions.ts +0 -9
  319. package/src/state/threads.ts +0 -142
  320. package/src/test-utils/fake-clock.ts +0 -88
  321. package/src/types.ts +0 -95
  322. package/src/ui/action-icons.ts +0 -53
  323. package/src/ui/agent-card.tsx +0 -218
  324. package/src/ui/avatar.tsx +0 -23
  325. package/src/ui/badge.tsx +0 -21
  326. package/src/ui/button.tsx +0 -49
  327. package/src/ui/card.tsx +0 -245
  328. package/src/ui/checkbox-group.tsx +0 -153
  329. package/src/ui/checkbox.tsx +0 -63
  330. package/src/ui/collapsible.tsx +0 -163
  331. package/src/ui/command.tsx +0 -103
  332. package/src/ui/dialog.tsx +0 -223
  333. package/src/ui/dock.tsx +0 -630
  334. package/src/ui/dropdown.tsx +0 -636
  335. package/src/ui/editable-label.tsx +0 -112
  336. package/src/ui/hover-card.tsx +0 -345
  337. package/src/ui/icon.tsx +0 -167
  338. package/src/ui/input.tsx +0 -391
  339. package/src/ui/kbd.tsx +0 -118
  340. package/src/ui/nav.tsx +0 -282
  341. package/src/ui/notice.tsx +0 -84
  342. package/src/ui/overlay.tsx +0 -277
  343. package/src/ui/pane-grid.tsx +0 -117
  344. package/src/ui/pane-group.tsx +0 -291
  345. package/src/ui/pane.tsx +0 -193
  346. package/src/ui/popover.tsx +0 -106
  347. package/src/ui/progress-bar.tsx +0 -83
  348. package/src/ui/prompt-dock.tsx +0 -145
  349. package/src/ui/radio.tsx +0 -150
  350. package/src/ui/resizable.tsx +0 -693
  351. package/src/ui/scroll-area.tsx +0 -26
  352. package/src/ui/segmented.tsx +0 -109
  353. package/src/ui/select.tsx +0 -168
  354. package/src/ui/separator.tsx +0 -10
  355. package/src/ui/settings-group.tsx +0 -67
  356. package/src/ui/skeleton.tsx +0 -73
  357. package/src/ui/slider.tsx +0 -178
  358. package/src/ui/status.tsx +0 -48
  359. package/src/ui/switch.tsx +0 -119
  360. package/src/ui/tabs.tsx +0 -168
  361. package/src/ui/textarea.tsx +0 -21
  362. package/src/ui/tooltip.tsx +0 -118
  363. package/src/utils/cn.ts +0 -30
  364. package/src/wire/chunk.ts +0 -248
  365. package/src/wire/consume.ts +0 -599
  366. package/src/wire/diagnostics.ts +0 -727
  367. package/src/wire/encode-probe.ts +0 -214
  368. package/src/wire/encode.ts +0 -947
  369. package/src/wire/files.ts +0 -342
  370. package/src/wire/formats/anthropic.ts +0 -274
  371. package/src/wire/formats/openai.ts +0 -228
  372. package/src/wire/index.ts +0 -95
  373. package/src/wire/media-types.ts +0 -344
  374. package/src/wire/read.ts +0 -396
  375. package/src/wire/sink-helpers.ts +0 -50
  376. package/src/wire/sse.ts +0 -153
package/src/ui/status.tsx DELETED
@@ -1,48 +0,0 @@
1
- import { type JSX, Show, splitProps } from 'solid-js';
2
- import { cn } from '../utils/cn';
3
-
4
- export type StatusKind = 'new' | 'online' | 'busy' | 'away' | 'offline';
5
-
6
- /** status → background hue utility (backed by the kit's tool-* / muted tokens). */
7
- export const STATUS_BG: Record<StatusKind, string> = {
8
- new: 'bg-tool-blue',
9
- online: 'bg-tool-green',
10
- busy: 'bg-tool-red',
11
- away: 'bg-tool-amber',
12
- offline: 'bg-muted-foreground',
13
- };
14
-
15
- const SIZE: Record<'sm' | 'md', string> = { sm: 'size-2', md: 'size-2.5' };
16
-
17
- export interface StatusProps extends JSX.HTMLAttributes<HTMLSpanElement> {
18
- status?: StatusKind;
19
- size?: 'sm' | 'md';
20
- /** Add an animated ping ring (disabled under prefers-reduced-motion). */
21
- pulse?: boolean;
22
- /** Accessible name. With it, the dot is announced; without it, it is decorative. */
23
- label?: string;
24
- }
25
-
26
- export function Status(props: StatusProps) {
27
- const [local, rest] = splitProps(props, ['status', 'size', 'pulse', 'label', 'class']);
28
- const kind = () => local.status ?? 'new';
29
- return (
30
- <span
31
- class={cn('relative inline-flex', local.class)}
32
- role={local.label ? 'status' : undefined}
33
- aria-label={local.label}
34
- aria-hidden={local.label ? undefined : 'true'}
35
- >
36
- <Show when={local.pulse}>
37
- <span
38
- aria-hidden="true"
39
- class={cn(
40
- 'absolute inline-flex h-full w-full animate-ping rounded-full opacity-75 motion-reduce:hidden',
41
- STATUS_BG[kind()],
42
- )}
43
- />
44
- </Show>
45
- <span {...rest} class={cn('relative inline-block rounded-full', STATUS_BG[kind()], SIZE[local.size ?? 'sm'])} />
46
- </span>
47
- );
48
- }
package/src/ui/switch.tsx DELETED
@@ -1,119 +0,0 @@
1
- import { type JSX, createSignal, splitProps } from 'solid-js';
2
- import { cn } from '../utils/cn';
3
-
4
- export interface SwitchProps
5
- extends Omit<
6
- JSX.ButtonHTMLAttributes<HTMLButtonElement>,
7
- | 'type' | 'role' | 'aria-checked' | 'children' | 'ref'
8
- | 'onChange' | 'onchange' | 'onClick' | 'onclick' | 'onKeyDown' | 'onkeydown'
9
- > {
10
- /** Controlled checked state. When set, the component defers state to the
11
- * parent; drive it from `onChange`. Omit for uncontrolled (internal) state. */
12
- checked?: boolean;
13
- /** Initial checked state when uncontrolled. */
14
- defaultChecked?: boolean;
15
- /** Disable interaction. */
16
- disabled?: boolean;
17
- /** Accessible label for the control. */
18
- label?: string;
19
- /** Form-control name. When set (paired with `value`), a hidden checkbox carries
20
- * the on/off value for serialization. */
21
- name?: string;
22
- /** Submitted value when checked (paired with `name`). Defaults to `'on'`. */
23
- value?: string;
24
- /** Fires with the next checked state on toggle. */
25
- onChange?: (checked: boolean) => void;
26
- /** Receives the inner `role="switch"` button so a parent can focus it. */
27
- buttonRef?: (el: HTMLButtonElement) => void;
28
- class?: string;
29
- }
30
-
31
- /**
32
- * A toggle switch (`role="switch"`). Controlled via `checked`, or uncontrolled
33
- * from `defaultChecked`. Keyboard-operable (Space/Enter) and theme-tokened.
34
- *
35
- * Anything not named in `SwitchProps` is forwarded to the inner button, so `id`,
36
- * `aria-required` / `aria-invalid` / `aria-describedby` and any `data-*` hook land
37
- * on the focusable element without a caller stamping them through a `ref`. The
38
- * switch keeps ownership of `type`, `role`, `aria-checked` and the toggle handlers:
39
- * those are the control, not decoration.
40
- */
41
- export function Switch(props: SwitchProps) {
42
- const [local, rest] = splitProps(props, [
43
- 'checked', 'defaultChecked', 'disabled', 'label', 'name', 'value', 'onChange', 'buttonRef', 'class',
44
- ]);
45
- const [internal, setInternal] = createSignal(local.defaultChecked ?? false);
46
- const isControlled = () => local.checked !== undefined;
47
- const isOn = () => (isControlled() ? !!local.checked : internal());
48
-
49
- const toggle = () => {
50
- if (local.disabled) return;
51
- const next = !isOn();
52
- if (!isControlled()) setInternal(next);
53
- local.onChange?.(next);
54
- };
55
-
56
- return (
57
- <>
58
- {local.name != null && (
59
- <input
60
- type="checkbox"
61
- name={local.name}
62
- value={local.value ?? 'on'}
63
- checked={isOn()}
64
- disabled={local.disabled}
65
- aria-hidden="true"
66
- tabindex={-1}
67
- style={{ position: 'absolute', width: '1px', height: '1px', overflow: 'hidden', clip: 'rect(0 0 0 0)', 'white-space': 'nowrap' }}
68
- onChange={() => { /* driven by the button; keep the input in sync only */ }}
69
- />
70
- )}
71
- {/* `{...rest}` comes FIRST so the attributes below win: a caller can add an
72
- `id` or an `aria-describedby`, but cannot turn this into something that is
73
- no longer a switch. */}
74
- <button
75
- {...rest}
76
- type="button"
77
- role="switch"
78
- ref={local.buttonRef}
79
- aria-checked={isOn()}
80
- aria-label={local.label}
81
- disabled={local.disabled}
82
- onClick={toggle}
83
- onKeyDown={(e) => {
84
- if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); toggle(); }
85
- }}
86
- class={cn(
87
- 'relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border transition-colors',
88
- 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
89
- 'disabled:cursor-not-allowed disabled:opacity-50',
90
- // WCAG 2.1 SC 1.4.11: the track IS this control's visual boundary, so it
91
- // needs 3:1 against the surface behind it. The OFF fill cannot carry that
92
- // — `--color-muted` is a shared surface token (measured 1.10:1 light on
93
- // `--color-background`) and darkening it to clear 3:1 would repaint every
94
- // muted surface in the kit. So the boundary moves to a border on the
95
- // control-edge token `--color-input`, which exists for exactly this and is
96
- // already held to the 3:1 floor for radios, checkboxes and inputs
97
- // (tests/primitives/control-contrast.test.ts). The ON track keeps its
98
- // ~17:1 `--color-primary` fill and takes a transparent border purely so
99
- // the two states stay the same size — the fill still paints under it.
100
- isOn() ? 'border-transparent bg-primary' : 'border-input bg-muted',
101
- local.class,
102
- )}
103
- >
104
- <span
105
- class={cn(
106
- 'inline-block h-4 w-4 rounded-full shadow transition-transform',
107
- // On the `primary` track use `primary-foreground` so the thumb stays
108
- // visible in both themes (in dark mode `primary` is light, where a
109
- // hard-coded white thumb vanished). Off-track stays white over `muted`.
110
- // The track is `border-box` with a 1px border, so the thumb travels
111
- // inside a 34px box: 2px in from each inner edge keeps both end
112
- // positions 3px from the track's outer edge.
113
- isOn() ? 'translate-x-4 bg-primary-foreground' : 'translate-x-0.5 bg-white',
114
- )}
115
- />
116
- </button>
117
- </>
118
- );
119
- }
package/src/ui/tabs.tsx DELETED
@@ -1,168 +0,0 @@
1
- import { For, type JSX, splitProps } from 'solid-js';
2
- import { renderIcon } from './icon';
3
- import { cn } from '../utils/cn';
4
-
5
- /** One tab in a `Tabs` strip. `id` is the selected `value` throughout. */
6
- export interface KaiTabItem {
7
- /** Stable id, emitted as the selected `value`. Also useful for `aria-controls`. */
8
- id: string;
9
- label?: string;
10
- /** Named icon (e.g. "code"), image URL / data-URI, or plain text. */
11
- icon?: string;
12
- disabled?: boolean;
13
- }
14
-
15
- export type TabsVariant = 'segmented' | 'underline';
16
-
17
- /** variant → tablist container utilities. */
18
- export const TABLIST_CLASS: Record<TabsVariant, string> = {
19
- segmented: 'inline-flex items-center gap-1 rounded-lg bg-muted p-1',
20
- underline: 'inline-flex items-center gap-1 border-b border-border',
21
- };
22
-
23
- /** variant → per-tab utilities, given whether the tab is active. */
24
- export function tabClass(variant: TabsVariant, active: boolean): string {
25
- const base =
26
- 'inline-flex items-center gap-1.5 whitespace-nowrap text-sm font-medium transition-colors ' +
27
- 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ' +
28
- 'disabled:pointer-events-none disabled:opacity-50';
29
- if (variant === 'underline') {
30
- return cn(
31
- base,
32
- 'border-b-2 px-3 py-2 -mb-px',
33
- active
34
- ? 'border-primary text-foreground'
35
- : 'border-transparent text-muted-foreground hover:text-foreground',
36
- );
37
- }
38
- return cn(
39
- base,
40
- 'rounded-md px-3 py-1.5',
41
- active
42
- ? 'bg-background text-foreground shadow-sm'
43
- : 'text-muted-foreground hover:text-foreground',
44
- );
45
- }
46
-
47
- export interface TabsProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'onChange'> {
48
- items?: KaiTabItem[];
49
- /** Selected item id. */
50
- value?: string;
51
- variant?: TabsVariant;
52
- /** Stretch the strip to full width, each tab sharing the space equally. */
53
- block?: boolean;
54
- /** Disable the whole strip. */
55
- disabled?: boolean;
56
- /** Fired with the newly-selected item's id. */
57
- onChange?: (value: string) => void;
58
- /** Capture the tablist node (so the facade's `focus()` can target the active tab). */
59
- ref?: (el: HTMLDivElement) => void;
60
- }
61
-
62
- /**
63
- * Accessible tab strip. Selection only (emits the selected id via `onChange`);
64
- * the consumer renders each tab's content. Roving tabindex, Arrow/Home/End
65
- * keyboard nav, disabled items skipped.
66
- */
67
- export function Tabs(props: TabsProps) {
68
- const [local, rest] = splitProps(props, [
69
- 'items', 'value', 'variant', 'block', 'disabled', 'onChange', 'ref', 'class',
70
- ]);
71
- const items = () => local.items ?? [];
72
- const variant = (): TabsVariant => local.variant ?? 'segmented';
73
-
74
- const tabEls: Record<string, HTMLButtonElement> = {};
75
-
76
- const enabled = () => items().filter((it) => !it.disabled);
77
- const activeId = () => local.value;
78
-
79
- // Roving tabindex needs exactly one tab in the tab order. The active tab gets
80
- // it; if nothing is selected, the first enabled tab does, so the strip is still
81
- // reachable by Tab.
82
- const rovingId = () => {
83
- if (activeId() !== undefined && enabled().some((it) => it.id === activeId())) return activeId();
84
- return enabled()[0]?.id;
85
- };
86
-
87
- const select = (item: KaiTabItem) => {
88
- if (local.disabled || item.disabled) return;
89
- if (item.id === local.value) return;
90
- local.onChange?.(item.id);
91
- };
92
-
93
- // Roving focus: move focus to the target tab and emit selection (activate on focus move).
94
- const focusId = (id: string) => {
95
- const el = tabEls[id];
96
- if (el) el.focus();
97
- };
98
-
99
- const onKeyDown = (e: KeyboardEvent, item: KaiTabItem) => {
100
- const list = enabled();
101
- if (list.length === 0) return;
102
- const i = list.findIndex((it) => it.id === item.id);
103
- let next: KaiTabItem | undefined;
104
- switch (e.key) {
105
- case 'ArrowRight':
106
- case 'ArrowDown':
107
- next = list[(i + 1) % list.length];
108
- break;
109
- case 'ArrowLeft':
110
- case 'ArrowUp':
111
- next = list[(i - 1 + list.length) % list.length];
112
- break;
113
- case 'Home':
114
- next = list[0];
115
- break;
116
- case 'End':
117
- next = list[list.length - 1];
118
- break;
119
- case 'Enter':
120
- case ' ':
121
- e.preventDefault();
122
- select(item);
123
- return;
124
- default:
125
- return;
126
- }
127
- if (next) {
128
- e.preventDefault();
129
- select(next);
130
- focusId(next.id);
131
- }
132
- };
133
-
134
- return (
135
- <div
136
- {...rest}
137
- ref={(el) => local.ref?.(el)}
138
- role="tablist"
139
- part="tablist"
140
- aria-disabled={local.disabled ? 'true' : undefined}
141
- class={cn(TABLIST_CLASS[variant()], local.block && 'flex w-full', local.class)}
142
- >
143
- <For each={items()}>
144
- {(item) => {
145
- const active = () => item.id === activeId();
146
- return (
147
- <button
148
- ref={(el) => { tabEls[item.id] = el; }}
149
- type="button"
150
- part="tab"
151
- role="tab"
152
- data-active={active() ? '' : undefined}
153
- aria-selected={active() ? 'true' : 'false'}
154
- tabindex={item.id === rovingId() ? 0 : -1}
155
- disabled={local.disabled || item.disabled}
156
- class={cn(tabClass(variant(), active()), local.block && 'flex-1 justify-center')}
157
- onClick={() => select(item)}
158
- onKeyDown={(e) => onKeyDown(e, item)}
159
- >
160
- {renderIcon(item.icon, { class: 'size-4 shrink-0' })}
161
- {item.label}
162
- </button>
163
- );
164
- }}
165
- </For>
166
- </div>
167
- );
168
- }
@@ -1,21 +0,0 @@
1
- import { type JSX, splitProps } from 'solid-js';
2
- import { cn } from '../utils/cn';
3
- import { useAutoResize } from '../primitives/use-auto-resize';
4
-
5
- export interface TextareaProps extends JSX.TextareaHTMLAttributes<HTMLTextAreaElement> {
6
- maxHeight?: number;
7
- autoResize?: boolean;
8
- }
9
-
10
- export function Textarea(props: TextareaProps) {
11
- const [local, rest] = splitProps(props, ['class', 'maxHeight', 'autoResize']);
12
- const { ref } = useAutoResize({ maxHeight: local.maxHeight });
13
- return (
14
- <textarea
15
- ref={local.autoResize !== false ? ref : undefined}
16
- class={cn('w-full resize-none rounded-md bg-transparent text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring', local.class)}
17
- rows={1}
18
- {...rest}
19
- />
20
- );
21
- }
@@ -1,118 +0,0 @@
1
- import { createSignal, createUniqueId, onCleanup, Show, type JSX, type Accessor, splitProps } from 'solid-js';
2
- import { Portal } from 'solid-js/web';
3
- import { type Placement } from '@floating-ui/dom';
4
- import { cn } from '../utils/cn';
5
- import { useChatConfig } from '../primitives/chat-config';
6
- import { createPresence, usePosition, useDismiss, As } from './overlay';
7
-
8
- /** Imperative open controller, handed to a parent (e.g. the kai-tooltip facade)
9
- * via `controllerRef` so it can drive/observe open state. */
10
- export interface TooltipController { open: Accessor<boolean>; setOpen: (v: boolean) => void; }
11
-
12
- export interface TooltipProps {
13
- content: string;
14
- children: JSX.Element;
15
- class?: string;
16
- openDelay?: number;
17
- /** Delay (ms) before it hides after the pointer leaves. Defaults to 0 (hides
18
- * immediately). */
19
- closeDelay?: number;
20
- /** Preferred placement (post flip/shift). Defaults to `'top'`. */
21
- placement?: Placement;
22
- /** Initial open state on mount (uncontrolled seed). */
23
- defaultOpen?: boolean;
24
- /** When true, hover/focus (and `show()`) never opens the tooltip. */
25
- disabled?: boolean;
26
- /** Receive the open controller (open accessor + setOpen) once mounted. */
27
- controllerRef?: (api: TooltipController) => void;
28
- dismissOnClick?: boolean;
29
- }
30
-
31
- export function Tooltip(props: TooltipProps) {
32
- const [local] = splitProps(props, ['content', 'children', 'class', 'openDelay', 'closeDelay', 'placement', 'defaultOpen', 'disabled', 'controllerRef', 'dismissOnClick']);
33
- const config = useChatConfig();
34
- const id = createUniqueId();
35
- const [open, setOpen] = createSignal(local.defaultOpen ?? false);
36
- const [triggerEl, setTriggerEl] = createSignal<HTMLElement>();
37
- const [contentEl, setContentEl] = createSignal<HTMLElement>();
38
- // Hand the open controller up so a facade (kai-tooltip) can drive/observe it.
39
- // setOpen is gated on `disabled` so the disclosure surface (show/hide/toggle)
40
- // can never force the tooltip open while disabled.
41
- local.controllerRef?.({ open, setOpen: (v) => setOpen(v && !local.disabled) });
42
- let timer: number | undefined;
43
- // True for the span of a click (pointerdown → focus → click). Suppresses the
44
- // focus-show so clicking a hovered trigger DISMISSES it instead of flickering
45
- // hide→show→hide (pointerdown hid it, the click-induced focus re-showed it,
46
- // then click hid it again). Keyboard focus has no preceding pointerdown, so it
47
- // still shows the tooltip normally.
48
- let pointerDown = false;
49
-
50
- const [pointerInside, setPointerInside] = createSignal(false);
51
- const [focusInside, setFocusInside] = createSignal(false);
52
-
53
- const show = (delay = 0) => {
54
- if (local.disabled) return;
55
- clearTimeout(timer);
56
- if (delay) timer = window.setTimeout(() => setOpen(true), delay);
57
- else setOpen(true);
58
- };
59
- const hide = () => {
60
- clearTimeout(timer);
61
- const delay = local.closeDelay ?? 0;
62
- if (delay) timer = window.setTimeout(() => setOpen(false), delay);
63
- else setOpen(false);
64
- };
65
- const maybeHide = () => { if (!pointerInside() && !focusInside()) hide(); };
66
- // Action-style tooltips should dismiss when their trigger is clicked: the pointer
67
- // never "leaves", so reset the inside flags and force-close until the next genuine
68
- // hover/focus. Opt out with dismissOnClick={false}.
69
- const dismiss = () => { if (local.dismissOnClick === false) return; setPointerInside(false); setFocusInside(false); hide(); };
70
- onCleanup(() => clearTimeout(timer));
71
-
72
- const presence = createPresence(open);
73
- const position = usePosition(triggerEl, contentEl, {
74
- placement: local.placement ?? 'top',
75
- gutter: 6,
76
- // Trigger removed from the DOM -> close so the tooltip portal doesn't orphan.
77
- onDisconnect: () => setOpen(false),
78
- });
79
- useDismiss({ enabled: open, onDismiss: hide, refs: () => [triggerEl(), contentEl()] });
80
-
81
- return (
82
- <>
83
- <As
84
- as="span"
85
- class="inline-flex"
86
- ref={setTriggerEl}
87
- aria-describedby={open() ? id : undefined}
88
- onPointerEnter={() => { setPointerInside(true); show(local.openDelay ?? 600); }}
89
- onPointerLeave={() => { setPointerInside(false); maybeHide(); }}
90
- onPointerDown={() => { pointerDown = true; dismiss(); window.setTimeout(() => { pointerDown = false; }, 0); }}
91
- onClick={dismiss}
92
- onFocusIn={() => { setFocusInside(true); if (!pointerDown) show(); }}
93
- onFocusOut={(e: FocusEvent) => { const t = triggerEl(); if (t && t.contains(e.relatedTarget as Node)) return; setFocusInside(false); maybeHide(); }}
94
- >
95
- {local.children}
96
- </As>
97
- <Show when={presence.present()}>
98
- <Portal mount={config.portalMount()}>
99
- <div
100
- ref={(el) => { setContentEl(el); presence.setRef(el); }}
101
- id={id}
102
- role="tooltip"
103
- data-expanded={presence.state() === 'open' ? '' : undefined}
104
- data-closed={presence.state() === 'closed' ? '' : undefined}
105
- style={{ position: 'fixed', left: `${position.pos().x}px`, top: `${position.pos().y}px`, 'pointer-events': 'none', visibility: position.hidden() ? 'hidden' : 'visible' }}
106
- class={cn(
107
- 'z-50 rounded-md bg-foreground px-2.5 py-1 text-xs text-background shadow-md',
108
- 'animate-in fade-in-0 zoom-in-95 data-[closed]:animate-out data-[closed]:fade-out-0 data-[closed]:zoom-out-95',
109
- local.class,
110
- )}
111
- >
112
- {local.content}
113
- </div>
114
- </Portal>
115
- </Show>
116
- </>
117
- );
118
- }
package/src/utils/cn.ts DELETED
@@ -1,30 +0,0 @@
1
- import { clsx, type ClassValue } from 'clsx';
2
- import { extendTailwindMerge } from 'tailwind-merge';
3
-
4
- // The kit defines custom font-size utilities via @theme tokens in theme.css:
5
- // text-micro / text-caption / text-meta / text-compact / text-body / text-title.
6
- // tailwind-merge has no way to know these are font sizes, so by default it
7
- // buckets `text-body` with text COLORS and drops a real color
8
- // (`text-transparent`, `text-foreground`, …)
9
- // whenever both appear in the same cn() call — which silently broke TextShimmer
10
- // inside the web components (the element adds `text-body`, dropping
11
- // `text-transparent`, so the gradient stayed hidden behind opaque text).
12
- //
13
- // Register them in the `font-size` group so they conflict only with other font
14
- // sizes (text-xs/sm/base/lg/…) and never with text colors. Since theme.css now
15
- // re-points Tailwind's own scale at the same tokens (text-xs ≡ text-meta,
16
- // text-sm ≡ text-body, text-base ≡ text-title), the semantic name and its
17
- // Tailwind alias are literally the same size — so they MUST land in one group
18
- // or `cn('text-sm', 'text-body')` would emit two classes for one declaration.
19
- // `text-lg` needs no entry: it is already a stock Tailwind font size.
20
- const twMerge = extendTailwindMerge({
21
- extend: {
22
- classGroups: {
23
- 'font-size': [{ text: ['micro', 'caption', 'meta', 'compact', 'body', 'title'] }],
24
- },
25
- },
26
- });
27
-
28
- export function cn(...inputs: ClassValue[]) {
29
- return twMerge(clsx(inputs));
30
- }