@kitn.ai/ui 0.17.0 → 0.18.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 (494) hide show
  1. package/README.md +28 -5
  2. package/dist/components/artifact.d.ts +39 -1
  3. package/dist/components/attachment-types.d.ts +12 -0
  4. package/dist/components/attachments.d.ts +2 -10
  5. package/dist/components/card.d.ts +27 -0
  6. package/dist/components/chain-of-thought.d.ts +78 -2
  7. package/dist/components/chat-scope-picker.d.ts +7 -0
  8. package/dist/components/chat-thread.d.ts +37 -12
  9. package/dist/components/choice-card.d.ts +26 -0
  10. package/dist/components/coachmark.d.ts +49 -0
  11. package/dist/components/composer-dom.d.ts +35 -0
  12. package/dist/components/composer-highlight.d.ts +48 -0
  13. package/dist/components/composer-history.d.ts +34 -0
  14. package/dist/components/composer.d.ts +86 -0
  15. package/dist/components/confirm-card.d.ts +17 -0
  16. package/dist/components/conversation-item.d.ts +9 -0
  17. package/dist/components/conversation-list.d.ts +36 -1
  18. package/dist/components/file-tree.d.ts +15 -0
  19. package/dist/components/form.d.ts +34 -0
  20. package/dist/components/markdown.d.ts +3 -0
  21. package/dist/components/message.d.ts +12 -0
  22. package/dist/components/model-switcher.d.ts +7 -0
  23. package/dist/components/prompt-input.d.ts +13 -4
  24. package/dist/components/prompt-suggestion.d.ts +9 -1
  25. package/dist/components/reasoning.d.ts +14 -1
  26. package/dist/components/response-compare.d.ts +14 -0
  27. package/dist/components/screen.d.ts +46 -0
  28. package/dist/components/tasks-card.d.ts +49 -1
  29. package/dist/components/toast.d.ts +12 -2
  30. package/dist/components/tool-types.d.ts +10 -0
  31. package/dist/components/tool.d.ts +8 -8
  32. package/dist/components/voice-input.d.ts +27 -0
  33. package/dist/components/voice-output.d.ts +33 -0
  34. package/dist/core-C8fzo39E.js +12 -0
  35. package/dist/custom-elements.json +8392 -1860
  36. package/dist/elements/agent-card.d.ts +1 -0
  37. package/dist/elements/agent-card.js +1 -0
  38. package/dist/elements/artifact.js +1 -1
  39. package/dist/elements/attachments.js +1 -1
  40. package/dist/elements/autoloader.js +1 -1
  41. package/dist/elements/avatar.d.ts +1 -0
  42. package/dist/elements/avatar.js +1 -0
  43. package/dist/elements/badge.d.ts +1 -0
  44. package/dist/elements/badge.js +1 -0
  45. package/dist/elements/button.d.ts +1 -0
  46. package/dist/elements/button.js +1 -0
  47. package/dist/elements/card.js +1 -1
  48. package/dist/elements/cards.js +1 -1
  49. package/dist/elements/chain-of-thought.js +1 -1
  50. package/dist/elements/chat-scope-picker.js +1 -1
  51. package/dist/elements/chat-types.d.ts +47 -0
  52. package/dist/elements/chat-workspace.js +1 -1
  53. package/dist/elements/chat.js +1 -1
  54. package/dist/elements/checkpoint.js +1 -1
  55. package/dist/elements/choice.js +1 -1
  56. package/dist/elements/chunks/Icon-DLLBeLG5.js +1 -0
  57. package/dist/elements/chunks/action-icons-UB4V5FNq.js +1 -0
  58. package/dist/elements/chunks/arrow-left-C-gwlUmx.js +1 -0
  59. package/dist/elements/chunks/attachments-CgbErf1r.js +1 -0
  60. package/dist/elements/chunks/badge-DTQpgB6N.js +1 -0
  61. package/dist/elements/chunks/button-XDUM6lXs.js +1 -0
  62. package/dist/elements/chunks/card-CBlFZ-7I.js +1 -0
  63. package/dist/elements/chunks/chat-thread-BIhmqwNL.js +1 -0
  64. package/dist/elements/chunks/check-hGUoVIKb.js +1 -0
  65. package/dist/elements/chunks/chevron-down-DDoaSUtO.js +1 -0
  66. package/dist/elements/chunks/chevron-right-CdGEUakB.js +1 -0
  67. package/dist/elements/chunks/circle-BKAZdmzb.js +1 -0
  68. package/dist/elements/chunks/circle-check-CmYG-y3I.js +1 -0
  69. package/dist/elements/chunks/circle-x-DewgAEym.js +1 -0
  70. package/dist/elements/chunks/cn-CU7UAWzk.js +1 -0
  71. package/dist/elements/chunks/code-block-DedwxwFI.js +1 -0
  72. package/dist/elements/chunks/collapsible-FfgmTHtM.js +1 -0
  73. package/dist/elements/chunks/composer-Cfbw5HKT.js +65 -0
  74. package/dist/elements/chunks/context-DwJmxlRE.js +1 -0
  75. package/dist/elements/chunks/conversation-list-DsCQMfPq.js +1 -0
  76. package/dist/elements/chunks/default-input-BuqsoENC.js +1 -0
  77. package/dist/elements/chunks/define-rGsaWsLL.js +1 -0
  78. package/dist/elements/chunks/disclosure-CwoAkpMH.js +1 -0
  79. package/dist/elements/chunks/download-DJ06G3Bz.js +1 -0
  80. package/dist/elements/chunks/dropdown-BFg8ri_R.js +1 -0
  81. package/dist/elements/chunks/ellipsis-dlN6YvGw.js +1 -0
  82. package/dist/elements/chunks/external-link-DBX2lc_R.js +1 -0
  83. package/dist/elements/chunks/file-text-HfwUx4F9.js +1 -0
  84. package/dist/elements/chunks/file-tree-C6Toj71u.js +1 -0
  85. package/dist/elements/chunks/folder-MYuqa9Xp.js +1 -0
  86. package/dist/elements/chunks/hover-card-gE7iyXdW.js +1 -0
  87. package/dist/elements/chunks/icon-Vqz4ivrY.js +1 -0
  88. package/dist/elements/chunks/{index-CTBEJeo6.js → index-BCRhi84a.js} +1 -1
  89. package/dist/elements/chunks/info-B_toFS0l.js +1 -0
  90. package/dist/elements/chunks/input-gzbHYZvQ.js +1 -0
  91. package/dist/elements/chunks/kbd-n49c4KZm.js +1 -0
  92. package/dist/elements/chunks/link-CKPs9yM0.js +1 -0
  93. package/dist/elements/chunks/loader-q6MamGus.js +1 -0
  94. package/dist/elements/chunks/{markdown-CMTGx9r8.js → markdown-DBrcqq4S.js} +9 -9
  95. package/dist/elements/chunks/message-CTqaYI0s.js +1 -0
  96. package/dist/elements/chunks/message-feedback-Cvzm03w0.js +1 -0
  97. package/dist/elements/chunks/message-square-CUg9eRCi.js +1 -0
  98. package/dist/elements/chunks/minimize-2-l2klxP6K.js +1 -0
  99. package/dist/elements/chunks/model-switcher-CmyjiHO1.js +1 -0
  100. package/dist/elements/chunks/overlay-C8sOYqjT.js +1 -0
  101. package/dist/elements/chunks/paperclip-42Ia7xHD.js +1 -0
  102. package/dist/elements/chunks/progress-bar-tzKMWAwO.js +1 -0
  103. package/dist/elements/chunks/prompt-suggestion-D3F6vP_A.js +1 -0
  104. package/dist/elements/chunks/reasoning-BJNmmyov.js +1 -0
  105. package/dist/elements/chunks/resizable-BRsk19qI.js +1 -0
  106. package/dist/elements/chunks/rotate-cw-BgcggLHC.js +1 -0
  107. package/dist/elements/chunks/scroll-area-CgGbFFbT.js +1 -0
  108. package/dist/elements/chunks/separator-8hM4GdHE.js +1 -0
  109. package/dist/elements/chunks/settings-CaUIYOg-.js +1 -0
  110. package/dist/elements/chunks/settings-group-CYjOVIZQ.js +1 -0
  111. package/dist/elements/chunks/share-BTYM3Ddt.js +1 -0
  112. package/dist/elements/chunks/skeleton-DsTYrPUe.js +1 -0
  113. package/dist/elements/chunks/slots-DkZ-Cmha.js +1 -0
  114. package/dist/elements/chunks/star-9R3LBQ9n.js +1 -0
  115. package/dist/elements/chunks/store-CYl5Y0_u.js +1 -0
  116. package/dist/elements/chunks/text-shimmer-CaYGv8Se.js +1 -0
  117. package/dist/elements/chunks/textarea-NEr2SLcD.js +1 -0
  118. package/dist/elements/chunks/thumbs-up-DZYZkFfc.js +1 -0
  119. package/dist/elements/chunks/toast-store-ClxVZRcc.js +1 -0
  120. package/dist/elements/chunks/tool-CHZOmoe9.js +1 -0
  121. package/dist/elements/chunks/tooltip-WpHElELC.js +1 -0
  122. package/dist/elements/chunks/triangle-alert-BlS80PUg.js +1 -0
  123. package/dist/elements/chunks/use-card-resolution-VSVoxDeJ.js +1 -0
  124. package/dist/elements/chunks/video-DxTPZqT8.js +1 -0
  125. package/dist/elements/chunks/x-C1qtndxn.js +1 -0
  126. package/dist/elements/coachmark.d.ts +1 -0
  127. package/dist/elements/coachmark.js +1 -0
  128. package/dist/elements/code-block.js +1 -1
  129. package/dist/elements/command.d.ts +1 -0
  130. package/dist/elements/command.js +1 -0
  131. package/dist/elements/compare.js +1 -1
  132. package/dist/elements/composer.d.ts +1 -0
  133. package/dist/elements/composer.js +1 -0
  134. package/dist/elements/confirm-card.js +1 -1
  135. package/dist/elements/context-meter.js +1 -1
  136. package/dist/elements/conversation-list.js +1 -1
  137. package/dist/elements/css.d.ts +1 -0
  138. package/dist/elements/default-input.d.ts +51 -0
  139. package/dist/elements/define.d.ts +53 -0
  140. package/dist/elements/dialog.d.ts +1 -0
  141. package/dist/elements/dialog.js +1 -0
  142. package/dist/elements/disclosure.d.ts +37 -0
  143. package/dist/elements/editable-label.d.ts +1 -0
  144. package/dist/elements/editable-label.js +1 -0
  145. package/dist/elements/embed.js +1 -1
  146. package/dist/elements/empty.js +1 -1
  147. package/dist/elements/feedback-bar.js +1 -1
  148. package/dist/elements/file-tree.js +1 -1
  149. package/dist/elements/file-upload.js +1 -1
  150. package/dist/elements/form.js +1 -1
  151. package/dist/elements/hover-card.d.ts +1 -0
  152. package/dist/elements/hover-card.js +1 -0
  153. package/dist/elements/icon.d.ts +1 -0
  154. package/dist/elements/icon.js +1 -0
  155. package/dist/elements/image.js +1 -1
  156. package/dist/elements/input.d.ts +1 -0
  157. package/dist/elements/input.js +1 -0
  158. package/dist/elements/kbd.d.ts +1 -0
  159. package/dist/elements/kbd.js +1 -0
  160. package/dist/elements/link-preview.js +1 -1
  161. package/dist/elements/loader.js +1 -1
  162. package/dist/elements/markdown.js +1 -1
  163. package/dist/elements/menu.d.ts +1 -0
  164. package/dist/elements/menu.js +1 -0
  165. package/dist/elements/message-skills.js +1 -1
  166. package/dist/elements/message.js +1 -1
  167. package/dist/elements/model-switcher.js +1 -1
  168. package/dist/elements/nav.d.ts +1 -0
  169. package/dist/elements/nav.js +1 -0
  170. package/dist/elements/notice.d.ts +1 -0
  171. package/dist/elements/notice.js +1 -0
  172. package/dist/elements/pane-group.d.ts +1 -0
  173. package/dist/elements/pane-group.js +1 -0
  174. package/dist/elements/pane.d.ts +1 -0
  175. package/dist/elements/pane.js +1 -0
  176. package/dist/elements/popover.js +1 -1
  177. package/dist/elements/progress-bar.d.ts +1 -0
  178. package/dist/elements/progress-bar.js +1 -0
  179. package/dist/elements/prompt-dock.d.ts +1 -0
  180. package/dist/elements/prompt-dock.js +1 -0
  181. package/dist/elements/prompt-input.js +1 -1
  182. package/dist/elements/prompt-suggestions.js +1 -1
  183. package/dist/elements/reasoning.js +1 -1
  184. package/dist/elements/register-impl.d.ts +0 -0
  185. package/dist/elements/register.d.ts +13 -0
  186. package/dist/elements/remote.d.ts +1 -0
  187. package/dist/elements/remote.js +1 -0
  188. package/dist/elements/resizable.js +1 -1
  189. package/dist/elements/response-stream.js +2 -2
  190. package/dist/elements/screen.d.ts +1 -0
  191. package/dist/elements/screen.js +1 -0
  192. package/dist/elements/scroll-area.d.ts +1 -0
  193. package/dist/elements/scroll-area.js +1 -0
  194. package/dist/elements/scroll-button.js +1 -1
  195. package/dist/elements/search.d.ts +1 -0
  196. package/dist/elements/search.js +1 -0
  197. package/dist/elements/segmented.d.ts +1 -0
  198. package/dist/elements/segmented.js +1 -0
  199. package/dist/elements/separator.d.ts +1 -0
  200. package/dist/elements/separator.js +1 -0
  201. package/dist/elements/setting-item.d.ts +1 -0
  202. package/dist/elements/setting-item.js +1 -0
  203. package/dist/elements/settings-group.d.ts +1 -0
  204. package/dist/elements/settings-group.js +1 -0
  205. package/dist/elements/skeleton.d.ts +1 -0
  206. package/dist/elements/skeleton.js +1 -0
  207. package/dist/elements/slots.d.ts +176 -0
  208. package/dist/elements/source.js +1 -1
  209. package/dist/elements/status.d.ts +1 -0
  210. package/dist/elements/status.js +1 -0
  211. package/dist/elements/switch.js +1 -1
  212. package/dist/elements/tabs.d.ts +1 -0
  213. package/dist/elements/tabs.js +1 -0
  214. package/dist/elements/tasks.js +1 -1
  215. package/dist/elements/text-shimmer.js +1 -1
  216. package/dist/elements/thinking-bar.js +1 -1
  217. package/dist/elements/toast.js +1 -1
  218. package/dist/elements/tool.js +1 -1
  219. package/dist/elements/tooltip.d.ts +1 -0
  220. package/dist/elements/tooltip.js +1 -0
  221. package/dist/elements/voice-input.js +1 -1
  222. package/dist/elements/voice-output.d.ts +1 -0
  223. package/dist/elements/voice-output.js +1 -0
  224. package/dist/elements.d.ts +733 -58
  225. package/dist/engine-javascript-C1x7zo1_.js +141 -0
  226. package/dist/index.d.ts +3 -2
  227. package/dist/index.js +8256 -5703
  228. package/dist/kai.es.js +1 -0
  229. package/dist/llms/llms-full.txt +1146 -64
  230. package/dist/llms/llms.txt +4 -4
  231. package/dist/mcp.es.js +62 -7
  232. package/dist/primitives/composer-model.d.ts +22 -0
  233. package/dist/primitives/composer-triggers.d.ts +19 -0
  234. package/dist/primitives/create-kai-chat.d.ts +38 -0
  235. package/dist/primitives/toast-store.d.ts +32 -2
  236. package/dist/primitives/use-speech-recognition.d.ts +26 -0
  237. package/dist/react/index.d.ts +1085 -97
  238. package/dist/react/runtime.d.ts +9 -2
  239. package/dist/react/use-kai-chat.d.ts +41 -0
  240. package/dist/react.js +572 -193
  241. package/dist/register-impl-CYWGkgbI.js +141 -0
  242. package/dist/schemas/tasks.schema.json +2 -2
  243. package/dist/state/index.d.ts +4 -0
  244. package/dist/state/messages.d.ts +11 -0
  245. package/dist/state/stream.d.ts +22 -0
  246. package/dist/state/suggestions.d.ts +4 -0
  247. package/dist/state.js +117 -0
  248. package/dist/theme.tokens.css +87 -0
  249. package/dist/types.d.ts +4 -0
  250. package/dist/ui/agent-card.d.ts +61 -0
  251. package/dist/ui/button.d.ts +5 -2
  252. package/dist/ui/card.d.ts +61 -0
  253. package/dist/ui/collapsible.d.ts +15 -1
  254. package/dist/ui/command.d.ts +33 -0
  255. package/dist/ui/dialog.d.ts +42 -0
  256. package/dist/ui/dropdown.d.ts +95 -1
  257. package/dist/ui/editable-label.d.ts +26 -0
  258. package/dist/ui/hover-card.d.ts +13 -1
  259. package/dist/ui/icon.d.ts +18 -0
  260. package/dist/ui/input.d.ts +33 -0
  261. package/dist/ui/kbd.d.ts +21 -0
  262. package/dist/ui/nav.d.ts +62 -0
  263. package/dist/ui/notice.d.ts +31 -0
  264. package/dist/ui/overlay.d.ts +12 -0
  265. package/dist/ui/pane-grid.d.ts +58 -0
  266. package/dist/ui/pane-group.d.ts +75 -0
  267. package/dist/ui/pane.d.ts +78 -0
  268. package/dist/ui/popover.d.ts +11 -1
  269. package/dist/ui/progress-bar.d.ts +23 -0
  270. package/dist/ui/prompt-dock.d.ts +96 -0
  271. package/dist/ui/resizable.d.ts +12 -0
  272. package/dist/ui/scroll-area.d.ts +4 -0
  273. package/dist/ui/segmented.d.ts +28 -0
  274. package/dist/ui/settings-group.d.ts +32 -0
  275. package/dist/ui/skeleton.d.ts +12 -0
  276. package/dist/ui/stat.d.ts +16 -0
  277. package/dist/ui/status.d.ts +13 -0
  278. package/dist/ui/switch.d.ts +8 -1
  279. package/dist/ui/tabs.d.ts +35 -0
  280. package/dist/ui/tooltip.d.ts +19 -1
  281. package/frameworks/react/index.tsx +1042 -157
  282. package/frameworks/react/runtime.tsx +30 -1
  283. package/frameworks/react/use-kai-chat.tsx +87 -0
  284. package/llms-full.txt +1146 -64
  285. package/llms.txt +4 -4
  286. package/package.json +23 -8
  287. package/src/agent-tooling/mcp/manifest.ts +14 -0
  288. package/src/agent-tooling/mcp/tools/debug.ts +10 -6
  289. package/src/agent-tooling/mcp/tools/reference.ts +32 -0
  290. package/src/agent-tooling/mcp/tools/scaffold.ts +30 -1
  291. package/src/components/artifact.tsx +98 -13
  292. package/src/components/attachment-types.ts +13 -0
  293. package/src/components/attachments.tsx +4 -14
  294. package/src/components/card.tsx +109 -15
  295. package/src/components/chain-of-thought.tsx +210 -1
  296. package/src/components/chat-scope-picker.tsx +13 -3
  297. package/src/components/chat-thread.tsx +225 -116
  298. package/src/components/choice-card.tsx +103 -11
  299. package/src/components/coachmark.tsx +245 -0
  300. package/src/components/component-meta.json +691 -102
  301. package/src/components/composer-dom.ts +159 -0
  302. package/src/components/composer-highlight.ts +242 -0
  303. package/src/components/composer-history.ts +82 -0
  304. package/src/components/composer.tsx +979 -0
  305. package/src/components/confirm-card.tsx +54 -1
  306. package/src/components/conversation-item.tsx +69 -7
  307. package/src/components/conversation-list.tsx +134 -37
  308. package/src/components/file-tree.tsx +197 -47
  309. package/src/components/form-widgets.tsx +9 -7
  310. package/src/components/form.tsx +140 -17
  311. package/src/components/image.tsx +3 -5
  312. package/src/components/link-preview.tsx +5 -4
  313. package/src/components/markdown.tsx +5 -2
  314. package/src/components/message.tsx +23 -4
  315. package/src/components/model-switcher.tsx +19 -4
  316. package/src/components/prompt-input.tsx +46 -75
  317. package/src/components/prompt-suggestion.tsx +48 -16
  318. package/src/components/reasoning.tsx +29 -6
  319. package/src/components/response-compare.tsx +31 -2
  320. package/src/components/screen.tsx +176 -0
  321. package/src/components/tasks-card.tsx +342 -21
  322. package/src/components/toast.tsx +119 -31
  323. package/src/components/tool-types.ts +10 -0
  324. package/src/components/tool.tsx +22 -16
  325. package/src/components/voice-input.tsx +102 -19
  326. package/src/components/voice-output.tsx +202 -0
  327. package/src/elements/agent-card.tsx +67 -0
  328. package/src/elements/artifact.tsx +53 -4
  329. package/src/elements/attachments.tsx +1 -0
  330. package/src/elements/avatar.tsx +33 -0
  331. package/src/elements/badge.tsx +32 -0
  332. package/src/elements/button.tsx +126 -0
  333. package/src/elements/card-media.jpg +0 -0
  334. package/src/elements/card.tsx +124 -31
  335. package/src/elements/cards.tsx +81 -7
  336. package/src/elements/chain-of-thought.tsx +77 -32
  337. package/src/elements/chat-scope-picker.tsx +35 -8
  338. package/src/elements/chat-types.ts +2 -2
  339. package/src/elements/chat-workspace.tsx +153 -41
  340. package/src/elements/chat.tsx +45 -23
  341. package/src/elements/choice.tsx +71 -19
  342. package/src/elements/coachmark.tsx +90 -0
  343. package/src/elements/command.tsx +209 -0
  344. package/src/elements/compare.tsx +24 -2
  345. package/src/elements/compiled.css +1 -1
  346. package/src/elements/composer.tsx +151 -0
  347. package/src/elements/confirm-card.tsx +36 -11
  348. package/src/elements/conversation-list.tsx +80 -11
  349. package/src/elements/default-input.tsx +75 -53
  350. package/src/elements/define.tsx +47 -6
  351. package/src/elements/dialog.tsx +98 -0
  352. package/src/elements/disclosure.ts +73 -0
  353. package/src/elements/editable-label.tsx +125 -0
  354. package/src/elements/element-manifest.json +129 -1
  355. package/src/elements/element-meta.json +5562 -1336
  356. package/src/elements/element-types.d.ts +732 -57
  357. package/src/elements/file-tree.tsx +12 -2
  358. package/src/elements/file-upload.tsx +1 -1
  359. package/src/elements/form.tsx +54 -11
  360. package/src/elements/hover-card.tsx +80 -0
  361. package/src/elements/icon-names.json +48 -0
  362. package/src/elements/icon.tsx +41 -0
  363. package/src/elements/input.tsx +203 -0
  364. package/src/elements/kbd.tsx +45 -0
  365. package/src/elements/menu.tsx +217 -0
  366. package/src/elements/message.tsx +58 -11
  367. package/src/elements/model-switcher.tsx +27 -1
  368. package/src/elements/nav.tsx +87 -0
  369. package/src/elements/notice.tsx +53 -0
  370. package/src/elements/pane-group.tsx +119 -0
  371. package/src/elements/pane.tsx +129 -0
  372. package/src/elements/popover.tsx +39 -17
  373. package/src/elements/progress-bar.tsx +39 -0
  374. package/src/elements/prompt-dock.tsx +81 -0
  375. package/src/elements/prompt-input.tsx +112 -63
  376. package/src/elements/prompt-suggestions.tsx +25 -9
  377. package/src/elements/reasoning.tsx +30 -9
  378. package/src/elements/register-impl.ts +38 -3
  379. package/src/elements/register.ts +11 -3
  380. package/src/elements/resizable.tsx +48 -11
  381. package/src/elements/screen.tsx +90 -0
  382. package/src/elements/scroll-area.tsx +33 -0
  383. package/src/elements/search.tsx +180 -0
  384. package/src/elements/segmented.tsx +135 -0
  385. package/src/elements/separator.tsx +36 -0
  386. package/src/elements/setting-item.tsx +50 -0
  387. package/src/elements/settings-group.tsx +37 -0
  388. package/src/elements/skeleton.tsx +45 -0
  389. package/src/elements/slots.ts +607 -0
  390. package/src/elements/source.tsx +13 -6
  391. package/src/elements/status.tsx +42 -0
  392. package/src/elements/switch.tsx +89 -14
  393. package/src/elements/tabs.tsx +95 -0
  394. package/src/elements/tasks.tsx +70 -14
  395. package/src/elements/toast.tsx +17 -2
  396. package/src/elements/tool.tsx +43 -9
  397. package/src/elements/tooltip.tsx +85 -0
  398. package/src/elements/video-poster.jpg +0 -0
  399. package/src/elements/voice-input.tsx +66 -16
  400. package/src/elements/voice-output.tsx +69 -0
  401. package/src/index.ts +5 -2
  402. package/src/primitives/card-schemas/tasks.schema.json +2 -2
  403. package/src/primitives/composer-model.ts +49 -0
  404. package/src/primitives/composer-triggers.ts +35 -0
  405. package/src/primitives/create-kai-chat.ts +66 -0
  406. package/src/primitives/toast-store.ts +43 -2
  407. package/src/primitives/use-speech-recognition.ts +135 -0
  408. package/src/state/index.ts +6 -0
  409. package/src/state/messages.ts +36 -0
  410. package/src/state/stream.ts +92 -0
  411. package/src/state/suggestions.ts +9 -0
  412. package/src/types.ts +4 -0
  413. package/src/ui/agent-card.tsx +212 -0
  414. package/src/ui/button.tsx +16 -5
  415. package/src/ui/card.tsx +245 -0
  416. package/src/ui/collapsible.tsx +30 -4
  417. package/src/ui/command.tsx +99 -0
  418. package/src/ui/dialog.tsx +217 -0
  419. package/src/ui/dropdown.tsx +375 -13
  420. package/src/ui/editable-label.tsx +112 -0
  421. package/src/ui/hover-card.tsx +28 -5
  422. package/src/ui/icon.tsx +110 -0
  423. package/src/ui/input.tsx +132 -0
  424. package/src/ui/kbd.tsx +118 -0
  425. package/src/ui/nav.tsx +282 -0
  426. package/src/ui/notice.tsx +84 -0
  427. package/src/ui/overlay.tsx +108 -2
  428. package/src/ui/pane-grid.tsx +116 -0
  429. package/src/ui/pane-group.tsx +280 -0
  430. package/src/ui/pane.tsx +193 -0
  431. package/src/ui/popover.tsx +16 -2
  432. package/src/ui/progress-bar.tsx +83 -0
  433. package/src/ui/prompt-dock.tsx +145 -0
  434. package/src/ui/resizable.tsx +69 -1
  435. package/src/ui/scroll-area.tsx +14 -3
  436. package/src/ui/segmented.tsx +109 -0
  437. package/src/ui/settings-group.tsx +67 -0
  438. package/src/ui/skeleton.tsx +62 -5
  439. package/src/ui/stat.tsx +41 -0
  440. package/src/ui/status.tsx +48 -0
  441. package/src/ui/switch.tsx +49 -23
  442. package/src/ui/tabs.tsx +168 -0
  443. package/src/ui/tooltip.tsx +52 -8
  444. package/theme.css +113 -0
  445. package/dist/components/slash-command.d.ts +0 -15
  446. package/dist/elements/chunks/Icon-D_Zmwmwh.js +0 -1
  447. package/dist/elements/chunks/action-icons-PVfIvcuG.js +0 -1
  448. package/dist/elements/chunks/attachments-Dp6vqtrc.js +0 -1
  449. package/dist/elements/chunks/button-CKyYD9G4.js +0 -1
  450. package/dist/elements/chunks/card-Cjho-PYk.js +0 -1
  451. package/dist/elements/chunks/chat-thread-RT808iPf.js +0 -1
  452. package/dist/elements/chunks/check-CDYaMYrM.js +0 -1
  453. package/dist/elements/chunks/chevron-down-3SBiq8HF.js +0 -1
  454. package/dist/elements/chunks/chevron-right-k2UFlIVK.js +0 -1
  455. package/dist/elements/chunks/cn-Dogu6PbV.js +0 -1
  456. package/dist/elements/chunks/code-block-BYUmfFSd.js +0 -1
  457. package/dist/elements/chunks/collapsible-BiNwdOn6.js +0 -1
  458. package/dist/elements/chunks/context-18g6oi4J.js +0 -1
  459. package/dist/elements/chunks/conversation-list-D9Y0NVdo.js +0 -1
  460. package/dist/elements/chunks/default-input-CSAoYYMd.js +0 -1
  461. package/dist/elements/chunks/download-D8K0Je8r.js +0 -1
  462. package/dist/elements/chunks/dropdown-bUs2iTia.js +0 -1
  463. package/dist/elements/chunks/external-link-6mA0wxab.js +0 -1
  464. package/dist/elements/chunks/file-text-DnaYk3Dm.js +0 -1
  465. package/dist/elements/chunks/file-tree-CgtRLlxK.js +0 -1
  466. package/dist/elements/chunks/hover-card-CIGw62gP.js +0 -1
  467. package/dist/elements/chunks/link-BlGSeoPy.js +0 -1
  468. package/dist/elements/chunks/loader-DvhR4qa0.js +0 -1
  469. package/dist/elements/chunks/message-CDZwXjhL.js +0 -1
  470. package/dist/elements/chunks/message-feedback-CYx81QiA.js +0 -1
  471. package/dist/elements/chunks/model-switcher-O_tUhoOT.js +0 -1
  472. package/dist/elements/chunks/overlay-DydXYMQW.js +0 -1
  473. package/dist/elements/chunks/prompt-suggestion-ldlWV5kd.js +0 -1
  474. package/dist/elements/chunks/reasoning-2PUnHlmr.js +0 -1
  475. package/dist/elements/chunks/resizable-B5WNbSeb.js +0 -1
  476. package/dist/elements/chunks/star-t9tI-P0q.js +0 -1
  477. package/dist/elements/chunks/store-C6rIooZz.js +0 -1
  478. package/dist/elements/chunks/text-shimmer-uh9V_KUh.js +0 -1
  479. package/dist/elements/chunks/textarea-3nm6Ia9U.js +0 -1
  480. package/dist/elements/chunks/thumbs-up-BBtguGld.js +0 -1
  481. package/dist/elements/chunks/toast-store-D8cL3fWl.js +0 -1
  482. package/dist/elements/chunks/tool-GJ3vwp1U.js +0 -1
  483. package/dist/elements/chunks/tooltip-DwKAz4XR.js +0 -1
  484. package/dist/elements/chunks/triangle-alert-Ct1zt2JL.js +0 -1
  485. package/dist/elements/chunks/use-card-resolution-D-_0Alzy.js +0 -1
  486. package/dist/elements/chunks/video-mVYiM99-.js +0 -1
  487. package/dist/elements/chunks/x-CzxL27Ch.js +0 -1
  488. package/dist/kitn-chat.es.js +0 -1
  489. package/dist/register-JyTglR6m.js +0 -1
  490. package/dist/register-impl-C6wlSsts.js +0 -77
  491. package/src/components/slash-command.tsx +0 -232
  492. package/src/elements/framework-usage.json +0 -588
  493. /package/dist/{kitn-chat-provider.d.ts → kai-provider.d.ts} +0 -0
  494. /package/dist/{kitn-chat-provider.es.js → kai-provider.es.js} +0 -0
