@kitn.ai/ui 0.26.0 → 0.27.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 +16 -5
- 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-BnFKqqtY.js} +1 -1
- package/dist/action-icons-CBskfBMz.js +1 -0
- package/dist/arrow-down-Br0qtpsz.js +1 -0
- package/dist/arrow-left-Dj7xgE12.js +1 -0
- package/dist/artifact-CvXEm1lS.js +1 -0
- package/dist/assets/dev-5XzXYR21.js +91 -0
- package/dist/attachments-C43ZegEq.js +1 -0
- package/dist/{elements/chunks/audio-visualizer-D7lB6mvR.js → audio-visualizer-B-79y1Tj.js} +1 -1
- package/dist/badge-BpUbq8c0.js +1 -0
- package/dist/bash-InADTalH.js +1 -6
- package/dist/bell-sn17Ip9v.js +1 -0
- package/dist/{elements/chunks/button-flUbeufF.js → button-BH6rN0U-.js} +1 -1
- package/dist/card-renderer-Cb1gQmth.js +1 -0
- package/dist/card-routing-DifQgS7n.js +1 -0
- package/dist/check-DPeeMUYx.js +1 -0
- package/dist/checkbox-Dc9Yov_B.js +1 -0
- package/dist/checkbox-group-B1kDLLYk.js +1 -0
- package/dist/chevron-down-CHSWk7ZT.js +1 -0
- package/dist/chevron-right-B7l_fMgx.js +1 -0
- package/dist/choice-card-BT3c1S8g.js +1 -0
- package/dist/circle-Bb0yOpqM.js +1 -0
- package/dist/circle-check-BGZpCiz7.js +1 -0
- package/dist/circle-x-wobWkoSx.js +1 -0
- package/dist/{elements/chunks/cn-CU7UAWzk.js → cn-DN5AWfiS.js} +1 -1
- package/dist/{elements/chunks/code-block-BdLiTitd.js → code-block-CUQ5mtv0.js} +1 -1
- package/dist/{elements/chunks/collapsible-BzbXpPzr.js → collapsible-CPJbf6FM.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 +46 -1
- package/dist/components/conversation-item.d.ts +19 -7
- package/dist/components/conversation-list.d.ts +17 -5
- package/dist/components/form-widgets.d.ts +67 -2
- package/dist/components/form.d.ts +48 -1
- 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/composer-CjngLzal.js +106 -0
- package/dist/confirm-card-DCx_A4bU.js +1 -0
- package/dist/construct-cli.es.js +1169 -0
- package/dist/{elements/chunks/context-VLIL3sJ-.js → context-BY8V-Nlp.js} +1 -1
- package/dist/controllable-D43BKmtX.js +1 -0
- package/dist/conversation-list-D4lLU_yS.js +1 -0
- package/dist/copy-B6DO4PqB.js +1 -0
- package/dist/core-AYMC6_lb.js +12 -5874
- package/dist/{create-tween-CQED4T0g.js → create-tween-BPzaefTp.js} +1 -1
- package/dist/{create-tween-BFT6c-Y8.js → create-tween-CnMHviKB.js} +1 -1
- package/dist/{create-tween-CJNlzoaO.js → create-tween-D1aiGZZh.js} +1 -1
- package/dist/{elements/chunks/create-tween-c4Z8TDYz.js → create-tween-DUSQUKpr.js} +2 -2
- package/dist/css-M7EaDHN_.js +1 -6
- package/dist/custom-elements.json +1400 -218
- package/dist/default-input-CucQEOqH.js +1 -0
- package/dist/define-CGGX-7Vg.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-CbLtajUQ.js} +1 -1
- package/dist/{elements/chunks/dropdown-BgWTthUx.js → dropdown-BwhViJFd.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 +101 -7
- 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 +362 -24
- package/dist/{elements/chunks/ellipsis-7gU33mL2.js → ellipsis-DFr4Vqr3.js} +1 -1
- package/dist/embed-5s_vU4J0.js +1 -0
- package/dist/engine-javascript-vq0WuIJl.js +14 -2516
- package/dist/{elements/chunks/external-link-CSOEsNlx.js → external-link-u9d85ORQ.js} +1 -1
- package/dist/file-text-CX7_x42o.js +1 -0
- package/dist/{elements/chunks/file-tree-zvB2i7P9.js → file-tree-D3kBjXI5.js} +1 -1
- package/dist/folder-V-YdIL8f.js +1 -0
- package/dist/form-BRNUMCN2.js +1 -0
- package/dist/github-dark-dimmed-DUshB20C.js +1 -4
- package/dist/github-light-JYsPkUQd.js +1 -4
- package/dist/hover-card-DaeiYrTA.js +1 -0
- package/dist/html-CPZ3oZQ7.js +1 -10
- package/dist/icon-BpixdZNq.js +1 -0
- package/dist/{elements/chunks/index-BCRhi84a.js → index-xu_pdcPi.js} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7330 -5852
- package/dist/index.server.js +5823 -4759
- package/dist/info-8mFsIjS3.js +1 -0
- package/dist/input-d1Yuu-hz.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-961zMPFB.js +1 -0
- package/dist/link-DlZZBGaR.js +1 -0
- package/dist/{elements/chunks/link-preview-OQ9IEq0f.js → link-preview-DIIbV2Sd.js} +1 -1
- package/dist/loader-YQszHFaW.js +1 -0
- package/dist/{elements/chunks/markdown-DgBFaGAz.js → markdown-CVk1MPsj.js} +1 -1
- package/dist/mcp.es.js +1285 -79
- package/dist/message-CwKVEdZg.js +1 -0
- package/dist/message-DS8lzHc1.js +1 -0
- package/dist/message-circle-Xf8Q-vZp.js +1 -0
- package/dist/message-square-Cxnwgkns.js +1 -0
- package/dist/{elements/chunks/minimize-2-DPIUKTrT.js → minimize-2-UEZmP2QT.js} +1 -1
- package/dist/{elements/chunks/model-switcher-DsT8tFB0.js → model-switcher-Kk1jEQ5t.js} +1 -1
- package/dist/{elements/chunks/overlay-DuiwdXjm.js → overlay-C1od6LOz.js} +1 -1
- package/dist/panel-right-ryET0yyn.js +1 -0
- package/dist/paperclip-BDNoZFJP.js +1 -0
- package/dist/play-OFIvYXUQ.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/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-BvYX0aoy.js +1 -0
- package/dist/prompt-suggestion-BRFu2lcu.js +1 -0
- package/dist/radio-DcL23cNJ.js +1 -0
- package/dist/react/index.d.ts +193 -19
- package/dist/react.js +216 -180
- package/dist/reasoning-Cackq4Rh.js +1 -0
- package/dist/register-impl-C7rENvPK.js +424 -0
- package/dist/{elements/chunks/resizable-D181b4fM.js → resizable-Cp9HUYih.js} +1 -1
- package/dist/rotate-ccw-0DLRDHH5.js +1 -0
- package/dist/rotate-cw-DOB9IGcU.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-emVmWP4K.js +1 -0
- package/dist/scroll-button-CeP_gv1x.js +1 -0
- package/dist/select-CWmu00tS.js +1 -0
- package/dist/{elements/chunks/separator-CeJHQqLW.js → separator-CE6vly6z.js} +1 -1
- package/dist/{elements/chunks/settings-CqaHgJF9.js → settings-CE-78SvZ.js} +1 -1
- package/dist/{elements/chunks/settings-group-CjqjLCOn.js → settings-group-ZFWNxFQR.js} +1 -1
- package/dist/{elements/chunks/skeleton-D8akBnKS.js → skeleton-BebdP4mf.js} +1 -1
- package/dist/slider-BAKRYUlz.js +1 -0
- package/dist/{solid-BtdqNZI7.js → solid-BE5ui6sy.js} +8727 -7212
- package/dist/{solid-CnavwBye.js → solid-DFhsce3O.js} +7015 -5886
- package/dist/solid.d.ts +10 -0
- package/dist/solid.js +240 -234
- package/dist/solid.server.js +240 -234
- package/dist/source-B0FlguSx.js +1 -0
- package/dist/star-CBMZvLuN.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/{elements/chunks/store-Cjq0qwYN.js → store-7eoadydQ.js} +1 -1
- package/dist/svelte--5p79yCD.js +1 -15
- package/dist/switch-CViARZCy.js +1 -0
- package/dist/tasks-card-MjCcOhR_.js +1 -0
- package/dist/text-shimmer-DKlwRF2G.js +1 -0
- package/dist/textarea-3ay2Me2-.js +1 -0
- package/dist/theme.tokens.css +82 -13
- package/dist/{elements/chunks/thumbs-up-DX2Ijk3H.js → thumbs-up-DQcu2HMO.js} +1 -1
- package/dist/toast-store-C6yKOhbk.js +1 -0
- package/dist/{elements/chunks/tool-DKQ2D1DP.js → tool-BCYNlfKy.js} +1 -1
- package/dist/{elements/chunks/tooltip-B0G99y8w.js → tooltip-05zI4hjs.js} +1 -1
- package/dist/trash-2-BR1RxGky.js +1 -0
- package/dist/{elements/chunks/triangle-alert-F9cyUEyy.js → triangle-alert-DHohDOCy.js} +1 -1
- package/dist/tsx-B8rCNbgL.js +1 -6
- 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 +22 -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-BbGW6A_u.js +1 -0
- package/dist/url-scheme-policy-DHpoTJwB.js +1 -0
- package/dist/use-card-resolution-CJW4grFa.js +1 -0
- package/dist/{variant-aurora-B8II3-I1.js → variant-aurora-BUOVgPOB.js} +2 -2
- package/dist/{variant-aurora-CMNWOSJR.js → variant-aurora-CUsUJvFI.js} +2 -2
- package/dist/{variant-aurora-CcuDMWwQ.js → variant-aurora-CW2i4bfr.js} +1 -1
- package/dist/{elements/chunks/variant-aurora-qt6Zct8M.js → variant-aurora-xiMPty8f.js} +1 -1
- package/dist/{variant-custom-L16JLLZy.js → variant-custom-BQtOnmeO.js} +1 -1
- package/dist/{variant-custom-C714mqKl.js → variant-custom-CAm9L-E5.js} +2 -2
- package/dist/{variant-custom-BdvYC7af.js → variant-custom-CAnzzppW.js} +2 -2
- package/dist/{elements/chunks/variant-custom-tJp22_BQ.js → variant-custom-D91HjAKz.js} +1 -1
- package/dist/{variant-wave-ecwykeyL.js → variant-wave-Ca1Ls4_y.js} +2 -2
- package/dist/{variant-wave-D7ruiA1W.js → variant-wave-CxX39DKd.js} +2 -2
- package/dist/{elements/chunks/variant-wave-CaQ5ti39.js → variant-wave-DYyzIIZv.js} +1 -1
- package/dist/{variant-wave-2S4La2Ka.js → variant-wave-uY5crU_K.js} +1 -1
- package/dist/vue-BmIZj4XD.js +1 -33
- package/dist/x-C5m1JFgi.js +1 -0
- package/frameworks/react/index.tsx +198 -20
- package/llms-full.txt +1178 -21
- package/llms.txt +6 -3
- package/package.json +17 -4
- package/src/agent-tooling/catalog/invariants.ts +1 -1
- 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 +131 -0
- package/src/agent-tooling/construct/codegen.ts +1353 -0
- package/src/agent-tooling/construct/construct.v1.schema.json +250 -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 +23 -0
- package/src/agent-tooling/construct/schema.ts +371 -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 +72 -9
- 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 +33 -9
- package/src/components/conversation-list.tsx +25 -10
- 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/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/elements/attachments.tsx +3 -1
- package/src/elements/chat-workspace.tsx +1 -1
- package/src/elements/chat.tsx +22 -4
- 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 +736 -46
- package/src/elements/element-nonscalar.json +15 -0
- package/src/elements/element-types.d.ts +362 -24
- 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 +2 -1
- 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/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 +10 -0
- package/src/state/index.ts +1 -1
- package/src/state/mock.ts +92 -6
- 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 +145 -6
- 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 +84 -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/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/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
|
@@ -3,6 +3,7 @@ import { cn } from '../utils/cn';
|
|
|
3
3
|
import { ChevronDown } from 'lucide-solid';
|
|
4
4
|
import { Markdown } from './markdown';
|
|
5
5
|
import { observeContentHeight } from '../primitives/use-resize-observer';
|
|
6
|
+
import { TextShimmer } from './text-shimmer';
|
|
6
7
|
|
|
7
8
|
interface ReasoningContextValue {
|
|
8
9
|
isOpen: () => boolean;
|
|
@@ -18,6 +19,11 @@ interface ReasoningContextValue {
|
|
|
18
19
|
/** The registered trigger. Deliberately a plain getter over a mutable
|
|
19
20
|
* variable, NOT a signal — registration must not re-run the content effect. */
|
|
20
21
|
trigger: () => HTMLElement | undefined;
|
|
22
|
+
/** Whether the reasoning is currently streaming — read by `ReasoningTrigger`
|
|
23
|
+
* to decide how its own label renders (shimmer while streaming, plain
|
|
24
|
+
* neutral text once settled). Kit-decides-HOW: every consumer gets the same
|
|
25
|
+
* "Thinking…" shimmer behavior for free, with no prop of their own. */
|
|
26
|
+
isStreaming: () => boolean;
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
/** Imperative open controller, handed to a parent (the kai-reasoning facade) via
|
|
@@ -49,10 +55,16 @@ export interface ReasoningProps {
|
|
|
49
55
|
disabled?: boolean;
|
|
50
56
|
/** Receive the open controller (open accessor + setOpen) once mounted. */
|
|
51
57
|
controllerRef?: (api: ReasoningController) => void;
|
|
58
|
+
/** Keep auto-opening while streaming and auto-closing when it settles (the
|
|
59
|
+
* pre-Task-19f `full` behavior). Default false: the panel starts per
|
|
60
|
+
* `defaultOpen` and stays exactly where the user leaves it — streaming only
|
|
61
|
+
* changes the trigger's label (shimmer), never the open state, matching the
|
|
62
|
+
* "closed chip, expand on click" default (owner ruling, 2026-08-26). */
|
|
63
|
+
openOnStream?: boolean;
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
function Reasoning(props: ReasoningProps) {
|
|
55
|
-
const [local] = splitProps(props, ['children', 'class', 'open', 'defaultOpen', 'onOpenChange', 'isStreaming', 'disabled', 'controllerRef']);
|
|
67
|
+
const [local] = splitProps(props, ['children', 'class', 'open', 'defaultOpen', 'onOpenChange', 'isStreaming', 'disabled', 'controllerRef', 'openOnStream']);
|
|
56
68
|
const [internalOpen, setInternalOpen] = createSignal(local.defaultOpen ?? false);
|
|
57
69
|
const [wasAutoOpened, setWasAutoOpened] = createSignal(false);
|
|
58
70
|
|
|
@@ -72,6 +84,7 @@ function Reasoning(props: ReasoningProps) {
|
|
|
72
84
|
};
|
|
73
85
|
|
|
74
86
|
createEffect(() => {
|
|
87
|
+
if (!local.openOnStream) return;
|
|
75
88
|
const streaming = local.isStreaming;
|
|
76
89
|
if (streaming && !wasAutoOpened()) {
|
|
77
90
|
if (!isControlled()) setInternalOpen(true);
|
|
@@ -104,6 +117,7 @@ function Reasoning(props: ReasoningProps) {
|
|
|
104
117
|
contentId,
|
|
105
118
|
registerTrigger: (el) => { triggerEl = el; },
|
|
106
119
|
trigger: () => triggerEl,
|
|
120
|
+
isStreaming: () => !!local.isStreaming,
|
|
107
121
|
}}
|
|
108
122
|
>
|
|
109
123
|
<div class={local.class}>{local.children}</div>
|
|
@@ -122,7 +136,7 @@ function ReasoningTrigger(props: ReasoningTriggerProps) {
|
|
|
122
136
|
// to register as the panel's focus-return target, and a spread `ref` would
|
|
123
137
|
// silently replace it. The consumer's ref is forwarded below instead.
|
|
124
138
|
const [local, rest] = splitProps(props, ['children', 'class', 'ref']);
|
|
125
|
-
const { isOpen, onOpenChange, disabled, contentId, registerTrigger } = useReasoningContext();
|
|
139
|
+
const { isOpen, onOpenChange, disabled, contentId, registerTrigger, isStreaming } = useReasoningContext();
|
|
126
140
|
|
|
127
141
|
return (
|
|
128
142
|
// The same disclosure contract as CollapsibleTrigger: an explicit
|
|
@@ -149,7 +163,20 @@ function ReasoningTrigger(props: ReasoningTriggerProps) {
|
|
|
149
163
|
onClick={() => { if (!disabled()) onOpenChange(!isOpen()); }}
|
|
150
164
|
{...rest}
|
|
151
165
|
>
|
|
152
|
-
|
|
166
|
+
{/* Content/chrome, not a control: was `text-primary`, the BRAND token, so
|
|
167
|
+
a consumer's branded --kai-color-primary bled onto the "Thinking"
|
|
168
|
+
label. `text-foreground` matches the sibling `<Tool>` disclosure
|
|
169
|
+
trigger's label (rendered via `Button variant="ghost"`, itself
|
|
170
|
+
`text-foreground`) — the established neutral for a disclosure
|
|
171
|
+
trigger's own label text in this codebase.
|
|
172
|
+
Kit-decides-HOW: while streaming, the label renders with the kit's
|
|
173
|
+
own `TextShimmer` (the common "Thinking…" shimmer, already used by
|
|
174
|
+
`Loader`'s `text-shimmer` variant) instead of static text; once
|
|
175
|
+
settled it's the plain neutral span above. Every consumer gets this
|
|
176
|
+
for free — no prop of their own. */}
|
|
177
|
+
<Show when={isStreaming()} fallback={<span class="text-foreground">{local.children}</span>}>
|
|
178
|
+
<TextShimmer class="font-medium">{local.children}</TextShimmer>
|
|
179
|
+
</Show>
|
|
153
180
|
<div
|
|
154
181
|
class={cn(
|
|
155
182
|
'transform transition-transform',
|
|
@@ -365,7 +365,7 @@ function CompareColumn(props: ColumnProps): JSX.Element {
|
|
|
365
365
|
return (
|
|
366
366
|
<div
|
|
367
367
|
class={cn(
|
|
368
|
-
'flex min-w-0 flex-col gap-3 rounded-lg border border-
|
|
368
|
+
'flex min-w-0 flex-col gap-3 rounded-lg border border-border bg-background/40 p-3',
|
|
369
369
|
props.hiddenClass?.(),
|
|
370
370
|
)}
|
|
371
371
|
>
|
|
@@ -432,7 +432,7 @@ function CollapsedWinner(props: {
|
|
|
432
432
|
}): JSX.Element {
|
|
433
433
|
return (
|
|
434
434
|
<div
|
|
435
|
-
class="flex flex-col gap-2 rounded-lg border border-
|
|
435
|
+
class="flex flex-col gap-2 rounded-lg border border-border bg-accent/40 p-3"
|
|
436
436
|
role={props.optimistic ? 'status' : undefined}
|
|
437
437
|
>
|
|
438
438
|
<div class="flex items-center gap-2 text-sm font-medium text-accent-foreground">
|
|
@@ -1,22 +1,62 @@
|
|
|
1
|
+
import { Show } from 'solid-js';
|
|
1
2
|
import { cn } from '../utils/cn';
|
|
2
3
|
import { Button } from '../ui/button';
|
|
3
4
|
import { useChatContainer } from './chat-container';
|
|
4
|
-
import {
|
|
5
|
+
import { ArrowDown } from 'lucide-solid';
|
|
6
|
+
|
|
7
|
+
/** The accessible name used when the consumer does not supply one. */
|
|
8
|
+
const DEFAULT_LABEL = 'Scroll to bottom';
|
|
5
9
|
|
|
6
10
|
export interface ScrollButtonProps {
|
|
7
11
|
class?: string;
|
|
8
12
|
variant?: 'outline' | 'ghost' | 'default';
|
|
9
13
|
size?: 'sm' | 'md' | 'lg' | 'icon' | 'icon-sm';
|
|
14
|
+
/**
|
|
15
|
+
* The button's accessible name. Used whether or not the label is visible, so
|
|
16
|
+
* the announced text is always localisable. Defaults to `"Scroll to bottom"`.
|
|
17
|
+
*/
|
|
18
|
+
label?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Also render `label` visibly beside the icon. Defaults to `false` (icon
|
|
21
|
+
* only). When it is visible the text IS the accessible name, so nothing is
|
|
22
|
+
* announced twice.
|
|
23
|
+
*/
|
|
24
|
+
showLabel?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The floating chip surface.
|
|
29
|
+
*
|
|
30
|
+
* The shared `outline` button variant is `bg-muted/50` — half-transparent, so
|
|
31
|
+
* message text showed through a control that floats over scrolling content, and
|
|
32
|
+
* its edge measured 1.05:1 against the thread behind it (SC 1.4.11 wants 3:1).
|
|
33
|
+
* `bg-card` is the same opaque surface popovers, dropdowns and hover cards sit
|
|
34
|
+
* on; `border-input` is the kit's control edge and clears 3:1 in both themes;
|
|
35
|
+
* `kai-elevation` is the shared, themeable float shadow (`--kai-shadow-color`),
|
|
36
|
+
* which is what keeps an opaque button reading as ABOVE the content.
|
|
37
|
+
*
|
|
38
|
+
* `ghost` and `default` are explicit consumer choices about the fill, so they
|
|
39
|
+
* keep theirs; every variant gets the elevation and the rounded-square radius.
|
|
40
|
+
*/
|
|
41
|
+
function surfaceClasses(variant: ScrollButtonProps['variant']) {
|
|
42
|
+
return (variant ?? 'outline') === 'outline'
|
|
43
|
+
? 'border border-input bg-card text-card-foreground kai-elevation'
|
|
44
|
+
: 'kai-elevation';
|
|
10
45
|
}
|
|
11
46
|
|
|
12
47
|
function ScrollButton(props: ScrollButtonProps) {
|
|
13
48
|
const { isAtBottom, scrollToBottom } = useChatContainer();
|
|
49
|
+
const label = () => props.label ?? DEFAULT_LABEL;
|
|
50
|
+
const showLabel = () => props.showLabel === true;
|
|
14
51
|
|
|
15
52
|
return (
|
|
16
53
|
<Button
|
|
17
54
|
variant={props.variant ?? 'outline'}
|
|
18
55
|
size={props.size ?? 'sm'}
|
|
19
|
-
aria-label
|
|
56
|
+
// When the label is visible it IS the accessible name. An aria-label on
|
|
57
|
+
// top of it would override the visible text and leave the two able to
|
|
58
|
+
// disagree, so it is only set for the icon-only case.
|
|
59
|
+
aria-label={showLabel() ? undefined : label()}
|
|
20
60
|
// At the bottom of the thread this button is fully transparent and
|
|
21
61
|
// pointer-inert, but it stayed in the tab order — a keyboard user landed
|
|
22
62
|
// on a control they could not see, with a focus ring painted on nothing.
|
|
@@ -25,7 +65,10 @@ function ScrollButton(props: ScrollButtonProps) {
|
|
|
25
65
|
tabindex={isAtBottom() ? -1 : 0}
|
|
26
66
|
aria-hidden={isAtBottom() ? 'true' : undefined}
|
|
27
67
|
class={cn(
|
|
28
|
-
'
|
|
68
|
+
'rounded-lg transition-all duration-150 ease-out',
|
|
69
|
+
surfaceClasses(props.variant),
|
|
70
|
+
// Square while icon-only; a pill-ish labelled button once the text is in.
|
|
71
|
+
showLabel() ? 'h-10 w-auto gap-1.5 px-3.5 text-sm' : 'h-10 w-10 px-0',
|
|
29
72
|
!isAtBottom()
|
|
30
73
|
? 'translate-y-0 scale-100 opacity-100'
|
|
31
74
|
: 'pointer-events-none translate-y-4 scale-95 opacity-0',
|
|
@@ -33,7 +76,16 @@ function ScrollButton(props: ScrollButtonProps) {
|
|
|
33
76
|
)}
|
|
34
77
|
onClick={() => scrollToBottom()}
|
|
35
78
|
>
|
|
36
|
-
|
|
79
|
+
{/* h-4, not the h-5 the chevron used. A ChevronDown only inks the lower
|
|
80
|
+
part of its 24px viewBox, so at a 20px box its visible mass is small;
|
|
81
|
+
ArrowDown inks the full height (stem + head), and at 20px inside a 40px
|
|
82
|
+
button it read as half the button wide and crowded the padding. 16px
|
|
83
|
+
balances the icon-only square and is the size lucide pairs with
|
|
84
|
+
text-sm, which is what the label renders at. */}
|
|
85
|
+
<ArrowDown class="h-4 w-4 shrink-0" aria-hidden="true" />
|
|
86
|
+
<Show when={showLabel()}>
|
|
87
|
+
<span>{label()}</span>
|
|
88
|
+
</Show>
|
|
37
89
|
</Button>
|
|
38
90
|
);
|
|
39
91
|
}
|
|
@@ -152,7 +152,12 @@ function SourceContent(props: SourceContentProps) {
|
|
|
152
152
|
width={16}
|
|
153
153
|
height={16}
|
|
154
154
|
/>
|
|
155
|
-
|
|
155
|
+
{/* Citation title/domain is CONTENT, not a control — was the BRAND
|
|
156
|
+
token. `text-foreground/80` matches how `SourceTrigger` above
|
|
157
|
+
already renders this same domain text (inherited from its `<a
|
|
158
|
+
class="... text-foreground/80 ...">`), so the hover-card header
|
|
159
|
+
and the trigger chip agree on the same domain's color. */}
|
|
160
|
+
<div class="text-foreground/80 truncate text-sm">
|
|
156
161
|
{ctx.domain.replace('www.', '')}
|
|
157
162
|
</div>
|
|
158
163
|
</div>
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from 'solid-js';
|
|
15
15
|
import { cn } from '../utils/cn';
|
|
16
16
|
import { Button } from '../ui/button';
|
|
17
|
+
import { Checkbox } from '../ui/checkbox';
|
|
17
18
|
import { ProgressBar } from '../ui/progress-bar';
|
|
18
19
|
import { Card } from './card';
|
|
19
20
|
import { DismissedStub } from './dismissed-stub';
|
|
@@ -21,7 +22,7 @@ import type { CardEnvelope, CardEvent, CardHost, CardResolution } from '../primi
|
|
|
21
22
|
import { useCardResolution } from './use-card-resolution';
|
|
22
23
|
import { emitCardEvent } from '../primitives/card-routing';
|
|
23
24
|
import { useCardHost } from '../primitives/card-host';
|
|
24
|
-
import { Check, Circle, CircleCheck
|
|
25
|
+
import { Check, Circle, CircleCheck } from 'lucide-solid';
|
|
25
26
|
|
|
26
27
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
27
28
|
// Types (tasks.schema.json) — AUTHORED IN ../primitives/card-data-types.ts.
|
|
@@ -415,14 +416,23 @@ export function TasksCard(props: TasksCardProps): JSX.Element {
|
|
|
415
416
|
progress() || res.isResolved() || readOnly() ? undefined : (
|
|
416
417
|
<div class="flex w-full flex-wrap items-center justify-between gap-2">
|
|
417
418
|
<Show when={local.data?.dismissible === true}>
|
|
419
|
+
{/* The contract `dismiss` verb — a footer ACTION (it emits
|
|
420
|
+
`{kind:'dismiss'}` and collapses the card to a re-openable
|
|
421
|
+
stub), not the chrome close in `Card`'s own `dismissible`
|
|
422
|
+
prop, which the contract cards deliberately never set.
|
|
423
|
+
Labelled rather than a bare ghost ✕: every other control in
|
|
424
|
+
this row says what it does, and an unlabelled 28px glyph
|
|
425
|
+
300px from the primary button reads as stray chrome. Same
|
|
426
|
+
shape in all four cards — `form` already looked like this.
|
|
427
|
+
`aria-label` is kept (redundant with the text) so the
|
|
428
|
+
element tests that select on it keep working. */}
|
|
418
429
|
<Button
|
|
419
430
|
type="button"
|
|
420
431
|
variant="ghost"
|
|
421
|
-
size="icon-sm"
|
|
422
432
|
aria-label="Dismiss"
|
|
423
433
|
onClick={onDismiss}
|
|
424
434
|
>
|
|
425
|
-
|
|
435
|
+
Dismiss
|
|
426
436
|
</Button>
|
|
427
437
|
</Show>
|
|
428
438
|
<span id={countId} aria-live="polite" class="text-xs text-muted-foreground">
|
|
@@ -485,7 +495,7 @@ export function TasksCard(props: TasksCardProps): JSX.Element {
|
|
|
485
495
|
if (confirmEnabled()) onConfirm();
|
|
486
496
|
}}
|
|
487
497
|
>
|
|
488
|
-
<div class="divide-y divide-border overflow-hidden rounded-lg border border-
|
|
498
|
+
<div class="divide-y divide-border overflow-hidden rounded-lg border border-border">
|
|
489
499
|
<Show when={showMaster()}>
|
|
490
500
|
{(() => {
|
|
491
501
|
const indeterminate = () => masterState() === 'indeterminate';
|
|
@@ -501,17 +511,20 @@ export function TasksCard(props: TasksCardProps): JSX.Element {
|
|
|
501
511
|
: 'text-foreground hover:bg-muted/50',
|
|
502
512
|
)}
|
|
503
513
|
>
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
514
|
+
{/* SQUARE `Checkbox` (the `.kai-checkbox` look), and the checklist below draws a
|
|
515
|
+
ROUND lucide Circle/CircleCheck instead. Deliberate, not drift: this
|
|
516
|
+
is `select` mode — a pick-list whose rows are a pending selection that
|
|
517
|
+
only commits when the confirm button fires, which is what a checkbox
|
|
518
|
+
means everywhere else. `progress` mode has no confirm and toggling a
|
|
519
|
+
row IS the action, so it uses the done/not-done affordance of a todo
|
|
520
|
+
list. See the D-2 row in
|
|
521
|
+
docs/superpowers/plans/2026-08-25-form-control-primitives.md; owner has
|
|
522
|
+
not ruled, so do not converge these on your own. */}
|
|
523
|
+
<Checkbox
|
|
507
524
|
checked={masterState() === 'checked'}
|
|
508
525
|
disabled={groupDisabled() || readOnly()}
|
|
526
|
+
indeterminate={indeterminate()}
|
|
509
527
|
aria-checked={indeterminate() ? 'mixed' : masterState() === 'checked'}
|
|
510
|
-
ref={(el) => {
|
|
511
|
-
createEffect(() => {
|
|
512
|
-
el.indeterminate = indeterminate();
|
|
513
|
-
});
|
|
514
|
-
}}
|
|
515
528
|
onChange={(e) => toggleAll(e.currentTarget.checked)}
|
|
516
529
|
/>
|
|
517
530
|
<span>Select all</span>
|
|
@@ -541,9 +554,8 @@ export function TasksCard(props: TasksCardProps): JSX.Element {
|
|
|
541
554
|
)}
|
|
542
555
|
data-task-id={task.id}
|
|
543
556
|
>
|
|
544
|
-
<
|
|
545
|
-
|
|
546
|
-
class="kai-checkbox mt-0.5"
|
|
557
|
+
<Checkbox
|
|
558
|
+
class="mt-0.5"
|
|
547
559
|
checked={checked()}
|
|
548
560
|
disabled={blocked() || readOnly()}
|
|
549
561
|
aria-disabled={blocked() ? 'true' : undefined}
|
|
@@ -603,7 +615,10 @@ function ProgressChecklist(props: {
|
|
|
603
615
|
<div class={cn('flex flex-col gap-3', props.groupClass)}>
|
|
604
616
|
<Show when={props.heading}>
|
|
605
617
|
<div class="flex items-center justify-between gap-3">
|
|
606
|
-
<span
|
|
618
|
+
<span
|
|
619
|
+
id={props.headingId}
|
|
620
|
+
class="text-title font-semibold tracking-tight text-foreground"
|
|
621
|
+
>
|
|
607
622
|
{props.heading}
|
|
608
623
|
</span>
|
|
609
624
|
<span
|
|
@@ -646,8 +661,23 @@ function ProgressChecklist(props: {
|
|
|
646
661
|
// row doesn't leave a noisy persistent outline — and it makes a
|
|
647
662
|
// Tab-focused completed row's open description perceivable. Dropped
|
|
648
663
|
// entirely when readonly (the row isn't focusable then).
|
|
664
|
+
//
|
|
665
|
+
// TWO tab stops exist per row and the ring has to cover both.
|
|
666
|
+
// `focus-visible:` matches only when the LABEL itself is focused,
|
|
667
|
+
// which is completed rows only (the `tabindex` below). Every row's
|
|
668
|
+
// other — and for an incomplete row, only — tab stop is the sr-only
|
|
669
|
+
// checkbox inside, so without `has-[:focus-visible]:` tabbing to an
|
|
670
|
+
// unchecked row put focus on an off-screen input with no indicator
|
|
671
|
+
// anywhere on screen. Both halves stay on the focus-VISIBLE axis on
|
|
672
|
+
// purpose: `focus-within:` would also fire for a mouse click (which
|
|
673
|
+
// forwards focus from the label to the checkbox), which is exactly
|
|
674
|
+
// the persistent-outline noise the paragraph above rejects. The
|
|
675
|
+
// description reveal below uses `group-focus-within:` because a
|
|
676
|
+
// hover-or-focus reveal wants the looser condition.
|
|
649
677
|
!props.readonly &&
|
|
650
678
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring',
|
|
679
|
+
!props.readonly &&
|
|
680
|
+
'has-[:focus-visible]:outline-none has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-inset has-[:focus-visible]:ring-ring',
|
|
651
681
|
props.readonly
|
|
652
682
|
? 'cursor-default'
|
|
653
683
|
: blocked()
|
|
@@ -680,6 +710,18 @@ function ProgressChecklist(props: {
|
|
|
680
710
|
)}
|
|
681
711
|
aria-hidden="true"
|
|
682
712
|
>
|
|
713
|
+
{/* ROUND, where `select` mode uses the square `Checkbox`. Deliberate:
|
|
714
|
+
this mode has no confirm button, so ticking a row IS the action and the
|
|
715
|
+
row is done-or-not rather than selected-or-not — the todo-list
|
|
716
|
+
affordance, which is how this mode has been described since it landed
|
|
717
|
+
(see the `mode` argType in tasks-card.stories.tsx and the JSDoc on
|
|
718
|
+
src/elements/tasks.tsx). D-2 in
|
|
719
|
+
docs/superpowers/plans/2026-08-25-form-control-primitives.md tracks
|
|
720
|
+
whether to keep the split; unruled, so leave both. NOTE the cost: the
|
|
721
|
+
icon replaces the visible native control, which is why the real input
|
|
722
|
+
above is `sr-only` and why the row's focus ring has to be driven by
|
|
723
|
+
`has-[:focus-visible]:`. Converging on `Checkbox` would take that
|
|
724
|
+
hazard away with it. */}
|
|
683
725
|
<Show
|
|
684
726
|
when={checked()}
|
|
685
727
|
fallback={<Circle size={18} />}
|
|
@@ -34,6 +34,11 @@ export interface ThreadProps {
|
|
|
34
34
|
* the kit checks its own seven built-ins and leaves your own card type
|
|
35
35
|
* unvalidated. A schema here WINS over a built-in of the same name. */
|
|
36
36
|
cardSchemas?: CardSchemaMap;
|
|
37
|
+
/** The custom-element host node to emit card events off when no `CardProvider`
|
|
38
|
+
* is present, forwarded through `MessageBody` to `CardRenderer`. The
|
|
39
|
+
* element facades pass their own host element so card events leave as the
|
|
40
|
+
* bubbling `kai-card` CustomEvent. */
|
|
41
|
+
cardHostElement?: HTMLElement;
|
|
37
42
|
/** Show a typing indicator on the pending assistant turn — use while awaiting
|
|
38
43
|
* the assistant's reply. */
|
|
39
44
|
loading?: boolean;
|
|
@@ -146,6 +151,7 @@ export function Thread(props: ThreadProps) {
|
|
|
146
151
|
parts={m().parts}
|
|
147
152
|
cardTypes={props.cardTypes}
|
|
148
153
|
cardSchemas={props.cardSchemas}
|
|
154
|
+
cardHostElement={props.cardHostElement}
|
|
149
155
|
isUser={m().role === 'user'}
|
|
150
156
|
markdown={m().role === 'assistant'}
|
|
151
157
|
actions={m().actions}
|
|
@@ -209,7 +215,10 @@ export function Thread(props: ThreadProps) {
|
|
|
209
215
|
</ChatContainerContent>
|
|
210
216
|
<Show when={showScrollButton()}>
|
|
211
217
|
<div class="absolute bottom-4 left-1/2 flex w-full max-w-3xl -translate-x-1/2 justify-center px-5">
|
|
212
|
-
|
|
218
|
+
{/* The button now owns its elevation (kai-elevation); a `shadow-sm`
|
|
219
|
+
here would set box-shadow a second time and the winner would
|
|
220
|
+
be stylesheet order, not this call site. */}
|
|
221
|
+
<ScrollButton />
|
|
213
222
|
</div>
|
|
214
223
|
</Show>
|
|
215
224
|
</ChatContainer>
|
package/src/components/toast.tsx
CHANGED
|
@@ -320,7 +320,7 @@ function anchorStyle(position: ToastPosition, r: TargetRect): Record<string, str
|
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
-
/** The overlay layer both region roots sit on
|
|
323
|
+
/** The overlay layer both region roots sit on. One token, one default:
|
|
324
324
|
* your app chrome must stay below the toast layer; set `--kai-toast-z`
|
|
325
325
|
* (default 100) on the host to move the layer. */
|
|
326
326
|
const TOAST_Z = 'var(--kai-toast-z, 100)';
|
|
@@ -25,6 +25,15 @@ export interface ToolPart {
|
|
|
25
25
|
type: string;
|
|
26
26
|
/** Semantic classification for rendering. Derive with classifyTool(type). */
|
|
27
27
|
kind?: ToolKind;
|
|
28
|
+
/** The call's lifecycle. A provider stream (real or `createMockResponder`)
|
|
29
|
+
* only ever ANNOUNCES a call: arguments stream in (`input-streaming`), then
|
|
30
|
+
* the part parks at `input-available` — and stays there. The kit parses and
|
|
31
|
+
* renders the call; EXECUTING it and answering is the host's side of the
|
|
32
|
+
* seam: after the read settles, run the tool and patch the part forward with
|
|
33
|
+
* `stream.upsertTool(id, { state: 'output-available', output })` (or
|
|
34
|
+
* `upsertToolPart`), or `output-error` + `errorText` on failure. The one
|
|
35
|
+
* exception is a call the provider ran itself (`raw` carries the result and
|
|
36
|
+
* the wire sets `output` directly) — never re-execute those. */
|
|
28
37
|
state: 'input-streaming' | 'input-available' | 'output-available' | 'output-error';
|
|
29
38
|
/** Last VALID parsed snapshot, fingerprint-deduped. The primary channel: this is
|
|
30
39
|
* what the kit renders. */
|
|
@@ -19,7 +19,9 @@ import {
|
|
|
19
19
|
interface Props extends Record<string, unknown> {
|
|
20
20
|
/** The attachments to render. Omit (or pass an empty array) for the empty
|
|
21
21
|
* state, which shows `emptyText` if set and nothing otherwise. Set as a JS
|
|
22
|
-
* property (array).
|
|
22
|
+
* property (array). Each item's `url` must be a `data:` URI or an https
|
|
23
|
+
* URL, never `URL.createObjectURL`: a `blob:` URL previews here but the
|
|
24
|
+
* wire encoders (`toOpenAIMessages`/`toAnthropicMessages`) refuse it. */
|
|
23
25
|
items?: AttachmentData[];
|
|
24
26
|
/** Layout: `grid` = visual tiles, `inline` = icon + label chips, `list` = rows. */
|
|
25
27
|
variant?: AttachmentVariant;
|
|
@@ -75,7 +75,7 @@ interface Events {
|
|
|
75
75
|
* (480px). Read once at upgrade. Parts: `header` · `start` · `main` · `end` ·
|
|
76
76
|
* `footer` (the asides also match `::part(aside)`).
|
|
77
77
|
*
|
|
78
|
-
* **BREAKING (
|
|
78
|
+
* **BREAKING (0.24):** this element was a chat
|
|
79
79
|
* preset; it is now a layout shell, and everything chat-shaped is gone from its
|
|
80
80
|
* surface. Where each removed prop went:
|
|
81
81
|
*
|
package/src/elements/chat.tsx
CHANGED
|
@@ -14,8 +14,20 @@ import type { ModelOption } from '../types';
|
|
|
14
14
|
|
|
15
15
|
type Props = Omit<ChatThreadProps,
|
|
16
16
|
'class' | 'onValueChange' | 'onSubmit' | 'onAttachmentsChange' | 'onSuggestionClick' | 'onModelChange'
|
|
17
|
-
| 'onMessageAction' | 'onWebSearch' | 'onVoice' | 'controllerRef' | 'cardTypes' | 'cardSchemas' | 'messages'
|
|
18
|
-
| 'accept' | 'onAttachmentsRejected'
|
|
17
|
+
| 'onMessageAction' | 'onWebSearch' | 'onVoice' | 'controllerRef' | 'cardTypes' | 'cardSchemas' | 'cardHostElement' | 'messages'
|
|
18
|
+
| 'accept' | 'onAttachmentsRejected'
|
|
19
|
+
// `headerEndContent`/`emptyContent` are JSX.Element escape hatches for a caller
|
|
20
|
+
// composing `ChatThread` directly as a Solid component (see their doc comments in
|
|
21
|
+
// chat-thread.tsx — the construct-engine's emitted App is the motivating case).
|
|
22
|
+
// `<kai-chat>` is the OPPOSITE shape: a custom element crossing the shadow-DOM
|
|
23
|
+
// boundary, where a `JSX.Element` value cannot exist for a consumer to construct
|
|
24
|
+
// (React/Vue/plain HTML have no such type) and the facade already has its own
|
|
25
|
+
// working mechanism for both regions — `slot="header-end"` and `slot="empty"`.
|
|
26
|
+
// Omitted here rather than left to flow through `Omit`'s default pass-through:
|
|
27
|
+
// without this, `gen-element-api.mjs` picked them up and put a JSX.Element type
|
|
28
|
+
// (which it stringifies as Solid's internal array-like union — meaningless to a
|
|
29
|
+
// web-component consumer) into `<kai-chat>`'s public prop surface and docs.
|
|
30
|
+
| 'headerEndContent' | 'emptyContent'> & Record<string, unknown> & {
|
|
19
31
|
/** Which attachment media types the user may stage, in HTML `accept` syntax:
|
|
20
32
|
* `<kai-chat accept="image/*,application/pdf">`. A plain string, so unlike
|
|
21
33
|
* `messages` it DOES work as an attribute. Omitted means no filter.
|
|
@@ -97,8 +109,9 @@ defineWebComponent<Props, Events>('kai-chat', {
|
|
|
97
109
|
suggestions: undefined, suggestionMode: 'submit', persistSuggestions: false, proseSize: 'sm',
|
|
98
110
|
codeTheme: 'github-dark-dimmed', codeHighlight: true, chatTitle: undefined,
|
|
99
111
|
models: undefined, currentModel: undefined, context: undefined, scrollButton: true,
|
|
100
|
-
webSearch: false, voice: false, triggers: undefined, kindIcons: undefined,
|
|
112
|
+
attach: true, webSearch: false, voice: false, triggers: undefined, kindIcons: undefined,
|
|
101
113
|
actionsReveal: 'always', cardTypes: undefined, cardSchemas: undefined, accept: undefined,
|
|
114
|
+
reasoning: undefined, reasoningOpen: undefined,
|
|
102
115
|
}, (props, { dispatch, flag, reflectFlag, element, expose }) => {
|
|
103
116
|
// `messages` is an untyped boundary: a consumer can hand it anything at
|
|
104
117
|
// runtime (a pre-0.20.0 `{ id, role, content }` array, in particular). Skip
|
|
@@ -164,12 +177,17 @@ defineWebComponent<Props, Events>('kai-chat', {
|
|
|
164
177
|
codeTheme={props.codeTheme as string} codeHighlight={flag('codeHighlight')}
|
|
165
178
|
chatTitle={props.chatTitle as string | undefined} models={props.models as ModelOption[] | undefined}
|
|
166
179
|
currentModel={props.currentModel as string | undefined} context={props.context as ChatThreadContextUsage | undefined}
|
|
167
|
-
scrollButton={props.scrollButton !== false} webSearch={flag('webSearch')} voice={flag('voice')}
|
|
180
|
+
scrollButton={props.scrollButton !== false} attach={flag('attach')} webSearch={flag('webSearch')} voice={flag('voice')}
|
|
181
|
+
reasoning={props.reasoning as 'full' | 'compact' | 'off' | undefined}
|
|
182
|
+
reasoningOpen={flag('reasoningOpen')}
|
|
168
183
|
triggers={props.triggers as TriggerDef[] | undefined}
|
|
169
184
|
kindIcons={props.kindIcons as Record<string, string> | undefined}
|
|
170
185
|
actionsReveal={props.actionsReveal as 'always' | 'hover'}
|
|
171
186
|
cardTypes={cardComponentsFromTags(props.cardTypes as Record<string, string> | undefined, (props as { theme?: string }).theme)}
|
|
172
187
|
cardSchemas={props.cardSchemas as Record<string, object> | undefined}
|
|
188
|
+
/* F-26: card parts emit off THIS element as the bubbling `kai-card` event,
|
|
189
|
+
so `listenForCardEvents(el)` / addEventListener('kai-card') work. */
|
|
190
|
+
cardHostElement={element}
|
|
173
191
|
onValueChange={(value) => dispatch('kai-value-change', { value })}
|
|
174
192
|
onSubmit={(detail) => dispatch('kai-submit', detail)}
|
|
175
193
|
accept={props.accept as string | undefined}
|