@cloudbase/agent-react-ui 1.0.1-alpha.32

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.
Files changed (109) hide show
  1. package/README.md +123 -0
  2. package/components.json +21 -0
  3. package/dist/index.css +4241 -0
  4. package/dist/index.css.map +1 -0
  5. package/dist/index.d.mts +59 -0
  6. package/dist/index.d.ts +59 -0
  7. package/dist/index.js +2169 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/index.mjs +2182 -0
  10. package/dist/index.mjs.map +1 -0
  11. package/example/.env.sample +2 -0
  12. package/example/App.tsx +368 -0
  13. package/example/app.css +1 -0
  14. package/example/index.html +12 -0
  15. package/example/main.tsx +9 -0
  16. package/example/vite.config.ts +34 -0
  17. package/package.json +75 -0
  18. package/postcss.config.cjs +3 -0
  19. package/src/components/ai-elements/agent.tsx +140 -0
  20. package/src/components/ai-elements/artifact.tsx +147 -0
  21. package/src/components/ai-elements/attachments.tsx +421 -0
  22. package/src/components/ai-elements/audio-player.tsx +228 -0
  23. package/src/components/ai-elements/canvas.tsx +22 -0
  24. package/src/components/ai-elements/chain-of-thought.tsx +228 -0
  25. package/src/components/ai-elements/checkpoint.tsx +71 -0
  26. package/src/components/ai-elements/code-block.tsx +532 -0
  27. package/src/components/ai-elements/commit.tsx +448 -0
  28. package/src/components/ai-elements/confirmation.tsx +176 -0
  29. package/src/components/ai-elements/connection.tsx +28 -0
  30. package/src/components/ai-elements/context.tsx +408 -0
  31. package/src/components/ai-elements/controls.tsx +18 -0
  32. package/src/components/ai-elements/conversation.tsx +100 -0
  33. package/src/components/ai-elements/edge.tsx +140 -0
  34. package/src/components/ai-elements/environment-variables.tsx +295 -0
  35. package/src/components/ai-elements/file-tree.tsx +258 -0
  36. package/src/components/ai-elements/image.tsx +24 -0
  37. package/src/components/ai-elements/inline-citation.tsx +287 -0
  38. package/src/components/ai-elements/message.tsx +336 -0
  39. package/src/components/ai-elements/mic-selector.tsx +370 -0
  40. package/src/components/ai-elements/model-selector.tsx +211 -0
  41. package/src/components/ai-elements/node.tsx +71 -0
  42. package/src/components/ai-elements/open-in-chat.tsx +365 -0
  43. package/src/components/ai-elements/package-info.tsx +233 -0
  44. package/src/components/ai-elements/panel.tsx +15 -0
  45. package/src/components/ai-elements/persona.tsx +270 -0
  46. package/src/components/ai-elements/plan.tsx +142 -0
  47. package/src/components/ai-elements/prompt-input.tsx +1263 -0
  48. package/src/components/ai-elements/queue.tsx +274 -0
  49. package/src/components/ai-elements/reasoning.tsx +193 -0
  50. package/src/components/ai-elements/sandbox.tsx +126 -0
  51. package/src/components/ai-elements/schema-display.tsx +458 -0
  52. package/src/components/ai-elements/shimmer.tsx +64 -0
  53. package/src/components/ai-elements/snippet.tsx +139 -0
  54. package/src/components/ai-elements/sources.tsx +77 -0
  55. package/src/components/ai-elements/speech-input.tsx +301 -0
  56. package/src/components/ai-elements/stack-trace.tsx +482 -0
  57. package/src/components/ai-elements/suggestion.tsx +53 -0
  58. package/src/components/ai-elements/task.tsx +87 -0
  59. package/src/components/ai-elements/terminal.tsx +261 -0
  60. package/src/components/ai-elements/test-results.tsx +485 -0
  61. package/src/components/ai-elements/tool.tsx +174 -0
  62. package/src/components/ai-elements/toolbar.tsx +16 -0
  63. package/src/components/ai-elements/transcription.tsx +124 -0
  64. package/src/components/ai-elements/voice-selector.tsx +479 -0
  65. package/src/components/ai-elements/web-preview.tsx +263 -0
  66. package/src/components/chat/Chat.tsx +178 -0
  67. package/src/components/chat/Input.tsx +98 -0
  68. package/src/components/chat/Message.tsx +276 -0
  69. package/src/components/chat/index.ts +2 -0
  70. package/src/components/index.ts +1 -0
  71. package/src/components/ui/accordion.tsx +64 -0
  72. package/src/components/ui/alert.tsx +66 -0
  73. package/src/components/ui/avatar.tsx +107 -0
  74. package/src/components/ui/badge.tsx +48 -0
  75. package/src/components/ui/button-group.tsx +83 -0
  76. package/src/components/ui/button.tsx +64 -0
  77. package/src/components/ui/card.tsx +92 -0
  78. package/src/components/ui/carousel.tsx +239 -0
  79. package/src/components/ui/collapsible.tsx +31 -0
  80. package/src/components/ui/command.tsx +184 -0
  81. package/src/components/ui/dialog.tsx +158 -0
  82. package/src/components/ui/dropdown-menu.tsx +257 -0
  83. package/src/components/ui/hover-card.tsx +42 -0
  84. package/src/components/ui/input-group.tsx +168 -0
  85. package/src/components/ui/input.tsx +21 -0
  86. package/src/components/ui/popover.tsx +87 -0
  87. package/src/components/ui/progress.tsx +31 -0
  88. package/src/components/ui/scroll-area.tsx +56 -0
  89. package/src/components/ui/select.tsx +190 -0
  90. package/src/components/ui/separator.tsx +28 -0
  91. package/src/components/ui/spinner.tsx +16 -0
  92. package/src/components/ui/switch.tsx +33 -0
  93. package/src/components/ui/tabs.tsx +91 -0
  94. package/src/components/ui/textarea.tsx +18 -0
  95. package/src/components/ui/tooltip.tsx +61 -0
  96. package/src/css/global.css +123 -0
  97. package/src/css/index.css +1 -0
  98. package/src/hooks/index.ts +1 -0
  99. package/src/hooks/use-copy-to-clipboard.ts +31 -0
  100. package/src/index.ts +4 -0
  101. package/src/lib/utils.ts +6 -0
  102. package/src/locales/context.ts +8 -0
  103. package/src/locales/hooks.ts +20 -0
  104. package/src/locales/index.ts +3 -0
  105. package/src/locales/langs/en.ts +17 -0
  106. package/src/locales/langs/index.ts +12 -0
  107. package/src/locales/langs/zh-cn.ts +18 -0
  108. package/tsconfig.json +21 -0
  109. package/tsup.config.ts +21 -0
