veryfront 0.1.997 → 0.1.998
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/esm/cli/templates/manifest.js +1 -1
- package/esm/deno.d.ts +7 -0
- package/esm/deno.js +11 -3
- package/esm/deps/esm.sh/react-dom@19.2.4.d.ts +2 -0
- package/esm/deps/esm.sh/react-dom@19.2.4.d.ts.map +1 -0
- package/esm/deps/esm.sh/react-dom@19.2.4.js +3 -0
- package/esm/react/react-dom.d.ts +3 -0
- package/esm/react/react-dom.d.ts.map +1 -0
- package/esm/react/react-dom.js +2 -0
- package/esm/src/agent/ag-ui/host-support.d.ts.map +1 -1
- package/esm/src/agent/ag-ui/host-support.js +12 -0
- package/esm/src/agent/react/index.d.ts +4 -2
- package/esm/src/agent/react/index.d.ts.map +1 -1
- package/esm/src/agent/react/index.js +2 -1
- package/esm/src/agent/react/use-agent-metadata.d.ts +5 -0
- package/esm/src/agent/react/use-agent-metadata.d.ts.map +1 -1
- package/esm/src/agent/react/use-agent-metadata.js +18 -9
- package/esm/src/agent/react/use-agents.d.ts +33 -0
- package/esm/src/agent/react/use-agents.d.ts.map +1 -0
- package/esm/src/agent/react/use-agents.js +72 -0
- package/esm/src/agent/react/use-chat/index.d.ts +1 -1
- package/esm/src/agent/react/use-chat/index.d.ts.map +1 -1
- package/esm/src/agent/react/use-chat/types.d.ts +3 -2
- package/esm/src/agent/react/use-chat/types.d.ts.map +1 -1
- package/esm/src/agent/react/use-chat/use-chat.d.ts +12 -1
- package/esm/src/agent/react/use-chat/use-chat.d.ts.map +1 -1
- package/esm/src/agent/react/use-chat/use-chat.js +47 -7
- package/esm/src/agent/react/use-chat/utils.d.ts.map +1 -1
- package/esm/src/agent/react/use-chat/utils.js +4 -0
- package/esm/src/agent/runtime/message-adapter.d.ts.map +1 -1
- package/esm/src/agent/runtime/message-adapter.js +3 -1
- package/esm/src/agent/runtime/text-generation-runtime-message-converter.d.ts.map +1 -1
- package/esm/src/agent/runtime/text-generation-runtime-message-converter.js +6 -2
- package/esm/src/chat/index.d.ts +17 -7
- package/esm/src/chat/index.d.ts.map +1 -1
- package/esm/src/chat/index.js +33 -7
- package/esm/src/chat/protocol.d.ts +13 -1
- package/esm/src/chat/protocol.d.ts.map +1 -1
- package/esm/src/chat/upload-handler.d.ts +55 -0
- package/esm/src/chat/upload-handler.d.ts.map +1 -0
- package/esm/src/chat/upload-handler.js +180 -0
- package/esm/src/discovery/import-rewriter.d.ts +1 -1
- package/esm/src/discovery/import-rewriter.d.ts.map +1 -1
- package/esm/src/discovery/import-rewriter.js +2 -0
- package/esm/src/discovery/transpiler.d.ts.map +1 -1
- package/esm/src/discovery/transpiler.js +2 -0
- package/esm/src/react/components/chat/agent-card.d.ts +84 -11
- package/esm/src/react/components/chat/agent-card.d.ts.map +1 -1
- package/esm/src/react/components/chat/agent-card.js +151 -57
- package/esm/src/react/components/chat/agent-picker.d.ts +166 -0
- package/esm/src/react/components/chat/agent-picker.d.ts.map +1 -0
- package/esm/src/react/components/chat/agent-picker.js +183 -0
- package/esm/src/react/components/chat/chat/components/animations.js +1 -1
- package/esm/src/react/components/chat/chat/components/attachment-pill.d.ts +125 -3
- package/esm/src/react/components/chat/chat/components/attachment-pill.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/attachment-pill.js +209 -25
- package/esm/src/react/components/chat/chat/components/attachments-panel.d.ts +149 -0
- package/esm/src/react/components/chat/chat/components/attachments-panel.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/components/attachments-panel.js +187 -0
- package/esm/src/react/components/chat/chat/components/branch-picker.d.ts +13 -2
- package/esm/src/react/components/chat/chat/components/branch-picker.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/branch-picker.js +6 -8
- package/esm/src/react/components/chat/chat/components/chat-messages-skeleton.d.ts +20 -0
- package/esm/src/react/components/chat/chat/components/chat-messages-skeleton.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/components/chat-messages-skeleton.js +31 -0
- package/esm/src/react/components/chat/chat/components/code-block.d.ts +9 -1
- package/esm/src/react/components/chat/chat/components/code-block.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/code-block.js +14 -6
- package/esm/src/react/components/chat/chat/components/drop-zone.d.ts +11 -4
- package/esm/src/react/components/chat/chat/components/drop-zone.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/drop-zone.js +10 -8
- package/esm/src/react/components/chat/chat/components/empty-state.d.ts +2 -1
- package/esm/src/react/components/chat/chat/components/empty-state.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/empty-state.js +7 -8
- package/esm/src/react/components/chat/chat/components/inference-badge.d.ts +6 -2
- package/esm/src/react/components/chat/chat/components/inference-badge.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/inference-badge.js +5 -4
- package/esm/src/react/components/chat/chat/components/inline-citation.d.ts +9 -1
- package/esm/src/react/components/chat/chat/components/inline-citation.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/inline-citation.js +19 -20
- package/esm/src/react/components/chat/chat/components/message-actions.d.ts +28 -5
- package/esm/src/react/components/chat/chat/components/message-actions.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/message-actions.js +24 -36
- package/esm/src/react/components/chat/chat/components/message-edit-form.d.ts +7 -2
- package/esm/src/react/components/chat/chat/components/message-edit-form.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/message-edit-form.js +5 -5
- package/esm/src/react/components/chat/chat/components/message-feedback.d.ts +11 -1
- package/esm/src/react/components/chat/chat/components/message-feedback.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/message-feedback.js +9 -11
- package/esm/src/react/components/chat/chat/components/quick-actions.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/quick-actions.js +3 -1
- package/esm/src/react/components/chat/chat/components/reasoning.d.ts +66 -3
- package/esm/src/react/components/chat/chat/components/reasoning.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/reasoning.js +95 -21
- package/esm/src/react/components/chat/chat/components/sidebar.d.ts +178 -12
- package/esm/src/react/components/chat/chat/components/sidebar.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/sidebar.js +228 -45
- package/esm/src/react/components/chat/chat/components/skill-badge.d.ts +6 -1
- package/esm/src/react/components/chat/chat/components/skill-badge.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/skill-badge.js +6 -5
- package/esm/src/react/components/chat/chat/components/skill-tool.d.ts +37 -0
- package/esm/src/react/components/chat/chat/components/skill-tool.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/components/skill-tool.js +46 -0
- package/esm/src/react/components/chat/chat/components/sources.d.ts +55 -3
- package/esm/src/react/components/chat/chat/components/sources.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/sources.js +50 -16
- package/esm/src/react/components/chat/chat/components/step-indicator.d.ts +42 -3
- package/esm/src/react/components/chat/chat/components/step-indicator.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/step-indicator.js +55 -12
- package/esm/src/react/components/chat/chat/components/tab-switcher.d.ts +1 -1
- package/esm/src/react/components/chat/chat/components/tab-switcher.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/tab-switcher.js +3 -3
- package/esm/src/react/components/chat/chat/components/tool-ui.d.ts +96 -3
- package/esm/src/react/components/chat/chat/components/tool-ui.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/components/tool-ui.js +158 -36
- package/esm/src/react/components/chat/chat/composition/api.d.ts +4 -2
- package/esm/src/react/components/chat/chat/composition/api.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/composition/api.js +4 -2
- package/esm/src/react/components/chat/chat/composition/chat-composer.d.ts +112 -5
- package/esm/src/react/components/chat/chat/composition/chat-composer.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/composition/chat-composer.js +251 -61
- package/esm/src/react/components/chat/chat/composition/chat-empty-state.d.ts +78 -0
- package/esm/src/react/components/chat/chat/composition/chat-empty-state.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/composition/chat-empty-state.js +63 -0
- package/esm/src/react/components/chat/chat/composition/chat-empty.d.ts +4 -1
- package/esm/src/react/components/chat/chat/composition/chat-empty.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/composition/chat-empty.js +11 -10
- package/esm/src/react/components/chat/chat/composition/chat-message-list.d.ts +11 -3
- package/esm/src/react/components/chat/chat/composition/chat-message-list.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/composition/chat-message-list.js +81 -111
- package/esm/src/react/components/chat/chat/composition/chat-root.d.ts +4 -0
- package/esm/src/react/components/chat/chat/composition/chat-root.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/composition/chat-root.js +3 -1
- package/esm/src/react/components/chat/chat/composition/error-banner.d.ts +4 -0
- package/esm/src/react/components/chat/chat/composition/error-banner.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/composition/error-banner.js +10 -7
- package/esm/src/react/components/chat/chat/composition/message.d.ts +123 -5
- package/esm/src/react/components/chat/chat/composition/message.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/composition/message.js +332 -53
- package/esm/src/react/components/chat/chat/composition/model-avatar.d.ts +6 -1
- package/esm/src/react/components/chat/chat/composition/model-avatar.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/composition/model-avatar.js +3 -4
- package/esm/src/react/components/chat/chat/composition/pending-message.d.ts +31 -0
- package/esm/src/react/components/chat/chat/composition/pending-message.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/composition/pending-message.js +31 -0
- package/esm/src/react/components/chat/chat/contexts/chat-context.d.ts +4 -0
- package/esm/src/react/components/chat/chat/contexts/chat-context.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/contexts/composer-context.d.ts +1 -0
- package/esm/src/react/components/chat/chat/contexts/composer-context.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/contexts/conversations-context.d.ts +29 -0
- package/esm/src/react/components/chat/chat/contexts/conversations-context.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/contexts/conversations-context.js +39 -0
- package/esm/src/react/components/chat/chat/contexts/index.d.ts +1 -1
- package/esm/src/react/components/chat/chat/contexts/index.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/contexts/index.js +1 -1
- package/esm/src/react/components/chat/chat/contexts/message-context.d.ts +2 -0
- package/esm/src/react/components/chat/chat/contexts/message-context.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/hooks/use-clipboard.d.ts +10 -0
- package/esm/src/react/components/chat/chat/hooks/use-clipboard.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/hooks/use-clipboard.js +34 -0
- package/esm/src/react/components/chat/chat/hooks/use-conversation.d.ts +21 -0
- package/esm/src/react/components/chat/chat/hooks/use-conversation.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/hooks/use-conversation.js +54 -0
- package/esm/src/react/components/chat/chat/hooks/use-conversations.d.ts +67 -0
- package/esm/src/react/components/chat/chat/hooks/use-conversations.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/hooks/use-conversations.js +317 -0
- package/esm/src/react/components/chat/chat/hooks/use-drop-zone.d.ts +27 -0
- package/esm/src/react/components/chat/chat/hooks/use-drop-zone.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/hooks/use-drop-zone.js +50 -0
- package/esm/src/react/components/chat/chat/hooks/use-stick-to-bottom.d.ts +49 -0
- package/esm/src/react/components/chat/chat/hooks/use-stick-to-bottom.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/hooks/use-stick-to-bottom.js +120 -0
- package/esm/src/react/components/chat/chat/hooks/use-upload.d.ts +34 -0
- package/esm/src/react/components/chat/chat/hooks/use-upload.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/hooks/use-upload.js +147 -0
- package/esm/src/react/components/chat/chat/hooks/use-uploads-registry.d.ts +37 -0
- package/esm/src/react/components/chat/chat/hooks/use-uploads-registry.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/hooks/use-uploads-registry.js +178 -0
- package/esm/src/react/components/chat/chat/index.d.ts +171 -31
- package/esm/src/react/components/chat/chat/index.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/index.js +371 -77
- package/esm/src/react/components/chat/chat/persistence/conversation-store.d.ts +63 -0
- package/esm/src/react/components/chat/chat/persistence/conversation-store.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/persistence/conversation-store.js +1 -0
- package/esm/src/react/components/chat/chat/persistence/local-conversation-store.d.ts +13 -0
- package/esm/src/react/components/chat/chat/persistence/local-conversation-store.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/persistence/local-conversation-store.js +102 -0
- package/esm/src/react/components/chat/chat/persistence/memory-conversation-store.d.ts +11 -0
- package/esm/src/react/components/chat/chat/persistence/memory-conversation-store.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat/persistence/memory-conversation-store.js +33 -0
- package/esm/src/react/components/chat/chat/utils/message-parts.d.ts +4 -1
- package/esm/src/react/components/chat/chat/utils/message-parts.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat/utils/message-parts.js +4 -0
- package/esm/src/react/components/chat/chat-actions.d.ts +164 -0
- package/esm/src/react/components/chat/chat-actions.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat-actions.js +191 -0
- package/esm/src/react/components/chat/chat-agent-picker.d.ts +50 -0
- package/esm/src/react/components/chat/chat-agent-picker.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat-agent-picker.js +40 -0
- package/esm/src/react/components/chat/chat-theme-scope.d.ts +26 -0
- package/esm/src/react/components/chat/chat-theme-scope.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat-theme-scope.js +27 -0
- package/esm/src/react/components/chat/chat-tokens-style.d.ts +21 -0
- package/esm/src/react/components/chat/chat-tokens-style.d.ts.map +1 -0
- package/esm/src/react/components/chat/chat-tokens-style.js +24 -0
- package/esm/src/react/components/chat/chat.d.ts +5 -5
- package/esm/src/react/components/chat/chat.d.ts.map +1 -1
- package/esm/src/react/components/chat/chat.js +5 -5
- package/esm/src/react/components/chat/color-mode.d.ts +46 -0
- package/esm/src/react/components/chat/color-mode.d.ts.map +1 -0
- package/esm/src/react/components/chat/color-mode.js +123 -0
- package/esm/src/react/components/chat/error-boundary.js +2 -2
- package/esm/src/react/components/chat/icons/index.d.ts +8 -0
- package/esm/src/react/components/chat/icons/index.d.ts.map +1 -1
- package/esm/src/react/components/chat/icons/index.js +64 -0
- package/esm/src/react/components/chat/markdown.d.ts +24 -1
- package/esm/src/react/components/chat/markdown.d.ts.map +1 -1
- package/esm/src/react/components/chat/markdown.js +122 -38
- package/esm/src/react/components/chat/model-selector.d.ts +130 -8
- package/esm/src/react/components/chat/model-selector.d.ts.map +1 -1
- package/esm/src/react/components/chat/model-selector.js +148 -121
- package/esm/src/react/components/chat/theme.d.ts +9 -12
- package/esm/src/react/components/chat/theme.d.ts.map +1 -1
- package/esm/src/react/components/chat/theme.js +149 -93
- package/esm/src/react/components/chat/ui/alert.d.ts +30 -0
- package/esm/src/react/components/chat/ui/alert.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/alert.js +35 -0
- package/esm/src/react/components/chat/ui/app-shell.d.ts +155 -0
- package/esm/src/react/components/chat/ui/app-shell.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/app-shell.js +276 -0
- package/esm/src/react/components/chat/ui/avatar.d.ts +24 -0
- package/esm/src/react/components/chat/ui/avatar.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/avatar.js +44 -0
- package/esm/src/react/components/chat/ui/badge.d.ts +24 -0
- package/esm/src/react/components/chat/ui/badge.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/badge.js +30 -0
- package/esm/src/react/components/chat/ui/button.d.ts +44 -0
- package/esm/src/react/components/chat/ui/button.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/button.js +108 -0
- package/esm/src/react/components/chat/ui/card.d.ts +42 -0
- package/esm/src/react/components/chat/ui/card.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/card.js +55 -0
- package/esm/src/react/components/chat/ui/checkbox.d.ts +28 -0
- package/esm/src/react/components/chat/ui/checkbox.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/checkbox.js +36 -0
- package/esm/src/react/components/chat/ui/code-block.d.ts +89 -0
- package/esm/src/react/components/chat/ui/code-block.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/code-block.js +277 -0
- package/esm/src/react/components/chat/ui/collapsible.d.ts +30 -0
- package/esm/src/react/components/chat/ui/collapsible.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/collapsible.js +44 -0
- package/esm/src/react/components/chat/ui/command.d.ts +65 -0
- package/esm/src/react/components/chat/ui/command.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/command.js +121 -0
- package/esm/src/react/components/chat/ui/cva.d.ts +36 -0
- package/esm/src/react/components/chat/ui/cva.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/cva.js +45 -0
- package/esm/src/react/components/chat/ui/dialog.d.ts +55 -0
- package/esm/src/react/components/chat/ui/dialog.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/dialog.js +116 -0
- package/esm/src/react/components/chat/ui/drawer.d.ts +41 -0
- package/esm/src/react/components/chat/ui/drawer.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/drawer.js +92 -0
- package/esm/src/react/components/chat/ui/dropdown-menu.d.ts +63 -0
- package/esm/src/react/components/chat/ui/dropdown-menu.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/dropdown-menu.js +76 -0
- package/esm/src/react/components/chat/ui/file-type.d.ts +26 -0
- package/esm/src/react/components/chat/ui/file-type.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/file-type.js +235 -0
- package/esm/src/react/components/chat/ui/floating.d.ts +29 -0
- package/esm/src/react/components/chat/ui/floating.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/floating.js +90 -0
- package/esm/src/react/components/chat/ui/icon-button.d.ts +19 -0
- package/esm/src/react/components/chat/ui/icon-button.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/icon-button.js +20 -0
- package/esm/src/react/components/chat/ui/index.d.ts +43 -0
- package/esm/src/react/components/chat/ui/index.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/index.js +42 -0
- package/esm/src/react/components/chat/ui/input.d.ts +27 -0
- package/esm/src/react/components/chat/ui/input.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/input.js +41 -0
- package/esm/src/react/components/chat/ui/label.d.ts +29 -0
- package/esm/src/react/components/chat/ui/label.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/label.js +40 -0
- package/esm/src/react/components/chat/ui/list.d.ts +47 -0
- package/esm/src/react/components/chat/ui/list.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/list.js +40 -0
- package/esm/src/react/components/chat/ui/pill.d.ts +26 -0
- package/esm/src/react/components/chat/ui/pill.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/pill.js +39 -0
- package/esm/src/react/components/chat/ui/popover.d.ts +47 -0
- package/esm/src/react/components/chat/ui/popover.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/popover.js +68 -0
- package/esm/src/react/components/chat/ui/progress-bar.d.ts +20 -0
- package/esm/src/react/components/chat/ui/progress-bar.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/progress-bar.js +31 -0
- package/esm/src/react/components/chat/ui/radio.d.ts +25 -0
- package/esm/src/react/components/chat/ui/radio.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/radio.js +29 -0
- package/esm/src/react/components/chat/ui/scroll-fade.d.ts +23 -0
- package/esm/src/react/components/chat/ui/scroll-fade.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/scroll-fade.js +40 -0
- package/esm/src/react/components/chat/ui/select.d.ts +64 -0
- package/esm/src/react/components/chat/ui/select.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/select.js +148 -0
- package/esm/src/react/components/chat/ui/shimmer.d.ts +25 -0
- package/esm/src/react/components/chat/ui/shimmer.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/shimmer.js +24 -0
- package/esm/src/react/components/chat/ui/skeleton.d.ts +14 -0
- package/esm/src/react/components/chat/ui/skeleton.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/skeleton.js +12 -0
- package/esm/src/react/components/chat/ui/slot.d.ts +21 -0
- package/esm/src/react/components/chat/ui/slot.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/slot.js +70 -0
- package/esm/src/react/components/chat/ui/status.d.ts +28 -0
- package/esm/src/react/components/chat/ui/status.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/status.js +23 -0
- package/esm/src/react/components/chat/ui/switch.d.ts +34 -0
- package/esm/src/react/components/chat/ui/switch.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/switch.js +58 -0
- package/esm/src/react/components/chat/ui/tabs.d.ts +44 -0
- package/esm/src/react/components/chat/ui/tabs.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/tabs.js +51 -0
- package/esm/src/react/components/chat/ui/tag.d.ts +22 -0
- package/esm/src/react/components/chat/ui/tag.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/tag.js +27 -0
- package/esm/src/react/components/chat/ui/textarea.d.ts +22 -0
- package/esm/src/react/components/chat/ui/textarea.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/textarea.js +35 -0
- package/esm/src/react/components/chat/ui/tooltip.d.ts +40 -0
- package/esm/src/react/components/chat/ui/tooltip.d.ts.map +1 -0
- package/esm/src/react/components/chat/ui/tooltip.js +132 -0
- package/esm/src/react/primitives/input-box.d.ts.map +1 -1
- package/esm/src/react/primitives/input-box.js +17 -4
- package/esm/src/server/handlers/dev/framework-candidates.generated.d.ts.map +1 -1
- package/esm/src/server/handlers/dev/framework-candidates.generated.js +9437 -1064
- package/esm/src/server/handlers/dev/projects/html-shell.d.ts +1 -1
- package/esm/src/server/handlers/dev/projects/html-shell.d.ts.map +1 -1
- package/esm/src/server/handlers/dev/projects/html-shell.js +1 -12
- package/esm/src/server/handlers/request/public-agents-list.handler.d.ts +18 -0
- package/esm/src/server/handlers/request/public-agents-list.handler.d.ts.map +1 -0
- package/esm/src/server/handlers/request/public-agents-list.handler.js +44 -0
- package/esm/src/server/runtime-handler/index.d.ts +1 -1
- package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.js +3 -0
- package/esm/src/studio/bridge/bridge-bundle.generated.d.ts +1 -1
- package/esm/src/studio/bridge/bridge-bundle.generated.d.ts.map +1 -1
- package/esm/src/studio/bridge/bridge-bundle.generated.js +3 -2
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/esm/src/workflow/blob/local-storage.d.ts +32 -0
- package/esm/src/workflow/blob/local-storage.d.ts.map +1 -0
- package/esm/src/workflow/blob/local-storage.js +179 -0
- package/esm/src/workflow/blob/types.d.ts +5 -0
- package/esm/src/workflow/blob/types.d.ts.map +1 -1
- package/esm/src/workflow/blob/veryfront-cloud-storage.d.ts +11 -0
- package/esm/src/workflow/blob/veryfront-cloud-storage.d.ts.map +1 -1
- package/esm/src/workflow/blob/veryfront-cloud-storage.js +36 -0
- package/package.json +5 -1
- package/esm/src/react/components/chat/chat/components/uploads-panel.d.ts +0 -20
- package/esm/src/react/components/chat/chat/components/uploads-panel.d.ts.map +0 -1
- package/esm/src/react/components/chat/chat/components/uploads-panel.js +0 -49
- package/esm/src/react/components/chat/chat/contexts/thread-list-context.d.ts +0 -28
- package/esm/src/react/components/chat/chat/contexts/thread-list-context.d.ts.map +0 -1
- package/esm/src/react/components/chat/chat/contexts/thread-list-context.js +0 -27
- package/esm/src/react/components/chat/chat/hooks/use-threads.d.ts +0 -28
- package/esm/src/react/components/chat/chat/hooks/use-threads.d.ts.map +0 -1
- package/esm/src/react/components/chat/chat/hooks/use-threads.js +0 -151
- package/esm/src/react/components/chat/chat-with-sidebar.d.ts +0 -110
- package/esm/src/react/components/chat/chat-with-sidebar.d.ts.map +0 -1
- package/esm/src/react/components/chat/chat-with-sidebar.js +0 -167
- package/esm/src/react/components/chat/message.d.ts +0 -42
- package/esm/src/react/components/chat/message.d.ts.map +0 -1
- package/esm/src/react/components/chat/message.js +0 -69
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentPicker — Popover + Command combobox for switching the active agent.
|
|
3
|
+
* Forked dependency-light 1:1 from Veryfront Studio's `AgentPicker`: a Pill (or
|
|
4
|
+
* input-style) trigger opens a searchable list of agent rows (Avatar + name),
|
|
5
|
+
* a Check marks the selection, and optional "Create Agent" / "Manage Agents"
|
|
6
|
+
* affordances sit at the bottom. Studio's mobile `Drawer`/`ResponsiveSwitch`
|
|
7
|
+
* branch is dropped (Studio-only deps) — the overlay always portals via our
|
|
8
|
+
* `Floating` (through `PopoverContent`) so it never clips in the iframe.
|
|
9
|
+
*
|
|
10
|
+
* Semantic Studio classes remapped to veryfront's `[var(--token)]` vocabulary;
|
|
11
|
+
* icons inherit the Command row's sizing. Composes the private chat/ui
|
|
12
|
+
* primitives (Popover, Command, Avatar) — no radix / cva / `@/` imports.
|
|
13
|
+
*
|
|
14
|
+
* @module react/components/chat/agent-picker
|
|
15
|
+
*/
|
|
16
|
+
import * as React from "../../../../react/react.js";
|
|
17
|
+
import { cn } from "./theme.js";
|
|
18
|
+
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "./ui/command.js";
|
|
19
|
+
import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover.js";
|
|
20
|
+
import { Pill } from "./ui/pill.js";
|
|
21
|
+
import { Avatar } from "./ui/avatar.js";
|
|
22
|
+
import { CheckIcon, ChevronDownIcon, PlusIcon, SparklesIcon } from "./icons/index.js";
|
|
23
|
+
import { COMPONENT_ERROR } from "../../../errors/error-registry.js";
|
|
24
|
+
/** Search box appears once the combined agent count crosses this. */
|
|
25
|
+
const SEARCH_THRESHOLD = 5;
|
|
26
|
+
const LOADING_ROW_WIDTHS = ["w-3/5", "w-3/4", "w-2/3"];
|
|
27
|
+
function totalAgentCount(agents, sections) {
|
|
28
|
+
return agents.length +
|
|
29
|
+
sections.reduce((acc, section) => acc + section.agents.length, 0);
|
|
30
|
+
}
|
|
31
|
+
function findAgent(id, agents, sections) {
|
|
32
|
+
if (id === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
const top = agents.find((agent) => agent.id === id);
|
|
35
|
+
if (top)
|
|
36
|
+
return top;
|
|
37
|
+
for (const section of sections) {
|
|
38
|
+
const hit = section.agents.find((agent) => agent.id === id);
|
|
39
|
+
if (hit)
|
|
40
|
+
return hit;
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
function AgentPickerLoadingRows() {
|
|
45
|
+
return (React.createElement("output", { "aria-label": "Loading agents", className: "block px-1 py-1" },
|
|
46
|
+
React.createElement("span", { className: "sr-only" }, "Loading agents"),
|
|
47
|
+
LOADING_ROW_WIDTHS.map((widthClass, index) => (React.createElement("div", { key: `${index}-${widthClass}`, "aria-hidden": "true", className: "flex items-center gap-3 px-3 py-2" },
|
|
48
|
+
React.createElement("div", { className: "size-5 shrink-0 rounded-full bg-[var(--accent)] animate-pulse" }),
|
|
49
|
+
React.createElement("div", { className: cn("h-3 rounded-md bg-[var(--accent)] animate-pulse", widthClass) }))))));
|
|
50
|
+
}
|
|
51
|
+
const AgentPickerContext = React.createContext(null);
|
|
52
|
+
/**
|
|
53
|
+
* Read the enclosing `AgentPicker` selection + open state. Throws when used
|
|
54
|
+
* outside an `<AgentPicker>`.
|
|
55
|
+
*/
|
|
56
|
+
export function useAgentPicker() {
|
|
57
|
+
const ctx = React.useContext(AgentPickerContext);
|
|
58
|
+
if (!ctx) {
|
|
59
|
+
throw COMPONENT_ERROR.create({
|
|
60
|
+
detail: "useAgentPicker must be used within a AgentPicker",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return ctx;
|
|
64
|
+
}
|
|
65
|
+
/** The pill (or input-style) combobox trigger. Toggles the popover. */
|
|
66
|
+
function AgentPickerTrigger({ inputStyle = false, invalid = false, children, className }) {
|
|
67
|
+
const { value, icons } = useAgentPicker();
|
|
68
|
+
const sections = React.useContext(AgentDataContext);
|
|
69
|
+
const selected = sections ? findAgent(value, sections.agents, sections.sections) : undefined;
|
|
70
|
+
const triggerLabel = selected?.name ?? "Select agent";
|
|
71
|
+
const content = children ?? (React.createElement(React.Fragment, null,
|
|
72
|
+
selected && (React.createElement(Avatar, { name: selected.name, avatarSrc: selected.avatarSrc, tone: "muted", "aria-hidden": "true", className: "size-5! bg-[var(--background)]" })),
|
|
73
|
+
React.createElement("span", { className: "min-w-0 truncate" }, triggerLabel),
|
|
74
|
+
inputStyle
|
|
75
|
+
? (icons?.chevron ??
|
|
76
|
+
React.createElement(ChevronDownIcon, { className: "ml-auto size-3.5 opacity-50" }))
|
|
77
|
+
: (icons?.chevron ?? React.createElement(ChevronDownIcon, { className: "ml-auto" }))));
|
|
78
|
+
const trigger = inputStyle
|
|
79
|
+
? (React.createElement("button", { type: "button", "data-invalid": invalid || undefined, className: cn("flex w-full items-center gap-2.5 rounded-md border border-[var(--input-border)] bg-[var(--input-bg)] h-[50px] px-3 text-base text-[var(--foreground)]", "data-[invalid=true]:border-[var(--status-error)]", className) }, content))
|
|
80
|
+
: (React.createElement(Pill, { className: cn("min-w-0 max-w-full", className) }, content));
|
|
81
|
+
return React.createElement(PopoverTrigger, { asChild: true }, trigger);
|
|
82
|
+
}
|
|
83
|
+
AgentPickerTrigger.displayName = "AgentPicker.Trigger";
|
|
84
|
+
/** The popover surface wrapping a `Command` (search + list region). */
|
|
85
|
+
function AgentPickerContent({ showSearch = false, searchPlaceholder = "Search agents...", children, className, }) {
|
|
86
|
+
return (React.createElement(PopoverContent, { align: "start", className: cn("min-w-[280px] p-0! rounded-lg", className) },
|
|
87
|
+
React.createElement(Command, { className: "bg-transparent" },
|
|
88
|
+
showSearch && React.createElement(CommandInput, { placeholder: searchPlaceholder }),
|
|
89
|
+
children)));
|
|
90
|
+
}
|
|
91
|
+
AgentPickerContent.displayName = "AgentPicker.Content";
|
|
92
|
+
/** The scrollable `Command` list region. */
|
|
93
|
+
function AgentPickerList({ children, className }) {
|
|
94
|
+
return (React.createElement(CommandList, { className: cn("max-h-[320px]", className) }, children));
|
|
95
|
+
}
|
|
96
|
+
AgentPickerList.displayName = "AgentPicker.List";
|
|
97
|
+
/** A single agent row (Avatar + name + selection check). */
|
|
98
|
+
function AgentPickerItem({ agent, selected, className }) {
|
|
99
|
+
const { value, onSelect, icons } = useAgentPicker();
|
|
100
|
+
const isSelected = selected ?? agent.id === value;
|
|
101
|
+
return (React.createElement(CommandItem, { value: agent.name, disabled: agent.disabled, onSelect: () => onSelect(agent.id), className: className },
|
|
102
|
+
React.createElement(Avatar, { name: agent.name, avatarSrc: agent.avatarSrc, tone: "muted", "aria-hidden": "true", className: "size-5! bg-[var(--background)]" }),
|
|
103
|
+
React.createElement("span", { className: "min-w-0 flex-1 truncate" }, agent.name),
|
|
104
|
+
isSelected &&
|
|
105
|
+
(icons?.check ?? React.createElement(CheckIcon, { className: "ml-auto opacity-70" }))));
|
|
106
|
+
}
|
|
107
|
+
AgentPickerItem.displayName = "AgentPicker.Item";
|
|
108
|
+
/**
|
|
109
|
+
* Data passed down so the default `Trigger` can resolve the selected label from
|
|
110
|
+
* the preset `agents` / `sections`. Only populated on the preset (childless)
|
|
111
|
+
* path; a fully-composed tree supplies its own trigger contents.
|
|
112
|
+
*/
|
|
113
|
+
const AgentDataContext = React.createContext(null);
|
|
114
|
+
/** The default preset body — the data-driven groups + action rows. */
|
|
115
|
+
function AgentPickerPresetBody({ agents, value, sections, onManage, onCreate, isLoading, icons, }) {
|
|
116
|
+
const hasSectionAgents = sections.some((section) => section.agents.length > 0);
|
|
117
|
+
const showLoading = isLoading && !hasSectionAgents;
|
|
118
|
+
return (React.createElement(React.Fragment, null,
|
|
119
|
+
!showLoading && React.createElement(CommandEmpty, null, "No agents found."),
|
|
120
|
+
agents.length > 0 && (React.createElement(CommandGroup, null, agents.map((agent) => (React.createElement(AgentPickerItem, { key: agent.id, agent: agent, selected: agent.id === value }))))),
|
|
121
|
+
showLoading && React.createElement(AgentPickerLoadingRows, null),
|
|
122
|
+
sections.map((section, index) => (React.createElement(CommandGroup, { key: section.label ?? `section-${index}`, heading: section.label }, section.agents.map((agent) => (React.createElement(AgentPickerItem, { key: agent.id, agent: agent, selected: agent.id === value })))))),
|
|
123
|
+
(onCreate || onManage) && (React.createElement(CommandGroup, null,
|
|
124
|
+
onCreate && (React.createElement(CommandItem, { value: "Create Agent", onSelect: onCreate },
|
|
125
|
+
icons?.create ?? React.createElement(PlusIcon, null),
|
|
126
|
+
"Create Agent")),
|
|
127
|
+
onManage && (React.createElement(CommandItem, { value: "Manage Agents", onSelect: onManage },
|
|
128
|
+
icons?.more ?? React.createElement(SparklesIcon, null),
|
|
129
|
+
"Manage Agents"))))));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* `AgentPicker.Root` — context provider + the popover shell. No children
|
|
133
|
+
* renders the default data-driven preset; pass children to recompose from
|
|
134
|
+
* `AgentPicker.Trigger` / `Content` / `List` / `Item`.
|
|
135
|
+
*/
|
|
136
|
+
function AgentPickerRoot({ agents, value, onValueChange, sections = [], onManage, onCreate, onOpenChange, inputStyle = false, invalid = false, isLoading = false, className, icons, children, }) {
|
|
137
|
+
const [open, setOpen] = React.useState(false);
|
|
138
|
+
const showSearch = totalAgentCount(agents, sections) > SEARCH_THRESHOLD;
|
|
139
|
+
const handleOpenChange = React.useCallback((nextOpen) => {
|
|
140
|
+
setOpen(nextOpen);
|
|
141
|
+
onOpenChange?.(nextOpen);
|
|
142
|
+
}, [onOpenChange]);
|
|
143
|
+
const handleSelect = React.useCallback((id) => {
|
|
144
|
+
handleOpenChange(false);
|
|
145
|
+
onValueChange?.(id);
|
|
146
|
+
}, [handleOpenChange, onValueChange]);
|
|
147
|
+
const handleManage = () => {
|
|
148
|
+
handleOpenChange(false);
|
|
149
|
+
onManage?.();
|
|
150
|
+
};
|
|
151
|
+
const handleCreate = () => {
|
|
152
|
+
handleOpenChange(false);
|
|
153
|
+
onCreate?.();
|
|
154
|
+
};
|
|
155
|
+
const context = {
|
|
156
|
+
value,
|
|
157
|
+
onSelect: handleSelect,
|
|
158
|
+
open,
|
|
159
|
+
setOpen: handleOpenChange,
|
|
160
|
+
icons,
|
|
161
|
+
};
|
|
162
|
+
return (React.createElement(AgentPickerContext.Provider, { value: context },
|
|
163
|
+
React.createElement(AgentDataContext.Provider, { value: { agents, sections } },
|
|
164
|
+
React.createElement(Popover, { open: open, onOpenChange: handleOpenChange }, children ?? (React.createElement(React.Fragment, null,
|
|
165
|
+
React.createElement(AgentPickerTrigger, { inputStyle: inputStyle, invalid: invalid, className: className }),
|
|
166
|
+
React.createElement(AgentPickerContent, { showSearch: showSearch },
|
|
167
|
+
React.createElement(AgentPickerList, null,
|
|
168
|
+
React.createElement(AgentPickerPresetBody, { agents: agents, value: value, sections: sections, onManage: onManage ? handleManage : undefined, onCreate: onCreate ? handleCreate : undefined, isLoading: isLoading, icons: icons })))))))));
|
|
169
|
+
}
|
|
170
|
+
AgentPickerRoot.displayName = "AgentPicker.Root";
|
|
171
|
+
/**
|
|
172
|
+
* AgentPicker — render `<AgentPicker agents={...} .../>` for the default
|
|
173
|
+
* data-driven combobox, or compose `AgentPicker.Trigger` / `Content` / `List` /
|
|
174
|
+
* `Item` for a custom menu. Mirrors the `ToolCall` compound: render it, or
|
|
175
|
+
* compose it.
|
|
176
|
+
*/
|
|
177
|
+
export const AgentPicker = Object.assign(AgentPickerRoot, {
|
|
178
|
+
Root: AgentPickerRoot,
|
|
179
|
+
Trigger: AgentPickerTrigger,
|
|
180
|
+
Content: AgentPickerContent,
|
|
181
|
+
List: AgentPickerList,
|
|
182
|
+
Item: AgentPickerItem,
|
|
183
|
+
});
|
|
@@ -8,7 +8,7 @@ export function Shimmer({ children }) {
|
|
|
8
8
|
/** Render loader. */
|
|
9
9
|
export function Loader({ className, size = 16, }) {
|
|
10
10
|
const dotSize = size / 4;
|
|
11
|
-
return (React.createElement("div", { className: cn("flex items-center gap-1", className) }, ["0ms", "150ms", "300ms"].map((animationDelay) => (React.createElement("span", { key: animationDelay, className: "animate-bounce rounded-full bg-[var(--
|
|
11
|
+
return (React.createElement("div", { className: cn("flex items-center gap-1", className) }, ["0ms", "150ms", "300ms"].map((animationDelay) => (React.createElement("span", { key: animationDelay, className: "animate-bounce rounded-full bg-[var(--faint)]", style: { width: dotSize, height: dotSize, animationDelay } })))));
|
|
12
12
|
}
|
|
13
13
|
/** Render fade in. */
|
|
14
14
|
export function FadeIn({ children, duration = 300, className, }) {
|
|
@@ -1,18 +1,140 @@
|
|
|
1
1
|
import * as React from "../../../../../../react/react.js";
|
|
2
|
+
/** Upload lifecycle state (shadcn-style). Drives the icon, label, and treatment. */
|
|
3
|
+
export type AttachmentState = "selected" | "uploading" | "processing" | "uploaded" | "error";
|
|
2
4
|
/** Public API contract for attachment info. */
|
|
3
5
|
export interface AttachmentInfo {
|
|
4
6
|
id: string;
|
|
5
7
|
name: string;
|
|
8
|
+
/** Legacy two-value status; prefer `state` for the full lifecycle. */
|
|
6
9
|
status?: "uploading" | "ready";
|
|
10
|
+
/** Upload lifecycle state — sets the icon, label, and container treatment. */
|
|
11
|
+
state?: AttachmentState;
|
|
12
|
+
/** Upload progress (0–100), shown in the `uploading` label. */
|
|
13
|
+
progress?: number;
|
|
7
14
|
type?: string;
|
|
8
15
|
size?: number;
|
|
9
16
|
preview?: string;
|
|
17
|
+
/** Resolved URL once the file has finished uploading. */
|
|
18
|
+
url?: string;
|
|
19
|
+
}
|
|
20
|
+
/** Icon overrides for {@link AttachmentPill}. Each defaults to its glyph. */
|
|
21
|
+
export interface AttachmentPillIcons {
|
|
22
|
+
/** Override the remove (✕) glyph. */
|
|
23
|
+
remove?: React.ReactNode;
|
|
24
|
+
/** Override the retry glyph. */
|
|
25
|
+
retry?: React.ReactNode;
|
|
10
26
|
}
|
|
11
27
|
/** Props accepted by attachment pill. */
|
|
12
|
-
export interface AttachmentPillProps {
|
|
28
|
+
export interface AttachmentPillProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
13
29
|
attachment: AttachmentInfo;
|
|
14
30
|
onRemove?: (id: string) => void;
|
|
31
|
+
/** Retry handler — surfaces a retry button in the `error` state. */
|
|
32
|
+
onRetry?: (id: string) => void;
|
|
33
|
+
/** Override the remove / retry button icons. */
|
|
34
|
+
icons?: AttachmentPillIcons;
|
|
35
|
+
/**
|
|
36
|
+
* Draw the outline + surrounding box. `false` gives a flat, borderless row
|
|
37
|
+
* (e.g. `AttachmentsPanel`, where the pills are a plain list). @default true
|
|
38
|
+
*/
|
|
39
|
+
bordered?: boolean;
|
|
40
|
+
/** Compose your own pill; when omitted, the default anatomy is rendered. */
|
|
41
|
+
children?: React.ReactNode;
|
|
42
|
+
}
|
|
43
|
+
/** Derived per-pill view state shared with `AttachmentPill.*` sub-parts. */
|
|
44
|
+
export interface AttachmentPillContextValue {
|
|
45
|
+
attachment: AttachmentInfo;
|
|
46
|
+
onRemove?: (id: string) => void;
|
|
47
|
+
onRetry?: (id: string) => void;
|
|
48
|
+
icons?: AttachmentPillIcons;
|
|
49
|
+
/** File extension (from the name, falling back to the media type). */
|
|
50
|
+
ext: string;
|
|
51
|
+
/** Tailwind color pair for the default (no-state) icon box. */
|
|
52
|
+
colorClass: string;
|
|
53
|
+
/** Whether the attachment resolves to an image. */
|
|
54
|
+
isImage: boolean;
|
|
55
|
+
/** The image `src` to show in the thumbnail (preview → url). */
|
|
56
|
+
imageSrc?: string;
|
|
57
|
+
/** Whether the current state is `error`. */
|
|
58
|
+
isError: boolean;
|
|
59
|
+
/** Whether a spinner overlay should show (uploading / processing). */
|
|
60
|
+
isBusy: boolean;
|
|
61
|
+
/** Whether the title should shimmer (uploading / processing). */
|
|
62
|
+
shimmerTitle: boolean;
|
|
63
|
+
/** The secondary label line for the current state. */
|
|
64
|
+
label: string;
|
|
65
|
+
/** Legacy dimming for the old `status="uploading"` API. */
|
|
66
|
+
legacyUploading: boolean;
|
|
67
|
+
/** Whether the remove control should render. */
|
|
68
|
+
showRemove: boolean;
|
|
69
|
+
/** The state glyph for the icon box (null → render the extension text). */
|
|
70
|
+
stateGlyph: React.ReactNode;
|
|
71
|
+
/** Tailwind classes for the icon box background/foreground. */
|
|
72
|
+
boxClass: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Read the enclosing `AttachmentPill` state. Throws when used outside an
|
|
76
|
+
* `AttachmentPill`.
|
|
77
|
+
*/
|
|
78
|
+
export declare function useAttachmentPill(): AttachmentPillContextValue;
|
|
79
|
+
/**
|
|
80
|
+
* `AttachmentPill.Thumbnail` — the image square (with a busy overlay). Renders
|
|
81
|
+
* only when the attachment resolves to a non-error image with a source.
|
|
82
|
+
*/
|
|
83
|
+
declare function AttachmentPillThumbnail({ className }: {
|
|
84
|
+
className?: string;
|
|
85
|
+
}): React.JSX.Element | null;
|
|
86
|
+
declare namespace AttachmentPillThumbnail {
|
|
87
|
+
var displayName: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* `AttachmentPill.Icon` — the state-glyph / file-extension square shown when
|
|
91
|
+
* there is no image thumbnail.
|
|
92
|
+
*/
|
|
93
|
+
declare function AttachmentPillIcon({ className }: {
|
|
94
|
+
className?: string;
|
|
95
|
+
}): React.JSX.Element;
|
|
96
|
+
declare namespace AttachmentPillIcon {
|
|
97
|
+
var displayName: string;
|
|
98
|
+
}
|
|
99
|
+
/** `AttachmentPill.Label` — the name + secondary state-line column. */
|
|
100
|
+
declare function AttachmentPillLabel({ className }: {
|
|
101
|
+
className?: string;
|
|
102
|
+
}): React.JSX.Element;
|
|
103
|
+
declare namespace AttachmentPillLabel {
|
|
104
|
+
var displayName: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* `AttachmentPill.Retry` — the retry control. Renders only in the `error` state
|
|
108
|
+
* when an `onRetry` handler is provided.
|
|
109
|
+
*/
|
|
110
|
+
declare function AttachmentPillRetry({ className }: {
|
|
111
|
+
className?: string;
|
|
112
|
+
}): React.JSX.Element | null;
|
|
113
|
+
declare namespace AttachmentPillRetry {
|
|
114
|
+
var displayName: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* `AttachmentPill.Remove` — the remove (✕) control. Renders only when an
|
|
118
|
+
* `onRemove` handler is provided and the pill isn't a legacy uploading pill.
|
|
119
|
+
*/
|
|
120
|
+
declare function AttachmentPillRemove({ className }: {
|
|
121
|
+
className?: string;
|
|
122
|
+
}): React.JSX.Element | null;
|
|
123
|
+
declare namespace AttachmentPillRemove {
|
|
124
|
+
var displayName: string;
|
|
15
125
|
}
|
|
16
|
-
/**
|
|
17
|
-
|
|
126
|
+
/**
|
|
127
|
+
* AttachmentPill — render `<AttachmentPill attachment={…} />` for the default
|
|
128
|
+
* chip, or compose `AttachmentPill.Root` + `.Thumbnail` / `.Icon` / `.Label` /
|
|
129
|
+
* `.Retry` / `.Remove` for a custom layout. Publicly aliased as `Attachment`.
|
|
130
|
+
*/
|
|
131
|
+
export declare const AttachmentPill: React.ForwardRefExoticComponent<AttachmentPillProps & React.RefAttributes<HTMLDivElement>> & {
|
|
132
|
+
Root: React.ForwardRefExoticComponent<AttachmentPillProps & React.RefAttributes<HTMLDivElement>>;
|
|
133
|
+
Thumbnail: typeof AttachmentPillThumbnail;
|
|
134
|
+
Icon: typeof AttachmentPillIcon;
|
|
135
|
+
Label: typeof AttachmentPillLabel;
|
|
136
|
+
Retry: typeof AttachmentPillRetry;
|
|
137
|
+
Remove: typeof AttachmentPillRemove;
|
|
138
|
+
};
|
|
139
|
+
export {};
|
|
18
140
|
//# sourceMappingURL=attachment-pill.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment-pill.d.ts","sourceRoot":"","sources":["../../../../../../../src/src/react/components/chat/chat/components/attachment-pill.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"attachment-pill.d.ts","sourceRoot":"","sources":["../../../../../../../src/src/react/components/chat/chat/components/attachment-pill.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,kCAAkC,CAAC;AAO1D,oFAAoF;AACpF,MAAM,MAAM,eAAe,GACvB,UAAU,GACV,WAAW,GACX,YAAY,GACZ,UAAU,GACV,OAAO,CAAC;AAEZ,+CAA+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAC/B,8EAA8E;IAC9E,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,6EAA6E;AAC7E,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,gCAAgC;IAChC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED,yCAAyC;AACzC,MAAM,WAAW,mBAAoB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC/E,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,oEAAoE;IACpE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,gDAAgD;IAChD,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AA6FD,4EAA4E;AAC5E,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,OAAO,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;IACtB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,eAAe,EAAE,OAAO,CAAC;IACzB,gDAAgD;IAChD,UAAU,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,0BAA0B,CAQ9D;AAiHD;;;GAGG;AACH,iBAAS,uBAAuB,CAC9B,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACpC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAsB1B;kBAxBQ,uBAAuB;;;AA2BhC;;;GAGG;AACH,iBAAS,kBAAkB,CACzB,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACpC,KAAK,CAAC,GAAG,CAAC,OAAO,CAkBnB;kBApBQ,kBAAkB;;;AAuB3B,uEAAuE;AACvE,iBAAS,mBAAmB,CAC1B,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACpC,KAAK,CAAC,GAAG,CAAC,OAAO,CAqBnB;kBAvBQ,mBAAmB;;;AA0B5B;;;GAGG;AACH,iBAAS,mBAAmB,CAC1B,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACpC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAgB1B;kBAlBQ,mBAAmB;;;AAqB5B;;;GAGG;AACH,iBAAS,oBAAoB,CAC3B,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACpC,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CA8B1B;kBAhCQ,oBAAoB;;;AAmC7B;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;;CAOzB,CAAC"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import * as React from "../../../../../../react/react.js";
|
|
2
2
|
import { cn } from "../../theme.js";
|
|
3
|
+
import { CheckIcon, ClockIcon, FileTextIcon, RefreshCwIcon } from "../../icons/index.js";
|
|
4
|
+
import { Button } from "../../ui/button.js";
|
|
5
|
+
import { Shimmer } from "./animations.js";
|
|
6
|
+
import { COMPONENT_ERROR } from "../../../../../errors/error-registry.js";
|
|
3
7
|
const FILE_TYPE_COLORS = {
|
|
4
|
-
pdf: "text-red-
|
|
5
|
-
docx: "text-blue-
|
|
6
|
-
csv: "text-emerald-
|
|
7
|
-
txt: "text-
|
|
8
|
-
md: "text-purple-
|
|
9
|
-
mdx: "text-purple-
|
|
8
|
+
pdf: "text-red-700 bg-red-100",
|
|
9
|
+
docx: "text-blue-700 bg-blue-100",
|
|
10
|
+
csv: "text-emerald-700 bg-emerald-100",
|
|
11
|
+
txt: "text-[var(--faint)] bg-[var(--tertiary)]",
|
|
12
|
+
md: "text-purple-700 bg-purple-100",
|
|
13
|
+
mdx: "text-purple-700 bg-purple-100",
|
|
10
14
|
};
|
|
11
15
|
function getExtension(name) {
|
|
12
16
|
const dot = name.lastIndexOf(".");
|
|
@@ -19,23 +23,203 @@ function formatSize(bytes) {
|
|
|
19
23
|
return `${(bytes / 1024).toFixed(0)} KB`;
|
|
20
24
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
21
25
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
React.createElement("span", { className: cn("inline-flex items-center justify-center rounded px-1 py-0.5 text-[9px] font-bold uppercase leading-none", colorClass) }, ext || "?"),
|
|
29
|
-
React.createElement("span", { className: "truncate max-w-[120px]" }, attachment.name),
|
|
30
|
-
attachment.size != null && (React.createElement("span", { className: "text-[10px] text-[var(--input-placeholder)] shrink-0" }, formatSize(attachment.size))),
|
|
31
|
-
attachment.status === "uploading"
|
|
32
|
-
? (React.createElement("span", { className: "size-3 shrink-0 rounded-full border-2 border-neutral-400 border-t-transparent animate-spin" }))
|
|
33
|
-
: onRemove && (React.createElement("button", { type: "button", onClick: () => onRemove(attachment.id), "aria-label": `Remove ${attachment.name}`, className: "size-4 shrink-0 flex items-center justify-center rounded-full hover:bg-[var(--accent)] text-[var(--input-placeholder)] hover:text-[var(--foreground)] transition-colors" },
|
|
34
|
-
React.createElement("svg", { className: "size-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" },
|
|
35
|
-
React.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
36
|
-
React.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })))),
|
|
37
|
-
showPreview && attachment.preview && (React.createElement("div", { className: "absolute bottom-full left-0 mb-2 z-50 w-64 pointer-events-none" },
|
|
38
|
-
React.createElement("div", { className: "bg-[var(--card)] border border-[var(--border)] rounded-xl shadow-lg p-3 text-left" },
|
|
39
|
-
React.createElement("p", { className: "text-[10px] font-medium text-[var(--muted-foreground)] uppercase mb-1" }, "Preview"),
|
|
40
|
-
React.createElement("p", { className: "text-xs text-[var(--card-foreground)] line-clamp-4 whitespace-pre-wrap" }, attachment.preview))))));
|
|
26
|
+
function getTypeLabel(attachment, ext, mediaType) {
|
|
27
|
+
if (attachment.status === "uploading")
|
|
28
|
+
return "Uploading";
|
|
29
|
+
if (attachment.size != null)
|
|
30
|
+
return formatSize(attachment.size);
|
|
31
|
+
return ext ? ext.toUpperCase() : (mediaType || "File");
|
|
41
32
|
}
|
|
33
|
+
/** Secondary line for the current lifecycle state. */
|
|
34
|
+
function getStateLabel(attachment, ext, mediaType) {
|
|
35
|
+
switch (attachment.state) {
|
|
36
|
+
case "selected":
|
|
37
|
+
return "Ready to upload";
|
|
38
|
+
case "uploading":
|
|
39
|
+
return attachment.progress != null
|
|
40
|
+
? `Uploading · ${Math.round(attachment.progress)}%`
|
|
41
|
+
: "Uploading";
|
|
42
|
+
case "processing":
|
|
43
|
+
return "Processing document";
|
|
44
|
+
case "uploaded":
|
|
45
|
+
return attachment.size != null ? `Uploaded · ${formatSize(attachment.size)}` : "Uploaded";
|
|
46
|
+
case "error":
|
|
47
|
+
return "Upload failed. Try again.";
|
|
48
|
+
default:
|
|
49
|
+
return getTypeLabel(attachment, ext, mediaType);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** A rounded spinner used while uploading. */
|
|
53
|
+
function Spinner() {
|
|
54
|
+
return (React.createElement("span", { className: "size-4.5 animate-spin rounded-full border-2 border-[var(--faint)] border-t-transparent" }));
|
|
55
|
+
}
|
|
56
|
+
/** Alert glyph for the error state (no dedicated icon in the barrel). */
|
|
57
|
+
function AlertGlyph() {
|
|
58
|
+
return (React.createElement("svg", { viewBox: "0 0 24 24", className: "size-4.5", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" },
|
|
59
|
+
React.createElement("circle", { cx: "12", cy: "12", r: "9" }),
|
|
60
|
+
React.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12.5" }),
|
|
61
|
+
React.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })));
|
|
62
|
+
}
|
|
63
|
+
const AttachmentPillContext = React.createContext(null);
|
|
64
|
+
/**
|
|
65
|
+
* Read the enclosing `AttachmentPill` state. Throws when used outside an
|
|
66
|
+
* `AttachmentPill`.
|
|
67
|
+
*/
|
|
68
|
+
export function useAttachmentPill() {
|
|
69
|
+
const ctx = React.useContext(AttachmentPillContext);
|
|
70
|
+
if (!ctx) {
|
|
71
|
+
throw COMPONENT_ERROR.create({
|
|
72
|
+
detail: "useAttachmentPill must be used within a AttachmentPill",
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return ctx;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* `AttachmentPill.Root` — context provider + the chip wrapper. No children
|
|
79
|
+
* renders the default anatomy; pass children to recompose.
|
|
80
|
+
*/
|
|
81
|
+
const AttachmentPillRoot = React.forwardRef(function AttachmentPill({ attachment, onRemove, onRetry, icons, bordered = true, className, children, ...props }, ref) {
|
|
82
|
+
const mediaType = attachment.type ?? "";
|
|
83
|
+
const ext = getExtension(attachment.name) ||
|
|
84
|
+
mediaType.split("/").pop()?.toLowerCase() || "";
|
|
85
|
+
const colorClass = FILE_TYPE_COLORS[ext] ??
|
|
86
|
+
"text-[var(--faint)] bg-[var(--tertiary)]";
|
|
87
|
+
const isImage = mediaType.startsWith("image/") ||
|
|
88
|
+
/\.(avif|gif|jpe?g|png|webp)$/i.test(attachment.name);
|
|
89
|
+
const state = attachment.state;
|
|
90
|
+
const isError = state === "error";
|
|
91
|
+
// Prefer the local object-URL `preview`; fall back to the resolved `url`
|
|
92
|
+
// (set on sent-message pills) so an uploaded image still shows a thumbnail.
|
|
93
|
+
const imageSrc = isImage ? (attachment.preview ?? attachment.url) : undefined;
|
|
94
|
+
const isBusy = state === "uploading" || state === "processing" ||
|
|
95
|
+
attachment.status === "uploading";
|
|
96
|
+
const shimmerTitle = state === "uploading" || state === "processing";
|
|
97
|
+
const label = getStateLabel(attachment, ext, mediaType);
|
|
98
|
+
// Legacy dimming only applies to the old `status` API (new states stay solid).
|
|
99
|
+
const legacyUploading = !state && attachment.status === "uploading";
|
|
100
|
+
const showRemove = Boolean(onRemove) &&
|
|
101
|
+
(Boolean(state) || attachment.status !== "uploading");
|
|
102
|
+
// The left box shows a state glyph when a lifecycle `state` is set, otherwise
|
|
103
|
+
// the file-type extension badge (default behaviour).
|
|
104
|
+
const stateGlyph = state === "selected"
|
|
105
|
+
? React.createElement(ClockIcon, { className: "size-4.5 text-[var(--faint)]" })
|
|
106
|
+
: state === "uploading"
|
|
107
|
+
? React.createElement(Spinner, null)
|
|
108
|
+
: state === "processing"
|
|
109
|
+
? React.createElement(FileTextIcon, { className: "size-4.5 text-[var(--faint)]" })
|
|
110
|
+
: state === "uploaded"
|
|
111
|
+
? React.createElement(CheckIcon, { className: "size-4.5 text-[var(--foreground)]" })
|
|
112
|
+
: isError
|
|
113
|
+
? React.createElement(AlertGlyph, null)
|
|
114
|
+
: null;
|
|
115
|
+
const boxClass = isError
|
|
116
|
+
? "bg-[color-mix(in_oklch,var(--destructive),transparent_86%)] text-[var(--destructive)]"
|
|
117
|
+
: state
|
|
118
|
+
? "bg-[var(--tertiary)] text-[var(--foreground)]"
|
|
119
|
+
: colorClass;
|
|
120
|
+
const context = {
|
|
121
|
+
attachment,
|
|
122
|
+
onRemove,
|
|
123
|
+
onRetry,
|
|
124
|
+
icons,
|
|
125
|
+
ext,
|
|
126
|
+
colorClass,
|
|
127
|
+
isImage,
|
|
128
|
+
imageSrc,
|
|
129
|
+
isError,
|
|
130
|
+
isBusy,
|
|
131
|
+
shimmerTitle,
|
|
132
|
+
label,
|
|
133
|
+
legacyUploading,
|
|
134
|
+
showRemove,
|
|
135
|
+
stateGlyph,
|
|
136
|
+
boxClass,
|
|
137
|
+
};
|
|
138
|
+
return (React.createElement(AttachmentPillContext.Provider, { value: context },
|
|
139
|
+
React.createElement("div", { ...props, ref: ref, className: cn(
|
|
140
|
+
// No width here on purpose — width is the container's decision
|
|
141
|
+
// (composer uses a fixed chip, AttachmentsPanel fills the row).
|
|
142
|
+
"group relative flex items-center gap-3 rounded-[var(--radius-md)] bg-[var(--secondary)] py-1 pl-1 pr-2 text-[var(--foreground)]", bordered && "border", bordered && (state === "selected"
|
|
143
|
+
? "border-dashed border-[var(--edge-medium)]"
|
|
144
|
+
: isError
|
|
145
|
+
? "border-[var(--destructive)] bg-[color-mix(in_oklch,var(--destructive),transparent_94%)]"
|
|
146
|
+
: "border-[var(--edge-medium)]"), legacyUploading && "opacity-70", className) }, children ?? (React.createElement(React.Fragment, null,
|
|
147
|
+
imageSrc && !isError ? React.createElement(AttachmentPillThumbnail, null) : React.createElement(AttachmentPillIcon, null),
|
|
148
|
+
React.createElement(AttachmentPillLabel, null),
|
|
149
|
+
React.createElement(AttachmentPillRetry, null),
|
|
150
|
+
React.createElement(AttachmentPillRemove, null))))));
|
|
151
|
+
});
|
|
152
|
+
AttachmentPillRoot.displayName = "AttachmentPill.Root";
|
|
153
|
+
/**
|
|
154
|
+
* `AttachmentPill.Thumbnail` — the image square (with a busy overlay). Renders
|
|
155
|
+
* only when the attachment resolves to a non-error image with a source.
|
|
156
|
+
*/
|
|
157
|
+
function AttachmentPillThumbnail({ className }) {
|
|
158
|
+
const { imageSrc, isError, isBusy } = useAttachmentPill();
|
|
159
|
+
if (!imageSrc || isError)
|
|
160
|
+
return null;
|
|
161
|
+
return (React.createElement("div", { className: cn("relative size-10 shrink-0 overflow-hidden rounded-[var(--radius-sm)] bg-[var(--tertiary)]", className) },
|
|
162
|
+
React.createElement("img", { alt: "", className: "size-full object-cover", src: imageSrc }),
|
|
163
|
+
isBusy && (React.createElement("div", { className: "absolute inset-0 flex items-center justify-center rounded-[var(--radius-sm)] bg-[var(--overlay)]" },
|
|
164
|
+
React.createElement("span", { className: "size-4 animate-spin rounded-full border-2 border-white border-t-transparent" })))));
|
|
165
|
+
}
|
|
166
|
+
AttachmentPillThumbnail.displayName = "AttachmentPill.Thumbnail";
|
|
167
|
+
/**
|
|
168
|
+
* `AttachmentPill.Icon` — the state-glyph / file-extension square shown when
|
|
169
|
+
* there is no image thumbnail.
|
|
170
|
+
*/
|
|
171
|
+
function AttachmentPillIcon({ className }) {
|
|
172
|
+
const { boxClass, stateGlyph, ext, legacyUploading } = useAttachmentPill();
|
|
173
|
+
return (React.createElement("div", { className: cn("relative flex size-10 shrink-0 items-center justify-center rounded-[var(--radius-sm)] text-[10px] font-medium uppercase leading-none", boxClass, className) },
|
|
174
|
+
stateGlyph ?? ext ?? "file",
|
|
175
|
+
legacyUploading && (React.createElement("div", { className: "absolute inset-0 flex items-center justify-center rounded-[var(--radius-sm)] bg-[var(--overlay)]" },
|
|
176
|
+
React.createElement("span", { className: "size-4 animate-spin rounded-full border-2 border-white border-t-transparent" })))));
|
|
177
|
+
}
|
|
178
|
+
AttachmentPillIcon.displayName = "AttachmentPill.Icon";
|
|
179
|
+
/** `AttachmentPill.Label` — the name + secondary state-line column. */
|
|
180
|
+
function AttachmentPillLabel({ className }) {
|
|
181
|
+
const { attachment, shimmerTitle, isError, label } = useAttachmentPill();
|
|
182
|
+
return (React.createElement("div", { className: cn("flex min-w-0 flex-1 flex-col gap-0.5", className) },
|
|
183
|
+
React.createElement("p", { className: "truncate text-sm font-medium leading-tight" }, shimmerTitle
|
|
184
|
+
? React.createElement(Shimmer, null, attachment.name || "Attachment")
|
|
185
|
+
: (attachment.name || "Attachment")),
|
|
186
|
+
React.createElement("p", { className: cn("truncate text-xs leading-tight", isError ? "text-[var(--destructive)]" : "text-[var(--faint)]") }, label)));
|
|
187
|
+
}
|
|
188
|
+
AttachmentPillLabel.displayName = "AttachmentPill.Label";
|
|
189
|
+
/**
|
|
190
|
+
* `AttachmentPill.Retry` — the retry control. Renders only in the `error` state
|
|
191
|
+
* when an `onRetry` handler is provided.
|
|
192
|
+
*/
|
|
193
|
+
function AttachmentPillRetry({ className }) {
|
|
194
|
+
const { attachment, isError, onRetry, icons } = useAttachmentPill();
|
|
195
|
+
if (!isError || !onRetry)
|
|
196
|
+
return null;
|
|
197
|
+
return (React.createElement(Button, { type: "button", variant: "icon-ghost", size: "icon-xs", on: "card", onClick: () => onRetry(attachment.id), "aria-label": `Retry ${attachment.name}`, className: cn("shrink-0", className) }, icons?.retry ?? React.createElement(RefreshCwIcon, null)));
|
|
198
|
+
}
|
|
199
|
+
AttachmentPillRetry.displayName = "AttachmentPill.Retry";
|
|
200
|
+
/**
|
|
201
|
+
* `AttachmentPill.Remove` — the remove (✕) control. Renders only when an
|
|
202
|
+
* `onRemove` handler is provided and the pill isn't a legacy uploading pill.
|
|
203
|
+
*/
|
|
204
|
+
function AttachmentPillRemove({ className }) {
|
|
205
|
+
const { attachment, showRemove, onRemove, icons } = useAttachmentPill();
|
|
206
|
+
if (!showRemove)
|
|
207
|
+
return null;
|
|
208
|
+
return (React.createElement(Button, { type: "button", variant: "icon-ghost", size: "icon-xs", on: "card", onClick: () => onRemove?.(attachment.id), "aria-label": `Remove ${attachment.name}`, className: cn("shrink-0 opacity-100 md:opacity-0 md:group-hover:opacity-100", className) }, icons?.remove ?? (React.createElement("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" },
|
|
209
|
+
React.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
210
|
+
React.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })))));
|
|
211
|
+
}
|
|
212
|
+
AttachmentPillRemove.displayName = "AttachmentPill.Remove";
|
|
213
|
+
/**
|
|
214
|
+
* AttachmentPill — render `<AttachmentPill attachment={…} />` for the default
|
|
215
|
+
* chip, or compose `AttachmentPill.Root` + `.Thumbnail` / `.Icon` / `.Label` /
|
|
216
|
+
* `.Retry` / `.Remove` for a custom layout. Publicly aliased as `Attachment`.
|
|
217
|
+
*/
|
|
218
|
+
export const AttachmentPill = Object.assign(AttachmentPillRoot, {
|
|
219
|
+
Root: AttachmentPillRoot,
|
|
220
|
+
Thumbnail: AttachmentPillThumbnail,
|
|
221
|
+
Icon: AttachmentPillIcon,
|
|
222
|
+
Label: AttachmentPillLabel,
|
|
223
|
+
Retry: AttachmentPillRetry,
|
|
224
|
+
Remove: AttachmentPillRemove,
|
|
225
|
+
});
|