@kitn.ai/ui 0.27.0 → 0.29.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 +10 -2
- package/dist/{Icon-BnFKqqtY.js → Icon-DObhsRtm.js} +1 -1
- package/dist/{action-icons-CBskfBMz.js → action-icons-CcgNN2oT.js} +1 -1
- package/dist/agent-tooling/construct/public.d.ts +15 -0
- package/dist/agent-tooling/construct/schema.d.ts +111 -0
- package/dist/arrow-down-CjRU3JgV.js +1 -0
- package/dist/arrow-left-Bnpb1UEW.js +1 -0
- package/dist/{artifact-CvXEm1lS.js → artifact-Bwt7OgcR.js} +1 -1
- package/dist/{attachments-C43ZegEq.js → attachments-Qr4kg-2b.js} +1 -1
- package/dist/{audio-visualizer-B-79y1Tj.js → audio-visualizer-DToYdfSc.js} +1 -1
- package/dist/{badge-BpUbq8c0.js → badge-CdEu_jn2.js} +1 -1
- package/dist/{bell-sn17Ip9v.js → bell-DQAAOpDz.js} +1 -1
- package/dist/{button-BH6rN0U-.js → button-DkuOnGLy.js} +1 -1
- package/dist/{card-renderer-Cb1gQmth.js → card-renderer-Jx70m6_l.js} +1 -1
- package/dist/{card-routing-DifQgS7n.js → card-routing-0YidER_3.js} +1 -1
- package/dist/check-njkVdZu2.js +1 -0
- package/dist/{checkbox-Dc9Yov_B.js → checkbox-D7iRB3nL.js} +1 -1
- package/dist/{checkbox-group-B1kDLLYk.js → checkbox-group-B2_rpoPM.js} +1 -1
- package/dist/chevron-down-B72s6PXR.js +1 -0
- package/dist/chevron-right-BatuHzUm.js +1 -0
- package/dist/{choice-card-BT3c1S8g.js → choice-card-m0BYqqOK.js} +1 -1
- package/dist/circle-check-B62pODB3.js +1 -0
- package/dist/{circle-x-wobWkoSx.js → circle-x-BPG0iPst.js} +1 -1
- package/dist/circle-zx0ByzY9.js +1 -0
- package/dist/code-block-ClMLKb7C.js +1 -0
- package/dist/{collapsible-CPJbf6FM.js → collapsible-B4DlWicL.js} +1 -1
- package/dist/components/chat-thread.d.ts +89 -1
- package/dist/components/conversation-item.d.ts +16 -0
- package/dist/components/conversation-panel.d.ts +29 -0
- package/dist/components/home-panel.d.ts +34 -0
- package/dist/components/widget-tab-bar.d.ts +16 -0
- package/dist/{composer-CjngLzal.js → composer-sQ0HcvyG.js} +3 -3
- package/dist/{confirm-card-DCx_A4bU.js → confirm-card-rQWDQsnC.js} +1 -1
- package/dist/construct-cli.es.js +185 -17
- package/dist/construct.d.ts +5 -0
- package/dist/construct.js +327 -0
- package/dist/{context-BY8V-Nlp.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-B6DO4PqB.js → copy-n9u9rqpi.js} +1 -1
- package/dist/core-C8fzo39E.js +1 -12
- package/dist/{create-tween-CnMHviKB.js → create-tween-C-q-JCM-.js} +1 -1
- package/dist/{create-tween-D1aiGZZh.js → create-tween-CRrJXxBd.js} +1 -1
- package/dist/{create-tween-BPzaefTp.js → create-tween-DZ3RRDHD.js} +1 -1
- package/dist/{create-tween-DUSQUKpr.js → create-tween-uPkArjIG.js} +1 -1
- package/dist/custom-elements.json +51 -2
- package/dist/{default-input-CucQEOqH.js → default-input-CaMrJkgH.js} +1 -1
- package/dist/define-By-uL588.js +1 -0
- package/dist/define.js +2 -2
- package/dist/define.server.js +2 -2
- package/dist/{disclosure-CbLtajUQ.js → disclosure-WUImBbDv.js} +1 -1
- package/dist/{dropdown-BwhViJFd.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/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.js +1 -1
- package/dist/elements/checkbox.js +1 -1
- 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/dialog.js +1 -1
- package/dist/elements/dock.js +3 -3
- package/dist/elements/dropdown.js +1 -1
- package/dist/elements/editable-label.js +1 -1
- 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.js +1 -1
- 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.js +1 -1
- 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 +1 -1
- 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.js +1 -1
- 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.js +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 +20 -4
- package/dist/{ellipsis-DFr4Vqr3.js → ellipsis-CbOpJnU3.js} +1 -1
- package/dist/{embed-5s_vU4J0.js → embed-CrfjkbUG.js} +1 -1
- package/dist/engine-javascript-C1x7zo1_.js +1 -141
- package/dist/{external-link-u9d85ORQ.js → external-link-ByXAwBBQ.js} +1 -1
- package/dist/{file-text-CX7_x42o.js → file-text-DMib2qwt.js} +1 -1
- package/dist/{file-tree-D3kBjXI5.js → file-tree-CJqM2aP7.js} +1 -1
- package/dist/{folder-V-YdIL8f.js → folder-_BAb929C.js} +1 -1
- package/dist/{form-BRNUMCN2.js → form-DSZgZQZk.js} +1 -1
- package/dist/{hover-card-DaeiYrTA.js → hover-card-BQbul9eq.js} +1 -1
- package/dist/{icon-BpixdZNq.js → icon-CdcfRhYI.js} +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2842 -2703
- package/dist/index.server.js +2820 -2681
- package/dist/{info-8mFsIjS3.js → info-DsFjGuI_.js} +1 -1
- package/dist/{input-d1Yuu-hz.js → input-DKbmkMos.js} +1 -1
- package/dist/kai.es.js +1 -1
- package/dist/{kbd-961zMPFB.js → kbd-PvdGhX4s.js} +1 -1
- package/dist/{link-preview-DIIbV2Sd.js → link-preview-DbM1866N.js} +1 -1
- package/dist/{link-DlZZBGaR.js → link-zF8PzWfF.js} +1 -1
- package/dist/{loader-YQszHFaW.js → loader-BM4CEz4G.js} +1 -1
- package/dist/{markdown-CVk1MPsj.js → markdown-LMvmAyBk.js} +7 -7
- package/dist/mcp.es.js +79 -5
- package/dist/{message-CwKVEdZg.js → message-BSsgvHvf.js} +1 -1
- package/dist/{message-DS8lzHc1.js → message-BYZECyek.js} +1 -1
- package/dist/message-circle-DruwObfX.js +1 -0
- package/dist/message-square-BG6q6mlm.js +1 -0
- package/dist/{minimize-2-UEZmP2QT.js → minimize-2-BQRoBV1V.js} +1 -1
- package/dist/{model-switcher-Kk1jEQ5t.js → model-switcher-CMpCOYcB.js} +1 -1
- package/dist/{overlay-C1od6LOz.js → overlay-Cb-MkyDa.js} +1 -1
- package/dist/{panel-right-ryET0yyn.js → panel-right-i8warFxT.js} +1 -1
- package/dist/{paperclip-BDNoZFJP.js → paperclip-ByY3UVO6.js} +1 -1
- package/dist/play-BvKKq3fX.js +1 -0
- package/dist/primitives/conversation-store.d.ts +54 -0
- package/dist/{progress-bar-BvYX0aoy.js → progress-bar-jVAHvMUf.js} +1 -1
- package/dist/{prompt-suggestion-BRFu2lcu.js → prompt-suggestion-CD-qtNgC.js} +1 -1
- package/dist/{radio-DcL23cNJ.js → radio-BsoBMhkF.js} +1 -1
- package/dist/react/index.d.ts +393 -0
- package/dist/react.js +20 -20
- package/dist/{reasoning-Cackq4Rh.js → reasoning-4kBPtlTx.js} +1 -1
- package/dist/register-impl-B1hLkrI8.js +424 -0
- package/dist/{resizable-Cp9HUYih.js → resizable-uPmY9VY-.js} +1 -1
- package/dist/{rotate-ccw-0DLRDHH5.js → rotate-ccw-B2xn93py.js} +1 -1
- package/dist/{rotate-cw-DOB9IGcU.js → rotate-cw-CMVLoCyH.js} +1 -1
- package/dist/{scroll-area-emVmWP4K.js → scroll-area-BqLUo8ZZ.js} +1 -1
- package/dist/{scroll-button-CeP_gv1x.js → scroll-button-DslXiJyL.js} +1 -1
- package/dist/{select-CWmu00tS.js → select-2cLRtPGT.js} +1 -1
- package/dist/{separator-CE6vly6z.js → separator-BWQtNJcM.js} +1 -1
- package/dist/{settings-CE-78SvZ.js → settings-BBR63jLg.js} +1 -1
- package/dist/{settings-group-ZFWNxFQR.js → settings-group-B2ciy-Iw.js} +1 -1
- package/dist/{skeleton-BebdP4mf.js → skeleton-CkHI-HgC.js} +1 -1
- package/dist/{slider-BAKRYUlz.js → slider-DDR9U-i0.js} +1 -1
- package/dist/{solid-BE5ui6sy.js → solid-BzCFdL25.js} +7720 -7058
- package/dist/{solid-DFhsce3O.js → solid-DruVOXnf.js} +5864 -5283
- package/dist/solid.d.ts +6 -2
- package/dist/solid.js +217 -210
- package/dist/solid.server.js +217 -210
- package/dist/{source-B0FlguSx.js → source-GEnFF528.js} +1 -1
- package/dist/{star-CBMZvLuN.js → star-CilHq8GP.js} +1 -1
- package/dist/store-Ciyk6eZG.js +1 -0
- package/dist/{switch-CViARZCy.js → switch-KkeQIbuH.js} +1 -1
- package/dist/{tasks-card-MjCcOhR_.js → tasks-card-BrN4bggJ.js} +1 -1
- package/dist/{text-shimmer-DKlwRF2G.js → text-shimmer-Dcj1MHuq.js} +1 -1
- package/dist/{textarea-3ay2Me2-.js → textarea-Dpvbngbg.js} +1 -1
- package/dist/theme.tokens.css +28 -0
- package/dist/{thumbs-up-DQcu2HMO.js → thumbs-up-CsT9Wzb9.js} +1 -1
- package/dist/{toast-store-C6yKOhbk.js → toast-store-tgK6MuMv.js} +1 -1
- package/dist/{tool-BCYNlfKy.js → tool-DzUjIBT8.js} +1 -1
- package/dist/{tooltip-05zI4hjs.js → tooltip-Bkkg_4t0.js} +1 -1
- package/dist/{trash-2-BR1RxGky.js → trash-2-jBKxjGGQ.js} +1 -1
- package/dist/{triangle-alert-DHohDOCy.js → triangle-alert-DlQ68ppf.js} +1 -1
- package/dist/types.d.ts +48 -3
- package/dist/ui/dock.d.ts +29 -0
- package/dist/{upload-BbGW6A_u.js → upload-TcAHXv9W.js} +1 -1
- package/dist/{url-scheme-policy-DHpoTJwB.js → url-scheme-policy-DR5DgvkM.js} +1 -1
- package/dist/{use-card-resolution-CJW4grFa.js → use-card-resolution-DaZqAdWf.js} +1 -1
- package/dist/{variant-aurora-xiMPty8f.js → variant-aurora-BhLuYxJR.js} +1 -1
- package/dist/{variant-aurora-BUOVgPOB.js → variant-aurora-CNmfHhcx.js} +2 -2
- package/dist/{variant-aurora-CUsUJvFI.js → variant-aurora-D6GsdTPA.js} +2 -2
- package/dist/{variant-aurora-CW2i4bfr.js → variant-aurora-DbW_OWL2.js} +1 -1
- package/dist/{variant-custom-D91HjAKz.js → variant-custom-BRvaNHSi.js} +1 -1
- package/dist/{variant-custom-BQtOnmeO.js → variant-custom-BvYHR62b.js} +1 -1
- package/dist/{variant-custom-CAnzzppW.js → variant-custom-DMTrEO5w.js} +2 -2
- package/dist/{variant-custom-CAm9L-E5.js → variant-custom-DV2x254s.js} +2 -2
- package/dist/{variant-wave-Ca1Ls4_y.js → variant-wave-BNMGrDfj.js} +2 -2
- package/dist/{variant-wave-uY5crU_K.js → variant-wave-BpDd8t3Z.js} +1 -1
- package/dist/{variant-wave-CxX39DKd.js → variant-wave-CyBueXj9.js} +2 -2
- package/dist/{variant-wave-DYyzIIZv.js → variant-wave-sp-qwsdI.js} +1 -1
- package/dist/x-Z5UntkIJ.js +1 -0
- package/frameworks/react/index.tsx +14 -4
- package/llms-full.txt +7 -2
- package/package.json +16 -16
- package/src/elements/element-meta.json +49 -6
- package/theme.css +28 -0
- package/bin/route.test.js +0 -58
- package/dist/arrow-down-Br0qtpsz.js +0 -1
- package/dist/arrow-left-Dj7xgE12.js +0 -1
- package/dist/check-DPeeMUYx.js +0 -1
- package/dist/chevron-down-CHSWk7ZT.js +0 -1
- package/dist/chevron-right-B7l_fMgx.js +0 -1
- package/dist/circle-Bb0yOpqM.js +0 -1
- package/dist/circle-check-BGZpCiz7.js +0 -1
- package/dist/code-block-CUQ5mtv0.js +0 -1
- package/dist/controllable-D43BKmtX.js +0 -1
- package/dist/conversation-list-D4lLU_yS.js +0 -1
- package/dist/define-CGGX-7Vg.js +0 -1
- package/dist/message-circle-Xf8Q-vZp.js +0 -1
- package/dist/message-square-Cxnwgkns.js +0 -1
- package/dist/play-OFIvYXUQ.js +0 -1
- package/dist/register-impl-C7rENvPK.js +0 -424
- package/dist/store-7eoadydQ.js +0 -1
- package/dist/x-C5m1JFgi.js +0 -1
- package/src/agent-tooling/archetypes.ts +0 -205
- package/src/agent-tooling/catalog/README.md +0 -676
- package/src/agent-tooling/catalog/catalog-types.ts +0 -231
- package/src/agent-tooling/catalog/fabrications.ts +0 -96
- package/src/agent-tooling/catalog/invariants.ts +0 -284
- package/src/agent-tooling/catalog/labs-titles.ts +0 -114
- package/src/agent-tooling/catalog/scenarios.ts +0 -87
- package/src/agent-tooling/catalog/surfaces.ts +0 -347
- package/src/agent-tooling/construct/cli-entry.ts +0 -8
- package/src/agent-tooling/construct/cli.ts +0 -131
- package/src/agent-tooling/construct/codegen.ts +0 -1353
- package/src/agent-tooling/construct/construct.v1.schema.json +0 -250
- package/src/agent-tooling/construct/dev.ts +0 -148
- package/src/agent-tooling/construct/fixtures/demo-widget.construct.json +0 -7
- package/src/agent-tooling/construct/fixtures/ops-console.construct.json +0 -44
- package/src/agent-tooling/construct/fixtures/owner-widget.construct.json +0 -23
- package/src/agent-tooling/construct/schema.ts +0 -371
- package/src/agent-tooling/integrations/anthropic.ts +0 -442
- package/src/agent-tooling/integrations/cloudflare.ts +0 -218
- package/src/agent-tooling/integrations/langgraph.ts +0 -133
- package/src/agent-tooling/integrations/mastra.ts +0 -182
- package/src/agent-tooling/integrations/mock.ts +0 -148
- package/src/agent-tooling/integrations/ollama.ts +0 -97
- package/src/agent-tooling/integrations/openai.ts +0 -95
- package/src/agent-tooling/integrations/openrouter.ts +0 -82
- package/src/agent-tooling/integrations/pi.ts +0 -176
- package/src/agent-tooling/integrations/pydantic-ai.ts +0 -108
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +0 -398
- package/src/agent-tooling/mcp/css-raw.d.ts +0 -12
- package/src/agent-tooling/mcp/manifest.ts +0 -422
- package/src/agent-tooling/mcp/server.ts +0 -116
- package/src/agent-tooling/mcp/stdio.ts +0 -18
- package/src/agent-tooling/mcp/tools/construct.ts +0 -130
- package/src/agent-tooling/mcp/tools/debug.ts +0 -621
- package/src/agent-tooling/mcp/tools/reference.ts +0 -980
- package/src/agent-tooling/mcp/tools/scaffold.ts +0 -6708
- package/src/agent-tooling/mcp/tools/theme.ts +0 -456
- package/src/agent-tooling/mcp/tools/types.ts +0 -14
- package/src/agent-tooling/mcp/validate-args.ts +0 -141
- package/src/agent-tooling/recipes/composed-thread.ts +0 -714
- package/src/agent-tooling/recipes/index.ts +0 -22
- package/src/agent-tooling/recipes/types.ts +0 -32
- package/src/agent-tooling/registry.ts +0 -132
- package/src/agent-tooling/route-emit.ts +0 -305
- package/src/agent-tooling/types.ts +0 -390
- package/src/components/artifact-card.tsx +0 -120
- package/src/components/artifact.tsx +0 -914
- package/src/components/attachment-types.ts +0 -66
- package/src/components/attachments.tsx +0 -536
- package/src/components/audio-visualizer/audio-visualizer.voice-fixture.ts +0 -257
- package/src/components/audio-visualizer/aurora.glsl.ts +0 -330
- package/src/components/audio-visualizer/fit-scale.ts +0 -112
- package/src/components/audio-visualizer/index.tsx +0 -528
- package/src/components/audio-visualizer/labs/lab-choreography.ts +0 -187
- package/src/components/audio-visualizer/labs/lab-shaders.ts +0 -363
- package/src/components/audio-visualizer/labs/lab-visualizer.tsx +0 -102
- package/src/components/audio-visualizer/shader-canvas.tsx +0 -876
- package/src/components/audio-visualizer/sizes.ts +0 -54
- package/src/components/audio-visualizer/variant-aurora.tsx +0 -305
- package/src/components/audio-visualizer/variant-bar.tsx +0 -175
- package/src/components/audio-visualizer/variant-custom.tsx +0 -344
- package/src/components/audio-visualizer/variant-grid.tsx +0 -175
- package/src/components/audio-visualizer/variant-radial.tsx +0 -163
- package/src/components/audio-visualizer/variant-wave.tsx +0 -130
- package/src/components/audio-visualizer/wave.glsl.ts +0 -130
- package/src/components/card-fallback.tsx +0 -60
- package/src/components/card-renderer.tsx +0 -220
- package/src/components/card.tsx +0 -212
- package/src/components/chain-of-thought.tsx +0 -348
- package/src/components/chat-container.tsx +0 -89
- package/src/components/chat-scope-picker.tsx +0 -57
- package/src/components/chat-thread.tsx +0 -518
- package/src/components/checkpoint.tsx +0 -88
- package/src/components/choice-card.tsx +0 -743
- package/src/components/coachmark.tsx +0 -249
- package/src/components/code-block.tsx +0 -181
- package/src/components/composer-dom.ts +0 -159
- package/src/components/composer-highlight.ts +0 -242
- package/src/components/composer-history.ts +0 -82
- package/src/components/composer.tsx +0 -1075
- package/src/components/confirm-card.tsx +0 -402
- package/src/components/context.tsx +0 -377
- package/src/components/conversation-item.tsx +0 -218
- package/src/components/conversation-list.tsx +0 -429
- package/src/components/dismissed-stub.tsx +0 -80
- package/src/components/embed.tsx +0 -200
- package/src/components/empty.tsx +0 -177
- package/src/components/feedback-bar.tsx +0 -166
- package/src/components/file-tree.tsx +0 -530
- package/src/components/file-upload.tsx +0 -167
- package/src/components/form-widgets.tsx +0 -525
- package/src/components/form.tsx +0 -1296
- package/src/components/image.tsx +0 -65
- package/src/components/link-preview.tsx +0 -195
- package/src/components/loader.tsx +0 -367
- package/src/components/markdown.tsx +0 -162
- package/src/components/message-skills.tsx +0 -40
- package/src/components/message.tsx +0 -765
- package/src/components/model-switcher.tsx +0 -132
- package/src/components/prompt-input.tsx +0 -188
- package/src/components/prompt-suggestion.tsx +0 -150
- package/src/components/reasoning.tsx +0 -293
- package/src/components/response-compare-types.ts +0 -152
- package/src/components/response-compare.tsx +0 -455
- package/src/components/response-stream.tsx +0 -109
- package/src/components/screen.tsx +0 -181
- package/src/components/scroll-button.tsx +0 -93
- package/src/components/source.tsx +0 -192
- package/src/components/tasks-card.tsx +0 -801
- package/src/components/text-shimmer.tsx +0 -37
- package/src/components/thinking-bar.tsx +0 -50
- package/src/components/thread.tsx +0 -228
- package/src/components/toast.tsx +0 -503
- package/src/components/tool-classify.ts +0 -26
- package/src/components/tool-types.ts +0 -49
- package/src/components/tool.tsx +0 -190
- package/src/components/use-card-resolution.ts +0 -44
- package/src/components/voice-input.tsx +0 -222
- package/src/components/voice-output.tsx +0 -242
- package/src/components/workspace-shell.tsx +0 -285
- package/src/diagnostics/hook.ts +0 -352
- package/src/diagnostics/index.ts +0 -82
- package/src/diagnostics/report-request.ts +0 -296
- package/src/elements/agent-card.tsx +0 -67
- package/src/elements/artifact.tsx +0 -194
- package/src/elements/attachments.tsx +0 -140
- package/src/elements/audio-visualizer.tsx +0 -227
- package/src/elements/autoloader.ts +0 -89
- package/src/elements/avatar.tsx +0 -33
- package/src/elements/badge.tsx +0 -32
- package/src/elements/button.tsx +0 -149
- package/src/elements/card.tsx +0 -133
- package/src/elements/cards.tsx +0 -266
- package/src/elements/chain-of-thought.tsx +0 -141
- package/src/elements/chat-scope-picker.tsx +0 -65
- package/src/elements/chat-types.ts +0 -102
- package/src/elements/chat-workspace.tsx +0 -188
- package/src/elements/chat.tsx +0 -212
- package/src/elements/checkbox-group.tsx +0 -164
- package/src/elements/checkbox.tsx +0 -134
- package/src/elements/checkpoint.tsx +0 -47
- package/src/elements/choice.tsx +0 -100
- package/src/elements/coachmark.tsx +0 -90
- package/src/elements/code-block.tsx +0 -60
- package/src/elements/command.tsx +0 -197
- package/src/elements/compare.tsx +0 -111
- package/src/elements/compiled.css +0 -2
- package/src/elements/composer.tsx +0 -162
- package/src/elements/confirm-card.tsx +0 -76
- package/src/elements/context-meter.tsx +0 -107
- package/src/elements/conversation-item.tsx +0 -120
- package/src/elements/conversation-list.tsx +0 -203
- package/src/elements/css.ts +0 -5
- package/src/elements/default-input.tsx +0 -392
- package/src/elements/define-entry.ts +0 -12
- package/src/elements/define.tsx +0 -563
- package/src/elements/diagnostic-events.ts +0 -114
- package/src/elements/dialog.tsx +0 -145
- package/src/elements/disclosure.ts +0 -95
- package/src/elements/dock.tsx +0 -215
- package/src/elements/dropdown.tsx +0 -123
- package/src/elements/editable-label.tsx +0 -140
- package/src/elements/element-data-types.ts +0 -152
- package/src/elements/element-diagnostics.ts +0 -392
- package/src/elements/element-manifest.json +0 -354
- package/src/elements/element-nonscalar.json +0 -185
- package/src/elements/element-types.d.ts +0 -4337
- package/src/elements/embed.tsx +0 -35
- package/src/elements/empty.tsx +0 -29
- package/src/elements/feedback-bar.tsx +0 -66
- package/src/elements/file-tree.tsx +0 -62
- package/src/elements/file-upload.tsx +0 -44
- package/src/elements/form.tsx +0 -94
- package/src/elements/hover-card.tsx +0 -80
- package/src/elements/icon.tsx +0 -41
- package/src/elements/image.tsx +0 -32
- package/src/elements/input.tsx +0 -492
- package/src/elements/kbd.tsx +0 -45
- package/src/elements/link-preview.tsx +0 -34
- package/src/elements/loader.tsx +0 -25
- package/src/elements/markdown.tsx +0 -38
- package/src/elements/menu.tsx +0 -241
- package/src/elements/message-skills.tsx +0 -83
- package/src/elements/message.tsx +0 -361
- package/src/elements/model-switcher.tsx +0 -121
- package/src/elements/nav.tsx +0 -87
- package/src/elements/notice.tsx +0 -53
- package/src/elements/pane-grid.tsx +0 -111
- package/src/elements/pane-group.tsx +0 -119
- package/src/elements/pane.tsx +0 -129
- package/src/elements/popover.tsx +0 -81
- package/src/elements/progress-bar.tsx +0 -39
- package/src/elements/prompt-dock.tsx +0 -82
- package/src/elements/prompt-input.tsx +0 -240
- package/src/elements/prompt-suggestions.tsx +0 -113
- package/src/elements/radio-group.tsx +0 -129
- package/src/elements/reasoning.tsx +0 -71
- package/src/elements/register-impl.ts +0 -148
- package/src/elements/register.ts +0 -76
- package/src/elements/remote.tsx +0 -225
- package/src/elements/resizable.globals.d.ts +0 -36
- package/src/elements/resizable.tsx +0 -704
- package/src/elements/response-stream.tsx +0 -40
- package/src/elements/screen.tsx +0 -90
- package/src/elements/scroll-area.tsx +0 -33
- package/src/elements/scroll-button.tsx +0 -179
- package/src/elements/search.tsx +0 -185
- package/src/elements/segmented.tsx +0 -129
- package/src/elements/select.tsx +0 -165
- package/src/elements/separator.tsx +0 -36
- package/src/elements/setting-item.tsx +0 -50
- package/src/elements/settings-group.tsx +0 -37
- package/src/elements/skeleton.tsx +0 -45
- package/src/elements/slider.tsx +0 -171
- package/src/elements/slot-text.ts +0 -73
- package/src/elements/slots.ts +0 -787
- package/src/elements/source.tsx +0 -126
- package/src/elements/status.tsx +0 -42
- package/src/elements/styles.css +0 -328
- package/src/elements/switch.tsx +0 -118
- package/src/elements/tabs.tsx +0 -95
- package/src/elements/tasks.tsx +0 -103
- package/src/elements/text-shimmer.tsx +0 -28
- package/src/elements/thinking-bar.tsx +0 -43
- package/src/elements/thread.tsx +0 -139
- package/src/elements/toast.tsx +0 -106
- package/src/elements/tool.tsx +0 -78
- package/src/elements/tooltip.tsx +0 -85
- package/src/elements/validate-messages.ts +0 -76
- package/src/elements/voice-input.tsx +0 -100
- package/src/elements/voice-output.tsx +0 -82
- package/src/index.ts +0 -428
- package/src/primitives/audio-bands.ts +0 -174
- package/src/primitives/card-component-types.ts +0 -63
- package/src/primitives/card-contract.ts +0 -80
- package/src/primitives/card-data-types.ts +0 -361
- package/src/primitives/card-host.tsx +0 -37
- package/src/primitives/card-recovery.ts +0 -160
- package/src/primitives/card-registry.tsx +0 -78
- package/src/primitives/card-resolution.ts +0 -36
- package/src/primitives/card-routing.ts +0 -85
- package/src/primitives/card-schemas/artifact.schema.json +0 -92
- package/src/primitives/card-schemas/card-envelope.schema.json +0 -14
- package/src/primitives/card-schemas/card-event.schema.json +0 -12
- package/src/primitives/card-schemas/choice.schema.json +0 -75
- package/src/primitives/card-schemas/confirm.schema.json +0 -65
- package/src/primitives/card-schemas/embed.schema.json +0 -63
- package/src/primitives/card-schemas/form.result.schema.json +0 -7
- package/src/primitives/card-schemas/form.schema.json +0 -53
- package/src/primitives/card-schemas/link.schema.json +0 -54
- package/src/primitives/card-schemas/tasks.result.schema.json +0 -16
- package/src/primitives/card-schemas/tasks.schema.json +0 -83
- package/src/primitives/card-tags.ts +0 -61
- package/src/primitives/card-validate-cards.ts +0 -255
- package/src/primitives/card-validate-schemas.ts +0 -58
- package/src/primitives/card-validate.ts +0 -131
- package/src/primitives/chat-config.tsx +0 -103
- package/src/primitives/composer-model.ts +0 -49
- package/src/primitives/composer-triggers.ts +0 -35
- package/src/primitives/controllable.ts +0 -21
- package/src/primitives/create-kai-chat.ts +0 -66
- package/src/primitives/create-tween.ts +0 -266
- package/src/primitives/embed-providers.ts +0 -254
- package/src/primitives/field-mask.ts +0 -256
- package/src/primitives/field-semantics.ts +0 -115
- package/src/primitives/highlighter.ts +0 -157
- package/src/primitives/input-mask.ts +0 -853
- package/src/primitives/link-preview.ts +0 -87
- package/src/primitives/message-feedback.ts +0 -124
- package/src/primitives/pdf-preview.ts +0 -121
- package/src/primitives/toast-store.ts +0 -338
- package/src/primitives/url-scheme-policy.ts +0 -70
- package/src/primitives/use-audio-analysis.ts +0 -340
- package/src/primitives/use-auto-resize.ts +0 -31
- package/src/primitives/use-resize-observer.ts +0 -45
- package/src/primitives/use-sequencer.ts +0 -72
- package/src/primitives/use-speech-recognition.ts +0 -146
- package/src/primitives/use-stick-to-bottom.ts +0 -75
- package/src/primitives/use-text-stream.ts +0 -143
- package/src/primitives/use-voice-recorder.ts +0 -62
- package/src/primitives/visualizer-sequences.ts +0 -350
- package/src/remote/host-embed.ts +0 -345
- package/src/remote/index.ts +0 -2
- package/src/remote/origin.ts +0 -30
- package/src/remote/provider-runtime.ts +0 -262
- package/src/remote/provider.ts +0 -2
- package/src/remote/validate.ts +0 -22
- package/src/remote/version.ts +0 -12
- package/src/remote/wire.ts +0 -48
- package/src/schemas/from-tool-call.ts +0 -151
- package/src/schemas/index.ts +0 -341
- package/src/schemas/provider-subsets.ts +0 -538
- package/src/schemas/registry.ts +0 -355
- package/src/schemas/tool-defs.ts +0 -793
- package/src/solid.ts +0 -165
- package/src/state/index.ts +0 -44
- package/src/state/messages.ts +0 -53
- package/src/state/mock.ts +0 -297
- package/src/state/parts.ts +0 -295
- package/src/state/persistence.ts +0 -180
- package/src/state/stream.ts +0 -246
- package/src/state/suggestions.ts +0 -9
- package/src/state/threads.ts +0 -142
- package/src/test-utils/fake-clock.ts +0 -88
- package/src/types.ts +0 -53
- package/src/ui/action-icons.ts +0 -53
- package/src/ui/agent-card.tsx +0 -218
- package/src/ui/avatar.tsx +0 -23
- package/src/ui/badge.tsx +0 -21
- package/src/ui/button.tsx +0 -49
- package/src/ui/card.tsx +0 -245
- package/src/ui/checkbox-group.tsx +0 -153
- package/src/ui/checkbox.tsx +0 -63
- package/src/ui/collapsible.tsx +0 -163
- package/src/ui/command.tsx +0 -103
- package/src/ui/dialog.tsx +0 -223
- package/src/ui/dock.tsx +0 -584
- package/src/ui/dropdown.tsx +0 -636
- package/src/ui/editable-label.tsx +0 -112
- package/src/ui/hover-card.tsx +0 -345
- package/src/ui/icon.tsx +0 -167
- package/src/ui/input.tsx +0 -391
- package/src/ui/kbd.tsx +0 -118
- package/src/ui/nav.tsx +0 -282
- package/src/ui/notice.tsx +0 -84
- package/src/ui/overlay.tsx +0 -277
- package/src/ui/pane-grid.tsx +0 -117
- package/src/ui/pane-group.tsx +0 -291
- package/src/ui/pane.tsx +0 -193
- package/src/ui/popover.tsx +0 -106
- package/src/ui/progress-bar.tsx +0 -83
- package/src/ui/prompt-dock.tsx +0 -145
- package/src/ui/radio.tsx +0 -150
- package/src/ui/resizable.tsx +0 -693
- package/src/ui/scroll-area.tsx +0 -26
- package/src/ui/segmented.tsx +0 -109
- package/src/ui/select.tsx +0 -168
- package/src/ui/separator.tsx +0 -10
- package/src/ui/settings-group.tsx +0 -67
- package/src/ui/skeleton.tsx +0 -73
- package/src/ui/slider.tsx +0 -178
- package/src/ui/status.tsx +0 -48
- package/src/ui/switch.tsx +0 -119
- package/src/ui/tabs.tsx +0 -168
- package/src/ui/textarea.tsx +0 -21
- package/src/ui/tooltip.tsx +0 -118
- package/src/utils/cn.ts +0 -30
- package/src/wire/chunk.ts +0 -248
- package/src/wire/consume.ts +0 -599
- package/src/wire/diagnostics.ts +0 -727
- package/src/wire/encode-probe.ts +0 -214
- package/src/wire/encode.ts +0 -947
- package/src/wire/files.ts +0 -342
- package/src/wire/formats/anthropic.ts +0 -274
- package/src/wire/formats/openai.ts +0 -228
- package/src/wire/index.ts +0 -95
- package/src/wire/media-types.ts +0 -344
- package/src/wire/read.ts +0 -396
- package/src/wire/sink-helpers.ts +0 -50
- package/src/wire/sse.ts +0 -153
|
@@ -1,525 +0,0 @@
|
|
|
1
|
-
import { type JSX, For, Show, createMemo, createSignal } from 'solid-js';
|
|
2
|
-
import { cn } from '../utils/cn';
|
|
3
|
-
import { Textarea } from '../ui/textarea';
|
|
4
|
-
import { Input, FIELD_BASE as inputBase } from '../ui/input';
|
|
5
|
-
import { Slider } from '../ui/slider';
|
|
6
|
-
import { Select } from '../ui/select';
|
|
7
|
-
import { Switch } from '../ui/switch';
|
|
8
|
-
import { Checkbox } from '../ui/checkbox';
|
|
9
|
-
import { RadioGroup } from '../ui/radio';
|
|
10
|
-
import { CheckboxGroup } from '../ui/checkbox-group';
|
|
11
|
-
import { Button } from '../ui/button';
|
|
12
|
-
import { Star, X } from 'lucide-solid';
|
|
13
|
-
import type { FieldMaskHint, FormField } from './form';
|
|
14
|
-
|
|
15
|
-
/** The shared prop shape every leaf widget receives from FieldRow. */
|
|
16
|
-
export interface WidgetProps {
|
|
17
|
-
id: string;
|
|
18
|
-
value: unknown;
|
|
19
|
-
field: FormField;
|
|
20
|
-
/**
|
|
21
|
-
* The field's resolved format hints, or an empty resolution.
|
|
22
|
-
*
|
|
23
|
-
* RESOLVED IN `FieldRow`, not here. The row already has to resolve them to render
|
|
24
|
-
* the format hint text and put its id in `aria-describedby`, and resolving the same
|
|
25
|
-
* untrusted `x-kai-*` keys a second time in the widget would warn twice about the
|
|
26
|
-
* same bad hint and could disagree with what the row said out loud.
|
|
27
|
-
*/
|
|
28
|
-
mask?: FieldMaskHint;
|
|
29
|
-
disabled: boolean;
|
|
30
|
-
placeholder?: string;
|
|
31
|
-
required: boolean;
|
|
32
|
-
invalid: boolean;
|
|
33
|
-
describedBy?: string;
|
|
34
|
-
label: string;
|
|
35
|
-
/**
|
|
36
|
-
* The id of the row's VISIBLE label element, for widgets whose control is a group
|
|
37
|
-
* rather than one labelable input.
|
|
38
|
-
*
|
|
39
|
-
* `FieldRow` used to suppress its `<label>` for those kinds and each widget named
|
|
40
|
-
* itself with `aria-label={props.label}`, which is a name only a screen reader can
|
|
41
|
-
* reach: "Severity", "Environments" and "Tags" were announced and invisible. The row
|
|
42
|
-
* now always renders the text and hands its id down here, so one string names the
|
|
43
|
-
* group and everybody can see it. Absent means the widget is on its own (a bare
|
|
44
|
-
* widget rendered outside `FieldRow`), so `aria-label` stays the fallback.
|
|
45
|
-
*/
|
|
46
|
-
labelledBy?: string;
|
|
47
|
-
onInput: (value: unknown) => void;
|
|
48
|
-
onBlur: () => void;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* How a GROUP widget names itself: the row's visible label when there is one,
|
|
53
|
-
* `aria-label` only as the fallback. Never both — two accessible names on one element
|
|
54
|
-
* is one too many, and `aria-labelledby` would win silently anyway.
|
|
55
|
-
*/
|
|
56
|
-
function groupNameProps(p: WidgetProps): { 'aria-labelledby'?: string; 'aria-label'?: string } {
|
|
57
|
-
return p.labelledBy !== undefined
|
|
58
|
-
? { 'aria-labelledby': p.labelledBy }
|
|
59
|
-
: { 'aria-label': p.label };
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function ariaProps(p: WidgetProps) {
|
|
63
|
-
return {
|
|
64
|
-
'aria-required': p.required || undefined,
|
|
65
|
-
'aria-invalid': p.invalid || undefined,
|
|
66
|
-
'aria-describedby': p.describedBy,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** text / email / url / date / datetime / time / password — all <input> variants. */
|
|
71
|
-
export function TextWidget(
|
|
72
|
-
props: WidgetProps & { variant: 'text' | 'email' | 'url' | 'date' | 'datetime' | 'time' | 'password' },
|
|
73
|
-
): JSX.Element {
|
|
74
|
-
const inputType = () => {
|
|
75
|
-
switch (props.variant) {
|
|
76
|
-
case 'email':
|
|
77
|
-
return 'email';
|
|
78
|
-
case 'url':
|
|
79
|
-
return 'url';
|
|
80
|
-
case 'date':
|
|
81
|
-
return 'date';
|
|
82
|
-
case 'datetime':
|
|
83
|
-
return 'datetime-local';
|
|
84
|
-
case 'time':
|
|
85
|
-
return 'time';
|
|
86
|
-
case 'password':
|
|
87
|
-
return 'password';
|
|
88
|
-
default:
|
|
89
|
-
return 'text';
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
// Render the bare `Input` control (no label/hint/error): `kai-form`'s FieldRow
|
|
93
|
-
// already supplies the label, description, and inline error around the widget.
|
|
94
|
-
// `Input` owns the field styling (its `FIELD_BASE` is the former `inputBase`),
|
|
95
|
-
// so the rendered input is byte-identical to the old raw `<input>`.
|
|
96
|
-
return (
|
|
97
|
-
<Input
|
|
98
|
-
id={props.id}
|
|
99
|
-
data-control
|
|
100
|
-
type={inputType()}
|
|
101
|
-
value={(props.value as string) ?? ''}
|
|
102
|
-
placeholder={props.placeholder}
|
|
103
|
-
invalid={props.invalid}
|
|
104
|
-
disabled={props.disabled}
|
|
105
|
-
minLength={props.field.minLength}
|
|
106
|
-
maxLength={props.field.maxLength}
|
|
107
|
-
// Masking (spec §7.3). Each is `undefined` for a field with no format hints, so
|
|
108
|
-
// an unhinted field renders exactly the input it rendered before. The hint TEXT
|
|
109
|
-
// is deliberately not passed as `Input`'s own `hint`: `FieldRow` renders it and
|
|
110
|
-
// owns the `aria-describedby` chain, and `Input`'s hint would mint a second one
|
|
111
|
-
// (spec §6). The submitted value is the CANONICAL one — `Input` emits canonical
|
|
112
|
-
// through `onValueInput` whenever a mask is active (spec §4), which is what
|
|
113
|
-
// makes "exactly one value per field" true without this widget choosing.
|
|
114
|
-
format={props.mask?.format}
|
|
115
|
-
guide={props.mask?.guide}
|
|
116
|
-
semantic={props.mask?.semantic}
|
|
117
|
-
{...ariaProps(props)}
|
|
118
|
-
onValueInput={(value) => props.onInput(value)}
|
|
119
|
-
onValueChange={() => props.onBlur()}
|
|
120
|
-
/>
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export function TextareaWidget(props: WidgetProps): JSX.Element {
|
|
125
|
-
const len = () => ((props.value as string) ?? '').length;
|
|
126
|
-
return (
|
|
127
|
-
<div class="flex flex-col gap-1">
|
|
128
|
-
<Textarea
|
|
129
|
-
id={props.id}
|
|
130
|
-
data-control
|
|
131
|
-
class={cn(inputBase, props.invalid && 'border-destructive dark:border-red-400/70')}
|
|
132
|
-
value={(props.value as string) ?? ''}
|
|
133
|
-
placeholder={props.placeholder}
|
|
134
|
-
disabled={props.disabled}
|
|
135
|
-
maxLength={props.field.maxLength}
|
|
136
|
-
{...ariaProps(props)}
|
|
137
|
-
onInput={(e) => props.onInput(e.currentTarget.value)}
|
|
138
|
-
onBlur={props.onBlur}
|
|
139
|
-
/>
|
|
140
|
-
<Show when={props.field.maxLength !== undefined}>
|
|
141
|
-
<span class="self-end text-xs text-muted-foreground">
|
|
142
|
-
{len()}/{props.field.maxLength}
|
|
143
|
-
</span>
|
|
144
|
-
</Show>
|
|
145
|
-
</div>
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export function NumberWidget(props: WidgetProps): JSX.Element {
|
|
150
|
-
const step = () => props.field['x-kai-step'] ?? (props.field.type === 'integer' ? 1 : undefined);
|
|
151
|
-
// `Input`, not a raw `<input class={inputBase}>` (plan step 6). The two render the
|
|
152
|
-
// same box — `FIELD_BASE` is the former `inputBase` — so nothing is visible. What the
|
|
153
|
-
// bypass lost was the focus-node-reuse fix documented at `ui/input.tsx:262-268`: with
|
|
154
|
-
// the class computed at the CALL SITE, `props.invalid` changing rebuilt the `<input>`
|
|
155
|
-
// node and took focus and caret with it, and `kai-form` derives `invalid` from the
|
|
156
|
-
// field's own value. `min`/`max`/`step` come from the schema and are forwarded
|
|
157
|
-
// untouched; no bound is invented here.
|
|
158
|
-
//
|
|
159
|
-
// No `format`/`guide`/`semantic`: masking is a text-field affordance and a
|
|
160
|
-
// `type="number"` field has no mask hints to resolve.
|
|
161
|
-
return (
|
|
162
|
-
<Input
|
|
163
|
-
id={props.id}
|
|
164
|
-
data-control
|
|
165
|
-
type="number"
|
|
166
|
-
value={props.value === undefined || props.value === null ? '' : String(props.value)}
|
|
167
|
-
placeholder={props.placeholder}
|
|
168
|
-
invalid={props.invalid}
|
|
169
|
-
disabled={props.disabled}
|
|
170
|
-
min={props.field.minimum}
|
|
171
|
-
max={props.field.maximum}
|
|
172
|
-
step={step()}
|
|
173
|
-
{...ariaProps(props)}
|
|
174
|
-
onValueInput={(value) => props.onInput(value)}
|
|
175
|
-
onValueChange={() => props.onBlur()}
|
|
176
|
-
/>
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export function SliderWidget(props: WidgetProps): JSX.Element {
|
|
181
|
-
// The 0..100 fallback is the WIDGET's, not the primitive's (plan §4). This widget is
|
|
182
|
-
// reading a consumer-authored JSON-Schema field where `minimum`/`maximum` are
|
|
183
|
-
// optional; `Slider` itself requires both, so no other caller inherits this guess.
|
|
184
|
-
const min = () => props.field.minimum ?? 0;
|
|
185
|
-
const max = () => props.field.maximum ?? 100;
|
|
186
|
-
const step = () => props.field['x-kai-step'] ?? (props.field.type === 'integer' ? 1 : undefined);
|
|
187
|
-
const current = () => (props.value === undefined || props.value === null ? min() : Number(props.value));
|
|
188
|
-
// The value bubble and the row that holds it BOTH live in the primitive now
|
|
189
|
-
// (`valueLabel`), so this widget no longer hand-builds either. Same markup, same
|
|
190
|
-
// classes, one owner, and the readout picked up an `aria-hidden` it did not have
|
|
191
|
-
// here: the slider already announces the number through `aria-valuetext` below.
|
|
192
|
-
return (
|
|
193
|
-
<Slider
|
|
194
|
-
id={props.id}
|
|
195
|
-
data-control
|
|
196
|
-
value={current()}
|
|
197
|
-
min={min()}
|
|
198
|
-
max={max()}
|
|
199
|
-
step={step()}
|
|
200
|
-
disabled={props.disabled}
|
|
201
|
-
valueLabel
|
|
202
|
-
aria-valuetext={String(current())}
|
|
203
|
-
{...ariaProps(props)}
|
|
204
|
-
onInput={(e) => props.onInput(Number(e.currentTarget.value))}
|
|
205
|
-
onBlur={props.onBlur}
|
|
206
|
-
/>
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export function RatingWidget(props: WidgetProps): JSX.Element {
|
|
211
|
-
const max = () => props.field.maximum ?? 5;
|
|
212
|
-
const min = () => props.field.minimum ?? 1;
|
|
213
|
-
const current = () => Number(props.value ?? 0);
|
|
214
|
-
const stars = () => Array.from({ length: max() }, (_, i) => i + 1);
|
|
215
|
-
/**
|
|
216
|
-
* Roving tabindex. Exactly one `role="radio"` is in the tab order — the selected
|
|
217
|
-
* star, or the first one while nothing is selected. The GROUP is deliberately not
|
|
218
|
-
* a tab stop: it used to be (`tabindex={0}` with every radio at `-1`), and the
|
|
219
|
-
* consequence was that arrow keys changed the value while focus never left the
|
|
220
|
-
* group, so the focus ring sat on the whole row and a screen reader announced the
|
|
221
|
-
* radiogroup instead of "3 stars, selected". Roving tabindex is the pattern the
|
|
222
|
-
* ARIA radiogroup spec asks for and it makes both symptoms go away at once.
|
|
223
|
-
*/
|
|
224
|
-
const activeStar = () => (current() >= min() && current() <= max() ? current() : min());
|
|
225
|
-
const refs = new Map<number, HTMLButtonElement>();
|
|
226
|
-
/** Set the value AND move DOM focus to the star that now owns it. */
|
|
227
|
-
const select = (n: number): void => {
|
|
228
|
-
const next = Math.min(max(), Math.max(min(), n));
|
|
229
|
-
props.onInput(next);
|
|
230
|
-
refs.get(next)?.focus();
|
|
231
|
-
};
|
|
232
|
-
const onKey = (e: KeyboardEvent): void => {
|
|
233
|
-
if (props.disabled) return;
|
|
234
|
-
if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {
|
|
235
|
-
e.preventDefault();
|
|
236
|
-
select(current() + 1);
|
|
237
|
-
} else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {
|
|
238
|
-
e.preventDefault();
|
|
239
|
-
select(current() - 1);
|
|
240
|
-
} else if (e.key === 'Home') {
|
|
241
|
-
e.preventDefault();
|
|
242
|
-
select(min());
|
|
243
|
-
} else if (e.key === 'End') {
|
|
244
|
-
e.preventDefault();
|
|
245
|
-
select(max());
|
|
246
|
-
}
|
|
247
|
-
};
|
|
248
|
-
return (
|
|
249
|
-
// `groupNameProps`: the row renders a visible "Rating" label whose `for` had
|
|
250
|
-
// nothing to point at (there is no single labelable control here, only stars).
|
|
251
|
-
// Pointing the group at that same visible text makes ONE string name the control.
|
|
252
|
-
<div
|
|
253
|
-
role="radiogroup"
|
|
254
|
-
{...groupNameProps(props)}
|
|
255
|
-
class="flex items-center gap-1 rounded-md"
|
|
256
|
-
{...ariaProps(props)}
|
|
257
|
-
>
|
|
258
|
-
<For each={stars()}>
|
|
259
|
-
{(n) => (
|
|
260
|
-
<button
|
|
261
|
-
type="button"
|
|
262
|
-
role="radio"
|
|
263
|
-
// `data-control` rides the roving tab stop, so `form.focusField()` —
|
|
264
|
-
// which focuses the single `[data-control]` inside the field — lands on
|
|
265
|
-
// the same star Tab would reach. It used to sit on the group, which is no
|
|
266
|
-
// longer focusable. No `id={props.id}`: the row's `<label for>` had
|
|
267
|
-
// nothing to point at before either, and pointing it at a star would make
|
|
268
|
-
// clicking the field label set the rating to 1. The group is named by the
|
|
269
|
-
// row's visible label (see `groupNameProps` above), which is what names it.
|
|
270
|
-
data-control={activeStar() === n ? '' : undefined}
|
|
271
|
-
aria-checked={current() === n}
|
|
272
|
-
aria-label={`${n} ${n === 1 ? 'star' : 'stars'}`}
|
|
273
|
-
tabindex={activeStar() === n ? 0 : -1}
|
|
274
|
-
disabled={props.disabled}
|
|
275
|
-
ref={(el) => refs.set(n, el)}
|
|
276
|
-
class="rounded p-0.5 text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
277
|
-
onKeyDown={onKey}
|
|
278
|
-
onClick={() => select(n)}
|
|
279
|
-
onBlur={props.onBlur}
|
|
280
|
-
>
|
|
281
|
-
<Star
|
|
282
|
-
size={20}
|
|
283
|
-
class={cn(n <= current() ? 'fill-current text-[var(--color-primary)]' : '')}
|
|
284
|
-
aria-hidden="true"
|
|
285
|
-
/>
|
|
286
|
-
</button>
|
|
287
|
-
)}
|
|
288
|
-
</For>
|
|
289
|
-
</div>
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* The boolean field's switch IS `ui/switch.tsx` — it is not a lookalike.
|
|
295
|
-
*
|
|
296
|
-
* This used to hand-roll its own `<button role="switch">` at 44×24 while
|
|
297
|
-
* `<kai-switch>` shipped the same control at 36×20, so a consumer putting the two
|
|
298
|
-
* side by side saw two different switches; and its thumb used `bg-background`,
|
|
299
|
-
* re-introducing in the copy the dark-mode disappearing-thumb bug that
|
|
300
|
-
* `ui/switch.tsx:80` carries a comment about having fixed. Delegating removes both.
|
|
301
|
-
* The size convergence (44×24 → 36×20) is visible inside `kai-form` and intended.
|
|
302
|
-
*
|
|
303
|
-
* The four form-only hooks — `id`, `data-control` and the `aria-required` /
|
|
304
|
-
* `aria-invalid` / `aria-describedby` trio — are ordinary props now (plan decision
|
|
305
|
-
* D-7). They used to be stamped onto the button through `buttonRef` + a
|
|
306
|
-
* `createEffect`, which worked but meant this widget reached into the primitive's
|
|
307
|
-
* DOM to make `form.focusField()` land. `Switch` forwards anything it does not own
|
|
308
|
-
* to its inner button, exactly like `Checkbox` and `Radio` forward to their inputs,
|
|
309
|
-
* so all four ride the same path every other widget's hooks do.
|
|
310
|
-
*/
|
|
311
|
-
export function SwitchWidget(props: WidgetProps): JSX.Element {
|
|
312
|
-
const on = () => props.value === true;
|
|
313
|
-
return (
|
|
314
|
-
<Switch
|
|
315
|
-
id={props.id}
|
|
316
|
-
data-control=""
|
|
317
|
-
checked={on()}
|
|
318
|
-
disabled={props.disabled}
|
|
319
|
-
label={props.label}
|
|
320
|
-
{...ariaProps(props)}
|
|
321
|
-
onChange={(next) => {
|
|
322
|
-
props.onInput(next);
|
|
323
|
-
props.onBlur();
|
|
324
|
-
}}
|
|
325
|
-
/>
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
export function CheckboxWidget(props: WidgetProps): JSX.Element {
|
|
330
|
-
return (
|
|
331
|
-
<label class="-mx-1.5 inline-flex cursor-pointer items-center gap-2.5 rounded-md px-1.5 py-1.5 text-sm text-foreground transition-colors hover:bg-muted/60">
|
|
332
|
-
<Checkbox
|
|
333
|
-
id={props.id}
|
|
334
|
-
data-control=""
|
|
335
|
-
checked={props.value === true}
|
|
336
|
-
disabled={props.disabled}
|
|
337
|
-
{...ariaProps(props)}
|
|
338
|
-
onChange={(e) => {
|
|
339
|
-
props.onInput(e.currentTarget.checked);
|
|
340
|
-
props.onBlur();
|
|
341
|
-
}}
|
|
342
|
-
/>
|
|
343
|
-
<span>{props.label}</span>
|
|
344
|
-
</label>
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
export function RadioGroupWidget(props: WidgetProps): JSX.Element {
|
|
349
|
-
// The row chrome, the `radiogroup` wrapper and the shared `name` all live in the
|
|
350
|
-
// primitive now; this widget only turns a JSON-Schema `enum` into options.
|
|
351
|
-
const options = createMemo(() =>
|
|
352
|
-
((props.field.enum ?? []) as unknown[]).map((opt) => ({ value: opt, label: String(opt) })),
|
|
353
|
-
);
|
|
354
|
-
return (
|
|
355
|
-
<RadioGroup<unknown>
|
|
356
|
-
data-control=""
|
|
357
|
-
{...groupNameProps(props)}
|
|
358
|
-
name={props.id}
|
|
359
|
-
options={options()}
|
|
360
|
-
value={props.value}
|
|
361
|
-
disabled={props.disabled}
|
|
362
|
-
{...ariaProps(props)}
|
|
363
|
-
onChange={(value) => {
|
|
364
|
-
props.onInput(value);
|
|
365
|
-
props.onBlur();
|
|
366
|
-
}}
|
|
367
|
-
/>
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
export function SelectWidget(props: WidgetProps): JSX.Element {
|
|
372
|
-
// The primitive renders no placeholder row unless it is given one; the 'Select…'
|
|
373
|
-
// wording is this widget's, because a schema-driven field has nowhere else to get it.
|
|
374
|
-
const options = createMemo(() =>
|
|
375
|
-
((props.field.enum ?? []) as unknown[]).map((opt) => ({ value: opt, label: String(opt) })),
|
|
376
|
-
);
|
|
377
|
-
return (
|
|
378
|
-
<Select<unknown>
|
|
379
|
-
id={props.id}
|
|
380
|
-
data-control
|
|
381
|
-
options={options()}
|
|
382
|
-
value={props.value}
|
|
383
|
-
placeholder={props.placeholder ?? 'Select…'}
|
|
384
|
-
invalid={props.invalid}
|
|
385
|
-
disabled={props.disabled}
|
|
386
|
-
{...ariaProps(props)}
|
|
387
|
-
onChange={(e) => {
|
|
388
|
-
props.onInput(e.currentTarget.value);
|
|
389
|
-
props.onBlur();
|
|
390
|
-
}}
|
|
391
|
-
/>
|
|
392
|
-
);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
function itemEnum(field: FormField): unknown[] {
|
|
396
|
-
const items = field.items;
|
|
397
|
-
if (items && 'enum' in items && Array.isArray(items.enum)) return items.enum;
|
|
398
|
-
return [];
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* An array field whose items are an `enum`, as a list of checkboxes.
|
|
403
|
-
*
|
|
404
|
-
* The bordered/divided row chrome, the `role="group"` wrapper and the rows themselves
|
|
405
|
-
* live in `ui/checkbox-group.tsx` now — this widget only turns a JSON-Schema
|
|
406
|
-
* `items.enum` into options and owns the array in and out. It used to hand-roll the
|
|
407
|
-
* identical chrome beside `RadioGroup`, which already owned it.
|
|
408
|
-
*
|
|
409
|
-
* The emitted array holds the SCHEMA's values, not their string forms, so a numeric
|
|
410
|
-
* or boolean enum survives a round trip.
|
|
411
|
-
*/
|
|
412
|
-
export function CheckboxGroupWidget(props: WidgetProps & { class?: string }): JSX.Element {
|
|
413
|
-
const selected = () => (Array.isArray(props.value) ? (props.value as unknown[]) : []);
|
|
414
|
-
const options = createMemo(() => itemEnum(props.field).map((opt) => ({ value: opt, label: String(opt) })));
|
|
415
|
-
// `name={props.id}`: a shared name so a native form submits the whole selection under
|
|
416
|
-
// one key and `FormData.getAll()` reads it back. `kai-form` collects through its own
|
|
417
|
-
// store rather than a native submit, but the control participating correctly is free
|
|
418
|
-
// here and losing it would be a silent downgrade.
|
|
419
|
-
return (
|
|
420
|
-
<CheckboxGroup<unknown>
|
|
421
|
-
data-control=""
|
|
422
|
-
{...groupNameProps(props)}
|
|
423
|
-
name={props.id}
|
|
424
|
-
class={props.class}
|
|
425
|
-
options={options()}
|
|
426
|
-
value={selected()}
|
|
427
|
-
disabled={props.disabled}
|
|
428
|
-
{...ariaProps(props)}
|
|
429
|
-
onChange={(next) => {
|
|
430
|
-
props.onInput(next);
|
|
431
|
-
props.onBlur();
|
|
432
|
-
}}
|
|
433
|
-
/>
|
|
434
|
-
);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* The LONG version of `checkbox-group`: an array-of-enum field whose option list is
|
|
439
|
-
* over the row's `inlineMax`.
|
|
440
|
-
*
|
|
441
|
-
* This was a `<select multiple>` until decision D-3 was ruled. `<select multiple>` is a
|
|
442
|
-
* poor control on every platform — the multi-select affordance is invisible, discovering
|
|
443
|
-
* it means knowing to ctrl/cmd-click, and there is no touch story at all. It is the same
|
|
444
|
-
* control as `checkbox-group`, so it renders as one, with a scroll cap because the only
|
|
445
|
-
* thing that made a long list bearable in a chat card was the select's fixed-height box.
|
|
446
|
-
*
|
|
447
|
-
* The scroll cap is a presentation decision (how a long list fits), not a limit: every
|
|
448
|
-
* option is rendered, nothing is truncated or dropped.
|
|
449
|
-
*/
|
|
450
|
-
export function MultiSelectWidget(props: WidgetProps): JSX.Element {
|
|
451
|
-
return <CheckboxGroupWidget {...props} class="max-h-60 overflow-y-auto" />;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
export function TagListWidget(props: WidgetProps): JSX.Element {
|
|
455
|
-
const tags = () => (Array.isArray(props.value) ? (props.value as string[]) : []);
|
|
456
|
-
const [draft, setDraft] = createSignal('');
|
|
457
|
-
const add = (): void => {
|
|
458
|
-
const v = draft().trim();
|
|
459
|
-
if (!v) return;
|
|
460
|
-
// No cap on how many tags may be added. How many is too many lands in a policy
|
|
461
|
-
// document, which makes it the consuming application's call (CLAUDE.md, plan §4).
|
|
462
|
-
props.onInput([...tags(), v]);
|
|
463
|
-
setDraft('');
|
|
464
|
-
props.onBlur();
|
|
465
|
-
};
|
|
466
|
-
const remove = (i: number): void => {
|
|
467
|
-
props.onInput(tags().filter((_, idx) => idx !== i));
|
|
468
|
-
props.onBlur();
|
|
469
|
-
};
|
|
470
|
-
return (
|
|
471
|
-
<div class="flex flex-col gap-2" role="group" {...groupNameProps(props)}>
|
|
472
|
-
<div class="flex flex-wrap gap-1.5">
|
|
473
|
-
<For each={tags()}>
|
|
474
|
-
{(tag, i) => (
|
|
475
|
-
<span class="inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-xs text-foreground">
|
|
476
|
-
{tag}
|
|
477
|
-
{/* `Button`, not a bare `<button>`, and a lucide `X` rather than the
|
|
478
|
-
literal "✕" character it used to render. A bare glyph is what a screen
|
|
479
|
-
reader falls back to when nothing else names the control; the icon is
|
|
480
|
-
`aria-hidden` and the `aria-label` is the only name, so every remove
|
|
481
|
-
control announces which tag it removes. */}
|
|
482
|
-
<Button
|
|
483
|
-
type="button"
|
|
484
|
-
variant="ghost"
|
|
485
|
-
size="icon-sm"
|
|
486
|
-
class="size-4 rounded-full p-0 text-muted-foreground hover:bg-transparent hover:text-foreground"
|
|
487
|
-
aria-label={`Remove ${tag}`}
|
|
488
|
-
disabled={props.disabled}
|
|
489
|
-
onClick={() => remove(i())}
|
|
490
|
-
>
|
|
491
|
-
<X size={12} aria-hidden="true" />
|
|
492
|
-
</Button>
|
|
493
|
-
</span>
|
|
494
|
-
)}
|
|
495
|
-
</For>
|
|
496
|
-
</div>
|
|
497
|
-
<div class="flex items-center gap-2">
|
|
498
|
-
{/* `Input` rather than a raw `<input class={inputBase}>` (plan step 6). Same box,
|
|
499
|
-
same classes; what the bypass lost was the focus-node-reuse fix at
|
|
500
|
-
`ui/input.tsx:262-268` and the masking `Input` owns. The draft field is not a
|
|
501
|
-
form control of its own — it holds text on its way to becoming a tag — so it
|
|
502
|
-
carries the row's `id` and `data-control` and nothing else. */}
|
|
503
|
-
<Input
|
|
504
|
-
id={props.id}
|
|
505
|
-
data-control
|
|
506
|
-
type="text"
|
|
507
|
-
value={draft()}
|
|
508
|
-
placeholder={props.placeholder ?? 'Add…'}
|
|
509
|
-
disabled={props.disabled}
|
|
510
|
-
{...ariaProps(props)}
|
|
511
|
-
onValueInput={(value) => setDraft(value)}
|
|
512
|
-
onKeyDown={(e) => {
|
|
513
|
-
if (e.key === 'Enter') {
|
|
514
|
-
e.preventDefault();
|
|
515
|
-
add();
|
|
516
|
-
}
|
|
517
|
-
}}
|
|
518
|
-
/>
|
|
519
|
-
<Button type="button" variant="outline" size="md" disabled={props.disabled} onClick={add}>
|
|
520
|
-
Add
|
|
521
|
-
</Button>
|
|
522
|
-
</div>
|
|
523
|
-
</div>
|
|
524
|
-
);
|
|
525
|
-
}
|