@@ -0,0 +1,261 @@
1
+ "use client";
2
+
3
+ import { Button } from "@/components/ui/button";
4
+ import { cn } from "@/lib/utils";
5
+ import Ansi from "ansi-to-react";
6
+ import { CheckIcon, CopyIcon, TerminalIcon, Trash2Icon } from "lucide-react";
7
+ import {
8
+ type ComponentProps,
9
+ createContext,
10
+ type HTMLAttributes,
11
+ useContext,
12
+ useEffect,
13
+ useRef,
14
+ useState,
15
+ } from "react";
16
+ import { Shimmer } from "./shimmer";
17
+
18
+ interface TerminalContextType {
19
+ output: string;
20
+ isStreaming: boolean;
21
+ autoScroll: boolean;
22
+ onClear?: () => void;
23
+ }
24
+
25
+ const TerminalContext = createContext<TerminalContextType>({
26
+ output: "",
27
+ isStreaming: false,
28
+ autoScroll: true,
29
+ });
30
+
31
+ export type TerminalProps = HTMLAttributes<HTMLDivElement> & {
32
+ output: string;
33
+ isStreaming?: boolean;
34
+ autoScroll?: boolean;
35
+ onClear?: () => void;
36
+ };
37
+
38
+ export const Terminal = ({
39
+ output,
40
+ isStreaming = false,
41
+ autoScroll = true,
42
+ onClear,
43
+ className,
44
+ children,
45
+ ...props
46
+ }: TerminalProps) => (
47
+ <TerminalContext.Provider
48
+ value={{ output, isStreaming, autoScroll, onClear }}
49
+ >
50
+ <div
51
+ className={cn(
52
+ "flex flex-col overflow-hidden rounded-lg border bg-zinc-950 text-zinc-100",
53
+ className
54
+ )}
55
+ {...props}
56
+ >
57
+ {children ?? (
58
+ <>
59
+ <TerminalHeader>
60
+ <TerminalTitle />
61
+ <div className="flex items-center gap-1">
62
+ <TerminalStatus />
63
+ <TerminalActions>
64
+ <TerminalCopyButton />
65
+ {onClear && <TerminalClearButton />}
66
+ </TerminalActions>
67
+ </div>
68
+ </TerminalHeader>
69
+ <TerminalContent />
70
+ </>
71
+ )}
72
+ </div>
73
+ </TerminalContext.Provider>
74
+ );
75
+
76
+ export type TerminalHeaderProps = HTMLAttributes<HTMLDivElement>;
77
+
78
+ export const TerminalHeader = ({
79
+ className,
80
+ children,
81
+ ...props
82
+ }: TerminalHeaderProps) => (
83
+ <div
84
+ className={cn(
85
+ "flex items-center justify-between border-zinc-800 border-b px-4 py-2",
86
+ className
87
+ )}
88
+ {...props}
89
+ >
90
+ {children}
91
+ </div>
92
+ );
93
+
94
+ export type TerminalTitleProps = HTMLAttributes<HTMLDivElement>;
95
+
96
+ export const TerminalTitle = ({
97
+ className,
98
+ children,
99
+ ...props
100
+ }: TerminalTitleProps) => (
101
+ <div
102
+ className={cn("flex items-center gap-2 text-sm text-zinc-400", className)}
103
+ {...props}
104
+ >
105
+ <TerminalIcon className="size-4" />
106
+ {children ?? "Terminal"}
107
+ </div>
108
+ );
109
+
110
+ export type TerminalStatusProps = HTMLAttributes<HTMLDivElement>;
111
+
112
+ export const TerminalStatus = ({
113
+ className,
114
+ children,
115
+ ...props
116
+ }: TerminalStatusProps) => {
117
+ const { isStreaming } = useContext(TerminalContext);
118
+
119
+ if (!isStreaming) {
120
+ return null;
121
+ }
122
+
123
+ return (
124
+ <div
125
+ className={cn("flex items-center gap-2 text-xs text-zinc-400", className)}
126
+ {...props}
127
+ >
128
+ {children ?? <Shimmer className="w-16" />}
129
+ </div>
130
+ );
131
+ };
132
+
133
+ export type TerminalActionsProps = HTMLAttributes<HTMLDivElement>;
134
+
135
+ export const TerminalActions = ({
136
+ className,
137
+ children,
138
+ ...props
139
+ }: TerminalActionsProps) => (
140
+ <div className={cn("flex items-center gap-1", className)} {...props}>
141
+ {children}
142
+ </div>
143
+ );
144
+
145
+ export type TerminalCopyButtonProps = ComponentProps<typeof Button> & {
146
+ onCopy?: () => void;
147
+ onError?: (error: Error) => void;
148
+ timeout?: number;
149
+ };
150
+
151
+ export const TerminalCopyButton = ({
152
+ onCopy,
153
+ onError,
154
+ timeout = 2000,
155
+ children,
156
+ className,
157
+ ...props
158
+ }: TerminalCopyButtonProps) => {
159
+ const [isCopied, setIsCopied] = useState(false);
160
+ const { output } = useContext(TerminalContext);
161
+
162
+ const copyToClipboard = async () => {
163
+ if (typeof window === "undefined" || !navigator?.clipboard?.writeText) {
164
+ onError?.(new Error("Clipboard API not available"));
165
+ return;
166
+ }
167
+
168
+ try {
169
+ await navigator.clipboard.writeText(output);
170
+ setIsCopied(true);
171
+ onCopy?.();
172
+ setTimeout(() => setIsCopied(false), timeout);
173
+ } catch (error) {
174
+ onError?.(error as Error);
175
+ }
176
+ };
177
+
178
+ const Icon = isCopied ? CheckIcon : CopyIcon;
179
+
180
+ return (
181
+ <Button
182
+ className={cn(
183
+ "size-7 shrink-0 text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100",
184
+ className
185
+ )}
186
+ onClick={copyToClipboard}
187
+ size="icon"
188
+ variant="ghost"
189
+ {...props}
190
+ >
191
+ {children ?? <Icon size={14} />}
192
+ </Button>
193
+ );
194
+ };
195
+
196
+ export type TerminalClearButtonProps = ComponentProps<typeof Button>;
197
+
198
+ export const TerminalClearButton = ({
199
+ children,
200
+ className,
201
+ ...props
202
+ }: TerminalClearButtonProps) => {
203
+ const { onClear } = useContext(TerminalContext);
204
+
205
+ if (!onClear) {
206
+ return null;
207
+ }
208
+
209
+ return (
210
+ <Button
211
+ className={cn(
212
+ "size-7 shrink-0 text-zinc-400 hover:bg-zinc-800 hover:text-zinc-100",
213
+ className
214
+ )}
215
+ onClick={onClear}
216
+ size="icon"
217
+ variant="ghost"
218
+ {...props}
219
+ >
220
+ {children ?? <Trash2Icon size={14} />}
221
+ </Button>
222
+ );
223
+ };
224
+
225
+ export type TerminalContentProps = HTMLAttributes<HTMLDivElement>;
226
+
227
+ export const TerminalContent = ({
228
+ className,
229
+ children,
230
+ ...props
231
+ }: TerminalContentProps) => {
232
+ const { output, isStreaming, autoScroll } = useContext(TerminalContext);
233
+ const containerRef = useRef<HTMLDivElement>(null);
234
+
235
+ // biome-ignore lint/correctness/useExhaustiveDependencies: output triggers auto-scroll when new content arrives
236
+ useEffect(() => {
237
+ if (autoScroll && containerRef.current) {
238
+ containerRef.current.scrollTop = containerRef.current.scrollHeight;
239
+ }
240
+ }, [output, autoScroll]);
241
+
242
+ return (
243
+ <div
244
+ className={cn(
245
+ "max-h-96 overflow-auto p-4 font-mono text-sm leading-relaxed",
246
+ className
247
+ )}
248
+ ref={containerRef}
249
+ {...props}
250
+ >
251
+ {children ?? (
252
+ <pre className="whitespace-pre-wrap break-words">
253
+ <Ansi>{output}</Ansi>
254
+ {isStreaming && (
255
+ <span className="ml-0.5 inline-block h-4 w-2 animate-pulse bg-zinc-100" />
256
+ )}
257
+ </pre>
258
+ )}
259
+ </div>
260
+ );
261
+ };