@kitn.ai/ui 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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-DLLBeLG5.js +1 -0
- package/dist/elements/chunks/action-icons-UB4V5FNq.js +1 -0
- package/dist/elements/chunks/arrow-left-C-gwlUmx.js +1 -0
- package/dist/elements/chunks/attachments-CgbErf1r.js +1 -0
- package/dist/elements/chunks/badge-DTQpgB6N.js +1 -0
- package/dist/elements/chunks/button-XDUM6lXs.js +1 -0
- package/dist/elements/chunks/card-CBlFZ-7I.js +1 -0
- package/dist/elements/chunks/chat-thread-BIhmqwNL.js +1 -0
- package/dist/elements/chunks/check-hGUoVIKb.js +1 -0
- package/dist/elements/chunks/chevron-down-DDoaSUtO.js +1 -0
- package/dist/elements/chunks/chevron-right-CdGEUakB.js +1 -0
- package/dist/elements/chunks/circle-BKAZdmzb.js +1 -0
- package/dist/elements/chunks/circle-check-CmYG-y3I.js +1 -0
- package/dist/elements/chunks/circle-x-DewgAEym.js +1 -0
- package/dist/elements/chunks/cn-CU7UAWzk.js +1 -0
- package/dist/elements/chunks/code-block-DedwxwFI.js +1 -0
- package/dist/elements/chunks/collapsible-FfgmTHtM.js +1 -0
- package/dist/elements/chunks/composer-Cfbw5HKT.js +65 -0
- package/dist/elements/chunks/context-DwJmxlRE.js +1 -0
- package/dist/elements/chunks/conversation-list-DsCQMfPq.js +1 -0
- package/dist/elements/chunks/default-input-BuqsoENC.js +1 -0
- package/dist/elements/chunks/define-rGsaWsLL.js +1 -0
- package/dist/elements/chunks/disclosure-CwoAkpMH.js +1 -0
- package/dist/elements/chunks/download-DJ06G3Bz.js +1 -0
- package/dist/elements/chunks/dropdown-BFg8ri_R.js +1 -0
- package/dist/elements/chunks/ellipsis-dlN6YvGw.js +1 -0
- package/dist/elements/chunks/external-link-DBX2lc_R.js +1 -0
- package/dist/elements/chunks/file-text-HfwUx4F9.js +1 -0
- package/dist/elements/chunks/file-tree-C6Toj71u.js +1 -0
- package/dist/elements/chunks/folder-MYuqa9Xp.js +1 -0
- package/dist/elements/chunks/hover-card-gE7iyXdW.js +1 -0
- package/dist/elements/chunks/icon-Vqz4ivrY.js +1 -0
- package/dist/elements/chunks/{index-CTBEJeo6.js → index-BCRhi84a.js} +1 -1
- package/dist/elements/chunks/info-B_toFS0l.js +1 -0
- package/dist/elements/chunks/input-gzbHYZvQ.js +1 -0
- package/dist/elements/chunks/kbd-n49c4KZm.js +1 -0
- package/dist/elements/chunks/link-CKPs9yM0.js +1 -0
- package/dist/elements/chunks/loader-q6MamGus.js +1 -0
- package/dist/elements/chunks/{markdown-CMTGx9r8.js → markdown-DBrcqq4S.js} +9 -9
- package/dist/elements/chunks/message-CTqaYI0s.js +1 -0
- package/dist/elements/chunks/message-feedback-Cvzm03w0.js +1 -0
- package/dist/elements/chunks/message-square-CUg9eRCi.js +1 -0
- package/dist/elements/chunks/minimize-2-l2klxP6K.js +1 -0
- package/dist/elements/chunks/model-switcher-CmyjiHO1.js +1 -0
- package/dist/elements/chunks/overlay-C8sOYqjT.js +1 -0
- package/dist/elements/chunks/paperclip-42Ia7xHD.js +1 -0
- package/dist/elements/chunks/progress-bar-tzKMWAwO.js +1 -0
- package/dist/elements/chunks/prompt-suggestion-D3F6vP_A.js +1 -0
- package/dist/elements/chunks/reasoning-BJNmmyov.js +1 -0
- package/dist/elements/chunks/resizable-BRsk19qI.js +1 -0
- package/dist/elements/chunks/rotate-cw-BgcggLHC.js +1 -0
- package/dist/elements/chunks/scroll-area-CgGbFFbT.js +1 -0
- package/dist/elements/chunks/separator-8hM4GdHE.js +1 -0
- package/dist/elements/chunks/settings-CaUIYOg-.js +1 -0
- package/dist/elements/chunks/settings-group-CYjOVIZQ.js +1 -0
- package/dist/elements/chunks/share-BTYM3Ddt.js +1 -0
- package/dist/elements/chunks/skeleton-DsTYrPUe.js +1 -0
- package/dist/elements/chunks/slots-DkZ-Cmha.js +1 -0
- package/dist/elements/chunks/star-9R3LBQ9n.js +1 -0
- package/dist/elements/chunks/store-CYl5Y0_u.js +1 -0
- package/dist/elements/chunks/text-shimmer-CaYGv8Se.js +1 -0
- package/dist/elements/chunks/textarea-NEr2SLcD.js +1 -0
- package/dist/elements/chunks/thumbs-up-DZYZkFfc.js +1 -0
- package/dist/elements/chunks/toast-store-ClxVZRcc.js +1 -0
- package/dist/elements/chunks/tool-CHZOmoe9.js +1 -0
- package/dist/elements/chunks/tooltip-WpHElELC.js +1 -0
- package/dist/elements/chunks/triangle-alert-BlS80PUg.js +1 -0
- package/dist/elements/chunks/use-card-resolution-VSVoxDeJ.js +1 -0
- package/dist/elements/chunks/video-DxTPZqT8.js +1 -0
- package/dist/elements/chunks/x-C1qtndxn.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 +8256 -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-CYWGkgbI.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 +75 -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 +23 -8
- package/src/agent-tooling/mcp/manifest.ts +14 -0
- package/src/agent-tooling/mcp/tools/debug.ts +10 -6
- 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 +245 -0
- package/src/components/component-meta.json +691 -102
- 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 +342 -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 +1 -1
- 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 +47 -6
- 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 +212 -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 +116 -0
- package/src/ui/pane-group.tsx +280 -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
|
@@ -2,7 +2,7 @@ import { For, createSignal, onMount, onCleanup } from 'solid-js';
|
|
|
2
2
|
import { defineWebComponent } from './define';
|
|
3
3
|
import { PromptSuggestion } from '../components/prompt-suggestion';
|
|
4
4
|
|
|
5
|
-
type Item = string | { label: string; value?: string };
|
|
5
|
+
type Item = string | { label: string; value?: string; icon?: string };
|
|
6
6
|
|
|
7
7
|
interface Props extends Record<string, unknown> {
|
|
8
8
|
/** The suggestions. Strings, or `{ label, value }` when the displayed text
|
|
@@ -10,9 +10,13 @@ interface Props extends Record<string, unknown> {
|
|
|
10
10
|
suggestions: Item[];
|
|
11
11
|
/** Chip style: `'outline'` (default), `'ghost'`, or `'default'` (filled). */
|
|
12
12
|
variant?: 'outline' | 'ghost' | 'default';
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
size?: '
|
|
13
|
+
/** Row height for `layout="list"`: `'md'` (default) or `'lg'` for taller rows.
|
|
14
|
+
* Chips are unaffected. */
|
|
15
|
+
size?: 'md' | 'lg';
|
|
16
|
+
/** Layout: `'chips'` (default) renders a wrapping row of rounded pills;
|
|
17
|
+
* `'list'` renders a vertical, full-width "Ideas for you" list — each row
|
|
18
|
+
* is left-aligned with a leading `icon`, a label, and a hover background. */
|
|
19
|
+
layout?: 'chips' | 'list';
|
|
16
20
|
/** Full-width left-aligned rows instead of pills. */
|
|
17
21
|
block?: boolean;
|
|
18
22
|
/** Substring to highlight within each suggestion. */
|
|
@@ -27,18 +31,20 @@ interface Events {
|
|
|
27
31
|
|
|
28
32
|
const labelOf = (s: Item) => (typeof s === 'string' ? s : s.label);
|
|
29
33
|
const valueOf = (s: Item) => (typeof s === 'string' ? s : s.value ?? s.label);
|
|
34
|
+
const iconOf = (s: Item) => (typeof s === 'string' ? undefined : s.icon);
|
|
30
35
|
|
|
31
36
|
/** Parse a single `<kai-suggestion>` node into an `Item` descriptor. */
|
|
32
37
|
export function parseSuggestionNode(n: Element): Item {
|
|
33
38
|
const text = n.textContent?.trim() ?? '';
|
|
34
39
|
const value = n.getAttribute('value') ?? text;
|
|
35
|
-
return { label: text, value };
|
|
40
|
+
return { label: text, value, icon: n.getAttribute('icon') ?? undefined };
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
/**
|
|
39
44
|
* `<kai-suggestions>` — a row/list of suggestion chips. Data via the
|
|
40
|
-
* `suggestions` property; `variant`/`block`/`highlight` attributes;
|
|
41
|
-
* `select`.
|
|
45
|
+
* `suggestions` property; `variant`/`layout`/`block`/`highlight` attributes;
|
|
46
|
+
* emits `select`. `layout="list"` renders the vertical "Ideas for you" list
|
|
47
|
+
* (leading icon + label + hover background) instead of pills.
|
|
42
48
|
*
|
|
43
49
|
* Alternatively, declare chips as `<kai-suggestion>` child elements
|
|
44
50
|
* (light-DOM data carriers — hidden by the Shadow DOM):
|
|
@@ -53,7 +59,8 @@ export function parseSuggestionNode(n: Element): Item {
|
|
|
53
59
|
defineWebComponent<Props, Events>('kai-suggestions', {
|
|
54
60
|
suggestions: [],
|
|
55
61
|
variant: 'outline',
|
|
56
|
-
size:
|
|
62
|
+
size: 'md',
|
|
63
|
+
layout: 'chips',
|
|
57
64
|
block: false,
|
|
58
65
|
highlight: undefined,
|
|
59
66
|
}, (props, { dispatch, flag, element }) => {
|
|
@@ -74,14 +81,23 @@ defineWebComponent<Props, Events>('kai-suggestions', {
|
|
|
74
81
|
// Merge prop suggestions (first) with declarative children (after).
|
|
75
82
|
const allSuggestions = () => [...(props.suggestions ?? []), ...slottedSuggestions()];
|
|
76
83
|
|
|
84
|
+
const isList = () => props.layout === 'list';
|
|
85
|
+
|
|
86
|
+
const containerClass = () =>
|
|
87
|
+
isList() ? 'flex flex-col gap-0.5'
|
|
88
|
+
: flag('block') ? 'flex flex-col gap-2'
|
|
89
|
+
: 'flex flex-wrap gap-2';
|
|
90
|
+
|
|
77
91
|
return (
|
|
78
|
-
<div class={
|
|
92
|
+
<div class={containerClass()}>
|
|
79
93
|
<For each={allSuggestions()}>
|
|
80
94
|
{(s) => (
|
|
81
95
|
<PromptSuggestion
|
|
82
96
|
variant={props.variant}
|
|
83
97
|
size={props.size}
|
|
98
|
+
icon={iconOf(s)}
|
|
84
99
|
block={flag('block')}
|
|
100
|
+
list={isList()}
|
|
85
101
|
highlight={props.highlight}
|
|
86
102
|
onClick={() => dispatch('kai-select', { value: valueOf(s) })}
|
|
87
103
|
>
|
|
@@ -1,46 +1,67 @@
|
|
|
1
1
|
import { defineWebComponent } from './define';
|
|
2
|
-
import { Reasoning, ReasoningTrigger, ReasoningContent } from '../components/reasoning';
|
|
2
|
+
import { Reasoning, ReasoningTrigger, ReasoningContent, type ReasoningController } from '../components/reasoning';
|
|
3
3
|
import { ChatConfig, useChatConfig } from '../primitives/chat-config';
|
|
4
|
+
import { wireDisclosure } from './disclosure';
|
|
4
5
|
|
|
5
6
|
interface Props extends Record<string, unknown> {
|
|
6
7
|
/** The reasoning text to display. */
|
|
7
8
|
text: string;
|
|
8
9
|
/** Trigger label. */
|
|
9
10
|
label?: string;
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
11
|
+
/** Drive/observe open state (Shoelace-style: settable + reflected to the `open`
|
|
12
|
+
* attribute; the element still self-manages on trigger click + while
|
|
13
|
+
* streaming). Set `el.open = true`; listen for `kai-open-change`. */
|
|
12
14
|
open?: boolean;
|
|
15
|
+
/** Initial open state on mount (uncontrolled seed). */
|
|
16
|
+
defaultOpen?: boolean;
|
|
13
17
|
/** While true, auto-expands (and re-collapses when it flips false). */
|
|
14
18
|
streaming?: boolean;
|
|
15
19
|
/** Render `text` as markdown. */
|
|
16
20
|
markdown?: boolean;
|
|
21
|
+
/** Gate the disclosure trigger — programmatic `show()/hide()/toggle()` still
|
|
22
|
+
* work, but the trigger click no longer toggles. */
|
|
23
|
+
disabled?: boolean;
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
/** Events fired by `<kai-reasoning>`. */
|
|
20
27
|
interface Events {
|
|
21
|
-
/**
|
|
28
|
+
/** The reasoning block expanded or collapsed (via the trigger, streaming
|
|
29
|
+
* auto-open, or a method). */
|
|
22
30
|
'kai-open-change': { open: boolean };
|
|
23
31
|
}
|
|
24
32
|
|
|
25
33
|
/**
|
|
26
34
|
* `<kai-reasoning>` — a collapsible reasoning/thinking block that auto-expands
|
|
27
|
-
* while `streaming`. Text via the `text` property; `markdown`/`streaming` flags
|
|
28
|
-
*
|
|
35
|
+
* while `streaming`. Text via the `text` property; `markdown`/`streaming` flags.
|
|
36
|
+
* Open state is the standard disclosure surface: settable+reflecting `open`,
|
|
37
|
+
* `kai-open-change`, and `show()`/`hide()`/`toggle()` (gated by `disabled`);
|
|
38
|
+
* seed with `defaultOpen`.
|
|
29
39
|
*/
|
|
30
40
|
defineWebComponent<Props, Events>('kai-reasoning', {
|
|
31
41
|
text: '',
|
|
32
42
|
label: 'Reasoning',
|
|
33
43
|
open: undefined,
|
|
44
|
+
defaultOpen: undefined,
|
|
34
45
|
streaming: false,
|
|
35
46
|
markdown: true,
|
|
36
|
-
|
|
47
|
+
disabled: undefined,
|
|
48
|
+
}, (props, ctx) => {
|
|
49
|
+
const { flag } = ctx;
|
|
37
50
|
const outer = useChatConfig();
|
|
51
|
+
let api: ReasoningController | undefined;
|
|
52
|
+
|
|
53
|
+
// The standard disclosure surface: settable+reflecting `open`, kai-open-change,
|
|
54
|
+
// show/hide/toggle, disabled-gating. See ./disclosure. This is the SOLE emitter
|
|
55
|
+
// of kai-open-change — we no longer dispatch it from Reasoning's onOpenChange.
|
|
56
|
+
wireDisclosure(ctx, () => api, () => props.open);
|
|
57
|
+
|
|
38
58
|
return (
|
|
39
59
|
<ChatConfig portalMount={outer.portalMount()}>
|
|
40
60
|
<Reasoning
|
|
41
|
-
|
|
61
|
+
defaultOpen={flag('defaultOpen')}
|
|
42
62
|
isStreaming={flag('streaming')}
|
|
43
|
-
|
|
63
|
+
disabled={flag('disabled')}
|
|
64
|
+
controllerRef={(a) => (api = a)}
|
|
44
65
|
>
|
|
45
66
|
<ReasoningTrigger>{props.label}</ReasoningTrigger>
|
|
46
67
|
<ReasoningContent markdown={flag('markdown')}>{props.text}</ReasoningContent>
|
|
@@ -22,9 +22,6 @@ import './context-meter';
|
|
|
22
22
|
import './feedback-bar';
|
|
23
23
|
import './chat-scope-picker';
|
|
24
24
|
// Phase 3 — input ecosystem
|
|
25
|
-
// (NB: SlashCommand is context-bound to PromptInput — it observes the input
|
|
26
|
-
// value via usePromptInput() — so it is NOT a standalone element. It will fold
|
|
27
|
-
// into <kai-prompt-input> as a `slash-commands` property in a later pass.)
|
|
28
25
|
import './prompt-suggestions';
|
|
29
26
|
import './file-upload';
|
|
30
27
|
import './voice-input';
|
|
@@ -37,6 +34,13 @@ import './message-skills';
|
|
|
37
34
|
import './source';
|
|
38
35
|
import './response-stream';
|
|
39
36
|
import './empty';
|
|
37
|
+
import './status';
|
|
38
|
+
import './nav';
|
|
39
|
+
import './progress-bar';
|
|
40
|
+
import './coachmark';
|
|
41
|
+
import './tabs';
|
|
42
|
+
import './voice-output';
|
|
43
|
+
import './screen';
|
|
40
44
|
import './chain-of-thought';
|
|
41
45
|
import './resizable';
|
|
42
46
|
import './file-tree';
|
|
@@ -44,6 +48,16 @@ import './artifact';
|
|
|
44
48
|
import './scroll-button';
|
|
45
49
|
import './popover';
|
|
46
50
|
import './switch';
|
|
51
|
+
import './button';
|
|
52
|
+
import './avatar';
|
|
53
|
+
import './badge';
|
|
54
|
+
import './tooltip';
|
|
55
|
+
import './notice';
|
|
56
|
+
import './icon';
|
|
57
|
+
import './separator';
|
|
58
|
+
import './scroll-area';
|
|
59
|
+
import './hover-card';
|
|
60
|
+
import './skeleton';
|
|
47
61
|
import './toast';
|
|
48
62
|
// Generative-UI cards (Card Contract)
|
|
49
63
|
import './card';
|
|
@@ -56,3 +70,24 @@ import './choice';
|
|
|
56
70
|
import './cards';
|
|
57
71
|
// Dual-response comparison (preference capture)
|
|
58
72
|
import './compare';
|
|
73
|
+
// Rich text composer with entity pills, trigger menus, and keyword highlighting
|
|
74
|
+
import './composer';
|
|
75
|
+
// W3 phase 2: cascading action menu from a JSON items-tree
|
|
76
|
+
import './menu';
|
|
77
|
+
// W4 phase 1: grouped filterable command/mention palette
|
|
78
|
+
import './command';
|
|
79
|
+
// Prompt dock + settings building blocks (graduated from SolidJS prototypes)
|
|
80
|
+
import './prompt-dock';
|
|
81
|
+
import './segmented';
|
|
82
|
+
import './settings-group';
|
|
83
|
+
import './setting-item';
|
|
84
|
+
// Multi-agent workspace primitives (graduated from SolidJS prototypes)
|
|
85
|
+
import './pane';
|
|
86
|
+
import './pane-group';
|
|
87
|
+
import './agent-card';
|
|
88
|
+
import './dialog';
|
|
89
|
+
// Input & search field family
|
|
90
|
+
import './input';
|
|
91
|
+
import './search';
|
|
92
|
+
import './kbd';
|
|
93
|
+
import './editable-label';
|
package/src/elements/register.ts
CHANGED
|
@@ -13,9 +13,17 @@
|
|
|
13
13
|
// Registration is async (a microtask after this module loads). Consumers that
|
|
14
14
|
// need the upgraded element (e.g. the React runtime) guard with
|
|
15
15
|
// customElements.whenDefined(), which resolves once the impl chunk has run.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
/** Resolves once the kai-* elements are registered (browser); inert on the server.
|
|
17
|
+
* Await this instead of customElements.whenDefined for a single ready signal.
|
|
18
|
+
*
|
|
19
|
+
* NOTE: this MUST stay an exported binding. A bare `void import('./register-impl')`
|
|
20
|
+
* is a result-unused dynamic import that the single-entry register-all build
|
|
21
|
+
* (vite.config.ts → dist/kai.es.js) tree-shakes away as dead code, leaving the
|
|
22
|
+
* bundle with NOTHING registered. Exporting the promise keeps the import live. */
|
|
23
|
+
export const elementsReady: Promise<unknown> =
|
|
24
|
+
typeof window !== 'undefined' && typeof customElements !== 'undefined'
|
|
25
|
+
? import('./register-impl')
|
|
26
|
+
: Promise.resolve();
|
|
19
27
|
|
|
20
28
|
export type { ChatMessage, ChatMessageAction } from './chat-types';
|
|
21
29
|
export { configureCodeHighlighting, isCodeHighlightingEnabled } from '../primitives/highlighter';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createSignal, createEffect, on, onMount, onCleanup, For, Show, type JSX } from 'solid-js';
|
|
2
2
|
import { defineWebComponent } from './define';
|
|
3
|
-
import { ResizableHandle, normalizeSize } from '../ui/resizable';
|
|
3
|
+
import { ResizableHandle, normalizeSize, clampBasis } from '../ui/resizable';
|
|
4
4
|
|
|
5
5
|
type Orientation = 'horizontal' | 'vertical';
|
|
6
6
|
|
|
@@ -34,6 +34,7 @@ interface ItemInfo {
|
|
|
34
34
|
max?: string;
|
|
35
35
|
locked: boolean;
|
|
36
36
|
hidden: boolean;
|
|
37
|
+
collapsed: boolean;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
/** Max number of panels a single group lays out (nest for more). */
|
|
@@ -100,6 +101,13 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
|
|
|
100
101
|
el.setAttribute('data-kai-default-size', el.getAttribute('size') ?? '');
|
|
101
102
|
}
|
|
102
103
|
const defaultSize = el.getAttribute('data-kai-default-size') || undefined;
|
|
104
|
+
// The `collapsed` boolean prop is reflected to a `collapsed` attribute by the
|
|
105
|
+
// item facade (see kai-resizable-item), so reading the attribute here works
|
|
106
|
+
// at INITIAL render from any framework — unlike the bare `hidden` boolean,
|
|
107
|
+
// whose JSX form sets neither the attribute nor the IDL property on a custom
|
|
108
|
+
// element. Treated as hidden-for-layout, independently of `hidden` so the
|
|
109
|
+
// back-compat hidden path (and maximize, which drives `hidden`) is untouched.
|
|
110
|
+
const collapsed = el.hasAttribute('collapsed') && el.getAttribute('collapsed') !== 'false';
|
|
103
111
|
return {
|
|
104
112
|
el,
|
|
105
113
|
size: el.getAttribute('size') ?? undefined,
|
|
@@ -111,14 +119,15 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
|
|
|
111
119
|
// (and direct `el.hidden = true`) set the property, which doesn't reflect
|
|
112
120
|
// to the attribute on a custom element.
|
|
113
121
|
hidden: el.hidden || (el.hasAttribute('hidden') && el.getAttribute('hidden') !== 'false'),
|
|
122
|
+
collapsed,
|
|
114
123
|
};
|
|
115
124
|
});
|
|
116
125
|
|
|
117
126
|
// Assign each visible item to its panel slot by visible order; clear the
|
|
118
|
-
// rest so hidden/extra items don't leak into a slot.
|
|
127
|
+
// rest so hidden/extra/collapsed items don't leak into a slot.
|
|
119
128
|
let visIdx = 0;
|
|
120
129
|
for (const info of parsed) {
|
|
121
|
-
if (info.hidden) {
|
|
130
|
+
if (info.hidden || info.collapsed) {
|
|
122
131
|
info.el.removeAttribute('slot');
|
|
123
132
|
} else {
|
|
124
133
|
info.el.setAttribute('slot', `p${visIdx}`);
|
|
@@ -153,12 +162,12 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
|
|
|
153
162
|
const b = next[i];
|
|
154
163
|
if (a.el !== b.el) return true;
|
|
155
164
|
if (a.size !== b.size || a.min !== b.min || a.max !== b.max) return true;
|
|
156
|
-
if (a.locked !== b.locked || a.hidden !== b.hidden) return true;
|
|
165
|
+
if (a.locked !== b.locked || a.hidden !== b.hidden || a.collapsed !== b.collapsed) return true;
|
|
157
166
|
}
|
|
158
167
|
return false;
|
|
159
168
|
}
|
|
160
169
|
|
|
161
|
-
const visible = () => items().filter((i) => !i.hidden);
|
|
170
|
+
const visible = () => items().filter((i) => !i.hidden && !i.collapsed);
|
|
162
171
|
|
|
163
172
|
/** Compute current panel sizes (percent of container) from the rendered DOM. */
|
|
164
173
|
function currentSizes(): number[] {
|
|
@@ -358,9 +367,11 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
|
|
|
358
367
|
// maximized item is still present and visible.
|
|
359
368
|
const maximizedEl = stash.item;
|
|
360
369
|
const isConnected = maximizedEl.isConnected && element.contains(maximizedEl);
|
|
361
|
-
const isVisible = isConnected
|
|
370
|
+
const isVisible = isConnected
|
|
371
|
+
&& !(maximizedEl.hidden || maximizedEl.hasAttribute('hidden'))
|
|
372
|
+
&& !(maximizedEl.hasAttribute('collapsed') && maximizedEl.getAttribute('collapsed') !== 'false');
|
|
362
373
|
if (!isConnected || !isVisible) {
|
|
363
|
-
// The maximized item was removed or hidden out from under us → restore.
|
|
374
|
+
// The maximized item was removed or hidden/collapsed out from under us → restore.
|
|
364
375
|
restore();
|
|
365
376
|
return;
|
|
366
377
|
}
|
|
@@ -375,7 +386,7 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
|
|
|
375
386
|
// the host's own attributes.
|
|
376
387
|
subtree: true,
|
|
377
388
|
attributes: true,
|
|
378
|
-
attributeFilter: ['size', 'locked', 'min', 'max', 'hidden'],
|
|
389
|
+
attributeFilter: ['size', 'locked', 'min', 'max', 'hidden', 'collapsed'],
|
|
379
390
|
});
|
|
380
391
|
onCleanup(() => {
|
|
381
392
|
mo.disconnect();
|
|
@@ -432,7 +443,9 @@ defineWebComponent<GroupProps, GroupEvents>('kai-resizable', {
|
|
|
432
443
|
const min = boundAttrs(info.min);
|
|
433
444
|
const max = boundAttrs(info.max);
|
|
434
445
|
const def = boundAttrs(info.defaultSize);
|
|
435
|
-
|
|
446
|
+
// Clamp the INITIAL basis into [min, max] so a % size on a wide
|
|
447
|
+
// container never paints past a px max and then snaps on first drag.
|
|
448
|
+
const basis = clampBasis(normalizeSize(info.size), normalizeSize(info.min), normalizeSize(info.max));
|
|
436
449
|
const prev = () => visible()[i() - 1];
|
|
437
450
|
const isStatic = () => !!(info.locked || prev()?.locked);
|
|
438
451
|
return (
|
|
@@ -514,6 +527,16 @@ interface ItemProps extends Record<string, unknown> {
|
|
|
514
527
|
locked?: boolean;
|
|
515
528
|
/** Hide this panel; its divider is dropped and the rest reflow. */
|
|
516
529
|
hidden?: boolean;
|
|
530
|
+
/**
|
|
531
|
+
* Collapse this panel — same layout effect as `hidden` (divider dropped, the
|
|
532
|
+
* rest reflow), but it WORKS as a bare boolean from framework JSX. A plain
|
|
533
|
+
* `<kai-resizable-item collapsed>` in React/Solid/Vue/Svelte collapses the panel
|
|
534
|
+
* at the first render; `hidden` does not, because a JSX boolean sets neither the
|
|
535
|
+
* `hidden` attribute nor the IDL property on a custom element, so the parent never
|
|
536
|
+
* sees it. The facade reflects `collapsed` to a `collapsed` attribute the parent
|
|
537
|
+
* reads. Prefer this over `hidden` for declarative collapse.
|
|
538
|
+
*/
|
|
539
|
+
collapsed?: boolean;
|
|
517
540
|
}
|
|
518
541
|
|
|
519
542
|
/**
|
|
@@ -527,7 +550,20 @@ defineWebComponent<ItemProps>('kai-resizable-item', {
|
|
|
527
550
|
max: undefined,
|
|
528
551
|
locked: false,
|
|
529
552
|
hidden: false,
|
|
530
|
-
|
|
553
|
+
collapsed: false,
|
|
554
|
+
}, (_props, { element, flag }) => {
|
|
555
|
+
// Reflect the reactive `collapsed` prop to the `collapsed` ATTRIBUTE the parent
|
|
556
|
+
// <kai-resizable> reads (and observes). This is what makes a bare JSX boolean
|
|
557
|
+
// collapse the panel at INITIAL render from any framework: component-register
|
|
558
|
+
// parses `<kai-resizable-item collapsed>` to `undefined` (not `true`), and a JSX
|
|
559
|
+
// boolean sets neither `hidden` nor the IDL property — so `flag('collapsed')`
|
|
560
|
+
// (which also honours the attribute) is the reliable source, and toggleAttribute
|
|
561
|
+
// mirrors it back so the parent's readItems()/MutationObserver lay it out. Same
|
|
562
|
+
// pattern as <kai-chat>'s `loading` reflection. We touch only `collapsed`, never
|
|
563
|
+
// `hidden`, so the back-compat hidden path and maximize (which drive `hidden`)
|
|
564
|
+
// are untouched.
|
|
565
|
+
createEffect(() => { element.toggleAttribute('collapsed', flag('collapsed')); });
|
|
566
|
+
return (
|
|
531
567
|
<>
|
|
532
568
|
{/* The item host fills the panel's single grid cell (the panel stretches it on
|
|
533
569
|
both axes) and OWNS the scroll: `display:block; width/height:100%;
|
|
@@ -550,4 +586,5 @@ defineWebComponent<ItemProps>('kai-resizable-item', {
|
|
|
550
586
|
<slot />
|
|
551
587
|
</div>
|
|
552
588
|
</>
|
|
553
|
-
) as unknown as JSX.Element
|
|
589
|
+
) as unknown as JSX.Element;
|
|
590
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { defineWebComponent } from './define';
|
|
2
|
+
import { Screen, type ScreenController } from '../components/screen';
|
|
3
|
+
import { wireDisclosure } from './disclosure';
|
|
4
|
+
|
|
5
|
+
interface Props extends Record<string, unknown> {
|
|
6
|
+
/** Drive/observe open state (Shoelace-style: settable + reflected to the `open`
|
|
7
|
+
* attribute; the element still self-manages). Set `el.open = true`, or
|
|
8
|
+
* `<kai-screen open>`; listen for `kai-open-change`. */
|
|
9
|
+
open?: boolean;
|
|
10
|
+
/** Initial open state on mount (uncontrolled seed). */
|
|
11
|
+
defaultOpen?: boolean;
|
|
12
|
+
/** Header title text. A projected `title` slot overrides it. (Named `headline`
|
|
13
|
+
* because `title` collides with the global `HTMLElement.title` attribute.) */
|
|
14
|
+
headline?: string;
|
|
15
|
+
/** Show the back button (default true). */
|
|
16
|
+
back?: boolean;
|
|
17
|
+
/** Opt out of marking sibling elements inert/aria-hidden while open (for unusual layouts). */
|
|
18
|
+
noInert?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Events fired by `<kai-screen>`. */
|
|
22
|
+
interface Events {
|
|
23
|
+
/** Back navigation intent: the back button or Escape. The consumer flips their
|
|
24
|
+
* own routing in response (the screen knows nothing about the trigger). */
|
|
25
|
+
'kai-back': Record<string, never>;
|
|
26
|
+
/** The screen opened or closed (a method, `Escape` close, or driven `open`). */
|
|
27
|
+
'kai-open-change': { open: boolean };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* `<kai-screen>` is a developer-swapped, full-bleed overlay destination: the
|
|
32
|
+
* push/drill-in surface that takes over its mount point under a back-header. The
|
|
33
|
+
* developer owns the swap (their own routing flips `open` in response to their
|
|
34
|
+
* trigger button and the screen's `kai-back`); the screen owns being the takeover.
|
|
35
|
+
*
|
|
36
|
+
* It fills whatever it is mounted in (mount at the app root for a full takeover,
|
|
37
|
+
* in a positioned region for a scoped one), marks sibling elements `inert` while
|
|
38
|
+
* open (the standard modal pattern; opt out with `no-inert`), moves focus in on
|
|
39
|
+
* open and restores it on close, and runs an enter/exit transition that honors
|
|
40
|
+
* `prefers-reduced-motion`. `Escape` fires `kai-back`.
|
|
41
|
+
*
|
|
42
|
+
* ```html
|
|
43
|
+
* <kai-screen headline="Design">
|
|
44
|
+
* <button slot="actions"><kai-avatar></kai-avatar></button>
|
|
45
|
+
* <div>…your surface…</div>
|
|
46
|
+
* </kai-screen>
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* Open state is the standard disclosure surface: settable+reflecting `open`,
|
|
50
|
+
* `kai-open-change`, and `show()`/`hide()`/`toggle()`; seed with `default-open`.
|
|
51
|
+
* Parts: `header` · `back` · `title` · `body`.
|
|
52
|
+
*/
|
|
53
|
+
defineWebComponent<Props, Events>('kai-screen', {
|
|
54
|
+
open: undefined,
|
|
55
|
+
defaultOpen: undefined,
|
|
56
|
+
headline: undefined,
|
|
57
|
+
back: undefined,
|
|
58
|
+
noInert: undefined,
|
|
59
|
+
}, (props, ctx) => {
|
|
60
|
+
const { flag, element, dispatch, expose } = ctx;
|
|
61
|
+
let api: ScreenController | undefined;
|
|
62
|
+
let surface: HTMLElement | undefined;
|
|
63
|
+
|
|
64
|
+
// The standard disclosure surface: settable+reflecting `open`, kai-open-change,
|
|
65
|
+
// show/hide/toggle. See ./disclosure. This is the SOLE emitter of kai-open-change.
|
|
66
|
+
wireDisclosure(ctx, () => api, () => props.open);
|
|
67
|
+
|
|
68
|
+
// focus() shadows the host's native focus so it targets the screen surface
|
|
69
|
+
// inside the shadow root (the WebAwesome/Shoelace convention).
|
|
70
|
+
expose({
|
|
71
|
+
/** Move focus to the screen surface (no-op while closed). */
|
|
72
|
+
focus: (options?: FocusOptions) => surface?.focus(options),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<Screen
|
|
77
|
+
defaultOpen={flag('defaultOpen')}
|
|
78
|
+
back={!(props.back === false || element.getAttribute('back') === 'false')}
|
|
79
|
+
noInert={flag('noInert')}
|
|
80
|
+
host={() => element}
|
|
81
|
+
titleSlot={<slot name="title">{props.headline as string | undefined}</slot>}
|
|
82
|
+
actions={<slot name="actions" />}
|
|
83
|
+
onBack={() => { dispatch('kai-back', {}); }}
|
|
84
|
+
controllerRef={(a) => (api = a)}
|
|
85
|
+
surfaceRef={(el) => (surface = el)}
|
|
86
|
+
>
|
|
87
|
+
<slot />
|
|
88
|
+
</Screen>
|
|
89
|
+
);
|
|
90
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ScrollArea, type ScrollOrientation } from '../ui/scroll-area';
|
|
2
|
+
import { defineWebComponent } from './define';
|
|
3
|
+
|
|
4
|
+
interface Props extends Record<string, unknown> {
|
|
5
|
+
/** Which axis scrolls. `vertical` (default) · `horizontal` · `both`. The cross
|
|
6
|
+
* axis is clamped so content can't overflow it. */
|
|
7
|
+
orientation?: ScrollOrientation;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* `<kai-scroll-area>` — a scroll container with a themed, thin, cross-browser
|
|
12
|
+
* scrollbar and a keyboard-reachable region. Project the scrollable content as
|
|
13
|
+
* light-DOM children and give the element a bounded size in your layout; the
|
|
14
|
+
* content then scrolls inside. Use `orientation` to pick the axis. Restyle the
|
|
15
|
+
* container via `::part(viewport)`; the scrollbar follows the
|
|
16
|
+
* `--color-scrollbar-thumb` token.
|
|
17
|
+
*
|
|
18
|
+
* ```html
|
|
19
|
+
* <kai-scroll-area style="height: 16rem">…long content…</kai-scroll-area>
|
|
20
|
+
* <kai-scroll-area orientation="horizontal" style="max-width: 24rem">…wide row…</kai-scroll-area>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
defineWebComponent<Props>('kai-scroll-area', {
|
|
24
|
+
orientation: 'vertical',
|
|
25
|
+
}, (props) => (
|
|
26
|
+
<>
|
|
27
|
+
{/* The element is a block box; the consumer sets its size, the viewport fills it. */}
|
|
28
|
+
<style>{':host{display:block;min-height:0}'}</style>
|
|
29
|
+
<ScrollArea class="h-full max-h-full w-full max-w-full" part="viewport" orientation={props.orientation as ScrollOrientation}>
|
|
30
|
+
<slot />
|
|
31
|
+
</ScrollArea>
|
|
32
|
+
</>
|
|
33
|
+
));
|