@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
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
createMemo,
|
|
8
8
|
createEffect,
|
|
9
9
|
on,
|
|
10
|
+
onMount,
|
|
10
11
|
ErrorBoundary,
|
|
11
12
|
} from 'solid-js';
|
|
12
13
|
import { cn } from '../utils/cn';
|
|
@@ -121,6 +122,21 @@ export function defaultActionId(actions: ConfirmAction[]): string | undefined {
|
|
|
121
122
|
// The <ConfirmCard> component.
|
|
122
123
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
123
124
|
|
|
125
|
+
/** Imperative handle exposed via `controllerRef` — surfaces the confirm card's
|
|
126
|
+
* latent action/dismiss capabilities so the `<kai-confirm>` facade can forward
|
|
127
|
+
* them as instance methods (focus/confirm/dismiss/reopen). */
|
|
128
|
+
export interface ConfirmController {
|
|
129
|
+
/** Focus the default action button (or the first action if none default). */
|
|
130
|
+
focus(options?: FocusOptions): void;
|
|
131
|
+
/** Activate an action by id (or the default action when omitted) — emits the
|
|
132
|
+
* `action` verb + resolves single-shot. */
|
|
133
|
+
confirm(actionId?: string): void;
|
|
134
|
+
/** Dismiss the card — emits `dismiss` + optimistically collapses to the stub. */
|
|
135
|
+
dismiss(): void;
|
|
136
|
+
/** Re-open a dismissed card from its stub — emits `reopen`. */
|
|
137
|
+
reopen(): void;
|
|
138
|
+
}
|
|
139
|
+
|
|
124
140
|
export interface ConfirmCardProps {
|
|
125
141
|
/** The confirm definition (CardEnvelope.data). */
|
|
126
142
|
data?: ConfirmCardData;
|
|
@@ -138,6 +154,9 @@ export interface ConfirmCardProps {
|
|
|
138
154
|
class?: string;
|
|
139
155
|
/** When set, render the chromed read-only view instead of the buttons. */
|
|
140
156
|
resolution?: CardResolution;
|
|
157
|
+
/** Receive the imperative controller once mounted. The `<kai-confirm>` facade
|
|
158
|
+
* forwards these as element methods (focus/confirm/dismiss/reopen). */
|
|
159
|
+
controllerRef?: (controller: ConfirmController) => void;
|
|
141
160
|
}
|
|
142
161
|
|
|
143
162
|
/**
|
|
@@ -159,6 +178,7 @@ export function ConfirmCard(props: ConfirmCardProps): JSX.Element {
|
|
|
159
178
|
'autofocus',
|
|
160
179
|
'class',
|
|
161
180
|
'resolution',
|
|
181
|
+
'controllerRef',
|
|
162
182
|
]);
|
|
163
183
|
|
|
164
184
|
const ctxHost = useCardHost();
|
|
@@ -220,6 +240,39 @@ export function ConfirmCard(props: ConfirmCardProps): JSX.Element {
|
|
|
220
240
|
const onReopen = (): void => emit({ kind: 'reopen', cardId: local.cardId });
|
|
221
241
|
|
|
222
242
|
let bodyRef: HTMLDivElement | undefined;
|
|
243
|
+
let actionsRef: HTMLDivElement | undefined;
|
|
244
|
+
|
|
245
|
+
// The default action button (or the first action button if none is marked
|
|
246
|
+
// default) — the same target the `autofocus` prop focuses on mount.
|
|
247
|
+
const focusTarget = (): HTMLButtonElement | null => {
|
|
248
|
+
if (!actionsRef) return null;
|
|
249
|
+
return (
|
|
250
|
+
actionsRef.querySelector<HTMLButtonElement>('button[data-kai-default="true"]') ??
|
|
251
|
+
actionsRef.querySelector<HTMLButtonElement>('button[data-action-id]')
|
|
252
|
+
);
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// ── Imperative controller (Pattern C): hand the facade a handle over the
|
|
256
|
+
// card's latent action/dismiss capabilities. Every method drives the SAME
|
|
257
|
+
// internal path the buttons drive, so the same kai-card events fire. ──────────
|
|
258
|
+
onMount(() => {
|
|
259
|
+
local.controllerRef?.({
|
|
260
|
+
// Focus the default (or first) action button on demand.
|
|
261
|
+
focus: (options) => focusTarget()?.focus(options),
|
|
262
|
+
// Activate an action by id (or the default action with no id) — the button path.
|
|
263
|
+
confirm: (actionId) => {
|
|
264
|
+
const list = actions();
|
|
265
|
+
const id = actionId ?? defaultId();
|
|
266
|
+
if (id === undefined) return;
|
|
267
|
+
const action = list.find((a) => a.id === id);
|
|
268
|
+
if (action) onAction(action);
|
|
269
|
+
},
|
|
270
|
+
// Trigger the dismiss path (the X-button path).
|
|
271
|
+
dismiss: () => onDismiss(),
|
|
272
|
+
// Re-open a dismissed card (the stub's affordance path).
|
|
273
|
+
reopen: () => onReopen(),
|
|
274
|
+
});
|
|
275
|
+
});
|
|
223
276
|
|
|
224
277
|
// Surface the resolved action id for host styling.
|
|
225
278
|
createEffect(() => {
|
|
@@ -269,7 +322,7 @@ export function ConfirmCard(props: ConfirmCardProps): JSX.Element {
|
|
|
269
322
|
<X size={16} aria-hidden="true" />
|
|
270
323
|
</Button>
|
|
271
324
|
</Show>
|
|
272
|
-
<div class="ml-auto flex flex-wrap items-center gap-2">
|
|
325
|
+
<div ref={actionsRef} class="ml-auto flex flex-wrap items-center gap-2">
|
|
273
326
|
<For each={actions()}>
|
|
274
327
|
{(action) => (
|
|
275
328
|
<Button
|
|
@@ -1,16 +1,78 @@
|
|
|
1
|
-
import { splitProps } from 'solid-js';
|
|
1
|
+
import { Show, splitProps, createMemo } from 'solid-js';
|
|
2
|
+
import { MessageSquare } from 'lucide-solid';
|
|
2
3
|
import { cn } from '../utils/cn';
|
|
3
4
|
import type { ConversationSummary } from '../types';
|
|
4
5
|
|
|
5
|
-
export interface ConversationItemProps {
|
|
6
|
+
export interface ConversationItemProps {
|
|
7
|
+
conversation: ConversationSummary;
|
|
8
|
+
isActive: boolean;
|
|
9
|
+
onSelect: (id: string) => void;
|
|
10
|
+
/** Dense single-line row: a leading dot + title, no message count. */
|
|
11
|
+
compact?: boolean;
|
|
12
|
+
class?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Short relative time from an ISO date string: "just now", "5m ago", "3h ago",
|
|
17
|
+
* "2d ago", "24d ago". Pure — it snapshots `now` (defaults to `Date.now()`) at
|
|
18
|
+
* call time, so it re-derives whenever the list re-renders; there is no internal
|
|
19
|
+
* ticking clock. Returns '' for a missing or unparseable date.
|
|
20
|
+
*/
|
|
21
|
+
export function relativeTimeShort(iso?: string, now: number = Date.now()): string {
|
|
22
|
+
if (!iso) return '';
|
|
23
|
+
const then = Date.parse(iso);
|
|
24
|
+
if (Number.isNaN(then)) return '';
|
|
25
|
+
const secs = Math.max(0, Math.round((now - then) / 1000));
|
|
26
|
+
if (secs < 60) return 'just now';
|
|
27
|
+
const mins = Math.floor(secs / 60);
|
|
28
|
+
if (mins < 60) return `${mins}m ago`;
|
|
29
|
+
const hours = Math.floor(mins / 60);
|
|
30
|
+
if (hours < 24) return `${hours}h ago`;
|
|
31
|
+
return `${Math.floor(hours / 24)}d ago`;
|
|
32
|
+
}
|
|
6
33
|
|
|
7
34
|
export function ConversationItem(props: ConversationItemProps) {
|
|
8
|
-
const [local] = splitProps(props, ['conversation', 'isActive', 'onSelect', 'class']);
|
|
35
|
+
const [local] = splitProps(props, ['conversation', 'isActive', 'onSelect', 'compact', 'class']);
|
|
36
|
+
// The trailing text: the consumer's own `trailing` field, else an auto relative
|
|
37
|
+
// time from updatedAt (fallback lastMessageAt). REACTIVITY: this (and the auto
|
|
38
|
+
// time) update when the consumer re-assigns the `conversations` array with a new
|
|
39
|
+
// reference — the kit's standard reactivity model — not via an internal clock.
|
|
40
|
+
const trailing = createMemo(
|
|
41
|
+
() => local.conversation.trailing ?? relativeTimeShort(local.conversation.updatedAt ?? local.conversation.lastMessageAt),
|
|
42
|
+
);
|
|
9
43
|
return (
|
|
10
|
-
<button
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
44
|
+
<button
|
|
45
|
+
data-conversation-id={local.conversation.id}
|
|
46
|
+
onClick={() => local.onSelect(local.conversation.id)}
|
|
47
|
+
class={cn(
|
|
48
|
+
'w-full rounded-lg text-left transition-colors',
|
|
49
|
+
local.compact ? 'px-2.5 py-1.5' : 'px-2.5 py-2',
|
|
50
|
+
local.isActive ? 'bg-muted' : 'hover:bg-muted/50',
|
|
51
|
+
local.class,
|
|
52
|
+
)}
|
|
53
|
+
>
|
|
54
|
+
<Show
|
|
55
|
+
when={local.compact}
|
|
56
|
+
fallback={
|
|
57
|
+
<>
|
|
58
|
+
<div class="flex items-center gap-2">
|
|
59
|
+
<div class={cn('min-w-0 flex-1 truncate text-sm', local.isActive ? 'font-medium text-foreground' : 'text-foreground/80')}>{local.conversation.title}</div>
|
|
60
|
+
<Show when={trailing()}>
|
|
61
|
+
<span part="trailing" class="ml-auto shrink-0 text-xs text-muted-foreground">{trailing()}</span>
|
|
62
|
+
</Show>
|
|
63
|
+
</div>
|
|
64
|
+
<div class={cn('mt-0.5 truncate text-xs', local.isActive ? 'text-foreground/70' : 'text-muted-foreground')}>{local.conversation.messageCount} messages</div>
|
|
65
|
+
</>
|
|
66
|
+
}
|
|
67
|
+
>
|
|
68
|
+
<div class="flex items-center gap-2.5">
|
|
69
|
+
<MessageSquare class={cn('size-3.5 shrink-0', local.isActive ? 'text-foreground' : 'text-muted-foreground')} />
|
|
70
|
+
<span class={cn('min-w-0 flex-1 truncate text-sm', local.isActive ? 'font-medium text-foreground' : 'text-foreground/80')}>{local.conversation.title}</span>
|
|
71
|
+
<Show when={trailing()}>
|
|
72
|
+
<span part="trailing" class="ml-auto shrink-0 text-xs text-muted-foreground">{trailing()}</span>
|
|
73
|
+
</Show>
|
|
74
|
+
</div>
|
|
75
|
+
</Show>
|
|
14
76
|
</button>
|
|
15
77
|
);
|
|
16
78
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { splitProps, For, Show, createSignal, createMemo } from 'solid-js';
|
|
1
|
+
import { splitProps, For, Show, createSignal, createMemo, onMount, type JSX } from 'solid-js';
|
|
2
|
+
import { PanelLeftOpen } from 'lucide-solid';
|
|
2
3
|
import { cn } from '../utils/cn';
|
|
3
4
|
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '../ui/collapsible';
|
|
4
5
|
import { Button } from '../ui/button';
|
|
@@ -7,6 +8,26 @@ import { ScrollArea } from '../ui/scroll-area';
|
|
|
7
8
|
import { ConversationItem } from './conversation-item';
|
|
8
9
|
import type { ConversationSummary, ConversationGroup } from '../types';
|
|
9
10
|
|
|
11
|
+
/**
|
|
12
|
+
* The collapsed-rail fallback: a floating reopen button shown when the
|
|
13
|
+
* conversation sidebar is collapsed. Shared by `kai-workspace` (its collapsed
|
|
14
|
+
* branch) and the standalone `kai-conversations` (collapsed mode), so the rail
|
|
15
|
+
* collapses identically in both. Renders only the button; the host owns the
|
|
16
|
+
* surrounding region (the workspace puts the thread beside it, the standalone
|
|
17
|
+
* element stands alone). `onExpand` reopens the rail.
|
|
18
|
+
*/
|
|
19
|
+
export function CollapsedRail(props: { onExpand: () => void; class?: string }) {
|
|
20
|
+
return (
|
|
21
|
+
<Button
|
|
22
|
+
variant="ghost" size="icon-sm" aria-label="Open sidebar"
|
|
23
|
+
class={cn('rounded-full bg-card/80 shadow-sm backdrop-blur', props.class)}
|
|
24
|
+
onClick={props.onExpand}
|
|
25
|
+
>
|
|
26
|
+
<PanelLeftOpen class="size-4" />
|
|
27
|
+
</Button>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
10
31
|
export interface ConversationListProps {
|
|
11
32
|
groups: ConversationGroup[];
|
|
12
33
|
conversations: ConversationSummary[];
|
|
@@ -14,12 +35,48 @@ export interface ConversationListProps {
|
|
|
14
35
|
onSelect: (id: string) => void;
|
|
15
36
|
onNewChat: () => void;
|
|
16
37
|
onToggleSidebar?: () => void;
|
|
38
|
+
/** Replaces the built-in title bar (toggle / "Chats" / New chat). */
|
|
39
|
+
header?: JSX.Element;
|
|
40
|
+
/** A row below the list (e.g. account / settings / usage). */
|
|
41
|
+
footer?: JSX.Element;
|
|
42
|
+
/** Replaces the built-in "no conversations yet" state. */
|
|
43
|
+
empty?: JSX.Element;
|
|
44
|
+
/** Dense single-line rows (a leading dot + title, no message count). */
|
|
45
|
+
compact?: boolean;
|
|
46
|
+
/** Fired whenever the built-in search box query changes (typing or a
|
|
47
|
+
* programmatic `clear()`). Lets the facade surface a `kai-search` event. */
|
|
48
|
+
onSearchChange?: (query: string) => void;
|
|
49
|
+
/** Receive the imperative controller once mounted. The `kai-conversations`
|
|
50
|
+
* facade uses it to focus / clear the internal search input. */
|
|
51
|
+
controllerRef?: (controller: ConversationListController) => void;
|
|
17
52
|
class?: string;
|
|
18
53
|
}
|
|
19
54
|
|
|
55
|
+
/** Imperative handle exposed via `controllerRef` — surfaces the internal search
|
|
56
|
+
* box to the `kai-conversations` facade (the searchQuery signal lives here). */
|
|
57
|
+
export interface ConversationListController {
|
|
58
|
+
/** Focus the built-in search `<input>`. */
|
|
59
|
+
focus(options?: FocusOptions): void;
|
|
60
|
+
/** Clear the internal search query (resets the list filter). */
|
|
61
|
+
clearSearch(): void;
|
|
62
|
+
}
|
|
63
|
+
|
|
20
64
|
export function ConversationList(props: ConversationListProps) {
|
|
21
|
-
const [local] = splitProps(props, ['groups', 'conversations', 'activeId', 'onSelect', 'onNewChat', 'onToggleSidebar', 'class']);
|
|
65
|
+
const [local] = splitProps(props, ['groups', 'conversations', 'activeId', 'onSelect', 'onNewChat', 'onToggleSidebar', 'header', 'footer', 'empty', 'compact', 'onSearchChange', 'controllerRef', 'class']);
|
|
22
66
|
const [searchQuery, setSearchQuery] = createSignal('');
|
|
67
|
+
const isEmpty = createMemo(() => local.conversations.length === 0);
|
|
68
|
+
// The search query is owned here; setQuery is the single mutation point so both
|
|
69
|
+
// typing and the imperative clearSearch() notify the facade (→ kai-search).
|
|
70
|
+
let searchInput: HTMLInputElement | undefined;
|
|
71
|
+
const setQuery = (q: string) => { setSearchQuery(q); local.onSearchChange?.(q); };
|
|
72
|
+
|
|
73
|
+
// Hand the imperative controller (focus / clear the search box) to the facade.
|
|
74
|
+
onMount(() => {
|
|
75
|
+
local.controllerRef?.({
|
|
76
|
+
focus: (options) => searchInput?.focus(options),
|
|
77
|
+
clearSearch: () => setQuery(''),
|
|
78
|
+
});
|
|
79
|
+
});
|
|
23
80
|
|
|
24
81
|
const filteredConversations = createMemo(() => {
|
|
25
82
|
const q = searchQuery().toLowerCase();
|
|
@@ -41,45 +98,85 @@ export function ConversationList(props: ConversationListProps) {
|
|
|
41
98
|
|
|
42
99
|
return (
|
|
43
100
|
<div class={cn('flex flex-col h-full bg-sidebar', local.class)}>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
101
|
+
{/* header (replace): the consumer's own title bar, else the built-in one. */}
|
|
102
|
+
<Show
|
|
103
|
+
when={local.header}
|
|
104
|
+
fallback={
|
|
105
|
+
<div class="flex items-center justify-between p-3 pb-2">
|
|
106
|
+
<div class="flex items-center gap-2">
|
|
107
|
+
<Button variant="ghost" size="icon-sm" aria-label="Toggle sidebar" onClick={local.onToggleSidebar}>
|
|
108
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
|
|
109
|
+
</Button>
|
|
110
|
+
<span class="text-sm font-semibold text-foreground">Chats</span>
|
|
111
|
+
</div>
|
|
112
|
+
<Button variant="ghost" size="icon-sm" aria-label="New chat" onClick={local.onNewChat}>
|
|
113
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
114
|
+
</Button>
|
|
115
|
+
</div>
|
|
116
|
+
}
|
|
117
|
+
>
|
|
118
|
+
{local.header}
|
|
119
|
+
</Show>
|
|
120
|
+
<Show when={!isEmpty()}>
|
|
121
|
+
<div class="px-3 pb-2">
|
|
122
|
+
<div class="flex items-center gap-2 rounded-md bg-surface-strong px-2.5 py-1.5">
|
|
123
|
+
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="text-muted-foreground"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
|
124
|
+
<input ref={searchInput} type="text" value={searchQuery()} onInput={(e) => setQuery(e.currentTarget.value)} placeholder="Search chats..."
|
|
125
|
+
aria-label="Search chats"
|
|
126
|
+
class="bg-transparent text-[13px] text-foreground placeholder:text-muted-foreground rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring w-full" />
|
|
127
|
+
</div>
|
|
50
128
|
</div>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
129
|
+
</Show>
|
|
130
|
+
{/* list, or the empty state (replace) when there are no conversations. */}
|
|
131
|
+
<Show
|
|
132
|
+
when={!isEmpty()}
|
|
133
|
+
fallback={
|
|
134
|
+
<Show
|
|
135
|
+
when={local.empty}
|
|
136
|
+
fallback={
|
|
137
|
+
<div class="flex flex-1 flex-col items-center justify-center gap-1 p-6 text-center text-sm text-muted-foreground">
|
|
138
|
+
No conversations yet
|
|
139
|
+
</div>
|
|
140
|
+
}
|
|
141
|
+
>
|
|
142
|
+
{local.empty}
|
|
143
|
+
</Show>
|
|
144
|
+
}
|
|
145
|
+
>
|
|
146
|
+
<ScrollArea class="flex-1 px-2">
|
|
147
|
+
<For each={local.groups}>
|
|
148
|
+
{(group) => {
|
|
149
|
+
const convs = createMemo(() => groupedConversations().get(group.id) ?? []);
|
|
150
|
+
return (
|
|
151
|
+
<Show when={convs().length > 0}>
|
|
152
|
+
<GroupSection name={group.name} count={convs().length} conversations={convs()} activeId={local.activeId} onSelect={local.onSelect} compact={local.compact} />
|
|
153
|
+
</Show>
|
|
154
|
+
);
|
|
155
|
+
}}
|
|
156
|
+
</For>
|
|
157
|
+
<Show when={ungrouped().length > 0}>
|
|
158
|
+
<Show
|
|
159
|
+
when={local.compact}
|
|
160
|
+
fallback={<GroupSection name="Ungrouped" count={ungrouped().length} conversations={ungrouped()} activeId={local.activeId} onSelect={local.onSelect} />}
|
|
161
|
+
>
|
|
162
|
+
<div class="space-y-0.5 py-1">
|
|
163
|
+
<For each={ungrouped()}>
|
|
164
|
+
{(conv) => <ConversationItem conversation={conv} isActive={conv.id === local.activeId} onSelect={local.onSelect} compact />}
|
|
165
|
+
</For>
|
|
166
|
+
</div>
|
|
167
|
+
</Show>
|
|
168
|
+
</Show>
|
|
169
|
+
</ScrollArea>
|
|
170
|
+
</Show>
|
|
171
|
+
{/* footer (inject): a row below the list (account / settings / …). */}
|
|
172
|
+
<Show when={local.footer}>
|
|
173
|
+
<div class="shrink-0 border-t border-border">{local.footer}</div>
|
|
174
|
+
</Show>
|
|
78
175
|
</div>
|
|
79
176
|
);
|
|
80
177
|
}
|
|
81
178
|
|
|
82
|
-
function GroupSection(props: { name: string; count: number; conversations: ConversationSummary[]; activeId?: string; onSelect: (id: string) => void }) {
|
|
179
|
+
function GroupSection(props: { name: string; count: number; conversations: ConversationSummary[]; activeId?: string; onSelect: (id: string) => void; compact?: boolean }) {
|
|
83
180
|
const [open, setOpen] = createSignal(true);
|
|
84
181
|
return (
|
|
85
182
|
<Collapsible open={open()} onOpenChange={setOpen}>
|
|
@@ -92,7 +189,7 @@ function GroupSection(props: { name: string; count: number; conversations: Conve
|
|
|
92
189
|
<CollapsibleContent>
|
|
93
190
|
<div class="pl-2 mt-0.5 space-y-0.5">
|
|
94
191
|
<For each={props.conversations}>
|
|
95
|
-
{(conv) => <ConversationItem conversation={conv} isActive={conv.id === props.activeId} onSelect={props.onSelect} />}
|
|
192
|
+
{(conv) => <ConversationItem conversation={conv} isActive={conv.id === props.activeId} onSelect={props.onSelect} compact={props.compact} />}
|
|
96
193
|
</For>
|
|
97
194
|
</div>
|
|
98
195
|
</CollapsibleContent>
|