@tangle-network/ui 7.0.0 → 8.1.0
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/CHANGELOG.md +12 -0
- package/dist/chat.d.ts +17 -72
- package/dist/chat.js +2 -4
- package/dist/{chunk-QIRVZMQY.js → chunk-C3BIVG72.js} +143 -107
- package/dist/{chunk-5CS3I7Y3.js → chunk-QUAU6ZNC.js} +111 -395
- package/dist/hooks.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -9
- package/dist/run.d.ts +30 -2
- package/dist/run.js +4 -6
- package/dist/sdk-hooks.d.ts +1 -1
- package/dist/{tool-call-feed-Bs3MyQMT.d.ts → tool-call-feed-D9iofJgW.d.ts} +1 -23
- package/package.json +2 -2
- package/src/chat/agent-timeline.tsx +139 -45
- package/src/chat/chat-container.tsx +6 -48
- package/src/chat/chat-message.tsx +0 -4
- package/src/chat/index.ts +0 -1
- package/src/markdown/markdown.stories.tsx +1 -1
- package/src/run/assistant-run-shell.tsx +115 -0
- package/src/run/index.ts +5 -1
- package/src/run/run-group.tsx +12 -76
- package/src/run/tool-call-step.tsx +5 -7
- package/src/chat/chat-input.stories.tsx +0 -142
- package/src/chat/chat-input.tsx +0 -389
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import * as Collapsible from "@radix-ui/react-collapsible";
|
|
3
|
+
import { ChevronDown, ChevronRight, Loader2, Sparkles } from "lucide-react";
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
|
|
6
|
+
export interface AssistantRunShellProps {
|
|
7
|
+
/** Header label, e.g. the agent name or "Tools". */
|
|
8
|
+
label: string;
|
|
9
|
+
/** Terse stat line beside the label, e.g. "3 tools, 2s thinking". */
|
|
10
|
+
summary?: string;
|
|
11
|
+
/** One-line preview shown next to the label AND below the header when collapsed. */
|
|
12
|
+
collapsedPreview?: string;
|
|
13
|
+
/** Small trailing glyphs before the status pill (e.g. category badges). */
|
|
14
|
+
badges?: ReactNode;
|
|
15
|
+
/** Drives the status pill and header spinner. */
|
|
16
|
+
isStreaming?: boolean;
|
|
17
|
+
collapsed: boolean;
|
|
18
|
+
onToggle: () => void;
|
|
19
|
+
/** Actions rendered outside the collapse trigger, right of the header. */
|
|
20
|
+
headerActions?: ReactNode;
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The collapsible "assistant run" container shared by `RunGroup` (session-model
|
|
27
|
+
* driven) and `AgentTimeline` (declarative item list). Owns the header
|
|
28
|
+
* (label · summary · badges · status pill · chevron), the collapsed preview, and
|
|
29
|
+
* the Radix collapse — so both transcripts fold agent activity the same way and
|
|
30
|
+
* there is one implementation of a run, not two. It renders only chrome; callers
|
|
31
|
+
* pass the run body (tool rows, reasoning, text) as `children`.
|
|
32
|
+
*/
|
|
33
|
+
export function AssistantRunShell({
|
|
34
|
+
label,
|
|
35
|
+
summary,
|
|
36
|
+
collapsedPreview,
|
|
37
|
+
badges,
|
|
38
|
+
isStreaming,
|
|
39
|
+
collapsed,
|
|
40
|
+
onToggle,
|
|
41
|
+
headerActions,
|
|
42
|
+
children,
|
|
43
|
+
className,
|
|
44
|
+
}: AssistantRunShellProps) {
|
|
45
|
+
return (
|
|
46
|
+
<Collapsible.Root open={!collapsed} onOpenChange={() => onToggle()}>
|
|
47
|
+
<div
|
|
48
|
+
className={cn(
|
|
49
|
+
"rounded-[28px] border border-[var(--border-subtle)] bg-[var(--bg-card)] shadow-none",
|
|
50
|
+
className,
|
|
51
|
+
)}
|
|
52
|
+
>
|
|
53
|
+
<div className="flex items-start gap-3 px-3 py-2.5">
|
|
54
|
+
<Collapsible.Trigger asChild>
|
|
55
|
+
<button
|
|
56
|
+
type="button"
|
|
57
|
+
className="w-full rounded-[20px] bg-transparent px-0 py-0 text-left transition-colors hover:bg-transparent"
|
|
58
|
+
>
|
|
59
|
+
<div className="flex items-center gap-2">
|
|
60
|
+
<span className="font-semibold text-foreground text-sm">{label}</span>
|
|
61
|
+
|
|
62
|
+
{summary ? (
|
|
63
|
+
<span className="text-[11px] text-muted-foreground">{summary}</span>
|
|
64
|
+
) : null}
|
|
65
|
+
{collapsed && collapsedPreview ? (
|
|
66
|
+
<span className="min-w-0 truncate text-[11px] text-foreground/70">
|
|
67
|
+
{collapsedPreview}
|
|
68
|
+
</span>
|
|
69
|
+
) : null}
|
|
70
|
+
|
|
71
|
+
<div className="ml-auto flex shrink-0 items-center gap-1.5">
|
|
72
|
+
{badges}
|
|
73
|
+
|
|
74
|
+
{isStreaming ? (
|
|
75
|
+
<span className="inline-flex items-center gap-1 rounded-full border border-[var(--border-accent)] bg-[var(--accent-surface-soft)] px-2 py-px text-[10px] font-semibold uppercase text-[var(--accent-text)]">
|
|
76
|
+
<Loader2 className="h-2.5 w-2.5 animate-spin" />
|
|
77
|
+
Running
|
|
78
|
+
</span>
|
|
79
|
+
) : (
|
|
80
|
+
<span className="inline-flex items-center gap-1 rounded-full border border-border px-2 py-px text-[10px] font-semibold uppercase text-muted-foreground">
|
|
81
|
+
<Sparkles className="h-2.5 w-2.5" />
|
|
82
|
+
Done
|
|
83
|
+
</span>
|
|
84
|
+
)}
|
|
85
|
+
|
|
86
|
+
{collapsed ? (
|
|
87
|
+
<ChevronRight className="h-3.5 w-3.5 text-muted-foreground" />
|
|
88
|
+
) : (
|
|
89
|
+
<ChevronDown className="h-3.5 w-3.5 text-muted-foreground" />
|
|
90
|
+
)}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</button>
|
|
94
|
+
</Collapsible.Trigger>
|
|
95
|
+
|
|
96
|
+
{headerActions ? (
|
|
97
|
+
<div className="flex shrink-0 flex-wrap items-center justify-end gap-1.5 pt-1">
|
|
98
|
+
{headerActions}
|
|
99
|
+
</div>
|
|
100
|
+
) : null}
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
{collapsed && collapsedPreview ? (
|
|
104
|
+
<div className="line-clamp-2 px-4 pb-4 text-sm leading-6 text-muted-foreground">
|
|
105
|
+
{collapsedPreview}
|
|
106
|
+
</div>
|
|
107
|
+
) : null}
|
|
108
|
+
|
|
109
|
+
<Collapsible.Content className="overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp">
|
|
110
|
+
<div className="border-t border-[var(--border-subtle)] px-4 pb-4 pt-3">{children}</div>
|
|
111
|
+
</Collapsible.Content>
|
|
112
|
+
</div>
|
|
113
|
+
</Collapsible.Root>
|
|
114
|
+
);
|
|
115
|
+
}
|
package/src/run/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { RunGroup, type RunGroupProps } from "./run-group";
|
|
2
|
+
export { AssistantRunShell, type AssistantRunShellProps } from "./assistant-run-shell";
|
|
2
3
|
export { InlineToolItem, type InlineToolItemProps } from "./inline-tool-item";
|
|
3
4
|
export {
|
|
4
5
|
InlineThinkingItem,
|
|
@@ -9,5 +10,8 @@ export {
|
|
|
9
10
|
type ExpandedToolDetailProps,
|
|
10
11
|
} from "./expanded-tool-detail";
|
|
11
12
|
export { LiveDuration } from "./run-item-primitives";
|
|
12
|
-
|
|
13
|
+
// ToolCallStep/ToolCallGroup are internal adapters over InlineToolItem (used by
|
|
14
|
+
// AgentTimeline + ToolCallFeed); only their status/type vocabulary is public
|
|
15
|
+
// because ToolCallData references it.
|
|
16
|
+
export { type ToolCallType, type ToolCallStatus } from "./tool-call-step";
|
|
13
17
|
export { ToolCallFeed, parseToolEvent, type ToolCallFeedProps, type ToolCallData, type FeedSegment } from "./tool-call-feed";
|
package/src/run/run-group.tsx
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { memo, useMemo, type ComponentType, type ReactNode } from "react";
|
|
2
|
-
import * as Collapsible from "@radix-ui/react-collapsible";
|
|
3
2
|
import {
|
|
4
3
|
Bot,
|
|
5
4
|
Loader2,
|
|
6
|
-
ChevronDown,
|
|
7
|
-
ChevronRight,
|
|
8
5
|
Terminal,
|
|
9
6
|
FileEdit,
|
|
10
7
|
FileSearch,
|
|
@@ -13,10 +10,8 @@ import {
|
|
|
13
10
|
Globe,
|
|
14
11
|
ClipboardList,
|
|
15
12
|
Settings,
|
|
16
|
-
Sparkles,
|
|
17
13
|
type LucideProps,
|
|
18
14
|
} from "lucide-react";
|
|
19
|
-
import { cn } from "../lib/utils";
|
|
20
15
|
import { formatDuration } from "../utils/format";
|
|
21
16
|
import type { Run, ToolCategory } from "../types/run";
|
|
22
17
|
import type { SessionPart, ToolPart, ReasoningPart } from "../types/parts";
|
|
@@ -24,6 +19,7 @@ import type { AgentBranding } from "../types/branding";
|
|
|
24
19
|
import type { CustomToolRenderer } from "../types/tool-display";
|
|
25
20
|
import { InlineToolItem } from "./inline-tool-item";
|
|
26
21
|
import { InlineThinkingItem } from "./inline-thinking-item";
|
|
22
|
+
import { AssistantRunShell } from "./assistant-run-shell";
|
|
27
23
|
import { Markdown } from "../markdown/markdown";
|
|
28
24
|
import {
|
|
29
25
|
OpenUIArtifactRenderer,
|
|
@@ -393,73 +389,16 @@ export const RunGroup = memo(
|
|
|
393
389
|
}
|
|
394
390
|
|
|
395
391
|
return (
|
|
396
|
-
<
|
|
397
|
-
|
|
398
|
-
{
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
>
|
|
407
|
-
<div className="flex items-center gap-2">
|
|
408
|
-
<span className={cn("font-semibold text-sm", branding.textClass)}>
|
|
409
|
-
{branding.label}
|
|
410
|
-
</span>
|
|
411
|
-
|
|
412
|
-
{renderSummary(run) ? (
|
|
413
|
-
<span className="text-[11px] text-muted-foreground">{renderSummary(run)}</span>
|
|
414
|
-
) : null}
|
|
415
|
-
{collapsed && run.summaryText ? (
|
|
416
|
-
<span className="min-w-0 truncate text-[11px] text-foreground/70">
|
|
417
|
-
{run.summaryText}
|
|
418
|
-
</span>
|
|
419
|
-
) : null}
|
|
420
|
-
|
|
421
|
-
<div className="ml-auto flex shrink-0 items-center gap-1.5">
|
|
422
|
-
<CategoryBadges categories={stats.toolCategories} />
|
|
423
|
-
|
|
424
|
-
{isStreaming ? (
|
|
425
|
-
<span className="inline-flex items-center gap-1 rounded-full border border-[var(--border-accent)] bg-[var(--accent-surface-soft)] px-2 py-px text-[10px] font-semibold uppercase text-[var(--accent-text)]">
|
|
426
|
-
<Loader2 className="h-2.5 w-2.5 animate-spin" />
|
|
427
|
-
Running
|
|
428
|
-
</span>
|
|
429
|
-
) : (
|
|
430
|
-
<span className="inline-flex items-center gap-1 rounded-full border border-border px-2 py-px text-[10px] font-semibold uppercase text-muted-foreground">
|
|
431
|
-
<Sparkles className="h-2.5 w-2.5" />
|
|
432
|
-
Done
|
|
433
|
-
</span>
|
|
434
|
-
)}
|
|
435
|
-
|
|
436
|
-
{!collapsed ? (
|
|
437
|
-
<ChevronDown className="h-3.5 w-3.5 text-muted-foreground" />
|
|
438
|
-
) : (
|
|
439
|
-
<ChevronRight className="h-3.5 w-3.5 text-muted-foreground" />
|
|
440
|
-
)}
|
|
441
|
-
</div>
|
|
442
|
-
</div>
|
|
443
|
-
</button>
|
|
444
|
-
</Collapsible.Trigger>
|
|
445
|
-
|
|
446
|
-
{headerActions ? (
|
|
447
|
-
<div className="flex shrink-0 flex-wrap items-center justify-end gap-1.5 pt-1">
|
|
448
|
-
{headerActions}
|
|
449
|
-
</div>
|
|
450
|
-
) : null}
|
|
451
|
-
</div>
|
|
452
|
-
|
|
453
|
-
{/* Summary text when collapsed */}
|
|
454
|
-
{collapsed && run.summaryText && (
|
|
455
|
-
<div className="px-4 pb-4 text-sm leading-6 text-muted-foreground line-clamp-2">
|
|
456
|
-
{run.summaryText}
|
|
457
|
-
</div>
|
|
458
|
-
)}
|
|
459
|
-
|
|
460
|
-
{/* Expanded content */}
|
|
461
|
-
<Collapsible.Content className="overflow-hidden data-[state=open]:animate-slideDown data-[state=closed]:animate-slideUp">
|
|
462
|
-
<div className={cn("border-t border-[var(--border-subtle)] px-4 pb-4 pt-3")}>
|
|
392
|
+
<AssistantRunShell
|
|
393
|
+
label={branding.label}
|
|
394
|
+
summary={renderSummary(run) || undefined}
|
|
395
|
+
collapsedPreview={run.summaryText ?? undefined}
|
|
396
|
+
badges={<CategoryBadges categories={stats.toolCategories} />}
|
|
397
|
+
isStreaming={isStreaming}
|
|
398
|
+
collapsed={collapsed}
|
|
399
|
+
onToggle={onToggle}
|
|
400
|
+
headerActions={headerActions}
|
|
401
|
+
>
|
|
463
402
|
{allParts.map(({ part, msgId, index }, partIndex) => {
|
|
464
403
|
const key = `${msgId}-${index}`;
|
|
465
404
|
|
|
@@ -549,10 +488,7 @@ export const RunGroup = memo(
|
|
|
549
488
|
</div>
|
|
550
489
|
);
|
|
551
490
|
})}
|
|
552
|
-
|
|
553
|
-
</Collapsible.Content>
|
|
554
|
-
</div>
|
|
555
|
-
</Collapsible.Root>
|
|
491
|
+
</AssistantRunShell>
|
|
556
492
|
);
|
|
557
493
|
},
|
|
558
494
|
);
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ToolCallStep —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `ToolCallFeed`) and the run group share ONE row implementation and one look.
|
|
8
|
-
* The bespoke row markup is gone; only the prop adapter remains.
|
|
2
|
+
* ToolCallStep — internal adapter over the canonical `InlineToolItem` row.
|
|
3
|
+
* Maps flat `ToolCallData`-style props (label / status / detail / output /
|
|
4
|
+
* duration) onto a `ToolPart` so `AgentTimeline` and `ToolCallFeed` share the
|
|
5
|
+
* one row implementation. Not exported publicly; only the `ToolCallType` /
|
|
6
|
+
* `ToolCallStatus` vocabulary is (via `ToolCallData`).
|
|
9
7
|
*/
|
|
10
8
|
|
|
11
9
|
import { type ReactNode } from "react";
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
-
import { ChatInput, type PendingFile } from './chat-input'
|
|
3
|
-
|
|
4
|
-
const meta: Meta<typeof ChatInput> = {
|
|
5
|
-
title: 'Chat/ChatInput',
|
|
6
|
-
component: ChatInput,
|
|
7
|
-
parameters: { layout: 'centered', backgrounds: { default: 'dark' } },
|
|
8
|
-
decorators: [
|
|
9
|
-
(Story) => (
|
|
10
|
-
<div className="w-[680px]">
|
|
11
|
-
<Story />
|
|
12
|
-
</div>
|
|
13
|
-
),
|
|
14
|
-
],
|
|
15
|
-
args: {
|
|
16
|
-
onSend: (msg, files) => console.log('send', msg, files),
|
|
17
|
-
onCancel: () => console.log('cancel'),
|
|
18
|
-
},
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export default meta
|
|
22
|
-
type Story = StoryObj<typeof ChatInput>
|
|
23
|
-
|
|
24
|
-
export const Empty: Story = {
|
|
25
|
-
name: 'Empty — ready',
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const WithModelSelector: Story = {
|
|
29
|
-
name: 'With model selector',
|
|
30
|
-
args: {
|
|
31
|
-
modelLabel: 'claude-sonnet-4-6',
|
|
32
|
-
onModelClick: () => console.log('model click'),
|
|
33
|
-
},
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export const WithAttachButtons: Story = {
|
|
37
|
-
name: 'With attach buttons',
|
|
38
|
-
args: {
|
|
39
|
-
onAttach: (files) => console.log('attach', files),
|
|
40
|
-
onAttachFolder: (files) => console.log('attach folder', files),
|
|
41
|
-
modelLabel: 'claude-sonnet-4-6',
|
|
42
|
-
onModelClick: () => console.log('model click'),
|
|
43
|
-
},
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const Streaming: Story = {
|
|
47
|
-
name: 'Streaming — stop button active',
|
|
48
|
-
args: {
|
|
49
|
-
isStreaming: true,
|
|
50
|
-
onCancel: () => console.log('cancel'),
|
|
51
|
-
onAttach: (files) => console.log('attach', files),
|
|
52
|
-
modelLabel: 'claude-sonnet-4-6',
|
|
53
|
-
},
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export const Disabled: Story = {
|
|
57
|
-
name: 'Disabled',
|
|
58
|
-
args: {
|
|
59
|
-
disabled: true,
|
|
60
|
-
onAttach: (files) => console.log('attach', files),
|
|
61
|
-
modelLabel: 'claude-sonnet-4-6',
|
|
62
|
-
},
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const sampleFiles: PendingFile[] = [
|
|
66
|
-
{ id: 'f1', name: 'dataset.csv', size: 204800, type: 'file', status: 'ready' },
|
|
67
|
-
{ id: 'f2', name: 'report.pdf', size: 1572864, type: 'file', status: 'uploading' },
|
|
68
|
-
]
|
|
69
|
-
|
|
70
|
-
export const WithFilesAttached: Story = {
|
|
71
|
-
name: 'With file attachments',
|
|
72
|
-
args: {
|
|
73
|
-
onAttach: (files) => console.log('attach', files),
|
|
74
|
-
pendingFiles: sampleFiles,
|
|
75
|
-
onRemoveFile: (id) => console.log('remove', id),
|
|
76
|
-
modelLabel: 'claude-sonnet-4-6',
|
|
77
|
-
onModelClick: () => console.log('model click'),
|
|
78
|
-
},
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const folderFiles: PendingFile[] = [
|
|
82
|
-
{ id: 'd1', name: 'my-project', size: 0, type: 'folder', fileCount: 42, status: 'ready' },
|
|
83
|
-
{ id: 'f3', name: 'notes.txt', size: 1024, type: 'file', status: 'ready' },
|
|
84
|
-
]
|
|
85
|
-
|
|
86
|
-
export const WithFolderAttached: Story = {
|
|
87
|
-
name: 'With folder + file',
|
|
88
|
-
args: {
|
|
89
|
-
onAttach: (files) => console.log('attach', files),
|
|
90
|
-
onAttachFolder: (files) => console.log('attach folder', files),
|
|
91
|
-
pendingFiles: folderFiles,
|
|
92
|
-
onRemoveFile: (id) => console.log('remove', id),
|
|
93
|
-
modelLabel: 'claude-sonnet-4-6',
|
|
94
|
-
},
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export const WithErrorFile: Story = {
|
|
98
|
-
name: 'With error attachment',
|
|
99
|
-
args: {
|
|
100
|
-
onAttach: (files) => console.log('attach', files),
|
|
101
|
-
pendingFiles: [
|
|
102
|
-
{ id: 'e1', name: 'too-large.zip', size: 524288000, type: 'file', status: 'error' },
|
|
103
|
-
{ id: 'f4', name: 'config.json', size: 2048, type: 'file', status: 'ready' },
|
|
104
|
-
],
|
|
105
|
-
onRemoveFile: (id) => console.log('remove', id),
|
|
106
|
-
},
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export const CustomPlaceholder: Story = {
|
|
110
|
-
name: 'Custom placeholder',
|
|
111
|
-
args: {
|
|
112
|
-
placeholder: 'Describe the data transformation you need…',
|
|
113
|
-
onAttach: (files) => console.log('attach', files),
|
|
114
|
-
modelLabel: 'gpt-4o',
|
|
115
|
-
},
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** Static drag-over overlay preview */
|
|
119
|
-
export const DragOverPreview: Story = {
|
|
120
|
-
name: 'Drag-over overlay (static preview)',
|
|
121
|
-
render: (args) => (
|
|
122
|
-
<div className="w-[680px] px-4 py-3 relative">
|
|
123
|
-
{/* Drag overlay replica */}
|
|
124
|
-
<div className="absolute inset-0 z-10 flex items-center justify-center rounded-[28px] border-2 border-dashed border-blue-400 bg-blue-500/8 backdrop-blur-sm pointer-events-none mx-4 my-3">
|
|
125
|
-
<div className="text-center">
|
|
126
|
-
<div className="mx-auto mb-3 flex h-12 w-12 items-center justify-center rounded-xl bg-blue-500/15">
|
|
127
|
-
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-blue-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
|
|
128
|
-
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
|
|
129
|
-
<polyline points="17 8 12 3 7 8" />
|
|
130
|
-
<line x1="12" y1="3" x2="12" y2="15" />
|
|
131
|
-
</svg>
|
|
132
|
-
</div>
|
|
133
|
-
<p className="text-sm font-semibold text-white">Drop files to add context</p>
|
|
134
|
-
<p className="mt-1 text-xs text-zinc-400">Files will be attached to your next message.</p>
|
|
135
|
-
</div>
|
|
136
|
-
</div>
|
|
137
|
-
{/* Underlying input (blurred) */}
|
|
138
|
-
<ChatInput {...args} onAttach={() => {}} />
|
|
139
|
-
</div>
|
|
140
|
-
),
|
|
141
|
-
args: {},
|
|
142
|
-
}
|