@kitn.ai/ui 0.28.0 → 0.30.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 (615) hide show
  1. package/README.md +11 -7
  2. package/dist/{Icon-DObhsRtm.js → Icon-BzBET3E-.js} +1 -1
  3. package/dist/{action-icons-CcgNN2oT.js → action-icons-DaW2pU6m.js} +1 -1
  4. package/dist/agent-tooling/construct/public.d.ts +15 -0
  5. package/dist/agent-tooling/construct/schema.d.ts +111 -0
  6. package/dist/arrow-down-D783iMJj.js +1 -0
  7. package/dist/arrow-left-0VLM5kyg.js +1 -0
  8. package/dist/artifact-DGjzHYUT.js +1 -0
  9. package/dist/{attachments-Qr4kg-2b.js → attachments-YvXHlg88.js} +1 -1
  10. package/dist/{audio-visualizer-DToYdfSc.js → audio-visualizer-9lz5IHsL.js} +1 -1
  11. package/dist/{badge-CdEu_jn2.js → badge-Dh_vp8A5.js} +1 -1
  12. package/dist/{bell-DQAAOpDz.js → bell-CT7_WUwS.js} +1 -1
  13. package/dist/{button-DkuOnGLy.js → button-C_3te6fm.js} +1 -1
  14. package/dist/{card-renderer-Jx70m6_l.js → card-renderer-DZVaGH2e.js} +1 -1
  15. package/dist/check-CiEOVnEN.js +1 -0
  16. package/dist/{checkbox-D7iRB3nL.js → checkbox-Bu2T2e0U.js} +1 -1
  17. package/dist/{checkbox-group-B2_rpoPM.js → checkbox-group-BiryEXPQ.js} +1 -1
  18. package/dist/chevron-down-CSobuZRG.js +1 -0
  19. package/dist/chevron-right-DR9ZAP-2.js +1 -0
  20. package/dist/{choice-card-m0BYqqOK.js → choice-card-CM6IjkmL.js} +1 -1
  21. package/dist/circle-BC66EYF7.js +1 -0
  22. package/dist/circle-check-BqmahW0O.js +1 -0
  23. package/dist/{circle-x-BPG0iPst.js → circle-x-Bk-dA5Wf.js} +1 -1
  24. package/dist/{code-block-ClMLKb7C.js → code-block-B26t-Q7q.js} +1 -1
  25. package/dist/{collapsible-B4DlWicL.js → collapsible-Bhc636Cf.js} +1 -1
  26. package/dist/components/builder-composer-triggers.d.ts +62 -0
  27. package/dist/components/builder-layout.d.ts +54 -0
  28. package/dist/components/builder-message-actions.d.ts +72 -0
  29. package/dist/components/builder-panel.d.ts +189 -0
  30. package/dist/components/builder-preview.d.ts +11 -0
  31. package/dist/components/builder-shell-controls.d.ts +69 -0
  32. package/dist/components/builder-skeleton.d.ts +58 -0
  33. package/dist/components/builder-start.d.ts +75 -0
  34. package/dist/components/builder-workspace-variants.d.ts +23 -0
  35. package/dist/components/captions.d.ts +66 -0
  36. package/dist/{composer-sQ0HcvyG.js → composer-DMI85B6j.js} +1 -1
  37. package/dist/{confirm-card-rQWDQsnC.js → confirm-card-B0YIAwXp.js} +1 -1
  38. package/dist/construct-cli.es.js +3 -3
  39. package/dist/construct.d.ts +5 -0
  40. package/dist/construct.js +327 -0
  41. package/dist/{context-0kg4ZX1J.js → context-DWgfhqWp.js} +1 -1
  42. package/dist/controllable-BagRpyHv.js +1 -0
  43. package/dist/{conversation-item-BxwQLaFJ.js → conversation-item-BsOsVGmT.js} +1 -1
  44. package/dist/{conversation-list-BCfGN1JU.js → conversation-list-aX3Vtc7L.js} +1 -1
  45. package/dist/{copy-n9u9rqpi.js → copy-BmEwsNhJ.js} +1 -1
  46. package/dist/core-C8fzo39E.js +1 -12
  47. package/dist/{create-tween-uPkArjIG.js → create-tween-CNOAU3Fx.js} +1 -1
  48. package/dist/{create-tween-C-q-JCM-.js → create-tween-WfqiENls.js} +1 -1
  49. package/dist/{create-tween-CRrJXxBd.js → create-tween-wlFtW9Kh.js} +1 -1
  50. package/dist/{create-tween-DZ3RRDHD.js → create-tween-zt79ba32.js} +1 -1
  51. package/dist/{default-input-CaMrJkgH.js → default-input-DMV5Eaze.js} +1 -1
  52. package/dist/define-CI0y3eE4.js +1 -0
  53. package/dist/define.js +40 -40
  54. package/dist/define.server.js +45 -45
  55. package/dist/{disclosure-WUImBbDv.js → disclosure-NnACBxsC.js} +1 -1
  56. package/dist/{dropdown-wZVeJOMd.js → dropdown-DT7G0RGR.js} +1 -1
  57. package/dist/elements/agent-card.js +1 -1
  58. package/dist/elements/artifact.js +1 -1
  59. package/dist/elements/attachments.js +1 -1
  60. package/dist/elements/audio-visualizer.js +1 -1
  61. package/dist/elements/avatar.js +1 -1
  62. package/dist/elements/badge.js +1 -1
  63. package/dist/elements/button.js +1 -1
  64. package/dist/elements/card.js +1 -1
  65. package/dist/elements/cards.js +1 -1
  66. package/dist/elements/chain-of-thought.js +1 -1
  67. package/dist/elements/chat-scope-picker.js +1 -1
  68. package/dist/elements/chat-workspace.js +1 -1
  69. package/dist/elements/chat.js +1 -1
  70. package/dist/elements/checkbox-group.js +1 -1
  71. package/dist/elements/checkbox.js +1 -1
  72. package/dist/elements/checkpoint.js +1 -1
  73. package/dist/elements/choice.js +1 -1
  74. package/dist/elements/coachmark.js +1 -1
  75. package/dist/elements/code-block.js +1 -1
  76. package/dist/elements/command.js +1 -1
  77. package/dist/elements/compare.js +1 -1
  78. package/dist/elements/composer.js +1 -1
  79. package/dist/elements/confirm-card.js +1 -1
  80. package/dist/elements/context-meter.js +1 -1
  81. package/dist/elements/conversation-item.js +1 -1
  82. package/dist/elements/conversation-list.js +1 -1
  83. package/dist/elements/dialog.js +1 -1
  84. package/dist/elements/dock.js +1 -1
  85. package/dist/elements/dropdown.js +1 -1
  86. package/dist/elements/editable-label.js +1 -1
  87. package/dist/elements/embed.js +1 -1
  88. package/dist/elements/empty.js +1 -1
  89. package/dist/elements/feedback-bar.js +1 -1
  90. package/dist/elements/file-tree.js +1 -1
  91. package/dist/elements/file-upload.js +1 -1
  92. package/dist/elements/form.js +1 -1
  93. package/dist/elements/hover-card.js +1 -1
  94. package/dist/elements/icon.js +1 -1
  95. package/dist/elements/image.js +1 -1
  96. package/dist/elements/input.js +1 -1
  97. package/dist/elements/kbd.js +1 -1
  98. package/dist/elements/link-preview.js +1 -1
  99. package/dist/elements/loader.js +1 -1
  100. package/dist/elements/markdown.js +1 -1
  101. package/dist/elements/menu.js +1 -1
  102. package/dist/elements/message-skills.js +1 -1
  103. package/dist/elements/message.js +1 -1
  104. package/dist/elements/model-switcher.js +1 -1
  105. package/dist/elements/nav.js +1 -1
  106. package/dist/elements/notice.js +1 -1
  107. package/dist/elements/pane-grid.js +1 -1
  108. package/dist/elements/pane-group.js +1 -1
  109. package/dist/elements/pane.js +1 -1
  110. package/dist/elements/popover.js +1 -1
  111. package/dist/elements/progress-bar.js +1 -1
  112. package/dist/elements/prompt-dock.js +1 -1
  113. package/dist/elements/prompt-input.js +1 -1
  114. package/dist/elements/prompt-suggestions.js +1 -1
  115. package/dist/elements/radio-group.js +1 -1
  116. package/dist/elements/reasoning.js +1 -1
  117. package/dist/elements/remote.js +1 -1
  118. package/dist/elements/resizable.js +1 -1
  119. package/dist/elements/response-stream.js +1 -1
  120. package/dist/elements/screen.js +1 -1
  121. package/dist/elements/scroll-area.js +1 -1
  122. package/dist/elements/scroll-button.js +1 -1
  123. package/dist/elements/search.js +1 -1
  124. package/dist/elements/segmented.js +1 -1
  125. package/dist/elements/select.js +1 -1
  126. package/dist/elements/separator.js +1 -1
  127. package/dist/elements/setting-item.js +1 -1
  128. package/dist/elements/settings-group.js +1 -1
  129. package/dist/elements/skeleton.js +1 -1
  130. package/dist/elements/slider.js +1 -1
  131. package/dist/elements/source.js +1 -1
  132. package/dist/elements/status.js +1 -1
  133. package/dist/elements/switch.js +1 -1
  134. package/dist/elements/tabs.js +1 -1
  135. package/dist/elements/tasks.js +1 -1
  136. package/dist/elements/text-shimmer.js +1 -1
  137. package/dist/elements/thinking-bar.js +1 -1
  138. package/dist/elements/thread.js +1 -1
  139. package/dist/elements/toast.js +1 -1
  140. package/dist/elements/tool.js +1 -1
  141. package/dist/elements/tooltip.js +1 -1
  142. package/dist/elements/voice-input.js +1 -1
  143. package/dist/elements/voice-output.js +1 -1
  144. package/dist/{ellipsis-CbOpJnU3.js → ellipsis-6pJ7SxYT.js} +1 -1
  145. package/dist/{embed-CrfjkbUG.js → embed-BMje-nxj.js} +1 -1
  146. package/dist/engine-javascript-C1x7zo1_.js +1 -141
  147. package/dist/{external-link-ByXAwBBQ.js → external-link-Beh9DKeR.js} +1 -1
  148. package/dist/{file-text-DMib2qwt.js → file-text-D1GPfZ8Q.js} +1 -1
  149. package/dist/{file-tree-CJqM2aP7.js → file-tree-Dwj2lqg-.js} +1 -1
  150. package/dist/{folder-_BAb929C.js → folder-b6D8x1DY.js} +1 -1
  151. package/dist/{form-DSZgZQZk.js → form-DWgdxDXu.js} +1 -1
  152. package/dist/{hover-card-BQbul9eq.js → hover-card-CWRkqm40.js} +1 -1
  153. package/dist/{icon-CdcfRhYI.js → icon-CL0jdhsf.js} +1 -1
  154. package/dist/index.js +1741 -1725
  155. package/dist/index.server.js +1582 -1566
  156. package/dist/{info-DsFjGuI_.js → info-0cOUherQ.js} +1 -1
  157. package/dist/{input-DKbmkMos.js → input-BH6Ru91Q.js} +1 -1
  158. package/dist/kai.es.js +1 -1
  159. package/dist/{kbd-PvdGhX4s.js → kbd-DRAnVtNX.js} +1 -1
  160. package/dist/{link-zF8PzWfF.js → link-Dlr0vssB.js} +1 -1
  161. package/dist/{link-preview-DbM1866N.js → link-preview-DODgRyV9.js} +1 -1
  162. package/dist/loader-KvJB6NrT.js +1 -0
  163. package/dist/{markdown-LMvmAyBk.js → markdown-DX9tuJVj.js} +1 -1
  164. package/dist/mcp.es.js +9 -5
  165. package/dist/{message-BYZECyek.js → message-BqQ7Ot5q.js} +1 -1
  166. package/dist/{message-BSsgvHvf.js → message-DkaGfBd8.js} +1 -1
  167. package/dist/message-circle-BPpp5QKv.js +1 -0
  168. package/dist/message-square-BLbsd9BJ.js +1 -0
  169. package/dist/{minimize-2-BQRoBV1V.js → minimize-2-CyOHJwcN.js} +1 -1
  170. package/dist/{model-switcher-CMpCOYcB.js → model-switcher-0hrKDiK2.js} +1 -1
  171. package/dist/{overlay-Cb-MkyDa.js → overlay-DBMFXie6.js} +1 -1
  172. package/dist/{panel-right-i8warFxT.js → panel-right-t8SWJL6e.js} +1 -1
  173. package/dist/{paperclip-ByY3UVO6.js → paperclip-CdzuOjbU.js} +1 -1
  174. package/dist/play-BXy1u7rW.js +1 -0
  175. package/dist/primitives/use-auto-resize.d.ts +11 -0
  176. package/dist/{progress-bar-jVAHvMUf.js → progress-bar-CiBtxMWT.js} +1 -1
  177. package/dist/{prompt-suggestion-CD-qtNgC.js → prompt-suggestion-I_DHP21i.js} +1 -1
  178. package/dist/{radio-BsoBMhkF.js → radio-C_p3n39l.js} +1 -1
  179. package/dist/{reasoning-4kBPtlTx.js → reasoning-BDwy_tIe.js} +1 -1
  180. package/dist/register-impl-DvEnhIxx.js +424 -0
  181. package/dist/{resizable-uPmY9VY-.js → resizable-SYC-fStM.js} +1 -1
  182. package/dist/{rotate-ccw-B2xn93py.js → rotate-ccw-B1nwmwuY.js} +1 -1
  183. package/dist/{rotate-cw-CMVLoCyH.js → rotate-cw-CLAnBcm1.js} +1 -1
  184. package/dist/{scroll-area-BqLUo8ZZ.js → scroll-area-zRyXoLhI.js} +1 -1
  185. package/dist/{scroll-button-DslXiJyL.js → scroll-button-jzrbYCG9.js} +1 -1
  186. package/dist/{select-2cLRtPGT.js → select-DM-0nEe0.js} +1 -1
  187. package/dist/{separator-BWQtNJcM.js → separator-BToOOoOt.js} +1 -1
  188. package/dist/{settings-BBR63jLg.js → settings-PaGo_S4U.js} +1 -1
  189. package/dist/{settings-group-B2ciy-Iw.js → settings-group-BFXGIfXq.js} +1 -1
  190. package/dist/{skeleton-CkHI-HgC.js → skeleton-DYpmFnnm.js} +1 -1
  191. package/dist/{slider-DDR9U-i0.js → slider-ebutAmkQ.js} +1 -1
  192. package/dist/{solid-DruVOXnf.js → solid-15v_3WVL.js} +3563 -3412
  193. package/dist/{solid-BzCFdL25.js → solid-5P-otgdi.js} +4502 -4296
  194. package/dist/solid.d.ts +6 -0
  195. package/dist/solid.js +259 -254
  196. package/dist/solid.server.js +259 -254
  197. package/dist/{source-GEnFF528.js → source-c1gpRl9h.js} +1 -1
  198. package/dist/{star-CilHq8GP.js → star-pcV_3LqF.js} +1 -1
  199. package/dist/{store-Ciyk6eZG.js → store-CSgbFFCg.js} +1 -1
  200. package/dist/{switch-KkeQIbuH.js → switch-Bh2OdLV2.js} +1 -1
  201. package/dist/{tasks-card-BrN4bggJ.js → tasks-card-CbqQAn2S.js} +1 -1
  202. package/dist/text-shimmer-BSzgEnDH.js +1 -0
  203. package/dist/textarea-DrYNt_0z.js +1 -0
  204. package/dist/theme.tokens.css +22 -21
  205. package/dist/{thumbs-up-CsT9Wzb9.js → thumbs-up-BL3-NenK.js} +1 -1
  206. package/dist/{toast-store-tgK6MuMv.js → toast-store-DkOlYczt.js} +1 -1
  207. package/dist/{tool-DzUjIBT8.js → tool-CeIWUVUe.js} +1 -1
  208. package/dist/{tooltip-Bkkg_4t0.js → tooltip-GA-nmg06.js} +1 -1
  209. package/dist/{trash-2-jBKxjGGQ.js → trash-2-CT66QWlm.js} +1 -1
  210. package/dist/{triangle-alert-DlQ68ppf.js → triangle-alert-CeHLWxhD.js} +1 -1
  211. package/dist/ui/color-field.d.ts +48 -0
  212. package/dist/ui/textarea.d.ts +4 -0
  213. package/dist/ui/toggle-chip.d.ts +40 -0
  214. package/dist/{upload-TcAHXv9W.js → upload-9Csb0F0J.js} +1 -1
  215. package/dist/{use-card-resolution-DaZqAdWf.js → use-card-resolution-Zg0a08Z-.js} +1 -1
  216. package/dist/{variant-aurora-DbW_OWL2.js → variant-aurora-4VBQHIKV.js} +1 -1
  217. package/dist/{variant-aurora-CNmfHhcx.js → variant-aurora-DBeCAQNk.js} +2 -2
  218. package/dist/{variant-aurora-D6GsdTPA.js → variant-aurora-FzHVXHby.js} +2 -2
  219. package/dist/{variant-aurora-BhLuYxJR.js → variant-aurora-LE3fqxgw.js} +1 -1
  220. package/dist/{variant-custom-BvYHR62b.js → variant-custom-AFRGcOBS.js} +1 -1
  221. package/dist/{variant-custom-DV2x254s.js → variant-custom-BQkNuPpE.js} +2 -2
  222. package/dist/{variant-custom-BRvaNHSi.js → variant-custom-DI5R0rln.js} +1 -1
  223. package/dist/{variant-custom-DMTrEO5w.js → variant-custom-WWnrrRHS.js} +2 -2
  224. package/dist/{variant-wave-CyBueXj9.js → variant-wave-DUCbH5oI.js} +2 -2
  225. package/dist/{variant-wave-BNMGrDfj.js → variant-wave-DuQV7DhQ.js} +2 -2
  226. package/dist/{variant-wave-BpDd8t3Z.js → variant-wave-nSI2sfII.js} +1 -1
  227. package/dist/{variant-wave-sp-qwsdI.js → variant-wave-wTP5v_jU.js} +1 -1
  228. package/dist/x-eiO9V6J6.js +1 -0
  229. package/{src/elements/styles.css → kit-base.css} +27 -44
  230. package/package.json +32 -17
  231. package/solid.css +33 -0
  232. package/theme.css +39 -23
  233. package/bin/route.test.js +0 -58
  234. package/dist/arrow-down-CjRU3JgV.js +0 -1
  235. package/dist/arrow-left-Bnpb1UEW.js +0 -1
  236. package/dist/artifact-Bwt7OgcR.js +0 -1
  237. package/dist/check-njkVdZu2.js +0 -1
  238. package/dist/chevron-down-B72s6PXR.js +0 -1
  239. package/dist/chevron-right-BatuHzUm.js +0 -1
  240. package/dist/circle-check-B62pODB3.js +0 -1
  241. package/dist/circle-zx0ByzY9.js +0 -1
  242. package/dist/controllable-CnGpMF6r.js +0 -1
  243. package/dist/define-By-uL588.js +0 -1
  244. package/dist/loader-BM4CEz4G.js +0 -1
  245. package/dist/message-circle-DruwObfX.js +0 -1
  246. package/dist/message-square-BG6q6mlm.js +0 -1
  247. package/dist/play-BvKKq3fX.js +0 -1
  248. package/dist/register-impl-B1hLkrI8.js +0 -424
  249. package/dist/text-shimmer-Dcj1MHuq.js +0 -1
  250. package/dist/textarea-Dpvbngbg.js +0 -1
  251. package/dist/x-Z5UntkIJ.js +0 -1
  252. package/src/agent-tooling/README.md +0 -192
  253. package/src/agent-tooling/archetypes.ts +0 -205
  254. package/src/agent-tooling/catalog/README.md +0 -676
  255. package/src/agent-tooling/catalog/catalog-types.ts +0 -231
  256. package/src/agent-tooling/catalog/fabrications.ts +0 -96
  257. package/src/agent-tooling/catalog/invariants.ts +0 -284
  258. package/src/agent-tooling/catalog/labs-titles.ts +0 -114
  259. package/src/agent-tooling/catalog/scenarios.ts +0 -87
  260. package/src/agent-tooling/catalog/surfaces.ts +0 -347
  261. package/src/agent-tooling/construct/cli-entry.ts +0 -8
  262. package/src/agent-tooling/construct/cli.ts +0 -147
  263. package/src/agent-tooling/construct/codegen.ts +0 -1635
  264. package/src/agent-tooling/construct/construct.v1.schema.json +0 -319
  265. package/src/agent-tooling/construct/dev.ts +0 -148
  266. package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +0 -7
  267. package/src/agent-tooling/construct/fixtures/ops-console.construct.json +0 -44
  268. package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +0 -32
  269. package/src/agent-tooling/construct/schema.ts +0 -452
  270. package/src/agent-tooling/integrations/anthropic.ts +0 -442
  271. package/src/agent-tooling/integrations/cloudflare.ts +0 -218
  272. package/src/agent-tooling/integrations/langgraph.ts +0 -133
  273. package/src/agent-tooling/integrations/mastra.ts +0 -182
  274. package/src/agent-tooling/integrations/mock.ts +0 -148
  275. package/src/agent-tooling/integrations/ollama.ts +0 -97
  276. package/src/agent-tooling/integrations/openai.ts +0 -95
  277. package/src/agent-tooling/integrations/openrouter.ts +0 -82
  278. package/src/agent-tooling/integrations/pi.ts +0 -176
  279. package/src/agent-tooling/integrations/pydantic-ai.ts +0 -108
  280. package/src/agent-tooling/integrations/vercel-ai-sdk.ts +0 -398
  281. package/src/agent-tooling/mcp/css-raw.d.ts +0 -12
  282. package/src/agent-tooling/mcp/manifest.ts +0 -422
  283. package/src/agent-tooling/mcp/server.ts +0 -116
  284. package/src/agent-tooling/mcp/stdio.ts +0 -18
  285. package/src/agent-tooling/mcp/tools/construct.ts +0 -130
  286. package/src/agent-tooling/mcp/tools/debug.ts +0 -621
  287. package/src/agent-tooling/mcp/tools/reference.ts +0 -980
  288. package/src/agent-tooling/mcp/tools/scaffold.ts +0 -6708
  289. package/src/agent-tooling/mcp/tools/theme.ts +0 -456
  290. package/src/agent-tooling/mcp/tools/types.ts +0 -14
  291. package/src/agent-tooling/mcp/validate-args.ts +0 -141
  292. package/src/agent-tooling/recipes/composed-thread.ts +0 -714
  293. package/src/agent-tooling/recipes/index.ts +0 -22
  294. package/src/agent-tooling/recipes/types.ts +0 -32
  295. package/src/agent-tooling/registry.ts +0 -132
  296. package/src/agent-tooling/route-emit.ts +0 -305
  297. package/src/agent-tooling/types.ts +0 -390
  298. package/src/components/artifact-card.tsx +0 -120
  299. package/src/components/artifact.tsx +0 -914
  300. package/src/components/attachment-types.ts +0 -66
  301. package/src/components/attachments.tsx +0 -536
  302. package/src/components/audio-visualizer/audio-visualizer.voice-fixture.ts +0 -257
  303. package/src/components/audio-visualizer/aurora.glsl.ts +0 -330
  304. package/src/components/audio-visualizer/fit-scale.ts +0 -112
  305. package/src/components/audio-visualizer/index.tsx +0 -528
  306. package/src/components/audio-visualizer/labs/lab-choreography.ts +0 -187
  307. package/src/components/audio-visualizer/labs/lab-shaders.ts +0 -363
  308. package/src/components/audio-visualizer/labs/lab-visualizer.tsx +0 -102
  309. package/src/components/audio-visualizer/shader-canvas.tsx +0 -876
  310. package/src/components/audio-visualizer/sizes.ts +0 -54
  311. package/src/components/audio-visualizer/variant-aurora.tsx +0 -305
  312. package/src/components/audio-visualizer/variant-bar.tsx +0 -175
  313. package/src/components/audio-visualizer/variant-custom.tsx +0 -344
  314. package/src/components/audio-visualizer/variant-grid.tsx +0 -175
  315. package/src/components/audio-visualizer/variant-radial.tsx +0 -163
  316. package/src/components/audio-visualizer/variant-wave.tsx +0 -130
  317. package/src/components/audio-visualizer/wave.glsl.ts +0 -130
  318. package/src/components/card-fallback.tsx +0 -60
  319. package/src/components/card-renderer.tsx +0 -220
  320. package/src/components/card.tsx +0 -212
  321. package/src/components/chain-of-thought.tsx +0 -348
  322. package/src/components/chat-container.tsx +0 -89
  323. package/src/components/chat-scope-picker.tsx +0 -57
  324. package/src/components/chat-thread.tsx +0 -1014
  325. package/src/components/checkpoint.tsx +0 -88
  326. package/src/components/choice-card.tsx +0 -743
  327. package/src/components/coachmark.tsx +0 -249
  328. package/src/components/code-block.tsx +0 -181
  329. package/src/components/composer-dom.ts +0 -159
  330. package/src/components/composer-highlight.ts +0 -242
  331. package/src/components/composer-history.ts +0 -82
  332. package/src/components/composer.tsx +0 -1075
  333. package/src/components/confirm-card.tsx +0 -402
  334. package/src/components/context.tsx +0 -377
  335. package/src/components/conversation-item.tsx +0 -241
  336. package/src/components/conversation-list.tsx +0 -429
  337. package/src/components/conversation-panel.tsx +0 -118
  338. package/src/components/dismissed-stub.tsx +0 -80
  339. package/src/components/embed.tsx +0 -200
  340. package/src/components/empty.tsx +0 -177
  341. package/src/components/feedback-bar.tsx +0 -166
  342. package/src/components/file-tree.tsx +0 -530
  343. package/src/components/file-upload.tsx +0 -167
  344. package/src/components/form-widgets.tsx +0 -525
  345. package/src/components/form.tsx +0 -1296
  346. package/src/components/home-panel.tsx +0 -159
  347. package/src/components/image.tsx +0 -65
  348. package/src/components/link-preview.tsx +0 -195
  349. package/src/components/loader.tsx +0 -367
  350. package/src/components/markdown.tsx +0 -162
  351. package/src/components/message-skills.tsx +0 -40
  352. package/src/components/message.tsx +0 -765
  353. package/src/components/model-switcher.tsx +0 -132
  354. package/src/components/prompt-input.tsx +0 -188
  355. package/src/components/prompt-suggestion.tsx +0 -150
  356. package/src/components/reasoning.tsx +0 -293
  357. package/src/components/response-compare-types.ts +0 -152
  358. package/src/components/response-compare.tsx +0 -455
  359. package/src/components/response-stream.tsx +0 -109
  360. package/src/components/screen.tsx +0 -181
  361. package/src/components/scroll-button.tsx +0 -93
  362. package/src/components/source.tsx +0 -192
  363. package/src/components/tasks-card.tsx +0 -801
  364. package/src/components/text-shimmer.tsx +0 -37
  365. package/src/components/thinking-bar.tsx +0 -50
  366. package/src/components/thread.tsx +0 -228
  367. package/src/components/toast.tsx +0 -503
  368. package/src/components/tool-classify.ts +0 -26
  369. package/src/components/tool-types.ts +0 -49
  370. package/src/components/tool.tsx +0 -190
  371. package/src/components/use-card-resolution.ts +0 -44
  372. package/src/components/voice-input.tsx +0 -222
  373. package/src/components/voice-output.tsx +0 -242
  374. package/src/components/widget-tab-bar.tsx +0 -73
  375. package/src/components/workspace-shell.tsx +0 -285
  376. package/src/diagnostics/hook.ts +0 -352
  377. package/src/diagnostics/index.ts +0 -82
  378. package/src/diagnostics/report-request.ts +0 -296
  379. package/src/elements/agent-card.tsx +0 -67
  380. package/src/elements/artifact.tsx +0 -194
  381. package/src/elements/attachments.tsx +0 -140
  382. package/src/elements/audio-visualizer.tsx +0 -227
  383. package/src/elements/autoloader.ts +0 -89
  384. package/src/elements/avatar.tsx +0 -33
  385. package/src/elements/badge.tsx +0 -32
  386. package/src/elements/button.tsx +0 -149
  387. package/src/elements/card.tsx +0 -133
  388. package/src/elements/cards.tsx +0 -266
  389. package/src/elements/chain-of-thought.tsx +0 -141
  390. package/src/elements/chat-scope-picker.tsx +0 -65
  391. package/src/elements/chat-types.ts +0 -102
  392. package/src/elements/chat-workspace.tsx +0 -188
  393. package/src/elements/chat.tsx +0 -304
  394. package/src/elements/checkbox-group.tsx +0 -164
  395. package/src/elements/checkbox.tsx +0 -134
  396. package/src/elements/checkpoint.tsx +0 -47
  397. package/src/elements/choice.tsx +0 -100
  398. package/src/elements/coachmark.tsx +0 -90
  399. package/src/elements/code-block.tsx +0 -60
  400. package/src/elements/command.tsx +0 -197
  401. package/src/elements/compare.tsx +0 -111
  402. package/src/elements/compiled.css +0 -2
  403. package/src/elements/composer.tsx +0 -162
  404. package/src/elements/confirm-card.tsx +0 -76
  405. package/src/elements/context-meter.tsx +0 -107
  406. package/src/elements/conversation-item.tsx +0 -120
  407. package/src/elements/conversation-list.tsx +0 -203
  408. package/src/elements/css.ts +0 -5
  409. package/src/elements/default-input.tsx +0 -392
  410. package/src/elements/define-entry.ts +0 -12
  411. package/src/elements/define.tsx +0 -563
  412. package/src/elements/diagnostic-events.ts +0 -114
  413. package/src/elements/dialog.tsx +0 -145
  414. package/src/elements/disclosure.ts +0 -95
  415. package/src/elements/dock.tsx +0 -215
  416. package/src/elements/dropdown.tsx +0 -123
  417. package/src/elements/editable-label.tsx +0 -140
  418. package/src/elements/element-data-types.ts +0 -152
  419. package/src/elements/element-diagnostics.ts +0 -392
  420. package/src/elements/element-manifest.json +0 -354
  421. package/src/elements/element-nonscalar.json +0 -187
  422. package/src/elements/element-types.d.ts +0 -4353
  423. package/src/elements/embed.tsx +0 -35
  424. package/src/elements/empty.tsx +0 -29
  425. package/src/elements/feedback-bar.tsx +0 -66
  426. package/src/elements/file-tree.tsx +0 -62
  427. package/src/elements/file-upload.tsx +0 -44
  428. package/src/elements/form.tsx +0 -94
  429. package/src/elements/hover-card.tsx +0 -80
  430. package/src/elements/icon.tsx +0 -41
  431. package/src/elements/image.tsx +0 -32
  432. package/src/elements/input.tsx +0 -492
  433. package/src/elements/kbd.tsx +0 -45
  434. package/src/elements/link-preview.tsx +0 -34
  435. package/src/elements/loader.tsx +0 -25
  436. package/src/elements/markdown.tsx +0 -38
  437. package/src/elements/menu.tsx +0 -241
  438. package/src/elements/message-skills.tsx +0 -83
  439. package/src/elements/message.tsx +0 -361
  440. package/src/elements/model-switcher.tsx +0 -121
  441. package/src/elements/nav.tsx +0 -87
  442. package/src/elements/notice.tsx +0 -53
  443. package/src/elements/pane-grid.tsx +0 -111
  444. package/src/elements/pane-group.tsx +0 -119
  445. package/src/elements/pane.tsx +0 -129
  446. package/src/elements/popover.tsx +0 -81
  447. package/src/elements/progress-bar.tsx +0 -39
  448. package/src/elements/prompt-dock.tsx +0 -82
  449. package/src/elements/prompt-input.tsx +0 -240
  450. package/src/elements/prompt-suggestions.tsx +0 -113
  451. package/src/elements/radio-group.tsx +0 -129
  452. package/src/elements/reasoning.tsx +0 -71
  453. package/src/elements/register-impl.ts +0 -148
  454. package/src/elements/register.ts +0 -76
  455. package/src/elements/remote.tsx +0 -225
  456. package/src/elements/resizable.globals.d.ts +0 -36
  457. package/src/elements/resizable.tsx +0 -704
  458. package/src/elements/response-stream.tsx +0 -40
  459. package/src/elements/screen.tsx +0 -90
  460. package/src/elements/scroll-area.tsx +0 -33
  461. package/src/elements/scroll-button.tsx +0 -179
  462. package/src/elements/search.tsx +0 -185
  463. package/src/elements/segmented.tsx +0 -129
  464. package/src/elements/select.tsx +0 -165
  465. package/src/elements/separator.tsx +0 -36
  466. package/src/elements/setting-item.tsx +0 -50
  467. package/src/elements/settings-group.tsx +0 -37
  468. package/src/elements/skeleton.tsx +0 -45
  469. package/src/elements/slider.tsx +0 -171
  470. package/src/elements/slot-text.ts +0 -73
  471. package/src/elements/slots.ts +0 -787
  472. package/src/elements/source.tsx +0 -126
  473. package/src/elements/status.tsx +0 -42
  474. package/src/elements/switch.tsx +0 -118
  475. package/src/elements/tabs.tsx +0 -95
  476. package/src/elements/tasks.tsx +0 -103
  477. package/src/elements/text-shimmer.tsx +0 -28
  478. package/src/elements/thinking-bar.tsx +0 -43
  479. package/src/elements/thread.tsx +0 -139
  480. package/src/elements/toast.tsx +0 -106
  481. package/src/elements/tool.tsx +0 -78
  482. package/src/elements/tooltip.tsx +0 -85
  483. package/src/elements/validate-messages.ts +0 -76
  484. package/src/elements/voice-input.tsx +0 -100
  485. package/src/elements/voice-output.tsx +0 -82
  486. package/src/index.ts +0 -430
  487. package/src/primitives/audio-bands.ts +0 -174
  488. package/src/primitives/card-component-types.ts +0 -63
  489. package/src/primitives/card-contract.ts +0 -80
  490. package/src/primitives/card-data-types.ts +0 -361
  491. package/src/primitives/card-host.tsx +0 -37
  492. package/src/primitives/card-recovery.ts +0 -160
  493. package/src/primitives/card-registry.tsx +0 -78
  494. package/src/primitives/card-resolution.ts +0 -36
  495. package/src/primitives/card-routing.ts +0 -85
  496. package/src/primitives/card-schemas/artifact.schema.json +0 -92
  497. package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
  498. package/src/primitives/card-schemas/card-event.schema.json +0 -12
  499. package/src/primitives/card-schemas/choice.schema.json +0 -75
  500. package/src/primitives/card-schemas/confirm.schema.json +0 -65
  501. package/src/primitives/card-schemas/embed.schema.json +0 -63
  502. package/src/primitives/card-schemas/form.result.schema.json +0 -7
  503. package/src/primitives/card-schemas/form.schema.json +0 -53
  504. package/src/primitives/card-schemas/link.schema.json +0 -54
  505. package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
  506. package/src/primitives/card-schemas/tasks.schema.json +0 -83
  507. package/src/primitives/card-tags.ts +0 -61
  508. package/src/primitives/card-validate-cards.ts +0 -255
  509. package/src/primitives/card-validate-schemas.ts +0 -58
  510. package/src/primitives/card-validate.ts +0 -131
  511. package/src/primitives/chat-config.tsx +0 -103
  512. package/src/primitives/composer-model.ts +0 -49
  513. package/src/primitives/composer-triggers.ts +0 -35
  514. package/src/primitives/controllable.ts +0 -21
  515. package/src/primitives/conversation-store.ts +0 -248
  516. package/src/primitives/create-kai-chat.ts +0 -66
  517. package/src/primitives/create-tween.ts +0 -266
  518. package/src/primitives/embed-providers.ts +0 -254
  519. package/src/primitives/field-mask.ts +0 -256
  520. package/src/primitives/field-semantics.ts +0 -115
  521. package/src/primitives/highlighter.ts +0 -157
  522. package/src/primitives/input-mask.ts +0 -853
  523. package/src/primitives/link-preview.ts +0 -87
  524. package/src/primitives/message-feedback.ts +0 -124
  525. package/src/primitives/pdf-preview.ts +0 -121
  526. package/src/primitives/toast-store.ts +0 -338
  527. package/src/primitives/url-scheme-policy.ts +0 -70
  528. package/src/primitives/use-audio-analysis.ts +0 -340
  529. package/src/primitives/use-auto-resize.ts +0 -31
  530. package/src/primitives/use-resize-observer.ts +0 -45
  531. package/src/primitives/use-sequencer.ts +0 -72
  532. package/src/primitives/use-speech-recognition.ts +0 -146
  533. package/src/primitives/use-stick-to-bottom.ts +0 -75
  534. package/src/primitives/use-text-stream.ts +0 -143
  535. package/src/primitives/use-voice-recorder.ts +0 -62
  536. package/src/primitives/visualizer-sequences.ts +0 -350
  537. package/src/remote/host-embed.ts +0 -345
  538. package/src/remote/index.ts +0 -2
  539. package/src/remote/origin.ts +0 -30
  540. package/src/remote/provider-runtime.ts +0 -262
  541. package/src/remote/provider.ts +0 -2
  542. package/src/remote/validate.ts +0 -22
  543. package/src/remote/version.ts +0 -12
  544. package/src/remote/wire.ts +0 -48
  545. package/src/schemas/from-tool-call.ts +0 -151
  546. package/src/schemas/index.ts +0 -341
  547. package/src/schemas/provider-subsets.ts +0 -538
  548. package/src/schemas/registry.ts +0 -355
  549. package/src/schemas/tool-defs.ts +0 -793
  550. package/src/solid.ts +0 -173
  551. package/src/state/index.ts +0 -44
  552. package/src/state/messages.ts +0 -53
  553. package/src/state/mock.ts +0 -297
  554. package/src/state/parts.ts +0 -295
  555. package/src/state/persistence.ts +0 -180
  556. package/src/state/stream.ts +0 -246
  557. package/src/state/suggestions.ts +0 -9
  558. package/src/state/threads.ts +0 -142
  559. package/src/test-utils/fake-clock.ts +0 -88
  560. package/src/types.ts +0 -95
  561. package/src/ui/action-icons.ts +0 -53
  562. package/src/ui/agent-card.tsx +0 -218
  563. package/src/ui/avatar.tsx +0 -23
  564. package/src/ui/badge.tsx +0 -21
  565. package/src/ui/button.tsx +0 -49
  566. package/src/ui/card.tsx +0 -245
  567. package/src/ui/checkbox-group.tsx +0 -153
  568. package/src/ui/checkbox.tsx +0 -63
  569. package/src/ui/collapsible.tsx +0 -163
  570. package/src/ui/command.tsx +0 -103
  571. package/src/ui/dialog.tsx +0 -223
  572. package/src/ui/dock.tsx +0 -630
  573. package/src/ui/dropdown.tsx +0 -636
  574. package/src/ui/editable-label.tsx +0 -112
  575. package/src/ui/hover-card.tsx +0 -345
  576. package/src/ui/icon.tsx +0 -167
  577. package/src/ui/input.tsx +0 -391
  578. package/src/ui/kbd.tsx +0 -118
  579. package/src/ui/nav.tsx +0 -282
  580. package/src/ui/notice.tsx +0 -84
  581. package/src/ui/overlay.tsx +0 -277
  582. package/src/ui/pane-grid.tsx +0 -117
  583. package/src/ui/pane-group.tsx +0 -291
  584. package/src/ui/pane.tsx +0 -193
  585. package/src/ui/popover.tsx +0 -106
  586. package/src/ui/progress-bar.tsx +0 -83
  587. package/src/ui/prompt-dock.tsx +0 -145
  588. package/src/ui/radio.tsx +0 -150
  589. package/src/ui/resizable.tsx +0 -693
  590. package/src/ui/scroll-area.tsx +0 -26
  591. package/src/ui/segmented.tsx +0 -109
  592. package/src/ui/select.tsx +0 -168
  593. package/src/ui/separator.tsx +0 -10
  594. package/src/ui/settings-group.tsx +0 -67
  595. package/src/ui/skeleton.tsx +0 -73
  596. package/src/ui/slider.tsx +0 -178
  597. package/src/ui/status.tsx +0 -48
  598. package/src/ui/switch.tsx +0 -119
  599. package/src/ui/tabs.tsx +0 -168
  600. package/src/ui/textarea.tsx +0 -21
  601. package/src/ui/tooltip.tsx +0 -118
  602. package/src/utils/cn.ts +0 -30
  603. package/src/wire/chunk.ts +0 -248
  604. package/src/wire/consume.ts +0 -599
  605. package/src/wire/diagnostics.ts +0 -727
  606. package/src/wire/encode-probe.ts +0 -214
  607. package/src/wire/encode.ts +0 -947
  608. package/src/wire/files.ts +0 -342
  609. package/src/wire/formats/anthropic.ts +0 -274
  610. package/src/wire/formats/openai.ts +0 -228
  611. package/src/wire/index.ts +0 -95
  612. package/src/wire/media-types.ts +0 -344
  613. package/src/wire/read.ts +0 -396
  614. package/src/wire/sink-helpers.ts +0 -50
  615. package/src/wire/sse.ts +0 -153