@@ -2,7 +2,7 @@ import { For, createSignal, onMount, onCleanup } from 'solid-js';
2
2
  import { defineWebComponent } from './define';
3
3
  import { PromptSuggestion } from '../components/prompt-suggestion';
4
4
 
5
- type Item = string | { label: string; value?: string };
5
+ type Item = string | { label: string; value?: string; icon?: string };
6
6
 
7
7
  interface Props extends Record<string, unknown> {
8
8
  /** The suggestions. Strings, or `{ label, value }` when the displayed text
@@ -10,9 +10,13 @@ interface Props extends Record<string, unknown> {
10
10
  suggestions: Item[];
11
11
  /** Chip style: `'outline'` (default), `'ghost'`, or `'default'` (filled). */
12
12
  variant?: 'outline' | 'ghost' | 'default';
13
- /** Size preset for each chip. Defaults to the pill default (`'lg'`); pass
14
- * `'sm'` for smaller pills (or `'md'`). */
15
- size?: 'sm' | 'md' | 'lg' | 'icon' | 'icon-sm';
13
+ /** Row height for `layout="list"`: `'md'` (default) or `'lg'` for taller rows.
14
+ * Chips are unaffected. */
15
+ size?: 'md' | 'lg';
16
+ /** Layout: `'chips'` (default) renders a wrapping row of rounded pills;
17
+ * `'list'` renders a vertical, full-width "Ideas for you" list — each row
18
+ * is left-aligned with a leading `icon`, a label, and a hover background. */
19
+ layout?: 'chips' | 'list';
16
20
  /** Full-width left-aligned rows instead of pills. */
17
21
  block?: boolean;
18
22
  /** Substring to highlight within each suggestion. */
@@ -27,18 +31,20 @@ interface Events {
27
31
 
28
32
  const labelOf = (s: Item) => (typeof s === 'string' ? s : s.label);
29
33
  const valueOf = (s: Item) => (typeof s === 'string' ? s : s.value ?? s.label);
34
+ const iconOf = (s: Item) => (typeof s === 'string' ? undefined : s.icon);
30
35
 
31
36
  /** Parse a single `<kai-suggestion>` node into an `Item` descriptor. */
32
37
  export function parseSuggestionNode(n: Element): Item {
33
38
  const text = n.textContent?.trim() ?? '';
34
39
  const value = n.getAttribute('value') ?? text;
35
- return { label: text, value };
40
+ return { label: text, value, icon: n.getAttribute('icon') ?? undefined };
36
41
  }
37
42
 
38
43
  /**
39
44
  * `<kai-suggestions>` — a row/list of suggestion chips. Data via the
40
- * `suggestions` property; `variant`/`block`/`highlight` attributes; emits
41
- * `select`.
45
+ * `suggestions` property; `variant`/`layout`/`block`/`highlight` attributes;
46
+ * emits `select`. `layout="list"` renders the vertical "Ideas for you" list
47
+ * (leading icon + label + hover background) instead of pills.
42
48
  *
43
49
  * Alternatively, declare chips as `<kai-suggestion>` child elements
44
50
  * (light-DOM data carriers — hidden by the Shadow DOM):
@@ -53,7 +59,8 @@ export function parseSuggestionNode(n: Element): Item {
53
59
  defineWebComponent<Props, Events>('kai-suggestions', {
54
60
  suggestions: [],
55
61
  variant: 'outline',
56
- size: undefined,
62
+ size: 'md',
63
+ layout: 'chips',
57
64
  block: false,
58
65
  highlight: undefined,
59
66
  }, (props, { dispatch, flag, element }) => {
@@ -74,14 +81,23 @@ defineWebComponent<Props, Events>('kai-suggestions', {
74
81
  // Merge prop suggestions (first) with declarative children (after).
75
82
  const allSuggestions = () => [...(props.suggestions ?? []), ...slottedSuggestions()];
76
83
 
84
+ const isList = () => props.layout === 'list';
85
+
86
+ const containerClass = () =>
87
+ isList() ? 'flex flex-col gap-0.5'
88
+ : flag('block') ? 'flex flex-col gap-2'
89
+ : 'flex flex-wrap gap-2';
90
+
77
91
  return (
78
- <div class={flag('block') ? 'flex flex-col gap-2' : 'flex flex-wrap gap-2'}>
92
+ <div class={containerClass()}>
79
93
  <For each={allSuggestions()}>
80
94
  {(s) => (
81
95
  <PromptSuggestion
82
96
  variant={props.variant}
83
97
  size={props.size}
98
+ icon={iconOf(s)}
84
99
  block={flag('block')}
100
+ list={isList()}
85
101
  highlight={props.highlight}
86
102
  onClick={() => dispatch('kai-select', { value: valueOf(s) })}
87
103
  >
@@ -1,46 +1,67 @@
1
1
  import { defineWebComponent } from './define';
2
- import { Reasoning, ReasoningTrigger, ReasoningContent } from '../components/reasoning';
2
+ import { Reasoning, ReasoningTrigger, ReasoningContent, type ReasoningController } from '../components/reasoning';
3
3
  import { ChatConfig, useChatConfig } from '../primitives/chat-config';
4
+ import { wireDisclosure } from './disclosure';
4
5
 
5
6
  interface Props extends Record<string, unknown> {
6
7
  /** The reasoning text to display. */
7
8
  text: string;
8
9
  /** Trigger label. */
9
10
  label?: string;
10
- /** Controlled open state set as a property (`el.open = true`). Omit for
11
- * uncontrolled (the trigger toggles it). */
11
+ /** Drive/observe open state (Shoelace-style: settable + reflected to the `open`
12
+ * attribute; the element still self-manages on trigger click + while
13
+ * streaming). Set `el.open = true`; listen for `kai-open-change`. */
12
14
  open?: boolean;
15
+ /** Initial open state on mount (uncontrolled seed). */
16
+ defaultOpen?: boolean;
13
17
  /** While true, auto-expands (and re-collapses when it flips false). */
14
18
  streaming?: boolean;
15
19
  /** Render `text` as markdown. */
16
20
  markdown?: boolean;
21
+ /** Gate the disclosure trigger — programmatic `show()/hide()/toggle()` still
22
+ * work, but the trigger click no longer toggles. */
23
+ disabled?: boolean;
17
24
  }
18
25
 
19
26
  /** Events fired by `<kai-reasoning>`. */
20
27
  interface Events {
21
- /** Open state changed (via the trigger or streaming auto-open). */
28
+ /** The reasoning block expanded or collapsed (via the trigger, streaming
29
+ * auto-open, or a method). */
22
30
  'kai-open-change': { open: boolean };
23
31
  }
24
32
 
25
33
  /**
26
34
  * `<kai-reasoning>` — a collapsible reasoning/thinking block that auto-expands
27
- * while `streaming`. Text via the `text` property; `markdown`/`streaming` flags;
28
- * `open` is a controlled property; emits `kai-open-change`.
35
+ * while `streaming`. Text via the `text` property; `markdown`/`streaming` flags.
36
+ * Open state is the standard disclosure surface: settable+reflecting `open`,
37
+ * `kai-open-change`, and `show()`/`hide()`/`toggle()` (gated by `disabled`);
38
+ * seed with `defaultOpen`.
29
39
  */
30
40
  defineWebComponent<Props, Events>('kai-reasoning', {
31
41
  text: '',
32
42
  label: 'Reasoning',
33
43
  open: undefined,
44
+ defaultOpen: undefined,
34
45
  streaming: false,
35
46
  markdown: true,
36
- }, (props, { dispatch, flag }) => {
47
+ disabled: undefined,
48
+ }, (props, ctx) => {
49
+ const { flag } = ctx;
37
50
  const outer = useChatConfig();
51
+ let api: ReasoningController | undefined;
52
+
53
+ // The standard disclosure surface: settable+reflecting `open`, kai-open-change,
54
+ // show/hide/toggle, disabled-gating. See ./disclosure. This is the SOLE emitter
55
+ // of kai-open-change — we no longer dispatch it from Reasoning's onOpenChange.
56
+ wireDisclosure(ctx, () => api, () => props.open);
57
+
38
58
  return (
39
59
  <ChatConfig portalMount={outer.portalMount()}>
40
60
  <Reasoning
41
- open={props.open}
61
+ defaultOpen={flag('defaultOpen')}
42
62
  isStreaming={flag('streaming')}
43
- onOpenChange={(open) => dispatch('kai-open-change', { open })}
63
+ disabled={flag('disabled')}
64
+ controllerRef={(a) => (api = a)}
44
65
  >
45
66
  <ReasoningTrigger>{props.label}</ReasoningTrigger>
46
67
  <ReasoningContent markdown={flag('markdown')}>{props.text}</ReasoningContent>
@@ -22,9 +22,6 @@ import './context-meter';
22
22
  import './feedback-bar';
23
23
  import './chat-scope-picker';
24
24
  // Phase 3 — input ecosystem
25
- // (NB: SlashCommand is context-bound to PromptInput — it observes the input
26
- // value via usePromptInput() — so it is NOT a standalone element. It will fold
27
- // into <kai-prompt-input> as a `slash-commands` property in a later pass.)
28
25
  import './prompt-suggestions';
29
26
  import './file-upload';
30
27
  import './voice-input';
@@ -37,6 +34,13 @@ import './message-skills';
37
34
  import './source';
38
35
  import './response-stream';
39
36
  import './empty';
37
+ import './status';
38
+ import './nav';
39
+ import './progress-bar';
40
+ import './coachmark';
41
+ import './tabs';
42
+ import './voice-output';
43
+ import './screen';
40
44
  import './chain-of-thought';
41
45
  import './resizable';
42
46
  import './file-tree';
@@ -44,6 +48,16 @@ import './artifact';
44
48
  import './scroll-button';
45
49
  import './popover';
46
50
  import './switch';
51
+ import './button';
52
+ import './avatar';
53
+ import './badge';
54
+ import './tooltip';
55
+ import './notice';
56
+ import './icon';
57
+ import './separator';
58
+ import './scroll-area';
59
+ import './hover-card';
60
+ import './skeleton';
47
61
  import './toast';
48
62
  // Generative-UI cards (Card Contract)
49
63
  import './card';
@@ -56,3 +70,24 @@ import './choice';
56
70
  import './cards';
57
71
  // Dual-response comparison (preference capture)
58
72
  import './compare';
73
+ // Rich text composer with entity pills, trigger menus, and keyword highlighting
74
+ import './composer';
75
+ // W3 phase 2: cascading action menu from a JSON items-tree
76
+ import './menu';
77
+ // W4 phase 1: grouped filterable command/mention palette
78
+ import './command';
79
+ // Prompt dock + settings building blocks (graduated from SolidJS prototypes)
80
+ import './prompt-dock';
81
+ import './segmented';
82
+ import './settings-group';
83
+ import './setting-item';
84
+ // Multi-agent workspace primitives (graduated from SolidJS prototypes)
85
+ import './pane';
86
+ import './pane-group';
87
+ import './agent-card';
88
+ import './dialog';
89
+ // Input & search field family
90
+ import './input';
91
+ import './search';
92
+ import './kbd';
93
+ import './editable-label';
@@ -13,9 +13,17 @@
13
13
  // Registration is async (a microtask after this module loads). Consumers that
14
14
  // need the upgraded element (e.g. the React runtime) guard with
15
15
  // customElements.whenDefined(), which resolves once the impl chunk has run.
16
- if (typeof window !== 'undefined' && typeof customElements !== 'undefined') {
17
- void import('./register-impl');
18
- }
16
+ /** Resolves once the kai-* elements are registered (browser); inert on the server.
17
+ * Await this instead of customElements.whenDefined for a single ready signal.
18
+ *
19
+ * NOTE: this MUST stay an exported binding. A bare `void import('./register-impl')`
20
+ * is a result-unused dynamic import that the single-entry register-all build
21
+ * (vite.config.ts → dist/kai.es.js) tree-shakes away as dead code, leaving the
22
+ * bundle with NOTHING registered. Exporting the promise keeps the import live. */
23
+ export const elementsReady: Promise<unknown> =
24
+ typeof window !== 'undefined' && typeof customElements !== 'undefined'
25
+ ? import('./register-impl')
26
+ : Promise.resolve();
19
27
 
20
28
  export type { ChatMessage, ChatMessageAction } from './chat-types';
21
29
  export { configureCodeHighlighting, isCodeHighlightingEnabled } from '../primitives/highlighter';
@@ -1,6 +1,6 @@
1
1
  import { createSignal, createEffect, on, onMount, onCleanup, For, Show, type JSX } from 'solid-js';
2
2
  import { defineWebComponent } from './define';
3
- import { ResizableHandle, normalizeSize } from '../ui/resizable';
3
+ import { ResizableHandle, normalizeSize, clampBasis } from '../ui/resizable';
4
4
 
5
5
  type Orientation = 'horizontal' | 'vertical';
6
6
 
@@ -34,6 +34,7 @@ interface ItemInfo {
34
34
  max?: string;
35
35
  locked: boolean;
36
36
  hidden: boolean;
37
+ collapsed: boolean;
37
38
  }
38
39
 
39
40
  /** Max number of panels a single group lays out (nest for more). */
@@ -100,6 +101,13 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
100
101
  el.setAttribute('data-kai-default-size', el.getAttribute('size') ?? '');
101
102
  }
102
103
  const defaultSize = el.getAttribute('data-kai-default-size') || undefined;
104
+ // The `collapsed` boolean prop is reflected to a `collapsed` attribute by the
105
+ // item facade (see kai-resizable-item), so reading the attribute here works
106
+ // at INITIAL render from any framework — unlike the bare `hidden` boolean,
107
+ // whose JSX form sets neither the attribute nor the IDL property on a custom
108
+ // element. Treated as hidden-for-layout, independently of `hidden` so the
109
+ // back-compat hidden path (and maximize, which drives `hidden`) is untouched.
110
+ const collapsed = el.hasAttribute('collapsed') && el.getAttribute('collapsed') !== 'false';
103
111
  return {
104
112
  el,
105
113
  size: el.getAttribute('size') ?? undefined,
@@ -111,14 +119,15 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
111
119
  // (and direct `el.hidden = true`) set the property, which doesn't reflect
112
120
  // to the attribute on a custom element.
113
121
  hidden: el.hidden || (el.hasAttribute('hidden') && el.getAttribute('hidden') !== 'false'),
122
+ collapsed,
114
123
  };
115
124
  });
116
125
 
117
126
  // Assign each visible item to its panel slot by visible order; clear the
118
- // rest so hidden/extra items don't leak into a slot.
127
+ // rest so hidden/extra/collapsed items don't leak into a slot.
119
128
  let visIdx = 0;
120
129
  for (const info of parsed) {
121
- if (info.hidden) {
130
+ if (info.hidden || info.collapsed) {
122
131
  info.el.removeAttribute('slot');
123
132
  } else {
124
133
  info.el.setAttribute('slot', `p${visIdx}`);
@@ -153,12 +162,12 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
153
162
  const b = next[i];
154
163
  if (a.el !== b.el) return true;
155
164
  if (a.size !== b.size || a.min !== b.min || a.max !== b.max) return true;
156
- if (a.locked !== b.locked || a.hidden !== b.hidden) return true;
165
+ if (a.locked !== b.locked || a.hidden !== b.hidden || a.collapsed !== b.collapsed) return true;
157
166
  }
158
167
  return false;
159
168
  }
160
169
 
161
- const visible = () => items().filter((i) => !i.hidden);
170
+ const visible = () => items().filter((i) => !i.hidden && !i.collapsed);
162
171
 
163
172
  /** Compute current panel sizes (percent of container) from the rendered DOM. */
164
173
  function currentSizes(): number[] {
@@ -358,9 +367,11 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
358
367
  // maximized item is still present and visible.
359
368
  const maximizedEl = stash.item;
360
369
  const isConnected = maximizedEl.isConnected && element.contains(maximizedEl);
361
- const isVisible = isConnected && !(maximizedEl.hidden || maximizedEl.hasAttribute('hidden'));
370
+ const isVisible = isConnected
371
+ && !(maximizedEl.hidden || maximizedEl.hasAttribute('hidden'))
372
+ && !(maximizedEl.hasAttribute('collapsed') && maximizedEl.getAttribute('collapsed') !== 'false');
362
373
  if (!isConnected || !isVisible) {
363
- // The maximized item was removed or hidden out from under us → restore.
374
+ // The maximized item was removed or hidden/collapsed out from under us → restore.
364
375
  restore();
365
376
  return;
366
377
  }
@@ -375,7 +386,7 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
375
386
  // the host's own attributes.
376
387
  subtree: true,
377
388
  attributes: true,
378
- attributeFilter: ['size', 'locked', 'min', 'max', 'hidden'],
389
+ attributeFilter: ['size', 'locked', 'min', 'max', 'hidden', 'collapsed'],
379
390
  });
380
391
  onCleanup(() => {
381
392
  mo.disconnect();
@@ -432,7 +443,9 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
432
443
  const min = boundAttrs(info.min);
433
444
  const max = boundAttrs(info.max);
434
445
  const def = boundAttrs(info.defaultSize);
435
- const basis = normalizeSize(info.size);
446
+ // Clamp the INITIAL basis into [min, max] so a % size on a wide
447
+ // container never paints past a px max and then snaps on first drag.
448
+ const basis = clampBasis(normalizeSize(info.size), normalizeSize(info.min), normalizeSize(info.max));
436
449
  const prev = () => visible()[i() - 1];
437
450
  const isStatic = () => !!(info.locked || prev()?.locked);
438
451
  return (
@@ -514,6 +527,16 @@ interface ItemProps extends Record<string, unknown> {
514
527
  locked?: boolean;
515
528
  /** Hide this panel; its divider is dropped and the rest reflow. */
516
529
  hidden?: boolean;
530
+ /**
531
+ * Collapse this panel — same layout effect as `hidden` (divider dropped, the
532
+ * rest reflow), but it WORKS as a bare boolean from framework JSX. A plain
533
+ * `<kai-resizable-item collapsed>` in React/Solid/Vue/Svelte collapses the panel
534
+ * at the first render; `hidden` does not, because a JSX boolean sets neither the
535
+ * `hidden` attribute nor the IDL property on a custom element, so the parent never
536
+ * sees it. The facade reflects `collapsed` to a `collapsed` attribute the parent
537
+ * reads. Prefer this over `hidden` for declarative collapse.
538
+ */
539
+ collapsed?: boolean;
517
540
  }
518
541
 
519
542
  /**
@@ -527,7 +550,20 @@ defineWebComponent<ItemProps>('kai-resizable-item', {
527
550
  max: undefined,
528
551
  locked: false,
529
552
  hidden: false,
530
- }, () => (
553
+ collapsed: false,
554
+ }, (_props, { element, flag }) => {
555
+ // Reflect the reactive `collapsed` prop to the `collapsed` ATTRIBUTE the parent
556
+ // <kai-resizable> reads (and observes). This is what makes a bare JSX boolean
557
+ // collapse the panel at INITIAL render from any framework: component-register
558
+ // parses `<kai-resizable-item collapsed>` to `undefined` (not `true`), and a JSX
559
+ // boolean sets neither `hidden` nor the IDL property — so `flag('collapsed')`
560
+ // (which also honours the attribute) is the reliable source, and toggleAttribute
561
+ // mirrors it back so the parent's readItems()/MutationObserver lay it out. Same
562
+ // pattern as <kai-chat>'s `loading` reflection. We touch only `collapsed`, never
563
+ // `hidden`, so the back-compat hidden path and maximize (which drive `hidden`)
564
+ // are untouched.
565
+ createEffect(() => { element.toggleAttribute('collapsed', flag('collapsed')); });
566
+ return (
531
567
  <>
532
568
  {/* The item host fills the panel's single grid cell (the panel stretches it on
533
569
  both axes) and OWNS the scroll: `display:block; width/height:100%;
@@ -550,4 +586,5 @@ defineWebComponent<ItemProps>('kai-resizable-item', {
550
586
  <slot />
551
587
  </div>
552
588
  </>
553
- ) as unknown as JSX.Element);
589
+ ) as unknown as JSX.Element;
590
+ });
@@ -0,0 +1,90 @@
1
+ import { defineWebComponent } from './define';
2
+ import { Screen, type ScreenController } from '../components/screen';
3
+ import { wireDisclosure } from './disclosure';
4
+
5
+ interface Props extends Record<string, unknown> {
6
+ /** Drive/observe open state (Shoelace-style: settable + reflected to the `open`
7
+ * attribute; the element still self-manages). Set `el.open = true`, or
8
+ * `<kai-screen open>`; listen for `kai-open-change`. */
9
+ open?: boolean;
10
+ /** Initial open state on mount (uncontrolled seed). */
11
+ defaultOpen?: boolean;
12
+ /** Header title text. A projected `title` slot overrides it. (Named `headline`
13
+ * because `title` collides with the global `HTMLElement.title` attribute.) */
14
+ headline?: string;
15
+ /** Show the back button (default true). */
16
+ back?: boolean;
17
+ /** Opt out of marking sibling elements inert/aria-hidden while open (for unusual layouts). */
18
+ noInert?: boolean;
19
+ }
20
+
21
+ /** Events fired by `<kai-screen>`. */
22
+ interface Events {
23
+ /** Back navigation intent: the back button or Escape. The consumer flips their
24
+ * own routing in response (the screen knows nothing about the trigger). */
25
+ 'kai-back': Record<string, never>;
26
+ /** The screen opened or closed (a method, `Escape` close, or driven `open`). */
27
+ 'kai-open-change': { open: boolean };
28
+ }
29
+
30
+ /**
31
+ * `<kai-screen>` is a developer-swapped, full-bleed overlay destination: the
32
+ * push/drill-in surface that takes over its mount point under a back-header. The
33
+ * developer owns the swap (their own routing flips `open` in response to their
34
+ * trigger button and the screen's `kai-back`); the screen owns being the takeover.
35
+ *
36
+ * It fills whatever it is mounted in (mount at the app root for a full takeover,
37
+ * in a positioned region for a scoped one), marks sibling elements `inert` while
38
+ * open (the standard modal pattern; opt out with `no-inert`), moves focus in on
39
+ * open and restores it on close, and runs an enter/exit transition that honors
40
+ * `prefers-reduced-motion`. `Escape` fires `kai-back`.
41
+ *
42
+ * ```html
43
+ * <kai-screen headline="Design">
44
+ * <button slot="actions"><kai-avatar></kai-avatar></button>
45
+ * <div>…your surface…</div>
46
+ * </kai-screen>
47
+ * ```
48
+ *
49
+ * Open state is the standard disclosure surface: settable+reflecting `open`,
50
+ * `kai-open-change`, and `show()`/`hide()`/`toggle()`; seed with `default-open`.
51
+ * Parts: `header` · `back` · `title` · `body`.
52
+ */
53
+ defineWebComponent<Props, Events>('kai-screen', {
54
+ open: undefined,
55
+ defaultOpen: undefined,
56
+ headline: undefined,
57
+ back: undefined,
58
+ noInert: undefined,
59
+ }, (props, ctx) => {
60
+ const { flag, element, dispatch, expose } = ctx;
61
+ let api: ScreenController | undefined;
62
+ let surface: HTMLElement | undefined;
63
+
64
+ // The standard disclosure surface: settable+reflecting `open`, kai-open-change,
65
+ // show/hide/toggle. See ./disclosure. This is the SOLE emitter of kai-open-change.
66
+ wireDisclosure(ctx, () => api, () => props.open);
67
+
68
+ // focus() shadows the host's native focus so it targets the screen surface
69
+ // inside the shadow root (the WebAwesome/Shoelace convention).
70
+ expose({
71
+ /** Move focus to the screen surface (no-op while closed). */
72
+ focus: (options?: FocusOptions) => surface?.focus(options),
73
+ });
74
+
75
+ return (
76
+ <Screen
77
+ defaultOpen={flag('defaultOpen')}
78
+ back={!(props.back === false || element.getAttribute('back') === 'false')}
79
+ noInert={flag('noInert')}
80
+ host={() => element}
81
+ titleSlot={<slot name="title">{props.headline as string | undefined}</slot>}
82
+ actions={<slot name="actions" />}
83
+ onBack={() => { dispatch('kai-back', {}); }}
84
+ controllerRef={(a) => (api = a)}
85
+ surfaceRef={(el) => (surface = el)}
86
+ >
87
+ <slot />
88
+ </Screen>
89
+ );
90
+ });
@@ -0,0 +1,33 @@
1
+ import { ScrollArea, type ScrollOrientation } from '../ui/scroll-area';
2
+ import { defineWebComponent } from './define';
3
+
4
+ interface Props extends Record<string, unknown> {
5
+ /** Which axis scrolls. `vertical` (default) · `horizontal` · `both`. The cross
6
+ * axis is clamped so content can't overflow it. */
7
+ orientation?: ScrollOrientation;
8
+ }
9
+
10
+ /**
11
+ * `<kai-scroll-area>` — a scroll container with a themed, thin, cross-browser
12
+ * scrollbar and a keyboard-reachable region. Project the scrollable content as
13
+ * light-DOM children and give the element a bounded size in your layout; the
14
+ * content then scrolls inside. Use `orientation` to pick the axis. Restyle the
15
+ * container via `::part(viewport)`; the scrollbar follows the
16
+ * `--color-scrollbar-thumb` token.
17
+ *
18
+ * ```html
19
+ * <kai-scroll-area style="height: 16rem">…long content…</kai-scroll-area>
20
+ * <kai-scroll-area orientation="horizontal" style="max-width: 24rem">…wide row…</kai-scroll-area>
21
+ * ```
22
+ */
23
+ defineWebComponent<Props>('kai-scroll-area', {
24
+ orientation: 'vertical',
25
+ }, (props) => (
26
+ <>
27
+ {/* The element is a block box; the consumer sets its size, the viewport fills it. */}
28
+ <style>{':host{display:block;min-height:0}'}</style>
29
+ <ScrollArea class="h-full max-h-full w-full max-w-full" part="viewport" orientation={props.orientation as ScrollOrientation}>
30
+ <slot />
31
+ </ScrollArea>
32
+ </>
33
+ ));