@kitn.ai/ui 0.25.2 → 0.26.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 +2 -2
- package/dist/components/attachment-types.d.ts +46 -1
- package/dist/components/attachments.d.ts +31 -0
- package/dist/components/audio-visualizer/fit-scale.d.ts +50 -0
- package/dist/components/audio-visualizer/index.d.ts +15 -1
- package/dist/components/audio-visualizer/variant-bar.d.ts +24 -1
- package/dist/components/chat-thread.d.ts +3 -41
- package/dist/components/code-block.d.ts +22 -0
- package/dist/components/conversation-item.d.ts +54 -1
- package/dist/components/conversation-list.d.ts +65 -0
- package/dist/components/form.d.ts +42 -0
- package/dist/components/message.d.ts +7 -0
- package/dist/components/toast.d.ts +2 -1
- package/dist/components/voice-input.d.ts +8 -0
- package/dist/components/voice-output.d.ts +12 -1
- package/dist/components/workspace-shell.d.ts +87 -0
- package/dist/{create-tween-B5Y4Im8G.js → create-tween-BFT6c-Y8.js} +1 -1
- package/dist/{create-tween-4z1XYLkR.js → create-tween-CJNlzoaO.js} +1 -1
- package/dist/{create-tween-CUzOlaMS.js → create-tween-CQED4T0g.js} +1 -1
- package/dist/custom-elements.json +2931 -2572
- package/dist/diagnostics/hook.d.ts +81 -0
- package/dist/diagnostics/index.d.ts +7 -0
- package/dist/diagnostics/report-request.d.ts +61 -0
- package/dist/diagnostics.d.ts +5 -0
- package/dist/diagnostics.js +209 -0
- 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/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/chunks/{Icon-b5A8hlHs.js → Icon--Y8vsFal.js} +1 -1
- package/dist/elements/chunks/action-icons-D9u3OzYW.js +1 -0
- package/dist/elements/chunks/arrow-left-CVh1TeN7.js +1 -0
- package/dist/elements/chunks/{artifact-BSuPYFHY.js → artifact-BkYcfIlZ.js} +1 -1
- package/dist/elements/chunks/attachments-DwfNlubq.js +1 -0
- package/dist/elements/chunks/audio-visualizer-D7lB6mvR.js +1 -0
- package/dist/elements/chunks/{badge-TIMiJFKc.js → badge-Q0-Cmwzz.js} +1 -1
- package/dist/elements/chunks/{button-B9okqG73.js → button-flUbeufF.js} +1 -1
- package/dist/elements/chunks/{card-renderer-CSoTL_e1.js → card-renderer-3Dyl-FpN.js} +1 -1
- package/dist/elements/chunks/check-B5kBPKeo.js +1 -0
- package/dist/elements/chunks/chevron-down-DZ1GS39h.js +1 -0
- package/dist/elements/chunks/chevron-right-CvP7OUd2.js +1 -0
- package/dist/elements/chunks/{choice-card-CGMc3kek.js → choice-card-D4QUIOWZ.js} +1 -1
- package/dist/elements/chunks/circle-CDf9g6MQ.js +1 -0
- package/dist/elements/chunks/circle-check-CA47Nqbz.js +1 -0
- package/dist/elements/chunks/{circle-x-mhH7pOK2.js → circle-x-CJ_HVbC8.js} +1 -1
- package/dist/elements/chunks/code-block-BdLiTitd.js +1 -0
- package/dist/elements/chunks/collapsible-BzbXpPzr.js +1 -0
- package/dist/elements/chunks/{composer-CZZmtYOT.js → composer-Byve-n8K.js} +2 -2
- package/dist/elements/chunks/{confirm-card-BWjf2-xo.js → confirm-card-B0flE3MN.js} +1 -1
- package/dist/elements/chunks/context-VLIL3sJ-.js +1 -0
- package/dist/elements/chunks/controllable-DTwTIlwp.js +1 -0
- package/dist/elements/chunks/conversation-item-BDztezOG.js +1 -0
- package/dist/elements/chunks/copy-Nf-kqxXH.js +1 -0
- package/dist/elements/chunks/{create-tween-CUrM6D_o.js → create-tween-c4Z8TDYz.js} +2 -2
- package/dist/elements/chunks/default-input-C2iLFq0b.js +1 -0
- package/dist/elements/chunks/define-wjHR1MkU.js +1 -0
- package/dist/elements/chunks/disclosure-CcNbyLy0.js +1 -0
- package/dist/elements/chunks/{download-DnCyWFJE.js → download-C4V7tBdb.js} +1 -1
- package/dist/elements/chunks/dropdown-BgWTthUx.js +1 -0
- package/dist/elements/chunks/{ellipsis-CVxqfsDZ.js → ellipsis-7gU33mL2.js} +1 -1
- package/dist/elements/chunks/embed-D3KewsIJ.js +1 -0
- package/dist/elements/chunks/{external-link-DG2sRdQL.js → external-link-CSOEsNlx.js} +1 -1
- package/dist/elements/chunks/{file-text-D0J9F6M7.js → file-text-D1G8khle.js} +1 -1
- package/dist/elements/chunks/{file-tree-yGWNK0Js.js → file-tree-zvB2i7P9.js} +1 -1
- package/dist/elements/chunks/{folder-NV1pi_ud.js → folder-WW2LGLid.js} +1 -1
- package/dist/elements/chunks/form-CQirdC4W.js +1 -0
- package/dist/elements/chunks/hover-card-CJJkfHTK.js +1 -0
- package/dist/elements/chunks/icon-Cfgmf4fa.js +1 -0
- package/dist/elements/chunks/{info-C8r5Q6cc.js → info-DX3YMOt6.js} +1 -1
- package/dist/elements/chunks/input-BtW9U6Sq.js +1 -0
- package/dist/elements/chunks/{kbd-OGJDUT-O.js → kbd-LGXwuT_V.js} +1 -1
- package/dist/elements/chunks/{link-BdsfLB7b.js → link-2My69BqT.js} +1 -1
- package/dist/elements/chunks/{link-preview-Cf5KOP-i.js → link-preview-OQ9IEq0f.js} +1 -1
- package/dist/elements/chunks/{loader-B5QzK_8_.js → loader-iOxc_Tu-.js} +1 -1
- package/dist/elements/chunks/{markdown-DbozyYqa.js → markdown-DgBFaGAz.js} +1 -1
- package/dist/elements/chunks/{message-DtXKPqiR.js → message-VMZohrXx.js} +1 -1
- package/dist/elements/chunks/message-circle-CpXMM-_n.js +1 -0
- package/dist/elements/chunks/message-square-DxcWtETQ.js +1 -0
- package/dist/elements/chunks/message-tZmV2A3p.js +1 -0
- package/dist/elements/chunks/{minimize-2-SegJ_oku.js → minimize-2-DPIUKTrT.js} +1 -1
- package/dist/elements/chunks/{model-switcher-D7JrFFHp.js → model-switcher-DsT8tFB0.js} +1 -1
- package/dist/elements/chunks/{overlay-CV7z2YuX.js → overlay-DuiwdXjm.js} +1 -1
- package/dist/elements/chunks/{paperclip-Bg0ITU3b.js → paperclip-CRZVp4z_.js} +1 -1
- package/dist/elements/chunks/{progress-bar-D1_rzt6N.js → progress-bar-DNy66e_E.js} +1 -1
- package/dist/elements/chunks/{prompt-suggestion-D5Sm8xF1.js → prompt-suggestion-Bn64Nl7L.js} +1 -1
- package/dist/elements/chunks/reasoning-Emn9N4-T.js +1 -0
- package/dist/elements/chunks/{resizable-Dpzjlvp4.js → resizable-D181b4fM.js} +1 -1
- package/dist/elements/chunks/{rotate-cw-DzVDJOA1.js → rotate-cw-CPWe37D9.js} +1 -1
- package/dist/elements/chunks/{scroll-area-93A1bbeG.js → scroll-area-ClZkZxIk.js} +1 -1
- package/dist/elements/chunks/scroll-button-DPE-t3x_.js +1 -0
- package/dist/elements/chunks/{separator-DH2r_ZSZ.js → separator-CeJHQqLW.js} +1 -1
- package/dist/elements/chunks/{settings-BFMOd6yB.js → settings-CqaHgJF9.js} +1 -1
- package/dist/elements/chunks/{settings-group-B3VZKIcz.js → settings-group-CjqjLCOn.js} +1 -1
- package/dist/elements/chunks/share-CyfnNEqp.js +1 -0
- package/dist/elements/chunks/{skeleton-N8BuWYmf.js → skeleton-D8akBnKS.js} +1 -1
- package/dist/elements/chunks/slots-DaNjX0rc.js +1 -0
- package/dist/elements/chunks/{source-w9V0NnBn.js → source-UWCvmVak.js} +1 -1
- package/dist/elements/chunks/{star-DHvACxtm.js → star-DoHFAikQ.js} +1 -1
- package/dist/elements/chunks/store-Cjq0qwYN.js +1 -0
- package/dist/elements/chunks/{tasks-card-lPxoodlA.js → tasks-card-CmZ5xh6v.js} +1 -1
- package/dist/elements/chunks/{text-shimmer-BY_rI3s5.js → text-shimmer-DYn09zrz.js} +1 -1
- package/dist/elements/chunks/textarea-skiGHURM.js +1 -0
- package/dist/elements/chunks/{thumbs-up-DQe0hvkZ.js → thumbs-up-DX2Ijk3H.js} +1 -1
- package/dist/elements/chunks/{toast-store-VUZZBhzH.js → toast-store-CFnQpThX.js} +1 -1
- package/dist/elements/chunks/{tool-C1YtxwPu.js → tool-DKQ2D1DP.js} +1 -1
- package/dist/elements/chunks/{tooltip-BqwnFWhn.js → tooltip-B0G99y8w.js} +1 -1
- package/dist/elements/chunks/{triangle-alert-B6or7F5u.js → triangle-alert-F9cyUEyy.js} +1 -1
- package/dist/elements/chunks/{use-card-resolution-DJg32jGH.js → use-card-resolution-DoA2f_EU.js} +1 -1
- package/dist/elements/chunks/{variant-aurora-QXTZPyST.js → variant-aurora-qt6Zct8M.js} +2 -2
- package/dist/elements/chunks/variant-custom-tJp22_BQ.js +1 -0
- package/dist/{variant-wave-BwzrHD1s.js → elements/chunks/variant-wave-CaQ5ti39.js} +2 -2
- package/dist/elements/chunks/x-B6UnOiLw.js +1 -0
- 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.d.ts +1 -0
- package/dist/elements/conversation-item.js +1 -0
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/default-input.d.ts +3 -3
- package/dist/elements/define.d.ts +27 -0
- package/dist/elements/diagnostic-events.d.ts +74 -0
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/dock.d.ts +1 -0
- package/dist/elements/dock.js +149 -0
- package/dist/elements/dropdown.d.ts +1 -0
- package/dist/elements/dropdown.js +1 -0
- package/dist/elements/editable-label.js +1 -1
- package/dist/elements/element-diagnostics.d.ts +81 -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-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/reasoning.js +1 -1
- package/dist/elements/register.d.ts +2 -0
- package/dist/elements/remote.js +1 -1
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +3 -3
- 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/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/slots.d.ts +35 -3
- 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 +232 -148
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5456 -4931
- package/dist/index.server.js +4142 -3669
- package/dist/kai-provider.es.js +40 -40
- package/dist/kai.es.js +1 -1
- package/dist/llms/llms-full.txt +184 -69
- package/dist/llms/llms.txt +3 -3
- package/dist/mcp.es.js +2669 -546
- package/dist/primitives/use-resize-observer.d.ts +23 -0
- package/dist/primitives/use-speech-recognition.d.ts +8 -0
- package/dist/primitives/use-text-stream.d.ts +5 -0
- package/dist/react/index.d.ts +115 -266
- package/dist/react.js +247 -221
- package/dist/register-impl-DpE7icIb.js +293 -0
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/tool-defs.d.ts +35 -0
- package/dist/schemas.js +403 -310
- package/dist/{solid-BMuDmFo_.js → solid-BtdqNZI7.js} +8435 -7394
- package/dist/{solid-CGYNdLRR.js → solid-CnavwBye.js} +5987 -5035
- package/dist/solid.d.ts +5 -0
- package/dist/solid.js +210 -203
- package/dist/solid.server.js +210 -203
- package/dist/state/index.d.ts +4 -0
- package/dist/state/persistence.d.ts +51 -0
- package/dist/state/stream.d.ts +50 -0
- package/dist/state/threads.d.ts +71 -0
- package/dist/state.js +269 -169
- package/dist/types.d.ts +4 -2
- package/dist/ui/dock.d.ts +109 -0
- package/dist/ui/hover-card.d.ts +44 -0
- package/dist/{variant-aurora-DwSOfraQ.js → variant-aurora-B8II3-I1.js} +27 -27
- package/dist/{variant-aurora-wKvAQ5wp.js → variant-aurora-CMNWOSJR.js} +28 -28
- package/dist/{variant-aurora-XEkPT0_z.js → variant-aurora-CcuDMWwQ.js} +2 -2
- package/dist/{variant-custom-eFIg2XWQ.js → variant-custom-BdvYC7af.js} +40 -40
- package/dist/{variant-custom-BhS9wIpU.js → variant-custom-C714mqKl.js} +65 -65
- package/dist/variant-custom-L16JLLZy.js +1 -0
- package/dist/{elements/chunks/variant-wave-DDCwhLas.js → variant-wave-2S4La2Ka.js} +2 -2
- package/dist/{variant-wave-CbVsmgwT.js → variant-wave-D7ruiA1W.js} +25 -25
- package/dist/{variant-wave-CUWGx9Bn.js → variant-wave-ecwykeyL.js} +21 -21
- package/dist/wire/chunk.d.ts +47 -0
- package/dist/wire/diagnostics.d.ts +575 -0
- package/dist/wire/encode-probe.d.ts +70 -0
- package/dist/wire/encode.d.ts +24 -0
- package/dist/wire/index.d.ts +2 -0
- package/dist/wire/sse.d.ts +10 -2
- package/dist/wire.js +917 -480
- package/frameworks/react/index.tsx +132 -93
- package/llms-full.txt +184 -69
- package/llms.txt +3 -3
- package/package.json +26 -6
- package/src/agent-tooling/archetypes.ts +41 -9
- package/src/agent-tooling/catalog/README.md +676 -0
- package/src/agent-tooling/catalog/catalog-types.ts +231 -0
- package/src/agent-tooling/catalog/fabrications.ts +96 -0
- package/src/agent-tooling/catalog/invariants.ts +284 -0
- package/src/agent-tooling/catalog/labs-titles.ts +114 -0
- package/src/agent-tooling/catalog/scenarios.ts +87 -0
- package/src/agent-tooling/catalog/surfaces.ts +275 -0
- package/src/agent-tooling/integrations/anthropic.ts +7 -1
- package/src/agent-tooling/integrations/cloudflare.ts +43 -2
- package/src/agent-tooling/integrations/langgraph.ts +7 -1
- package/src/agent-tooling/integrations/mastra.ts +7 -1
- package/src/agent-tooling/integrations/mock.ts +92 -17
- package/src/agent-tooling/integrations/ollama.ts +7 -1
- package/src/agent-tooling/integrations/openai.ts +7 -1
- package/src/agent-tooling/integrations/openrouter.ts +7 -1
- package/src/agent-tooling/integrations/pi.ts +56 -1
- package/src/agent-tooling/integrations/vercel-ai-sdk.ts +7 -1
- package/src/agent-tooling/mcp/css-raw.d.ts +12 -0
- package/src/agent-tooling/mcp/manifest.ts +100 -1
- package/src/agent-tooling/mcp/server.ts +61 -5
- package/src/agent-tooling/mcp/tools/reference.ts +440 -4
- package/src/agent-tooling/mcp/tools/scaffold.ts +1834 -307
- package/src/agent-tooling/mcp/tools/theme.ts +146 -30
- package/src/agent-tooling/mcp/validate-args.ts +141 -0
- package/src/agent-tooling/registry.ts +19 -7
- package/src/agent-tooling/route-emit.ts +26 -2
- package/src/components/attachment-types.ts +47 -1
- package/src/components/attachments.tsx +169 -22
- package/src/components/audio-visualizer/fit-scale.ts +112 -0
- package/src/components/audio-visualizer/index.tsx +80 -3
- package/src/components/audio-visualizer/variant-aurora.tsx +10 -4
- package/src/components/audio-visualizer/variant-bar.tsx +38 -6
- package/src/components/audio-visualizer/variant-custom.tsx +8 -2
- package/src/components/audio-visualizer/variant-grid.tsx +16 -11
- package/src/components/audio-visualizer/variant-radial.tsx +15 -10
- package/src/components/audio-visualizer/variant-wave.tsx +7 -2
- package/src/components/chat-container.tsx +4 -1
- package/src/components/chat-thread.tsx +36 -7
- package/src/components/code-block.tsx +79 -3
- package/src/components/composer.tsx +8 -1
- package/src/components/conversation-item.tsx +114 -4
- package/src/components/conversation-list.tsx +212 -12
- package/src/components/embed.tsx +4 -0
- package/src/components/form.tsx +41 -14
- package/src/components/message.tsx +75 -5
- package/src/components/response-stream.tsx +13 -7
- package/src/components/screen.tsx +5 -0
- package/src/components/scroll-button.tsx +7 -0
- package/src/components/toast.tsx +11 -5
- package/src/components/voice-input.tsx +35 -3
- package/src/components/voice-output.tsx +46 -6
- package/src/components/workspace-shell.tsx +285 -0
- package/src/diagnostics/hook.ts +352 -0
- package/src/diagnostics/index.ts +82 -0
- package/src/diagnostics/report-request.ts +296 -0
- package/src/elements/attachments.tsx +6 -7
- package/src/elements/audio-visualizer.tsx +48 -4
- package/src/elements/chat-workspace.tsx +159 -287
- package/src/elements/chat.tsx +12 -9
- package/src/elements/code-block.tsx +19 -1
- package/src/elements/command.tsx +4 -1
- package/src/elements/compiled.css +1 -1
- package/src/elements/conversation-item.tsx +80 -0
- package/src/elements/conversation-list.tsx +60 -11
- package/src/elements/default-input.tsx +5 -5
- package/src/elements/define.tsx +168 -8
- package/src/elements/diagnostic-events.ts +114 -0
- package/src/elements/dialog.tsx +47 -0
- package/src/elements/disclosure.ts +34 -12
- package/src/elements/dock.tsx +204 -0
- package/src/elements/dropdown.tsx +123 -0
- package/src/elements/element-diagnostics.ts +392 -0
- package/src/elements/element-manifest.json +12 -0
- package/src/elements/element-meta.json +672 -439
- package/src/elements/element-nonscalar.json +170 -0
- package/src/elements/element-types.d.ts +232 -148
- package/src/elements/menu.tsx +13 -0
- package/src/elements/prompt-dock.tsx +2 -1
- package/src/elements/prompt-input.tsx +8 -8
- package/src/elements/register-impl.ts +46 -0
- package/src/elements/register.ts +28 -0
- package/src/elements/resizable.tsx +52 -25
- package/src/elements/scroll-button.tsx +5 -0
- package/src/elements/slots.ts +107 -12
- package/src/elements/styles.css +30 -6
- package/src/elements/thinking-bar.tsx +16 -7
- package/src/elements/toast.tsx +3 -0
- package/src/elements/tool.tsx +26 -5
- package/src/elements/voice-input.tsx +11 -2
- package/src/elements/voice-output.tsx +16 -3
- package/src/index.ts +2 -0
- package/src/primitives/use-resize-observer.ts +33 -0
- package/src/primitives/use-speech-recognition.ts +12 -1
- package/src/primitives/use-stick-to-bottom.ts +34 -2
- package/src/primitives/use-text-stream.ts +33 -2
- package/src/remote/provider-runtime.ts +6 -3
- package/src/schemas/index.ts +1 -0
- package/src/schemas/tool-defs.ts +297 -6
- package/src/solid.ts +5 -0
- package/src/state/index.ts +12 -0
- package/src/state/persistence.ts +180 -0
- package/src/state/stream.ts +71 -4
- package/src/state/threads.ts +142 -0
- package/src/types.ts +4 -2
- package/src/ui/dialog.tsx +6 -0
- package/src/ui/dock.tsx +445 -0
- package/src/ui/dropdown.tsx +67 -23
- package/src/ui/hover-card.tsx +156 -6
- package/src/ui/input.tsx +29 -10
- package/src/ui/resizable.tsx +11 -0
- package/src/wire/chunk.ts +47 -0
- package/src/wire/consume.ts +185 -26
- package/src/wire/diagnostics.ts +727 -0
- package/src/wire/encode-probe.ts +214 -0
- package/src/wire/encode.ts +267 -14
- package/src/wire/formats/anthropic.ts +8 -1
- package/src/wire/formats/openai.ts +5 -0
- package/src/wire/index.ts +22 -0
- package/src/wire/read.ts +250 -6
- package/src/wire/sse.ts +16 -3
- package/dist/elements/chunks/action-icons-DW9muWrY.js +0 -1
- package/dist/elements/chunks/arrow-left-iJVnQmxA.js +0 -1
- package/dist/elements/chunks/attachments-CL6TaqIb.js +0 -1
- package/dist/elements/chunks/audio-visualizer-BuUqQmaO.js +0 -1
- package/dist/elements/chunks/chat-thread-DxoKaStk.js +0 -1
- package/dist/elements/chunks/check-MdLzbxrm.js +0 -1
- package/dist/elements/chunks/chevron-down-MK7IzDqe.js +0 -1
- package/dist/elements/chunks/chevron-right-C5jXhmtV.js +0 -1
- package/dist/elements/chunks/circle-BG7VkPep.js +0 -1
- package/dist/elements/chunks/circle-check-GqvO2UBs.js +0 -1
- package/dist/elements/chunks/code-block-ClhQO9RW.js +0 -1
- package/dist/elements/chunks/collapsible-DBcBkFPh.js +0 -1
- package/dist/elements/chunks/context-hKjNqiyQ.js +0 -1
- package/dist/elements/chunks/conversation-list-CsGJjSKG.js +0 -1
- package/dist/elements/chunks/default-input-B1Mem5wu.js +0 -1
- package/dist/elements/chunks/define-B_tXMYRm.js +0 -1
- package/dist/elements/chunks/disclosure-DAoYOKew.js +0 -1
- package/dist/elements/chunks/dropdown-CmNna5lT.js +0 -1
- package/dist/elements/chunks/embed-CjAD2jSi.js +0 -1
- package/dist/elements/chunks/form-Cp8Y00Wn.js +0 -1
- package/dist/elements/chunks/hover-card-6KtXpLwT.js +0 -1
- package/dist/elements/chunks/icon-97R8SR2p.js +0 -1
- package/dist/elements/chunks/input-DrseEjhp.js +0 -1
- package/dist/elements/chunks/message-CE4k-qaj.js +0 -1
- package/dist/elements/chunks/message-square-C9ovmtOo.js +0 -1
- package/dist/elements/chunks/reasoning-BrxQfpfI.js +0 -1
- package/dist/elements/chunks/scroll-button-CrTo7wm4.js +0 -1
- package/dist/elements/chunks/share-DgNbkJKY.js +0 -1
- package/dist/elements/chunks/slots-CIw9RlAe.js +0 -1
- package/dist/elements/chunks/store-HIPGhNz9.js +0 -1
- package/dist/elements/chunks/textarea-DPfuhswM.js +0 -1
- package/dist/elements/chunks/variant-custom-D5ZlmziF.js +0 -1
- package/dist/elements/chunks/video-Bb86fVYI.js +0 -1
- package/dist/elements/chunks/x-BOhjBeOd.js +0 -1
- package/dist/primitives/card-validate-generator.testlib.d.ts +0 -20
- package/dist/register-impl-DGmGzrEM.js +0 -145
- package/dist/variant-custom-MkTNTycd.js +0 -1
- package/src/primitives/card-validate-generator.testlib.ts +0 -38
package/llms-full.txt
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @kitn.ai/ui
|
|
5
5
|
|
|
6
|
-
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML.
|
|
6
|
+
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 83 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
|
|
7
7
|
|
|
8
8
|
## Install
|
|
9
9
|
|
|
@@ -37,7 +37,7 @@ Drop an element into any framework (React, Vue, plain HTML). Data in via JS prop
|
|
|
37
37
|
- `<kai-prompt-input>` — standalone composer with send button.
|
|
38
38
|
|
|
39
39
|
**Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
|
|
40
|
-
All
|
|
40
|
+
All 83 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
|
|
41
41
|
|
|
42
42
|
## Key rules for the web components
|
|
43
43
|
|
|
@@ -151,7 +151,7 @@ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
|
|
|
151
151
|
|
|
152
152
|
## Docs
|
|
153
153
|
|
|
154
|
-
- Full element reference (all
|
|
154
|
+
- Full element reference (all 83 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
|
|
155
155
|
- Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
|
|
156
156
|
- Working examples: https://github.com/kitn-ai/ui/tree/main/examples
|
|
157
157
|
- Storybook: https://storybook.kitn.dev
|
|
@@ -248,7 +248,7 @@ The same reassign rule applies to every array/object property (`models`, `contex
|
|
|
248
248
|
|
|
249
249
|
---
|
|
250
250
|
|
|
251
|
-
## Element reference (
|
|
251
|
+
## Element reference (83 elements, generated from custom-elements.json)
|
|
252
252
|
|
|
253
253
|
Every element also accepts the `theme` attribute. Array/object properties are marked with a `—` attribute: they must be set as JS properties.
|
|
254
254
|
|
|
@@ -357,6 +357,8 @@ Every element also accepts the `theme` attribute. Array/object properties are ma
|
|
|
357
357
|
| Part | Description |
|
|
358
358
|
|---|---|
|
|
359
359
|
| `::part(preview)` | The image shown in an attachment’s hover-card preview. Bounded by default (max ~320×256, aspect preserved) so a large image never blows up the card. Raise or lower the cap from outside. — `kai-attachments::part(preview) { max-width: 32rem; max-height: 24rem }` |
|
|
360
|
+
| `::part(attachment)` | One attachment item: the chip, row or tile, whichever variant is rendering. Restyle its background, radius or border from outside without caring which layout it is. — `kai-chat::part(attachment) { border-radius: 0.25rem }` |
|
|
361
|
+
| `::part(attachment-name)` | The attachment’s filename label. Present in every variant that shows one (a grid tile omits it for an image, which is its own label). Retune its type or hide it entirely. — `kai-chat::part(attachment-name) { font-size: 0.75rem }` |
|
|
360
362
|
|
|
361
363
|
---
|
|
362
364
|
|
|
@@ -378,9 +380,10 @@ Every element also accepts the `theme` attribute. Array/object properties are ma
|
|
|
378
380
|
| `color` | `color` | `undefined \| string` | CSS color for the geometry, overriding the inherited `currentColor`. Attribute: `color`. |
|
|
379
381
|
| `complexity` | `complexity` | `undefined \| number` | Shader variants only: pattern density, 0..1. Attribute: `complexity`. |
|
|
380
382
|
| `label` | `label` | `undefined \| string` | Setting this makes the element an announced image (`role="img"`) instead of decorative (`aria-hidden`). Attribute: `label`. |
|
|
381
|
-
| `stream` | — | `undefined \| MediaStream` | Live microphone or WebRTC audio to analyze. JS property only. |
|
|
382
|
-
| `audioElement` | — | `undefined \| HTMLMediaElement` | An `<audio>` or `<video>` element to tap for its audio. JS property only. |
|
|
383
|
-
| `bands` | — | `undefined \| number[]` | Pre-computed levels, 0..1. Set this and no AudioContext is ever built, which is what keeps headless/SSR rendering and browser-speech-synthesis playback (which exposes no audio node) free of Web Audio entirely. JS property only. A new array reference is required for each update; mutating the existing array in place will not re-render. |
|
|
383
|
+
| `stream` | — | `undefined \| MediaStream` | Live microphone or WebRTC audio to analyze. JS property only. NOTE: amplitude renders only while state is "speaking" unless listening-amplitude is set; every other state plays its scripted animation and ignores the audio. |
|
|
384
|
+
| `audioElement` | — | `undefined \| HTMLMediaElement` | An `<audio>` or `<video>` element to tap for its audio. JS property only. NOTE: amplitude renders only while state is "speaking" unless listening-amplitude is set; every other state plays its scripted animation and ignores the audio. |
|
|
385
|
+
| `bands` | — | `undefined \| number[]` | Pre-computed levels, 0..1. Set this and no AudioContext is ever built, which is what keeps headless/SSR rendering and browser-speech-synthesis playback (which exposes no audio node) free of Web Audio entirely. JS property only. A new array reference is required for each update; mutating the existing array in place will not re-render. NOTE: amplitude renders only while state is "speaking" unless listening-amplitude is set; every other state plays its scripted animation and ignores the audio. |
|
|
386
|
+
| `listeningAmplitude` | `listening-amplitude` | `undefined \| false \| true` | Render live amplitude during the listening state as well, using the same presentation as speaking. Off by default, which keeps LiveKit parity: amplitude from stream, audio-element or bands renders only while state is "speaking". Set it to show a real mic-level picture while the user is the one talking. Boolean. Attribute: `listening-amplitude` (a bare attribute means true; reflected, so the property reads back what the attribute set). |
|
|
384
387
|
| `shader` | — | `undefined \| { fragment: string; uniforms?: undefined \| Record<string, { type: "1f" \| "1i" \| "1fv" \| "2f" \| "3f" \| "3fv" \| "4f" \| "4fv" \| "Matrix2fv" \| "Matrix3fv" \| "Matrix4fv"; value: number \| number[] }> }` | Custom fragment shader for `variant="custom"`. JS property only. |
|
|
385
388
|
| `animateWhenNotVisible` | `animate-when-not-visible` | `undefined \| false \| true` | Shader variants only: keep animating while scrolled off screen. Off by default, which stops drawing and releases the WebGL context until the element comes back (browsers ration contexts to roughly 16 a page). Does not override `prefers-reduced-motion`. Attribute: `animate-when-not-visible`. |
|
|
386
389
|
|
|
@@ -602,7 +605,6 @@ _No events._
|
|
|
602
605
|
| Property | Attribute | Type | Description |
|
|
603
606
|
|---|---|---|---|
|
|
604
607
|
| `theme` | `theme` | `"light" \| "dark" \| "auto"` | Color mode (`auto` follows prefers-color-scheme). |
|
|
605
|
-
| `search` | `search` | `undefined \| false \| true` | Show a Search (Globe) button in the input toolbar; fires a `search` event. |
|
|
606
608
|
| `value` | — | `undefined \| string \| ({ type: "text"; text: string } \| { type: "entity"; entity: { kind: string; id: string; label: string; icon?: undefined \| string; promptText?: undefined \| string; data?: undefined \| Record<string, unknown> } })[]` | Value of the input. A **string** is controlled (the host owns the text and updates it on `kai-value-change`). A **ComposerDoc** is a one-time seed that pre-populates pills; the user then edits freely. Leave unset for uncontrolled. |
|
|
607
609
|
| `placeholder` | `placeholder` | `undefined \| string` | Placeholder text shown in the empty input. |
|
|
608
610
|
| `loading` | `loading` | `undefined \| false \| true` | When true, shows the loading/streaming state and disables submit (use while awaiting the assistant's reply). |
|
|
@@ -625,6 +627,7 @@ _No events._
|
|
|
625
627
|
| `composer` | `composer` | `undefined \| false \| true` | REPLACE: full custom composer in place of the built-in prompt input. The projected content wires its own submit (the data-flow boundary). |
|
|
626
628
|
| `composerActions` | `composer-actions` | `undefined \| false \| true` | INJECT: accessory row just above the composer (e.g. extra actions). |
|
|
627
629
|
| `footer` | `footer` | `undefined \| false \| true` | INJECT: footer row below the composer (disclaimers, token meter, …). |
|
|
630
|
+
| `webSearch` | `web-search` | `undefined \| false \| true` | Show a web-search (Globe) button in the input toolbar; calls `onWebSearch`. |
|
|
628
631
|
| `voice` | `voice` | `undefined \| false \| true` | Show a Voice (Mic) button in the input toolbar; fires a `voice` event. |
|
|
629
632
|
| `triggers` | — | `undefined \| { char: string; kind: string; items?: undefined \| { id: string; label: string; icon?: undefined \| string; description?: undefined \| string; group?: undefined \| string; kind?: undefined \| string; promptText?: undefined \| string; data?: undefined \| Record<string, unknown> }[] }[]` | Rich entity triggers. Each `{ char, kind, items }` opens a caret-anchored menu that inserts an atomic pill (`/` skills, `@` agents/plugins). Set as a JS property; forwarded to the input. |
|
|
630
633
|
| `kindIcons` | — | `undefined \| Record<string, string>` | Default icon per entity kind (kind → image src) for pills/menu items. |
|
|
@@ -642,11 +645,11 @@ _No events._
|
|
|
642
645
|
| `kai-attachments-rejected` | `CustomEvent<{ rejected: { filename: string; mediaType: string; reason: "filtered" \| "unsupported" }[] }>` | One or more picked files were refused because `accept` excluded them. The element renders NO message of its own: it reports the facts (name, media type, whether the kit could have sent it) and what the user should see is the application's call. Only ever fires when `accept` is set. |
|
|
643
646
|
| `kai-message-action` | `CustomEvent<{ messageId: string; action: string; state?: undefined \| "on" \| "off" }>` | An action button on a message was clicked. `action` is the built-in name or custom id. `state` is present only for the toggleable feedback votes: `'on'` when a like/dislike is set, `'off'` when re-tapped to clear. |
|
|
644
647
|
| `kai-model-change` | `CustomEvent<{ modelId: string }>` | The header model switcher changed. |
|
|
645
|
-
| `kai-search` | `CustomEvent<Record<string, never>>` | The Search button was clicked. |
|
|
646
648
|
| `kai-submit` | `CustomEvent<{ value: string; attachments: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }[] }>` | User submitted a message. |
|
|
647
649
|
| `kai-suggestion-click` | `CustomEvent<{ value: string }>` | A suggestion chip was clicked (only in `suggestion-mode="fill"`). |
|
|
648
650
|
| `kai-value-change` | `CustomEvent<{ value: string }>` | Fired on every input change. |
|
|
649
651
|
| `kai-voice` | `CustomEvent<Record<string, never>>` | The Mic / voice button was clicked. |
|
|
652
|
+
| `kai-web-search` | `CustomEvent<Record<string, never>>` | The web-search (Globe) toolbar button was clicked. |
|
|
650
653
|
|
|
651
654
|
**Methods** (call on the element instance: `document.querySelector('kai-chat').focus(…)`):
|
|
652
655
|
|
|
@@ -795,10 +798,17 @@ _No events._
|
|
|
795
798
|
| `language` | `language` | `undefined \| string` | Language grammar (e.g. `js`, `python`). Defaults to `tsx`. |
|
|
796
799
|
| `codeTheme` | `code-theme` | `undefined \| string` | Shiki theme name. |
|
|
797
800
|
| `codeHighlight` | `code-highlight` | `undefined \| false \| true` | Disable syntax highlighting (renders plain text, no Shiki). |
|
|
801
|
+
| `copy` | `copy` | `undefined \| false \| true` | Show the copy button. **Defaults to ON**, because this element is documented as shipping one. Opt out with `copy="false"` or `el.copy = false`. |
|
|
798
802
|
| `proseSize` | `prose-size` | `undefined \| "xs" \| "sm" \| "base" \| "lg"` | Code text sizing. |
|
|
799
803
|
|
|
800
804
|
_No events._
|
|
801
805
|
|
|
806
|
+
**Styleable parts** (restyle from outside via `kai-code-block::part(name)`):
|
|
807
|
+
|
|
808
|
+
| Part | Description |
|
|
809
|
+
|---|---|
|
|
810
|
+
| `::part(copy)` | The copy-to-clipboard button in the header row. Hide it with `copy="false"` rather than CSS. — `kai-code-block::part(copy) { color: var(--color-primary) }` |
|
|
811
|
+
|
|
802
812
|
---
|
|
803
813
|
|
|
804
814
|
### `kai-command` / `Command`
|
|
@@ -962,6 +972,41 @@ _No events._
|
|
|
962
972
|
|
|
963
973
|
---
|
|
964
974
|
|
|
975
|
+
### `kai-conversation-item` / `ConversationItem`
|
|
976
|
+
|
|
977
|
+
**Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
|
|
978
|
+
|
|
979
|
+
| Property | Attribute | Type | Description |
|
|
980
|
+
|---|---|---|---|
|
|
981
|
+
| `theme` | `theme` | `"light" \| "dark" \| "auto"` | Color mode (`auto` follows prefers-color-scheme). |
|
|
982
|
+
| `conversationId` | `conversation-id` | `undefined \| string` | The row's identity, handed to the container's selection contract. In the element this is the `conversation-id` attribute (host `id` is the fallback). |
|
|
983
|
+
| `active` | `active` | `undefined \| false \| true` | Selected state. Reflected as `aria-current` on the row body and a `data-active` styling hook on the row; the container drives it from its `activeId`. |
|
|
984
|
+
| `compact` | `compact` | `undefined \| false \| true` | Dense single-line row padding. |
|
|
985
|
+
|
|
986
|
+
_No events._
|
|
987
|
+
|
|
988
|
+
**Slots** (project your own markup via `slot="name"` on a light-DOM child):
|
|
989
|
+
|
|
990
|
+
| Slot | Mode | Description |
|
|
991
|
+
|---|---|---|
|
|
992
|
+
| _(default)_ | inject | The row title. `leading`, `meta` and `menu` are the named regions around it. |
|
|
993
|
+
| `leading` | inject | Leading region before the title (an icon or avatar). |
|
|
994
|
+
| `meta` | inject | Meta region under the title (a timestamp or status line). |
|
|
995
|
+
| `menu` | inject | Your own row menu (a popover trigger). Never selects the row. |
|
|
996
|
+
|
|
997
|
+
**Styleable parts** (restyle from outside via `kai-conversation-item::part(name)`):
|
|
998
|
+
|
|
999
|
+
| Part | Description |
|
|
1000
|
+
|---|---|
|
|
1001
|
+
| `::part(body)` | The activation surface inside the row (button role; carries aria-current and the roving tabindex). The focus ring paints here. — `kai-conversation-item::part(body) { outline-offset: 2px }` |
|
|
1002
|
+
| `::part(row)` | The whole row surface. Carries `data-active` while selected. — `kai-conversation-item::part(row) { border-radius: 0.5rem }` |
|
|
1003
|
+
| `::part(title)` | The title line (the default slot renders inside it). — `kai-conversation-item::part(title) { font-weight: 600 }` |
|
|
1004
|
+
| `::part(leading)` | Leading region before the title (an icon or avatar). |
|
|
1005
|
+
| `::part(meta)` | Meta region under the title (a timestamp or status line). |
|
|
1006
|
+
| `::part(menu)` | Your own row menu (a popover trigger). Never selects the row. |
|
|
1007
|
+
|
|
1008
|
+
---
|
|
1009
|
+
|
|
965
1010
|
### `kai-conversations` / `Conversations`
|
|
966
1011
|
|
|
967
1012
|
**Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
|
|
@@ -970,17 +1015,18 @@ _No events._
|
|
|
970
1015
|
|---|---|---|---|
|
|
971
1016
|
| `theme` | `theme` | `"light" \| "dark" \| "auto"` | Color mode (`auto` follows prefers-color-scheme). |
|
|
972
1017
|
| `groups` | — | `undefined \| { id: string; userId?: undefined \| string; teamId?: undefined \| string; name: string; sortOrder: number; createdAt: string }[]` | The list's section headers (`{ id, name, sortOrder, createdAt }`), rendered in array order. A group carries no conversations of its own; it is matched against `conversations` by id, so the two props are complementary rather than alternatives. Omit for an ungrouped list. Set as a JS property. |
|
|
973
|
-
| `conversations` | — | `undefined \| { id: string; title: string; groupId?: undefined \| string; scope
|
|
1018
|
+
| `conversations` | — | `undefined \| { id: string; title: string; groupId?: undefined \| string; scope?: undefined \| { type: "document" \| "collection"; documentId?: undefined \| string; filters?: undefined \| { tags?: undefined \| string[]; authors?: undefined \| string[]; contentType?: undefined \| "transcript" \| "markdown"; dateRange?: undefined \| { from: string; to: string } } }; messageCount: number; lastMessageAt?: undefined \| string; updatedAt: string; trailing?: undefined \| string }[]` | Every conversation the list renders, flat. Each one is filed under the group whose `id` equals its `groupId`; one with no `groupId`, or with a `groupId` matching no entry in `groups`, falls into a trailing "Ungrouped" section, so nothing you pass in is ever dropped. There is no recency bucketing. Set as a JS property. Omit to supply them as `<kai-conversation>` light-DOM children instead, or for the empty state. A search query that matches nothing shows a visible "No conversations match your search" state, distinct from the zero-conversations empty state. Slotted `<kai-conversation-item>` children switch the list into item mode instead: your own rows win and this array is not rendered. |
|
|
974
1019
|
| `activeId` | `active-id` | `undefined \| string` | The id of the currently-open conversation, highlighted in the list. |
|
|
975
1020
|
| `collapsed` | `collapsed` | `undefined \| false \| true` | Controlled collapsed state. Set as a JS property (`el.collapsed = true`) to drive the rail from your app, updating it in response to `kai-collapse-toggle`. Omit for uncontrolled (the element manages it). Collapsed shrinks the rail to a floating reopen button. |
|
|
976
1021
|
| `defaultCollapsed` | `default-collapsed` | `undefined \| false \| true` | Initial collapsed state when uncontrolled (default false). Use the `default-collapsed` attribute to start collapsed in plain HTML. |
|
|
1022
|
+
| `compact` | `compact` | `undefined \| false \| true` | Dense single-line rows (a leading dot + title, no message count). |
|
|
977
1023
|
|
|
978
1024
|
**Events** (non-bubbling `CustomEvent`s — listen directly on the element):
|
|
979
1025
|
|
|
980
1026
|
| Event | `detail` type | Description |
|
|
981
1027
|
|---|---|---|
|
|
982
1028
|
| `kai-collapse-toggle` | `CustomEvent<{ collapsed: false \| true }>` | The rail was collapsed or expanded (via the toggle, the reopen button, or a `collapse()`/`expand()`/`toggle()` call). |
|
|
983
|
-
| `kai-conversation-select` | `CustomEvent<{ id: string }>` | A conversation was selected. |
|
|
1029
|
+
| `kai-conversation-select` | `CustomEvent<{ id: string }>` | A conversation was selected. The selection event in BOTH modes: a batteries data row, or an activated `<kai-conversation-item>` child (click, Enter or Space). |
|
|
984
1030
|
| `kai-new-chat` | `CustomEvent<Record<string, never>>` | The "New chat" button was clicked. |
|
|
985
1031
|
| `kai-search` | `CustomEvent<{ query: string }>` | The built-in search box query changed (typing, or a programmatic `clear()` which fires it with `''`). Lets a consumer mirror or server-side the filter. |
|
|
986
1032
|
| `kai-toggle-sidebar` | `CustomEvent<Record<string, never>>` | The sidebar toggle was clicked. |
|
|
@@ -1000,6 +1046,7 @@ _No events._
|
|
|
1000
1046
|
|
|
1001
1047
|
| Slot | Mode | Description |
|
|
1002
1048
|
|---|---|---|
|
|
1049
|
+
| _(default)_ | inject | Your own `<kai-conversation-item>` rows (item mode: the consumer-owned loop). Data rows do not render while any are present. |
|
|
1003
1050
|
| `header` | replace | Full custom title bar; replaces the built-in toggle / "Chats" / New-chat row. |
|
|
1004
1051
|
| `empty` | replace | Custom zero-state shown when there are no conversations; replaces the built-in "No conversations yet". |
|
|
1005
1052
|
| `footer` | inject | A row below the list: account, settings, or usage. |
|
|
@@ -1008,13 +1055,14 @@ _No events._
|
|
|
1008
1055
|
|
|
1009
1056
|
| Child element | Attributes | Text content | Notes |
|
|
1010
1057
|
|---|---|---|---|
|
|
1011
|
-
| `<kai-conversation>` | `group-id`, `id` | yes | Parse a single light-DOM `<kai-conversation>` element into a `ConversationSummary`. Attribute mapping: - `id` → ConversationSummary.id - `group-id` → ConversationSummary.groupId (optional) - textContent → ConversationSummary.title
|
|
1058
|
+
| `<kai-conversation>` | `group-id`, `id` | yes | Parse a single light-DOM `<kai-conversation>` element into a `ConversationSummary`. Attribute mapping: - `id` → ConversationSummary.id - `group-id` → ConversationSummary.groupId (optional) - textContent → ConversationSummary.title Fields not expressible as HTML attributes are NOT fabricated (F-10): the optional `scope` and `lastMessageAt` stay absent, and the required `messageCount`/`updatedAt` get honest defaults — zero messages, and an empty `updatedAt` from which no trailing relative time is derived (the epoch it used to fabricate rendered a bogus "many days ago" on every declarative row). |
|
|
1012
1059
|
|
|
1013
1060
|
**Styleable parts** (restyle from outside via `kai-conversations::part(name)`):
|
|
1014
1061
|
|
|
1015
1062
|
| Part | Description |
|
|
1016
1063
|
|---|---|
|
|
1017
1064
|
| `::part(trailing)` | The right-aligned trailing text on each conversation row (a count, status, or relative time). Set it per item via the `trailing` field; otherwise a short auto relative time is derived from `updatedAt`. Recolor or resize it from outside. — `kai-conversations::part(trailing) { color: var(--color-primary); font-variant-numeric: tabular-nums }` |
|
|
1065
|
+
| `::part(items)` | The item-mode listbox region wrapping your slotted `<kai-conversation-item>` children. — `kai-conversations::part(items) { gap: 2px }` |
|
|
1018
1066
|
|
|
1019
1067
|
---
|
|
1020
1068
|
|
|
@@ -1027,6 +1075,7 @@ _No events._
|
|
|
1027
1075
|
| `theme` | `theme` | `"light" \| "dark" \| "auto"` | Color mode (`auto` follows prefers-color-scheme). |
|
|
1028
1076
|
| `open` | `open` | `undefined \| false \| true` | Drive/observe open state (Shoelace-style: settable + reflected to the `open` attribute; the element still self-manages on Escape/backdrop). Set `el.open = true`, or `<kai-dialog open>`; listen for `kai-open-change`. |
|
|
1029
1077
|
| `defaultOpen` | `default-open` | `undefined \| false \| true` | Initial open state on mount (uncontrolled seed). |
|
|
1078
|
+
| `label` | `label` | `undefined \| string` | Accessible name for the modal, used when no `header` slot is projected: `<kai-dialog label="Delete workspace">`. A projected `header` WINS over this (it becomes `aria-labelledby`), because ARIA resolves `aria-labelledby` ahead of `aria-label` and the visible heading is the name both a sighted and a screen-reader user can be talked through. Defaults to `Dialog` so a modal is never nameless. |
|
|
1030
1079
|
|
|
1031
1080
|
**Events** (non-bubbling `CustomEvent`s — listen directly on the element):
|
|
1032
1081
|
|
|
@@ -1063,6 +1112,96 @@ _No events._
|
|
|
1063
1112
|
|
|
1064
1113
|
---
|
|
1065
1114
|
|
|
1115
|
+
### `kai-dock` / `Dock`
|
|
1116
|
+
|
|
1117
|
+
**Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
|
|
1118
|
+
|
|
1119
|
+
| Property | Attribute | Type | Description |
|
|
1120
|
+
|---|---|---|---|
|
|
1121
|
+
| `theme` | `theme` | `"light" \| "dark" \| "auto"` | Color mode (`auto` follows prefers-color-scheme). |
|
|
1122
|
+
| `open` | `open` | `undefined \| false \| true` | Drive/observe open state (Shoelace-style: settable + reflected to the `open` attribute; the element still self-manages on the launcher and Escape). Set `el.open = true`, or `<kai-dock open>`; listen for `kai-open-change`. |
|
|
1123
|
+
| `defaultOpen` | `default-open` | `undefined \| false \| true` | Initial open state on mount (uncontrolled seed). |
|
|
1124
|
+
| `position` | `position` | `undefined \| "bottom-end" \| "bottom-start" \| "top-end" \| "top-start"` | Which corner the dock sits in. Logical, so `-end` follows the writing direction and an RTL page docks on the left. Attribute: `position`. |
|
|
1125
|
+
| `label` | `label` | `undefined \| string` | The widget's NAME. Derives the panel's accessible name and both launcher names (`Open ${label}` / `Close ${label}`). Defaults to `Chat`. |
|
|
1126
|
+
| `openLabel` | `open-label` | `undefined \| string` | i18n override for the launcher's name while closed (default `Open ${label}`). |
|
|
1127
|
+
| `closeLabel` | `close-label` | `undefined \| string` | i18n override for the launcher's name while open (default `Close ${label}`). |
|
|
1128
|
+
| `unread` | `unread` | `undefined \| false \| true` | Show the unread dot. YOURS: it renders only while closed, and the dock never writes it back. Clear it in your `kai-open-change` handler. |
|
|
1129
|
+
| `disabled` | `disabled` | `undefined \| false \| true` | Disable the launcher; `show()` and `toggle()` are gated on it. |
|
|
1130
|
+
| `focusOnOpen` | `focus-on-open` | `undefined \| "content" \| "panel" \| "none"` | Where focus lands on open: `content` (default, the first element you slotted), `panel`, or `none`. Attribute: `focus-on-open`. |
|
|
1131
|
+
|
|
1132
|
+
**Events** (non-bubbling `CustomEvent`s — listen directly on the element):
|
|
1133
|
+
|
|
1134
|
+
| Event | `detail` type | Description |
|
|
1135
|
+
|---|---|---|
|
|
1136
|
+
| `kai-open-change` | `CustomEvent<{ open: false \| true }>` | The dock opened or closed (the launcher, Escape, a driven `open`, or a method). |
|
|
1137
|
+
|
|
1138
|
+
**Methods** (call on the element instance: `document.querySelector('kai-dock').show()`):
|
|
1139
|
+
|
|
1140
|
+
| Method | Signature | Description |
|
|
1141
|
+
|---|---|---|
|
|
1142
|
+
| `show` | `(): void` | Open it programmatically (no-op while disabled). |
|
|
1143
|
+
| `hide` | `(): void` | Close it programmatically. |
|
|
1144
|
+
| `toggle` | `(): void` | Flip the open state (closes while disabled). |
|
|
1145
|
+
| `focus` | `(options?: FocusOptions): void` | Move focus to the panel while open, or to the launcher while closed. |
|
|
1146
|
+
|
|
1147
|
+
**Slots** (project your own markup via `slot="name"` on a light-DOM child):
|
|
1148
|
+
|
|
1149
|
+
| Slot | Mode | Description |
|
|
1150
|
+
|---|---|---|
|
|
1151
|
+
| _(default)_ | inject | The panel body, the same region as `slot="panel"`. |
|
|
1152
|
+
| `panel` | replace | The panel body. ANY element: a `<kai-chat>`, a form, your own component. The dock never reads or types it, and the default slot is the same region. |
|
|
1153
|
+
| `launcher` | inject | Content inside the built-in button while CLOSED; defaults to a chat glyph. Text works as well as an icon: the button keeps its height and grows sideways into a pill, so a label like "Support" is not clipped. The BUTTON is never slotted away, because it owns aria-expanded, aria-controls, the toggle wiring and the focus return. |
|
|
1154
|
+
| `launcher-open` | inject | Content inside the button while OPEN; defaults to a ✕. Fill only `launcher` and that glyph stays while open rather than morphing into a built-in that clashes with it. |
|
|
1155
|
+
|
|
1156
|
+
**Styleable parts** (restyle from outside via `kai-dock::part(name)`):
|
|
1157
|
+
|
|
1158
|
+
| Part | Description |
|
|
1159
|
+
|---|---|
|
|
1160
|
+
| `::part(launcher)` | The launcher button pinned to the corner: a disc by default, a pill once you slot a text label. Restyle its surface or shadow; --kai-dock-launcher-size sets its height and its minimum width. — `kai-dock::part(launcher) { background: var(--color-info) }` |
|
|
1161
|
+
| `::part(badge)` | The unread dot on the launcher, rendered only while closed and only when `unread` is set. Restyle its color or size. — `kai-dock::part(badge) { background: var(--color-success) }` |
|
|
1162
|
+
| `::part(panel)` | The panel body. ANY element: a `<kai-chat>`, a form, your own component. The dock never reads or types it, and the default slot is the same region. |
|
|
1163
|
+
|
|
1164
|
+
---
|
|
1165
|
+
|
|
1166
|
+
### `kai-dropdown` / `Dropdown`
|
|
1167
|
+
|
|
1168
|
+
**Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
|
|
1169
|
+
|
|
1170
|
+
| Property | Attribute | Type | Description |
|
|
1171
|
+
|---|---|---|---|
|
|
1172
|
+
| `theme` | `theme` | `"light" \| "dark" \| "auto"` | Color mode (`auto` follows prefers-color-scheme). |
|
|
1173
|
+
| `triggerIcon` | `trigger-icon` | `undefined \| string` | Built-in trigger: leading icon (a named icon like `"plus"`, an image URL/data-URI, or text). A slotted `slot="trigger"` overrides it. |
|
|
1174
|
+
| `triggerLabel` | `trigger-label` | `undefined \| string` | Built-in trigger: a text label. This is the trigger's VISIBLE text, so it is also its accessible name, and `label` does not override it: an accessible name that does not contain the visible text is unreachable by speech input (WCAG 2.5.3, Label in Name). Same rule `kai-menu` follows. |
|
|
1175
|
+
| `triggerIconTrailing` | `trigger-icon-trailing` | `undefined \| string` | Built-in trigger: a trailing icon (e.g. `"chevron-down"` for a select look). |
|
|
1176
|
+
| `label` | `label` | `undefined \| string` | Accessible name for a trigger with no visible label. Ignored when `triggerLabel` is set, which is already the visible name. It DOES name a slotted `slot="trigger"`, which is VISUAL content with the name supplied separately: the same two-slot distinction `kai-menu` documents. |
|
|
1177
|
+
| `full` | `full` | `undefined \| false \| true` | Stretch the trigger to the full width of its container (a block row). Attribute: `full`. |
|
|
1178
|
+
| `open` | `open` | `undefined \| false \| true` | Drive/observe open state (Shoelace-style: settable + reflected to the `open` attribute, the menu still self-manages on click/keyboard). Set `el.open = true`, or `<kai-dropdown open>`; listen for `kai-open-change`. |
|
|
1179
|
+
| `defaultOpen` | `default-open` | `undefined \| false \| true` | Initial open state on mount (uncontrolled seed). |
|
|
1180
|
+
| `disabled` | `disabled` | `undefined \| false \| true` | Disable the trigger: click/keyboard and `show()` no longer open the menu. |
|
|
1181
|
+
|
|
1182
|
+
**Events** (non-bubbling `CustomEvent`s — listen directly on the element):
|
|
1183
|
+
|
|
1184
|
+
| Event | `detail` type | Description |
|
|
1185
|
+
|---|---|---|
|
|
1186
|
+
| `kai-open-change` | `CustomEvent<{ open: false \| true }>` | The menu opened or closed (click, keyboard, Escape, outside-click, or a method). |
|
|
1187
|
+
|
|
1188
|
+
**Methods** (call on the element instance: `document.querySelector('kai-dropdown').show()`):
|
|
1189
|
+
|
|
1190
|
+
| Method | Signature | Description |
|
|
1191
|
+
|---|---|---|
|
|
1192
|
+
| `show` | `(): void` | Open it programmatically (no-op while disabled). |
|
|
1193
|
+
| `hide` | `(): void` | Close it programmatically. |
|
|
1194
|
+
| `toggle` | `(): void` | Flip the open state (closes while disabled). |
|
|
1195
|
+
|
|
1196
|
+
**Slots** (project your own markup via `slot="name"` on a light-DOM child):
|
|
1197
|
+
|
|
1198
|
+
| Slot | Mode | Description |
|
|
1199
|
+
|---|---|---|
|
|
1200
|
+
| _(default)_ | inject | The menu body: your own rows. Give each `role="menuitem"`. The control that opens it is the `trigger` slot. |
|
|
1201
|
+
| `trigger` | replace | Visual content of the trigger button (an icon, text, an `<svg>`). Replaces the built-in trigger* content; name it with `label`. |
|
|
1202
|
+
|
|
1203
|
+
---
|
|
1204
|
+
|
|
1066
1205
|
### `kai-editable-label` / `EditableLabel`
|
|
1067
1206
|
|
|
1068
1207
|
**Properties** (every element also accepts `theme="light|dark|auto"`; only scalar props work as HTML attributes):
|
|
@@ -1462,6 +1601,7 @@ _No events._
|
|
|
1462
1601
|
| `triggerLabel` | `trigger-label` | `undefined \| string` | Built-in trigger: a text label (e.g. `"High"`). This is the trigger's VISIBLE text, so it is also its accessible name, and `label` does not override it: an accessible name that does not contain the visible text is unreachable by speech input, which is what WCAG 2.5.3 (Label in Name) exists for. A slotted `slot="trigger"` replaces this built-in trigger entirely and is named differently; see `label`. |
|
|
1463
1602
|
| `triggerIconTrailing` | `trigger-icon-trailing` | `undefined \| string` | Built-in trigger: a trailing icon (e.g. `"chevron-down"` for a select look). |
|
|
1464
1603
|
| `label` | `label` | `undefined \| string` | Accessible name for a trigger with no visible label. Ignored when `triggerLabel` is set, which is already the visible name. It DOES name a slotted `slot="trigger"`, and that is a difference in what the two slots MEAN, not a limitation. `<kai-button>`'s slot IS the button's label, so text slotted there is the name and `label` steps aside. This slot is VISUAL content, a `+` or an `<svg>`, with the name supplied separately: decoration beside a name, never a second name competing with one. So `label` names the trigger here by design. Slotting a real WORD rather than a glyph makes that word a visible label, and an accessible name has to contain the visible text. Then either drop `label` or make it contain the word you slotted. |
|
|
1604
|
+
| `full` | `full` | `undefined \| false \| true` | Stretch the trigger to the full width of the menu's container (a block row), e.g. a sidebar-footer account row. Same affordance as `<kai-button full>`. Attribute: `full`. |
|
|
1465
1605
|
| `open` | `open` | `undefined \| false \| true` | Drive/observe open state (Shoelace-style: settable + reflected to the `open` attribute, the menu still self-manages on click/keyboard). Set `el.open = true`, or `<kai-menu open>`; listen for `kai-open-change`. |
|
|
1466
1606
|
| `defaultOpen` | `default-open` | `undefined \| false \| true` | Initial open state on mount (uncontrolled seed). |
|
|
1467
1607
|
| `disabled` | `disabled` | `undefined \| false \| true` | Disable the trigger: click/keyboard and `show()` no longer open the menu. |
|
|
@@ -1550,6 +1690,8 @@ _No events._
|
|
|
1550
1690
|
| `::part(content)` | The rendered message text/markdown region (same node as `bubble`). Target it to tune typography from outside. — `kai-message::part(content) { font-size: 0.9375rem }` |
|
|
1551
1691
|
| `::part(actions)` | The action-bar row (copy / like / regenerate …). Restyle its spacing or hide it entirely from outside. — `kai-message::part(actions) { gap: 0.25rem }` |
|
|
1552
1692
|
| `::part(citations)` | The citation row rendered from the message’s `source` parts: a wrapped row of chips below the bubble, never inside it. Restyle its spacing or hide it entirely from outside. — `kai-message::part(citations) { gap: 0.5rem }` |
|
|
1693
|
+
| `::part(attachment)` | One attachment item: the chip, row or tile, whichever variant is rendering. Restyle its background, radius or border from outside without caring which layout it is. — `kai-chat::part(attachment) { border-radius: 0.25rem }` |
|
|
1694
|
+
| `::part(attachment-name)` | The attachment’s filename label. Present in every variant that shows one (a grid tile omits it for an image, which is its own label). Retune its type or hide it entirely. — `kai-chat::part(attachment-name) { font-size: 0.75rem }` |
|
|
1553
1695
|
| `::part(avatar)` | Replaces the built-in avatar rail with your own node. Use `avatar="none"` to omit the rail and let the body span the full row. |
|
|
1554
1696
|
|
|
1555
1697
|
---
|
|
@@ -1847,7 +1989,7 @@ _No events._
|
|
|
1847
1989
|
| `loading` | `loading` | `undefined \| false \| true` | Show the loading/streaming state and block submit (use while awaiting a reply). |
|
|
1848
1990
|
| `suggestions` | — | `undefined \| string[]` | Starter prompts shown above the input. Clicking one follows `suggestionMode`. Set as a JS property. |
|
|
1849
1991
|
| `suggestionMode` | `suggestion-mode` | `undefined \| "submit" \| "fill"` | What clicking a suggestion does: `'submit'` (default) sends it immediately as if typed and submitted; `'fill'` just places it in the input. |
|
|
1850
|
-
| `
|
|
1992
|
+
| `webSearch` | `web-search` | `undefined \| false \| true` | Show a web-search (Globe) button in the left toolbar; clicking it fires a `kai-web-search` event. Attribute: `web-search`. |
|
|
1851
1993
|
| `voice` | `voice` | `undefined \| false \| true` | Show a Voice (Mic) button in the left toolbar; clicking it fires a `voice` event. |
|
|
1852
1994
|
| `stoppable` | `stoppable` | `undefined \| false \| true` | When set and `loading` is true, the send button is replaced by a Stop button (square icon, "Stop" aria-label). Clicking it fires `kai-stop`. |
|
|
1853
1995
|
| `submit` | `submit` | `undefined \| "always" \| "auto"` | Send-button visibility. `'always'` (default) always shows it; `'auto'` shows it only when there's text/attachments (an empty composer hides it, though Enter still submits). To hide it entirely (Enter-only), it's pure CSS: `::part(send){display:none}`, no prop needed. Restyle via `::part(send)`. The Stop button (`stoppable` + `loading`) is unaffected. |
|
|
@@ -1861,13 +2003,13 @@ _No events._
|
|
|
1861
2003
|
| Event | `detail` type | Description |
|
|
1862
2004
|
|---|---|---|
|
|
1863
2005
|
| `kai-attachments-change` | `CustomEvent<{ attachments: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }[] }>` | The staged attachments changed: a file was added (via the paperclip) or removed (per-chip ×). Carries the full current list so a consumer can react in real time (validate, show upload progress, toggle the send button). |
|
|
1864
|
-
| `kai-search` | `CustomEvent<Record<string, never>>` | The Search (Globe) toolbar button was clicked. |
|
|
1865
2006
|
| `kai-stop` | `CustomEvent<Record<string, never>>` | The Stop button was clicked while `stoppable` and `loading` are both true. |
|
|
1866
2007
|
| `kai-submit` | `CustomEvent<{ value: string; doc: ({ type: "text"; text: string } \| { type: "entity"; entity: { kind: string; id: string; label: string; icon?: undefined \| string; promptText?: undefined \| string; data?: undefined \| Record<string, unknown> } })[]; entities: { kind: string; id: string; label: string; icon?: undefined \| string; promptText?: undefined \| string; data?: undefined \| Record<string, unknown> }[]; attachments: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }[] }>` | The user submitted the prompt (Enter or send button). `value` is the flattened text (back-compat); `doc` is the structured document and `entities` the inserted pills (skills/agents) for downstream expansion. |
|
|
1867
2008
|
| `kai-suggestion-click` | `CustomEvent<{ value: string }>` | A suggestion was clicked while `suggestion-mode="fill"`. |
|
|
1868
2009
|
| `kai-toolbar-action` | `CustomEvent<{ action: string }>` | A custom `<kai-action>` toolbar button was clicked. `action` is the `id` of the `<kai-action>` element that was clicked. |
|
|
1869
2010
|
| `kai-value-change` | `CustomEvent<{ value: string; doc: ({ type: "text"; text: string } \| { type: "entity"; entity: { kind: string; id: string; label: string; icon?: undefined \| string; promptText?: undefined \| string; data?: undefined \| Record<string, unknown> } })[]; entities: { kind: string; id: string; label: string; icon?: undefined \| string; promptText?: undefined \| string; data?: undefined \| Record<string, unknown> }[] }>` | The input changed (fires on every edit). Carries the flattened `value` plus the structured `doc` + `entities`. |
|
|
1870
2011
|
| `kai-voice` | `CustomEvent<Record<string, never>>` | The Voice (Mic) toolbar button was clicked. |
|
|
2012
|
+
| `kai-web-search` | `CustomEvent<Record<string, never>>` | The web-search (Globe) toolbar button was clicked. |
|
|
1871
2013
|
|
|
1872
2014
|
**Methods** (call on the element instance: `document.querySelector('kai-prompt-input').focus(…)`):
|
|
1873
2015
|
|
|
@@ -2703,6 +2845,7 @@ _No events._
|
|
|
2703
2845
|
| `kai-recording-change` | `CustomEvent<{ recording: false \| true }>` | Recording started or stopped. Lets the host drive its own UI (waveform, push-to-talk indicator) in sync with the mic. Fires on real transitions only (manual click and programmatic start()/stop()), never on mount. |
|
|
2704
2846
|
| `kai-transcript-interim` | `CustomEvent<{ text: string }>` | Live partial transcript during native recognition (only when `interim` is set). Fires repeatedly before the final `kai-transcription`. |
|
|
2705
2847
|
| `kai-transcription` | `CustomEvent<{ text: string }>` | Final transcript: the `transcribe` property resolved, OR native `SpeechRecognition` produced final text (no `transcribe` set). |
|
|
2848
|
+
| `kai-voice-error` | `CustomEvent<{ source: "recognition"; error: string; message: string }>` | A voice session failed, so no failure is ever silent. `detail.source` names the failing side (`recognition` on `<kai-voice-input>`, `synthesis` on `<kai-voice-output>`), `detail.error` carries the platform error code, the thrown exception's name, or `no-result` when recognition ended with no error and no text (the user said nothing), and `detail.message` is human-readable. Deliberate cancellation does not fire. |
|
|
2706
2849
|
|
|
2707
2850
|
**Methods** (call on the element instance: `document.querySelector('kai-voice-input').start()`):
|
|
2708
2851
|
|
|
@@ -2729,8 +2872,9 @@ _No events._
|
|
|
2729
2872
|
|
|
2730
2873
|
| Event | `detail` type | Description |
|
|
2731
2874
|
|---|---|---|
|
|
2732
|
-
| `kai-speaking-change` | `CustomEvent<{ speaking: false \| true }>` | Playback started or stopped. Drive your own UI in sync. Fires on real transitions only (manual click and programmatic speak()/stop()), never on mount. |
|
|
2875
|
+
| `kai-speaking-change` | `CustomEvent<{ speaking: false \| true }>` | Playback started or stopped. Drive your own UI in sync. `speaking: true` fires when audio actually starts (utterance.onstart natively; audio playback beginning on the `synthesize` path), not when speak() is called; earlier releases fired it optimistically inside speak() itself. Fires on real transitions only (manual click and programmatic speak()/stop()), never on mount. |
|
|
2733
2876
|
| `kai-synthesized` | `CustomEvent<{ blob: Blob }>` | The model path (`synthesize`) resolved audio: the raw `Blob` before playback. |
|
|
2877
|
+
| `kai-voice-error` | `CustomEvent<{ source: "synthesis"; error: string; message: string }>` | A voice session failed, so no failure is ever silent. `detail.source` names the failing side (`recognition` on `<kai-voice-input>`, `synthesis` on `<kai-voice-output>`), `detail.error` carries the platform error code, the thrown exception's name, or `no-result` when recognition ended with no error and no text (the user said nothing), and `detail.message` is human-readable. Deliberate cancellation does not fire. |
|
|
2734
2878
|
|
|
2735
2879
|
**Methods** (call on the element instance: `document.querySelector('kai-voice-output').speak()`):
|
|
2736
2880
|
|
|
@@ -2756,79 +2900,50 @@ _No events._
|
|
|
2756
2900
|
| Property | Attribute | Type | Description |
|
|
2757
2901
|
|---|---|---|---|
|
|
2758
2902
|
| `theme` | `theme` | `"light" \| "dark" \| "auto"` | Color mode (`auto` follows prefers-color-scheme). |
|
|
2759
|
-
| `
|
|
2760
|
-
| `
|
|
2761
|
-
| `
|
|
2762
|
-
| `
|
|
2763
|
-
| `
|
|
2764
|
-
| `
|
|
2765
|
-
| `
|
|
2766
|
-
| `suggestions` | — | `undefined \| string[]` | |
|
|
2767
|
-
| `suggestionMode` | `suggestion-mode` | `undefined \| "submit" \| "fill"` | |
|
|
2768
|
-
| `proseSize` | `prose-size` | `undefined \| "xs" \| "sm" \| "base" \| "lg"` | |
|
|
2769
|
-
| `codeTheme` | `code-theme` | `undefined \| string` | |
|
|
2770
|
-
| `codeHighlight` | `code-highlight` | `undefined \| false \| true` | |
|
|
2771
|
-
| `chatTitle` | `chat-title` | `undefined \| string` | |
|
|
2772
|
-
| `models` | — | `undefined \| { id: string; name: string; provider?: undefined \| string; description?: undefined \| string; group?: undefined \| string }[]` | |
|
|
2773
|
-
| `currentModel` | `current-model` | `undefined \| string` | |
|
|
2774
|
-
| `context` | — | `undefined \| { usedTokens: number; maxTokens: number; inputTokens?: undefined \| number; outputTokens?: undefined \| number; estimatedCost?: undefined \| number }` | |
|
|
2775
|
-
| `scrollButton` | `scroll-button` | `undefined \| false \| true` | |
|
|
2776
|
-
| `search` | `search` | `undefined \| false \| true` | |
|
|
2777
|
-
| `voice` | `voice` | `undefined \| false \| true` | |
|
|
2778
|
-
| `triggers` | — | `undefined \| { char: string; kind: string; items?: undefined \| { id: string; label: string; icon?: undefined \| string; description?: undefined \| string; group?: undefined \| string; kind?: undefined \| string; promptText?: undefined \| string; data?: undefined \| Record<string, unknown> }[] }[]` | Rich entity triggers (`/` skills, `@` agents/plugins) forwarded to the input. |
|
|
2779
|
-
| `kindIcons` | — | `undefined \| Record<string, string>` | Default icon per entity kind (kind → image src) forwarded to the input. |
|
|
2780
|
-
| `sidebarWidth` | `sidebar-width` | `undefined \| number` | Sidebar default width as a percent of the workspace (default 26). |
|
|
2781
|
-
| `sidebarMinWidth` | `sidebar-min-width` | `undefined \| number` | Sidebar min width in px (default 240). |
|
|
2782
|
-
| `sidebarMaxWidth` | `sidebar-max-width` | `undefined \| number` | Sidebar max width in px (default 420). |
|
|
2783
|
-
| `sidebarCollapsed` | `sidebar-collapsed` | `undefined \| false \| true` | Controlled collapsed state. Set this as a JS property (`el.sidebarCollapsed = true`) to drive the sidebar from your app, updating it in response to the `kai-sidebar-toggle` event. Omit for uncontrolled (the element manages it). |
|
|
2784
|
-
| `defaultSidebarCollapsed` | `default-sidebar-collapsed` | `undefined \| false \| true` | Initial collapsed state when uncontrolled (default false). Use the `default-sidebar-collapsed` attribute to start collapsed in plain HTML. |
|
|
2785
|
-
| `collapseBelow` | `collapse-below` | `undefined \| number` | Auto-collapse the rail when the workspace's own width drops below this many px, and re-expand when it grows back above. Uncontrolled only (it never fights an app-driven `sidebarCollapsed`); omit to disable. Fires `kai-sidebar-toggle`. Attribute: `collapse-below`. |
|
|
2786
|
-
| `compact` | `compact` | `undefined \| false \| true` | Render Recents as dense single-line rows (a leading dot + title, no count). |
|
|
2787
|
-
| `noConversations` | `no-conversations` | `undefined \| false \| true` | Suppress the built-in ConversationList so the `sidebar-header` slot owns the whole rail flex region (for apps that supply their own rail nav). Default false. Attribute: `no-conversations`. |
|
|
2788
|
-
| `cardTypes` | — | `undefined \| Record<string, string>` | Optional card type -> custom-element tag overrides/additions for `card` parts (merged over the built-ins). Property: `el.cardTypes`. Typed as a plain string map (not the `CardTagMap` alias) so the generated React wrapper inlines it instead of emitting an unresolved named type. |
|
|
2789
|
-
| `cardSchemas` | — | `undefined \| Record<string, object>` | JSON Schemas for the card types this app renders, keyed by envelope type. The companion of `cardTypes`, which says what DRAWS a card while this says what a VALID one looks like. An OBJECT, so it is a JS property only: `el.cardSchemas = { 'pricing-table': pricingSchema }`, never an attribute. `createCardRegistry(...).validationSchemas` is exactly this shape. Without it the kit validates its own seven built-ins and leaves your own card type, the one your app actually cares about, as the only unchecked thing on screen. A schema here WINS over a built-in of the same name. Typed `Record<string, object>` rather than `Record<string, JsonSchema>` deliberately: an imported `.json` schema widens `"type"` to `string`, and an authored one carries `$schema`/`title`/`description`/`additionalProperties`, so the tighter type would reject both of the normal ways to supply one. |
|
|
2903
|
+
| `startCollapsed` | `start-collapsed` | `undefined \| false \| true` | Controlled collapsed state of the start aside. Set this as a JS property (`el.startCollapsed = true`) to drive the aside from your app, updating it in response to the `kai-aside-toggle` event. Omit for uncontrolled (the element manages it). |
|
|
2904
|
+
| `defaultStartCollapsed` | `default-start-collapsed` | `undefined \| false \| true` | Initial collapsed state of the start aside when uncontrolled (default false). Use the `default-start-collapsed` attribute to start collapsed in plain HTML. |
|
|
2905
|
+
| `endCollapsed` | `end-collapsed` | `undefined \| false \| true` | Controlled collapsed state of the end aside. Set this as a JS property (`el.endCollapsed = true`) to drive the aside from your app, updating it in response to the `kai-aside-toggle` event. Omit for uncontrolled (the element manages it). |
|
|
2906
|
+
| `defaultEndCollapsed` | `default-end-collapsed` | `undefined \| false \| true` | Initial collapsed state of the end aside when uncontrolled (default false). Use the `default-end-collapsed` attribute to start collapsed in plain HTML. |
|
|
2907
|
+
| `collapseBelow` | `collapse-below` | `undefined \| number` | Auto-collapse both asides when the shell's own width drops below this many px, and re-expand when it grows back above. Applies to uncontrolled asides only (it never fights an app-driven collapsed prop); omit to disable. Fires `kai-aside-toggle`. Attribute: `collapse-below`. |
|
|
2908
|
+
| `drawerBelow` | `drawer-below` | `undefined \| number` | Below this shell width in px, an expanded aside renders as an overlay drawer over the main region instead of a column beside it. Escape inside the drawer closes it and returns focus to the element focused before it opened. Omit to disable. Attribute: `drawer-below`. |
|
|
2909
|
+
| `compact` | `compact` | `undefined \| false \| true` | Density hint. Reflected as a `data-compact` hook on the root (and as the `compact` attribute on the element) for your CSS and slotted content; the shell itself keeps no other opinion about density. |
|
|
2790
2910
|
|
|
2791
2911
|
**Events** (non-bubbling `CustomEvent`s — listen directly on the element):
|
|
2792
2912
|
|
|
2793
2913
|
| Event | `detail` type | Description |
|
|
2794
2914
|
|---|---|---|
|
|
2795
|
-
| `kai-
|
|
2796
|
-
| `kai-
|
|
2797
|
-
| `kai-model-change` | `CustomEvent<{ modelId: string }>` | The header model switcher changed. |
|
|
2798
|
-
| `kai-new-chat` | `CustomEvent<Record<string, never>>` | The "New chat" button was clicked. |
|
|
2799
|
-
| `kai-search` | `CustomEvent<Record<string, never>>` | The Search button was clicked. |
|
|
2800
|
-
| `kai-sidebar-toggle` | `CustomEvent<{ collapsed: false \| true }>` | The sidebar was collapsed or expanded. |
|
|
2801
|
-
| `kai-submit` | `CustomEvent<{ value: string; attachments: { id: string; type: "file" \| "source-document"; filename?: undefined \| string; mediaType?: undefined \| string; url?: undefined \| string; title?: undefined \| string }[] }>` | User submitted a message. |
|
|
2802
|
-
| `kai-suggestion-click` | `CustomEvent<{ value: string }>` | A suggestion chip was clicked (only in `suggestion-mode="fill"`). |
|
|
2803
|
-
| `kai-value-change` | `CustomEvent<{ value: string }>` | Fired on every input change. |
|
|
2804
|
-
| `kai-voice` | `CustomEvent<Record<string, never>>` | The Mic / voice button was clicked. |
|
|
2915
|
+
| `kai-aside-resize` | `CustomEvent<{ side: "start" \| "end"; width: number }>` | The aside was resized (fires per drag step, keyboard nudge, or a handle double-click reset), width in px. |
|
|
2916
|
+
| `kai-aside-toggle` | `CustomEvent<{ side: "start" \| "end"; collapsed: false \| true }>` | An aside collapsed or expanded (a method, the breakpoint, the drawer's Escape). |
|
|
2805
2917
|
|
|
2806
|
-
**Methods** (call on the element instance: `document.querySelector('kai-workspace').
|
|
2918
|
+
**Methods** (call on the element instance: `document.querySelector('kai-workspace').toggleAside(…)`):
|
|
2807
2919
|
|
|
2808
2920
|
| Method | Signature | Description |
|
|
2809
2921
|
|---|---|---|
|
|
2810
|
-
| `
|
|
2811
|
-
| `
|
|
2812
|
-
| `
|
|
2813
|
-
| `focus` | `(options?: FocusOptions): void` | Focus the thread's composer. |
|
|
2814
|
-
| `clear` | `(): void` | Clear the thread draft + staged attachments. |
|
|
2815
|
-
| `send` | `(): void` | Submit the current thread draft programmatically (fires `kai-submit`). |
|
|
2816
|
-
| `scrollToBottom` | `(behavior?: ScrollBehavior): void` | Scroll the thread to the newest message. |
|
|
2922
|
+
| `toggleAside` | `(side: WorkspaceAsideSide): void` | Collapse/expand one aside (fires `kai-aside-toggle`). |
|
|
2923
|
+
| `collapseAside` | `(side: WorkspaceAsideSide): void` | Force one aside collapsed (fires `kai-aside-toggle`). |
|
|
2924
|
+
| `expandAside` | `(side: WorkspaceAsideSide): void` | Force one aside expanded (fires `kai-aside-toggle`). |
|
|
2817
2925
|
|
|
2818
2926
|
**Slots** (project your own markup via `slot="name"` on a light-DOM child):
|
|
2819
2927
|
|
|
2820
2928
|
| Slot | Mode | Description |
|
|
2821
2929
|
|---|---|---|
|
|
2822
|
-
|
|
|
2823
|
-
| `
|
|
2824
|
-
| `
|
|
2825
|
-
| `main` |
|
|
2930
|
+
| _(default)_ | inject | The main region content (same region as the `main` slot): your `<kai-chat>`, or any app view. |
|
|
2931
|
+
| `header` | inject | The top band across the full shell width (app bar, tabs, breadcrumbs). |
|
|
2932
|
+
| `start` | inject | The inline-start aside column (a conversation rail, a nav, a file tree). Resizable and collapsible. |
|
|
2933
|
+
| `main` | inject | The main region. Unnamed children project here too, via the default slot. |
|
|
2934
|
+
| `end` | inject | The inline-end aside column (inspector, notes, preview). Resizable and collapsible. |
|
|
2935
|
+
| `footer` | inject | The bottom band across the full shell width (status bar, disclaimers). |
|
|
2826
2936
|
|
|
2827
2937
|
**Styleable parts** (restyle from outside via `kai-workspace::part(name)`):
|
|
2828
2938
|
|
|
2829
2939
|
| Part | Description |
|
|
2830
2940
|
|---|---|
|
|
2831
|
-
| `::part(
|
|
2941
|
+
| `::part(aside)` | Both aside columns match this part (each also matches its own start/end part). Restyle the shared aside surface or border from outside; the --kai-workspace-start-* and --kai-workspace-end-* custom properties set the widths. — `kai-workspace::part(aside) { background: var(--color-card) }` |
|
|
2942
|
+
| `::part(header)` | The top band across the full shell width (app bar, tabs, breadcrumbs). |
|
|
2943
|
+
| `::part(start)` | The inline-start aside column (a conversation rail, a nav, a file tree). Resizable and collapsible. |
|
|
2944
|
+
| `::part(main)` | The main region. Unnamed children project here too, via the default slot. |
|
|
2945
|
+
| `::part(end)` | The inline-end aside column (inspector, notes, preview). Resizable and collapsible. |
|
|
2946
|
+
| `::part(footer)` | The bottom band across the full shell width (status bar, disclaimers). |
|
|
2832
2947
|
|
|
2833
2948
|
---
|
|
2834
2949
|
|
package/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- AUTO-GENERATED by scripts/gen-llms.mjs — do not edit by hand. Run `npm run build`. -->
|
|
2
2
|
# @kitn.ai/ui
|
|
3
3
|
|
|
4
|
-
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML.
|
|
4
|
+
> Framework-agnostic, Shadow-DOM web components for building AI chat interfaces — works in React, Vue, Angular, Svelte, or plain HTML. 83 custom elements, every one prefixed `kai-` (e.g. `<kai-chat>`, `<kai-artifact>`): streaming responses, markdown + code rendering, reasoning/tool panels, attachments, conversation sidebar, voice input. Zero framework dependency for consumers; the SolidJS runtime it is authored in is bundled in, so the host needs nothing.
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
@@ -35,7 +35,7 @@ Drop an element into any framework (React, Vue, plain HTML). Data in via JS prop
|
|
|
35
35
|
- `<kai-prompt-input>` — standalone composer with send button.
|
|
36
36
|
|
|
37
37
|
**Layer 2 — composable primitives** (`import { … } from '@kitn.ai/ui'`):
|
|
38
|
-
All
|
|
38
|
+
All 83 elements are also exported individually. Use them for custom layouts or features `<kai-chat>` does not expose (ChainOfThought, FeedbackBar, ThinkingBar, VoiceInput, …). Your bundler tree-shakes the rest.
|
|
39
39
|
|
|
40
40
|
## Key rules for the web components
|
|
41
41
|
|
|
@@ -149,7 +149,7 @@ For Tailwind builds: `@import "@kitn.ai/ui/theme.css"` in your CSS.
|
|
|
149
149
|
|
|
150
150
|
## Docs
|
|
151
151
|
|
|
152
|
-
- Full element reference (all
|
|
152
|
+
- Full element reference (all 83 elements, every prop/event): ./llms-full.txt — https://kitn.dev/llms-full.txt
|
|
153
153
|
- Machine-readable Custom Elements Manifest: https://unpkg.com/@kitn.ai/ui/dist/custom-elements.json
|
|
154
154
|
- Working examples: https://github.com/kitn-ai/ui/tree/main/examples
|
|
155
155
|
- Storybook: https://storybook.kitn.dev
|