@@ -1,704 +0,0 @@
1
- import { createSignal, createEffect, on, onMount, onCleanup, For, Show, type JSX } from 'solid-js';
2
- import { defineWebComponent } from './define';
3
- import { ResizableHandle, normalizeSize, clampBasis } from '../ui/resizable';
4
-
5
- type Orientation = 'horizontal' | 'vertical';
6
-
7
- /** Bubbling, composed intent: a descendant asks the nearest enclosing
8
- * <kai-resizable> to maximize the item containing it (filling, hiding siblings)
9
- * or to restore. Any panel content may emit it — the protocol is zero-config. */
10
- export interface KaiMaximizeIntentDetail {
11
- /** true = maximize the item containing me; false = restore. */
12
- requested: boolean;
13
- }
14
-
15
- /** Composed, non-bubbling notification the group dispatches DOWN onto the
16
- * affected <kai-resizable-item> (on maximize) or the group host + the formerly
17
- * maximized item (on restore) so descendant content can sync its affordance. */
18
- export interface KaiMaximizeStateDetail {
19
- /** Whether THIS subtree's item is the maximized one. */
20
- maximized: boolean;
21
- }
22
-
23
- /** Event type names for the cross-element maximize protocol. */
24
- export const KAI_MAXIMIZE_INTENT = 'kai-maximize-intent' as const;
25
- export const KAI_MAXIMIZE_STATE = 'kai-maximize-state' as const;
26
-
27
- /** Parsed view of a `<kai-resizable-item>` light child. */
28
- interface ItemInfo {
29
- el: HTMLElement;
30
- size?: string;
31
- /** Original configured size, captured once and stable across drags (for dblclick-reset). */
32
- defaultSize?: string;
33
- min?: string;
34
- max?: string;
35
- locked: boolean;
36
- hidden: boolean;
37
- collapsed: boolean;
38
- }
39
-
40
- /** Max number of panels a single group lays out (nest for more). */
41
- const MAX_ITEMS = 3;
42
-
43
- /** Convert a px-or-% bound to `data-*` attribute values the handle understands. */
44
- function boundAttrs(value: string | undefined): { pxAttr?: string; pctAttr?: string } {
45
- if (value === undefined || value === '') return {};
46
- const t = value.trim();
47
- if (t.endsWith('px')) return { pxAttr: String(parseFloat(t)) };
48
- if (t.endsWith('%')) return { pctAttr: String(parseFloat(t)) };
49
- if (Number.isFinite(Number(t))) return { pctAttr: t };
50
- return {};
51
- }
52
-
53
- interface GroupProps extends Record<string, unknown> {
54
- /** Layout axis: `horizontal` (row, default) or `vertical` (column). */
55
- orientation?: Orientation;
56
- /** Which item index is maximized (null = none). Declarative source of truth. */
57
- maximizedIndex?: number | null;
58
- /**
59
- * Divider affordance drawn inside each draggable handle's 8px grab zone:
60
- * - `line` (default): a 1px hairline, transparent at rest, tinting on hover/drag.
61
- * - `grip`: a dotted grip handle.
62
- * - `none`: no visible divider, just the invisible hit-area.
63
- * The full grab zone and keyboard/ARIA behavior are identical for all three.
64
- */
65
- handle?: 'line' | 'grip' | 'none';
66
- }
67
-
68
- interface GroupEvents extends Record<string, unknown> {
69
- /** Fired on drag-end / keyboard resize / visibility change. `detail.sizes` = panel sizes in percent. */
70
- 'kai-change': { sizes: number[] };
71
- /** Observe layout maximize state. */
72
- 'kai-maximize-change': { maximized: boolean; index: number | null };
73
- /** Authoritative maximize state, dispatched as a raw composed CustomEvent (not
74
- * through `dispatch`) onto the affected `<kai-resizable-item>` and, on restore,
75
- * onto the group host. A nested element (e.g. `<kai-artifact>`) listens for it
76
- * to reconcile its own toggle. */
77
- 'kai-maximize-state': { maximized: boolean };
78
- }
79
-
80
- /**
81
- * `<kai-resizable>` — a composable, resizable multi-panel layout (up to 3 panels)
82
- * with auto-inserted draggable dividers. It lays out its `<kai-resizable-item>`
83
- * light children along an axis (`orientation`), reading each item's `size`,
84
- * `min`, `max`, `locked` and `hidden` attributes via a `MutationObserver`. A
85
- * divider is interactive only between two unlocked, visible panels. Emits a
86
- * `change` event (`detail.sizes`, percent) on resize / visibility change.
87
- */
88
- defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
89
- orientation: 'horizontal',
90
- maximizedIndex: null,
91
- handle: 'line',
92
- }, (props, { element, dispatch, expose }) => {
93
- const [items, setItems] = createSignal<ItemInfo[]>([]);
94
- const orientation = (): Orientation => (props.orientation === 'vertical' ? 'vertical' : 'horizontal');
95
-
96
- /** Read the current `<kai-resizable-item>` light children + their attributes. */
97
- function readItems() {
98
- const all = Array.from(element.children).filter(
99
- (c): c is HTMLElement => c.tagName.toLowerCase() === 'kai-resizable-item',
100
- );
101
- if (all.length > MAX_ITEMS) {
102
- // eslint-disable-next-line no-console
103
- console.warn(
104
- `<kai-resizable>: only the first ${MAX_ITEMS} <kai-resizable-item> children are laid out ` +
105
- `(got ${all.length}). Nest <kai-resizable> for more.`,
106
- );
107
- }
108
- const capped = all.slice(0, MAX_ITEMS);
109
- const parsed: ItemInfo[] = capped.map((el) => {
110
- // Capture the ORIGINAL configured size ONCE per item, before any drag (or
111
- // `persistSizes`) overwrites the live `size` attribute. Stashed on a non-
112
- // observed data-* attr so dblclick-reset always snaps to the true default,
113
- // not to wherever the user last dragged. Empty string = no explicit default.
114
- if (!el.hasAttribute('data-kai-default-size')) {
115
- el.setAttribute('data-kai-default-size', el.getAttribute('size') ?? '');
116
- }
117
- const defaultSize = el.getAttribute('data-kai-default-size') || undefined;
118
- // The `collapsed` boolean prop is reflected to a `collapsed` attribute by the
119
- // item facade (see kai-resizable-item), so reading the attribute here works
120
- // at INITIAL render from any framework — unlike the bare `hidden` boolean,
121
- // whose JSX form sets neither the attribute nor the IDL property on a custom
122
- // element. Treated as hidden-for-layout, independently of `hidden` so the
123
- // back-compat hidden path (and maximize, which drives `hidden`) is untouched.
124
- const collapsed = el.hasAttribute('collapsed') && el.getAttribute('collapsed') !== 'false';
125
- return {
126
- el,
127
- size: el.getAttribute('size') ?? undefined,
128
- defaultSize,
129
- min: el.getAttribute('min') ?? undefined,
130
- max: el.getAttribute('max') ?? undefined,
131
- locked: el.hasAttribute('locked') && el.getAttribute('locked') !== 'false',
132
- // Honour both the `hidden` attribute and the property, because on THIS element
133
- // they are two independent halves of the state and either can be the only one
134
- // set. Not a fact about custom elements in general — a custom element that does
135
- // not declare a `hidden` prop keeps the native reflecting accessor. It is a fact
136
- // about this one: `<kai-resizable-item>` declares `hidden: false`, so
137
- // component-register owns the property and nothing reflects. Measured:
138
- // `el.hidden = true` writes no attribute, and after maximize writes the
139
- // attribute `el.hidden` reads `undefined`. This union is what absorbs that, and
140
- // it is why `hidden` is exempt from the reflectFlag migration rather than broken
141
- // by it — see reflectItemConfig's doc below.
142
- hidden: el.hidden || (el.hasAttribute('hidden') && el.getAttribute('hidden') !== 'false'),
143
- collapsed,
144
- };
145
- });
146
-
147
- // Assign each visible item to its panel slot by visible order; clear the
148
- // rest so hidden/extra/collapsed items don't leak into a slot.
149
- let visIdx = 0;
150
- for (const info of parsed) {
151
- if (info.hidden || info.collapsed) {
152
- info.el.removeAttribute('slot');
153
- } else {
154
- info.el.setAttribute('slot', `p${visIdx}`);
155
- visIdx++;
156
- }
157
- }
158
- for (const el of all.slice(MAX_ITEMS)) el.removeAttribute('slot');
159
-
160
- // BUG FIX (U10b): the MutationObserver fires for ANY subtree change, including
161
- // a slotted child re-rendering its CONTENT (e.g. a new chat message). If we
162
- // unconditionally `setItems(parsed)`, the <For> re-keys and each panel's
163
- // flex-basis is re-derived from the item's `size` ATTRIBUTE — wiping out any
164
- // size the user dragged (which lives only as inline flex-basis on the panel
165
- // div, set by ResizableHandle.settleToPercent). The composite <kai-workspace>
166
- // never hits this because it renders Solid panels directly with no re-read.
167
- //
168
- // So: only commit a new items() array when the panel LAYOUT actually changed —
169
- // i.e. an item was added/removed, or a config attribute (size/min/max/locked/
170
- // hidden) changed. A pure content mutation is structurally identical and is
171
- // skipped, leaving the dragged inline basis intact.
172
- if (!itemsChanged(items(), parsed)) return;
173
- setItems(parsed);
174
- }
175
-
176
- /** True when the parsed item list differs structurally (identity, order, or any
177
- * layout-affecting config attribute) from the current one. Content-only
178
- * mutations leave every field equal → returns false → no re-render. */
179
- function itemsChanged(prev: ItemInfo[], next: ItemInfo[]): boolean {
180
- if (prev.length !== next.length) return true;
181
- for (let i = 0; i < prev.length; i++) {
182
- const a = prev[i];
183
- const b = next[i];
184
- if (a.el !== b.el) return true;
185
- if (a.size !== b.size || a.min !== b.min || a.max !== b.max) return true;
186
- if (a.locked !== b.locked || a.hidden !== b.hidden || a.collapsed !== b.collapsed) return true;
187
- }
188
- return false;
189
- }
190
-
191
- const visible = () => items().filter((i) => !i.hidden && !i.collapsed);
192
-
193
- /** Compute current panel sizes (percent of container) from the rendered DOM. */
194
- function currentSizes(): number[] {
195
- return visible().map((info) => {
196
- const panel = info.el.assignedSlot?.closest('[data-panel]') as HTMLElement | null;
197
- const target = panel ?? info.el;
198
- const parent = target.parentElement;
199
- const dim = orientation() === 'horizontal' ? 'width' : 'height';
200
- const total = parent ? parent.getBoundingClientRect()[dim] : 0;
201
- const val = target.getBoundingClientRect()[dim];
202
- return total > 0 ? Math.round((val / total) * 100) : 0;
203
- });
204
- }
205
-
206
- function emitChange() {
207
- dispatch('kai-change', { sizes: currentSizes() });
208
- }
209
-
210
- /** Guard: while writing `size` attributes back from a live layout, the
211
- * MutationObserver must NOT treat our own writes as an external structural
212
- * change (which would re-render and could fight the in-flight drag). */
213
- let persistingSizes = false;
214
-
215
- /**
216
- * BUG FIX (U10b) — durability: a drag/keyboard resize writes inline flex-basis
217
- * onto the panel divs only; the item `size` ATTRIBUTE (the source of truth that
218
- * `readItems` re-derives basis from) is left at its initial value. Persist the
219
- * live percent back to each visible item's `size` attribute so the dragged
220
- * layout survives ANY later re-read (including a genuine add/remove relayout),
221
- * not just content-only mutations. Guarded so it doesn't trip the observer.
222
- */
223
- function persistSizes() {
224
- const vis = visible();
225
- const live = currentSizes();
226
- if (vis.length !== live.length) return;
227
- persistingSizes = true;
228
- vis.forEach((info, i) => {
229
- const pct = live[i];
230
- if (Number.isFinite(pct) && pct > 0) info.el.setAttribute('size', `${pct}%`);
231
- });
232
- // Hold the guard across the MutationObserver microtask (it fires AFTER this
233
- // synchronous code), then clear it — otherwise the observer sees the flag
234
- // already false and re-reads our own writes. Same pattern as applyingMaximize.
235
- queueMicrotask(() => { persistingSizes = false; });
236
- }
237
-
238
- // --- Task 2: maximize/restore core ---
239
-
240
- interface SavedItemState {
241
- el: HTMLElement;
242
- size: string | null;
243
- hidden: boolean;
244
- locked: boolean;
245
- }
246
- interface MaximizeStash {
247
- /** The element that was maximized (identity anchor for re-target + events). */
248
- item: HTMLElement;
249
- /** Per-element stash keyed by element identity, not position. */
250
- saved: SavedItemState[];
251
- }
252
- const [maximized, setMaximized] = createSignal<MaximizeStash | null>(null);
253
- /** Re-entrancy guard: while we (un)apply maximize attributes, the observer must
254
- * NOT emit a mid-flight `change`. The final relayout emits the real one. */
255
- let applyingMaximize = false;
256
-
257
- /** Find the capped <kai-resizable-item> ancestor of an event target, if any. */
258
- function findContainingItem(node: Node | null): HTMLElement | null {
259
- let el = node instanceof Element ? node : node?.parentElement ?? null;
260
- // The intent is composed; its target may be inside the artifact's shadow.
261
- // Resolve to a direct light child <kai-resizable-item> of THIS group.
262
- const capped = items().map((i) => i.el);
263
- while (el) {
264
- if (el instanceof HTMLElement && capped.includes(el)) return el;
265
- el = el.parentElement ?? (el.getRootNode() as ShadowRoot).host ?? null;
266
- }
267
- return null;
268
- }
269
-
270
- function readAttrState(el: HTMLElement) {
271
- return {
272
- size: el.getAttribute('size'),
273
- hidden: el.hidden || (el.hasAttribute('hidden') && el.getAttribute('hidden') !== 'false'),
274
- locked: el.hasAttribute('locked') && el.getAttribute('locked') !== 'false',
275
- };
276
- }
277
-
278
- function setBoolAttr(el: HTMLElement, name: string, on: boolean) {
279
- if (on) el.setAttribute(name, '');
280
- else el.removeAttribute(name);
281
- }
282
-
283
- function maximizeItem(item: HTMLElement) {
284
- const list = items();
285
- const index = list.findIndex((i) => i.el === item);
286
- if (index < 0) return;
287
- const current = maximized();
288
- if (current) {
289
- if (current.item === item) return; // same item → no-op
290
- restore(); // different item → re-target
291
- }
292
- applyingMaximize = true;
293
- // Capture the EFFECTIVE current % so a post-drag layout restores faithfully.
294
- const live = currentSizes(); // visible-order percents (Playwright-verified)
295
- let visIdx = 0;
296
- const saved: SavedItemState[] = list.map((info) => {
297
- const prev = readAttrState(info.el);
298
- if (!prev.hidden) {
299
- // Write the live % back as the stashed size baseline.
300
- const pct = live[visIdx++];
301
- if (Number.isFinite(pct) && pct > 0) info.el.setAttribute('size', `${pct}%`);
302
- }
303
- return { el: info.el, size: info.el.getAttribute('size'), hidden: prev.hidden, locked: prev.locked };
304
- });
305
- // Hide every other item; free the maximized one to fill.
306
- list.forEach((info, i) => {
307
- if (i === index) {
308
- info.el.removeAttribute('size');
309
- info.el.removeAttribute('locked');
310
- setBoolAttr(info.el, 'hidden', false);
311
- } else {
312
- setBoolAttr(info.el, 'hidden', true);
313
- }
314
- });
315
- setMaximized({ item, saved });
316
- element.setAttribute('data-maximized', '');
317
- item.setAttribute('data-maximized-panel', '');
318
- readItems();
319
- emitChange();
320
- // Keep applyingMaximize = true until AFTER the MutationObserver microtask fires
321
- // so its queueMicrotask(emitChange) sees the guard and skips (storm guard).
322
- queueMicrotask(() => { applyingMaximize = false; });
323
- // Tell the maximized subtree (and only it) it is now maximized.
324
- item.dispatchEvent(new CustomEvent('kai-maximize-state', { detail: { maximized: true }, bubbles: false, composed: true }));
325
- dispatch('kai-maximize-change', { maximized: true, index });
326
- }
327
-
328
- function restore() {
329
- const stash = maximized();
330
- if (!stash) return;
331
- applyingMaximize = true;
332
- // Re-apply saved state keyed by element identity; items no longer in the DOM
333
- // are simply skipped. This is safe regardless of sibling additions/removals
334
- // that happened while maximized (no index drift).
335
- for (const s of stash.saved) {
336
- if (!s.el.isConnected) continue;
337
- if (s.size === null) s.el.removeAttribute('size');
338
- else s.el.setAttribute('size', s.size);
339
- setBoolAttr(s.el, 'hidden', s.hidden);
340
- setBoolAttr(s.el, 'locked', s.locked);
341
- s.el.removeAttribute('data-maximized-panel');
342
- }
343
- const prevItem = stash.item;
344
- setMaximized(null);
345
- element.removeAttribute('data-maximized');
346
- readItems();
347
- emitChange();
348
- // Keep applyingMaximize = true until AFTER the MutationObserver microtask fires
349
- // so its queueMicrotask(emitChange) sees the guard and skips (storm guard).
350
- queueMicrotask(() => { applyingMaximize = false; });
351
- // Broadcast restore on the host AND directly on the formerly-maximized item.
352
- element.dispatchEvent(new CustomEvent('kai-maximize-state', { detail: { maximized: false }, bubbles: false, composed: true }));
353
- prevItem?.dispatchEvent(new CustomEvent('kai-maximize-state', { detail: { maximized: false }, bubbles: false, composed: true }));
354
- dispatch('kai-maximize-change', { maximized: false, index: null });
355
- }
356
-
357
- onMount(() => {
358
- readItems();
359
- const onIntent = (e: Event) => {
360
- const ce = e as CustomEvent<KaiMaximizeIntentDetail>;
361
- e.stopPropagation(); // nearest group wins (nesting)
362
- const item = findContainingItem(ce.target as Node);
363
- if (!item) return; // outside any item → ignore
364
- if (ce.detail.requested) maximizeItem(item);
365
- else restore();
366
- };
367
- element.addEventListener('kai-maximize-intent', onIntent);
368
-
369
- const onKeydown = (e: KeyboardEvent) => {
370
- // Only act while maximized — the capture listener on the host already
371
- // ensures the event originates within the group.
372
- if (e.key !== 'Escape' || !maximized()) return;
373
- e.stopPropagation();
374
- restore();
375
- };
376
- element.addEventListener('keydown', onKeydown, true);
377
-
378
- const mo = new MutationObserver(() => {
379
- // Skip our OWN per-drag size writes (persistSizes). Re-reading here would
380
- // setItems() → re-render the <For>, replacing the ResizableHandle mid-drag
381
- // and dropping its pointer capture — the drag stalls after the first move.
382
- // (The flag is held across this observer microtask; see persistSizes.)
383
- if (persistingSizes) return;
384
- readItems();
385
- const stash = maximized();
386
- if (stash) {
387
- // Use element identity, not a positional index, to detect whether the
388
- // maximized item is still present and visible.
389
- const maximizedEl = stash.item;
390
- const isConnected = maximizedEl.isConnected && element.contains(maximizedEl);
391
- const isVisible = isConnected
392
- && !(maximizedEl.hidden || maximizedEl.hasAttribute('hidden'))
393
- && !(maximizedEl.hasAttribute('collapsed') && maximizedEl.getAttribute('collapsed') !== 'false');
394
- if (!isConnected || !isVisible) {
395
- // The maximized item was removed or hidden/collapsed out from under us → restore.
396
- restore();
397
- return;
398
- }
399
- }
400
- if (applyingMaximize) return; // our own maximize writes — skip the emit
401
- queueMicrotask(emitChange);
402
- });
403
- mo.observe(element, {
404
- childList: true,
405
- // Attribute changes happen on the <kai-resizable-item> *children*, so we
406
- // must observe the subtree (filtered to the config attributes) — not just
407
- // the host's own attributes.
408
- subtree: true,
409
- attributes: true,
410
- attributeFilter: ['size', 'locked', 'min', 'max', 'hidden', 'collapsed'],
411
- });
412
- onCleanup(() => {
413
- mo.disconnect();
414
- element.removeEventListener('kai-maximize-intent', onIntent);
415
- element.removeEventListener('keydown', onKeydown, true);
416
- });
417
-
418
- // --- Task 3: imperative host methods + declarative maximizedIndex prop ---
419
-
420
- // Imperative host API. Routed through `expose()` like every other element's,
421
- // so gen-element-api.mjs sees it and the generated element interface carries
422
- // `maximize`/`restore` — a direct assignment onto `element` was invisible to
423
- // the extractor and needed an `as unknown as` cast to type-check here.
424
- expose({
425
- /** Imperatively maximize the item at `index` (thin wrapper over `maximizedIndex`). */
426
- maximize: (index: number) => {
427
- const it = items()[index]?.el;
428
- if (it) maximizeItem(it);
429
- },
430
- /** Imperatively restore from the maximized layout. */
431
- restore: () => restore(),
432
- });
433
-
434
- // Declarative maximizedIndex → maximize/restore. Skip the initial null run.
435
- createEffect(
436
- on(
437
- () => props.maximizedIndex,
438
- (idx) => {
439
- if (idx == null) restore();
440
- else {
441
- const it = items()[idx]?.el;
442
- if (it) maximizeItem(it);
443
- }
444
- },
445
- { defer: true },
446
- ),
447
- );
448
- });
449
-
450
- const isHoriz = () => orientation() === 'horizontal';
451
-
452
- return (
453
- <>
454
- {/* A resizable layout fills its container — default the host to a block
455
- that stretches, so consumers only need to give a parent (or the element)
456
- a height. Override with an explicit height on the element if needed. */}
457
- <style>{':host{display:block;height:100%}'}</style>
458
- <div
459
- data-resizable-root
460
- data-orientation={orientation()}
461
- style={{
462
- display: 'flex',
463
- 'flex-direction': isHoriz() ? 'row' : 'column',
464
- width: '100%',
465
- height: '100%',
466
- }}
467
- >
468
- <For each={visible()}>
469
- {(info, i) => {
470
- const min = boundAttrs(info.min);
471
- const max = boundAttrs(info.max);
472
- const def = boundAttrs(info.defaultSize);
473
- // Clamp the INITIAL basis into [min, max] so a % size on a wide
474
- // container never paints past a px max and then snaps on first drag.
475
- const basis = clampBasis(normalizeSize(info.size), normalizeSize(info.min), normalizeSize(info.max));
476
- const prev = () => visible()[i() - 1];
477
- const isStatic = () => !!(info.locked || prev()?.locked);
478
- return (
479
- <>
480
- <Show when={i() > 0}>
481
- <ResizableHandle
482
- handle={props.handle ?? 'line'}
483
- orientation={orientation()}
484
- static={isStatic()}
485
- onPanelResize={() => {
486
- // Persist the dragged/dblclick-reset layout back to the item
487
- // `size` attributes so it survives later re-reads, then emit.
488
- persistSizes();
489
- queueMicrotask(emitChange);
490
- }}
491
- />
492
- </Show>
493
- <div
494
- data-panel
495
- data-locked={info.locked ? '' : undefined}
496
- data-min-size={min.pxAttr}
497
- data-min-size-pct={min.pctAttr}
498
- data-max-size={max.pxAttr}
499
- data-max-size-pct={max.pctAttr}
500
- // Reflect the configured default size so a dblclick on the
501
- // adjacent <ResizableHandle> can snap this panel back to it.
502
- data-default-size={def.pxAttr}
503
- data-default-size-pct={def.pctAttr}
504
- style={{
505
- // The panel is a flex item of the root: `flex-basis` sizes its
506
- // MAIN axis (width when horizontal, height when vertical) and the
507
- // drag/keyboard handlers rewrite that basis — so the layout spine
508
- // stays a plain flex row/column (drag math unchanged).
509
- //
510
- // For the FILL, the panel is itself a `display:grid` with a single
511
- // `minmax(0,1fr)` cell on BOTH axes. A grid item (the slotted
512
- // `<kai-resizable-item>`) stretches to fill its cell on both axes by
513
- // default (`place-items:stretch`), and a `1fr` track inside a
514
- // definite-sized grid is a *definite* length — so content fills
515
- // height AND width whether or not it sets `height:100%`, in both
516
- // orientations. A flex panel only stretches the CROSS axis (which is
517
- // why the previous `display:flex` panel collapsed the main axis to
518
- // content height). This mirrors how Shoelace/Web Awesome
519
- // `<sl-split-panel>` lay panels out with grid for guaranteed fill,
520
- // adapted here to a per-panel grid cell (our double slot boundary
521
- // makes a slot-as-grid-item unusable — a slot with assigned nodes
522
- // has a zero box). min:0 on both axes enables shrink-to-scroll;
523
- // overflow clips (the item owns the scroll).
524
- ...(basis !== undefined
525
- ? { 'flex-basis': basis, 'flex-grow': '0', 'flex-shrink': '0' }
526
- : { flex: '1 1 0%' }),
527
- display: 'grid',
528
- 'grid-template-rows': 'minmax(0, 1fr)',
529
- 'grid-template-columns': 'minmax(0, 1fr)',
530
- 'min-width': '0',
531
- 'min-height': '0',
532
- overflow: 'hidden',
533
- }}
534
- >
535
- <slot name={`p${i()}`} />
536
- </div>
537
- </>
538
- );
539
- }}
540
- </For>
541
- </div>
542
- </>
543
- );
544
- });
545
-
546
- /**
547
- * Reflect a `<kai-resizable-item>`'s reactive CONFIG props to the ATTRIBUTES the
548
- * parent `<kai-resizable>` reads (`readItems()` + its `size`/`min`/`max`/`locked`
549
- * MutationObserver). Framework runtimes (React et al.) assign these as DOM
550
- * *properties* — `el.size = "280px"` — but component-register only mirrors
551
- * attribute→property, never the reverse, so a property-set size never becomes an
552
- * attribute and the parent silently falls back to a flexible split. This is the
553
- * exact class of bug the `collapsed` reflection already fixed; handled here for
554
- * `size`/`min`/`max` (the STRINGS). The booleans — `collapsed` and `locked` — go
555
- * through `reflectFlag` in the facade body instead, which reflects AND keeps the
556
- * property readable; see WebComponentContext.reflectFlag.
557
- *
558
- * `hidden` is deliberately NOT reflected, and NOT because it is already fine — it is
559
- * split exactly like the others, and measurably so: `el.hidden = true` leaves no
560
- * attribute (a plain `<div>` gets one), and after maximize writes the attribute
561
- * `el.hidden` reads `undefined`. Declaring `hidden: false` is what does it — it makes
562
- * `hidden` a component-register prop, whose non-reflecting accessor shadows the native
563
- * reflecting one. What makes the split HARMLESS here is that both readers take the
564
- * union, `el.hidden || el.hasAttribute('hidden')`, so neither half can be missed.
565
- * Routing it through `reflectFlag` would put a second writer on an attribute the
566
- * maximize/restore path already owns, so it is a behaviour decision of its own rather
567
- * than part of the read-back fix. See the exemption in
568
- * tests/elements/reflected-boolean-coverage.test.ts.
569
- *
570
- * Durability (don't fight drags): the parent WRITES `size` back to the live percent
571
- * during a drag (`persistSizes` → `setAttribute('size', …)`), and that attribute
572
- * write back-propagates into this prop's signal (component-register's
573
- * attributeChangedCallback → property → the solid-element prop signal). A naive
574
- * "reflect on every signal change" effect would therefore re-stomp the dragged size
575
- * the next time a framework re-render re-asserts the ORIGINAL declared `size`
576
- * (e.g. React re-runs `el.size = "280px"` on every render). So each string reflect
577
- * only writes when the value the CONSUMER declared actually changes: a signal value
578
- * that already equals the current attribute came FROM an attribute write (a drag),
579
- * not the consumer, so it is left untouched and is not adopted as the new baseline.
580
- * Net effect: a dragged size survives re-renders, while an explicit `size` change
581
- * still applies. `size` prop signals use Solid's DEFAULT (same-value-skipping)
582
- * equality — this guard is needed on top of that only because of the drag-write
583
- * back-propagation, which same-value-skip alone can't see.
584
- *
585
- * Exported for unit testing (the live Shadow-DOM element is not jsdom-friendly).
586
- */
587
- export function reflectItemConfig(
588
- element: HTMLElement,
589
- props: { readonly size?: string; readonly min?: string; readonly max?: string },
590
- ) {
591
- const norm = (v: unknown): string | null => (v == null || v === '' ? null : String(v));
592
- const reflectString = (name: 'size' | 'min' | 'max') => {
593
- // Last value the CONSUMER declared (distinct from a value the parent wrote to
594
- // the attribute mid-drag). Starts `undefined`, which `norm` never returns, so
595
- // the first genuine value always reflects.
596
- let lastConsumer: string | null | undefined;
597
- createEffect(() => {
598
- const desired = norm(props[name]); // reactive read
599
- if (desired === lastConsumer) return; // consumer intent unchanged → leave the attr (the drag owns it)
600
- const current = element.getAttribute(name);
601
- // Already matches — either untouched or the parent wrote it (drag). Don't
602
- // adopt it as the consumer baseline and don't fight it.
603
- if (desired === current) return;
604
- lastConsumer = desired;
605
- if (desired === null) element.removeAttribute(name);
606
- else element.setAttribute(name, desired);
607
- });
608
- };
609
- reflectString('size');
610
- reflectString('min');
611
- reflectString('max');
612
- // `locked` used to be reflected here too. It is a BOOLEAN, so it now goes through
613
- // `reflectFlag` in the facade body next to `collapsed` — a boolean reflected with a
614
- // bare `toggleAttribute` reads back `undefined` (see WebComponentContext.reflectFlag),
615
- // and `reflectFlag` is only reachable from the facade's context. What is left here is
616
- // the string props, which is this helper's real subject: the drag-durability guard.
617
- }
618
-
619
- interface ItemProps extends Record<string, unknown> {
620
- /** Initial main-axis size: `"280px"` (fixed) or `"25%"`/`25` (percent). Omitted → flexible. */
621
- size?: string;
622
- /** Minimum size during resize (px or %). */
623
- min?: string;
624
- /** Maximum size during resize (px or %). */
625
- max?: string;
626
- /** Fix this panel's size; adjacent dividers become non-draggable. */
627
- locked?: boolean;
628
- /** Hide this panel; its divider is dropped and the rest reflow. */
629
- hidden?: boolean;
630
- /**
631
- * Collapse this panel. Same layout effect as `hidden` (divider dropped, the rest
632
- * reflow), but it WORKS as a bare boolean from framework JSX. A plain
633
- * `<kai-resizable-item collapsed>` in React/Solid/Vue/Svelte collapses the panel
634
- * at the first render; `hidden` does not, because a JSX boolean sets neither the
635
- * `hidden` attribute nor the IDL property on a custom element, so the parent never
636
- * sees it. The facade reflects `collapsed` to a `collapsed` attribute the parent
637
- * reads. Prefer this over `hidden` for declarative collapse.
638
- */
639
- collapsed?: boolean;
640
- }
641
-
642
- /**
643
- * `<kai-resizable-item>` — a passive config-carrier inside `<kai-resizable>`. It
644
- * renders its own slotted light content (`<slot/>`); the parent `<kai-resizable>`
645
- * reads its `size`/`min`/`max`/`locked`/`hidden` attributes to lay it out.
646
- */
647
- defineWebComponent<ItemProps>('kai-resizable-item', {
648
- size: undefined,
649
- min: undefined,
650
- max: undefined,
651
- locked: false,
652
- hidden: false,
653
- collapsed: false,
654
- }, (props, { element, reflectFlag }) => {
655
- // Reflect the reactive `collapsed` prop to the `collapsed` ATTRIBUTE the parent
656
- // <kai-resizable> reads (and observes). This is what makes a bare JSX boolean
657
- // collapse the panel at INITIAL render from any framework: component-register
658
- // parses `<kai-resizable-item collapsed>` to `undefined` (not `true`), and a JSX
659
- // boolean sets neither `hidden` nor the IDL property — so the flag resolution
660
- // (which also honours the attribute) is the reliable source, and the attribute is
661
- // mirrored back so the parent's readItems()/MutationObserver lay it out. Same
662
- // pattern as <kai-chat>'s `loading` reflection, and now literally the same code:
663
- // `reflectFlag` also makes `el.collapsed` READ BACK, which a hand-rolled
664
- // toggleAttribute effect does not (WebComponentContext.reflectFlag).
665
- //
666
- // We touch only `collapsed` and `locked`, never `hidden`, so the back-compat hidden
667
- // path and maximize (which drive `hidden`) are untouched — see the named exemption
668
- // in tests/elements/reflected-boolean-coverage.test.ts for why `hidden` is a
669
- // separate decision rather than an oversight.
670
- reflectFlag('collapsed');
671
- // `locked` is the parent's other boolean input; the parent also writes it during
672
- // maximize/restore, and because the flag resolution re-derives from that same
673
- // attribute state the reflection stays self-consistent (no fight).
674
- reflectFlag('locked');
675
- // Reflect the STRING config props (`size`/`min`/`max`) property→attribute for the
676
- // SAME reason — a framework that sets them as DOM properties (React et al.) would
677
- // otherwise be invisible to the parent. See reflectItemConfig for the
678
- // drag-durability guard on `size`.
679
- reflectItemConfig(element, props);
680
- return (
681
- <>
682
- {/* The item host fills the panel's single grid cell (the panel stretches it on
683
- both axes) and OWNS the scroll: `display:block; width/height:100%;
684
- overflow:auto`. min:0 enables shrink-to-scroll.
685
-
686
- The FILL of the *slotted* content happens one level in: a `display:grid`
687
- wrapper with a single `minmax(0,1fr)` cell whose ONLY child is the `<slot>`.
688
- A grid item stretches to fill its cell on BOTH axes by default
689
- (`place-items:stretch`) into a *definite* `1fr` track, so slotted content
690
- fills width AND height whether or not it sets `height:100%`. The grid MUST
691
- be its own element wrapping the slot — NOT the host — because the element
692
- facade renders an empty portal-mount `<div>` (for overlays) as a sibling of
693
- the facade output; if the host itself were the grid, that portal div would
694
- become a second grid item and steal a track (collapsing content to the auto
695
- row). Scoping the grid to a wrapper whose sole child is the slot keeps
696
- exactly one grid item and is robust to the facade's portal sibling.
697
- Mirrors how Shoelace/Web Awesome `<sl-split-panel>` use grid for fill. */}
698
- <style>{':host{display:block;width:100%;height:100%;min-width:0;min-height:0;overflow:auto}'}</style>
699
- <div style={{ display: 'grid', 'grid-template-rows': 'minmax(0, 1fr)', 'grid-template-columns': 'minmax(0, 1fr)', width: '100%', height: '100%', 'min-width': '0', 'min-height': '0' }}>
700
- <slot />
701
- </div>
702
- </>
703
- ) as unknown as JSX.Element;
704
- });