@kitn.ai/ui 0.26.0 → 0.28.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.
- package/README.md +25 -6
- package/bin/mcp.js +16 -3
- package/bin/route.js +23 -0
- package/bin/route.test.js +58 -0
- package/dist/{elements/chunks/Icon--Y8vsFal.js → Icon-DObhsRtm.js} +1 -1
- package/dist/action-icons-CcgNN2oT.js +1 -0
- package/dist/arrow-down-CjRU3JgV.js +1 -0
- package/dist/arrow-left-Bnpb1UEW.js +1 -0
- package/dist/artifact-Bwt7OgcR.js +1 -0
- package/dist/assets/dev-5XzXYR21.js +91 -0
- package/dist/attachments-Qr4kg-2b.js +1 -0
- package/dist/{elements/chunks/audio-visualizer-D7lB6mvR.js → audio-visualizer-DToYdfSc.js} +1 -1
- package/dist/badge-CdEu_jn2.js +1 -0
- package/dist/bash-InADTalH.js +1 -6
- package/dist/bell-DQAAOpDz.js +1 -0
- package/dist/{elements/chunks/button-flUbeufF.js → button-DkuOnGLy.js} +1 -1
- package/dist/card-renderer-Jx70m6_l.js +1 -0
- package/dist/card-routing-0YidER_3.js +1 -0
- package/dist/check-njkVdZu2.js +1 -0
- package/dist/checkbox-D7iRB3nL.js +1 -0
- package/dist/checkbox-group-B2_rpoPM.js +1 -0
- package/dist/chevron-down-B72s6PXR.js +1 -0
- package/dist/chevron-right-BatuHzUm.js +1 -0
- package/dist/choice-card-m0BYqqOK.js +1 -0
- package/dist/circle-check-B62pODB3.js +1 -0
- package/dist/circle-x-BPG0iPst.js +1 -0
- package/dist/circle-zx0ByzY9.js +1 -0
- package/dist/{elements/chunks/cn-CU7UAWzk.js → cn-DN5AWfiS.js} +1 -1
- package/dist/code-block-ClMLKb7C.js +1 -0
- package/dist/{elements/chunks/collapsible-BzbXpPzr.js → collapsible-B4DlWicL.js} +1 -1
- package/dist/components/attachment-types.d.ts +7 -0
- package/dist/components/audio-visualizer/fit-scale.d.ts +1 -1
- package/dist/components/card-renderer.d.ts +13 -0
- package/dist/components/card.d.ts +4 -0
- package/dist/components/chat-thread.d.ts +135 -2
- package/dist/components/conversation-item.d.ts +35 -7
- package/dist/components/conversation-list.d.ts +17 -5
- package/dist/components/conversation-panel.d.ts +29 -0
- package/dist/components/form-widgets.d.ts +67 -2
- package/dist/components/form.d.ts +48 -1
- package/dist/components/home-panel.d.ts +34 -0
- package/dist/components/message.d.ts +25 -3
- package/dist/components/reasoning.d.ts +6 -0
- package/dist/components/scroll-button.d.ts +11 -0
- package/dist/components/thread.d.ts +5 -0
- package/dist/components/tool-types.d.ts +9 -0
- package/dist/components/widget-tab-bar.d.ts +16 -0
- package/dist/composer-sQ0HcvyG.js +106 -0
- package/dist/confirm-card-rQWDQsnC.js +1 -0
- package/dist/construct-cli.es.js +1337 -0
- package/dist/{elements/chunks/context-VLIL3sJ-.js → context-0kg4ZX1J.js} +1 -1
- package/dist/controllable-CnGpMF6r.js +1 -0
- package/dist/conversation-item-BxwQLaFJ.js +1 -0
- package/dist/conversation-list-BCfGN1JU.js +1 -0
- package/dist/copy-n9u9rqpi.js +1 -0
- package/dist/core-AYMC6_lb.js +12 -5874
- package/dist/{create-tween-BFT6c-Y8.js → create-tween-C-q-JCM-.js} +1 -1
- package/dist/{create-tween-CJNlzoaO.js → create-tween-CRrJXxBd.js} +1 -1
- package/dist/{create-tween-CQED4T0g.js → create-tween-DZ3RRDHD.js} +1 -1
- package/dist/{elements/chunks/create-tween-c4Z8TDYz.js → create-tween-uPkArjIG.js} +2 -2
- package/dist/css-M7EaDHN_.js +1 -6
- package/dist/custom-elements.json +1433 -202
- package/dist/default-input-CaMrJkgH.js +1 -0
- package/dist/define-By-uL588.js +1 -0
- package/dist/define.d.ts +4 -0
- package/dist/define.js +510 -0
- package/dist/define.server.d.ts +5 -0
- package/dist/define.server.js +506 -0
- package/dist/{elements/chunks/disclosure-CcNbyLy0.js → disclosure-WUImBbDv.js} +1 -1
- package/dist/{elements/chunks/dropdown-BgWTthUx.js → dropdown-wZVeJOMd.js} +1 -1
- package/dist/elements/agent-card.js +1 -1
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/audio-visualizer.js +1 -1
- package/dist/elements/autoloader.js +1 -1
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/badge.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkbox-group.d.ts +1 -0
- package/dist/elements/checkbox-group.js +1 -0
- package/dist/elements/checkbox.d.ts +1 -0
- package/dist/elements/checkbox.js +1 -0
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/coachmark.js +1 -1
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.js +1 -1
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.js +1 -1
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-item.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/define-entry.d.ts +12 -0
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.js +102 -8
- package/dist/elements/dropdown.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/element-data-types.d.ts +37 -0
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.js +1 -1
- package/dist/elements/icon.js +1 -1
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.js +1 -1
- package/dist/elements/kbd.js +1 -1
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.js +1 -1
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.js +1 -1
- package/dist/elements/notice.js +1 -1
- package/dist/elements/pane-grid.d.ts +1 -0
- package/dist/elements/pane-grid.js +1 -0
- package/dist/elements/pane-group.js +1 -1
- package/dist/elements/pane.js +1 -1
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.js +1 -1
- package/dist/elements/prompt-dock.js +1 -1
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/radio-group.d.ts +1 -0
- package/dist/elements/radio-group.js +1 -0
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +2 -2
- package/dist/elements/screen.js +1 -1
- package/dist/elements/scroll-area.js +1 -1
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.js +1 -1
- package/dist/elements/segmented.js +1 -1
- package/dist/elements/select.d.ts +1 -0
- package/dist/elements/select.js +1 -0
- package/dist/elements/separator.js +1 -1
- package/dist/elements/setting-item.js +1 -1
- package/dist/elements/settings-group.js +1 -1
- package/dist/elements/skeleton.js +1 -1
- package/dist/elements/slider.d.ts +1 -0
- package/dist/elements/slider.js +1 -0
- package/dist/elements/slots.d.ts +1 -1
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.js +1 -1
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.js +1 -1
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/thread.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.js +1 -1
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.js +1 -1
- package/dist/elements.d.ts +380 -26
- package/dist/{elements/chunks/ellipsis-7gU33mL2.js → ellipsis-CbOpJnU3.js} +1 -1
- package/dist/embed-CrfjkbUG.js +1 -0
- package/dist/engine-javascript-vq0WuIJl.js +14 -2516
- package/dist/{elements/chunks/external-link-CSOEsNlx.js → external-link-ByXAwBBQ.js} +1 -1
- package/dist/file-text-DMib2qwt.js +1 -0
- package/dist/{elements/chunks/file-tree-zvB2i7P9.js → file-tree-CJqM2aP7.js} +1 -1
- package/dist/folder-_BAb929C.js +1 -0
- package/dist/form-DSZgZQZk.js +1 -0
- package/dist/github-dark-dimmed-DUshB20C.js +1 -4
- package/dist/github-light-JYsPkUQd.js +1 -4
- package/dist/hover-card-BQbul9eq.js +1 -0
- package/dist/html-CPZ3oZQ7.js +1 -10
- package/dist/icon-CdcfRhYI.js +1 -0
- package/dist/{elements/chunks/index-BCRhi84a.js → index-xu_pdcPi.js} +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +7474 -5857
- package/dist/index.server.js +5965 -4762
- package/dist/info-DsFjGuI_.js +1 -0
- package/dist/input-DKbmkMos.js +1 -0
- package/dist/javascript-C25yR2R2.js +1 -6
- package/dist/json-DxJze_jm.js +1 -6
- package/dist/kai.es.js +1 -1
- package/dist/kbd-PvdGhX4s.js +1 -0
- package/dist/{elements/chunks/link-preview-OQ9IEq0f.js → link-preview-DbM1866N.js} +1 -1
- package/dist/link-zF8PzWfF.js +1 -0
- package/dist/loader-BM4CEz4G.js +1 -0
- package/dist/{elements/chunks/markdown-DgBFaGAz.js → markdown-LMvmAyBk.js} +7 -7
- package/dist/mcp.es.js +1361 -81
- package/dist/message-BSsgvHvf.js +1 -0
- package/dist/message-BYZECyek.js +1 -0
- package/dist/message-circle-DruwObfX.js +1 -0
- package/dist/message-square-BG6q6mlm.js +1 -0
- package/dist/{elements/chunks/minimize-2-DPIUKTrT.js → minimize-2-BQRoBV1V.js} +1 -1
- package/dist/{elements/chunks/model-switcher-DsT8tFB0.js → model-switcher-CMpCOYcB.js} +1 -1
- package/dist/{elements/chunks/overlay-DuiwdXjm.js → overlay-Cb-MkyDa.js} +1 -1
- package/dist/panel-right-i8warFxT.js +1 -0
- package/dist/paperclip-ByY3UVO6.js +1 -0
- package/dist/play-BvKKq3fX.js +1 -0
- package/dist/primitives/card-data-types.d.ts +49 -0
- package/dist/primitives/card-routing.d.ts +1 -33
- package/dist/primitives/card-validate.d.ts +2 -2
- package/dist/primitives/chat-config.d.ts +29 -2
- package/dist/primitives/conversation-store.d.ts +54 -0
- package/dist/primitives/field-mask.d.ts +96 -0
- package/dist/primitives/field-semantics.d.ts +36 -0
- package/dist/primitives/input-mask.d.ts +46 -0
- package/dist/primitives/url-scheme-policy.d.ts +34 -0
- package/dist/primitives/use-resize-observer.d.ts +2 -2
- package/dist/progress-bar-jVAHvMUf.js +1 -0
- package/dist/prompt-suggestion-CD-qtNgC.js +1 -0
- package/dist/radio-BsoBMhkF.js +1 -0
- package/dist/react/index.d.ts +586 -19
- package/dist/react.js +223 -187
- package/dist/reasoning-4kBPtlTx.js +1 -0
- package/dist/register-impl-B1hLkrI8.js +424 -0
- package/dist/{elements/chunks/resizable-D181b4fM.js → resizable-uPmY9VY-.js} +1 -1
- package/dist/rotate-ccw-B2xn93py.js +1 -0
- package/dist/rotate-cw-CMVLoCyH.js +1 -0
- package/dist/schemas/form.schema.json +21 -1
- package/dist/schemas/tool-defs.d.ts +11 -1
- package/dist/schemas.js +81 -81
- package/dist/scroll-area-BqLUo8ZZ.js +1 -0
- package/dist/scroll-button-DslXiJyL.js +1 -0
- package/dist/select-2cLRtPGT.js +1 -0
- package/dist/{elements/chunks/separator-CeJHQqLW.js → separator-BWQtNJcM.js} +1 -1
- package/dist/{elements/chunks/settings-CqaHgJF9.js → settings-BBR63jLg.js} +1 -1
- package/dist/{elements/chunks/settings-group-CjqjLCOn.js → settings-group-B2ciy-Iw.js} +1 -1
- package/dist/{elements/chunks/skeleton-D8akBnKS.js → skeleton-CkHI-HgC.js} +1 -1
- package/dist/slider-DDR9U-i0.js +1 -0
- package/dist/{solid-BtdqNZI7.js → solid-BzCFdL25.js} +9771 -7594
- package/dist/{solid-CnavwBye.js → solid-DruVOXnf.js} +7893 -6183
- package/dist/solid.d.ts +16 -2
- package/dist/solid.js +256 -243
- package/dist/solid.server.js +256 -243
- package/dist/source-GEnFF528.js +1 -0
- package/dist/star-CilHq8GP.js +1 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/mock.d.ts +32 -2
- package/dist/state.js +133 -108
- package/dist/store-Ciyk6eZG.js +1 -0
- package/dist/svelte--5p79yCD.js +1 -15
- package/dist/switch-KkeQIbuH.js +1 -0
- package/dist/tasks-card-BrN4bggJ.js +1 -0
- package/dist/text-shimmer-Dcj1MHuq.js +1 -0
- package/dist/textarea-Dpvbngbg.js +1 -0
- package/dist/theme.tokens.css +110 -13
- package/dist/{elements/chunks/thumbs-up-DX2Ijk3H.js → thumbs-up-CsT9Wzb9.js} +1 -1
- package/dist/toast-store-tgK6MuMv.js +1 -0
- package/dist/{elements/chunks/tool-DKQ2D1DP.js → tool-DzUjIBT8.js} +1 -1
- package/dist/{elements/chunks/tooltip-B0G99y8w.js → tooltip-Bkkg_4t0.js} +1 -1
- package/dist/trash-2-jBKxjGGQ.js +1 -0
- package/dist/{elements/chunks/triangle-alert-F9cyUEyy.js → triangle-alert-DlQ68ppf.js} +1 -1
- package/dist/tsx-B8rCNbgL.js +1 -6
- package/dist/types.d.ts +48 -3
- package/dist/typescript-RycA9KXf.js +1 -6
- package/dist/ui/checkbox-group.d.ts +83 -0
- package/dist/ui/checkbox.d.ts +40 -0
- package/dist/ui/dock.d.ts +51 -0
- package/dist/ui/icon.d.ts +3 -0
- package/dist/ui/input.d.ts +48 -2
- package/dist/ui/radio.d.ts +85 -0
- package/dist/ui/select.d.ts +71 -0
- package/dist/ui/slider.d.ts +65 -0
- package/dist/ui/switch.d.ts +9 -2
- package/dist/upload-TcAHXv9W.js +1 -0
- package/dist/url-scheme-policy-DR5DgvkM.js +1 -0
- package/dist/use-card-resolution-DaZqAdWf.js +1 -0
- package/dist/{elements/chunks/variant-aurora-qt6Zct8M.js → variant-aurora-BhLuYxJR.js} +1 -1
- package/dist/{variant-aurora-B8II3-I1.js → variant-aurora-CNmfHhcx.js} +2 -2
- package/dist/{variant-aurora-CMNWOSJR.js → variant-aurora-D6GsdTPA.js} +2 -2
- package/dist/{variant-aurora-CcuDMWwQ.js → variant-aurora-DbW_OWL2.js} +1 -1
- package/dist/{elements/chunks/variant-custom-tJp22_BQ.js → variant-custom-BRvaNHSi.js} +1 -1
- package/dist/{variant-custom-L16JLLZy.js → variant-custom-BvYHR62b.js} +1 -1
- package/dist/{variant-custom-BdvYC7af.js → variant-custom-DMTrEO5w.js} +2 -2
- package/dist/{variant-custom-C714mqKl.js → variant-custom-DV2x254s.js} +2 -2
- package/dist/{variant-wave-ecwykeyL.js → variant-wave-BNMGrDfj.js} +2 -2
- package/dist/{variant-wave-2S4La2Ka.js → variant-wave-BpDd8t3Z.js} +1 -1
- package/dist/{variant-wave-D7ruiA1W.js → variant-wave-CyBueXj9.js} +2 -2
- package/dist/{elements/chunks/variant-wave-CaQ5ti39.js → variant-wave-sp-qwsdI.js} +1 -1
- package/dist/vue-BmIZj4XD.js +1 -33
- package/dist/x-Z5UntkIJ.js +1 -0
- package/frameworks/react/index.tsx +210 -22
- package/llms-full.txt +1184 -22
- package/llms.txt +6 -3
- package/package.json +17 -4
- package/src/agent-tooling/README.md +192 -0
- package/src/agent-tooling/catalog/invariants.ts +3 -3
- package/src/agent-tooling/catalog/surfaces.ts +72 -0
- package/src/agent-tooling/construct/cli-entry.ts +8 -0
- package/src/agent-tooling/construct/cli.ts +147 -0
- package/src/agent-tooling/construct/codegen.ts +1635 -0
- package/src/agent-tooling/construct/construct.v1.schema.json +319 -0
- package/src/agent-tooling/construct/dev.ts +148 -0
- package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +7 -0
- package/src/agent-tooling/construct/fixtures/ops-console.construct.json +44 -0
- package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +32 -0
- package/src/agent-tooling/construct/schema.ts +452 -0
- package/src/agent-tooling/mcp/server.ts +2 -1
- package/src/agent-tooling/mcp/tools/construct.ts +130 -0
- package/src/agent-tooling/mcp/tools/debug.ts +126 -4
- package/src/agent-tooling/mcp/tools/reference.ts +104 -3
- package/src/agent-tooling/recipes/composed-thread.ts +714 -0
- package/src/agent-tooling/recipes/index.ts +22 -0
- package/src/agent-tooling/recipes/types.ts +32 -0
- package/src/agent-tooling/registry.ts +5 -0
- package/src/components/attachment-types.ts +7 -0
- package/src/components/audio-visualizer/fit-scale.ts +1 -1
- package/src/components/card-renderer.tsx +39 -8
- package/src/components/card.tsx +10 -2
- package/src/components/chat-scope-picker.tsx +2 -2
- package/src/components/chat-thread.tsx +602 -43
- package/src/components/choice-card.tsx +102 -37
- package/src/components/coachmark.tsx +1 -1
- package/src/components/code-block.tsx +2 -2
- package/src/components/composer.tsx +89 -15
- package/src/components/confirm-card.tsx +20 -4
- package/src/components/conversation-item.tsx +56 -9
- package/src/components/conversation-list.tsx +25 -10
- package/src/components/conversation-panel.tsx +118 -0
- package/src/components/empty.tsx +14 -3
- package/src/components/file-tree.tsx +5 -1
- package/src/components/form-widgets.tsx +257 -195
- package/src/components/form.tsx +297 -9
- package/src/components/home-panel.tsx +159 -0
- package/src/components/loader.tsx +12 -5
- package/src/components/message-skills.tsx +1 -1
- package/src/components/message.tsx +71 -11
- package/src/components/prompt-input.tsx +7 -1
- package/src/components/prompt-suggestion.tsx +4 -1
- package/src/components/reasoning.tsx +30 -3
- package/src/components/response-compare.tsx +2 -2
- package/src/components/scroll-button.tsx +56 -4
- package/src/components/source.tsx +6 -1
- package/src/components/tasks-card.tsx +58 -16
- package/src/components/thread.tsx +10 -1
- package/src/components/toast.tsx +1 -1
- package/src/components/tool-types.ts +9 -0
- package/src/components/widget-tab-bar.tsx +73 -0
- package/src/elements/attachments.tsx +3 -1
- package/src/elements/chat-workspace.tsx +1 -1
- package/src/elements/chat.tsx +115 -5
- package/src/elements/checkbox-group.tsx +164 -0
- package/src/elements/checkbox.tsx +134 -0
- package/src/elements/compiled.css +1 -1
- package/src/elements/composer.tsx +12 -1
- package/src/elements/conversation-item.tsx +62 -22
- package/src/elements/conversation-list.tsx +2 -2
- package/src/elements/define-entry.ts +12 -0
- package/src/elements/dock.tsx +11 -0
- package/src/elements/element-data-types.ts +40 -0
- package/src/elements/element-manifest.json +24 -0
- package/src/elements/element-meta.json +767 -34
- package/src/elements/element-nonscalar.json +17 -0
- package/src/elements/element-types.d.ts +380 -26
- package/src/elements/feedback-bar.tsx +5 -0
- package/src/elements/icon-names.json +29 -0
- package/src/elements/input.tsx +312 -23
- package/src/elements/message.tsx +2 -0
- package/src/elements/pane-grid.tsx +111 -0
- package/src/elements/prompt-input.tsx +8 -2
- package/src/elements/radio-group.tsx +129 -0
- package/src/elements/register-impl.ts +6 -0
- package/src/elements/scroll-button.tsx +54 -6
- package/src/elements/select.tsx +165 -0
- package/src/elements/slider.tsx +171 -0
- package/src/elements/slots.ts +1 -1
- package/src/elements/styles.css +89 -3
- package/src/elements/thread.tsx +2 -0
- package/src/elements/toast.tsx +14 -1
- package/src/index.ts +5 -2
- package/src/primitives/card-data-types.ts +49 -0
- package/src/primitives/card-host.tsx +4 -2
- package/src/primitives/card-routing.ts +7 -56
- package/src/primitives/card-schemas/form.schema.json +21 -1
- package/src/primitives/card-validate.ts +10 -2
- package/src/primitives/chat-config.tsx +33 -6
- package/src/primitives/conversation-store.ts +248 -0
- package/src/primitives/field-mask.ts +256 -0
- package/src/primitives/field-semantics.ts +115 -0
- package/src/primitives/input-mask.ts +853 -0
- package/src/primitives/toast-store.ts +66 -4
- package/src/primitives/url-scheme-policy.ts +70 -0
- package/src/primitives/use-resize-observer.ts +2 -2
- package/src/schemas/tool-defs.ts +12 -2
- package/src/solid.ts +20 -2
- package/src/state/index.ts +1 -1
- package/src/state/mock.ts +92 -6
- package/src/types.ts +45 -3
- package/src/ui/agent-card.tsx +2 -2
- package/src/ui/avatar.tsx +1 -1
- package/src/ui/checkbox-group.tsx +153 -0
- package/src/ui/checkbox.tsx +63 -0
- package/src/ui/dock.tsx +192 -7
- package/src/ui/icon.tsx +53 -0
- package/src/ui/input.tsx +249 -9
- package/src/ui/kbd.tsx +1 -1
- package/src/ui/nav.tsx +1 -1
- package/src/ui/pane-group.tsx +2 -2
- package/src/ui/radio.tsx +150 -0
- package/src/ui/select.tsx +168 -0
- package/src/ui/slider.tsx +178 -0
- package/src/ui/switch.tsx +49 -18
- package/src/utils/cn.ts +11 -5
- package/theme.css +112 -13
- package/dist/elements/chunks/action-icons-D9u3OzYW.js +0 -1
- package/dist/elements/chunks/arrow-left-CVh1TeN7.js +0 -1
- package/dist/elements/chunks/artifact-BkYcfIlZ.js +0 -1
- package/dist/elements/chunks/attachments-DwfNlubq.js +0 -1
- package/dist/elements/chunks/badge-Q0-Cmwzz.js +0 -1
- package/dist/elements/chunks/bash-InADTalH.js +0 -1
- package/dist/elements/chunks/card-renderer-3Dyl-FpN.js +0 -1
- package/dist/elements/chunks/card-routing-BK09BdmL.js +0 -1
- package/dist/elements/chunks/check-B5kBPKeo.js +0 -1
- package/dist/elements/chunks/chevron-down-DZ1GS39h.js +0 -1
- package/dist/elements/chunks/chevron-right-CvP7OUd2.js +0 -1
- package/dist/elements/chunks/choice-card-D4QUIOWZ.js +0 -1
- package/dist/elements/chunks/circle-CDf9g6MQ.js +0 -1
- package/dist/elements/chunks/circle-check-CA47Nqbz.js +0 -1
- package/dist/elements/chunks/circle-x-CJ_HVbC8.js +0 -1
- package/dist/elements/chunks/code-block-BdLiTitd.js +0 -1
- package/dist/elements/chunks/composer-Byve-n8K.js +0 -69
- package/dist/elements/chunks/confirm-card-B0flE3MN.js +0 -1
- package/dist/elements/chunks/controllable-DTwTIlwp.js +0 -1
- package/dist/elements/chunks/conversation-item-BDztezOG.js +0 -1
- package/dist/elements/chunks/copy-Nf-kqxXH.js +0 -1
- package/dist/elements/chunks/core-AYMC6_lb.js +0 -12
- package/dist/elements/chunks/css-M7EaDHN_.js +0 -1
- package/dist/elements/chunks/default-input-C2iLFq0b.js +0 -1
- package/dist/elements/chunks/define-wjHR1MkU.js +0 -1
- package/dist/elements/chunks/download-C4V7tBdb.js +0 -1
- package/dist/elements/chunks/embed-D3KewsIJ.js +0 -1
- package/dist/elements/chunks/engine-javascript-vq0WuIJl.js +0 -141
- package/dist/elements/chunks/file-text-D1G8khle.js +0 -1
- package/dist/elements/chunks/folder-WW2LGLid.js +0 -1
- package/dist/elements/chunks/form-CQirdC4W.js +0 -1
- package/dist/elements/chunks/github-dark-dimmed-DUshB20C.js +0 -1
- package/dist/elements/chunks/github-light-JYsPkUQd.js +0 -1
- package/dist/elements/chunks/hover-card-CJJkfHTK.js +0 -1
- package/dist/elements/chunks/html-CPZ3oZQ7.js +0 -1
- package/dist/elements/chunks/icon-Cfgmf4fa.js +0 -1
- package/dist/elements/chunks/info-DX3YMOt6.js +0 -1
- package/dist/elements/chunks/input-BtW9U6Sq.js +0 -1
- package/dist/elements/chunks/javascript-C25yR2R2.js +0 -1
- package/dist/elements/chunks/json-DxJze_jm.js +0 -1
- package/dist/elements/chunks/kbd-LGXwuT_V.js +0 -1
- package/dist/elements/chunks/link-2My69BqT.js +0 -1
- package/dist/elements/chunks/loader-iOxc_Tu-.js +0 -1
- package/dist/elements/chunks/message-VMZohrXx.js +0 -1
- package/dist/elements/chunks/message-circle-CpXMM-_n.js +0 -1
- package/dist/elements/chunks/message-square-DxcWtETQ.js +0 -1
- package/dist/elements/chunks/message-tZmV2A3p.js +0 -1
- package/dist/elements/chunks/paperclip-CRZVp4z_.js +0 -1
- package/dist/elements/chunks/progress-bar-DNy66e_E.js +0 -1
- package/dist/elements/chunks/prompt-suggestion-Bn64Nl7L.js +0 -1
- package/dist/elements/chunks/reasoning-Emn9N4-T.js +0 -1
- package/dist/elements/chunks/rotate-cw-CPWe37D9.js +0 -1
- package/dist/elements/chunks/scroll-area-ClZkZxIk.js +0 -1
- package/dist/elements/chunks/scroll-button-DPE-t3x_.js +0 -1
- package/dist/elements/chunks/share-CyfnNEqp.js +0 -1
- package/dist/elements/chunks/source-UWCvmVak.js +0 -1
- package/dist/elements/chunks/star-DoHFAikQ.js +0 -1
- package/dist/elements/chunks/store-Cjq0qwYN.js +0 -1
- package/dist/elements/chunks/svelte--5p79yCD.js +0 -1
- package/dist/elements/chunks/tasks-card-CmZ5xh6v.js +0 -1
- package/dist/elements/chunks/text-shimmer-DYn09zrz.js +0 -1
- package/dist/elements/chunks/textarea-skiGHURM.js +0 -1
- package/dist/elements/chunks/toast-store-CFnQpThX.js +0 -1
- package/dist/elements/chunks/tsx-B8rCNbgL.js +0 -1
- package/dist/elements/chunks/typescript-RycA9KXf.js +0 -1
- package/dist/elements/chunks/use-card-resolution-DoA2f_EU.js +0 -1
- package/dist/elements/chunks/vue-BmIZj4XD.js +0 -1
- package/dist/elements/chunks/x-B6UnOiLw.js +0 -1
- package/dist/llms/llms-full.txt +0 -2949
- package/dist/llms/llms.txt +0 -156
- package/dist/register-impl-DpE7icIb.js +0 -293
- package/dist/ui/stat.d.ts +0 -16
- package/src/ui/stat.tsx +0 -41
- /package/dist/{elements/chunks/card-tags-D8lZ-C_U.js → card-tags-D8lZ-C_U.js} +0 -0
- /package/dist/{elements/chunks/link-preview-DNILK391.js → link-preview-DNILK391.js} +0 -0
- /package/dist/{elements/chunks/slots-DaNjX0rc.js → slots-DaNjX0rc.js} +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type JSX, splitProps, createEffect } from 'solid-js';
|
|
2
|
+
import { cn } from '../utils/cn';
|
|
3
|
+
|
|
4
|
+
export interface CheckboxProps extends Omit<JSX.InputHTMLAttributes<HTMLInputElement>, 'type' | 'children'> {
|
|
5
|
+
/**
|
|
6
|
+
* The mixed / partially-checked state ("some of the things below are ticked").
|
|
7
|
+
*
|
|
8
|
+
* `indeterminate` is a DOM PROPERTY with no HTML attribute, so it cannot be set
|
|
9
|
+
* from markup — every caller that wanted it used to reach for a `ref` plus a
|
|
10
|
+
* `createEffect`. That effect now lives in here, once, and callers pass a prop.
|
|
11
|
+
*
|
|
12
|
+
* Note that the property is purely visual plus an accessibility hint: a checkbox
|
|
13
|
+
* whose `indeterminate` is true still reports `checked === false` and submits
|
|
14
|
+
* accordingly. A native indeterminate checkbox already announces as "mixed", so
|
|
15
|
+
* this component does not stamp `aria-checked="mixed"` on top of it — pass one
|
|
16
|
+
* yourself if you also want the attribute in the DOM.
|
|
17
|
+
*/
|
|
18
|
+
indeterminate?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A checkbox. A REAL `<input type="checkbox">` behind `appearance: none`, styled by
|
|
23
|
+
* the kit's `.kai-checkbox` rule, never a `<div>` wearing `role="checkbox"`.
|
|
24
|
+
*
|
|
25
|
+
* That is the whole design: the native control brings keyboard operation (Space),
|
|
26
|
+
* the `:focus-visible` ring, form participation via `name` / `value`, and correct
|
|
27
|
+
* screen-reader announcement — all of it for free and all of it correct. Every
|
|
28
|
+
* accessibility defect this kit's control audit found was in a control that had
|
|
29
|
+
* replaced the native element with something hand-rolled.
|
|
30
|
+
*
|
|
31
|
+
* Everything not listed in `CheckboxProps` is forwarded to the input, so `id`,
|
|
32
|
+
* `name`, `value`, `required`, `disabled`, `aria-*` and any `data-*` hook behave
|
|
33
|
+
* exactly as they do on a plain `<input>`.
|
|
34
|
+
*
|
|
35
|
+
* Validation is deliberately absent. `required` is passed through to the native
|
|
36
|
+
* attribute and nothing else — whether an unchecked box is an error is the
|
|
37
|
+
* consuming application's call, not the kit's.
|
|
38
|
+
*
|
|
39
|
+
* ```tsx
|
|
40
|
+
* <Checkbox name="notify" checked={on()} onChange={(e) => setOn(e.currentTarget.checked)} />
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function Checkbox(props: CheckboxProps): JSX.Element {
|
|
44
|
+
const [local, rest] = splitProps(props, ['class', 'indeterminate', 'ref']);
|
|
45
|
+
return (
|
|
46
|
+
<input
|
|
47
|
+
{...rest}
|
|
48
|
+
type="checkbox"
|
|
49
|
+
class={cn('kai-checkbox', local.class)}
|
|
50
|
+
ref={(el) => {
|
|
51
|
+
// `ref` is split out and re-applied by hand because this component needs the
|
|
52
|
+
// element for `indeterminate` as well. Solid always hands a component a ref
|
|
53
|
+
// FUNCTION (a variable ref compiles into one), so the typeof guard is for the
|
|
54
|
+
// hand-written object case only.
|
|
55
|
+
const forward = local.ref;
|
|
56
|
+
if (typeof forward === 'function') (forward as (el: HTMLInputElement) => void)(el);
|
|
57
|
+
createEffect(() => {
|
|
58
|
+
el.indeterminate = !!local.indeterminate;
|
|
59
|
+
});
|
|
60
|
+
}}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
package/src/ui/dock.tsx
CHANGED
|
@@ -42,6 +42,19 @@ export interface DockProps {
|
|
|
42
42
|
unread?: boolean;
|
|
43
43
|
/** Disable the launcher. */
|
|
44
44
|
disabled?: boolean;
|
|
45
|
+
/** Suppress the dock's own built-in mobile `[part="close"]` X. Off (rendered) by
|
|
46
|
+
* default — the built-in X is the FALLBACK close route for panel content with no
|
|
47
|
+
* header of its own, which is the general case the dock has to cover since it
|
|
48
|
+
* never reads what it holds. Set `true` when the slotted/composed content
|
|
49
|
+
* supplies its own close affordance in its own header row (e.g. `ChatThread`'s
|
|
50
|
+
* `headerEndContent`) — with both present the two X's stack, one floating over
|
|
51
|
+
* the other's row, which is exactly the "doesn't look intentional" feedback this
|
|
52
|
+
* prop exists to let a caller avoid. TRADEOFF: the mobile panel reserves a
|
|
53
|
+
* padding band above its content so the built-in X never paints over it; that
|
|
54
|
+
* band stays reserved unless you set `hideClose` true, so only set it once your
|
|
55
|
+
* own control is actually in place — otherwise you get the band with no X to
|
|
56
|
+
* justify it. */
|
|
57
|
+
hideClose?: boolean;
|
|
45
58
|
/** Where focus lands on open. Defaults to `content`. */
|
|
46
59
|
focusOnOpen?: DockFocusOnOpen;
|
|
47
60
|
/** Controlled open state. When set, the component never changes it itself — drive it
|
|
@@ -79,6 +92,52 @@ export function DockCloseGlyph(): JSX.Element {
|
|
|
79
92
|
return <X size={24} />;
|
|
80
93
|
}
|
|
81
94
|
|
|
95
|
+
export interface DockLauncherImageProps {
|
|
96
|
+
/** The icon URL. */
|
|
97
|
+
src: string;
|
|
98
|
+
/** Alt text — usually left empty: the launcher BUTTON already carries the
|
|
99
|
+
* accessible name (Dock derives it from `label`/`openLabel`/`closeLabel`),
|
|
100
|
+
* so a second name on the icon inside it would be redundant, not missing. */
|
|
101
|
+
alt?: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* A branded launcher icon with a built-in fallback to {@link DockLauncherGlyph}
|
|
106
|
+
* on load failure — a dead link, or a placeholder URL nobody swapped for a
|
|
107
|
+
* real asset yet (exactly what shipped in `kai dev`'s own `owner-widget`
|
|
108
|
+
* fixture: `launcherIcon: "https://example.com/logo.png"`, which never
|
|
109
|
+
* resolves, so the FAB rendered a permanently broken image). Decides loudly
|
|
110
|
+
* with one `console.warn` naming the failing URL, then swaps — never a
|
|
111
|
+
* silent broken-image icon sitting in the corner of someone's page.
|
|
112
|
+
*
|
|
113
|
+
* Lives here, not on {@link Dock} itself: `Dock`'s `launcher` prop is
|
|
114
|
+
* deliberately ANY content (an emoji, a "Support" text pill, this image,
|
|
115
|
+
* whatever a consumer slots in) and the dock never inspects what it's
|
|
116
|
+
* holding — teaching it to specifically understand "this might be an
|
|
117
|
+
* `<img>` that can 404" would be the one prop where that boundary breaks.
|
|
118
|
+
* This is a plain sibling component a `launcher` value can be built FROM,
|
|
119
|
+
* same relationship `DockLauncherGlyph`/`DockCloseGlyph` already have to
|
|
120
|
+
* `Dock`. The construct engine's `emitDockLauncher` (codegen.ts) renders
|
|
121
|
+
* `<DockLauncherImage src={...} />` for a construct-authored `launcherIcon`
|
|
122
|
+
* rather than hand-rolling the same onError dance in emitted output.
|
|
123
|
+
*/
|
|
124
|
+
export function DockLauncherImage(props: DockLauncherImageProps) {
|
|
125
|
+
const [failed, setFailed] = createSignal(false);
|
|
126
|
+
return (
|
|
127
|
+
<Show when={!failed()} fallback={<DockLauncherGlyph />}>
|
|
128
|
+
<img
|
|
129
|
+
src={props.src}
|
|
130
|
+
alt={props.alt ?? ''}
|
|
131
|
+
style={{ width: '24px', height: '24px', 'border-radius': '9999px' }}
|
|
132
|
+
onError={() => {
|
|
133
|
+
console.warn(`[kai] Dock launcher icon failed to load (${props.src}); falling back to the default glyph.`);
|
|
134
|
+
setFailed(true);
|
|
135
|
+
}}
|
|
136
|
+
/>
|
|
137
|
+
</Show>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
82
141
|
/**
|
|
83
142
|
* The dock's own stylesheet, scoped to its shadow root.
|
|
84
143
|
*
|
|
@@ -139,7 +198,12 @@ const DOCK_CSS = `
|
|
|
139
198
|
/* ABOVE the panel, always. At <=480px the panel goes fixed/inset:0 and it comes
|
|
140
199
|
after the launcher in DOM order, so at z-index:auto it painted OVER the launcher
|
|
141
200
|
and a touch user lost every pointer route to closing. Both reference
|
|
142
|
-
implementations stacked the launcher over the panel for the same reason.
|
|
201
|
+
implementations stacked the launcher over the panel for the same reason. The
|
|
202
|
+
launcher itself is now HIDDEN while the panel is open at that width (see the
|
|
203
|
+
<=480px block below) in favour of the in-panel [part="close"] X, but this
|
|
204
|
+
z-index still matters for the moment between "open" landing and the panel's
|
|
205
|
+
own transition finishing, and for any consumer CSS that reintroduces the
|
|
206
|
+
launcher there. */
|
|
143
207
|
z-index: 1;
|
|
144
208
|
flex: none;
|
|
145
209
|
display: inline-flex;
|
|
@@ -168,6 +232,58 @@ const DOCK_CSS = `
|
|
|
168
232
|
[data-kai-dock] [part="launcher"]:focus-visible { outline: 2px solid var(--color-ring); outline-offset: 2px; }
|
|
169
233
|
[data-kai-dock] [part="launcher"]:disabled { opacity: 0.55; cursor: not-allowed; }
|
|
170
234
|
|
|
235
|
+
/* The mobile-only close affordance rendered INSIDE the panel. Hidden by default and
|
|
236
|
+
only switched on inside the <=480px media block below, alongside the rule that
|
|
237
|
+
hides the launcher while the panel is open at that width — same query drives both,
|
|
238
|
+
CSS-only, no JS viewport logic. Absolutely positioned against the panel, which is
|
|
239
|
+
the panel's own containing block once the narrow-viewport rule below sets it to
|
|
240
|
+
position: fixed.
|
|
241
|
+
|
|
242
|
+
The inset is a CONSUMER-OVERRIDABLE TOKEN, same idiom as every other geometry
|
|
243
|
+
value in this file (--kai-dock-width and friends). The dock is content-agnostic —
|
|
244
|
+
it never reads what is slotted into the panel — so it cannot know whether that
|
|
245
|
+
content renders its own trailing controls (a ChatThread header-end slot with
|
|
246
|
+
share/settings icons, say) in the same top-right corner.
|
|
247
|
+
|
|
248
|
+
The mobile block below reserves a BAND of the panel's own padding above whatever
|
|
249
|
+
is slotted, sized to this button's own footprint, so nothing paints under this X
|
|
250
|
+
by default -- verified fix (round 1) against a real ChatThread header-end slot
|
|
251
|
+
colliding with it at 375px. Owner feedback on the real widget (round 2): for a
|
|
252
|
+
construct with only a title in the header, that band read as a dead empty strip
|
|
253
|
+
with the X floating alone in it -- "that doesn't look like the empty component
|
|
254
|
+
either, lets do better." The actual fix composes instead of reserving space:
|
|
255
|
+
ChatThread now has its own headerEndContent escape hatch (see its prop doc) so a
|
|
256
|
+
caller puts the close control INSIDE the header row, sharing it with the title --
|
|
257
|
+
zero collision by construction, no band needed. hideClose on this component (see
|
|
258
|
+
its prop doc) then suppresses this built-in X for exactly that case, and the
|
|
259
|
+
band above is scoped to :not([data-hide-close]) so it comes off ONLY there --
|
|
260
|
+
every other consumer (anyone who hasn't opted into hideClose, including a
|
|
261
|
+
hand-authored dock with real header-end content) keeps the band, same as round 1
|
|
262
|
+
shipped, so the collision it fixed stays fixed for them. What remains here for
|
|
263
|
+
that default case is a plain absolute overlay, top-right of the panel, with
|
|
264
|
+
these consumer-overridable inset tokens for the rare case it should deliberately
|
|
265
|
+
sit in front of something (e.g. a single small badge). */
|
|
266
|
+
[data-kai-dock] [part="close"] {
|
|
267
|
+
display: none;
|
|
268
|
+
position: absolute;
|
|
269
|
+
inset-block-start: var(--kai-dock-close-inset-block, 0.75rem);
|
|
270
|
+
inset-inline-end: var(--kai-dock-close-inset-inline, 0.75rem);
|
|
271
|
+
z-index: 1;
|
|
272
|
+
align-items: center;
|
|
273
|
+
justify-content: center;
|
|
274
|
+
inline-size: 2.25rem;
|
|
275
|
+
block-size: 2.25rem;
|
|
276
|
+
padding: 0;
|
|
277
|
+
border: 0;
|
|
278
|
+
border-radius: 9999px;
|
|
279
|
+
background: var(--color-background);
|
|
280
|
+
color: var(--color-foreground);
|
|
281
|
+
box-shadow: 0 2px 8px -2px rgb(0 0 0 / 0.3);
|
|
282
|
+
cursor: pointer;
|
|
283
|
+
}
|
|
284
|
+
[data-kai-dock] [part="close"]:hover { background: var(--color-muted, var(--color-background)); }
|
|
285
|
+
[data-kai-dock] [part="close"]:focus-visible { outline: 2px solid var(--color-ring); outline-offset: 2px; }
|
|
286
|
+
|
|
171
287
|
[data-kai-dock] [part="badge"] {
|
|
172
288
|
position: absolute;
|
|
173
289
|
inset-block-start: 3px;
|
|
@@ -175,7 +291,7 @@ const DOCK_CSS = `
|
|
|
175
291
|
inline-size: 0.75rem;
|
|
176
292
|
block-size: 0.75rem;
|
|
177
293
|
border-radius: 9999px;
|
|
178
|
-
background: var(--color-
|
|
294
|
+
background: var(--color-unread);
|
|
179
295
|
box-shadow: 0 0 0 2px var(--color-primary);
|
|
180
296
|
}
|
|
181
297
|
|
|
@@ -222,10 +338,12 @@ const DOCK_CSS = `
|
|
|
222
338
|
[data-kai-dock][data-position^="top"] [part="panel"][data-closed] { transform: translateY(-0.5rem); }
|
|
223
339
|
|
|
224
340
|
/* Narrow viewports take the panel full-bleed. A SHIPPED DEFAULT, not a prop: both
|
|
225
|
-
references wrote this rule independently, which makes it a HOW.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
341
|
+
references wrote this rule independently, which makes it a HOW. While the panel is
|
|
342
|
+
OPEN at this width the launcher hides and the panel's own [part="close"] X becomes
|
|
343
|
+
the pointer close route instead — a FAB floating over a full-bleed panel read as
|
|
344
|
+
wrong (owner feedback) and Escape alone strands a touch user with no visible
|
|
345
|
+
affordance at all. Closed, the launcher is unaffected: it is the panel's own
|
|
346
|
+
[data-expanded] state that gates both rules below, not the media query alone. */
|
|
229
347
|
@media (max-width: 480px) {
|
|
230
348
|
[data-kai-dock] [part="panel"] {
|
|
231
349
|
position: fixed;
|
|
@@ -237,6 +355,41 @@ const DOCK_CSS = `
|
|
|
237
355
|
border: 0;
|
|
238
356
|
border-radius: 0;
|
|
239
357
|
}
|
|
358
|
+
|
|
359
|
+
/* Reserve a band for the built-in [part="close"] X ABOVE whatever is slotted,
|
|
360
|
+
rather than overlaying it on top of the panel's own content — the fix round 1
|
|
361
|
+
collision protection (verified against a real ChatThread header-end slot at
|
|
362
|
+
375px: without this, the X painted directly over trailing icon buttons).
|
|
363
|
+
DERIVED from the button's own inset + size tokens, not a second hand-typed
|
|
364
|
+
number.
|
|
365
|
+
|
|
366
|
+
SCOPED to :not([data-hide-close]) — round 2 (owner feedback: the band read as
|
|
367
|
+
a dead strip when nothing but the X occupied it) removed this UNCONDITIONALLY
|
|
368
|
+
and reintroduced the very collision round 1 fixed, for every consumer who
|
|
369
|
+
never opted into hideClose. hideClose is only true for a caller that supplies
|
|
370
|
+
its OWN close control in its own header row (ChatThread's headerEndContent is
|
|
371
|
+
the one that does today) — the built-in X and this band both come off
|
|
372
|
+
together for that case, since there is nothing left for the band to protect.
|
|
373
|
+
Every other consumer -- including a hand-authored kai-dock with real
|
|
374
|
+
slot="header-end" content and no opinion on hideClose -- keeps the band, the
|
|
375
|
+
same as round 1 shipped. */
|
|
376
|
+
[data-kai-dock]:not([data-hide-close]) [part="panel"] {
|
|
377
|
+
padding-block-start: calc(2 * var(--kai-dock-close-inset-block, 0.75rem) + 2.25rem);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/* The full-bleed panel gets its own close affordance instead of relying on the
|
|
381
|
+
launcher, which is hidden below while the panel is open at this width — a FAB
|
|
382
|
+
floating over a full-bleed panel with no other visible close route is exactly
|
|
383
|
+
what the owner flagged. Escape and the X both still work; the launcher comes
|
|
384
|
+
back the instant the panel closes because data-expanded is gone by then.
|
|
385
|
+
Absolutely positioned, so the padding-block-start above (a content-box
|
|
386
|
+
concern) does not shift IT — only the in-flow slotted content. Content that
|
|
387
|
+
supplies its own close control passes hideClose, which drops the button from
|
|
388
|
+
the render tree entirely (see the component body) rather than being gated
|
|
389
|
+
here — so this rule stays a plain, unconditional width-query switch; the band
|
|
390
|
+
above is what actually varies with hideClose. */
|
|
391
|
+
[data-kai-dock] [part="close"] { display: inline-flex; }
|
|
392
|
+
[data-kai-dock]:has([part="panel"][data-expanded]) [part="launcher"] { display: none; }
|
|
240
393
|
}
|
|
241
394
|
|
|
242
395
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -310,6 +463,15 @@ function isWithin(root: Node, node: Node | null): boolean {
|
|
|
310
463
|
* own menus; swallowing a key from a page you are a guest on is a decide-quietly move.
|
|
311
464
|
* - **No focus trap**, deliberately, unlike `kai-dialog`. The page staying usable is
|
|
312
465
|
* the whole point of "docked", which is also why the panel is `aria-modal="false"`.
|
|
466
|
+
* - **Mobile close route.** At <=480px the panel goes full-bleed and the launcher
|
|
467
|
+
* hides while it is open — a floating launcher over a full-bleed panel is not an
|
|
468
|
+
* obvious close affordance. The panel gets its own `[part="close"]` X, top-right,
|
|
469
|
+
* CSS-gated by the SAME media query and `[data-expanded]`, so it needs no viewport
|
|
470
|
+
* JS. Desktop is unaffected: the launcher keeps toggling and no X ever renders.
|
|
471
|
+
* This is the FALLBACK route, for panel content with no header of its own to hold
|
|
472
|
+
* a close control — content that does (a `ChatThread` using `headerEndContent`,
|
|
473
|
+
* say) passes `hideClose` to drop this X instead of stacking a second one over
|
|
474
|
+
* its own header row.
|
|
313
475
|
*
|
|
314
476
|
* WHAT IT REFUSES: it never aborts a request, never persists its own open state, never
|
|
315
477
|
* decides what "unread" means, and never clears `unread` on open — writing over a
|
|
@@ -393,7 +555,17 @@ export function Dock(props: DockProps) {
|
|
|
393
555
|
return (
|
|
394
556
|
<>
|
|
395
557
|
<style>{DOCK_CSS}</style>
|
|
396
|
-
<div
|
|
558
|
+
<div
|
|
559
|
+
data-kai-dock
|
|
560
|
+
data-position={props.position ?? 'bottom-end'}
|
|
561
|
+
// Drives the mobile panel's reserved-band rule below: present only when the
|
|
562
|
+
// built-in [part="close"] X is ACTUALLY suppressed (hideClose true), so the
|
|
563
|
+
// band stays on for every consumer who hasn't opted into their own close
|
|
564
|
+
// control — see the [part="close"]/reserved-band comments for why removing
|
|
565
|
+
// it unconditionally regressed the collision it existed to prevent.
|
|
566
|
+
bool:data-hide-close={!!props.hideClose}
|
|
567
|
+
onKeyDown={onKeyDown}
|
|
568
|
+
>
|
|
397
569
|
<button
|
|
398
570
|
ref={(el) => { launcher = el; props.launcherRef?.(el); }}
|
|
399
571
|
part="launcher"
|
|
@@ -437,6 +609,19 @@ export function Dock(props: DockProps) {
|
|
|
437
609
|
'pointer-events': isOpen() ? 'auto' : 'none',
|
|
438
610
|
}}
|
|
439
611
|
>
|
|
612
|
+
{/* Mobile-only (see the <=480px rule in DOCK_CSS): the full-bleed panel's
|
|
613
|
+
own close affordance, since the launcher is hidden by the same query
|
|
614
|
+
while the panel is open. Reuses the launcher's derived close name
|
|
615
|
+
rather than a new prop — same string, same i18n override. Dropped
|
|
616
|
+
from the render tree entirely (not just hidden) when `hideClose` is
|
|
617
|
+
set — the panel content supplies its own, in its own header, and a
|
|
618
|
+
second X floating over that row is the exact "doesn't look
|
|
619
|
+
intentional" feedback `hideClose` exists to avoid. */}
|
|
620
|
+
<Show when={!props.hideClose}>
|
|
621
|
+
<button type="button" part="close" aria-label={launcherName()} onClick={() => setOpen(false)}>
|
|
622
|
+
<DockCloseGlyph />
|
|
623
|
+
</button>
|
|
624
|
+
</Show>
|
|
440
625
|
{props.children}
|
|
441
626
|
</div>
|
|
442
627
|
</div>
|
package/src/ui/icon.tsx
CHANGED
|
@@ -9,6 +9,16 @@ import {
|
|
|
9
9
|
Archive, ArrowUp, Bookmark, Copy, Ellipsis, ExternalLink, Flag,
|
|
10
10
|
GitBranch, GitPullRequest, ListFilter, RotateCw,
|
|
11
11
|
Moon, Sun,
|
|
12
|
+
// Device / viewport glyphs.
|
|
13
|
+
Tablet, Smartphone, Laptop,
|
|
14
|
+
// Direction glyphs completing the chevron + arrow quartets.
|
|
15
|
+
ChevronRight, ChevronUp, ArrowRight, ArrowDown, PanelRight,
|
|
16
|
+
// Status glyphs (kai-notice / kai-toast / kai-tool render these already).
|
|
17
|
+
Check, Info, TriangleAlert, CircleCheck, CircleAlert, CircleX,
|
|
18
|
+
// Action glyphs the kit performs but could not be named.
|
|
19
|
+
Trash2, Download, Upload, Link, RotateCcw,
|
|
20
|
+
// Pane / media chrome.
|
|
21
|
+
Maximize2, Minimize2, Eye, EyeOff, Bell, Square, Minus, Play,
|
|
12
22
|
} from 'lucide-solid';
|
|
13
23
|
|
|
14
24
|
type IconComponent = Component<{ class?: string }>;
|
|
@@ -68,8 +78,51 @@ const NAMED_ICONS: Record<string, IconComponent> = {
|
|
|
68
78
|
// Theme / appearance glyphs.
|
|
69
79
|
moon: Moon,
|
|
70
80
|
sun: Sun,
|
|
81
|
+
// Device / viewport glyphs. `desktop` and `mobile` are aliases onto the same
|
|
82
|
+
// components as `monitor`/`smartphone` — lucide's names are not the words a
|
|
83
|
+
// consumer reaches for, and an alias costs nothing in the bundle.
|
|
84
|
+
desktop: Monitor,
|
|
85
|
+
laptop: Laptop,
|
|
86
|
+
tablet: Tablet,
|
|
87
|
+
smartphone: Smartphone,
|
|
88
|
+
mobile: Smartphone,
|
|
89
|
+
// Direction glyphs — chevron-down/left and arrow-left/up were here without
|
|
90
|
+
// their opposites; both quartets are now complete.
|
|
91
|
+
'chevron-right': ChevronRight,
|
|
92
|
+
'chevron-up': ChevronUp,
|
|
93
|
+
'arrow-right': ArrowRight,
|
|
94
|
+
'arrow-down': ArrowDown,
|
|
95
|
+
'panel-right': PanelRight,
|
|
96
|
+
// Status glyphs. kai-notice / kai-toast / kai-tool already paint these, so a
|
|
97
|
+
// host building matching UI needs to be able to name them.
|
|
98
|
+
check: Check,
|
|
99
|
+
info: Info,
|
|
100
|
+
'triangle-alert': TriangleAlert,
|
|
101
|
+
'circle-check': CircleCheck,
|
|
102
|
+
'circle-alert': CircleAlert,
|
|
103
|
+
'circle-x': CircleX,
|
|
104
|
+
// Action glyphs. `trash`/`download`/`link` match the keys action-icons.ts
|
|
105
|
+
// already uses for message actions; `upload` is download's missing sibling.
|
|
106
|
+
trash: Trash2,
|
|
107
|
+
download: Download,
|
|
108
|
+
upload: Upload,
|
|
109
|
+
link: Link,
|
|
110
|
+
'rotate-ccw': RotateCcw,
|
|
111
|
+
// Pane / media chrome (kai-pane, kai-artifact, kai-embed, kai-agent-card).
|
|
112
|
+
'maximize-2': Maximize2,
|
|
113
|
+
'minimize-2': Minimize2,
|
|
114
|
+
eye: Eye,
|
|
115
|
+
'eye-off': EyeOff,
|
|
116
|
+
bell: Bell,
|
|
117
|
+
square: Square,
|
|
118
|
+
minus: Minus,
|
|
119
|
+
play: Play,
|
|
71
120
|
};
|
|
72
121
|
|
|
122
|
+
/** Every curated icon name, sorted. Derived from `NAMED_ICONS` so a gallery,
|
|
123
|
+
* a story control or a test can never drift from the map itself. */
|
|
124
|
+
export const ICON_NAMES: readonly string[] = Object.keys(NAMED_ICONS).sort();
|
|
125
|
+
|
|
73
126
|
/** Render an item icon.
|
|
74
127
|
*
|
|
75
128
|
* Resolution order:
|