@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
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { createEffect, createSignal, untrack, Show } from 'solid-js';
|
|
2
|
+
import { defineWebComponent } from './define';
|
|
3
|
+
import { Input } from '../ui/input';
|
|
4
|
+
import { Kbd } from '../ui/kbd';
|
|
5
|
+
import { Loader } from '../components/loader';
|
|
6
|
+
import { renderIcon } from '../ui/icon';
|
|
7
|
+
|
|
8
|
+
interface Props extends Record<string, unknown> {
|
|
9
|
+
/** Controlled query — settable and reflected to the `value` attribute. Read
|
|
10
|
+
* `el.value` for live state. */
|
|
11
|
+
value?: string;
|
|
12
|
+
/** Placeholder. Defaults to `Search…`. */
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
/** Leading icon-NAME string (a curated name, URL, or text), resolved to a glyph
|
|
15
|
+
* the same way `kai-button`'s `icon` is. Defaults to `search`. */
|
|
16
|
+
icon?: string;
|
|
17
|
+
/** Debounce window for `kai-search`, in ms. Defaults to `200`. */
|
|
18
|
+
debounce?: number;
|
|
19
|
+
/** Show a spinner in place of the leading icon while results load. */
|
|
20
|
+
loading?: boolean;
|
|
21
|
+
/** Optional shortcut hint shown (as a `kai-kbd`) while the field is empty,
|
|
22
|
+
* e.g. `Mod+K`. Display only; it does not bind the key. */
|
|
23
|
+
shortcut?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Events fired by `<kai-search>`. */
|
|
27
|
+
interface Events {
|
|
28
|
+
/** The query changed (debounced live, and on clear). */
|
|
29
|
+
'kai-search': { value: string };
|
|
30
|
+
/** Enter was pressed. */
|
|
31
|
+
'kai-submit': { value: string };
|
|
32
|
+
/** The field committed (blur). */
|
|
33
|
+
'kai-change': { value: string };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* `<kai-search>` — a debounced filter field built on `kai-input`. Type to fire a
|
|
38
|
+
* debounced `kai-search`, press Enter for `kai-submit`. A clear (×) button shows
|
|
39
|
+
* once there's a value; an optional `shortcut` renders a `kai-kbd` hint while the
|
|
40
|
+
* field is empty.
|
|
41
|
+
*
|
|
42
|
+
* ```html
|
|
43
|
+
* <kai-search placeholder="Search docs" shortcut="Mod+K"></kai-search>
|
|
44
|
+
* <script type="module">
|
|
45
|
+
* import '@kitn.ai/ui/elements';
|
|
46
|
+
* const s = document.querySelector('kai-search');
|
|
47
|
+
* s.addEventListener('kai-search', (e) => filter(e.detail.value));
|
|
48
|
+
* s.addEventListener('kai-submit', (e) => go(e.detail.value));
|
|
49
|
+
* </script>
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* Drive/read the query with the `value` property (reflected to the attribute).
|
|
53
|
+
* Restyle via `::part(field)`, `::part(input)`, and `::part(clear)`.
|
|
54
|
+
*/
|
|
55
|
+
defineWebComponent<Props, Events>('kai-search', {
|
|
56
|
+
value: undefined,
|
|
57
|
+
placeholder: 'Search…',
|
|
58
|
+
icon: 'search',
|
|
59
|
+
debounce: 200,
|
|
60
|
+
loading: false,
|
|
61
|
+
shortcut: undefined,
|
|
62
|
+
}, (props, ctx) => {
|
|
63
|
+
const { element, dispatch, flag, expose } = ctx;
|
|
64
|
+
|
|
65
|
+
// Lift the query into the facade and drive Input CONTROLLED so the host can read
|
|
66
|
+
// it (`el.value` / `:host([value])`) and set it after mount. Mirrors kai-segmented.
|
|
67
|
+
const [value, setValue] = createSignal(
|
|
68
|
+
(props.value as string | undefined) ?? element.getAttribute('value') ?? '',
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const coerce = (v: unknown): string =>
|
|
72
|
+
v == null ? (element.getAttribute('value') ?? '') : String(v);
|
|
73
|
+
|
|
74
|
+
// Reads return LIVE state; host writes (`el.value = …`) drive it WITHOUT firing
|
|
75
|
+
// events. The equality guard kills the reflect write-back loop.
|
|
76
|
+
Object.defineProperty(element, 'value', {
|
|
77
|
+
get: () => value(),
|
|
78
|
+
set: (v: unknown) => { const next = coerce(v); if (untrack(value) !== next) setValue(next); },
|
|
79
|
+
configurable: true,
|
|
80
|
+
enumerable: true,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Reflect internal value → `[value]` host attribute (for `:host([value])`).
|
|
84
|
+
createEffect(() => {
|
|
85
|
+
const v = value();
|
|
86
|
+
if (v) {
|
|
87
|
+
if (element.getAttribute('value') !== v) element.setAttribute('value', v);
|
|
88
|
+
} else if (element.hasAttribute('value')) {
|
|
89
|
+
element.removeAttribute('value');
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Debounced kai-search: each keystroke resets the timer; it fires once after the
|
|
94
|
+
// window. Clearing fires immediately (timer cancelled).
|
|
95
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
96
|
+
const debounceMs = () => {
|
|
97
|
+
const ms = Number(props.debounce ?? 200);
|
|
98
|
+
return Number.isFinite(ms) && ms >= 0 ? ms : 200;
|
|
99
|
+
};
|
|
100
|
+
const scheduleSearch = (next: string) => {
|
|
101
|
+
if (timer) clearTimeout(timer);
|
|
102
|
+
timer = setTimeout(() => dispatch('kai-search', { value: next }), debounceMs());
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const getInput = (): HTMLInputElement | null =>
|
|
106
|
+
element.shadowRoot?.querySelector<HTMLInputElement>('input') ?? null;
|
|
107
|
+
|
|
108
|
+
const onInput = (next: string) => {
|
|
109
|
+
setValue(next);
|
|
110
|
+
scheduleSearch(next);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// Empty the field, fire kai-search '' immediately (cancelling any pending), refocus.
|
|
114
|
+
const clear = () => {
|
|
115
|
+
if (timer) clearTimeout(timer);
|
|
116
|
+
setValue('');
|
|
117
|
+
dispatch('kai-search', { value: '' });
|
|
118
|
+
getInput()?.focus();
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
122
|
+
if (e.key === 'Enter') dispatch('kai-submit', { value: untrack(value) });
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
expose({
|
|
126
|
+
focus: () => getInput()?.focus(),
|
|
127
|
+
clear,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Leading: a spinner while loading, otherwise the resolved icon glyph.
|
|
131
|
+
const leading = (
|
|
132
|
+
<Show
|
|
133
|
+
when={flag('loading')}
|
|
134
|
+
fallback={renderIcon((props.icon as string) ?? 'search', {
|
|
135
|
+
class: 'size-4 shrink-0',
|
|
136
|
+
imgClass: 'size-4 shrink-0',
|
|
137
|
+
spanClass: 'inline-flex size-4 shrink-0 items-center justify-center',
|
|
138
|
+
ariaHidden: true,
|
|
139
|
+
})}
|
|
140
|
+
>
|
|
141
|
+
<Loader variant="circular" size="sm" />
|
|
142
|
+
</Show>
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Trailing: a clear button once there's a value, else a shortcut hint if set.
|
|
146
|
+
const trailing = (
|
|
147
|
+
<>
|
|
148
|
+
<Show when={value()}>
|
|
149
|
+
<button
|
|
150
|
+
type="button"
|
|
151
|
+
part="clear"
|
|
152
|
+
aria-label="Clear"
|
|
153
|
+
class="inline-flex size-5 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
154
|
+
onClick={clear}
|
|
155
|
+
>
|
|
156
|
+
{renderIcon('x', { class: 'size-4', imgClass: 'size-4' })}
|
|
157
|
+
</button>
|
|
158
|
+
</Show>
|
|
159
|
+
<Show when={!value() && props.shortcut}>
|
|
160
|
+
<Kbd keys={props.shortcut as string} size="sm" class="opacity-80" />
|
|
161
|
+
</Show>
|
|
162
|
+
</>
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<>
|
|
167
|
+
<style>{':host{display:block}'}</style>
|
|
168
|
+
<Input
|
|
169
|
+
type="search"
|
|
170
|
+
value={value()}
|
|
171
|
+
placeholder={(props.placeholder as string) ?? 'Search…'}
|
|
172
|
+
leading={leading}
|
|
173
|
+
trailing={trailing}
|
|
174
|
+
onValueInput={onInput}
|
|
175
|
+
onValueChange={(v) => dispatch('kai-change', { value: v })}
|
|
176
|
+
onKeyDown={onKeyDown}
|
|
177
|
+
/>
|
|
178
|
+
</>
|
|
179
|
+
);
|
|
180
|
+
});
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { createEffect, createSignal, untrack } from 'solid-js';
|
|
2
|
+
import { defineWebComponent } from './define';
|
|
3
|
+
import { Segmented, type SegmentedOption } from '../ui/segmented';
|
|
4
|
+
import { renderIcon } from '../ui/icon';
|
|
5
|
+
|
|
6
|
+
/** A single segment. `icon` is an icon-NAME string (web-component-friendly) —
|
|
7
|
+
* a curated name (e.g. `"code"`), a URL/data-URI, or plain text — resolved to a
|
|
8
|
+
* glyph via the kit's icon renderer (the same path `kai-button`'s `icon` uses). */
|
|
9
|
+
interface Option {
|
|
10
|
+
value: string;
|
|
11
|
+
label: string;
|
|
12
|
+
icon?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface Props extends Record<string, unknown> {
|
|
16
|
+
/** The selectable segments, left to right. Set as a JS property (array). */
|
|
17
|
+
options: Option[];
|
|
18
|
+
/** Controlled selected `value` — settable and reflected to the `value`
|
|
19
|
+
* attribute. `el.value = 'preview'` drives it; choosing a segment updates it
|
|
20
|
+
* and fires `kai-change`. Read `el.value` for live state. */
|
|
21
|
+
value?: string;
|
|
22
|
+
/** Control density: `sm` or `md`. Defaults to `md`. */
|
|
23
|
+
size?: 'sm' | 'md';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Events fired by `<kai-segmented>`. */
|
|
27
|
+
interface Events {
|
|
28
|
+
/** A segment was chosen. */
|
|
29
|
+
'kai-change': { value: string };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* `<kai-segmented>` — a single-select pill track (segmented / toggle group).
|
|
34
|
+
* Feed it `options` (a JS-property array), drive/read the selection with the
|
|
35
|
+
* `value` property (settable + reflected to the `value` attribute, so
|
|
36
|
+
* `:host([value])` and `el.value` see live state), and listen for `kai-change`.
|
|
37
|
+
*
|
|
38
|
+
* ```html
|
|
39
|
+
* <kai-segmented value="preview"></kai-segmented>
|
|
40
|
+
* <script type="module">
|
|
41
|
+
* import '@kitn.ai/ui/elements';
|
|
42
|
+
* const seg = document.querySelector('kai-segmented');
|
|
43
|
+
* seg.options = [
|
|
44
|
+
* { value: 'code', label: 'Code', icon: 'code' },
|
|
45
|
+
* { value: 'preview', label: 'Preview', icon: 'monitor' },
|
|
46
|
+
* ];
|
|
47
|
+
* seg.addEventListener('kai-change', (e) => console.log(e.detail.value));
|
|
48
|
+
* seg.value = 'code'; // drive it (no kai-change — the host already knows)
|
|
49
|
+
* </script>
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* Each option's `icon` is an icon-name string resolved to a glyph (curated name,
|
|
53
|
+
* URL, or text). Restyle via `::part(track)` and `::part(segment)`.
|
|
54
|
+
*/
|
|
55
|
+
defineWebComponent<Props, Events>('kai-segmented', {
|
|
56
|
+
options: [],
|
|
57
|
+
value: undefined,
|
|
58
|
+
size: 'md',
|
|
59
|
+
}, (props, ctx) => {
|
|
60
|
+
const { element, dispatch } = ctx;
|
|
61
|
+
|
|
62
|
+
// Lift the selected value into the facade and drive Segmented CONTROLLED so the
|
|
63
|
+
// host can read it (`el.value` / `:host([value])`) and set it after mount. Seed
|
|
64
|
+
// from the `value` property/attribute present on mount (options usually arrive
|
|
65
|
+
// as a property after upgrade, so we don't auto-select the first segment here).
|
|
66
|
+
const [value, setValue] = createSignal(
|
|
67
|
+
(props.value as string | undefined) ?? element.getAttribute('value') ?? '',
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Coerce any value coming through the `value` setter (a JS assignment, or the
|
|
71
|
+
// write-back from `attributeChangedCallback`) to a string — falling back to the
|
|
72
|
+
// live attribute when it's nullish, so the reflect write-back equals the signal
|
|
73
|
+
// and the equality guards below absorb it (no attr⇄prop feedback loop; mirrors
|
|
74
|
+
// kai-switch's `checked`).
|
|
75
|
+
const coerce = (v: unknown): string =>
|
|
76
|
+
v == null ? (element.getAttribute('value') ?? '') : String(v);
|
|
77
|
+
|
|
78
|
+
// Apply a new value and fire kai-change once (the user-choice path).
|
|
79
|
+
const apply = (next: string) => {
|
|
80
|
+
if (untrack(value) === next) return;
|
|
81
|
+
setValue(next);
|
|
82
|
+
dispatch('kai-change', { value: next });
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Override the `value` property so reads return LIVE state (the signal) and host
|
|
86
|
+
// writes (`el.value = …`) drive it WITHOUT firing kai-change — distinct from the
|
|
87
|
+
// user-choice path. The equality guard kills the reflect write-back loop.
|
|
88
|
+
Object.defineProperty(element, 'value', {
|
|
89
|
+
get: () => value(),
|
|
90
|
+
set: (v: unknown) => { const next = coerce(v); if (untrack(value) !== next) setValue(next); },
|
|
91
|
+
configurable: true,
|
|
92
|
+
enumerable: true,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Reflect internal value → the `[value]` host attribute (for `:host([value])`).
|
|
96
|
+
// The guard against the live attribute keeps the write-back the reflect triggers
|
|
97
|
+
// (attributeChangedCallback → setter) from looping.
|
|
98
|
+
createEffect(() => {
|
|
99
|
+
const v = value();
|
|
100
|
+
if (v) {
|
|
101
|
+
if (element.getAttribute('value') !== v) element.setAttribute('value', v);
|
|
102
|
+
} else if (element.hasAttribute('value')) {
|
|
103
|
+
element.removeAttribute('value');
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Resolve each option's icon-NAME string into a rendered glyph, the same path
|
|
108
|
+
// kai-button uses for its `icon` prop, and hand the primitive `{value,label,icon:JSX}`.
|
|
109
|
+
const resolved = (): SegmentedOption[] =>
|
|
110
|
+
(props.options ?? []).map((o) => ({
|
|
111
|
+
value: o.value,
|
|
112
|
+
label: o.label,
|
|
113
|
+
icon: o.icon
|
|
114
|
+
? renderIcon(o.icon, {
|
|
115
|
+
class: 'size-4 shrink-0',
|
|
116
|
+
imgClass: 'size-4 shrink-0',
|
|
117
|
+
spanClass: 'inline-flex size-4 shrink-0 items-center justify-center',
|
|
118
|
+
ariaHidden: true,
|
|
119
|
+
})
|
|
120
|
+
: undefined,
|
|
121
|
+
}));
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<>
|
|
125
|
+
{/* Base sets `:host{display:block}`; the track flows inline like a pill. */}
|
|
126
|
+
<style>{':host{display:inline-flex}'}</style>
|
|
127
|
+
<Segmented
|
|
128
|
+
options={resolved()}
|
|
129
|
+
value={value()}
|
|
130
|
+
size={(props.size as 'sm' | 'md' | undefined) ?? 'md'}
|
|
131
|
+
onChange={(next) => apply(next)}
|
|
132
|
+
/>
|
|
133
|
+
</>
|
|
134
|
+
);
|
|
135
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Separator } from '../ui/separator';
|
|
2
|
+
import { defineWebComponent } from './define';
|
|
3
|
+
|
|
4
|
+
interface Props extends Record<string, unknown> {
|
|
5
|
+
/** `horizontal` (default, block + full-width) or `vertical` (a rule inside a
|
|
6
|
+
* flex/grid row — it stretches to the row height). */
|
|
7
|
+
orientation?: 'horizontal' | 'vertical';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* `<kai-separator>` — a themed divider between groups of content (toolbar
|
|
12
|
+
* sections, menu groups, header/sidebar splits). Carries `role="separator"`.
|
|
13
|
+
* Restyle via `::part(separator)`.
|
|
14
|
+
*
|
|
15
|
+
* ```html
|
|
16
|
+
* <kai-separator></kai-separator>
|
|
17
|
+
* <div style="display:flex; gap:.5rem">
|
|
18
|
+
* <span>A</span><kai-separator orientation="vertical"></kai-separator><span>B</span>
|
|
19
|
+
* </div>
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
defineWebComponent<Props>('kai-separator', {
|
|
23
|
+
orientation: 'horizontal',
|
|
24
|
+
}, (props) => {
|
|
25
|
+
const vertical = () => props.orientation === 'vertical';
|
|
26
|
+
return (
|
|
27
|
+
<>
|
|
28
|
+
{/* The host owns its layout box: a horizontal rule is block + full-width;
|
|
29
|
+
a vertical rule is an inline-block flex item that stretches to the row. */}
|
|
30
|
+
<style>{vertical()
|
|
31
|
+
? ':host{display:inline-block;align-self:stretch}'
|
|
32
|
+
: ':host{display:block}'}</style>
|
|
33
|
+
<Separator orientation={vertical() ? 'vertical' : 'horizontal'} part="separator" />
|
|
34
|
+
</>
|
|
35
|
+
);
|
|
36
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createSignal, onCleanup, onMount } from 'solid-js';
|
|
2
|
+
import { SettingItem } from '../ui/settings-group';
|
|
3
|
+
import { defineWebComponent } from './define';
|
|
4
|
+
|
|
5
|
+
interface Props extends Record<string, unknown> {
|
|
6
|
+
/** Row label (primary text). Attribute: `label`. */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** Optional secondary description under the label. Attribute: `description`. */
|
|
9
|
+
description?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* `<kai-setting-item>` — one row inside a `<kai-settings-group>`: a left
|
|
14
|
+
* label/description block and an optional right-aligned control. Slot the control
|
|
15
|
+
* (a `<kai-switch>`, segmented control, select, …) into `slot="control"`; omit it
|
|
16
|
+
* for a plain label row.
|
|
17
|
+
*
|
|
18
|
+
* Themeable `::part`s: `label` (the label/description block) and `control`.
|
|
19
|
+
*
|
|
20
|
+
* ```html
|
|
21
|
+
* <kai-setting-item label="Reduce motion" description="Minimize animations.">
|
|
22
|
+
* <kai-switch slot="control"></kai-switch>
|
|
23
|
+
* </kai-setting-item>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
defineWebComponent<Props>('kai-setting-item', {
|
|
27
|
+
label: '',
|
|
28
|
+
description: undefined,
|
|
29
|
+
}, (props, { element }) => {
|
|
30
|
+
// The control region only renders when `slot="control"` is actually filled, so
|
|
31
|
+
// a plain label row has no stray right-side wrapper. An empty `<slot>` is always
|
|
32
|
+
// a truthy node, so we track occupancy and gate on it (the kai-card approach).
|
|
33
|
+
// Re-read on child/attribute mutations so a late-slotted control lights up.
|
|
34
|
+
const [hasControl, setHasControl] = createSignal(false);
|
|
35
|
+
onMount(() => {
|
|
36
|
+
const read = () => setHasControl(!!element.querySelector(':scope > [slot="control"]'));
|
|
37
|
+
read();
|
|
38
|
+
const observer = new MutationObserver(read);
|
|
39
|
+
observer.observe(element, { childList: true, attributes: true, subtree: true });
|
|
40
|
+
onCleanup(() => observer.disconnect());
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<SettingItem
|
|
45
|
+
label={props.label ?? ''}
|
|
46
|
+
description={props.description}
|
|
47
|
+
control={hasControl() ? <slot name="control" /> : undefined}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SettingsGroup } from '../ui/settings-group';
|
|
2
|
+
import { defineWebComponent } from './define';
|
|
3
|
+
|
|
4
|
+
interface Props extends Record<string, unknown> {
|
|
5
|
+
/** Small section heading shown above the card. Attribute: `heading`. */
|
|
6
|
+
heading?: string;
|
|
7
|
+
/** Optional muted description under the heading. Attribute: `description`. */
|
|
8
|
+
description?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* `<kai-settings-group>` — a settings section: a small heading + optional muted
|
|
13
|
+
* description over a bordered, rounded card that stacks `<kai-setting-item>` rows
|
|
14
|
+
* with hairline dividers. Put the rows as light-DOM children (the default slot).
|
|
15
|
+
*
|
|
16
|
+
* Host-agnostic chrome: the SAME group drops into a modal or a full settings
|
|
17
|
+
* page; only the rows change per app.
|
|
18
|
+
*
|
|
19
|
+
* Themeable `::part`s: `header` (the heading/description block) and `body` (the
|
|
20
|
+
* rows card).
|
|
21
|
+
*
|
|
22
|
+
* ```html
|
|
23
|
+
* <kai-settings-group heading="Appearance" description="How the app looks.">
|
|
24
|
+
* <kai-setting-item label="Theme">
|
|
25
|
+
* <kai-switch slot="control"></kai-switch>
|
|
26
|
+
* </kai-setting-item>
|
|
27
|
+
* </kai-settings-group>
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
defineWebComponent<Props>('kai-settings-group', {
|
|
31
|
+
heading: '',
|
|
32
|
+
description: undefined,
|
|
33
|
+
}, (props) => (
|
|
34
|
+
<SettingsGroup heading={props.heading ?? ''} description={props.description}>
|
|
35
|
+
<slot />
|
|
36
|
+
</SettingsGroup>
|
|
37
|
+
));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Skeleton, type SkeletonVariant } from '../ui/skeleton';
|
|
2
|
+
import { defineWebComponent } from './define';
|
|
3
|
+
|
|
4
|
+
interface Props extends Record<string, unknown> {
|
|
5
|
+
/** `text` (one or more lines), `rect` (a block), or `circle` (round).
|
|
6
|
+
* Defaults to `text`. */
|
|
7
|
+
variant?: SkeletonVariant;
|
|
8
|
+
/** CSS width (e.g. `'12rem'`, `'60%'`). Defaults to full width (responsive);
|
|
9
|
+
* for `circle` it is the diameter. */
|
|
10
|
+
width?: string;
|
|
11
|
+
/** CSS height. Defaults per variant (a text line height; circle = width). */
|
|
12
|
+
height?: string;
|
|
13
|
+
/** `text` only: number of lines; the last is shorter. Defaults to 1. */
|
|
14
|
+
lines?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* `<kai-skeleton>` — a pulsing loading placeholder that preserves layout while
|
|
19
|
+
* content arrives. Responsive by default (fills its container's width). It is
|
|
20
|
+
* prop-driven because utility classes can't cross the shadow boundary: pick a
|
|
21
|
+
* `variant` and optionally set `width` / `height` / `lines`.
|
|
22
|
+
*
|
|
23
|
+
* ```html
|
|
24
|
+
* <kai-skeleton variant="text" lines="3"></kai-skeleton>
|
|
25
|
+
* <kai-skeleton variant="circle" width="2.5rem"></kai-skeleton>
|
|
26
|
+
* <kai-skeleton variant="rect" height="10rem"></kai-skeleton>
|
|
27
|
+
* ```
|
|
28
|
+
* Recolor by overriding the `--color-muted` token.
|
|
29
|
+
*/
|
|
30
|
+
defineWebComponent<Props>('kai-skeleton', {
|
|
31
|
+
variant: 'text',
|
|
32
|
+
width: undefined,
|
|
33
|
+
height: undefined,
|
|
34
|
+
lines: undefined,
|
|
35
|
+
}, (props) => (
|
|
36
|
+
<>
|
|
37
|
+
<style>{':host{display:block}'}</style>
|
|
38
|
+
<Skeleton
|
|
39
|
+
variant={props.variant ?? 'text'}
|
|
40
|
+
width={props.width}
|
|
41
|
+
height={props.height}
|
|
42
|
+
lines={props.lines != null ? Number(props.lines) : undefined}
|
|
43
|
+
/>
|
|
44
|
+
</>
|
|
45
|
+
));
|