@kitn.ai/ui 0.17.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -5
- package/dist/components/artifact.d.ts +39 -1
- package/dist/components/attachment-types.d.ts +12 -0
- package/dist/components/attachments.d.ts +2 -10
- package/dist/components/card.d.ts +27 -0
- package/dist/components/chain-of-thought.d.ts +78 -2
- package/dist/components/chat-scope-picker.d.ts +7 -0
- package/dist/components/chat-thread.d.ts +37 -12
- package/dist/components/choice-card.d.ts +26 -0
- package/dist/components/coachmark.d.ts +49 -0
- package/dist/components/composer-dom.d.ts +35 -0
- package/dist/components/composer-highlight.d.ts +48 -0
- package/dist/components/composer-history.d.ts +34 -0
- package/dist/components/composer.d.ts +86 -0
- package/dist/components/confirm-card.d.ts +17 -0
- package/dist/components/conversation-item.d.ts +9 -0
- package/dist/components/conversation-list.d.ts +36 -1
- package/dist/components/file-tree.d.ts +15 -0
- package/dist/components/form.d.ts +34 -0
- package/dist/components/markdown.d.ts +3 -0
- package/dist/components/message.d.ts +12 -0
- package/dist/components/model-switcher.d.ts +7 -0
- package/dist/components/prompt-input.d.ts +13 -4
- package/dist/components/prompt-suggestion.d.ts +9 -1
- package/dist/components/reasoning.d.ts +14 -1
- package/dist/components/response-compare.d.ts +14 -0
- package/dist/components/screen.d.ts +46 -0
- package/dist/components/tasks-card.d.ts +49 -1
- package/dist/components/toast.d.ts +12 -2
- package/dist/components/tool-types.d.ts +10 -0
- package/dist/components/tool.d.ts +8 -8
- package/dist/components/voice-input.d.ts +27 -0
- package/dist/components/voice-output.d.ts +33 -0
- package/dist/core-C8fzo39E.js +12 -0
- package/dist/custom-elements.json +8392 -1860
- package/dist/elements/agent-card.d.ts +1 -0
- package/dist/elements/agent-card.js +1 -0
- package/dist/elements/artifact.js +1 -1
- package/dist/elements/attachments.js +1 -1
- package/dist/elements/autoloader.js +1 -1
- package/dist/elements/avatar.d.ts +1 -0
- package/dist/elements/avatar.js +1 -0
- package/dist/elements/badge.d.ts +1 -0
- package/dist/elements/badge.js +1 -0
- package/dist/elements/button.d.ts +1 -0
- package/dist/elements/button.js +1 -0
- package/dist/elements/card.js +1 -1
- package/dist/elements/cards.js +1 -1
- package/dist/elements/chain-of-thought.js +1 -1
- package/dist/elements/chat-scope-picker.js +1 -1
- package/dist/elements/chat-types.d.ts +47 -0
- package/dist/elements/chat-workspace.js +1 -1
- package/dist/elements/chat.js +1 -1
- package/dist/elements/checkpoint.js +1 -1
- package/dist/elements/choice.js +1 -1
- package/dist/elements/chunks/Icon-C2LTALdM.js +1 -0
- package/dist/elements/chunks/action-icons-Dtl8Ox5D.js +1 -0
- package/dist/elements/chunks/arrow-left-GbBceGBE.js +1 -0
- package/dist/elements/chunks/attachments-DLJcWCDV.js +1 -0
- package/dist/elements/chunks/badge-BTNZTODL.js +1 -0
- package/dist/elements/chunks/button-DBDZebGr.js +1 -0
- package/dist/elements/chunks/card-YfCyI4fH.js +1 -0
- package/dist/elements/chunks/chat-thread-Dz2qbzvI.js +1 -0
- package/dist/elements/chunks/check-fhmRksq_.js +1 -0
- package/dist/elements/chunks/chevron-down-DcRg1aRU.js +1 -0
- package/dist/elements/chunks/chevron-right-ChzBcNJ-.js +1 -0
- package/dist/elements/chunks/circle-B4fTe9v6.js +1 -0
- package/dist/elements/chunks/circle-check-CJV-3Rem.js +1 -0
- package/dist/elements/chunks/circle-x-pDtzlghQ.js +1 -0
- package/dist/elements/chunks/cn-CU7UAWzk.js +1 -0
- package/dist/elements/chunks/code-block-DZ6mz6vs.js +1 -0
- package/dist/elements/chunks/collapsible-CWUAShMC.js +1 -0
- package/dist/elements/chunks/composer-BZyPU6gD.js +65 -0
- package/dist/elements/chunks/context-Cx6eQA_G.js +1 -0
- package/dist/elements/chunks/conversation-list-C4xTQSpT.js +1 -0
- package/dist/elements/chunks/default-input-BZcwyKcP.js +1 -0
- package/dist/elements/chunks/define-CNSKFZCd.js +1 -0
- package/dist/elements/chunks/disclosure-BcBs--Jf.js +1 -0
- package/dist/elements/chunks/download-BDQwcFav.js +1 -0
- package/dist/elements/chunks/dropdown-wgs8xCJZ.js +1 -0
- package/dist/elements/chunks/ellipsis-CUiEJ6R1.js +1 -0
- package/dist/elements/chunks/external-link-DJUmC7g2.js +1 -0
- package/dist/elements/chunks/file-text-DOYfYvrh.js +1 -0
- package/dist/elements/chunks/file-tree-DQzNQrbr.js +1 -0
- package/dist/elements/chunks/folder-DBDUBANz.js +1 -0
- package/dist/elements/chunks/hover-card-BQGdGAQ3.js +1 -0
- package/dist/elements/chunks/icon-CAyRqVrg.js +1 -0
- package/dist/elements/chunks/{index-CTBEJeo6.js → index-BCRhi84a.js} +1 -1
- package/dist/elements/chunks/info-DBQl-m6e.js +1 -0
- package/dist/elements/chunks/input-DZD67EvW.js +1 -0
- package/dist/elements/chunks/kbd-DbyVrlnU.js +1 -0
- package/dist/elements/chunks/link-vko7AttA.js +1 -0
- package/dist/elements/chunks/loader-Cg6rO8tQ.js +1 -0
- package/dist/elements/chunks/{markdown-CMTGx9r8.js → markdown-n3Xbj3PR.js} +9 -9
- package/dist/elements/chunks/message-CgKytiSB.js +1 -0
- package/dist/elements/chunks/message-feedback-Ds3-US0e.js +1 -0
- package/dist/elements/chunks/message-square-MmRkvc-M.js +1 -0
- package/dist/elements/chunks/minimize-2-3kCdE0q3.js +1 -0
- package/dist/elements/chunks/model-switcher-BMtXGwLU.js +1 -0
- package/dist/elements/chunks/overlay-B1-MBI6h.js +1 -0
- package/dist/elements/chunks/paperclip-DDEfmkHc.js +1 -0
- package/dist/elements/chunks/progress-bar-Dwbiyv3s.js +1 -0
- package/dist/elements/chunks/prompt-suggestion-9lvgFcEa.js +1 -0
- package/dist/elements/chunks/reasoning-DzHWsdAJ.js +1 -0
- package/dist/elements/chunks/resizable-Bq_eHxUm.js +1 -0
- package/dist/elements/chunks/rotate-cw-jpisOdOV.js +1 -0
- package/dist/elements/chunks/scroll-area-g5Ze3K6f.js +1 -0
- package/dist/elements/chunks/separator-Bmjc5XyX.js +1 -0
- package/dist/elements/chunks/settings-Cz1bMJP9.js +1 -0
- package/dist/elements/chunks/settings-group-9imY3kRA.js +1 -0
- package/dist/elements/chunks/share-BdenF0wQ.js +1 -0
- package/dist/elements/chunks/skeleton-Pjc5jiaY.js +1 -0
- package/dist/elements/chunks/slots-DkZ-Cmha.js +1 -0
- package/dist/elements/chunks/star-DY6z1UUH.js +1 -0
- package/dist/elements/chunks/store-th4VyJXM.js +1 -0
- package/dist/elements/chunks/text-shimmer-CEi-tlXr.js +1 -0
- package/dist/elements/chunks/textarea-CboigarR.js +1 -0
- package/dist/elements/chunks/thumbs-up-BR33KLfA.js +1 -0
- package/dist/elements/chunks/toast-store-BEMda0fv.js +1 -0
- package/dist/elements/chunks/tool-TMued3WO.js +1 -0
- package/dist/elements/chunks/tooltip-Cft_Rxiw.js +1 -0
- package/dist/elements/chunks/triangle-alert-B07fX3Q8.js +1 -0
- package/dist/elements/chunks/use-card-resolution-M36zVciB.js +1 -0
- package/dist/elements/chunks/video-MKp3LmNT.js +1 -0
- package/dist/elements/chunks/x-Ckwicf6g.js +1 -0
- package/dist/elements/coachmark.d.ts +1 -0
- package/dist/elements/coachmark.js +1 -0
- package/dist/elements/code-block.js +1 -1
- package/dist/elements/command.d.ts +1 -0
- package/dist/elements/command.js +1 -0
- package/dist/elements/compare.js +1 -1
- package/dist/elements/composer.d.ts +1 -0
- package/dist/elements/composer.js +1 -0
- package/dist/elements/confirm-card.js +1 -1
- package/dist/elements/context-meter.js +1 -1
- package/dist/elements/conversation-list.js +1 -1
- package/dist/elements/css.d.ts +1 -0
- package/dist/elements/default-input.d.ts +51 -0
- package/dist/elements/define.d.ts +53 -0
- package/dist/elements/dialog.d.ts +1 -0
- package/dist/elements/dialog.js +1 -0
- package/dist/elements/disclosure.d.ts +37 -0
- package/dist/elements/editable-label.d.ts +1 -0
- package/dist/elements/editable-label.js +1 -0
- package/dist/elements/embed.js +1 -1
- package/dist/elements/empty.js +1 -1
- package/dist/elements/feedback-bar.js +1 -1
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/form.js +1 -1
- package/dist/elements/hover-card.d.ts +1 -0
- package/dist/elements/hover-card.js +1 -0
- package/dist/elements/icon.d.ts +1 -0
- package/dist/elements/icon.js +1 -0
- package/dist/elements/image.js +1 -1
- package/dist/elements/input.d.ts +1 -0
- package/dist/elements/input.js +1 -0
- package/dist/elements/kbd.d.ts +1 -0
- package/dist/elements/kbd.js +1 -0
- package/dist/elements/link-preview.js +1 -1
- package/dist/elements/loader.js +1 -1
- package/dist/elements/markdown.js +1 -1
- package/dist/elements/menu.d.ts +1 -0
- package/dist/elements/menu.js +1 -0
- package/dist/elements/message-skills.js +1 -1
- package/dist/elements/message.js +1 -1
- package/dist/elements/model-switcher.js +1 -1
- package/dist/elements/nav.d.ts +1 -0
- package/dist/elements/nav.js +1 -0
- package/dist/elements/notice.d.ts +1 -0
- package/dist/elements/notice.js +1 -0
- package/dist/elements/pane-group.d.ts +1 -0
- package/dist/elements/pane-group.js +1 -0
- package/dist/elements/pane.d.ts +1 -0
- package/dist/elements/pane.js +1 -0
- package/dist/elements/popover.js +1 -1
- package/dist/elements/progress-bar.d.ts +1 -0
- package/dist/elements/progress-bar.js +1 -0
- package/dist/elements/prompt-dock.d.ts +1 -0
- package/dist/elements/prompt-dock.js +1 -0
- package/dist/elements/prompt-input.js +1 -1
- package/dist/elements/prompt-suggestions.js +1 -1
- package/dist/elements/reasoning.js +1 -1
- package/dist/elements/register-impl.d.ts +0 -0
- package/dist/elements/register.d.ts +13 -0
- package/dist/elements/remote.d.ts +1 -0
- package/dist/elements/remote.js +1 -0
- package/dist/elements/resizable.js +1 -1
- package/dist/elements/response-stream.js +2 -2
- package/dist/elements/screen.d.ts +1 -0
- package/dist/elements/screen.js +1 -0
- package/dist/elements/scroll-area.d.ts +1 -0
- package/dist/elements/scroll-area.js +1 -0
- package/dist/elements/scroll-button.js +1 -1
- package/dist/elements/search.d.ts +1 -0
- package/dist/elements/search.js +1 -0
- package/dist/elements/segmented.d.ts +1 -0
- package/dist/elements/segmented.js +1 -0
- package/dist/elements/separator.d.ts +1 -0
- package/dist/elements/separator.js +1 -0
- package/dist/elements/setting-item.d.ts +1 -0
- package/dist/elements/setting-item.js +1 -0
- package/dist/elements/settings-group.d.ts +1 -0
- package/dist/elements/settings-group.js +1 -0
- package/dist/elements/skeleton.d.ts +1 -0
- package/dist/elements/skeleton.js +1 -0
- package/dist/elements/slots.d.ts +176 -0
- package/dist/elements/source.js +1 -1
- package/dist/elements/status.d.ts +1 -0
- package/dist/elements/status.js +1 -0
- package/dist/elements/switch.js +1 -1
- package/dist/elements/tabs.d.ts +1 -0
- package/dist/elements/tabs.js +1 -0
- package/dist/elements/tasks.js +1 -1
- package/dist/elements/text-shimmer.js +1 -1
- package/dist/elements/thinking-bar.js +1 -1
- package/dist/elements/toast.js +1 -1
- package/dist/elements/tool.js +1 -1
- package/dist/elements/tooltip.d.ts +1 -0
- package/dist/elements/tooltip.js +1 -0
- package/dist/elements/voice-input.js +1 -1
- package/dist/elements/voice-output.d.ts +1 -0
- package/dist/elements/voice-output.js +1 -0
- package/dist/elements.d.ts +733 -58
- package/dist/engine-javascript-C1x7zo1_.js +141 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +8255 -5703
- package/dist/kai.es.js +1 -0
- package/dist/llms/llms-full.txt +1146 -64
- package/dist/llms/llms.txt +4 -4
- package/dist/mcp.es.js +62 -7
- package/dist/primitives/composer-model.d.ts +22 -0
- package/dist/primitives/composer-triggers.d.ts +19 -0
- package/dist/primitives/create-kai-chat.d.ts +38 -0
- package/dist/primitives/toast-store.d.ts +32 -2
- package/dist/primitives/use-speech-recognition.d.ts +26 -0
- package/dist/react/index.d.ts +1085 -97
- package/dist/react/runtime.d.ts +9 -2
- package/dist/react/use-kai-chat.d.ts +41 -0
- package/dist/react.js +572 -193
- package/dist/register-impl-cKscku5m.js +141 -0
- package/dist/schemas/tasks.schema.json +2 -2
- package/dist/state/index.d.ts +4 -0
- package/dist/state/messages.d.ts +11 -0
- package/dist/state/stream.d.ts +22 -0
- package/dist/state/suggestions.d.ts +4 -0
- package/dist/state.js +117 -0
- package/dist/theme.tokens.css +87 -0
- package/dist/types.d.ts +4 -0
- package/dist/ui/agent-card.d.ts +61 -0
- package/dist/ui/button.d.ts +5 -2
- package/dist/ui/card.d.ts +61 -0
- package/dist/ui/collapsible.d.ts +15 -1
- package/dist/ui/command.d.ts +33 -0
- package/dist/ui/dialog.d.ts +42 -0
- package/dist/ui/dropdown.d.ts +95 -1
- package/dist/ui/editable-label.d.ts +26 -0
- package/dist/ui/hover-card.d.ts +13 -1
- package/dist/ui/icon.d.ts +18 -0
- package/dist/ui/input.d.ts +33 -0
- package/dist/ui/kbd.d.ts +21 -0
- package/dist/ui/nav.d.ts +62 -0
- package/dist/ui/notice.d.ts +31 -0
- package/dist/ui/overlay.d.ts +12 -0
- package/dist/ui/pane-grid.d.ts +58 -0
- package/dist/ui/pane-group.d.ts +77 -0
- package/dist/ui/pane.d.ts +78 -0
- package/dist/ui/popover.d.ts +11 -1
- package/dist/ui/progress-bar.d.ts +23 -0
- package/dist/ui/prompt-dock.d.ts +96 -0
- package/dist/ui/resizable.d.ts +12 -0
- package/dist/ui/scroll-area.d.ts +4 -0
- package/dist/ui/segmented.d.ts +28 -0
- package/dist/ui/settings-group.d.ts +32 -0
- package/dist/ui/skeleton.d.ts +12 -0
- package/dist/ui/stat.d.ts +16 -0
- package/dist/ui/status.d.ts +13 -0
- package/dist/ui/switch.d.ts +8 -1
- package/dist/ui/tabs.d.ts +35 -0
- package/dist/ui/tooltip.d.ts +19 -1
- package/frameworks/react/index.tsx +1042 -157
- package/frameworks/react/runtime.tsx +30 -1
- package/frameworks/react/use-kai-chat.tsx +87 -0
- package/llms-full.txt +1146 -64
- package/llms.txt +4 -4
- package/package.json +31 -10
- package/src/agent-tooling/mcp/manifest.ts +14 -0
- package/src/agent-tooling/mcp/tools/debug.ts +11 -7
- package/src/agent-tooling/mcp/tools/reference.ts +32 -0
- package/src/agent-tooling/mcp/tools/scaffold.ts +30 -1
- package/src/components/artifact.tsx +98 -13
- package/src/components/attachment-types.ts +13 -0
- package/src/components/attachments.tsx +4 -14
- package/src/components/card.tsx +109 -15
- package/src/components/chain-of-thought.tsx +210 -1
- package/src/components/chat-scope-picker.tsx +13 -3
- package/src/components/chat-thread.tsx +225 -116
- package/src/components/choice-card.tsx +103 -11
- package/src/components/coachmark.tsx +249 -0
- package/src/components/component-meta.json +699 -110
- package/src/components/composer-dom.ts +159 -0
- package/src/components/composer-highlight.ts +242 -0
- package/src/components/composer-history.ts +82 -0
- package/src/components/composer.tsx +979 -0
- package/src/components/confirm-card.tsx +54 -1
- package/src/components/conversation-item.tsx +69 -7
- package/src/components/conversation-list.tsx +134 -37
- package/src/components/file-tree.tsx +197 -47
- package/src/components/form-widgets.tsx +9 -7
- package/src/components/form.tsx +140 -17
- package/src/components/image.tsx +3 -5
- package/src/components/link-preview.tsx +5 -4
- package/src/components/markdown.tsx +5 -2
- package/src/components/message.tsx +23 -4
- package/src/components/model-switcher.tsx +19 -4
- package/src/components/prompt-input.tsx +46 -75
- package/src/components/prompt-suggestion.tsx +48 -16
- package/src/components/reasoning.tsx +29 -6
- package/src/components/response-compare.tsx +31 -2
- package/src/components/screen.tsx +176 -0
- package/src/components/tasks-card.tsx +341 -21
- package/src/components/toast.tsx +119 -31
- package/src/components/tool-types.ts +10 -0
- package/src/components/tool.tsx +22 -16
- package/src/components/voice-input.tsx +102 -19
- package/src/components/voice-output.tsx +202 -0
- package/src/elements/agent-card.tsx +67 -0
- package/src/elements/artifact.tsx +53 -4
- package/src/elements/attachments.tsx +1 -0
- package/src/elements/avatar.tsx +33 -0
- package/src/elements/badge.tsx +32 -0
- package/src/elements/button.tsx +126 -0
- package/src/elements/card-media.jpg +0 -0
- package/src/elements/card.tsx +124 -31
- package/src/elements/cards.tsx +81 -7
- package/src/elements/chain-of-thought.tsx +77 -32
- package/src/elements/chat-scope-picker.tsx +35 -8
- package/src/elements/chat-types.ts +2 -2
- package/src/elements/chat-workspace.tsx +153 -41
- package/src/elements/chat.tsx +45 -23
- package/src/elements/choice.tsx +71 -19
- package/src/elements/coachmark.tsx +90 -0
- package/src/elements/command.tsx +209 -0
- package/src/elements/compare.tsx +24 -2
- package/src/elements/compiled.css +2 -2
- package/src/elements/composer.tsx +151 -0
- package/src/elements/confirm-card.tsx +36 -11
- package/src/elements/conversation-list.tsx +80 -11
- package/src/elements/default-input.tsx +75 -53
- package/src/elements/define.tsx +87 -7
- package/src/elements/dialog.tsx +98 -0
- package/src/elements/disclosure.ts +73 -0
- package/src/elements/editable-label.tsx +125 -0
- package/src/elements/element-manifest.json +129 -1
- package/src/elements/element-meta.json +5562 -1336
- package/src/elements/element-types.d.ts +732 -57
- package/src/elements/file-tree.tsx +12 -2
- package/src/elements/file-upload.tsx +1 -1
- package/src/elements/form.tsx +54 -11
- package/src/elements/hover-card.tsx +80 -0
- package/src/elements/icon-names.json +48 -0
- package/src/elements/icon.tsx +41 -0
- package/src/elements/input.tsx +203 -0
- package/src/elements/kbd.tsx +45 -0
- package/src/elements/menu.tsx +217 -0
- package/src/elements/message.tsx +58 -11
- package/src/elements/model-switcher.tsx +27 -1
- package/src/elements/nav.tsx +87 -0
- package/src/elements/notice.tsx +53 -0
- package/src/elements/pane-group.tsx +119 -0
- package/src/elements/pane.tsx +129 -0
- package/src/elements/popover.tsx +39 -17
- package/src/elements/progress-bar.tsx +39 -0
- package/src/elements/prompt-dock.tsx +81 -0
- package/src/elements/prompt-input.tsx +112 -63
- package/src/elements/prompt-suggestions.tsx +25 -9
- package/src/elements/reasoning.tsx +30 -9
- package/src/elements/register-impl.ts +38 -3
- package/src/elements/register.ts +11 -3
- package/src/elements/resizable.tsx +48 -11
- package/src/elements/screen.tsx +90 -0
- package/src/elements/scroll-area.tsx +33 -0
- package/src/elements/search.tsx +180 -0
- package/src/elements/segmented.tsx +135 -0
- package/src/elements/separator.tsx +36 -0
- package/src/elements/setting-item.tsx +50 -0
- package/src/elements/settings-group.tsx +37 -0
- package/src/elements/skeleton.tsx +45 -0
- package/src/elements/slots.ts +607 -0
- package/src/elements/source.tsx +13 -6
- package/src/elements/status.tsx +42 -0
- package/src/elements/switch.tsx +89 -14
- package/src/elements/tabs.tsx +95 -0
- package/src/elements/tasks.tsx +70 -14
- package/src/elements/toast.tsx +17 -2
- package/src/elements/tool.tsx +43 -9
- package/src/elements/tooltip.tsx +85 -0
- package/src/elements/video-poster.jpg +0 -0
- package/src/elements/voice-input.tsx +66 -16
- package/src/elements/voice-output.tsx +69 -0
- package/src/index.ts +5 -2
- package/src/primitives/card-schemas/tasks.schema.json +2 -2
- package/src/primitives/composer-model.ts +49 -0
- package/src/primitives/composer-triggers.ts +35 -0
- package/src/primitives/create-kai-chat.ts +66 -0
- package/src/primitives/toast-store.ts +43 -2
- package/src/primitives/use-speech-recognition.ts +135 -0
- package/src/state/index.ts +6 -0
- package/src/state/messages.ts +36 -0
- package/src/state/stream.ts +92 -0
- package/src/state/suggestions.ts +9 -0
- package/src/types.ts +4 -0
- package/src/ui/agent-card.tsx +218 -0
- package/src/ui/button.tsx +16 -5
- package/src/ui/card.tsx +245 -0
- package/src/ui/collapsible.tsx +30 -4
- package/src/ui/command.tsx +99 -0
- package/src/ui/dialog.tsx +217 -0
- package/src/ui/dropdown.tsx +375 -13
- package/src/ui/editable-label.tsx +112 -0
- package/src/ui/hover-card.tsx +28 -5
- package/src/ui/icon.tsx +110 -0
- package/src/ui/input.tsx +132 -0
- package/src/ui/kbd.tsx +118 -0
- package/src/ui/nav.tsx +282 -0
- package/src/ui/notice.tsx +84 -0
- package/src/ui/overlay.tsx +108 -2
- package/src/ui/pane-grid.tsx +117 -0
- package/src/ui/pane-group.tsx +291 -0
- package/src/ui/pane.tsx +193 -0
- package/src/ui/popover.tsx +16 -2
- package/src/ui/progress-bar.tsx +83 -0
- package/src/ui/prompt-dock.tsx +145 -0
- package/src/ui/resizable.tsx +69 -1
- package/src/ui/scroll-area.tsx +14 -3
- package/src/ui/segmented.tsx +109 -0
- package/src/ui/settings-group.tsx +67 -0
- package/src/ui/skeleton.tsx +62 -5
- package/src/ui/stat.tsx +41 -0
- package/src/ui/status.tsx +48 -0
- package/src/ui/switch.tsx +49 -23
- package/src/ui/tabs.tsx +168 -0
- package/src/ui/tooltip.tsx +52 -8
- package/theme.css +113 -0
- package/dist/components/slash-command.d.ts +0 -15
- package/dist/elements/chunks/Icon-D_Zmwmwh.js +0 -1
- package/dist/elements/chunks/action-icons-PVfIvcuG.js +0 -1
- package/dist/elements/chunks/attachments-Dp6vqtrc.js +0 -1
- package/dist/elements/chunks/button-CKyYD9G4.js +0 -1
- package/dist/elements/chunks/card-Cjho-PYk.js +0 -1
- package/dist/elements/chunks/chat-thread-RT808iPf.js +0 -1
- package/dist/elements/chunks/check-CDYaMYrM.js +0 -1
- package/dist/elements/chunks/chevron-down-3SBiq8HF.js +0 -1
- package/dist/elements/chunks/chevron-right-k2UFlIVK.js +0 -1
- package/dist/elements/chunks/cn-Dogu6PbV.js +0 -1
- package/dist/elements/chunks/code-block-BYUmfFSd.js +0 -1
- package/dist/elements/chunks/collapsible-BiNwdOn6.js +0 -1
- package/dist/elements/chunks/context-18g6oi4J.js +0 -1
- package/dist/elements/chunks/conversation-list-D9Y0NVdo.js +0 -1
- package/dist/elements/chunks/default-input-CSAoYYMd.js +0 -1
- package/dist/elements/chunks/download-D8K0Je8r.js +0 -1
- package/dist/elements/chunks/dropdown-bUs2iTia.js +0 -1
- package/dist/elements/chunks/external-link-6mA0wxab.js +0 -1
- package/dist/elements/chunks/file-text-DnaYk3Dm.js +0 -1
- package/dist/elements/chunks/file-tree-CgtRLlxK.js +0 -1
- package/dist/elements/chunks/hover-card-CIGw62gP.js +0 -1
- package/dist/elements/chunks/link-BlGSeoPy.js +0 -1
- package/dist/elements/chunks/loader-DvhR4qa0.js +0 -1
- package/dist/elements/chunks/message-CDZwXjhL.js +0 -1
- package/dist/elements/chunks/message-feedback-CYx81QiA.js +0 -1
- package/dist/elements/chunks/model-switcher-O_tUhoOT.js +0 -1
- package/dist/elements/chunks/overlay-DydXYMQW.js +0 -1
- package/dist/elements/chunks/prompt-suggestion-ldlWV5kd.js +0 -1
- package/dist/elements/chunks/reasoning-2PUnHlmr.js +0 -1
- package/dist/elements/chunks/resizable-B5WNbSeb.js +0 -1
- package/dist/elements/chunks/star-t9tI-P0q.js +0 -1
- package/dist/elements/chunks/store-C6rIooZz.js +0 -1
- package/dist/elements/chunks/text-shimmer-uh9V_KUh.js +0 -1
- package/dist/elements/chunks/textarea-3nm6Ia9U.js +0 -1
- package/dist/elements/chunks/thumbs-up-BBtguGld.js +0 -1
- package/dist/elements/chunks/toast-store-D8cL3fWl.js +0 -1
- package/dist/elements/chunks/tool-GJ3vwp1U.js +0 -1
- package/dist/elements/chunks/tooltip-DwKAz4XR.js +0 -1
- package/dist/elements/chunks/triangle-alert-Ct1zt2JL.js +0 -1
- package/dist/elements/chunks/use-card-resolution-D-_0Alzy.js +0 -1
- package/dist/elements/chunks/video-mVYiM99-.js +0 -1
- package/dist/elements/chunks/x-CzxL27Ch.js +0 -1
- package/dist/kitn-chat.es.js +0 -1
- package/dist/register-JyTglR6m.js +0 -1
- package/dist/register-impl-C6wlSsts.js +0 -77
- package/src/components/slash-command.tsx +0 -232
- package/src/elements/framework-usage.json +0 -588
- /package/dist/{kitn-chat-provider.d.ts → kai-provider.d.ts} +0 -0
- /package/dist/{kitn-chat-provider.es.js → kai-provider.es.js} +0 -0
package/src/ui/collapsible.tsx
CHANGED
|
@@ -22,6 +22,7 @@ interface CollapsibleCtx {
|
|
|
22
22
|
open: Accessor<boolean>;
|
|
23
23
|
toggle: () => void;
|
|
24
24
|
contentId: string;
|
|
25
|
+
disabled: Accessor<boolean>;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
const Ctx = createContext<CollapsibleCtx>();
|
|
@@ -32,25 +33,48 @@ const useCollapsible = () => {
|
|
|
32
33
|
return c;
|
|
33
34
|
};
|
|
34
35
|
|
|
36
|
+
/** Imperative open controller, handed to a parent (e.g. the kai-tool facade)
|
|
37
|
+
* via `controllerRef` so it can drive/observe open state — mirrors
|
|
38
|
+
* HoverCardController. Only available when the Collapsible is UNCONTROLLED
|
|
39
|
+
* (no `open` prop); in controlled mode the parent already owns the state. */
|
|
40
|
+
export interface CollapsibleController { open: Accessor<boolean>; setOpen: (v: boolean) => void; }
|
|
41
|
+
|
|
35
42
|
export function Collapsible(props: {
|
|
36
43
|
open?: boolean;
|
|
37
44
|
defaultOpen?: boolean;
|
|
38
45
|
onOpenChange?: (open: boolean) => void;
|
|
46
|
+
/** When true, the trigger no longer toggles (programmatic show/hide still work
|
|
47
|
+
* via the controller; this only gates the user-facing trigger). */
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
/** Receive the open controller (open accessor + setOpen) once mounted.
|
|
50
|
+
* Only meaningful in uncontrolled mode (no `open` prop). */
|
|
51
|
+
controllerRef?: (api: CollapsibleController) => void;
|
|
39
52
|
children: JSX.Element;
|
|
40
53
|
class?: string;
|
|
41
54
|
}) {
|
|
42
|
-
const [local, rest] = splitProps(props, ['open', 'defaultOpen', 'onOpenChange', 'children', 'class']);
|
|
55
|
+
const [local, rest] = splitProps(props, ['open', 'defaultOpen', 'onOpenChange', 'disabled', 'controllerRef', 'children', 'class']);
|
|
43
56
|
const [uncontrolled, setUncontrolled] = createSignal(local.defaultOpen ?? false);
|
|
44
57
|
const isControlled = () => local.open !== undefined;
|
|
45
58
|
const open = () => (isControlled() ? !!local.open : uncontrolled());
|
|
46
|
-
const
|
|
47
|
-
|
|
59
|
+
const disabled = () => !!local.disabled;
|
|
60
|
+
// setOpen drives the open state and notifies onOpenChange — the single mutate
|
|
61
|
+
// path shared by the trigger and the imperative controller.
|
|
62
|
+
const setOpen = (next: boolean) => {
|
|
63
|
+
if (open() === next) return;
|
|
48
64
|
if (!isControlled()) setUncontrolled(next);
|
|
49
65
|
local.onOpenChange?.(next);
|
|
50
66
|
};
|
|
67
|
+
const toggle = () => {
|
|
68
|
+
if (disabled()) return;
|
|
69
|
+
setOpen(!open());
|
|
70
|
+
};
|
|
71
|
+
// Hand the controller up once. setOpen is NOT gated by disabled — disabled only
|
|
72
|
+
// suppresses the user trigger; programmatic show/hide remain available (the
|
|
73
|
+
// facade's wireDisclosure applies its own disabled-gating on show/toggle).
|
|
74
|
+
local.controllerRef?.({ open, setOpen });
|
|
51
75
|
const contentId = createUniqueId();
|
|
52
76
|
return (
|
|
53
|
-
<Ctx.Provider value={{ open, toggle, contentId }}>
|
|
77
|
+
<Ctx.Provider value={{ open, toggle, contentId, disabled }}>
|
|
54
78
|
<div
|
|
55
79
|
class={local.class}
|
|
56
80
|
{...rest}
|
|
@@ -78,10 +102,12 @@ export function CollapsibleTrigger(props: {
|
|
|
78
102
|
type: 'button' as const,
|
|
79
103
|
'aria-expanded': ctx.open(),
|
|
80
104
|
'aria-controls': ctx.contentId,
|
|
105
|
+
disabled: ctx.disabled() || undefined,
|
|
81
106
|
'data-expanded': ctx.open() ? '' : undefined,
|
|
82
107
|
'data-closed': ctx.open() ? undefined : '',
|
|
83
108
|
'data-state': ctx.open() ? 'open' : 'closed',
|
|
84
109
|
onClick: (e: MouseEvent) => {
|
|
110
|
+
if (ctx.disabled()) return;
|
|
85
111
|
if (typeof local.onClick === 'function') {
|
|
86
112
|
(local.onClick as (e: MouseEvent) => void)(e);
|
|
87
113
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { For, Show, type JSX } from 'solid-js';
|
|
2
|
+
import { cn } from '../utils/cn';
|
|
3
|
+
import { renderIcon } from './icon';
|
|
4
|
+
import { Kbd } from './kbd';
|
|
5
|
+
|
|
6
|
+
export interface CommandRow {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
icon?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
/** Optional keyboard shortcut shown as right-aligned key caps; uses the
|
|
12
|
+
* kai-kbd `keys` syntax (e.g. "Mod+K", "Alt+1"). */
|
|
13
|
+
shortcut?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface CommandGroup {
|
|
17
|
+
group?: string;
|
|
18
|
+
items: CommandRow[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CommandListProps {
|
|
22
|
+
groups: CommandGroup[];
|
|
23
|
+
activeId?: string;
|
|
24
|
+
onSelect: (id: string) => void;
|
|
25
|
+
emptyLabel?: string;
|
|
26
|
+
/** Accessible label for the listbox container. Defaults to 'Command palette'. */
|
|
27
|
+
ariaLabel?: string;
|
|
28
|
+
/** id applied to the listbox container, for aria-controls wiring. */
|
|
29
|
+
id?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* `CommandList` — a presentational grouped listbox for command/mention palettes.
|
|
34
|
+
*
|
|
35
|
+
* Renders a `role="listbox"` container. Groups with a `group` name get a muted
|
|
36
|
+
* section header. Each row is a `role="option"` button with icon, label, and
|
|
37
|
+
* optional description. Clicking a row calls `onSelect(id)`. When there are no
|
|
38
|
+
* groups/items it renders `emptyLabel` (default "No results").
|
|
39
|
+
*/
|
|
40
|
+
export function CommandList(props: CommandListProps): JSX.Element {
|
|
41
|
+
const hasItems = () => props.groups.some((g) => g.items.length > 0);
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<div role="listbox" aria-label={props.ariaLabel ?? 'Command palette'} id={props.id}>
|
|
45
|
+
<Show
|
|
46
|
+
when={hasItems()}
|
|
47
|
+
fallback={
|
|
48
|
+
<div class="px-3 py-4 text-center text-sm text-muted-foreground select-none">
|
|
49
|
+
{props.emptyLabel ?? 'No results'}
|
|
50
|
+
</div>
|
|
51
|
+
}
|
|
52
|
+
>
|
|
53
|
+
<For each={props.groups}>
|
|
54
|
+
{(group) => (
|
|
55
|
+
<Show when={group.items.length > 0}>
|
|
56
|
+
<>
|
|
57
|
+
<Show when={group.group}>
|
|
58
|
+
<div class="px-3 pt-2 pb-1 text-xs font-medium text-muted-foreground select-none">
|
|
59
|
+
{group.group}
|
|
60
|
+
</div>
|
|
61
|
+
</Show>
|
|
62
|
+
<For each={group.items}>
|
|
63
|
+
{(row) => (
|
|
64
|
+
<button
|
|
65
|
+
role="option"
|
|
66
|
+
aria-selected={row.id === props.activeId}
|
|
67
|
+
class={cn(
|
|
68
|
+
'flex w-full items-center gap-2 px-3 py-1.5 text-left text-sm transition-colors',
|
|
69
|
+
row.id === props.activeId
|
|
70
|
+
? 'bg-muted text-foreground'
|
|
71
|
+
: 'text-foreground hover:bg-muted',
|
|
72
|
+
)}
|
|
73
|
+
// Prevent blur on the search input so keyboard nav keeps working.
|
|
74
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
75
|
+
onClick={() => props.onSelect(row.id)}
|
|
76
|
+
>
|
|
77
|
+
<Show when={row.icon}>{(icon) => renderIcon(icon(), { imgClass: 'size-4 shrink-0 rounded object-cover', spanClass: 'flex size-4 shrink-0 items-center justify-center text-sm', ariaHidden: true })}</Show>
|
|
78
|
+
<span class="font-medium whitespace-nowrap shrink-0">{row.label}</span>
|
|
79
|
+
<Show when={row.description}>
|
|
80
|
+
<span class="min-w-0 truncate text-muted-foreground">{row.description}</span>
|
|
81
|
+
</Show>
|
|
82
|
+
<Show when={row.shortcut}>
|
|
83
|
+
{(sc) => (
|
|
84
|
+
<span part="shortcut" class="ml-auto shrink-0 pl-3">
|
|
85
|
+
<Kbd keys={sc()} platform="auto" size="sm" />
|
|
86
|
+
</span>
|
|
87
|
+
)}
|
|
88
|
+
</Show>
|
|
89
|
+
</button>
|
|
90
|
+
)}
|
|
91
|
+
</For>
|
|
92
|
+
</>
|
|
93
|
+
</Show>
|
|
94
|
+
)}
|
|
95
|
+
</For>
|
|
96
|
+
</Show>
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createEffect, createSignal, createUniqueId, Show, type Accessor, type JSX,
|
|
3
|
+
} from 'solid-js';
|
|
4
|
+
import { Portal } from 'solid-js/web';
|
|
5
|
+
import { cn } from '../utils/cn';
|
|
6
|
+
import { useChatConfig } from '../primitives/chat-config';
|
|
7
|
+
import { createPresence } from './overlay';
|
|
8
|
+
|
|
9
|
+
/** Imperative open controller, handed to a parent (e.g. the kai-dialog facade)
|
|
10
|
+
* via `controllerRef` so it can drive/observe open state with `wireDisclosure`. */
|
|
11
|
+
export interface DialogController { open: Accessor<boolean>; setOpen: (v: boolean) => void; }
|
|
12
|
+
|
|
13
|
+
export interface DialogProps {
|
|
14
|
+
/** Dialog body — the default slot / main content. */
|
|
15
|
+
children?: JSX.Element;
|
|
16
|
+
/** Optional header region (e.g. a title). Rendered above the body with a divider. */
|
|
17
|
+
header?: JSX.Element;
|
|
18
|
+
/** Optional footer region (e.g. action buttons). Rendered below the body with a divider. */
|
|
19
|
+
footer?: JSX.Element;
|
|
20
|
+
/** Controlled open state. When set, the component never changes it itself —
|
|
21
|
+
* drive it from `onOpenChange`. Omit for uncontrolled (internal) state. */
|
|
22
|
+
open?: boolean;
|
|
23
|
+
/** Initial open state when uncontrolled. */
|
|
24
|
+
defaultOpen?: boolean;
|
|
25
|
+
/** Fires whenever the dialog wants to open or close (Escape / backdrop / method). */
|
|
26
|
+
onOpenChange?: (open: boolean) => void;
|
|
27
|
+
/** Receive the open controller (open accessor + setOpen) once mounted. */
|
|
28
|
+
controllerRef?: (api: DialogController) => void;
|
|
29
|
+
/** Receive the focusable panel node so a facade's `focus()` can target it. */
|
|
30
|
+
panelRef?: (el: HTMLElement) => void;
|
|
31
|
+
/** Accessible name for the dialog when no `header` is provided. */
|
|
32
|
+
'aria-label'?: string;
|
|
33
|
+
/** Extra class applied to the panel (e.g. a wider `max-w-*`). */
|
|
34
|
+
class?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Focusable-element selector for the Tab focus trap. */
|
|
38
|
+
const FOCUSABLE_SELECTOR = [
|
|
39
|
+
'a[href]', 'button:not([disabled])', 'input:not([disabled])',
|
|
40
|
+
'select:not([disabled])', 'textarea:not([disabled])',
|
|
41
|
+
'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])',
|
|
42
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
43
|
+
].join(',');
|
|
44
|
+
|
|
45
|
+
/** Roughly "rendered + not visibility:hidden" — skips display:none / hidden nodes. */
|
|
46
|
+
function isVisible(el: HTMLElement): boolean {
|
|
47
|
+
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length)
|
|
48
|
+
&& getComputedStyle(el).visibility !== 'hidden';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Tabbable descendants of `panel`, in tab order. Crosses `<slot>` boundaries:
|
|
53
|
+
* when used as a web-component facade the panel's real content is light-DOM nodes
|
|
54
|
+
* assigned to its slots, not panel descendants, so a plain querySelectorAll would
|
|
55
|
+
* miss them. We walk the tree and expand each slot to its assigned elements.
|
|
56
|
+
*/
|
|
57
|
+
function getTabbables(panel: HTMLElement): HTMLElement[] {
|
|
58
|
+
const out: HTMLElement[] = [];
|
|
59
|
+
const walk = (node: Element) => {
|
|
60
|
+
for (const child of Array.from(node.children)) {
|
|
61
|
+
if (child instanceof HTMLSlotElement) {
|
|
62
|
+
for (const assigned of child.assignedElements()) {
|
|
63
|
+
if (assigned instanceof HTMLElement) {
|
|
64
|
+
if (assigned.matches(FOCUSABLE_SELECTOR)) out.push(assigned);
|
|
65
|
+
walk(assigned);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
} else if (child instanceof HTMLElement) {
|
|
69
|
+
if (child.matches(FOCUSABLE_SELECTOR)) out.push(child);
|
|
70
|
+
walk(child);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
walk(panel);
|
|
75
|
+
return out.filter(isVisible);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** The deepest active element, drilling through nested shadow roots (so a focused
|
|
79
|
+
* node inside a shadow tree resolves to the real element, not its host). */
|
|
80
|
+
function deepActiveElement(): HTMLElement | null {
|
|
81
|
+
let el = document.activeElement as HTMLElement | null;
|
|
82
|
+
while (el?.shadowRoot?.activeElement) el = el.shadowRoot.activeElement as HTMLElement;
|
|
83
|
+
return el;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Dialog is the presentational centered modal surface. It renders through a Portal
|
|
88
|
+
* (so it escapes any clipping/stacking ancestor), dims the page with a backdrop,
|
|
89
|
+
* and centers a panel with a sensible max width/height and internal scroll. It
|
|
90
|
+
* closes on Escape and on a backdrop click (never on a panel click), moves focus
|
|
91
|
+
* into the panel on open and restores it on close, and runs a basic Tab focus
|
|
92
|
+
* trap so keyboard focus cycles within the panel while open. The developer owns
|
|
93
|
+
* when it opens (drive `open` / `defaultOpen`); this owns being the modal.
|
|
94
|
+
*
|
|
95
|
+
* Styleable parts: `backdrop` · `panel` · `header` · `body` · `footer`.
|
|
96
|
+
*/
|
|
97
|
+
export function Dialog(props: DialogProps) {
|
|
98
|
+
const config = useChatConfig();
|
|
99
|
+
const [internalOpen, setInternalOpen] = createSignal(props.defaultOpen ?? false);
|
|
100
|
+
const headerId = `kai-dialog-title-${createUniqueId()}`;
|
|
101
|
+
|
|
102
|
+
const isControlled = () => props.open !== undefined;
|
|
103
|
+
const isOpen = () => (isControlled() ? !!props.open : internalOpen());
|
|
104
|
+
const setOpen = (v: boolean) => {
|
|
105
|
+
if (!isControlled()) setInternalOpen(v);
|
|
106
|
+
props.onOpenChange?.(v);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// Hand the open controller up to a parent (e.g. the kai-dialog facade) so it can
|
|
110
|
+
// drive/observe open state via wireDisclosure.
|
|
111
|
+
props.controllerRef?.({ open: isOpen, setOpen });
|
|
112
|
+
|
|
113
|
+
const presence = createPresence(isOpen);
|
|
114
|
+
|
|
115
|
+
let backdrop: HTMLElement | undefined;
|
|
116
|
+
let panel: HTMLElement | undefined;
|
|
117
|
+
// The element that had focus before we opened, restored on close.
|
|
118
|
+
let restoreFocus: HTMLElement | null = null;
|
|
119
|
+
// Track where a click started so a drag that ends on the backdrop (e.g. a text
|
|
120
|
+
// selection begun inside the panel) does not falsely dismiss.
|
|
121
|
+
let pointerDownOnBackdrop = false;
|
|
122
|
+
|
|
123
|
+
// Move focus into the panel on open; restore it on close. Seeded prev=false so a
|
|
124
|
+
// `defaultOpen` (open-at-mount) still runs the open branch.
|
|
125
|
+
createEffect((wasOpen: boolean) => {
|
|
126
|
+
const open = isOpen();
|
|
127
|
+
if (open && !wasOpen) {
|
|
128
|
+
restoreFocus = deepActiveElement();
|
|
129
|
+
queueMicrotask(() => panel?.focus());
|
|
130
|
+
} else if (!open && wasOpen) {
|
|
131
|
+
const target = restoreFocus;
|
|
132
|
+
restoreFocus = null;
|
|
133
|
+
if (target && target.isConnected) queueMicrotask(() => target.focus());
|
|
134
|
+
}
|
|
135
|
+
return open;
|
|
136
|
+
}, false);
|
|
137
|
+
|
|
138
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
139
|
+
if (e.key === 'Escape') {
|
|
140
|
+
e.stopPropagation();
|
|
141
|
+
setOpen(false);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (e.key !== 'Tab' || !panel) return;
|
|
145
|
+
// Basic focus trap: keep Tab / Shift+Tab cycling within the panel.
|
|
146
|
+
const items = getTabbables(panel);
|
|
147
|
+
if (!items.length) {
|
|
148
|
+
e.preventDefault();
|
|
149
|
+
panel.focus();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const active = deepActiveElement();
|
|
153
|
+
const idx = active ? items.indexOf(active) : -1;
|
|
154
|
+
if (e.shiftKey) {
|
|
155
|
+
if (idx <= 0) { e.preventDefault(); items[items.length - 1].focus(); }
|
|
156
|
+
} else if (idx === -1 || idx === items.length - 1) {
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
items[0].focus();
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const onClick = (e: MouseEvent) => {
|
|
163
|
+
if (pointerDownOnBackdrop && e.target === backdrop) setOpen(false);
|
|
164
|
+
pointerDownOnBackdrop = false;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<Show when={presence.present()}>
|
|
169
|
+
<Portal mount={config.portalMount()}>
|
|
170
|
+
<div
|
|
171
|
+
ref={(el) => { backdrop = el; presence.setRef(el); }}
|
|
172
|
+
part="backdrop"
|
|
173
|
+
data-expanded={presence.state() === 'open' ? '' : undefined}
|
|
174
|
+
data-closed={presence.state() === 'closed' ? '' : undefined}
|
|
175
|
+
onPointerDown={(e) => { pointerDownOnBackdrop = e.target === e.currentTarget; }}
|
|
176
|
+
onClick={onClick}
|
|
177
|
+
onKeyDown={onKeyDown}
|
|
178
|
+
class={cn(
|
|
179
|
+
'fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4',
|
|
180
|
+
'animate-in fade-in-0 data-[closed]:animate-out data-[closed]:fade-out-0 motion-reduce:animate-none',
|
|
181
|
+
)}
|
|
182
|
+
>
|
|
183
|
+
<div
|
|
184
|
+
ref={(el) => { panel = el; props.panelRef?.(el); }}
|
|
185
|
+
part="panel"
|
|
186
|
+
role="dialog"
|
|
187
|
+
aria-modal="true"
|
|
188
|
+
aria-labelledby={props.header ? headerId : undefined}
|
|
189
|
+
aria-label={props.header ? undefined : props['aria-label']}
|
|
190
|
+
tabindex={-1}
|
|
191
|
+
data-expanded={presence.state() === 'open' ? '' : undefined}
|
|
192
|
+
data-closed={presence.state() === 'closed' ? '' : undefined}
|
|
193
|
+
class={cn(
|
|
194
|
+
'flex max-h-[85vh] w-full max-w-lg flex-col overflow-hidden rounded-xl border border-border bg-background text-foreground shadow-xl outline-none',
|
|
195
|
+
'animate-in fade-in-0 zoom-in-95 data-[closed]:animate-out data-[closed]:fade-out-0 data-[closed]:zoom-out-95 motion-reduce:animate-none',
|
|
196
|
+
props.class,
|
|
197
|
+
)}
|
|
198
|
+
>
|
|
199
|
+
<Show when={props.header}>
|
|
200
|
+
<header part="header" id={headerId} class="shrink-0 border-b border-border px-5 py-4 text-base font-semibold text-foreground">
|
|
201
|
+
{props.header}
|
|
202
|
+
</header>
|
|
203
|
+
</Show>
|
|
204
|
+
<div part="body" class="min-h-0 flex-1 overflow-auto px-5 py-4 text-sm text-foreground">
|
|
205
|
+
{props.children}
|
|
206
|
+
</div>
|
|
207
|
+
<Show when={props.footer}>
|
|
208
|
+
<footer part="footer" class="flex shrink-0 items-center justify-end gap-2 border-t border-border px-5 py-3">
|
|
209
|
+
{props.footer}
|
|
210
|
+
</footer>
|
|
211
|
+
</Show>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
</Portal>
|
|
215
|
+
</Show>
|
|
216
|
+
);
|
|
217
|
+
}
|