@kitn.ai/ui 0.14.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 (370) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +394 -0
  3. package/dist/bash-InADTalH.js +1 -0
  4. package/dist/core-AYMC6_lb.js +12 -0
  5. package/dist/css-M7EaDHN_.js +1 -0
  6. package/dist/custom-elements.json +4739 -0
  7. package/dist/engine-javascript-vq0WuIJl.js +141 -0
  8. package/dist/github-dark-dimmed-DUshB20C.js +1 -0
  9. package/dist/github-light-JYsPkUQd.js +1 -0
  10. package/dist/host-embed.d.ts +33 -0
  11. package/dist/html-CPZ3oZQ7.js +1 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/javascript-C25yR2R2.js +1 -0
  14. package/dist/json-DxJze_jm.js +1 -0
  15. package/dist/kitn-chat-provider.d.ts +2 -0
  16. package/dist/kitn-chat-provider.es.js +240 -0
  17. package/dist/kitn-chat.es.js +77 -0
  18. package/dist/llms/llms-full.txt +1018 -0
  19. package/dist/llms/llms.txt +104 -0
  20. package/dist/origin.d.ts +5 -0
  21. package/dist/provider-runtime.d.ts +27 -0
  22. package/dist/schemas/card-envelope.schema.json +14 -0
  23. package/dist/schemas/card-event.schema.json +12 -0
  24. package/dist/schemas/choice.schema.json +70 -0
  25. package/dist/schemas/confirm.schema.json +65 -0
  26. package/dist/schemas/embed.schema.json +65 -0
  27. package/dist/schemas/form.result.schema.json +7 -0
  28. package/dist/schemas/form.schema.json +33 -0
  29. package/dist/schemas/link.schema.json +56 -0
  30. package/dist/schemas/tasks.result.schema.json +16 -0
  31. package/dist/schemas/tasks.schema.json +78 -0
  32. package/dist/svelte--5p79yCD.js +1 -0
  33. package/dist/theme.tokens.css +176 -0
  34. package/dist/tsx-B8rCNbgL.js +1 -0
  35. package/dist/typescript-RycA9KXf.js +1 -0
  36. package/dist/validate.d.ts +4 -0
  37. package/dist/version.d.ts +4 -0
  38. package/dist/vue-BmIZj4XD.js +1 -0
  39. package/dist/wire.d.ts +53 -0
  40. package/frameworks/react/index.tsx +948 -0
  41. package/frameworks/react/runtime.tsx +94 -0
  42. package/llms-full.txt +1018 -0
  43. package/llms.txt +104 -0
  44. package/package.json +141 -0
  45. package/src/components/artifact.stories.tsx +138 -0
  46. package/src/components/artifact.tsx +743 -0
  47. package/src/components/attachments.stories.tsx +303 -0
  48. package/src/components/attachments.test.tsx +64 -0
  49. package/src/components/attachments.tsx +399 -0
  50. package/src/components/card-fallback.tsx +28 -0
  51. package/src/components/card-renderer.tsx +52 -0
  52. package/src/components/card.tsx +110 -0
  53. package/src/components/chain-of-thought.stories.tsx +211 -0
  54. package/src/components/chain-of-thought.tsx +139 -0
  55. package/src/components/chat-container.stories.tsx +187 -0
  56. package/src/components/chat-container.tsx +82 -0
  57. package/src/components/chat-scope-picker.tsx +47 -0
  58. package/src/components/chat-thread.test.tsx +58 -0
  59. package/src/components/chat-thread.tsx +249 -0
  60. package/src/components/checkpoint.stories.tsx +102 -0
  61. package/src/components/checkpoint.tsx +88 -0
  62. package/src/components/choice-card.tsx +569 -0
  63. package/src/components/code-block.stories.tsx +150 -0
  64. package/src/components/code-block.tsx +105 -0
  65. package/src/components/component-meta.json +3735 -0
  66. package/src/components/confirm-card.stories.tsx +74 -0
  67. package/src/components/confirm-card.tsx +315 -0
  68. package/src/components/context.stories.tsx +229 -0
  69. package/src/components/context.test.tsx +133 -0
  70. package/src/components/context.tsx +363 -0
  71. package/src/components/conversation-item.stories.tsx +125 -0
  72. package/src/components/conversation-item.tsx +16 -0
  73. package/src/components/conversation-list.stories.tsx +133 -0
  74. package/src/components/conversation-list.tsx +101 -0
  75. package/src/components/default-input.test.tsx +111 -0
  76. package/src/components/embed.tsx +196 -0
  77. package/src/components/empty.stories.tsx +434 -0
  78. package/src/components/empty.tsx +166 -0
  79. package/src/components/feedback-bar.stories.tsx +138 -0
  80. package/src/components/feedback-bar.test.tsx +103 -0
  81. package/src/components/feedback-bar.tsx +166 -0
  82. package/src/components/file-tree.stories.tsx +73 -0
  83. package/src/components/file-tree.tsx +383 -0
  84. package/src/components/file-upload.stories.tsx +156 -0
  85. package/src/components/file-upload.tsx +161 -0
  86. package/src/components/form-widgets.tsx +461 -0
  87. package/src/components/form.tsx +873 -0
  88. package/src/components/image.stories.tsx +89 -0
  89. package/src/components/image.tsx +67 -0
  90. package/src/components/link-preview.tsx +194 -0
  91. package/src/components/loader.stories.tsx +181 -0
  92. package/src/components/loader.tsx +333 -0
  93. package/src/components/markdown.stories.tsx +180 -0
  94. package/src/components/markdown.tsx +81 -0
  95. package/src/components/message-action-bar.test.tsx +128 -0
  96. package/src/components/message-narrow.stories.tsx +329 -0
  97. package/src/components/message-skills.stories.tsx +211 -0
  98. package/src/components/message-skills.tsx +36 -0
  99. package/src/components/message.stories.tsx +281 -0
  100. package/src/components/message.tsx +227 -0
  101. package/src/components/model-switcher.stories.tsx +123 -0
  102. package/src/components/model-switcher.test.tsx +65 -0
  103. package/src/components/model-switcher.tsx +87 -0
  104. package/src/components/prompt-input.stories.tsx +222 -0
  105. package/src/components/prompt-input.tsx +211 -0
  106. package/src/components/prompt-suggestion.stories.tsx +142 -0
  107. package/src/components/prompt-suggestion.tsx +115 -0
  108. package/src/components/reasoning.stories.tsx +140 -0
  109. package/src/components/reasoning.tsx +156 -0
  110. package/src/components/resizable.test.tsx +226 -0
  111. package/src/components/response-stream.tsx +103 -0
  112. package/src/components/scroll-button.stories.tsx +100 -0
  113. package/src/components/scroll-button.tsx +34 -0
  114. package/src/components/slash-command.stories.tsx +163 -0
  115. package/src/components/slash-command.tsx +232 -0
  116. package/src/components/source-list.test.tsx +152 -0
  117. package/src/components/source.stories.tsx +124 -0
  118. package/src/components/source.tsx +129 -0
  119. package/src/components/tasks-card.stories.tsx +78 -0
  120. package/src/components/tasks-card.tsx +432 -0
  121. package/src/components/text-shimmer.stories.tsx +87 -0
  122. package/src/components/text-shimmer.tsx +37 -0
  123. package/src/components/thinking-bar.stories.tsx +87 -0
  124. package/src/components/thinking-bar.tsx +50 -0
  125. package/src/components/tool.stories.tsx +153 -0
  126. package/src/components/tool.tsx +184 -0
  127. package/src/components/use-card-resolution.ts +28 -0
  128. package/src/components/voice-input.stories.tsx +83 -0
  129. package/src/components/voice-input.tsx +107 -0
  130. package/src/elements/artifact.stories.tsx +506 -0
  131. package/src/elements/artifact.tsx +137 -0
  132. package/src/elements/attachments.stories.tsx +190 -0
  133. package/src/elements/attachments.tsx +136 -0
  134. package/src/elements/card.stories.tsx +113 -0
  135. package/src/elements/card.tsx +40 -0
  136. package/src/elements/cards.stories.tsx +59 -0
  137. package/src/elements/cards.tsx +97 -0
  138. package/src/elements/catalog.stories.tsx +491 -0
  139. package/src/elements/chain-of-thought.declarative.test.tsx +153 -0
  140. package/src/elements/chain-of-thought.stories.tsx +113 -0
  141. package/src/elements/chain-of-thought.tsx +92 -0
  142. package/src/elements/chat-scope-picker.stories.tsx +73 -0
  143. package/src/elements/chat-scope-picker.tsx +36 -0
  144. package/src/elements/chat-types.ts +42 -0
  145. package/src/elements/chat-workspace.stories.tsx +288 -0
  146. package/src/elements/chat-workspace.tsx +161 -0
  147. package/src/elements/chat.stories.tsx +151 -0
  148. package/src/elements/chat.tsx +80 -0
  149. package/src/elements/checkpoint.stories.tsx +72 -0
  150. package/src/elements/checkpoint.tsx +47 -0
  151. package/src/elements/choice.stories.tsx +240 -0
  152. package/src/elements/choice.tsx +48 -0
  153. package/src/elements/code-block.stories.tsx +83 -0
  154. package/src/elements/code-block.tsx +42 -0
  155. package/src/elements/compiled.css +2 -0
  156. package/src/elements/composed-shell.stories.tsx +316 -0
  157. package/src/elements/confirm-card.stories.tsx +227 -0
  158. package/src/elements/confirm-card.tsx +51 -0
  159. package/src/elements/context-meter.stories.tsx +151 -0
  160. package/src/elements/context-meter.tsx +121 -0
  161. package/src/elements/conversation-list.declarative.test.tsx +137 -0
  162. package/src/elements/conversation-list.stories.tsx +243 -0
  163. package/src/elements/conversation-list.tsx +80 -0
  164. package/src/elements/css.ts +5 -0
  165. package/src/elements/default-input.tsx +247 -0
  166. package/src/elements/define.tsx +171 -0
  167. package/src/elements/element-meta.json +3314 -0
  168. package/src/elements/element-types.d.ts +710 -0
  169. package/src/elements/embed.stories.tsx +213 -0
  170. package/src/elements/embed.tsx +35 -0
  171. package/src/elements/empty.stories.tsx +111 -0
  172. package/src/elements/empty.tsx +29 -0
  173. package/src/elements/feedback-bar.stories.tsx +114 -0
  174. package/src/elements/feedback-bar.tsx +61 -0
  175. package/src/elements/file-tree.stories.tsx +134 -0
  176. package/src/elements/file-tree.tsx +52 -0
  177. package/src/elements/file-upload.stories.tsx +82 -0
  178. package/src/elements/file-upload.tsx +44 -0
  179. package/src/elements/form.stories.tsx +248 -0
  180. package/src/elements/form.tsx +43 -0
  181. package/src/elements/framework-usage.json +563 -0
  182. package/src/elements/image.stories.tsx +71 -0
  183. package/src/elements/image.tsx +32 -0
  184. package/src/elements/link-preview.stories.tsx +209 -0
  185. package/src/elements/link-preview.tsx +34 -0
  186. package/src/elements/loader.stories.tsx +88 -0
  187. package/src/elements/loader.tsx +25 -0
  188. package/src/elements/markdown.stories.tsx +76 -0
  189. package/src/elements/markdown.tsx +38 -0
  190. package/src/elements/message-skills.declarative.test.tsx +104 -0
  191. package/src/elements/message-skills.stories.tsx +114 -0
  192. package/src/elements/message-skills.tsx +85 -0
  193. package/src/elements/message.stories.tsx +218 -0
  194. package/src/elements/message.tsx +162 -0
  195. package/src/elements/model-switcher.declarative.test.tsx +130 -0
  196. package/src/elements/model-switcher.stories.tsx +198 -0
  197. package/src/elements/model-switcher.tsx +93 -0
  198. package/src/elements/popover.stories.tsx +80 -0
  199. package/src/elements/popover.tsx +59 -0
  200. package/src/elements/prompt-input-slash-command.test.tsx +128 -0
  201. package/src/elements/prompt-input-stoppable.test.tsx +88 -0
  202. package/src/elements/prompt-input-toolbar-actions.test.tsx +120 -0
  203. package/src/elements/prompt-input.stories.tsx +331 -0
  204. package/src/elements/prompt-input.tsx +185 -0
  205. package/src/elements/prompt-suggestions.declarative.test.tsx +164 -0
  206. package/src/elements/prompt-suggestions.stories.tsx +213 -0
  207. package/src/elements/prompt-suggestions.tsx +94 -0
  208. package/src/elements/reasoning.stories.tsx +77 -0
  209. package/src/elements/reasoning.tsx +50 -0
  210. package/src/elements/register.ts +56 -0
  211. package/src/elements/remote.stories.tsx +314 -0
  212. package/src/elements/remote.tsx +221 -0
  213. package/src/elements/resizable.d.ts +27 -0
  214. package/src/elements/resizable.stories.tsx +426 -0
  215. package/src/elements/resizable.tsx +553 -0
  216. package/src/elements/response-stream.stories.tsx +79 -0
  217. package/src/elements/response-stream.tsx +40 -0
  218. package/src/elements/scroll-button.stories.tsx +202 -0
  219. package/src/elements/scroll-button.test.tsx +148 -0
  220. package/src/elements/scroll-button.tsx +126 -0
  221. package/src/elements/source-list.stories.tsx +143 -0
  222. package/src/elements/source.stories.tsx +88 -0
  223. package/src/elements/source.tsx +120 -0
  224. package/src/elements/styles.css +199 -0
  225. package/src/elements/switch.stories.tsx +56 -0
  226. package/src/elements/switch.tsx +43 -0
  227. package/src/elements/tasks.stories.tsx +237 -0
  228. package/src/elements/tasks.tsx +46 -0
  229. package/src/elements/text-shimmer.stories.tsx +64 -0
  230. package/src/elements/text-shimmer.tsx +28 -0
  231. package/src/elements/thinking-bar.stories.tsx +72 -0
  232. package/src/elements/thinking-bar.tsx +34 -0
  233. package/src/elements/tool.stories.tsx +89 -0
  234. package/src/elements/tool.tsx +23 -0
  235. package/src/elements/voice-input.stories.tsx +88 -0
  236. package/src/elements/voice-input.tsx +41 -0
  237. package/src/index.ts +253 -0
  238. package/src/primitives/card-contract.ts +71 -0
  239. package/src/primitives/card-host.tsx +35 -0
  240. package/src/primitives/card-registry.tsx +67 -0
  241. package/src/primitives/card-resolution.ts +36 -0
  242. package/src/primitives/card-routing.ts +79 -0
  243. package/src/primitives/card-schemas/card-envelope.schema.json +14 -0
  244. package/src/primitives/card-schemas/card-event.schema.json +12 -0
  245. package/src/primitives/card-schemas/choice.schema.json +70 -0
  246. package/src/primitives/card-schemas/confirm.schema.json +65 -0
  247. package/src/primitives/card-schemas/embed.schema.json +65 -0
  248. package/src/primitives/card-schemas/form.result.schema.json +7 -0
  249. package/src/primitives/card-schemas/form.schema.json +33 -0
  250. package/src/primitives/card-schemas/link.schema.json +56 -0
  251. package/src/primitives/card-schemas/tasks.result.schema.json +16 -0
  252. package/src/primitives/card-schemas/tasks.schema.json +78 -0
  253. package/src/primitives/card-validate.ts +95 -0
  254. package/src/primitives/chat-config.tsx +76 -0
  255. package/src/primitives/controllable.test.ts +47 -0
  256. package/src/primitives/controllable.ts +21 -0
  257. package/src/primitives/embed-providers.ts +254 -0
  258. package/src/primitives/highlighter.ts +157 -0
  259. package/src/primitives/link-preview.ts +87 -0
  260. package/src/primitives/pdf-preview.ts +121 -0
  261. package/src/primitives/use-auto-resize.ts +31 -0
  262. package/src/primitives/use-resize-observer.ts +12 -0
  263. package/src/primitives/use-stick-to-bottom.ts +43 -0
  264. package/src/primitives/use-text-stream.ts +112 -0
  265. package/src/primitives/use-voice-recorder.ts +50 -0
  266. package/src/remote/host-embed.ts +345 -0
  267. package/src/remote/index.ts +2 -0
  268. package/src/remote/origin.ts +30 -0
  269. package/src/remote/provider-runtime.ts +259 -0
  270. package/src/remote/provider.ts +2 -0
  271. package/src/remote/validate.ts +22 -0
  272. package/src/remote/version.ts +12 -0
  273. package/src/remote/wire.ts +48 -0
  274. package/src/stories/chat-panel-layout.stories.tsx +145 -0
  275. package/src/stories/chat-scene.tsx +571 -0
  276. package/src/stories/checkpoint-restore.stories.tsx +256 -0
  277. package/src/stories/context-usage.stories.tsx +212 -0
  278. package/src/stories/conversation-with-reasoning.stories.tsx +182 -0
  279. package/src/stories/conversation-with-sources.stories.tsx +471 -0
  280. package/src/stories/docs/Accessibility.mdx +119 -0
  281. package/src/stories/docs/ChildElements.mdx +269 -0
  282. package/src/stories/docs/ForAIAgents.mdx +162 -0
  283. package/src/stories/docs/GettingStarted.mdx +65 -0
  284. package/src/stories/docs/Installation.mdx +83 -0
  285. package/src/stories/docs/Introduction.mdx +50 -0
  286. package/src/stories/docs/SolidJsAdvanced.mdx +17 -0
  287. package/src/stories/docs/Theming.mdx +85 -0
  288. package/src/stories/docs/element-controls.ts +121 -0
  289. package/src/stories/docs/frameworks/Angular.mdx +245 -0
  290. package/src/stories/docs/frameworks/Html.mdx +227 -0
  291. package/src/stories/docs/frameworks/Overview.mdx +47 -0
  292. package/src/stories/docs/frameworks/React.mdx +227 -0
  293. package/src/stories/docs/frameworks/Solid.mdx +173 -0
  294. package/src/stories/docs/frameworks/Svelte.mdx +194 -0
  295. package/src/stories/docs/frameworks/Vue.mdx +238 -0
  296. package/src/stories/docs/generative-ui-overview.mdx +186 -0
  297. package/src/stories/docs/recipes/SpeechToText.mdx +7 -0
  298. package/src/stories/docs/recipes/Streaming.mdx +68 -0
  299. package/src/stories/docs/recipes/TextToSpeech.mdx +35 -0
  300. package/src/stories/docs/theme-editor/canvas.tsx +32 -0
  301. package/src/stories/docs/theme-editor/inspector.tsx +66 -0
  302. package/src/stories/docs/theme-editor/presets.test.ts +32 -0
  303. package/src/stories/docs/theme-editor/presets.ts +64 -0
  304. package/src/stories/docs/theme-editor/theme-css.test.ts +19 -0
  305. package/src/stories/docs/theme-editor/theme-css.ts +15 -0
  306. package/src/stories/docs/theme-editor/theme-editor.tsx +146 -0
  307. package/src/stories/docs/theme-tokens.tsx +174 -0
  308. package/src/stories/examples/ChoosingComponents.mdx +106 -0
  309. package/src/stories/examples/sample-data.ts +79 -0
  310. package/src/stories/examples/usage/checkpoint-restore.ts +156 -0
  311. package/src/stories/examples/usage/context-usage.ts +591 -0
  312. package/src/stories/examples/usage/conversation-with-reasoning.ts +224 -0
  313. package/src/stories/examples/usage/conversation-with-sources.ts +589 -0
  314. package/src/stories/examples/usage/empty-state.ts +144 -0
  315. package/src/stories/examples/usage/full-chat-app.ts +277 -0
  316. package/src/stories/examples/usage/index.ts +63 -0
  317. package/src/stories/examples/usage/message-actions.ts +704 -0
  318. package/src/stories/examples/usage/pattern-centered-conversation.ts +446 -0
  319. package/src/stories/examples/usage/pattern-chat-panel-layout.ts +442 -0
  320. package/src/stories/examples/usage/pattern-docked-widget.ts +479 -0
  321. package/src/stories/examples/usage/prompt-input-variants.ts +1356 -0
  322. package/src/stories/examples/usage/streaming-response.ts +687 -0
  323. package/src/stories/examples/usage/types.ts +33 -0
  324. package/src/stories/full-chat.stories.tsx +18 -0
  325. package/src/stories/message-actions.stories.tsx +230 -0
  326. package/src/stories/pattern-centered-conversation.stories.tsx +93 -0
  327. package/src/stories/pattern-docked-widget.stories.tsx +93 -0
  328. package/src/stories/pattern-empty-state.stories.tsx +76 -0
  329. package/src/stories/prompt-input-variants.stories.tsx +456 -0
  330. package/src/stories/streaming-response.stories.tsx +438 -0
  331. package/src/stories/theme-editor.stories.tsx +16 -0
  332. package/src/stories/token-reference.stories.tsx +18 -0
  333. package/src/stories/typography.stories.tsx +78 -0
  334. package/src/types.ts +47 -0
  335. package/src/ui/action-icons.ts +52 -0
  336. package/src/ui/avatar.stories.tsx +103 -0
  337. package/src/ui/avatar.tsx +23 -0
  338. package/src/ui/badge.stories.tsx +86 -0
  339. package/src/ui/badge.tsx +21 -0
  340. package/src/ui/button.stories.tsx +145 -0
  341. package/src/ui/button.tsx +38 -0
  342. package/src/ui/collapsible.stories.tsx +69 -0
  343. package/src/ui/collapsible.tsx +125 -0
  344. package/src/ui/dropdown.stories.tsx +59 -0
  345. package/src/ui/dropdown.tsx +196 -0
  346. package/src/ui/hover-card.stories.tsx +77 -0
  347. package/src/ui/hover-card.test.tsx +30 -0
  348. package/src/ui/hover-card.tsx +172 -0
  349. package/src/ui/overlay.stories.tsx +115 -0
  350. package/src/ui/overlay.tsx +158 -0
  351. package/src/ui/popover.stories.tsx +81 -0
  352. package/src/ui/popover.test.tsx +99 -0
  353. package/src/ui/popover.tsx +92 -0
  354. package/src/ui/resizable.stories.tsx +236 -0
  355. package/src/ui/resizable.tsx +576 -0
  356. package/src/ui/scroll-area.stories.tsx +50 -0
  357. package/src/ui/scroll-area.tsx +15 -0
  358. package/src/ui/separator.stories.tsx +81 -0
  359. package/src/ui/separator.tsx +10 -0
  360. package/src/ui/skeleton.stories.tsx +337 -0
  361. package/src/ui/skeleton.tsx +16 -0
  362. package/src/ui/switch.stories.tsx +51 -0
  363. package/src/ui/switch.test.tsx +59 -0
  364. package/src/ui/switch.tsx +62 -0
  365. package/src/ui/textarea.stories.tsx +76 -0
  366. package/src/ui/textarea.tsx +21 -0
  367. package/src/ui/tooltip.stories.tsx +74 -0
  368. package/src/ui/tooltip.tsx +68 -0
  369. package/src/utils/cn.ts +24 -0
  370. package/theme.css +187 -0
