@kitn.ai/ui 0.17.0 → 0.18.1
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 +28 -5
- package/dist/components/artifact.d.ts +39 -1
- package/dist/components/attachment-types.d.ts +12 -0
- package/dist/components/attachments.d.ts +2 -10
- package/dist/components/card.d.ts +27 -0
- package/dist/components/chain-of-thought.d.ts +78 -2
- package/dist/components/chat-scope-picker.d.ts +7 -0
- package/dist/components/chat-thread.d.ts +37 -12
- package/dist/components/choice-card.d.ts +26 -0
- package/dist/components/coachmark.d.ts +49 -0
- package/dist/components/composer-dom.d.ts +35 -0
- package/dist/components/composer-highlight.d.ts +48 -0
- package/dist/components/composer-history.d.ts +34 -0
- package/dist/components/composer.d.ts +86 -0
- package/dist/components/confirm-card.d.ts +17 -0
- package/dist/components/conversation-item.d.ts +9 -0
- package/dist/components/conversation-list.d.ts +36 -1
- package/dist/components/file-tree.d.ts +15 -0
- package/dist/components/form.d.ts +34 -0
- package/dist/components/markdown.d.ts +3 -0
- package/dist/components/message.d.ts +12 -0
- package/dist/components/model-switcher.d.ts +7 -0
- package/dist/components/prompt-input.d.ts +13 -4
- package/dist/components/prompt-suggestion.d.ts +9 -1
- package/dist/components/reasoning.d.ts +14 -1
- package/dist/components/response-compare.d.ts +14 -0
- package/dist/components/screen.d.ts +46 -0
- package/dist/components/tasks-card.d.ts +49 -1
- package/dist/components/toast.d.ts +12 -2
- package/dist/components/tool-types.d.ts +10 -0
- package/dist/components/tool.d.ts +8 -8
- package/dist/components/voice-input.d.ts +27 -0
- package/dist/components/voice-output.d.ts +33 -0
- package/dist/core-C8fzo39E.js +12 -0
- package/dist/custom-elements.json +8392 -1860
- package/dist/elements/agent-card.d.ts +1 -0
- package/dist/elements/agent-card.js +1 -0
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/autoloader.js +1 -1
- package/dist/elements/avatar.d.ts +1 -0
- package/dist/elements/avatar.js +1 -0
- package/dist/elements/badge.d.ts +1 -0
- package/dist/elements/badge.js +1 -0
- package/dist/elements/button.d.ts +1 -0
- package/dist/elements/button.js +1 -0
- 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-types.d.ts +47 -0
- 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-C2LTALdM.js +1 -0
- package/dist/elements/chunks/action-icons-Dtl8Ox5D.js +1 -0
- package/dist/elements/chunks/arrow-left-GbBceGBE.js +1 -0
- package/dist/elements/chunks/attachments-DLJcWCDV.js +1 -0
- package/dist/elements/chunks/badge-BTNZTODL.js +1 -0
- package/dist/elements/chunks/button-DBDZebGr.js +1 -0
- package/dist/elements/chunks/card-YfCyI4fH.js +1 -0
- package/dist/elements/chunks/chat-thread-Dz2qbzvI.js +1 -0
- package/dist/elements/chunks/check-fhmRksq_.js +1 -0
- package/dist/elements/chunks/chevron-down-DcRg1aRU.js +1 -0
- package/dist/elements/chunks/chevron-right-ChzBcNJ-.js +1 -0
- package/dist/elements/chunks/circle-B4fTe9v6.js +1 -0
- package/dist/elements/chunks/circle-check-CJV-3Rem.js +1 -0
- package/dist/elements/chunks/circle-x-pDtzlghQ.js +1 -0
- package/dist/elements/chunks/cn-CU7UAWzk.js +1 -0
- package/dist/elements/chunks/code-block-DZ6mz6vs.js +1 -0
- package/dist/elements/chunks/collapsible-CWUAShMC.js +1 -0
- package/dist/elements/chunks/composer-BZyPU6gD.js +65 -0
- package/dist/elements/chunks/context-Cx6eQA_G.js +1 -0
- package/dist/elements/chunks/conversation-list-C4xTQSpT.js +1 -0
- package/dist/elements/chunks/default-input-BZcwyKcP.js +1 -0
- package/dist/elements/chunks/define-CNSKFZCd.js +1 -0
- package/dist/elements/chunks/disclosure-BcBs--Jf.js +1 -0
- package/dist/elements/chunks/download-BDQwcFav.js +1 -0
- package/dist/elements/chunks/dropdown-wgs8xCJZ.js +1 -0
- package/dist/elements/chunks/ellipsis-CUiEJ6R1.js +1 -0
- package/dist/elements/chunks/external-link-DJUmC7g2.js +1 -0
- package/dist/elements/chunks/file-text-DOYfYvrh.js +1 -0
- package/dist/elements/chunks/file-tree-DQzNQrbr.js +1 -0
- package/dist/elements/chunks/folder-DBDUBANz.js +1 -0
- package/dist/elements/chunks/hover-card-BQGdGAQ3.js +1 -0
- package/dist/elements/chunks/icon-CAyRqVrg.js +1 -0
- package/dist/elements/chunks/{index-CTBEJeo6.js → index-BCRhi84a.js} +1 -1
- package/dist/elements/chunks/info-DBQl-m6e.js +1 -0
- package/dist/elements/chunks/input-DZD67EvW.js +1 -0
- package/dist/elements/chunks/kbd-DbyVrlnU.js +1 -0
- package/dist/elements/chunks/link-vko7AttA.js +1 -0
- package/dist/elements/chunks/loader-Cg6rO8tQ.js +1 -0
- package/dist/elements/chunks/{markdown-CMTGx9r8.js → markdown-n3Xbj3PR.js} +9 -9
- package/dist/elements/chunks/message-CgKytiSB.js +1 -0
- package/dist/elements/chunks/message-feedback-Ds3-US0e.js +1 -0
- package/dist/elements/chunks/message-square-MmRkvc-M.js +1 -0
- package/dist/elements/chunks/minimize-2-3kCdE0q3.js +1 -0
- package/dist/elements/chunks/model-switcher-BMtXGwLU.js +1 -0
- package/dist/elements/chunks/overlay-B1-MBI6h.js +1 -0
- package/dist/elements/chunks/paperclip-DDEfmkHc.js +1 -0
- package/dist/elements/chunks/progress-bar-Dwbiyv3s.js +1 -0
- package/dist/elements/chunks/prompt-suggestion-9lvgFcEa.js +1 -0
- package/dist/elements/chunks/reasoning-DzHWsdAJ.js +1 -0
- package/dist/elements/chunks/resizable-Bq_eHxUm.js +1 -0
- package/dist/elements/chunks/rotate-cw-jpisOdOV.js +1 -0
- package/dist/elements/chunks/scroll-area-g5Ze3K6f.js +1 -0
- package/dist/elements/chunks/separator-Bmjc5XyX.js +1 -0
- package/dist/elements/chunks/settings-Cz1bMJP9.js +1 -0
- package/dist/elements/chunks/settings-group-9imY3kRA.js +1 -0
- package/dist/elements/chunks/share-BdenF0wQ.js +1 -0
- package/dist/elements/chunks/skeleton-Pjc5jiaY.js +1 -0
- package/dist/elements/chunks/slots-DkZ-Cmha.js +1 -0
- package/dist/elements/chunks/star-DY6z1UUH.js +1 -0
- package/dist/elements/chunks/store-th4VyJXM.js +1 -0
- package/dist/elements/chunks/text-shimmer-CEi-tlXr.js +1 -0
- package/dist/elements/chunks/textarea-CboigarR.js +1 -0
- package/dist/elements/chunks/thumbs-up-BR33KLfA.js +1 -0
- package/dist/elements/chunks/toast-store-BEMda0fv.js +1 -0
- package/dist/elements/chunks/tool-TMued3WO.js +1 -0
- package/dist/elements/chunks/tooltip-Cft_Rxiw.js +1 -0
- package/dist/elements/chunks/triangle-alert-B07fX3Q8.js +1 -0
- package/dist/elements/chunks/use-card-resolution-M36zVciB.js +1 -0
- package/dist/elements/chunks/video-MKp3LmNT.js +1 -0
- package/dist/elements/chunks/x-Ckwicf6g.js +1 -0
- package/dist/elements/coachmark.d.ts +1 -0
- package/dist/elements/coachmark.js +1 -0
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.d.ts +1 -0
- package/dist/elements/command.js +1 -0
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.d.ts +1 -0
- package/dist/elements/composer.js +1 -0
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/css.d.ts +1 -0
- package/dist/elements/default-input.d.ts +51 -0
- package/dist/elements/define.d.ts +53 -0
- package/dist/elements/dialog.d.ts +1 -0
- package/dist/elements/dialog.js +1 -0
- package/dist/elements/disclosure.d.ts +37 -0
- package/dist/elements/editable-label.d.ts +1 -0
- package/dist/elements/editable-label.js +1 -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.d.ts +1 -0
- package/dist/elements/hover-card.js +1 -0
- package/dist/elements/icon.d.ts +1 -0
- package/dist/elements/icon.js +1 -0
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.d.ts +1 -0
- package/dist/elements/input.js +1 -0
- package/dist/elements/kbd.d.ts +1 -0
- package/dist/elements/kbd.js +1 -0
- 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.d.ts +1 -0
- package/dist/elements/menu.js +1 -0
- 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.d.ts +1 -0
- package/dist/elements/nav.js +1 -0
- package/dist/elements/notice.d.ts +1 -0
- package/dist/elements/notice.js +1 -0
- package/dist/elements/pane-group.d.ts +1 -0
- package/dist/elements/pane-group.js +1 -0
- package/dist/elements/pane.d.ts +1 -0
- package/dist/elements/pane.js +1 -0
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.d.ts +1 -0
- package/dist/elements/progress-bar.js +1 -0
- package/dist/elements/prompt-dock.d.ts +1 -0
- package/dist/elements/prompt-dock.js +1 -0
- 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-impl.d.ts +0 -0
- package/dist/elements/register.d.ts +13 -0
- package/dist/elements/remote.d.ts +1 -0
- package/dist/elements/remote.js +1 -0
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +2 -2
- package/dist/elements/screen.d.ts +1 -0
- package/dist/elements/screen.js +1 -0
- package/dist/elements/scroll-area.d.ts +1 -0
- package/dist/elements/scroll-area.js +1 -0
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.d.ts +1 -0
- package/dist/elements/search.js +1 -0
- package/dist/elements/segmented.d.ts +1 -0
- package/dist/elements/segmented.js +1 -0
- package/dist/elements/separator.d.ts +1 -0
- package/dist/elements/separator.js +1 -0
- package/dist/elements/setting-item.d.ts +1 -0
- package/dist/elements/setting-item.js +1 -0
- package/dist/elements/settings-group.d.ts +1 -0
- package/dist/elements/settings-group.js +1 -0
- package/dist/elements/skeleton.d.ts +1 -0
- package/dist/elements/skeleton.js +1 -0
- package/dist/elements/slots.d.ts +176 -0
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.d.ts +1 -0
- package/dist/elements/status.js +1 -0
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.d.ts +1 -0
- package/dist/elements/tabs.js +1 -0
- 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/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.d.ts +1 -0
- package/dist/elements/tooltip.js +1 -0
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.d.ts +1 -0
- package/dist/elements/voice-output.js +1 -0
- package/dist/elements.d.ts +733 -58
- package/dist/engine-javascript-C1x7zo1_.js +141 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +8255 -5703
- package/dist/kai.es.js +1 -0
- package/dist/llms/llms-full.txt +1146 -64
- package/dist/llms/llms.txt +4 -4
- package/dist/mcp.es.js +62 -7
- package/dist/primitives/composer-model.d.ts +22 -0
- package/dist/primitives/composer-triggers.d.ts +19 -0
- package/dist/primitives/create-kai-chat.d.ts +38 -0
- package/dist/primitives/toast-store.d.ts +32 -2
- package/dist/primitives/use-speech-recognition.d.ts +26 -0
- package/dist/react/index.d.ts +1085 -97
- package/dist/react/runtime.d.ts +9 -2
- package/dist/react/use-kai-chat.d.ts +41 -0
- package/dist/react.js +572 -193
- package/dist/register-impl-cKscku5m.js +141 -0
- package/dist/schemas/tasks.schema.json +2 -2
- package/dist/state/index.d.ts +4 -0
- package/dist/state/messages.d.ts +11 -0
- package/dist/state/stream.d.ts +22 -0
- package/dist/state/suggestions.d.ts +4 -0
- package/dist/state.js +117 -0
- package/dist/theme.tokens.css +87 -0
- package/dist/types.d.ts +4 -0
- package/dist/ui/agent-card.d.ts +61 -0
- package/dist/ui/button.d.ts +5 -2
- package/dist/ui/card.d.ts +61 -0
- package/dist/ui/collapsible.d.ts +15 -1
- package/dist/ui/command.d.ts +33 -0
- package/dist/ui/dialog.d.ts +42 -0
- package/dist/ui/dropdown.d.ts +95 -1
- package/dist/ui/editable-label.d.ts +26 -0
- package/dist/ui/hover-card.d.ts +13 -1
- package/dist/ui/icon.d.ts +18 -0
- package/dist/ui/input.d.ts +33 -0
- package/dist/ui/kbd.d.ts +21 -0
- package/dist/ui/nav.d.ts +62 -0
- package/dist/ui/notice.d.ts +31 -0
- package/dist/ui/overlay.d.ts +12 -0
- package/dist/ui/pane-grid.d.ts +58 -0
- package/dist/ui/pane-group.d.ts +77 -0
- package/dist/ui/pane.d.ts +78 -0
- package/dist/ui/popover.d.ts +11 -1
- package/dist/ui/progress-bar.d.ts +23 -0
- package/dist/ui/prompt-dock.d.ts +96 -0
- package/dist/ui/resizable.d.ts +12 -0
- package/dist/ui/scroll-area.d.ts +4 -0
- package/dist/ui/segmented.d.ts +28 -0
- package/dist/ui/settings-group.d.ts +32 -0
- package/dist/ui/skeleton.d.ts +12 -0
- package/dist/ui/stat.d.ts +16 -0
- package/dist/ui/status.d.ts +13 -0
- package/dist/ui/switch.d.ts +8 -1
- package/dist/ui/tabs.d.ts +35 -0
- package/dist/ui/tooltip.d.ts +19 -1
- package/frameworks/react/index.tsx +1042 -157
- package/frameworks/react/runtime.tsx +30 -1
- package/frameworks/react/use-kai-chat.tsx +87 -0
- package/llms-full.txt +1146 -64
- package/llms.txt +4 -4
- package/package.json +31 -10
- package/src/agent-tooling/mcp/manifest.ts +14 -0
- package/src/agent-tooling/mcp/tools/debug.ts +11 -7
- package/src/agent-tooling/mcp/tools/reference.ts +32 -0
- package/src/agent-tooling/mcp/tools/scaffold.ts +30 -1
- package/src/components/artifact.tsx +98 -13
- package/src/components/attachment-types.ts +13 -0
- package/src/components/attachments.tsx +4 -14
- package/src/components/card.tsx +109 -15
- package/src/components/chain-of-thought.tsx +210 -1
- package/src/components/chat-scope-picker.tsx +13 -3
- package/src/components/chat-thread.tsx +225 -116
- package/src/components/choice-card.tsx +103 -11
- package/src/components/coachmark.tsx +249 -0
- package/src/components/component-meta.json +699 -110
- package/src/components/composer-dom.ts +159 -0
- package/src/components/composer-highlight.ts +242 -0
- package/src/components/composer-history.ts +82 -0
- package/src/components/composer.tsx +979 -0
- package/src/components/confirm-card.tsx +54 -1
- package/src/components/conversation-item.tsx +69 -7
- package/src/components/conversation-list.tsx +134 -37
- package/src/components/file-tree.tsx +197 -47
- package/src/components/form-widgets.tsx +9 -7
- package/src/components/form.tsx +140 -17
- package/src/components/image.tsx +3 -5
- package/src/components/link-preview.tsx +5 -4
- package/src/components/markdown.tsx +5 -2
- package/src/components/message.tsx +23 -4
- package/src/components/model-switcher.tsx +19 -4
- package/src/components/prompt-input.tsx +46 -75
- package/src/components/prompt-suggestion.tsx +48 -16
- package/src/components/reasoning.tsx +29 -6
- package/src/components/response-compare.tsx +31 -2
- package/src/components/screen.tsx +176 -0
- package/src/components/tasks-card.tsx +341 -21
- package/src/components/toast.tsx +119 -31
- package/src/components/tool-types.ts +10 -0
- package/src/components/tool.tsx +22 -16
- package/src/components/voice-input.tsx +102 -19
- package/src/components/voice-output.tsx +202 -0
- package/src/elements/agent-card.tsx +67 -0
- package/src/elements/artifact.tsx +53 -4
- package/src/elements/attachments.tsx +1 -0
- package/src/elements/avatar.tsx +33 -0
- package/src/elements/badge.tsx +32 -0
- package/src/elements/button.tsx +126 -0
- package/src/elements/card-media.jpg +0 -0
- package/src/elements/card.tsx +124 -31
- package/src/elements/cards.tsx +81 -7
- package/src/elements/chain-of-thought.tsx +77 -32
- package/src/elements/chat-scope-picker.tsx +35 -8
- package/src/elements/chat-types.ts +2 -2
- package/src/elements/chat-workspace.tsx +153 -41
- package/src/elements/chat.tsx +45 -23
- package/src/elements/choice.tsx +71 -19
- package/src/elements/coachmark.tsx +90 -0
- package/src/elements/command.tsx +209 -0
- package/src/elements/compare.tsx +24 -2
- package/src/elements/compiled.css +2 -2
- package/src/elements/composer.tsx +151 -0
- package/src/elements/confirm-card.tsx +36 -11
- package/src/elements/conversation-list.tsx +80 -11
- package/src/elements/default-input.tsx +75 -53
- package/src/elements/define.tsx +87 -7
- package/src/elements/dialog.tsx +98 -0
- package/src/elements/disclosure.ts +73 -0
- package/src/elements/editable-label.tsx +125 -0
- package/src/elements/element-manifest.json +129 -1
- package/src/elements/element-meta.json +5562 -1336
- package/src/elements/element-types.d.ts +732 -57
- package/src/elements/file-tree.tsx +12 -2
- package/src/elements/file-upload.tsx +1 -1
- package/src/elements/form.tsx +54 -11
- package/src/elements/hover-card.tsx +80 -0
- package/src/elements/icon-names.json +48 -0
- package/src/elements/icon.tsx +41 -0
- package/src/elements/input.tsx +203 -0
- package/src/elements/kbd.tsx +45 -0
- package/src/elements/menu.tsx +217 -0
- package/src/elements/message.tsx +58 -11
- package/src/elements/model-switcher.tsx +27 -1
- package/src/elements/nav.tsx +87 -0
- package/src/elements/notice.tsx +53 -0
- package/src/elements/pane-group.tsx +119 -0
- package/src/elements/pane.tsx +129 -0
- package/src/elements/popover.tsx +39 -17
- package/src/elements/progress-bar.tsx +39 -0
- package/src/elements/prompt-dock.tsx +81 -0
- package/src/elements/prompt-input.tsx +112 -63
- package/src/elements/prompt-suggestions.tsx +25 -9
- package/src/elements/reasoning.tsx +30 -9
- package/src/elements/register-impl.ts +38 -3
- package/src/elements/register.ts +11 -3
- package/src/elements/resizable.tsx +48 -11
- package/src/elements/screen.tsx +90 -0
- package/src/elements/scroll-area.tsx +33 -0
- package/src/elements/search.tsx +180 -0
- package/src/elements/segmented.tsx +135 -0
- package/src/elements/separator.tsx +36 -0
- package/src/elements/setting-item.tsx +50 -0
- package/src/elements/settings-group.tsx +37 -0
- package/src/elements/skeleton.tsx +45 -0
- package/src/elements/slots.ts +607 -0
- package/src/elements/source.tsx +13 -6
- package/src/elements/status.tsx +42 -0
- package/src/elements/switch.tsx +89 -14
- package/src/elements/tabs.tsx +95 -0
- package/src/elements/tasks.tsx +70 -14
- package/src/elements/toast.tsx +17 -2
- package/src/elements/tool.tsx +43 -9
- package/src/elements/tooltip.tsx +85 -0
- package/src/elements/video-poster.jpg +0 -0
- package/src/elements/voice-input.tsx +66 -16
- package/src/elements/voice-output.tsx +69 -0
- package/src/index.ts +5 -2
- package/src/primitives/card-schemas/tasks.schema.json +2 -2
- package/src/primitives/composer-model.ts +49 -0
- package/src/primitives/composer-triggers.ts +35 -0
- package/src/primitives/create-kai-chat.ts +66 -0
- package/src/primitives/toast-store.ts +43 -2
- package/src/primitives/use-speech-recognition.ts +135 -0
- package/src/state/index.ts +6 -0
- package/src/state/messages.ts +36 -0
- package/src/state/stream.ts +92 -0
- package/src/state/suggestions.ts +9 -0
- package/src/types.ts +4 -0
- package/src/ui/agent-card.tsx +218 -0
- package/src/ui/button.tsx +16 -5
- package/src/ui/card.tsx +245 -0
- package/src/ui/collapsible.tsx +30 -4
- package/src/ui/command.tsx +99 -0
- package/src/ui/dialog.tsx +217 -0
- package/src/ui/dropdown.tsx +375 -13
- package/src/ui/editable-label.tsx +112 -0
- package/src/ui/hover-card.tsx +28 -5
- package/src/ui/icon.tsx +110 -0
- package/src/ui/input.tsx +132 -0
- package/src/ui/kbd.tsx +118 -0
- package/src/ui/nav.tsx +282 -0
- package/src/ui/notice.tsx +84 -0
- package/src/ui/overlay.tsx +108 -2
- package/src/ui/pane-grid.tsx +117 -0
- package/src/ui/pane-group.tsx +291 -0
- package/src/ui/pane.tsx +193 -0
- package/src/ui/popover.tsx +16 -2
- package/src/ui/progress-bar.tsx +83 -0
- package/src/ui/prompt-dock.tsx +145 -0
- package/src/ui/resizable.tsx +69 -1
- package/src/ui/scroll-area.tsx +14 -3
- package/src/ui/segmented.tsx +109 -0
- package/src/ui/settings-group.tsx +67 -0
- package/src/ui/skeleton.tsx +62 -5
- package/src/ui/stat.tsx +41 -0
- package/src/ui/status.tsx +48 -0
- package/src/ui/switch.tsx +49 -23
- package/src/ui/tabs.tsx +168 -0
- package/src/ui/tooltip.tsx +52 -8
- package/theme.css +113 -0
- package/dist/components/slash-command.d.ts +0 -15
- package/dist/elements/chunks/Icon-D_Zmwmwh.js +0 -1
- package/dist/elements/chunks/action-icons-PVfIvcuG.js +0 -1
- package/dist/elements/chunks/attachments-Dp6vqtrc.js +0 -1
- package/dist/elements/chunks/button-CKyYD9G4.js +0 -1
- package/dist/elements/chunks/card-Cjho-PYk.js +0 -1
- package/dist/elements/chunks/chat-thread-RT808iPf.js +0 -1
- package/dist/elements/chunks/check-CDYaMYrM.js +0 -1
- package/dist/elements/chunks/chevron-down-3SBiq8HF.js +0 -1
- package/dist/elements/chunks/chevron-right-k2UFlIVK.js +0 -1
- package/dist/elements/chunks/cn-Dogu6PbV.js +0 -1
- package/dist/elements/chunks/code-block-BYUmfFSd.js +0 -1
- package/dist/elements/chunks/collapsible-BiNwdOn6.js +0 -1
- package/dist/elements/chunks/context-18g6oi4J.js +0 -1
- package/dist/elements/chunks/conversation-list-D9Y0NVdo.js +0 -1
- package/dist/elements/chunks/default-input-CSAoYYMd.js +0 -1
- package/dist/elements/chunks/download-D8K0Je8r.js +0 -1
- package/dist/elements/chunks/dropdown-bUs2iTia.js +0 -1
- package/dist/elements/chunks/external-link-6mA0wxab.js +0 -1
- package/dist/elements/chunks/file-text-DnaYk3Dm.js +0 -1
- package/dist/elements/chunks/file-tree-CgtRLlxK.js +0 -1
- package/dist/elements/chunks/hover-card-CIGw62gP.js +0 -1
- package/dist/elements/chunks/link-BlGSeoPy.js +0 -1
- package/dist/elements/chunks/loader-DvhR4qa0.js +0 -1
- package/dist/elements/chunks/message-CDZwXjhL.js +0 -1
- package/dist/elements/chunks/message-feedback-CYx81QiA.js +0 -1
- package/dist/elements/chunks/model-switcher-O_tUhoOT.js +0 -1
- package/dist/elements/chunks/overlay-DydXYMQW.js +0 -1
- package/dist/elements/chunks/prompt-suggestion-ldlWV5kd.js +0 -1
- package/dist/elements/chunks/reasoning-2PUnHlmr.js +0 -1
- package/dist/elements/chunks/resizable-B5WNbSeb.js +0 -1
- package/dist/elements/chunks/star-t9tI-P0q.js +0 -1
- package/dist/elements/chunks/store-C6rIooZz.js +0 -1
- package/dist/elements/chunks/text-shimmer-uh9V_KUh.js +0 -1
- package/dist/elements/chunks/textarea-3nm6Ia9U.js +0 -1
- package/dist/elements/chunks/thumbs-up-BBtguGld.js +0 -1
- package/dist/elements/chunks/toast-store-D8cL3fWl.js +0 -1
- package/dist/elements/chunks/tool-GJ3vwp1U.js +0 -1
- package/dist/elements/chunks/tooltip-DwKAz4XR.js +0 -1
- package/dist/elements/chunks/triangle-alert-Ct1zt2JL.js +0 -1
- package/dist/elements/chunks/use-card-resolution-D-_0Alzy.js +0 -1
- package/dist/elements/chunks/video-mVYiM99-.js +0 -1
- package/dist/elements/chunks/x-CzxL27Ch.js +0 -1
- package/dist/kitn-chat.es.js +0 -1
- package/dist/register-JyTglR6m.js +0 -1
- package/dist/register-impl-C6wlSsts.js +0 -77
- package/src/components/slash-command.tsx +0 -232
- package/src/elements/framework-usage.json +0 -588
- /package/dist/{kitn-chat-provider.d.ts → kai-provider.d.ts} +0 -0
- /package/dist/{kitn-chat-provider.es.js → kai-provider.es.js} +0 -0
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composition slots for `kai-*` elements. A slot is a named region a consumer
|
|
3
|
+
* fills with their own markup. This registry is the SINGLE SOURCE OF TRUTH:
|
|
4
|
+
* the facade derives its detection from it (and, later, docs are generated
|
|
5
|
+
* from it). See docs/superpowers/specs/2026-06-23-kai-chat-composition-seams-design.md.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** `inject` = additive (the built-in region still renders, your markup is added
|
|
9
|
+
* in). `replace` = your markup stands in for the whole region — you own that
|
|
10
|
+
* region's data + events (a slotted light-DOM node can't read the component's
|
|
11
|
+
* reactive state). */
|
|
12
|
+
export type SlotMode = 'inject' | 'replace';
|
|
13
|
+
|
|
14
|
+
export interface SlotDef {
|
|
15
|
+
/** Slot name (kebab-case). Also the `::part` name when `part` is true. */
|
|
16
|
+
name: string;
|
|
17
|
+
mode: SlotMode;
|
|
18
|
+
/** Expose `::part(name)` on the region wrapper for consumer styling. */
|
|
19
|
+
part?: boolean;
|
|
20
|
+
/** One-line contract: what the consumer projects / owns. Feeds the docs. */
|
|
21
|
+
doc: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Slots of `<kai-chat>`, in render order. */
|
|
25
|
+
export const CHAT_SLOTS: SlotDef[] = [
|
|
26
|
+
{ name: 'header-start', mode: 'inject', doc: 'Leading header controls, left of the title.' },
|
|
27
|
+
{ name: 'header-end', mode: 'inject', doc: 'Trailing header controls.' },
|
|
28
|
+
{ name: 'header', mode: 'replace', part: true, doc: 'Full custom header; replaces the built-in title/model/context bar.' },
|
|
29
|
+
{ name: 'sidebar', mode: 'inject', part: true, doc: 'Left column (your nav / conversation list). Fixed width; use compose-your-own for resizable.' },
|
|
30
|
+
{ name: 'empty', mode: 'replace', doc: 'Custom zero-state rendered in the message area while the thread is empty. Replaces the empty message list only — the composer and any suggestions still render.' },
|
|
31
|
+
{ name: 'composer', mode: 'replace', doc: 'Full custom composer; you own submit + loading, drive the thread via messages.' },
|
|
32
|
+
{ name: 'composer-actions', mode: 'inject', doc: 'Accessory row above the composer.' },
|
|
33
|
+
{ name: 'footer', mode: 'inject', part: true, doc: 'Row below the composer (disclaimers, token meter).' },
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
/** Slots of `<kai-prompt-input>` (and the default composer inside `<kai-chat>`). Native
|
|
37
|
+
* shadow slots — an empty slot renders nothing, so no facade flag-gating is required.
|
|
38
|
+
*
|
|
39
|
+
* These are ONLY positions inside the card's shadow boundary — places a consumer
|
|
40
|
+
* cannot reach from their own DOM. Content ABOVE/BELOW the whole card is the
|
|
41
|
+
* consumer's own light-DOM layout (a sibling element), so there is intentionally
|
|
42
|
+
* no outer block slot here. (When the input is nested inside `<kai-chat>`'s shadow,
|
|
43
|
+
* that surrounding hole belongs to `kai-chat` — see `composer-actions`/`footer`.) */
|
|
44
|
+
export const PROMPT_INPUT_SLOTS: SlotDef[] = [
|
|
45
|
+
{ name: 'input-top', mode: 'inject', doc: 'Inside the card, above the textarea (e.g. an inline status strip). For content above/below the whole card, use your own layout — that is light DOM you control.' },
|
|
46
|
+
{ name: 'toolbar-start', mode: 'inject', doc: 'Leading controls in the input toolbar — where a + menu goes.' },
|
|
47
|
+
{ name: 'toolbar-end', mode: 'inject', doc: 'Trailing controls in the toolbar, before the Send button.' },
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
/** Slots of `<kai-conversations>` (also used inside `<kai-chat>`'s `sidebar`).
|
|
51
|
+
* Names mirror `<kai-chat>`'s so the two compose with one vocabulary. */
|
|
52
|
+
export const CONVERSATIONS_SLOTS: SlotDef[] = [
|
|
53
|
+
{ name: 'header', mode: 'replace', doc: 'Full custom title bar; replaces the built-in toggle / "Chats" / New-chat row.' },
|
|
54
|
+
{ name: 'empty', mode: 'replace', doc: 'Custom zero-state shown when there are no conversations; replaces the built-in "No conversations yet".' },
|
|
55
|
+
{ name: 'footer', mode: 'inject', doc: 'A row below the list — account, settings, or usage.' },
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
/** Styleable `::part`s of `<kai-conversations>`. */
|
|
59
|
+
export const CONVERSATIONS_PARTS: PartDef[] = [
|
|
60
|
+
{
|
|
61
|
+
name: 'trailing',
|
|
62
|
+
doc: '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.',
|
|
63
|
+
recipe: 'kai-conversations::part(trailing) { color: var(--color-primary); font-variant-numeric: tabular-nums }',
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
/** Slots of `<kai-message>` — per-message composition seams. `before-body` and
|
|
68
|
+
* `after-body` are INJECT regions inside the message's body column; `avatar`
|
|
69
|
+
* REPLACES the built-in avatar rail (pair it with `avatar="none"` to omit the
|
|
70
|
+
* rail entirely). These are the keystone of compose-your-own message lists. */
|
|
71
|
+
export const MESSAGE_SLOTS: SlotDef[] = [
|
|
72
|
+
{ name: 'before-body', mode: 'inject', doc: 'A per-message header at the TOP of the body, above reasoning/tools/content — a model-name label, a role + timestamp line.' },
|
|
73
|
+
{ name: 'after-body', mode: 'inject', doc: 'A row at the BOTTOM of the body, below the action bar — a citation/sources row, a token-cost/latency line.' },
|
|
74
|
+
{ name: 'avatar', mode: 'replace', part: true, doc: '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.' },
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
/** Slots of `<kai-notice>`. The message is the default slot; these are the named seams. */
|
|
78
|
+
export const NOTICE_SLOTS: SlotDef[] = [
|
|
79
|
+
{ name: 'action', mode: 'inject', doc: 'A trailing action beside the message — a link or button.' },
|
|
80
|
+
{ name: 'icon', mode: 'replace', doc: 'A custom leading icon (any inline SVG, inherits `currentColor`). Overrides the severity default and the `icon` prop — the same escape hatch as `kai-button`.' },
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
/** Slots of `<kai-button>` (the label is the default slot). */
|
|
84
|
+
export const BUTTON_SLOTS: SlotDef[] = [
|
|
85
|
+
{ name: 'icon', mode: 'replace', doc: 'A custom leading icon (any inline SVG, inherits `currentColor`). Wins over the `icon` prop.' },
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
/** Slots of `<kai-hover-card>` (the trigger is the default slot). */
|
|
89
|
+
export const HOVER_CARD_SLOTS: SlotDef[] = [
|
|
90
|
+
{ name: 'card', mode: 'inject', doc: 'The rich content shown in the floating hover card.' },
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
/** Slots of `<kai-menu>` (the menu items come from the `items` prop). */
|
|
94
|
+
export const MENU_SLOTS: SlotDef[] = [
|
|
95
|
+
{ name: 'trigger', mode: 'replace', doc: 'Your own trigger element; replaces the built-in button driven by the `trigger-icon` / `trigger-label` props.' },
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
/** A styleable `::part` the kit renders (NOT a slot — you don't project into it;
|
|
99
|
+
* you restyle it from outside via `::part(name)`). This registry is the source
|
|
100
|
+
* of truth so the styling surface is discoverable: docs + the `kai` MCP
|
|
101
|
+
* component reference are generated from it, the same way slots are. The
|
|
102
|
+
* `recipe` is a copy-pasteable example — including the "just hide it" case that
|
|
103
|
+
* is pure CSS and therefore intentionally NOT a prop. */
|
|
104
|
+
export interface PartDef {
|
|
105
|
+
/** `::part(name)` exposed for consumer styling. */
|
|
106
|
+
name: string;
|
|
107
|
+
/** One-line contract: what the part is. */
|
|
108
|
+
doc: string;
|
|
109
|
+
/** A copy-pasteable styling example for docs / the MCP reference. */
|
|
110
|
+
recipe?: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Styleable `::part`s of `<kai-chat>` (beyond the slot-backed `header`/`sidebar`/
|
|
114
|
+
* `footer` parts). */
|
|
115
|
+
export const CHAT_PARTS: PartDef[] = [
|
|
116
|
+
{
|
|
117
|
+
name: 'header-bar',
|
|
118
|
+
doc: 'The built-in header bar (the title / model-switcher / context row that hosts the header-start/header-end inject slots). Restyle its height, padding, or gap from outside without replacing the whole header via the `header` slot.',
|
|
119
|
+
recipe: 'kai-chat::part(header-bar) { height: 3.5rem; padding-inline: 1rem; gap: 0.5rem }',
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
/** Styleable `::part`s of `<kai-prompt-input>`. */
|
|
124
|
+
export const PROMPT_INPUT_PARTS: PartDef[] = [
|
|
125
|
+
{
|
|
126
|
+
name: 'send',
|
|
127
|
+
doc: 'The send button. Restyle from outside, or hide it entirely (Enter-only) — hiding is pure CSS, which is why there is no `submit="never"`.',
|
|
128
|
+
recipe: 'kai-prompt-input::part(send) { display: none } /* Enter-only; or restyle: background, border-radius, … */',
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
/** Styleable `::part`s of `<kai-button>`. */
|
|
133
|
+
export const BUTTON_PARTS: PartDef[] = [
|
|
134
|
+
{
|
|
135
|
+
name: 'button',
|
|
136
|
+
doc: 'The button element. Restyle radius, padding, colors, or weight from outside; the `variant`/`size` props set the defaults.',
|
|
137
|
+
recipe: 'kai-button::part(button) { border-radius: 9999px; font-weight: 600 }',
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
/** Styleable `::part`s of `<kai-badge>`. */
|
|
142
|
+
export const BADGE_PARTS: PartDef[] = [
|
|
143
|
+
{
|
|
144
|
+
name: 'badge',
|
|
145
|
+
doc: 'The badge pill. Restyle its background, color, or shape; the `variant` prop (default/count/citation) sets the defaults.',
|
|
146
|
+
recipe: 'kai-badge::part(badge) { background: var(--color-primary); color: var(--color-primary-foreground) }',
|
|
147
|
+
},
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
/** Styleable `::part`s of `<kai-icon>`. */
|
|
151
|
+
export const ICON_PARTS: PartDef[] = [
|
|
152
|
+
{
|
|
153
|
+
name: 'icon',
|
|
154
|
+
doc: 'The icon wrapper. Inherits `currentColor` and the `size` prop by default; recolor or resize it from outside.',
|
|
155
|
+
recipe: 'kai-icon::part(icon) { color: var(--color-primary) }',
|
|
156
|
+
},
|
|
157
|
+
];
|
|
158
|
+
|
|
159
|
+
/** Styleable `::part`s of `<kai-separator>`. */
|
|
160
|
+
export const SEPARATOR_PARTS: PartDef[] = [
|
|
161
|
+
{
|
|
162
|
+
name: 'separator',
|
|
163
|
+
doc: 'The divider line. Restyle its color, thickness, or inset from outside.',
|
|
164
|
+
recipe: 'kai-separator::part(separator) { background: var(--color-border) }',
|
|
165
|
+
},
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
/** Styleable `::part`s of `<kai-scroll-area>`. */
|
|
169
|
+
export const SCROLL_AREA_PARTS: PartDef[] = [
|
|
170
|
+
{
|
|
171
|
+
name: 'viewport',
|
|
172
|
+
doc: 'The scrolling container. Add padding or a max-height from outside; the thin scrollbar follows `--color-scrollbar-thumb`.',
|
|
173
|
+
recipe: 'kai-scroll-area::part(viewport) { padding-right: 0.5rem }',
|
|
174
|
+
},
|
|
175
|
+
];
|
|
176
|
+
|
|
177
|
+
/** Styleable `::part`s of `<kai-skeleton>`. */
|
|
178
|
+
export const SKELETON_PARTS: PartDef[] = [
|
|
179
|
+
{
|
|
180
|
+
name: 'skeleton',
|
|
181
|
+
doc: 'The shimmer block(s). Recolor or change the opacity from outside; the default is a low-contrast foreground tint that reads in both light and dark.',
|
|
182
|
+
recipe: 'kai-skeleton::part(skeleton) { background: var(--color-primary); opacity: 0.15 }',
|
|
183
|
+
},
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
/** Styleable `::part`s of `<kai-message>`. (The `avatar` part is contributed by
|
|
187
|
+
* the `avatar` slot's `part: true` flag, so it is not repeated here.) */
|
|
188
|
+
export const MESSAGE_PARTS: PartDef[] = [
|
|
189
|
+
{
|
|
190
|
+
name: 'row',
|
|
191
|
+
doc: 'The message row wrapper (avatar rail + body column). Restyle its gap or alignment from outside.',
|
|
192
|
+
recipe: 'kai-message::part(row) { gap: 0.75rem }',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: 'bubble',
|
|
196
|
+
doc: 'The content bubble wrapper. Restyle its background, radius, or padding; for a user message this is the rounded chat bubble.',
|
|
197
|
+
recipe: 'kai-message::part(bubble) { background: var(--color-primary); color: var(--color-primary-foreground) }',
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: 'content',
|
|
201
|
+
doc: 'The rendered message text/markdown region (same node as `bubble`). Target it to tune typography from outside.',
|
|
202
|
+
recipe: 'kai-message::part(content) { font-size: 0.9375rem }',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'actions',
|
|
206
|
+
doc: 'The action-bar row (copy / like / regenerate …). Restyle its spacing or hide it entirely from outside.',
|
|
207
|
+
recipe: 'kai-message::part(actions) { gap: 0.25rem }',
|
|
208
|
+
},
|
|
209
|
+
];
|
|
210
|
+
|
|
211
|
+
/** Styleable `::part`s of `<kai-attachments>`. */
|
|
212
|
+
export const ATTACHMENTS_PARTS: PartDef[] = [
|
|
213
|
+
{
|
|
214
|
+
name: 'preview',
|
|
215
|
+
doc: '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.',
|
|
216
|
+
recipe: 'kai-attachments::part(preview) { max-width: 32rem; max-height: 24rem }',
|
|
217
|
+
},
|
|
218
|
+
];
|
|
219
|
+
|
|
220
|
+
/** Styleable `::part`s of `<kai-status>`. */
|
|
221
|
+
export const STATUS_PARTS: PartDef[] = [
|
|
222
|
+
{
|
|
223
|
+
name: 'dot',
|
|
224
|
+
doc: 'The status dot. Recolor or resize it from outside; the `status` prop sets the default hue.',
|
|
225
|
+
recipe: 'kai-status::part(dot) { background: var(--color-tool-green) }',
|
|
226
|
+
},
|
|
227
|
+
];
|
|
228
|
+
|
|
229
|
+
/** Styleable `::part`s of `<kai-tabs>`. */
|
|
230
|
+
export const TABS_PARTS: PartDef[] = [
|
|
231
|
+
{
|
|
232
|
+
name: 'tablist',
|
|
233
|
+
doc: 'The tab strip container (role="tablist"). Restyle its gap, padding, background, or radius from outside; the `variant` prop sets the segmented/underline defaults.',
|
|
234
|
+
recipe: 'kai-tabs::part(tablist) { gap: 0.5rem; background: var(--color-card) }',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
name: 'tab',
|
|
238
|
+
doc: 'A single tab button. Restyle from outside; the active tab carries a `[data-active]` attribute, so target `::part(tab)[data-active]` for the selected look.',
|
|
239
|
+
recipe: 'kai-tabs::part(tab)[data-active] { color: var(--color-primary); font-weight: 600 }',
|
|
240
|
+
},
|
|
241
|
+
];
|
|
242
|
+
|
|
243
|
+
/** Styleable `::part`s of `<kai-voice-output>`. */
|
|
244
|
+
export const VOICE_OUTPUT_PARTS: PartDef[] = [
|
|
245
|
+
{
|
|
246
|
+
name: 'button',
|
|
247
|
+
doc: 'The speaker/play button. Restyle radius, size, padding, or colors from outside; it is a ghost icon button by default.',
|
|
248
|
+
recipe: 'kai-voice-output::part(button) { border-radius: 9999px; color: var(--color-primary) }',
|
|
249
|
+
},
|
|
250
|
+
];
|
|
251
|
+
|
|
252
|
+
/** Slots of `<kai-screen>` (the default slot is the screen body). */
|
|
253
|
+
export const SCREEN_SLOTS: SlotDef[] = [
|
|
254
|
+
{ name: 'title', mode: 'replace', part: true, doc: 'Rich header title; overrides the `headline` prop.' },
|
|
255
|
+
{ name: 'actions', mode: 'inject', doc: 'Header trailing cluster (e.g. an avatar or overflow menu).' },
|
|
256
|
+
];
|
|
257
|
+
|
|
258
|
+
/** Styleable `::part`s of `<kai-screen>`. */
|
|
259
|
+
export const SCREEN_PARTS: PartDef[] = [
|
|
260
|
+
{
|
|
261
|
+
name: 'header',
|
|
262
|
+
doc: 'The back-header bar (back button + title + actions). Restyle its height, padding, or border from outside.',
|
|
263
|
+
recipe: 'kai-screen::part(header) { height: 3.25rem; padding-inline: 1rem }',
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: 'back',
|
|
267
|
+
doc: 'The back button. Restyle or hide it from outside; `back="false"` removes it entirely.',
|
|
268
|
+
recipe: 'kai-screen::part(back) { border-radius: 9999px }',
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: 'body',
|
|
272
|
+
doc: 'The full-bleed surface that fills the mount point and scrolls its content. Tune padding or background from outside.',
|
|
273
|
+
recipe: 'kai-screen::part(body) { background: var(--color-card) }',
|
|
274
|
+
},
|
|
275
|
+
];
|
|
276
|
+
|
|
277
|
+
/** Slots of `<kai-card>` — structural regions only (the title/description are body
|
|
278
|
+
* or `slot="header"` content you mark up). The body is the default slot. */
|
|
279
|
+
export const CARD_SLOTS: SlotDef[] = [
|
|
280
|
+
{ name: 'media', mode: 'inject', doc: 'Full-bleed media (image/video/illustration) at the top (vertical) or start (horizontal). Clipped to the card corners.' },
|
|
281
|
+
{ name: 'header', mode: 'inject', doc: 'Header content, e.g. a title. Rendered above the body.' },
|
|
282
|
+
{ name: 'header-actions', mode: 'inject', doc: 'An actions cluster pinned to the end of the header row.' },
|
|
283
|
+
{ name: 'footer', mode: 'inject', doc: 'Footer content rendered below the body.' },
|
|
284
|
+
{ name: 'footer-actions', mode: 'inject', doc: 'Action buttons pinned to the end of the footer. Do NOT combine with a clickable/href card (nested interactive).' },
|
|
285
|
+
];
|
|
286
|
+
|
|
287
|
+
/** Styleable `::part`s of `<kai-card>`. */
|
|
288
|
+
export const CARD_PARTS: PartDef[] = [
|
|
289
|
+
{
|
|
290
|
+
name: 'card',
|
|
291
|
+
doc: 'The card root (a div, or an a when href is set). Restyle its radius, border, or background; set --kai-card-spacing for padding/gaps (the dense prop sets the compact default).',
|
|
292
|
+
recipe: 'kai-card::part(card) { border-radius: 1rem; --kai-card-spacing: 1.5rem }',
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: 'media',
|
|
296
|
+
doc: 'The full-bleed media region. Cap or crop it from outside (e.g. a fixed height with object-fit).',
|
|
297
|
+
recipe: 'kai-card::part(media) { max-height: 12rem }',
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
name: 'header',
|
|
301
|
+
doc: 'The header row (header content + header-actions). Add a divider or adjust its alignment.',
|
|
302
|
+
recipe: 'kai-card::part(header) { border-bottom: 1px solid var(--color-border) }',
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: 'body',
|
|
306
|
+
doc: 'The default-slot body region.',
|
|
307
|
+
recipe: 'kai-card::part(body) { font-size: 0.9375rem }',
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: 'footer',
|
|
311
|
+
doc: 'The footer row (footer content + footer-actions).',
|
|
312
|
+
recipe: 'kai-card::part(footer) { border-top: 1px solid var(--color-border) }',
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
name: 'dismiss',
|
|
316
|
+
doc: 'The dismiss (×) button shown when dismissible. Recolor or reposition it from outside.',
|
|
317
|
+
recipe: 'kai-card::part(dismiss) { color: var(--color-muted-foreground) }',
|
|
318
|
+
},
|
|
319
|
+
];
|
|
320
|
+
|
|
321
|
+
/** Injection slots of `<kai-workspace>` (the carrier regions the consumer drops
|
|
322
|
+
* content into: brand/tabs, the upgrade/Design/user-menu cluster, a top banner). */
|
|
323
|
+
export const WORKSPACE_SLOTS: SlotDef[] = [
|
|
324
|
+
{ name: 'sidebar-header', mode: 'inject', doc: 'Top of the conversation rail (brand, a kai-tabs strip).' },
|
|
325
|
+
{ name: 'sidebar-footer', mode: 'inject', doc: 'Bottom of the rail: an upgrade card, a Design trigger, a user-menu cluster.' },
|
|
326
|
+
{ name: 'main-header', mode: 'inject', doc: 'Top of the main region (a top-placed banner or a corner action).' },
|
|
327
|
+
{ name: 'main', mode: 'replace', doc: 'Replace the built-in chat thread with your own main view (a home or dashboard screen). Omit to keep the thread.' },
|
|
328
|
+
];
|
|
329
|
+
|
|
330
|
+
/** Styleable `::part`s of `<kai-workspace>`. */
|
|
331
|
+
export const WORKSPACE_PARTS: PartDef[] = [
|
|
332
|
+
{
|
|
333
|
+
name: 'sidebar',
|
|
334
|
+
doc: 'The conversation rail. Carries a subtle, theme-aware default background (bg-surface); override its background, border, or width from outside. `sidebar-min-width` sets its min px width and `collapse-below` auto-collapses it under a width.',
|
|
335
|
+
recipe: 'kai-workspace::part(sidebar) { background: var(--color-card); border-right: 1px solid var(--color-border) }',
|
|
336
|
+
},
|
|
337
|
+
];
|
|
338
|
+
|
|
339
|
+
/** Styleable `::part`s of `<kai-nav>`. */
|
|
340
|
+
export const NAV_PARTS: PartDef[] = [
|
|
341
|
+
{
|
|
342
|
+
name: 'nav',
|
|
343
|
+
doc: 'The nav list container. Restyle its gap or padding from outside.',
|
|
344
|
+
recipe: 'kai-nav::part(nav) { gap: 0.25rem }',
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
name: 'item',
|
|
348
|
+
doc: 'A nav item button (leaf or group parent). The active leaf carries aria-current="page" and a group parent carries aria-expanded; target `::part(item)[aria-current]` for the selected look or `::part(item)[aria-expanded]` for a group row.',
|
|
349
|
+
recipe: 'kai-nav::part(item)[aria-current] { background: var(--color-accent) }',
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
name: 'group',
|
|
353
|
+
doc: 'The nested child list rendered under an expanded group item. Add a left guide line or tune its indent from outside.',
|
|
354
|
+
recipe: 'kai-nav::part(group) { border-left: 1px solid var(--color-border); margin-left: 1.1rem }',
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
name: 'chevron',
|
|
358
|
+
doc: 'The disclosure chevron on a group row (rotates when expanded). Recolor or resize it from outside.',
|
|
359
|
+
recipe: 'kai-nav::part(chevron) { opacity: 1; color: var(--color-primary) }',
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
name: 'status',
|
|
363
|
+
doc: 'The per-item status cluster (a colored dot in the tone hue + an optional label). Shown only when an item carries a `status`; the `pulse` flag animates the dot. Restyle from outside.',
|
|
364
|
+
recipe: 'kai-nav::part(status) { gap: 0.5rem }',
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
name: 'meta',
|
|
368
|
+
doc: 'The right-aligned muted trailing text on a row (e.g. a relative time). Shown only when an item carries `meta`; restyle from outside.',
|
|
369
|
+
recipe: 'kai-nav::part(meta) { color: var(--color-foreground); font-variant-numeric: tabular-nums }',
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
name: 'item-action',
|
|
373
|
+
doc: 'The trailing per-item action / close button, a sibling of the item button. Shown only when an item carries `action` or `closable`; reveal it on hover or pin it visible from outside.',
|
|
374
|
+
recipe: 'kai-nav::part(item-action) { opacity: 1 }',
|
|
375
|
+
},
|
|
376
|
+
];
|
|
377
|
+
|
|
378
|
+
/** Slots of `<kai-coachmark>` (the anchor/trigger is the default slot). */
|
|
379
|
+
export const COACHMARK_SLOTS: SlotDef[] = [
|
|
380
|
+
{ name: 'content', mode: 'replace', doc: 'The bubble body text shown under the headline.' },
|
|
381
|
+
];
|
|
382
|
+
|
|
383
|
+
/** Styleable `::part`s of `<kai-coachmark>`. */
|
|
384
|
+
export const COACHMARK_PARTS: PartDef[] = [
|
|
385
|
+
{ name: 'bubble', doc: 'The hint bubble panel. Restyle its background, radius, or padding from outside; the default is bg-primary.', recipe: 'kai-coachmark::part(bubble) { border-radius: 1rem }' },
|
|
386
|
+
{ name: 'arrow', doc: 'The arrow pointing at the anchor. Inherits the bubble color; recolor it alongside the bubble.', recipe: 'kai-coachmark::part(arrow) { background: var(--color-accent) }' },
|
|
387
|
+
{ name: 'badge', doc: 'The small badge pill beside the headline (e.g. "New").', recipe: 'kai-coachmark::part(badge) { text-transform: none }' },
|
|
388
|
+
{ name: 'title', doc: 'The bold headline text.', recipe: 'kai-coachmark::part(title) { font-size: 0.9375rem }' },
|
|
389
|
+
{ name: 'dismiss', doc: 'The dismiss button. Recolor or reposition it from outside.', recipe: 'kai-coachmark::part(dismiss) { color: var(--color-primary-foreground) }' },
|
|
390
|
+
];
|
|
391
|
+
|
|
392
|
+
/** Styleable `::part`s of `<kai-progress-bar>`. */
|
|
393
|
+
export const PROGRESS_BAR_PARTS: PartDef[] = [
|
|
394
|
+
{ name: 'track', doc: 'The progress track (the background bar). Restyle its height, radius, or background from outside.', recipe: 'kai-progress-bar::part(track) { height: 0.5rem }' },
|
|
395
|
+
{ name: 'fill', doc: 'The filled portion; its width follows value/max. Recolor it from outside.', recipe: 'kai-progress-bar::part(fill) { background: var(--color-tool-green) }' },
|
|
396
|
+
];
|
|
397
|
+
|
|
398
|
+
/** Styleable `::part`s of `<kai-file-tree>` — the changed-files / diff bits, shown
|
|
399
|
+
* only when a file carries diff metadata (or the `summary` attribute is set). */
|
|
400
|
+
export const FILE_TREE_PARTS: PartDef[] = [
|
|
401
|
+
{
|
|
402
|
+
name: 'summary',
|
|
403
|
+
doc: 'The changed-files summary header (the file count, the summed +additions/-deletions, and the Collapse-all/Expand-all toggle). Rendered only when the `summary` attribute is set; restyle or hide it from outside.',
|
|
404
|
+
recipe: 'kai-file-tree::part(summary) { border-bottom: none; padding-block: 0.5rem }',
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
name: 'status',
|
|
408
|
+
doc: 'The per-row change-status letter (A/M/D/R/U), shown when a file carries a `status`. Colored with the conventional VCS tool hues; restyle from outside.',
|
|
409
|
+
recipe: 'kai-file-tree::part(status) { font-weight: 700 }',
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
name: 'stat-additions',
|
|
413
|
+
doc: 'The trailing `+N` additions stat on a file row (success/green tool hue, tabular-nums). Shown only when a file carries `additions`.',
|
|
414
|
+
recipe: 'kai-file-tree::part(stat-additions) { color: var(--color-tool-green) }',
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
name: 'stat-deletions',
|
|
418
|
+
doc: 'The trailing `-N` deletions stat on a file row (error/red tool hue, tabular-nums). Shown only when a file carries `deletions`.',
|
|
419
|
+
recipe: 'kai-file-tree::part(stat-deletions) { color: var(--color-tool-red) }',
|
|
420
|
+
},
|
|
421
|
+
];
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Per-element composition surface — the SINGLE registry the build extracts
|
|
425
|
+
* (`scripts/gen-element-api.mjs`) into `element-meta.json`, the Custom Elements
|
|
426
|
+
* Manifest (`cssParts`/`slots`), `docs/web-components.md`, and the `kai` MCP
|
|
427
|
+
* `component_reference`. Each entry maps a `kai-*` tag to the slots it projects
|
|
428
|
+
* and the `::part`s it exposes for styling. Slots flagged `part: true` are ALSO
|
|
429
|
+
* styleable parts, so they surface in both places.
|
|
430
|
+
*
|
|
431
|
+
* Adding a `part="…"` in a facade/component without registering it here fails the
|
|
432
|
+
* `slots.test.ts` drift guard — keep this in sync with the source.
|
|
433
|
+
*/
|
|
434
|
+
export interface ElementComposition {
|
|
435
|
+
slots?: SlotDef[];
|
|
436
|
+
parts?: PartDef[];
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/** Slots + styleable `::part`s of `<kai-prompt-dock>`. */
|
|
440
|
+
export const PROMPT_DOCK_SLOTS: SlotDef[] = [
|
|
441
|
+
{ name: 'top', mode: 'inject', part: true, doc: 'The top lip: a notice or banner above the input. Rendered only when filled.' },
|
|
442
|
+
{ name: 'bottom', mode: 'inject', part: true, doc: 'The bottom lip: a mode or controls row below the input. Rendered only when filled.' },
|
|
443
|
+
];
|
|
444
|
+
export const PROMPT_DOCK_PARTS: PartDef[] = [
|
|
445
|
+
{
|
|
446
|
+
name: 'tray',
|
|
447
|
+
doc: 'The recessed tray that frames the input. The `appearance`/`frame` props set the defaults; the --kai-prompt-dock-* tokens fine-tune surface/border/radius/inset.',
|
|
448
|
+
recipe: 'kai-prompt-dock::part(tray) { --kai-prompt-dock-radius: 1rem }',
|
|
449
|
+
},
|
|
450
|
+
];
|
|
451
|
+
|
|
452
|
+
/** Styleable `::part`s of `<kai-segmented>`. */
|
|
453
|
+
export const SEGMENTED_PARTS: PartDef[] = [
|
|
454
|
+
{ name: 'track', doc: 'The segmented track (the pill container holding the segments). Restyle its background, radius, or padding.', recipe: 'kai-segmented::part(track) { border-radius: 9999px }' },
|
|
455
|
+
{ name: 'segment', doc: 'Each segment button. Restyle padding, font weight, or the selected look.', recipe: 'kai-segmented::part(segment) { font-weight: 600 }' },
|
|
456
|
+
];
|
|
457
|
+
|
|
458
|
+
/** Styleable `::part`s of `<kai-settings-group>`. */
|
|
459
|
+
export const SETTINGS_GROUP_PARTS: PartDef[] = [
|
|
460
|
+
{ name: 'header', doc: 'The group heading + description block. Restyle its spacing or typography.', recipe: 'kai-settings-group::part(header) { margin-bottom: 0.75rem }' },
|
|
461
|
+
{ name: 'body', doc: 'The bordered card holding the setting rows. Restyle its surface, border, or radius.', recipe: 'kai-settings-group::part(body) { border-radius: 1rem }' },
|
|
462
|
+
];
|
|
463
|
+
|
|
464
|
+
/** Slots + styleable `::part`s of `<kai-setting-item>`. */
|
|
465
|
+
export const SETTING_ITEM_SLOTS: SlotDef[] = [
|
|
466
|
+
{ name: 'control', mode: 'inject', part: true, doc: 'The row control (a switch, segmented, select, etc.), right-aligned. Omit it for a label-only row.' },
|
|
467
|
+
];
|
|
468
|
+
export const SETTING_ITEM_PARTS: PartDef[] = [
|
|
469
|
+
{ name: 'label', doc: 'The label + description block on the left of the row. Restyle its typography or spacing.', recipe: 'kai-setting-item::part(label) { gap: 0.125rem }' },
|
|
470
|
+
];
|
|
471
|
+
|
|
472
|
+
/** Slots + styleable `::part`s of `<kai-pane>` (the editor-group pane frame). */
|
|
473
|
+
export const PANE_SLOTS: SlotDef[] = [
|
|
474
|
+
{ name: 'leading', mode: 'inject', doc: 'A glyph or avatar at the start of the pane header.' },
|
|
475
|
+
{ name: 'actions', mode: 'inject', doc: 'Extra header controls, before the built-in window controls.' },
|
|
476
|
+
{ name: 'footer', mode: 'inject', part: true, doc: 'A pinned row below the body (e.g. a composer).' },
|
|
477
|
+
];
|
|
478
|
+
export const PANE_PARTS: PartDef[] = [
|
|
479
|
+
{ name: 'header', doc: 'The pane header bar (leading + title/status + actions + window controls).', recipe: 'kai-pane::part(header) { padding-inline: 0.75rem }' },
|
|
480
|
+
{ name: 'body', doc: 'The scrolling body region (the default slot).', recipe: 'kai-pane::part(body) { padding: 1rem }' },
|
|
481
|
+
{ name: 'controls', doc: 'The window-control cluster (maximize/close, and split/dock when enabled).', recipe: 'kai-pane::part(controls) { gap: 0.25rem }' },
|
|
482
|
+
];
|
|
483
|
+
|
|
484
|
+
/** Styleable `::part`s of `<kai-agent-card>`. */
|
|
485
|
+
export const AGENT_CARD_PARTS: PartDef[] = [
|
|
486
|
+
{ name: 'status', doc: 'The leading tone-colored status dot.', recipe: 'kai-agent-card::part(status) { width: 0.625rem; height: 0.625rem }' },
|
|
487
|
+
{ name: 'menu', doc: 'The trailing overflow ("...") menu button.', recipe: 'kai-agent-card::part(menu) { opacity: 1 }' },
|
|
488
|
+
];
|
|
489
|
+
|
|
490
|
+
/** Slots + styleable `::part`s of `<kai-dialog>` (the centered modal). */
|
|
491
|
+
export const DIALOG_SLOTS: SlotDef[] = [
|
|
492
|
+
{ name: 'header', mode: 'inject', part: true, doc: 'Optional title region at the top of the panel.' },
|
|
493
|
+
{ name: 'footer', mode: 'inject', part: true, doc: 'Optional actions region at the bottom of the panel.' },
|
|
494
|
+
];
|
|
495
|
+
export const DIALOG_PARTS: PartDef[] = [
|
|
496
|
+
{ name: 'backdrop', doc: 'The full-area scrim behind the panel. Restyle its color/blur.', recipe: 'kai-dialog::part(backdrop) { background: rgb(0 0 0 / 0.6) }' },
|
|
497
|
+
{ name: 'panel', doc: 'The centered modal panel. Restyle width, radius, padding.', recipe: 'kai-dialog::part(panel) { max-width: 32rem }' },
|
|
498
|
+
{ name: 'body', doc: 'The scrolling content region (the default slot).', recipe: 'kai-dialog::part(body) { padding: 1.25rem }' },
|
|
499
|
+
];
|
|
500
|
+
|
|
501
|
+
/** Styleable `::part`s of `<kai-pane-group>` (the editor group: a tab strip over
|
|
502
|
+
* the active tab's pane). The per-tab content slots are NAMED DYNAMICALLY by tab
|
|
503
|
+
* id (`slot="<tab id>"`) plus a default slot, so they are not enumerable here —
|
|
504
|
+
* only the styleable parts are registered. */
|
|
505
|
+
export const PANE_GROUP_PARTS: PartDef[] = [
|
|
506
|
+
{ name: 'tabs', doc: 'The tab strip (role="tablist"). Restyle its background, height, padding, or gap from outside.', recipe: 'kai-pane-group::part(tabs) { background: var(--color-card); gap: 0.25rem }' },
|
|
507
|
+
{ name: 'tab', doc: 'A single tab button. The active tab carries `[aria-selected="true"]`; target `::part(tab)[aria-selected="true"]` for the selected look.', recipe: 'kai-pane-group::part(tab)[aria-selected="true"] { background: var(--color-accent) }' },
|
|
508
|
+
{ name: 'body', doc: 'The active tab\'s content region (the named/default slot host).', recipe: 'kai-pane-group::part(body) { padding: 0.75rem }' },
|
|
509
|
+
{ name: 'menu', doc: 'The per-tab "…" overflow button. Reveal it on hover or pin it visible from outside.', recipe: 'kai-pane-group::part(menu) { opacity: 1 }' },
|
|
510
|
+
{ name: 'close', doc: 'The per-tab close ("×") button. Recolor, resize, or hide it from outside.', recipe: 'kai-pane-group::part(close) { color: var(--color-muted-foreground) }' },
|
|
511
|
+
];
|
|
512
|
+
|
|
513
|
+
/** Affix slots + styleable `::part`s of `<kai-input>` (the field shell). */
|
|
514
|
+
export const INPUT_SLOTS: SlotDef[] = [
|
|
515
|
+
{ name: 'leading', mode: 'inject', doc: 'A glyph, prefix, or affix at the start of the field, inside the border.' },
|
|
516
|
+
{ name: 'trailing', mode: 'inject', doc: 'A button, unit, or affix at the end of the field, inside the border.' },
|
|
517
|
+
];
|
|
518
|
+
export const INPUT_PARTS: PartDef[] = [
|
|
519
|
+
{ name: 'field', doc: 'The bordered control box (the row wrapping any affixes plus the input). Restyle its border, radius, surface, or focus ring.', recipe: 'kai-input::part(field) { border-radius: 0.75rem }' },
|
|
520
|
+
{ name: 'input', doc: 'The inner input element. Restyle its text, padding, or placeholder.', recipe: 'kai-input::part(input) { font-variant-numeric: tabular-nums }' },
|
|
521
|
+
{ name: 'label', doc: 'The field label above the control. Restyle its typography or spacing.', recipe: 'kai-input::part(label) { font-weight: 600 }' },
|
|
522
|
+
{ name: 'hint', doc: 'The hint or error line below the control. Restyle its typography.', recipe: 'kai-input::part(hint) { font-style: italic }' },
|
|
523
|
+
];
|
|
524
|
+
|
|
525
|
+
/** Styleable `::part`s of `<kai-search>` (the debounced filter field; composes the
|
|
526
|
+
* kai-input field plus a clear button). */
|
|
527
|
+
export const SEARCH_PARTS: PartDef[] = [
|
|
528
|
+
{ name: 'field', doc: 'The bordered control box (the row wrapping the search icon, input, and clear button).', recipe: 'kai-search::part(field) { border-radius: 9999px }' },
|
|
529
|
+
{ name: 'input', doc: 'The inner search input element.', recipe: 'kai-search::part(input) { font-size: 0.875rem }' },
|
|
530
|
+
{ name: 'clear', doc: 'The trailing clear ("x") button, shown when the field is non-empty.', recipe: 'kai-search::part(clear) { opacity: 1 }' },
|
|
531
|
+
];
|
|
532
|
+
|
|
533
|
+
/** Styleable `::part`s of `<kai-editable-label>` (inline rename; the edit field is the kai-input field). */
|
|
534
|
+
export const EDITABLE_LABEL_PARTS: PartDef[] = [
|
|
535
|
+
{ name: 'text', doc: 'The read-mode label text. Restyle its typography; it swaps to the input on edit.', recipe: 'kai-editable-label::part(text) { font-weight: 600 }' },
|
|
536
|
+
{ name: 'input', doc: 'The edit-mode input (the composed kai-input field).', recipe: 'kai-editable-label::part(input) { font: inherit }' },
|
|
537
|
+
];
|
|
538
|
+
|
|
539
|
+
/** Styleable `::part`s of `<kai-kbd>` (the keyboard-shortcut display). */
|
|
540
|
+
export const KBD_PARTS: PartDef[] = [
|
|
541
|
+
{ name: 'key', doc: 'Each key cap. Restyle its surface, border, radius, or font.', recipe: 'kai-kbd::part(key) { border-radius: 0.375rem }' },
|
|
542
|
+
{ name: 'separator', doc: 'The gap between key caps. Inject a literal joiner (e.g. a plus sign) from outside.', recipe: 'kai-kbd::part(separator)::after { content: "+" }' },
|
|
543
|
+
];
|
|
544
|
+
|
|
545
|
+
/** Styleable `::part`s of `<kai-command>` (the command palette). */
|
|
546
|
+
export const COMMAND_PARTS: PartDef[] = [
|
|
547
|
+
{ name: 'shortcut', doc: 'The right-aligned per-row keyboard shortcut, rendered as kai-kbd key caps. Shown only when a row carries a `shortcut`.', recipe: 'kai-command::part(shortcut) { opacity: 0.8 }' },
|
|
548
|
+
];
|
|
549
|
+
|
|
550
|
+
/** Styleable `::part`s of `<kai-menu>` (the actions dropdown). */
|
|
551
|
+
export const MENU_PARTS: PartDef[] = [
|
|
552
|
+
{ name: 'shortcut', doc: 'The right-aligned per-item keyboard shortcut, rendered as kai-kbd key caps. Shown only when an item carries a `shortcut`.', recipe: 'kai-menu::part(shortcut) { opacity: 0.8 }' },
|
|
553
|
+
];
|
|
554
|
+
|
|
555
|
+
export const ELEMENT_COMPOSITION: Record<string, ElementComposition> = {
|
|
556
|
+
'kai-chat': { slots: CHAT_SLOTS, parts: CHAT_PARTS },
|
|
557
|
+
'kai-command': { parts: COMMAND_PARTS },
|
|
558
|
+
'kai-conversations': { slots: CONVERSATIONS_SLOTS, parts: CONVERSATIONS_PARTS },
|
|
559
|
+
'kai-message': { slots: MESSAGE_SLOTS, parts: MESSAGE_PARTS },
|
|
560
|
+
'kai-prompt-input': { slots: PROMPT_INPUT_SLOTS, parts: PROMPT_INPUT_PARTS },
|
|
561
|
+
'kai-button': { slots: BUTTON_SLOTS, parts: BUTTON_PARTS },
|
|
562
|
+
'kai-badge': { parts: BADGE_PARTS },
|
|
563
|
+
'kai-icon': { parts: ICON_PARTS },
|
|
564
|
+
'kai-separator': { parts: SEPARATOR_PARTS },
|
|
565
|
+
'kai-scroll-area': { parts: SCROLL_AREA_PARTS },
|
|
566
|
+
'kai-notice': { slots: NOTICE_SLOTS },
|
|
567
|
+
'kai-hover-card': { slots: HOVER_CARD_SLOTS },
|
|
568
|
+
'kai-menu': { slots: MENU_SLOTS, parts: MENU_PARTS },
|
|
569
|
+
'kai-skeleton': { parts: SKELETON_PARTS },
|
|
570
|
+
'kai-attachments': { parts: ATTACHMENTS_PARTS },
|
|
571
|
+
'kai-status': { parts: STATUS_PARTS },
|
|
572
|
+
'kai-tabs': { parts: TABS_PARTS },
|
|
573
|
+
'kai-voice-output': { parts: VOICE_OUTPUT_PARTS },
|
|
574
|
+
'kai-screen': { slots: SCREEN_SLOTS, parts: SCREEN_PARTS },
|
|
575
|
+
'kai-card': { slots: CARD_SLOTS, parts: CARD_PARTS },
|
|
576
|
+
'kai-workspace': { slots: WORKSPACE_SLOTS, parts: WORKSPACE_PARTS },
|
|
577
|
+
'kai-nav': { parts: NAV_PARTS },
|
|
578
|
+
'kai-coachmark': { slots: COACHMARK_SLOTS, parts: COACHMARK_PARTS },
|
|
579
|
+
'kai-progress-bar': { parts: PROGRESS_BAR_PARTS },
|
|
580
|
+
'kai-file-tree': { parts: FILE_TREE_PARTS },
|
|
581
|
+
'kai-prompt-dock': { slots: PROMPT_DOCK_SLOTS, parts: PROMPT_DOCK_PARTS },
|
|
582
|
+
'kai-segmented': { parts: SEGMENTED_PARTS },
|
|
583
|
+
'kai-settings-group': { parts: SETTINGS_GROUP_PARTS },
|
|
584
|
+
'kai-setting-item': { slots: SETTING_ITEM_SLOTS, parts: SETTING_ITEM_PARTS },
|
|
585
|
+
'kai-pane': { slots: PANE_SLOTS, parts: PANE_PARTS },
|
|
586
|
+
'kai-pane-group': { parts: PANE_GROUP_PARTS },
|
|
587
|
+
'kai-agent-card': { parts: AGENT_CARD_PARTS },
|
|
588
|
+
'kai-dialog': { slots: DIALOG_SLOTS, parts: DIALOG_PARTS },
|
|
589
|
+
'kai-input': { slots: INPUT_SLOTS, parts: INPUT_PARTS },
|
|
590
|
+
'kai-search': { parts: SEARCH_PARTS },
|
|
591
|
+
'kai-kbd': { parts: KBD_PARTS },
|
|
592
|
+
'kai-editable-label': { parts: EDITABLE_LABEL_PARTS },
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Which slots have projected light-DOM content — a DIRECT child of `host`
|
|
597
|
+
* carrying the matching `slot` attribute. Pure and synchronous; safe in jsdom
|
|
598
|
+
* and SSR (returns all-false when `host` has no matching children). The facade
|
|
599
|
+
* calls this on mount and on every childList mutation.
|
|
600
|
+
*/
|
|
601
|
+
export function readSlots(host: Element, defs: SlotDef[] = CHAT_SLOTS): Record<string, boolean> {
|
|
602
|
+
const out: Record<string, boolean> = {};
|
|
603
|
+
for (const def of defs) {
|
|
604
|
+
out[def.name] = !!host.querySelector(`:scope > [slot="${def.name}"]`);
|
|
605
|
+
}
|
|
606
|
+
return out;
|
|
607
|
+
}
|
package/src/elements/source.tsx
CHANGED
|
@@ -25,12 +25,19 @@ defineWebComponent<SourceProps>('kai-source', {
|
|
|
25
25
|
description: '',
|
|
26
26
|
showFavicon: false,
|
|
27
27
|
}, (props, { flag }) => (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
<>
|
|
29
|
+
{/* The shared element base sets `:host{display:block}` (styles.css). A block host
|
|
30
|
+
makes each citation chip its own line box, so inline `[n]` markers stack and
|
|
31
|
+
push the trailing prose/period to a new line. inline-flex (like kai-button /
|
|
32
|
+
kai-tooltip) drops the line box so the chip flows inline with the answer text. */}
|
|
33
|
+
<style>{':host{display:inline-flex}'}</style>
|
|
34
|
+
<Show when={props.href}>
|
|
35
|
+
<Source href={props.href!}>
|
|
36
|
+
<SourceTrigger label={props.label} showFavicon={flag('showFavicon')} />
|
|
37
|
+
<SourceContent title={props.headline ?? ''} description={props.description ?? ''} />
|
|
38
|
+
</Source>
|
|
39
|
+
</Show>
|
|
40
|
+
</>
|
|
34
41
|
));
|
|
35
42
|
|
|
36
43
|
// --- <kai-sources> — a wrapped list of citation links ---
|