@agentuity/workbench 0.0.64 → 0.0.65
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/dist/components/App.d.ts +6 -0
- package/dist/components/App.d.ts.map +1 -0
- package/dist/components/App.js +13 -0
- package/dist/components/App.js.map +1 -0
- package/dist/components/ConnectionStatus.d.ts +7 -0
- package/dist/components/ConnectionStatus.d.ts.map +1 -0
- package/dist/components/ConnectionStatus.js +52 -0
- package/dist/components/ConnectionStatus.js.map +1 -0
- package/dist/components/Inline.d.ts +10 -0
- package/dist/components/Inline.d.ts.map +1 -0
- package/dist/components/Inline.js +11 -0
- package/dist/components/Inline.js.map +1 -0
- package/dist/components/ai-elements/actions.d.ts +10 -0
- package/dist/components/ai-elements/actions.d.ts.map +1 -0
- package/dist/components/ai-elements/actions.js +14 -0
- package/dist/components/ai-elements/actions.js.map +1 -0
- package/dist/components/ai-elements/artifact.d.ts +24 -0
- package/dist/components/ai-elements/artifact.d.ts.map +1 -0
- package/dist/components/ai-elements/artifact.js +21 -0
- package/dist/components/ai-elements/artifact.js.map +1 -0
- package/dist/components/ai-elements/branch.d.ts +21 -0
- package/dist/components/ai-elements/branch.d.ts.map +1 -0
- package/dist/components/ai-elements/branch.js +71 -0
- package/dist/components/ai-elements/branch.js.map +1 -0
- package/dist/components/ai-elements/canvas.d.ts +9 -0
- package/dist/components/ai-elements/canvas.d.ts.map +1 -0
- package/dist/components/ai-elements/canvas.js +6 -0
- package/dist/components/ai-elements/canvas.js.map +1 -0
- package/dist/components/ai-elements/chain-of-thought.d.ts +30 -0
- package/dist/components/ai-elements/chain-of-thought.d.ts.map +1 -0
- package/dist/components/ai-elements/chain-of-thought.js +52 -0
- package/dist/components/ai-elements/chain-of-thought.js.map +1 -0
- package/dist/components/ai-elements/code-block.d.ts +18 -0
- package/dist/components/ai-elements/code-block.d.ts.map +1 -0
- package/dist/components/ai-elements/code-block.js +89 -0
- package/dist/components/ai-elements/code-block.js.map +1 -0
- package/dist/components/ai-elements/confirmation.d.ts +27 -0
- package/dist/components/ai-elements/confirmation.d.ts.map +1 -0
- package/dist/components/ai-elements/confirmation.js +57 -0
- package/dist/components/ai-elements/confirmation.js.map +1 -0
- package/dist/components/ai-elements/connection.d.ts +3 -0
- package/dist/components/ai-elements/connection.d.ts.map +1 -0
- package/dist/components/ai-elements/connection.js +4 -0
- package/dist/components/ai-elements/connection.js.map +1 -0
- package/dist/components/ai-elements/context.d.ts +33 -0
- package/dist/components/ai-elements/context.d.ts.map +1 -0
- package/dist/components/ai-elements/context.js +167 -0
- package/dist/components/ai-elements/context.js.map +1 -0
- package/dist/components/ai-elements/controls.d.ts +5 -0
- package/dist/components/ai-elements/controls.d.ts.map +1 -0
- package/dist/components/ai-elements/controls.js +6 -0
- package/dist/components/ai-elements/controls.js.map +1 -0
- package/dist/components/ai-elements/conversation.d.ts +16 -0
- package/dist/components/ai-elements/conversation.d.ts.map +1 -0
- package/dist/components/ai-elements/conversation.js +18 -0
- package/dist/components/ai-elements/conversation.js.map +1 -0
- package/dist/components/ai-elements/edge.d.ts +6 -0
- package/dist/components/ai-elements/edge.d.ts.map +1 -0
- package/dist/components/ai-elements/edge.js +83 -0
- package/dist/components/ai-elements/edge.js.map +1 -0
- package/dist/components/ai-elements/image.d.ts +7 -0
- package/dist/components/ai-elements/image.d.ts.map +1 -0
- package/dist/components/ai-elements/image.js +4 -0
- package/dist/components/ai-elements/image.js.map +1 -0
- package/dist/components/ai-elements/inline-citation.d.ts +39 -0
- package/dist/components/ai-elements/inline-citation.d.ts.map +1 -0
- package/dist/components/ai-elements/inline-citation.js +62 -0
- package/dist/components/ai-elements/inline-citation.js.map +1 -0
- package/dist/components/ai-elements/loader.d.ts +6 -0
- package/dist/components/ai-elements/loader.d.ts.map +1 -0
- package/dist/components/ai-elements/loader.js +5 -0
- package/dist/components/ai-elements/loader.js.map +1 -0
- package/dist/components/ai-elements/message.d.ts +20 -0
- package/dist/components/ai-elements/message.d.ts.map +1 -0
- package/dist/components/ai-elements/message.js +26 -0
- package/dist/components/ai-elements/message.js.map +1 -0
- package/dist/components/ai-elements/node.d.ts +22 -0
- package/dist/components/ai-elements/node.d.ts.map +1 -0
- package/dist/components/ai-elements/node.js +12 -0
- package/dist/components/ai-elements/node.js.map +1 -0
- package/dist/components/ai-elements/open-in-chat.d.ts +29 -0
- package/dist/components/ai-elements/open-in-chat.d.ts.map +1 -0
- package/dist/components/ai-elements/open-in-chat.js +97 -0
- package/dist/components/ai-elements/open-in-chat.js.map +1 -0
- package/dist/components/ai-elements/panel.d.ts +6 -0
- package/dist/components/ai-elements/panel.d.ts.map +1 -0
- package/dist/components/ai-elements/panel.js +5 -0
- package/dist/components/ai-elements/panel.js.map +1 -0
- package/dist/components/ai-elements/plan.d.ts +26 -0
- package/dist/components/ai-elements/plan.d.ts.map +1 -0
- package/dist/components/ai-elements/plan.js +32 -0
- package/dist/components/ai-elements/plan.js.map +1 -0
- package/dist/components/ai-elements/prompt-input.d.ts +187 -0
- package/dist/components/ai-elements/prompt-input.d.ts.map +1 -0
- package/dist/components/ai-elements/prompt-input.js +544 -0
- package/dist/components/ai-elements/prompt-input.js.map +1 -0
- package/dist/components/ai-elements/queue.d.ts +62 -0
- package/dist/components/ai-elements/queue.d.ts.map +1 -0
- package/dist/components/ai-elements/queue.js +25 -0
- package/dist/components/ai-elements/queue.js.map +1 -0
- package/dist/components/ai-elements/reasoning.d.ts +17 -0
- package/dist/components/ai-elements/reasoning.d.ts.map +1 -0
- package/dist/components/ai-elements/reasoning.js +77 -0
- package/dist/components/ai-elements/reasoning.js.map +1 -0
- package/dist/components/ai-elements/response.d.ts +6 -0
- package/dist/components/ai-elements/response.d.ts.map +1 -0
- package/dist/components/ai-elements/response.js +8 -0
- package/dist/components/ai-elements/response.js.map +1 -0
- package/dist/components/ai-elements/shimmer.d.ts +10 -0
- package/dist/components/ai-elements/shimmer.d.ts.map +1 -0
- package/dist/components/ai-elements/shimmer.js +19 -0
- package/dist/components/ai-elements/shimmer.js.map +1 -0
- package/dist/components/ai-elements/sources.d.ts +13 -0
- package/dist/components/ai-elements/sources.d.ts.map +1 -0
- package/dist/components/ai-elements/sources.js +10 -0
- package/dist/components/ai-elements/sources.js.map +1 -0
- package/dist/components/ai-elements/suggestion.d.ts +11 -0
- package/dist/components/ai-elements/suggestion.d.ts.map +1 -0
- package/dist/components/ai-elements/suggestion.js +13 -0
- package/dist/components/ai-elements/suggestion.js.map +1 -0
- package/dist/components/ai-elements/task.d.ts +15 -0
- package/dist/components/ai-elements/task.d.ts.map +1 -0
- package/dist/components/ai-elements/task.js +11 -0
- package/dist/components/ai-elements/task.js.map +1 -0
- package/dist/components/ai-elements/tool.d.ts +24 -0
- package/dist/components/ai-elements/tool.d.ts.map +1 -0
- package/dist/components/ai-elements/tool.js +47 -0
- package/dist/components/ai-elements/tool.js.map +1 -0
- package/dist/components/ai-elements/toolbar.d.ts +6 -0
- package/dist/components/ai-elements/toolbar.d.ts.map +1 -0
- package/dist/components/ai-elements/toolbar.js +5 -0
- package/dist/components/ai-elements/toolbar.js.map +1 -0
- package/dist/components/ai-elements/web-preview.d.ts +35 -0
- package/dist/components/ai-elements/web-preview.d.ts.map +1 -0
- package/dist/components/ai-elements/web-preview.js +63 -0
- package/dist/components/ai-elements/web-preview.js.map +1 -0
- package/dist/components/internal/Chat.d.ts +11 -0
- package/dist/components/internal/Chat.d.ts.map +1 -0
- package/dist/components/internal/Chat.js +52 -0
- package/dist/components/internal/Chat.js.map +1 -0
- package/dist/components/internal/Header.d.ts +10 -0
- package/dist/components/internal/Header.d.ts.map +1 -0
- package/dist/components/internal/Header.js +31 -0
- package/dist/components/internal/Header.js.map +1 -0
- package/dist/components/internal/InputSection.d.ts +14 -0
- package/dist/components/internal/InputSection.d.ts.map +1 -0
- package/dist/components/internal/InputSection.js +212 -0
- package/dist/components/internal/InputSection.js.map +1 -0
- package/dist/components/internal/Schema.d.ts +7 -0
- package/dist/components/internal/Schema.d.ts.map +1 -0
- package/dist/components/internal/Schema.js +14 -0
- package/dist/components/internal/Schema.js.map +1 -0
- package/dist/components/internal/WorkbenchProvider.d.ts +11 -0
- package/dist/components/internal/WorkbenchProvider.d.ts.map +1 -0
- package/dist/components/internal/WorkbenchProvider.js +224 -0
- package/dist/components/internal/WorkbenchProvider.js.map +1 -0
- package/dist/components/internal/logo.d.ts +2 -0
- package/dist/components/internal/logo.d.ts.map +1 -0
- package/dist/components/internal/logo.js +5 -0
- package/dist/components/internal/logo.js.map +1 -0
- package/dist/components/ui/alert.d.ts +10 -0
- package/dist/components/ui/alert.d.ts.map +1 -0
- package/dist/components/ui/alert.js +25 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +7 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/avatar.js +14 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +10 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +23 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/button.d.ts +3 -4
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/card.d.ts +2 -1
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/card.js +4 -1
- package/dist/components/ui/card.js.map +1 -1
- package/dist/components/ui/carousel.d.ts +20 -0
- package/dist/components/ui/carousel.d.ts.map +1 -0
- package/dist/components/ui/carousel.js +92 -0
- package/dist/components/ui/carousel.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +5 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/checkbox.js +9 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +6 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +14 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/command.d.ts +19 -0
- package/dist/components/ui/command.d.ts.map +1 -0
- package/dist/components/ui/command.js +34 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +16 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +36 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +26 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +52 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/field.d.ts +25 -0
- package/dist/components/ui/field.d.ts.map +1 -0
- package/dist/components/ui/field.js +74 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/form.d.ts +25 -0
- package/dist/components/ui/form.d.ts.map +1 -0
- package/dist/components/ui/form.js +58 -0
- package/dist/components/ui/form.js.map +1 -0
- package/dist/components/ui/hover-card.d.ts +7 -0
- package/dist/components/ui/hover-card.d.ts.map +1 -0
- package/dist/components/ui/hover-card.js +14 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +17 -0
- package/dist/components/ui/input-group.d.ts.map +1 -0
- package/dist/components/ui/input-group.js +64 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input.d.ts +1 -2
- package/dist/components/ui/input.d.ts.map +1 -1
- package/dist/components/ui/input.js +3 -5
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/label.d.ts +5 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +9 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/popover.d.ts +8 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/popover.js +18 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/progress.d.ts +5 -0
- package/dist/components/ui/progress.d.ts.map +1 -0
- package/dist/components/ui/progress.js +9 -0
- package/dist/components/ui/progress.js.map +1 -0
- package/dist/components/ui/resizable-provider.d.ts +15 -0
- package/dist/components/ui/resizable-provider.d.ts.map +1 -0
- package/dist/components/ui/resizable-provider.js +54 -0
- package/dist/components/ui/resizable-provider.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +9 -0
- package/dist/components/ui/resizable.d.ts.map +1 -0
- package/dist/components/ui/resizable.js +16 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +6 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +11 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +16 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.js +39 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.d.ts +5 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +9 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/switch.d.ts +5 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +8 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +8 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +17 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +4 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/textarea.js +7 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/theme-provider.d.ts +14 -0
- package/dist/components/ui/theme-provider.d.ts.map +1 -0
- package/dist/components/ui/theme-provider.js +37 -0
- package/dist/components/ui/theme-provider.js.map +1 -0
- package/dist/components/ui/theme-toggle.d.ts +2 -0
- package/dist/components/ui/theme-toggle.d.ts.map +1 -0
- package/dist/components/ui/theme-toggle.js +10 -0
- package/dist/components/ui/theme-toggle.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +10 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/toggle.js +26 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +8 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +17 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/components.d.ts +10 -6
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +11 -36
- package/dist/components.js.map +1 -1
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useAgentSchemas.d.ts +70 -0
- package/dist/hooks/useAgentSchemas.d.ts.map +1 -0
- package/dist/hooks/useAgentSchemas.js +90 -0
- package/dist/hooks/useAgentSchemas.js.map +1 -0
- package/dist/hooks/useWorkbenchSchemas.d.ts +56 -0
- package/dist/hooks/useWorkbenchSchemas.d.ts.map +1 -0
- package/dist/hooks/useWorkbenchSchemas.js +63 -0
- package/dist/hooks/useWorkbenchSchemas.js.map +1 -0
- package/dist/hooks/useWorkbenchWebsocket.d.ts +14 -0
- package/dist/hooks/useWorkbenchWebsocket.d.ts.map +1 -0
- package/dist/hooks/useWorkbenchWebsocket.js +163 -0
- package/dist/hooks/useWorkbenchWebsocket.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -5
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +5 -0
- package/dist/server.js.map +1 -0
- package/dist/styles.css +3423 -196
- package/dist/types/config.d.ts +29 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/workbench.d.ts +1 -2
- package/dist/workbench.d.ts.map +1 -1
- package/dist/workbench.js +0 -2
- package/dist/workbench.js.map +1 -1
- package/package.json +50 -7
- package/src/components/App.tsx +29 -0
- package/src/components/ConnectionStatus.tsx +67 -0
- package/src/components/Inline.tsx +16 -0
- package/src/components/ai-elements/actions.tsx +60 -0
- package/src/components/ai-elements/artifact.tsx +118 -0
- package/src/components/ai-elements/branch.tsx +187 -0
- package/src/components/ai-elements/canvas.tsx +24 -0
- package/src/components/ai-elements/chain-of-thought.tsx +198 -0
- package/src/components/ai-elements/code-block.tsx +175 -0
- package/src/components/ai-elements/confirmation.tsx +119 -0
- package/src/components/ai-elements/connection.tsx +16 -0
- package/src/components/ai-elements/context.tsx +357 -0
- package/src/components/ai-elements/controls.tsx +18 -0
- package/src/components/ai-elements/conversation.tsx +90 -0
- package/src/components/ai-elements/edge.tsx +131 -0
- package/src/components/ai-elements/image.tsx +16 -0
- package/src/components/ai-elements/inline-citation.tsx +246 -0
- package/src/components/ai-elements/loader.tsx +88 -0
- package/src/components/ai-elements/message.tsx +63 -0
- package/src/components/ai-elements/node.tsx +66 -0
- package/src/components/ai-elements/open-in-chat.tsx +333 -0
- package/src/components/ai-elements/panel.tsx +12 -0
- package/src/components/ai-elements/plan.tsx +123 -0
- package/src/components/ai-elements/prompt-input.tsx +1203 -0
- package/src/components/ai-elements/queue.tsx +231 -0
- package/src/components/ai-elements/reasoning.tsx +163 -0
- package/src/components/ai-elements/response.tsx +19 -0
- package/src/components/ai-elements/shimmer.tsx +53 -0
- package/src/components/ai-elements/sources.tsx +53 -0
- package/src/components/ai-elements/suggestion.tsx +47 -0
- package/src/components/ai-elements/task.tsx +64 -0
- package/src/components/ai-elements/tool.tsx +136 -0
- package/src/components/ai-elements/toolbar.tsx +13 -0
- package/src/components/ai-elements/web-preview.tsx +238 -0
- package/src/components/internal/Chat.tsx +183 -0
- package/src/components/internal/Header.tsx +77 -0
- package/src/components/internal/InputSection.tsx +427 -0
- package/src/components/internal/Schema.tsx +111 -0
- package/src/components/internal/WorkbenchProvider.tsx +265 -0
- package/src/components/internal/logo.tsx +11 -0
- package/src/components/ui/alert.tsx +60 -0
- package/src/components/ui/avatar.tsx +42 -0
- package/src/components/ui/badge.tsx +40 -0
- package/src/components/ui/button.tsx +10 -5
- package/src/components/ui/card.tsx +4 -1
- package/src/components/ui/carousel.tsx +234 -0
- package/src/components/ui/checkbox.tsx +27 -0
- package/src/components/ui/collapsible.tsx +21 -0
- package/src/components/ui/command.tsx +153 -0
- package/src/components/ui/dialog.tsx +127 -0
- package/src/components/ui/dropdown-menu.tsx +228 -0
- package/src/components/ui/field.tsx +234 -0
- package/src/components/ui/form.tsx +154 -0
- package/src/components/ui/hover-card.tsx +36 -0
- package/src/components/ui/input-group.tsx +158 -0
- package/src/components/ui/input.tsx +16 -18
- package/src/components/ui/label.tsx +21 -0
- package/src/components/ui/popover.tsx +42 -0
- package/src/components/ui/progress.tsx +28 -0
- package/src/components/ui/resizable-provider.tsx +83 -0
- package/src/components/ui/resizable.tsx +54 -0
- package/src/components/ui/scroll-area.tsx +54 -0
- package/src/components/ui/select.tsx +172 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/switch.tsx +26 -0
- package/src/components/ui/tabs.tsx +52 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/theme-provider.tsx +71 -0
- package/src/components/ui/theme-toggle.tsx +30 -0
- package/src/components/ui/toggle.tsx +44 -0
- package/src/components/ui/tooltip.tsx +55 -0
- package/src/components.tsx +28 -74
- package/src/hooks/index.ts +19 -0
- package/src/hooks/useAgentSchemas.ts +144 -0
- package/src/hooks/useWorkbenchSchemas.ts +69 -0
- package/src/hooks/useWorkbenchWebsocket.ts +220 -0
- package/src/index.ts +5 -11
- package/src/server.ts +6 -0
- package/src/styles.css +214 -59
- package/src/types/config.ts +34 -0
- package/src/types.ts +1 -1
- package/src/workbench.ts +1 -4
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import React, { createContext, useContext, useEffect, useState } from 'react';
|
|
2
|
+
import type { UIMessage } from 'ai';
|
|
3
|
+
import type { WorkbenchConfig } from '@agentuity/core/workbench';
|
|
4
|
+
import type { WorkbenchContextType, ConnectionStatus } from '../../types/config';
|
|
5
|
+
import { useAgentSchemas } from '../../hooks/useAgentSchemas';
|
|
6
|
+
import { useWorkbenchWebsocket } from '../../hooks/useWorkbenchWebsocket';
|
|
7
|
+
|
|
8
|
+
const WorkbenchContext = createContext<WorkbenchContextType | null>(null);
|
|
9
|
+
|
|
10
|
+
export function useWorkbench() {
|
|
11
|
+
const context = useContext(WorkbenchContext);
|
|
12
|
+
if (!context) {
|
|
13
|
+
throw new Error('useWorkbench must be used within a WorkbenchProvider');
|
|
14
|
+
}
|
|
15
|
+
return context;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface WorkbenchProviderProps {
|
|
19
|
+
config: WorkbenchConfig;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function WorkbenchProvider({ config, children }: WorkbenchProviderProps) {
|
|
24
|
+
const [messages, setMessages] = useState<UIMessage[]>([]);
|
|
25
|
+
const [selectedAgent, setSelectedAgent] = useState<string>('');
|
|
26
|
+
const [inputMode, setInputMode] = useState<'text' | 'form'>('text');
|
|
27
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
28
|
+
const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>('disconnected');
|
|
29
|
+
|
|
30
|
+
// Config values
|
|
31
|
+
const baseUrl = config.port ? `http://localhost:${config.port}` : undefined;
|
|
32
|
+
const apiKey = config.apiKey;
|
|
33
|
+
const shouldUseSchemas = true;
|
|
34
|
+
|
|
35
|
+
// Debug logging
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (process.env.NODE_ENV === 'development') {
|
|
38
|
+
console.log('WorkbenchProvider Debug:', {
|
|
39
|
+
baseUrl,
|
|
40
|
+
shouldUseSchemas,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}, [baseUrl, shouldUseSchemas]);
|
|
44
|
+
|
|
45
|
+
const {
|
|
46
|
+
data: schemaData,
|
|
47
|
+
isLoading: schemasLoading,
|
|
48
|
+
error: schemasError,
|
|
49
|
+
refetch: refetchSchemas,
|
|
50
|
+
} = useAgentSchemas({
|
|
51
|
+
baseUrl,
|
|
52
|
+
apiKey,
|
|
53
|
+
enabled: shouldUseSchemas,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// WebSocket connection for dev server restart detection
|
|
57
|
+
const { connected } = useWorkbenchWebsocket({
|
|
58
|
+
baseUrl,
|
|
59
|
+
apiKey,
|
|
60
|
+
onConnect: () => {
|
|
61
|
+
setConnectionStatus('connected');
|
|
62
|
+
refetchSchemas();
|
|
63
|
+
},
|
|
64
|
+
onReconnect: () => {
|
|
65
|
+
setConnectionStatus('connected');
|
|
66
|
+
refetchSchemas();
|
|
67
|
+
},
|
|
68
|
+
onAlive: () => {
|
|
69
|
+
setConnectionStatus('connected');
|
|
70
|
+
refetchSchemas();
|
|
71
|
+
},
|
|
72
|
+
onRestarting: () => {
|
|
73
|
+
setConnectionStatus('restarting');
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Update connection status based on WebSocket connection state
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!connected && connectionStatus !== 'restarting') {
|
|
80
|
+
setConnectionStatus('disconnected');
|
|
81
|
+
}
|
|
82
|
+
}, [connected, connectionStatus]);
|
|
83
|
+
|
|
84
|
+
// Convert schema data to Agent format, no fallback
|
|
85
|
+
const agents = schemaData?.agents;
|
|
86
|
+
// Log schema fetch errors for debugging
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (schemasError) {
|
|
89
|
+
console.warn(
|
|
90
|
+
'Failed to fetch agent schemas from API, using static configuration:',
|
|
91
|
+
schemasError.message
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}, [schemasError]);
|
|
95
|
+
|
|
96
|
+
const [suggestions, _setSuggestions] = useState<string[]>([]);
|
|
97
|
+
|
|
98
|
+
// Set initial agent selection
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (agents && Object.keys(agents).length > 0 && !selectedAgent) {
|
|
101
|
+
setSelectedAgent(Object.keys(agents)[0]);
|
|
102
|
+
}
|
|
103
|
+
}, [agents, selectedAgent]);
|
|
104
|
+
|
|
105
|
+
// Fetch suggestions from API if endpoint is provided
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
// No API endpoints hardcoded for now
|
|
108
|
+
}, []);
|
|
109
|
+
|
|
110
|
+
const _fetchSuggestions = async () => {
|
|
111
|
+
// No API endpoints for now
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const submitMessage = async (value: string, _mode: 'text' | 'form' = 'text') => {
|
|
115
|
+
if (!selectedAgent) return;
|
|
116
|
+
|
|
117
|
+
const selectedAgentData = agents?.[selectedAgent];
|
|
118
|
+
const hasInputSchema = selectedAgentData?.schema?.input?.json;
|
|
119
|
+
|
|
120
|
+
// Only require value for agents with input schemas
|
|
121
|
+
if (hasInputSchema && !value.trim()) return;
|
|
122
|
+
|
|
123
|
+
// Add user message
|
|
124
|
+
const displayText = hasInputSchema
|
|
125
|
+
? value
|
|
126
|
+
: `Running ${selectedAgentData?.metadata.name || 'agent'}...`;
|
|
127
|
+
const userMessage: UIMessage = {
|
|
128
|
+
id: Date.now().toString(),
|
|
129
|
+
role: 'user',
|
|
130
|
+
parts: [{ type: 'text', text: displayText }],
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
134
|
+
setIsLoading(true);
|
|
135
|
+
|
|
136
|
+
if (!baseUrl) {
|
|
137
|
+
const errorMessage: UIMessage = {
|
|
138
|
+
id: (Date.now() + 1).toString(),
|
|
139
|
+
role: 'assistant',
|
|
140
|
+
parts: [
|
|
141
|
+
{
|
|
142
|
+
type: 'text',
|
|
143
|
+
text: 'Error: No base URL configured. Please configure a port in the workbench config.',
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
setMessages((prev) => [...prev, errorMessage]);
|
|
148
|
+
setIsLoading(false);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
// Parse input - if it's JSON, parse it, otherwise use as string
|
|
154
|
+
// For agents without input schema, send undefined
|
|
155
|
+
let parsedInput: unknown;
|
|
156
|
+
if (!hasInputSchema) {
|
|
157
|
+
parsedInput = undefined;
|
|
158
|
+
} else {
|
|
159
|
+
try {
|
|
160
|
+
parsedInput = JSON.parse(value);
|
|
161
|
+
} catch {
|
|
162
|
+
parsedInput = value;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Call execution endpoint with timeout
|
|
167
|
+
const headers: Record<string, string> = {
|
|
168
|
+
'Content-Type': 'application/json',
|
|
169
|
+
};
|
|
170
|
+
if (apiKey) {
|
|
171
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const controller = new AbortController();
|
|
175
|
+
const timeoutId = setTimeout(() => controller.abort(), 30000); // 30s timeout
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
const response = await fetch(`${baseUrl}/_agentuity/workbench/execute`, {
|
|
179
|
+
method: 'POST',
|
|
180
|
+
headers,
|
|
181
|
+
body: JSON.stringify({
|
|
182
|
+
agentId: selectedAgent,
|
|
183
|
+
input: parsedInput,
|
|
184
|
+
}),
|
|
185
|
+
signal: controller.signal,
|
|
186
|
+
});
|
|
187
|
+
clearTimeout(timeoutId);
|
|
188
|
+
|
|
189
|
+
if (!response.ok) {
|
|
190
|
+
const errorData = await response
|
|
191
|
+
.json()
|
|
192
|
+
.catch(() => ({ error: response.statusText }));
|
|
193
|
+
throw new Error(errorData.error || `Request failed with status ${response.status}`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const result = await response.json();
|
|
197
|
+
|
|
198
|
+
// Format result as JSON string for display
|
|
199
|
+
const resultText =
|
|
200
|
+
typeof result === 'object' ? JSON.stringify(result, null, 2) : String(result);
|
|
201
|
+
|
|
202
|
+
const assistantMessage: UIMessage = {
|
|
203
|
+
id: (Date.now() + 1).toString(),
|
|
204
|
+
role: 'assistant',
|
|
205
|
+
parts: [{ type: 'text', text: resultText }],
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
setMessages((prev) => [...prev, assistantMessage]);
|
|
209
|
+
} catch (fetchError) {
|
|
210
|
+
clearTimeout(timeoutId);
|
|
211
|
+
throw fetchError;
|
|
212
|
+
}
|
|
213
|
+
} catch (error) {
|
|
214
|
+
console.error('Failed to submit message:', error);
|
|
215
|
+
const errorText =
|
|
216
|
+
error instanceof Error
|
|
217
|
+
? error.name === 'AbortError'
|
|
218
|
+
? 'Request timed out. Please try again.'
|
|
219
|
+
: error.message
|
|
220
|
+
: 'Sorry, I encountered an error processing your message.';
|
|
221
|
+
|
|
222
|
+
const errorMessage: UIMessage = {
|
|
223
|
+
id: (Date.now() + 1).toString(),
|
|
224
|
+
role: 'assistant',
|
|
225
|
+
parts: [
|
|
226
|
+
{
|
|
227
|
+
type: 'text',
|
|
228
|
+
text: errorText,
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
};
|
|
232
|
+
setMessages((prev) => [...prev, errorMessage]);
|
|
233
|
+
} finally {
|
|
234
|
+
setIsLoading(false);
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const handleAgentSelect = async (agentId: string) => {
|
|
239
|
+
setSelectedAgent(agentId);
|
|
240
|
+
// No handlers configured for now
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const contextValue: WorkbenchContextType = {
|
|
244
|
+
config,
|
|
245
|
+
agents: agents || {},
|
|
246
|
+
suggestions,
|
|
247
|
+
messages,
|
|
248
|
+
setMessages,
|
|
249
|
+
selectedAgent,
|
|
250
|
+
setSelectedAgent: handleAgentSelect,
|
|
251
|
+
inputMode,
|
|
252
|
+
setInputMode,
|
|
253
|
+
isLoading: isLoading || (shouldUseSchemas && !!schemasLoading),
|
|
254
|
+
submitMessage,
|
|
255
|
+
// Schema data from API
|
|
256
|
+
schemas: schemaData,
|
|
257
|
+
schemasLoading: !!schemasLoading,
|
|
258
|
+
schemasError,
|
|
259
|
+
refetchSchemas,
|
|
260
|
+
// Connection status
|
|
261
|
+
connectionStatus,
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
return <WorkbenchContext.Provider value={contextValue}>{children}</WorkbenchContext.Provider>;
|
|
265
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export default function Logo() {
|
|
3
|
+
return (
|
|
4
|
+
<div className="flex items-center space-x-2">
|
|
5
|
+
<div className="w-8 h-8 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center">
|
|
6
|
+
<span className="text-white font-bold text-sm">A</span>
|
|
7
|
+
</div>
|
|
8
|
+
<span className="font-semibold text-lg">Agentuity</span>
|
|
9
|
+
</div>
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
|
|
6
|
+
const alertVariants = cva(
|
|
7
|
+
'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default: 'bg-card text-card-foreground',
|
|
12
|
+
destructive:
|
|
13
|
+
'text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
defaultVariants: {
|
|
17
|
+
variant: 'default',
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
function Alert({
|
|
23
|
+
className,
|
|
24
|
+
variant,
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
data-slot="alert"
|
|
30
|
+
role="alert"
|
|
31
|
+
className={cn(alertVariants({ variant }), className)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {
|
|
38
|
+
return (
|
|
39
|
+
<div
|
|
40
|
+
data-slot="alert-title"
|
|
41
|
+
className={cn('col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight', className)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function AlertDescription({ className, ...props }: React.ComponentProps<'div'>) {
|
|
48
|
+
return (
|
|
49
|
+
<div
|
|
50
|
+
data-slot="alert-description"
|
|
51
|
+
className={cn(
|
|
52
|
+
'text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed',
|
|
53
|
+
className
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { Alert, AlertTitle, AlertDescription };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
3
|
+
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
|
|
6
|
+
function Avatar({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
|
|
7
|
+
return (
|
|
8
|
+
<AvatarPrimitive.Root
|
|
9
|
+
data-slot="avatar"
|
|
10
|
+
className={cn('relative flex size-8 shrink-0 overflow-hidden rounded-full', className)}
|
|
11
|
+
{...props}
|
|
12
|
+
/>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
|
|
17
|
+
return (
|
|
18
|
+
<AvatarPrimitive.Image
|
|
19
|
+
data-slot="avatar-image"
|
|
20
|
+
className={cn('aspect-square size-full', className)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function AvatarFallback({
|
|
27
|
+
className,
|
|
28
|
+
...props
|
|
29
|
+
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
|
|
30
|
+
return (
|
|
31
|
+
<AvatarPrimitive.Fallback
|
|
32
|
+
data-slot="avatar-fallback"
|
|
33
|
+
className={cn(
|
|
34
|
+
'bg-muted flex size-full items-center justify-center rounded-full',
|
|
35
|
+
className
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { Avatar, AvatarImage, AvatarFallback };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
4
|
+
|
|
5
|
+
import { cn } from '../../lib/utils';
|
|
6
|
+
|
|
7
|
+
const badgeVariants = cva(
|
|
8
|
+
'inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default:
|
|
13
|
+
'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
|
|
14
|
+
secondary:
|
|
15
|
+
'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
|
|
16
|
+
destructive:
|
|
17
|
+
'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
|
|
18
|
+
outline: 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: {
|
|
22
|
+
variant: 'default',
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
function Badge({
|
|
28
|
+
className,
|
|
29
|
+
variant,
|
|
30
|
+
asChild = false,
|
|
31
|
+
...props
|
|
32
|
+
}: React.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
|
|
33
|
+
const Comp = asChild ? Slot : 'span';
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Comp data-slot="badge" className={cn(badgeVariants({ variant }), className)} {...props} />
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { Badge, badgeVariants };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Slot } from '@radix-ui/react-slot';
|
|
2
2
|
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
-
import * as React from 'react';
|
|
3
|
+
import type * as React from 'react';
|
|
4
|
+
|
|
4
5
|
import { cn } from '../../lib/utils';
|
|
5
6
|
|
|
6
7
|
const buttonVariants = cva(
|
|
@@ -33,12 +34,16 @@ const buttonVariants = cva(
|
|
|
33
34
|
}
|
|
34
35
|
);
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
function Button({
|
|
38
|
+
className,
|
|
39
|
+
variant,
|
|
40
|
+
size,
|
|
41
|
+
asChild = false,
|
|
42
|
+
...props
|
|
43
|
+
}: React.ComponentProps<'button'> &
|
|
37
44
|
VariantProps<typeof buttonVariants> & {
|
|
38
45
|
asChild?: boolean;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function Button({ className, variant, size, asChild = false, ...props }: ButtonProps) {
|
|
46
|
+
}) {
|
|
42
47
|
const Comp = asChild ? Slot : 'button';
|
|
43
48
|
|
|
44
49
|
return (
|
|
@@ -10,6 +10,9 @@ function Card({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
10
10
|
);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
|
|
14
|
+
return <div className={cn('flex flex-col space-y-1.5 p-6', className)} {...props} />;
|
|
15
|
+
}
|
|
13
16
|
function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
14
17
|
return <div className={cn('flex flex-col space-y-1.5 p-6', className)} {...props} />;
|
|
15
18
|
}
|
|
@@ -35,4 +38,4 @@ function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
35
38
|
return <div className={cn('flex items-center p-6 pt-0', className)} {...props} />;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
|
|
41
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import useEmblaCarousel, { type UseEmblaCarouselType } from 'embla-carousel-react';
|
|
5
|
+
import { ArrowLeft, ArrowRight } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
import { cn } from '../../lib/utils';
|
|
8
|
+
import { Button } from './button';
|
|
9
|
+
|
|
10
|
+
type CarouselApi = UseEmblaCarouselType[1];
|
|
11
|
+
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
|
|
12
|
+
type CarouselOptions = UseCarouselParameters[0];
|
|
13
|
+
type CarouselPlugin = UseCarouselParameters[1];
|
|
14
|
+
|
|
15
|
+
type CarouselProps = {
|
|
16
|
+
opts?: CarouselOptions;
|
|
17
|
+
plugins?: CarouselPlugin;
|
|
18
|
+
orientation?: 'horizontal' | 'vertical';
|
|
19
|
+
setApi?: (api: CarouselApi) => void;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type CarouselContextProps = {
|
|
23
|
+
carouselRef: ReturnType<typeof useEmblaCarousel>[0];
|
|
24
|
+
api: ReturnType<typeof useEmblaCarousel>[1];
|
|
25
|
+
scrollPrev: () => void;
|
|
26
|
+
scrollNext: () => void;
|
|
27
|
+
canScrollPrev: boolean;
|
|
28
|
+
canScrollNext: boolean;
|
|
29
|
+
} & CarouselProps;
|
|
30
|
+
|
|
31
|
+
const CarouselContext = React.createContext<CarouselContextProps | null>(null);
|
|
32
|
+
|
|
33
|
+
function useCarousel() {
|
|
34
|
+
const context = React.useContext(CarouselContext);
|
|
35
|
+
|
|
36
|
+
if (!context) {
|
|
37
|
+
throw new Error('useCarousel must be used within a <Carousel />');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return context;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function Carousel({
|
|
44
|
+
orientation = 'horizontal',
|
|
45
|
+
opts,
|
|
46
|
+
setApi,
|
|
47
|
+
plugins,
|
|
48
|
+
className,
|
|
49
|
+
children,
|
|
50
|
+
...props
|
|
51
|
+
}: React.ComponentProps<'div'> & CarouselProps) {
|
|
52
|
+
const [carouselRef, api] = useEmblaCarousel(
|
|
53
|
+
{
|
|
54
|
+
...opts,
|
|
55
|
+
axis: orientation === 'horizontal' ? 'x' : 'y',
|
|
56
|
+
},
|
|
57
|
+
plugins
|
|
58
|
+
);
|
|
59
|
+
const [canScrollPrev, setCanScrollPrev] = React.useState(false);
|
|
60
|
+
const [canScrollNext, setCanScrollNext] = React.useState(false);
|
|
61
|
+
|
|
62
|
+
const onSelect = React.useCallback((api: CarouselApi) => {
|
|
63
|
+
if (!api) return;
|
|
64
|
+
setCanScrollPrev(api.canScrollPrev());
|
|
65
|
+
setCanScrollNext(api.canScrollNext());
|
|
66
|
+
}, []);
|
|
67
|
+
|
|
68
|
+
const scrollPrev = React.useCallback(() => {
|
|
69
|
+
api?.scrollPrev();
|
|
70
|
+
}, [api]);
|
|
71
|
+
|
|
72
|
+
const scrollNext = React.useCallback(() => {
|
|
73
|
+
api?.scrollNext();
|
|
74
|
+
}, [api]);
|
|
75
|
+
|
|
76
|
+
const handleKeyDown = React.useCallback(
|
|
77
|
+
(event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
78
|
+
if (event.key === 'ArrowLeft') {
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
scrollPrev();
|
|
81
|
+
} else if (event.key === 'ArrowRight') {
|
|
82
|
+
event.preventDefault();
|
|
83
|
+
scrollNext();
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
[scrollPrev, scrollNext]
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
React.useEffect(() => {
|
|
90
|
+
if (!api || !setApi) return;
|
|
91
|
+
setApi(api);
|
|
92
|
+
}, [api, setApi]);
|
|
93
|
+
|
|
94
|
+
React.useEffect(() => {
|
|
95
|
+
if (!api) return;
|
|
96
|
+
onSelect(api);
|
|
97
|
+
api.on('reInit', onSelect);
|
|
98
|
+
api.on('select', onSelect);
|
|
99
|
+
|
|
100
|
+
return () => {
|
|
101
|
+
api?.off('select', onSelect);
|
|
102
|
+
};
|
|
103
|
+
}, [api, onSelect]);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<CarouselContext.Provider
|
|
107
|
+
value={{
|
|
108
|
+
carouselRef,
|
|
109
|
+
api: api,
|
|
110
|
+
opts,
|
|
111
|
+
orientation: orientation || (opts?.axis === 'y' ? 'vertical' : 'horizontal'),
|
|
112
|
+
scrollPrev,
|
|
113
|
+
scrollNext,
|
|
114
|
+
canScrollPrev,
|
|
115
|
+
canScrollNext,
|
|
116
|
+
}}
|
|
117
|
+
>
|
|
118
|
+
<div
|
|
119
|
+
onKeyDownCapture={handleKeyDown}
|
|
120
|
+
className={cn('relative', className)}
|
|
121
|
+
role="region"
|
|
122
|
+
aria-roledescription="carousel"
|
|
123
|
+
data-slot="carousel"
|
|
124
|
+
{...props}
|
|
125
|
+
>
|
|
126
|
+
{children}
|
|
127
|
+
</div>
|
|
128
|
+
</CarouselContext.Provider>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function CarouselContent({ className, ...props }: React.ComponentProps<'div'>) {
|
|
133
|
+
const { carouselRef, orientation } = useCarousel();
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<div ref={carouselRef} className="overflow-hidden" data-slot="carousel-content">
|
|
137
|
+
<div
|
|
138
|
+
className={cn(
|
|
139
|
+
'flex',
|
|
140
|
+
orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',
|
|
141
|
+
className
|
|
142
|
+
)}
|
|
143
|
+
{...props}
|
|
144
|
+
/>
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function CarouselItem({ className, ...props }: React.ComponentProps<'div'>) {
|
|
150
|
+
const { orientation } = useCarousel();
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<div
|
|
154
|
+
role="group"
|
|
155
|
+
aria-roledescription="slide"
|
|
156
|
+
data-slot="carousel-item"
|
|
157
|
+
className={cn(
|
|
158
|
+
'min-w-0 shrink-0 grow-0 basis-full',
|
|
159
|
+
orientation === 'horizontal' ? 'pl-4' : 'pt-4',
|
|
160
|
+
className
|
|
161
|
+
)}
|
|
162
|
+
{...props}
|
|
163
|
+
/>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function CarouselPrevious({
|
|
168
|
+
className,
|
|
169
|
+
variant = 'outline',
|
|
170
|
+
size = 'icon',
|
|
171
|
+
...props
|
|
172
|
+
}: React.ComponentProps<typeof Button>) {
|
|
173
|
+
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<Button
|
|
177
|
+
data-slot="carousel-previous"
|
|
178
|
+
variant={variant}
|
|
179
|
+
size={size}
|
|
180
|
+
className={cn(
|
|
181
|
+
'absolute size-8 rounded-full',
|
|
182
|
+
orientation === 'horizontal'
|
|
183
|
+
? 'top-1/2 -left-12 -translate-y-1/2'
|
|
184
|
+
: '-top-12 left-1/2 -translate-x-1/2 rotate-90',
|
|
185
|
+
className
|
|
186
|
+
)}
|
|
187
|
+
disabled={!canScrollPrev}
|
|
188
|
+
onClick={scrollPrev}
|
|
189
|
+
{...props}
|
|
190
|
+
>
|
|
191
|
+
<ArrowLeft />
|
|
192
|
+
<span className="sr-only">Previous slide</span>
|
|
193
|
+
</Button>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function CarouselNext({
|
|
198
|
+
className,
|
|
199
|
+
variant = 'outline',
|
|
200
|
+
size = 'icon',
|
|
201
|
+
...props
|
|
202
|
+
}: React.ComponentProps<typeof Button>) {
|
|
203
|
+
const { orientation, scrollNext, canScrollNext } = useCarousel();
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
<Button
|
|
207
|
+
data-slot="carousel-next"
|
|
208
|
+
variant={variant}
|
|
209
|
+
size={size}
|
|
210
|
+
className={cn(
|
|
211
|
+
'absolute size-8 rounded-full',
|
|
212
|
+
orientation === 'horizontal'
|
|
213
|
+
? 'top-1/2 -right-12 -translate-y-1/2'
|
|
214
|
+
: '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',
|
|
215
|
+
className
|
|
216
|
+
)}
|
|
217
|
+
disabled={!canScrollNext}
|
|
218
|
+
onClick={scrollNext}
|
|
219
|
+
{...props}
|
|
220
|
+
>
|
|
221
|
+
<ArrowRight />
|
|
222
|
+
<span className="sr-only">Next slide</span>
|
|
223
|
+
</Button>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export {
|
|
228
|
+
type CarouselApi,
|
|
229
|
+
Carousel,
|
|
230
|
+
CarouselContent,
|
|
231
|
+
CarouselItem,
|
|
232
|
+
CarouselPrevious,
|
|
233
|
+
CarouselNext,
|
|
234
|
+
};
|