@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
package/src/elements/define.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { customElement } from 'solid-element';
|
|
2
2
|
import { ChatConfig } from '../primitives/chat-config';
|
|
3
3
|
import { ELEMENT_CSS } from './css';
|
|
4
|
-
import { createSignal, onCleanup,
|
|
4
|
+
import { createSignal, onCleanup, Show, type JSX } from 'solid-js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Shared constructable stylesheet, built once and adopted by every element's
|
|
@@ -67,6 +67,17 @@ export interface WebComponentContext<E = Record<string, unknown>> {
|
|
|
67
67
|
* `name` is the camelCase prop name; the matching kebab attribute is derived.
|
|
68
68
|
*/
|
|
69
69
|
flag: (name: string) => boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Expose imperative methods on the host element instance — the input half of a
|
|
72
|
+
* component's interaction surface (`el.focus()`, `el.clear()`, `el.scrollToBottom()`,
|
|
73
|
+
* …), the counterpart to the events `dispatch` fires. Call once from the facade
|
|
74
|
+
* with closures over its internal state/refs; each entry is assigned to the host,
|
|
75
|
+
* so a consumer calls it directly: `document.querySelector('kai-prompt-input').focus()`.
|
|
76
|
+
* Overriding a native method name (e.g. `focus`) shadows it on the instance so it
|
|
77
|
+
* can target the right control inside the shadow root (the WebAwesome/Shoelace
|
|
78
|
+
* convention). Methods are attached when the facade renders (on element upgrade).
|
|
79
|
+
*/
|
|
80
|
+
expose: (methods: Record<string, (...args: never[]) => unknown>) => void;
|
|
70
81
|
}
|
|
71
82
|
|
|
72
83
|
/** camelCase prop name → kebab-case attribute (`hoverCard` → `hover-card`). */
|
|
@@ -77,6 +88,8 @@ function toAttr(name: string): string {
|
|
|
77
88
|
/** Underlying flag resolution; see `WebComponentContext.flag`. */
|
|
78
89
|
function resolveFlag(element: HTMLElement, value: unknown, attribute: string): boolean {
|
|
79
90
|
if (value === true) return true;
|
|
91
|
+
// An explicit JS false wins over a present attribute (see WebComponentContext.flag); this also prevents a feedback loop when an effect writes the attribute it reads.
|
|
92
|
+
if (value === false) return false;
|
|
80
93
|
return element.hasAttribute(attribute) && element.getAttribute(attribute) !== 'false';
|
|
81
94
|
}
|
|
82
95
|
|
|
@@ -124,13 +137,27 @@ export function defineWebComponent<P extends Record<string, unknown>, E = Record
|
|
|
124
137
|
}
|
|
125
138
|
}
|
|
126
139
|
|
|
140
|
+
// Props that NAME a reflected global IDL accessor (today: only `role`, from
|
|
141
|
+
// ARIAMixin's Element.prototype.role). Unlike RESERVED (which throws), these are
|
|
142
|
+
// allowed as plain styling props, but they must NEVER reach the host as an
|
|
143
|
+
// attribute: kai-message uses role='user'|'assistant' to pick its layout, and
|
|
144
|
+
// those are not valid ARIA roles, so a reflected role="user" / role="assistant"
|
|
145
|
+
// fails axe's aria-roles rule. The native IDL setter reflects to an attribute
|
|
146
|
+
// whenever the property is set BEFORE connectedCallback (e.g. in a framework
|
|
147
|
+
// `ref`: `el.role = 'user'`), which is the window before component-register
|
|
148
|
+
// installs its own (non-reflecting) per-instance accessor in initializeProps. We
|
|
149
|
+
// shadow the native accessor on the element prototype with a plain non-reflecting
|
|
150
|
+
// one, so setting the property only STORES the value (component-register still
|
|
151
|
+
// reads it back for styling) and never touches a host attribute.
|
|
152
|
+
const NON_REFLECTING = ['role'];
|
|
153
|
+
|
|
127
154
|
// Every element gets a `theme` property/attribute: 'light' | 'dark' | 'auto'
|
|
128
155
|
// (default 'auto' = follow the OS `prefers-color-scheme`). It drives a `.dark`
|
|
129
156
|
// class on an inner wrapper, which the injected kit CSS already styles — so dark
|
|
130
157
|
// mode works in standalone Shadow-DOM usage with no token duplication.
|
|
131
158
|
const defaults = { theme: 'auto', ...propDefaults };
|
|
132
159
|
|
|
133
|
-
customElement(tag, defaults, (props: typeof defaults, options: { element: object }) => {
|
|
160
|
+
const Ctor = customElement(tag, defaults, (props: typeof defaults, options: { element: object }) => {
|
|
134
161
|
const element = options.element as HTMLElement;
|
|
135
162
|
let portalNode!: HTMLDivElement;
|
|
136
163
|
|
|
@@ -144,17 +171,45 @@ export function defineWebComponent<P extends Record<string, unknown>, E = Record
|
|
|
144
171
|
const flag = (name: string) =>
|
|
145
172
|
resolveFlag(element, (props as Record<string, unknown>)[name], toAttr(name));
|
|
146
173
|
|
|
174
|
+
// Attach imperative methods onto the host instance. See WebComponentContext.expose.
|
|
175
|
+
// Uses defineProperty so a method can shadow an inherited getter-only accessor
|
|
176
|
+
// (e.g. `focus`/`blur`) which a plain assignment would throw on. A method name
|
|
177
|
+
// must NOT collide with a declared prop (the prop's accessor would be clobbered)
|
|
178
|
+
// — pick a distinct verb (e.g. `send()` next to a `submit` prop). Failures warn
|
|
179
|
+
// and skip rather than breaking the element's render.
|
|
180
|
+
const expose: WebComponentContext<E>['expose'] = (methods) => {
|
|
181
|
+
for (const [name, fn] of Object.entries(methods)) {
|
|
182
|
+
try {
|
|
183
|
+
Object.defineProperty(element, name, { value: fn, writable: true, configurable: true });
|
|
184
|
+
} catch (err) {
|
|
185
|
+
console.warn(`defineWebComponent(${tag}): could not expose method "${name}"`, err);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
147
190
|
const isDark = createDarkMode(() => props.theme as string | undefined);
|
|
148
191
|
|
|
149
192
|
// Prefer a single shared stylesheet adopted into this shadow root; only emit
|
|
150
193
|
// an inline <style> when Constructable Stylesheets aren't supported.
|
|
194
|
+
//
|
|
195
|
+
// Adopt SYNCHRONOUSLY, before solid-element inserts the rendered content into
|
|
196
|
+
// the shadow root. component-register attaches the shadow root lazily on first
|
|
197
|
+
// `renderRoot` access — which happens during that insert, AFTER this facade
|
|
198
|
+
// function returns. So we pre-attach the shadow root here (with the same
|
|
199
|
+
// `mode: 'open'` the renderRoot getter would use, making it a no-op for
|
|
200
|
+
// solid-element) and adopt the sheet now. If we deferred to onMount instead,
|
|
201
|
+
// the content would paint UNSTYLED and then animate from that bare state to
|
|
202
|
+
// its resting style once the sheet landed — every `transition-colors` button
|
|
203
|
+
// and menu/dropdown trigger flashing as if hovered-then-un-hovered on first
|
|
204
|
+
// render. Adopting first means the very first computed style of every node is
|
|
205
|
+
// already the resting style, so no transition can fire on load.
|
|
151
206
|
const sheet = getSharedSheet();
|
|
152
|
-
|
|
153
|
-
const root = element.shadowRoot;
|
|
154
|
-
if (
|
|
207
|
+
if (sheet) {
|
|
208
|
+
const root = element.shadowRoot ?? element.attachShadow({ mode: 'open' });
|
|
209
|
+
if ('adoptedStyleSheets' in root && !root.adoptedStyleSheets.includes(sheet)) {
|
|
155
210
|
root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];
|
|
156
211
|
}
|
|
157
|
-
}
|
|
212
|
+
}
|
|
158
213
|
|
|
159
214
|
return (
|
|
160
215
|
<>
|
|
@@ -168,10 +223,35 @@ export function defineWebComponent<P extends Record<string, unknown>, E = Record
|
|
|
168
223
|
<div classList={{ dark: isDark() }} style={{ display: 'contents', color: 'var(--color-foreground)' }}>
|
|
169
224
|
<div ref={portalNode} />
|
|
170
225
|
<ChatConfig portalMount={portalNode}>
|
|
171
|
-
{Facade(props as unknown as P, { element, dispatch, flag })}
|
|
226
|
+
{Facade(props as unknown as P, { element, dispatch, flag, expose })}
|
|
172
227
|
</ChatConfig>
|
|
173
228
|
</div>
|
|
174
229
|
</>
|
|
175
230
|
);
|
|
176
231
|
});
|
|
232
|
+
|
|
233
|
+
// Shadow any reflected native IDL accessor this element re-uses as a prop (see
|
|
234
|
+
// NON_REFLECTING) with a plain, non-reflecting store on the element prototype.
|
|
235
|
+
// This must live on the prototype (not the instance) so it is already in place
|
|
236
|
+
// when the value is set before connectedCallback, the window in which the native
|
|
237
|
+
// setter would otherwise reflect it to a host attribute. component-register reads
|
|
238
|
+
// the property back during initializeProps to seed the styling prop, and later
|
|
239
|
+
// shadows this with its own (also non-reflecting) per-instance accessor.
|
|
240
|
+
const proto = (Ctor as unknown as { prototype?: object } | undefined)?.prototype;
|
|
241
|
+
if (proto) {
|
|
242
|
+
for (const key of NON_REFLECTING) {
|
|
243
|
+
if (!(key in defaults)) continue;
|
|
244
|
+
const store = Symbol(`kai-prop:${key}`);
|
|
245
|
+
Object.defineProperty(proto, key, {
|
|
246
|
+
get(this: Record<symbol, unknown>) {
|
|
247
|
+
return this[store];
|
|
248
|
+
},
|
|
249
|
+
set(this: Record<symbol, unknown>, value: unknown) {
|
|
250
|
+
this[store] = value;
|
|
251
|
+
},
|
|
252
|
+
enumerable: true,
|
|
253
|
+
configurable: true,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
177
257
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createSignal, onCleanup, onMount } from 'solid-js';
|
|
2
|
+
import { defineWebComponent } from './define';
|
|
3
|
+
import { Dialog, type DialogController } from '../ui/dialog';
|
|
4
|
+
import { wireDisclosure } from './disclosure';
|
|
5
|
+
|
|
6
|
+
interface Props extends Record<string, unknown> {
|
|
7
|
+
/** Drive/observe open state (Shoelace-style: settable + reflected to the `open`
|
|
8
|
+
* attribute; the element still self-manages on Escape/backdrop). Set
|
|
9
|
+
* `el.open = true`, or `<kai-dialog open>`; listen for `kai-open-change`. */
|
|
10
|
+
open?: boolean;
|
|
11
|
+
/** Initial open state on mount (uncontrolled seed). */
|
|
12
|
+
defaultOpen?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Events fired by `<kai-dialog>`. */
|
|
16
|
+
interface Events {
|
|
17
|
+
/** The dialog opened or closed (Escape, backdrop click, a driven `open`, or a method). */
|
|
18
|
+
'kai-open-change': { open: boolean };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* `<kai-dialog>` — a centered modal: a dimmed backdrop over the page with a
|
|
23
|
+
* centered panel of arbitrary content. It is the real primitive behind the kind
|
|
24
|
+
* of modal that settings panels and broadcast composers reach for.
|
|
25
|
+
*
|
|
26
|
+
* **How to use** — slot the body, and optionally a `header` and `footer`:
|
|
27
|
+
* ```html
|
|
28
|
+
* <kai-dialog open>
|
|
29
|
+
* <h2 slot="header">Broadcast a message</h2>
|
|
30
|
+
* <textarea placeholder="What's on your mind?"></textarea>
|
|
31
|
+
* <div slot="footer">
|
|
32
|
+
* <button onclick="this.closest('kai-dialog').hide()">Cancel</button>
|
|
33
|
+
* <button>Send</button>
|
|
34
|
+
* </div>
|
|
35
|
+
* </kai-dialog>
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* The default slot is the body; `header`/`footer` are optional regions with
|
|
39
|
+
* dividers. The backdrop dims the page; clicking it (or pressing Escape) closes
|
|
40
|
+
* the dialog. Focus moves into the panel on open and is restored on close, and a
|
|
41
|
+
* basic Tab focus trap keeps keyboard focus inside while open.
|
|
42
|
+
*
|
|
43
|
+
* Open state is the standard disclosure surface: settable+reflecting `open`,
|
|
44
|
+
* `kai-open-change`, and `show()`/`hide()`/`toggle()`; seed with `default-open`.
|
|
45
|
+
* It also exposes `focus()` to move focus to the panel. Parts: `backdrop` ·
|
|
46
|
+
* `panel` · `header` · `body` · `footer`.
|
|
47
|
+
*/
|
|
48
|
+
defineWebComponent<Props, Events>('kai-dialog', {
|
|
49
|
+
open: undefined,
|
|
50
|
+
defaultOpen: undefined,
|
|
51
|
+
}, (props, ctx) => {
|
|
52
|
+
const { flag, element, expose } = ctx;
|
|
53
|
+
let api: DialogController | undefined;
|
|
54
|
+
let panel: HTMLElement | undefined;
|
|
55
|
+
|
|
56
|
+
// The standard disclosure surface: settable+reflecting `open`, kai-open-change,
|
|
57
|
+
// show/hide/toggle. See ./disclosure. The SOLE emitter of kai-open-change — the
|
|
58
|
+
// primitive's onOpenChange is intentionally NOT wired here to avoid a double
|
|
59
|
+
// dispatch.
|
|
60
|
+
wireDisclosure(ctx, () => api, () => props.open);
|
|
61
|
+
|
|
62
|
+
// Only render the header/footer chrome (border + padding) when the consumer has
|
|
63
|
+
// actually projected content for that slot — otherwise an empty bordered region
|
|
64
|
+
// would show. Tracked off the host's light-DOM children.
|
|
65
|
+
const [hasHeader, setHasHeader] = createSignal(false);
|
|
66
|
+
const [hasFooter, setHasFooter] = createSignal(false);
|
|
67
|
+
const recompute = () => {
|
|
68
|
+
setHasHeader(!!element.querySelector(':scope > [slot="header"]'));
|
|
69
|
+
setHasFooter(!!element.querySelector(':scope > [slot="footer"]'));
|
|
70
|
+
};
|
|
71
|
+
onMount(() => {
|
|
72
|
+
recompute();
|
|
73
|
+
if (typeof MutationObserver === 'function') {
|
|
74
|
+
const obs = new MutationObserver(recompute);
|
|
75
|
+
obs.observe(element, { childList: true });
|
|
76
|
+
onCleanup(() => obs.disconnect());
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// focus() shadows the host's native focus so it targets the dialog panel inside
|
|
81
|
+
// the shadow root (the WebAwesome/Shoelace convention).
|
|
82
|
+
expose({
|
|
83
|
+
/** Move focus to the dialog panel (no-op while closed). */
|
|
84
|
+
focus: (options?: FocusOptions) => panel?.focus(options),
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<Dialog
|
|
89
|
+
defaultOpen={flag('defaultOpen')}
|
|
90
|
+
header={hasHeader() ? <slot name="header" /> : undefined}
|
|
91
|
+
footer={hasFooter() ? <slot name="footer" /> : undefined}
|
|
92
|
+
controllerRef={(a) => (api = a)}
|
|
93
|
+
panelRef={(el) => (panel = el)}
|
|
94
|
+
>
|
|
95
|
+
<slot />
|
|
96
|
+
</Dialog>
|
|
97
|
+
);
|
|
98
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createEffect, untrack, type Accessor } from 'solid-js';
|
|
2
|
+
import type { WebComponentContext } from './define';
|
|
3
|
+
|
|
4
|
+
/** The open controller a primitive hands up via `controllerRef` so a facade can
|
|
5
|
+
* drive + observe its open/closed state. */
|
|
6
|
+
export interface OpenController {
|
|
7
|
+
open: Accessor<boolean>;
|
|
8
|
+
setOpen: (v: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Wire the standard Shoelace/WebAwesome-style overlay surface onto an internal
|
|
13
|
+
* open controller — the kit's convention for every open/close element (hover-card,
|
|
14
|
+
* tooltip, popover, menu, model-switcher, scope-picker, collapsibles, …). NOT
|
|
15
|
+
* React-controlled: the element keeps self-managing; this layers the host-facing
|
|
16
|
+
* conveniences on top.
|
|
17
|
+
*
|
|
18
|
+
* Given the primitive's `{ open, setOpen }` controller, it provides:
|
|
19
|
+
* - **`open` reflects** to the host `[open]` attribute (for `:host([open])` CSS),
|
|
20
|
+
* and is **settable** — `el.open = true` / `<el open>` drives it;
|
|
21
|
+
* - **`kai-open-change` `{ open }`** fires once per change (a guarded reflect
|
|
22
|
+
* avoids the attribute⇄prop feedback loop);
|
|
23
|
+
* - **`show()` / `hide()` / `toggle()`** instance methods, gated by `disabled`.
|
|
24
|
+
*
|
|
25
|
+
* The facade still:
|
|
26
|
+
* - declares the `open` / `defaultOpen` / `disabled` props (defaults `undefined`),
|
|
27
|
+
* - seeds the primitive from `defaultOpen` (e.g. via the primitive's own prop),
|
|
28
|
+
* - includes `'kai-open-change': { open: boolean }` in its `Events` map.
|
|
29
|
+
*
|
|
30
|
+
* @param ctx the facade's WebComponentContext (its Events must include kai-open-change).
|
|
31
|
+
* @param getApi returns the open controller once the primitive has handed it up (may be undefined early).
|
|
32
|
+
* @param openProp reads the raw reactive `open` prop (e.g. `() => props.open`) — used to tell
|
|
33
|
+
* "consumer explicitly set open" from "unset" so a `defaultOpen` seed isn't clobbered.
|
|
34
|
+
*/
|
|
35
|
+
export function wireDisclosure<E extends { 'kai-open-change': { open: boolean } }>(
|
|
36
|
+
ctx: WebComponentContext<E>,
|
|
37
|
+
getApi: () => OpenController | undefined,
|
|
38
|
+
openProp: () => unknown,
|
|
39
|
+
): void {
|
|
40
|
+
const { element, dispatch, flag, expose } = ctx;
|
|
41
|
+
let prev: boolean | undefined;
|
|
42
|
+
|
|
43
|
+
// Reflect internal open → the `[open]` host attribute + fire kai-open-change.
|
|
44
|
+
createEffect(() => {
|
|
45
|
+
const api = getApi();
|
|
46
|
+
if (!api) return;
|
|
47
|
+
const o = api.open();
|
|
48
|
+
element.toggleAttribute('open', o);
|
|
49
|
+
if (prev !== undefined && prev !== o) dispatch('kai-open-change', { open: o } as E['kai-open-change']);
|
|
50
|
+
prev = o;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// External `open` prop/attr → drive internal state. Only when the consumer has
|
|
54
|
+
// EXPLICITLY set it (so a defaultOpen seed survives mount); the equality guard
|
|
55
|
+
// keeps the reflect above from looping back through the prop.
|
|
56
|
+
createEffect(() => {
|
|
57
|
+
const api = getApi();
|
|
58
|
+
if (!api) return;
|
|
59
|
+
const explicit = openProp() !== undefined || element.hasAttribute('open');
|
|
60
|
+
if (!explicit) return;
|
|
61
|
+
const desired = flag('open');
|
|
62
|
+
if (desired !== untrack(api.open)) api.setOpen(desired);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
expose({
|
|
66
|
+
/** Open it programmatically (no-op while disabled). */
|
|
67
|
+
show: () => { if (!flag('disabled')) getApi()?.setOpen(true); },
|
|
68
|
+
/** Close it programmatically. */
|
|
69
|
+
hide: () => getApi()?.setOpen(false),
|
|
70
|
+
/** Flip the open state (closes while disabled). */
|
|
71
|
+
toggle: () => { const api = getApi(); if (api) api.setOpen(flag('disabled') ? false : !api.open()); },
|
|
72
|
+
});
|
|
73
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createEffect, createSignal, untrack } from 'solid-js';
|
|
2
|
+
import { defineWebComponent } from './define';
|
|
3
|
+
import { EditableLabel } from '../ui/editable-label';
|
|
4
|
+
|
|
5
|
+
interface Props extends Record<string, unknown> {
|
|
6
|
+
/** The label text — settable and reflected to the `value` attribute. Read
|
|
7
|
+
* `el.value` for live state. */
|
|
8
|
+
value?: string;
|
|
9
|
+
/** Controlled edit state. `el.editing = true` opens the field; reflected to the
|
|
10
|
+
* `editing` attribute. */
|
|
11
|
+
editing?: boolean;
|
|
12
|
+
/** Placeholder shown while editing / when the value is empty. */
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
/** Disable entering edit mode. */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Events fired by `<kai-editable-label>`. */
|
|
19
|
+
interface Events {
|
|
20
|
+
/** Committed a changed value (Enter / blur). */
|
|
21
|
+
'kai-rename': { value: string };
|
|
22
|
+
/** Edit was cancelled (Esc); the text is restored. */
|
|
23
|
+
'kai-cancel': Record<string, never>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* `<kai-editable-label>` — inline rename, built on `kai-input`. Shows `value` as
|
|
28
|
+
* text; double-click (or `el.edit()`, or `editing`) swaps in an autofocused
|
|
29
|
+
* field. Enter or blur commits → `kai-rename` (only when the value changed); Esc
|
|
30
|
+
* cancels → `kai-cancel` (the text is restored).
|
|
31
|
+
*
|
|
32
|
+
* ```html
|
|
33
|
+
* <kai-editable-label value="Project Alpha"></kai-editable-label>
|
|
34
|
+
* <script type="module">
|
|
35
|
+
* import '@kitn.ai/ui/elements';
|
|
36
|
+
* const label = document.querySelector('kai-editable-label');
|
|
37
|
+
* label.addEventListener('kai-rename', (e) => save(e.detail.value));
|
|
38
|
+
* label.edit(); // open the field programmatically
|
|
39
|
+
* </script>
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* Methods: `edit()`, `commit()`, `cancel()`. Restyle via `::part(text)` and
|
|
43
|
+
* `::part(input)`.
|
|
44
|
+
*/
|
|
45
|
+
defineWebComponent<Props, Events>('kai-editable-label', {
|
|
46
|
+
value: undefined,
|
|
47
|
+
editing: false,
|
|
48
|
+
placeholder: undefined,
|
|
49
|
+
disabled: false,
|
|
50
|
+
}, (props, ctx) => {
|
|
51
|
+
const { element, dispatch, flag, expose } = ctx;
|
|
52
|
+
|
|
53
|
+
// Controlled value, mirrored to the `value` attribute (the kai-segmented pattern).
|
|
54
|
+
const [value, setValue] = createSignal(
|
|
55
|
+
(props.value as string | undefined) ?? element.getAttribute('value') ?? '',
|
|
56
|
+
);
|
|
57
|
+
const coerce = (v: unknown): string =>
|
|
58
|
+
v == null ? (element.getAttribute('value') ?? '') : String(v);
|
|
59
|
+
Object.defineProperty(element, 'value', {
|
|
60
|
+
get: () => value(),
|
|
61
|
+
set: (v: unknown) => { const next = coerce(v); if (untrack(value) !== next) setValue(next); },
|
|
62
|
+
configurable: true,
|
|
63
|
+
enumerable: true,
|
|
64
|
+
});
|
|
65
|
+
createEffect(() => {
|
|
66
|
+
const v = value();
|
|
67
|
+
if (v) {
|
|
68
|
+
if (element.getAttribute('value') !== v) element.setAttribute('value', v);
|
|
69
|
+
} else if (element.hasAttribute('value')) {
|
|
70
|
+
element.removeAttribute('value');
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Edit state lives in the facade and drives the primitive. The methods map to
|
|
75
|
+
// the primitive's own gestures so every commit / cancel flows through its guarded
|
|
76
|
+
// Enter/Esc/blur handlers (no double-fire). Controlled `editing` rides the native
|
|
77
|
+
// solid-element prop/attribute: we follow it (so `el.editing = true` /
|
|
78
|
+
// `<kai-editable-label editing>` opens the field) and reflect it, but never
|
|
79
|
+
// override the property with a side-effecting `Object.defineProperty` — doing so
|
|
80
|
+
// fires the setter during solid-element's upgrade and corrupts the signal.
|
|
81
|
+
const [editing, setEditing] = createSignal(flag('editing'));
|
|
82
|
+
createEffect(() => setEditing(flag('editing')));
|
|
83
|
+
createEffect(() => {
|
|
84
|
+
if (editing()) {
|
|
85
|
+
if (!element.hasAttribute('editing')) element.setAttribute('editing', '');
|
|
86
|
+
} else if (element.hasAttribute('editing')) {
|
|
87
|
+
element.removeAttribute('editing');
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const getInput = (): HTMLInputElement | null =>
|
|
92
|
+
element.shadowRoot?.querySelector<HTMLInputElement>('input') ?? null;
|
|
93
|
+
|
|
94
|
+
const enter = () => { if (!flag('disabled')) setEditing(true); };
|
|
95
|
+
// Blur drives the primitive's blur-commit; Escape drives its cancel.
|
|
96
|
+
const commit = () => { getInput()?.blur(); };
|
|
97
|
+
const cancel = () => {
|
|
98
|
+
const input = getInput();
|
|
99
|
+
if (input) {
|
|
100
|
+
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true, composed: true }));
|
|
101
|
+
} else if (untrack(editing)) {
|
|
102
|
+
setEditing(false);
|
|
103
|
+
dispatch('kai-cancel', {});
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
expose({ edit: enter, commit, cancel });
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<>
|
|
111
|
+
<style>{':host{display:inline-flex}'}</style>
|
|
112
|
+
<EditableLabel
|
|
113
|
+
value={value()}
|
|
114
|
+
editing={editing()}
|
|
115
|
+
placeholder={props.placeholder as string | undefined}
|
|
116
|
+
disabled={flag('disabled')}
|
|
117
|
+
onRename={(next) => {
|
|
118
|
+
setEditing(false);
|
|
119
|
+
if (next !== untrack(value)) { setValue(next); dispatch('kai-rename', { value: next }); }
|
|
120
|
+
}}
|
|
121
|
+
onCancel={() => { setEditing(false); dispatch('kai-cancel', {}); }}
|
|
122
|
+
/>
|
|
123
|
+
</>
|
|
124
|
+
);
|
|
125
|
+
});
|
|
@@ -27,6 +27,13 @@
|
|
|
27
27
|
"kai-sources": "source",
|
|
28
28
|
"kai-response-stream": "response-stream",
|
|
29
29
|
"kai-empty": "empty",
|
|
30
|
+
"kai-status": "status",
|
|
31
|
+
"kai-nav": "nav",
|
|
32
|
+
"kai-progress-bar": "progress-bar",
|
|
33
|
+
"kai-coachmark": "coachmark",
|
|
34
|
+
"kai-tabs": "tabs",
|
|
35
|
+
"kai-voice-output": "voice-output",
|
|
36
|
+
"kai-screen": "screen",
|
|
30
37
|
"kai-chain-of-thought": "chain-of-thought",
|
|
31
38
|
"kai-resizable": "resizable",
|
|
32
39
|
"kai-resizable-item": "resizable",
|
|
@@ -35,6 +42,16 @@
|
|
|
35
42
|
"kai-scroll-button": "scroll-button",
|
|
36
43
|
"kai-popover": "popover",
|
|
37
44
|
"kai-switch": "switch",
|
|
45
|
+
"kai-button": "button",
|
|
46
|
+
"kai-avatar": "avatar",
|
|
47
|
+
"kai-badge": "badge",
|
|
48
|
+
"kai-tooltip": "tooltip",
|
|
49
|
+
"kai-notice": "notice",
|
|
50
|
+
"kai-icon": "icon",
|
|
51
|
+
"kai-separator": "separator",
|
|
52
|
+
"kai-scroll-area": "scroll-area",
|
|
53
|
+
"kai-hover-card": "hover-card",
|
|
54
|
+
"kai-skeleton": "skeleton",
|
|
38
55
|
"kai-toast-region": "toast",
|
|
39
56
|
"kai-card": "card",
|
|
40
57
|
"kai-form": "form",
|
|
@@ -44,7 +61,22 @@
|
|
|
44
61
|
"kai-tasks": "tasks",
|
|
45
62
|
"kai-choice": "choice",
|
|
46
63
|
"kai-cards": "cards",
|
|
47
|
-
"kai-compare": "compare"
|
|
64
|
+
"kai-compare": "compare",
|
|
65
|
+
"kai-composer": "composer",
|
|
66
|
+
"kai-menu": "menu",
|
|
67
|
+
"kai-command": "command",
|
|
68
|
+
"kai-prompt-dock": "prompt-dock",
|
|
69
|
+
"kai-segmented": "segmented",
|
|
70
|
+
"kai-settings-group": "settings-group",
|
|
71
|
+
"kai-setting-item": "setting-item",
|
|
72
|
+
"kai-pane": "pane",
|
|
73
|
+
"kai-pane-group": "pane-group",
|
|
74
|
+
"kai-agent-card": "agent-card",
|
|
75
|
+
"kai-dialog": "dialog",
|
|
76
|
+
"kai-input": "input",
|
|
77
|
+
"kai-search": "search",
|
|
78
|
+
"kai-kbd": "kbd",
|
|
79
|
+
"kai-editable-label": "editable-label"
|
|
48
80
|
},
|
|
49
81
|
"files": {
|
|
50
82
|
"conversation-list": [
|
|
@@ -126,6 +158,27 @@
|
|
|
126
158
|
"empty": [
|
|
127
159
|
"kai-empty"
|
|
128
160
|
],
|
|
161
|
+
"status": [
|
|
162
|
+
"kai-status"
|
|
163
|
+
],
|
|
164
|
+
"nav": [
|
|
165
|
+
"kai-nav"
|
|
166
|
+
],
|
|
167
|
+
"progress-bar": [
|
|
168
|
+
"kai-progress-bar"
|
|
169
|
+
],
|
|
170
|
+
"coachmark": [
|
|
171
|
+
"kai-coachmark"
|
|
172
|
+
],
|
|
173
|
+
"tabs": [
|
|
174
|
+
"kai-tabs"
|
|
175
|
+
],
|
|
176
|
+
"voice-output": [
|
|
177
|
+
"kai-voice-output"
|
|
178
|
+
],
|
|
179
|
+
"screen": [
|
|
180
|
+
"kai-screen"
|
|
181
|
+
],
|
|
129
182
|
"chain-of-thought": [
|
|
130
183
|
"kai-chain-of-thought"
|
|
131
184
|
],
|
|
@@ -148,6 +201,36 @@
|
|
|
148
201
|
"switch": [
|
|
149
202
|
"kai-switch"
|
|
150
203
|
],
|
|
204
|
+
"button": [
|
|
205
|
+
"kai-button"
|
|
206
|
+
],
|
|
207
|
+
"avatar": [
|
|
208
|
+
"kai-avatar"
|
|
209
|
+
],
|
|
210
|
+
"badge": [
|
|
211
|
+
"kai-badge"
|
|
212
|
+
],
|
|
213
|
+
"tooltip": [
|
|
214
|
+
"kai-tooltip"
|
|
215
|
+
],
|
|
216
|
+
"notice": [
|
|
217
|
+
"kai-notice"
|
|
218
|
+
],
|
|
219
|
+
"icon": [
|
|
220
|
+
"kai-icon"
|
|
221
|
+
],
|
|
222
|
+
"separator": [
|
|
223
|
+
"kai-separator"
|
|
224
|
+
],
|
|
225
|
+
"scroll-area": [
|
|
226
|
+
"kai-scroll-area"
|
|
227
|
+
],
|
|
228
|
+
"hover-card": [
|
|
229
|
+
"kai-hover-card"
|
|
230
|
+
],
|
|
231
|
+
"skeleton": [
|
|
232
|
+
"kai-skeleton"
|
|
233
|
+
],
|
|
151
234
|
"toast": [
|
|
152
235
|
"kai-toast-region"
|
|
153
236
|
],
|
|
@@ -177,6 +260,51 @@
|
|
|
177
260
|
],
|
|
178
261
|
"compare": [
|
|
179
262
|
"kai-compare"
|
|
263
|
+
],
|
|
264
|
+
"composer": [
|
|
265
|
+
"kai-composer"
|
|
266
|
+
],
|
|
267
|
+
"menu": [
|
|
268
|
+
"kai-menu"
|
|
269
|
+
],
|
|
270
|
+
"command": [
|
|
271
|
+
"kai-command"
|
|
272
|
+
],
|
|
273
|
+
"prompt-dock": [
|
|
274
|
+
"kai-prompt-dock"
|
|
275
|
+
],
|
|
276
|
+
"segmented": [
|
|
277
|
+
"kai-segmented"
|
|
278
|
+
],
|
|
279
|
+
"settings-group": [
|
|
280
|
+
"kai-settings-group"
|
|
281
|
+
],
|
|
282
|
+
"setting-item": [
|
|
283
|
+
"kai-setting-item"
|
|
284
|
+
],
|
|
285
|
+
"pane": [
|
|
286
|
+
"kai-pane"
|
|
287
|
+
],
|
|
288
|
+
"pane-group": [
|
|
289
|
+
"kai-pane-group"
|
|
290
|
+
],
|
|
291
|
+
"agent-card": [
|
|
292
|
+
"kai-agent-card"
|
|
293
|
+
],
|
|
294
|
+
"dialog": [
|
|
295
|
+
"kai-dialog"
|
|
296
|
+
],
|
|
297
|
+
"input": [
|
|
298
|
+
"kai-input"
|
|
299
|
+
],
|
|
300
|
+
"search": [
|
|
301
|
+
"kai-search"
|
|
302
|
+
],
|
|
303
|
+
"kbd": [
|
|
304
|
+
"kai-kbd"
|
|
305
|
+
],
|
|
306
|
+
"editable-label": [
|
|
307
|
+
"kai-editable-label"
|
|
180
308
|
]
|
|
181
309
|
}
|
|
182
310
|
}
|