package/llms.txt ADDED
@@ -0,0 +1,104 @@
1
+ <!-- AUTO-GENERATED by scripts/gen-llms.mjs — do not edit by hand. Run `npm run build`. -->
2
+ # @kitn.ai/ui
3
+
4
+ > Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 44 `kitn-*` custom elements: streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ npm install @kitn.ai/ui
10
+ # SolidJS consumers also need the peer dep:
11
+ npm install solid-js
12
+ ```
13
+
14
+ ## #1 rule: array/object data goes on JS PROPERTIES, not HTML attributes
15
+
16
+ This is the single most common mistake. Arrays and objects (`messages`, `models`, `context`, `suggestions`, `slashCommands`, …) MUST be assigned as JavaScript properties on the element. They CANNOT be passed as HTML attributes — an HTML attribute is always a string and will be ignored or mis-parsed.
17
+
18
+ ```js
19
+ const chat = document.querySelector('kai-chat');
20
+ chat.messages = [{ id: '1', role: 'assistant', content: 'Hi!' }]; // ✅ property
21
+ ```
22
+ ```html
23
+ <kai-chat messages="[...]"></kai-chat> <!-- ❌ never works -->
24
+ ```
25
+
26
+ Only scalar values (string/number/boolean) work as attributes (e.g. `placeholder`, `loading`, `theme`).
27
+
28
+ ## Two layers
29
+
30
+ **Layer 1 — batteries-included web components** (`import '@kitn.ai/ui/elements'`):
31
+ Drop an element into any framework (React, Vue, plain HTML). Data in via JS properties; interactions out via non-bubbling CustomEvents.
32
+
33
+ - `<kai-chat>` — full chat UI (message list + prompt input). The primary starting point.
34
+ - `<kai-conversations>` — sidebar conversation browser with group support.
35
+ - `<kai-prompt-input>` — standalone composer with send button.
36
+
37
+ **Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
38
+ All 44 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
39
+
40
+ ## Key rules for the web components
41
+
42
+ 1. **Array/object data = JS properties** (see above). Scalars may be attributes.
43
+ 2. **Events are non-bubbling `CustomEvent`s** — listen directly on the element:
44
+ `chat.addEventListener('kai-submit', (e) => console.log(e.detail.value))`
45
+ 3. **`theme` attribute** (`'light' | 'dark' | 'auto'`) works on every element. Default `auto` follows `prefers-color-scheme`.
46
+ 4. **Theming via CSS custom properties** — override `--kai-color-*` tokens on `:root`; they pierce Shadow DOM.
47
+
48
+ ## ChatMessage schema (required for `<kai-chat>`)
49
+
50
+ ```ts
51
+ interface ChatMessage {
52
+ id: string;
53
+ role: 'user' | 'assistant';
54
+ content: string;
55
+ reasoning?: { text: string; label?: string };
56
+ tools?: ToolPart[];
57
+ attachments?: AttachmentData[];
58
+ actions?: ('copy' | 'like' | 'dislike' | 'regenerate' | 'edit')[];
59
+ }
60
+ ```
61
+
62
+ ## Framework wiring
63
+
64
+ **Plain HTML / CDN**
65
+ ```html
66
+ <script type="module" src="https://unpkg.com/@kitn.ai/ui/elements"></script>
67
+ <kai-chat style="display:block;height:100vh"></kai-chat>
68
+ <script type="module">
69
+ const chat = document.querySelector('kai-chat');
70
+ chat.messages = [];
71
+ </script>
72
+ ```
73
+
74
+ **React** — typed wrappers auto-set properties and expose `on<Event>` props:
75
+ ```tsx
76
+ import { Chat } from '@kitn.ai/ui/react';
77
+ <Chat messages={messages} onSubmit={(e) => send(e.detail.value)} />
78
+ ```
79
+
80
+ **Vue** — use the element directly; pass arrays via `.prop`:
81
+ ```vue
82
+ <kai-chat :messages.prop="messages" @kai-submit="send" />
83
+ ```
84
+
85
+ ## Theming
86
+
87
+ ```css
88
+ :root {
89
+ --kai-color-background: #0f0f0f;
90
+ --kai-color-primary: #7c3aed;
91
+ --kai-color-muted: #1e1e1e;
92
+ }
93
+ ```
94
+
95
+ For plain HTML/CDN: `<link rel="stylesheet" href="…/@kitn.ai/ui/theme.tokens.css">`.
96
+ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
97
+
98
+ ## Docs
99
+
100
+ - Full element reference (all 44 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
101
+ - Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
102
+ - Working examples: https://github.com/kitn-ai/ui/tree/main/examples
103
+ - Storybook: https://storybook.kitn.dev
104
+ - Repository: https://github.com/kitn-ai/ui
package/package.json ADDED
@@ -0,0 +1,141 @@
1
+ {
2
+ "name": "@kitn.ai/ui",
3
+ "version": "0.14.1",
4
+ "type": "module",
5
+ "description": "Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. Authored in SolidJS.",
6
+ "keywords": [
7
+ "web-components",
8
+ "custom-elements",
9
+ "shadow-dom",
10
+ "ai",
11
+ "chat",
12
+ "chatbot",
13
+ "llm",
14
+ "chat-ui",
15
+ "streaming",
16
+ "markdown",
17
+ "framework-agnostic",
18
+ "react",
19
+ "vue",
20
+ "angular",
21
+ "svelte",
22
+ "solid-js"
23
+ ],
24
+ "license": "MIT",
25
+ "homepage": "https://ui.kitn.ai",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/kitn-ai/ui.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/kitn-ai/ui/issues"
32
+ },
33
+ "main": "src/index.ts",
34
+ "types": "src/index.ts",
35
+ "unpkg": "./dist/kitn-chat.es.js",
36
+ "jsdelivr": "./dist/kitn-chat.es.js",
37
+ "customElements": "dist/custom-elements.json",
38
+ "exports": {
39
+ ".": "./src/index.ts",
40
+ "./elements": {
41
+ "types": "./src/elements/element-types.d.ts",
42
+ "default": "./dist/kitn-chat.es.js"
43
+ },
44
+ "./theme.css": "./theme.css",
45
+ "./theme.tokens.css": "./dist/theme.tokens.css",
46
+ "./react": "./frameworks/react/index.tsx",
47
+ "./provider": {
48
+ "types": "./dist/kitn-chat-provider.d.ts",
49
+ "default": "./dist/kitn-chat-provider.es.js"
50
+ }
51
+ },
52
+ "files": [
53
+ "dist",
54
+ "src",
55
+ "frameworks",
56
+ "theme.css",
57
+ "llms.txt",
58
+ "llms-full.txt"
59
+ ],
60
+ "scripts": {
61
+ "prepublishOnly": "npm run build",
62
+ "prebuild": "npm run build:css",
63
+ "build": "vite build --config vite.config.ts && vite build --config vite.config.provider.ts",
64
+ "postbuild": "npm run build:theme && npm run build:api && npm run build:schemas",
65
+ "build:theme": "node scripts/build-theme-tokens.mjs",
66
+ "build:api": "node scripts/gen-element-api.mjs",
67
+ "build:schemas": "node scripts/copy-card-schemas.mjs",
68
+ "test": "vitest run",
69
+ "test:react": "vitest run --config vitest.react.config.ts",
70
+ "test:storybook": "vitest run --project=storybook",
71
+ "test:watch": "vitest",
72
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.react.json && tsc --noEmit -p tsconfig.react.test.json",
73
+ "examples": "echo 'Serving repo root on http://localhost:8000 — open http://localhost:8000/examples/composable/index.html' && python3 -m http.server 8000",
74
+ "dev": "npm run build:css && storybook dev -p 6006",
75
+ "storybook": "npm run build:css && storybook dev -p 6006",
76
+ "build-storybook": "npm run build:css && storybook build",
77
+ "build:css": "tailwindcss -i src/elements/styles.css -o src/elements/compiled.css --minify",
78
+ "build:css:watch": "tailwindcss -i src/elements/styles.css -o src/elements/compiled.css --watch",
79
+ "dev:provider": "vite examples/remote-provider --port 6007 --strictPort",
80
+ "dev:host": "vite examples/remote-host --port 6006 --strictPort",
81
+ "test:e2e": "playwright test"
82
+ },
83
+ "dependencies": {
84
+ "@floating-ui/dom": "^1.7.6",
85
+ "@shikijs/langs": "^4.2.0",
86
+ "@shikijs/themes": "^4.2.0",
87
+ "class-variance-authority": "^0.7.0",
88
+ "clsx": "^2.1.0",
89
+ "lucide-solid": "^0.400.0",
90
+ "marked": "^18.0.0",
91
+ "shiki": "^4.0.2",
92
+ "solid-element": "^1.9.1",
93
+ "solid-js": "^1.9.0",
94
+ "tailwind-merge": "^2.5.0"
95
+ },
96
+ "devDependencies": {
97
+ "@playwright/test": "^1.60.0",
98
+ "@solidjs/testing-library": "^0.8.0",
99
+ "@storybook/addon-a11y": "^10.4.2",
100
+ "@storybook/addon-docs": "^10.3.5",
101
+ "@storybook/addon-themes": "^10.3.5",
102
+ "@storybook/addon-vitest": "^10.3.5",
103
+ "@tailwindcss/cli": "^4.3.0",
104
+ "@tailwindcss/postcss": "^4.2.2",
105
+ "@tailwindcss/typography": "^0.5.19",
106
+ "@testing-library/jest-dom": "^6.0.0",
107
+ "@testing-library/react": "^16.3.2",
108
+ "@types/react": "^19.2.17",
109
+ "@types/react-dom": "^19.2.3",
110
+ "@vitejs/plugin-react": "^4.7.0",
111
+ "@vitest/browser-playwright": "4.1.2",
112
+ "@vitest/coverage-v8": "4.1.2",
113
+ "axe-core": "^4.12.1",
114
+ "concurrently": "^10.0.3",
115
+ "http-server": "^14.1.1",
116
+ "jsdom": "^24.0.0",
117
+ "playwright": "^1.59.1",
118
+ "react": "^19.2.7",
119
+ "react-dom": "^19.2.7",
120
+ "remark-gfm": "^4.0.1",
121
+ "storybook": "^10.3.5",
122
+ "storybook-dark-mode": "^5.0.0",
123
+ "storybook-solidjs-vite": "^10.0.12",
124
+ "tailwindcss": "^4.2.2",
125
+ "tw-animate-css": "^1.4.0",
126
+ "typescript": "^5.5.0",
127
+ "vite": "^6.0.0",
128
+ "vite-plugin-dts": "^4.5.4",
129
+ "vite-plugin-solid": "^2.11.0",
130
+ "vitest": "^4.1.0"
131
+ },
132
+ "peerDependencies": {
133
+ "react": ">=18",
134
+ "solid-js": "^1.9.0"
135
+ },
136
+ "peerDependenciesMeta": {
137
+ "react": {
138
+ "optional": true
139
+ }
140
+ }
141
+ }
@@ -0,0 +1,138 @@
1
+ import type { Meta, StoryObj } from 'storybook-solidjs-vite';
2
+ import { createSignal } from 'solid-js';
3
+ import { Artifact, type ArtifactFile, type ArtifactTab } from './artifact';
4
+ import { componentDescription } from '../stories/docs/element-controls';
5
+
6
+ // Storybook serves examples/artifact-fixtures at /artifact-fixtures.
7
+ const BASE = new URL('artifact-fixtures', document.baseURI).href;
8
+
9
+ const FILES: ArtifactFile[] = [
10
+ {
11
+ path: 'index.html',
12
+ url: `${BASE}/index.html`,
13
+ type: 'html',
14
+ language: 'html',
15
+ code: `<!DOCTYPE html>\n<html lang="en">\n <head><link rel="stylesheet" href="css/site.css" /></head>\n <body><h1>Starboard</h1><a href="about.html">About</a></body>\n</html>`,
16
+ },
17
+ {
18
+ path: 'about.html',
19
+ url: `${BASE}/about.html`,
20
+ type: 'html',
21
+ language: 'html',
22
+ code: `<!DOCTYPE html>\n<html lang="en">\n <body data-page="about"><h1>About</h1><a href="index.html">Home</a></body>\n</html>`,
23
+ },
24
+ {
25
+ path: 'css/site.css',
26
+ url: `${BASE}/css/site.css`,
27
+ type: 'other',
28
+ language: 'css',
29
+ code: `:root { --accent: #6ea8fe; }\nbody { font-family: system-ui, sans-serif; }`,
30
+ },
31
+ { path: 'assets/logo.svg', url: `${BASE}/assets/logo.svg`, type: 'image' },
32
+ { path: 'assets/report.pdf', url: `${BASE}/assets/report.pdf`, type: 'pdf' },
33
+ ];
34
+
35
+ const meta = {
36
+ title: 'Solid (Advanced)/Elements/Artifact',
37
+ component: Artifact,
38
+ tags: ['autodocs'],
39
+ parameters: {
40
+ layout: 'padded',
41
+ docs: {
42
+ description: componentDescription([
43
+ 'A framed, switchable **generated-artifact viewer** — the "canvas / artifacts" pattern. A sandboxed `<iframe>` with a functional nav toolbar (back · forward · reload · home + editable path field) and a **Preview | Code** toggle; the Code tab shows a `FileTree` + the active file source via `CodeBlock`.',
44
+ '**When to use:** to show an AI-generated artifact your backend hosts (page, doc, image, PDF) beside the conversation. The component frames; your backend serves — so relative links, back/forward and multi-format work natively.',
45
+ '**How to use:** set `src` to the hosted URL and `files` (`{ path, url?, code?, language?, type? }[]`) for the Code tree. The iframe `sandbox` defaults to `allow-scripts allow-forms` (not `allow-same-origin`). Handle `onNavigate(url)`, `onTabChange(tab)`, `onFileSelect(path)`.',
46
+ '**Placement:** the preview/canvas panel of a chat shell (e.g. `list | chat | artifact`). It **fills** its container — give the parent a height.',
47
+ ]),
48
+ },
49
+ },
50
+ argTypes: {
51
+ files: { control: false },
52
+ src: { control: 'text' },
53
+ tab: { control: 'select', options: ['preview', 'code'] },
54
+ sandbox: { control: 'text' },
55
+ },
56
+ args: { src: `${BASE}/index.html`, files: FILES, tab: 'preview' as ArtifactTab },
57
+ render: (args) => (
58
+ <div class="h-[520px] w-full max-w-[900px]">
59
+ <Artifact
60
+ src={args.src}
61
+ files={args.files}
62
+ tab={args.tab}
63
+ sandbox={args.sandbox}
64
+ iframeTitle="Starboard artifact preview"
65
+ />
66
+ </div>
67
+ ),
68
+ } satisfies Meta<typeof Artifact>;
69
+
70
+ export default meta;
71
+ type Story = StoryObj<typeof meta>;
72
+
73
+ const IMPORT = `import { Artifact } from '@kitn.ai/ui';`;
74
+ const src = (code: string) => ({
75
+ parameters: { docs: { source: { code: `${IMPORT}\n\n${code}`, language: 'tsx' } } },
76
+ });
77
+
78
+ export const Playground: Story = {
79
+ ...src(`<Artifact src={src} files={files} tab="preview" />`),
80
+ };
81
+
82
+ export const CodeTab: Story = {
83
+ name: 'Code tab',
84
+ args: { tab: 'code' as ArtifactTab },
85
+ render: (args: { src?: string; files: ArtifactFile[] }) => (
86
+ <div class="h-[520px] w-full max-w-[900px]">
87
+ <Artifact src={args.src} files={args.files} tab="code" activeFile="index.html" iframeTitle="Starboard artifact preview" />
88
+ </div>
89
+ ),
90
+ ...src(`<Artifact src={src} files={files} tab="code" activeFile="index.html" />`),
91
+ };
92
+
93
+ /** Controlled — observe the emitted nav model. */
94
+ export const Controlled: Story = {
95
+ render: () => {
96
+ const [log, setLog] = createSignal<string[]>([]);
97
+ const push = (s: string) => setLog((l) => [s, ...l].slice(0, 6));
98
+ return (
99
+ <div class="flex flex-col gap-2">
100
+ <div class="h-[420px] w-full max-w-[900px]">
101
+ <Artifact
102
+ src={`${BASE}/index.html`}
103
+ files={FILES}
104
+ iframeTitle="Starboard artifact preview"
105
+ onNavigate={(url) => push(`navigate → ${url}`)}
106
+ onTabChange={(t) => push(`kai-tab-change → ${t}`)}
107
+ onFileSelect={(p) => push(`kai-file-select → ${p}`)}
108
+ />
109
+ </div>
110
+ <pre class="m-0 min-h-24 max-w-[900px] rounded-lg bg-muted px-3 py-2.5 text-xs text-muted-foreground">
111
+ {log().length ? log().join('\n') : '(navigate the preview / switch tabs / pick a file…)'}
112
+ </pre>
113
+ </div>
114
+ );
115
+ },
116
+ ...src(`<Artifact src={src} files={files}
117
+ onNavigate={(url) => …} onTabChange={(t) => …} onFileSelect={(p) => …} />`),
118
+ };
119
+
120
+ /** PDFs render inline via pdf.js (loaded on demand from a CDN). */
121
+ export const PdfPreview: Story = {
122
+ name: 'PDF (inline)',
123
+ render: () => (
124
+ <div class="h-[520px] w-full max-w-[900px]">
125
+ <Artifact src={`${BASE}/assets/report.pdf`} files={FILES} />
126
+ </div>
127
+ ),
128
+ };
129
+
130
+ /** Fallback card when inline rendering can't work (here the src 404s). */
131
+ export const PdfFallback: Story = {
132
+ name: 'PDF (fallback card)',
133
+ render: () => (
134
+ <div class="h-[520px] w-full max-w-[900px]">
135
+ <Artifact src={`${BASE}/assets/does-not-exist.pdf`} />
136
+ </div>
137
+ ),
138
+ };