assistant-ui 0.0.120 → 0.0.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +1 -2
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/cloud.d.ts +25 -0
- package/dist/commands/cloud.d.ts.map +1 -0
- package/dist/commands/cloud.js +194 -0
- package/dist/commands/cloud.js.map +1 -0
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +10 -2
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/info.js +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +1 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +95 -23
- package/dist/commands/mcp.js.map +1 -1
- package/dist/lib/agent-skill.d.ts +2 -2
- package/dist/lib/agent-skill.d.ts.map +1 -1
- package/dist/lib/agent-skill.js +10 -28
- package/dist/lib/agent-skill.js.map +1 -1
- package/dist/lib/cloud-abort.d.ts +2 -0
- package/dist/lib/cloud-abort.d.ts.map +1 -0
- package/dist/lib/cloud-abort.js +13 -0
- package/dist/lib/cloud-abort.js.map +1 -0
- package/dist/lib/cloud-auth.d.ts +28 -0
- package/dist/lib/cloud-auth.d.ts.map +1 -0
- package/dist/lib/cloud-auth.js +169 -0
- package/dist/lib/cloud-auth.js.map +1 -0
- package/dist/lib/cloud-config.d.ts +21 -0
- package/dist/lib/cloud-config.d.ts.map +1 -0
- package/dist/lib/cloud-config.js +76 -0
- package/dist/lib/cloud-config.js.map +1 -0
- package/dist/lib/cloud-provision.d.ts +20 -0
- package/dist/lib/cloud-provision.d.ts.map +1 -0
- package/dist/lib/cloud-provision.js +55 -0
- package/dist/lib/cloud-provision.js.map +1 -0
- package/dist/lib/cloud-setup-login.d.ts +9 -0
- package/dist/lib/cloud-setup-login.d.ts.map +1 -0
- package/dist/lib/cloud-setup-login.js +137 -0
- package/dist/lib/cloud-setup-login.js.map +1 -0
- package/dist/lib/cloud-url.d.ts +2 -0
- package/dist/lib/cloud-url.d.ts.map +1 -0
- package/dist/lib/cloud-url.js +14 -0
- package/dist/lib/cloud-url.js.map +1 -0
- package/dist/lib/create-project.d.ts +0 -9
- package/dist/lib/create-project.d.ts.map +1 -1
- package/dist/lib/create-project.js +15 -46
- package/dist/lib/create-project.js.map +1 -1
- package/dist/lib/transform.d.ts +0 -4
- package/dist/lib/transform.d.ts.map +1 -1
- package/dist/lib/transform.js +8 -17
- package/dist/lib/transform.js.map +1 -1
- package/dist/lib/utils/download.d.ts +5 -0
- package/dist/lib/utils/download.d.ts.map +1 -0
- package/dist/lib/utils/download.js +41 -0
- package/dist/lib/utils/download.js.map +1 -0
- package/dist/lib/utils/file-scanner.d.ts +0 -1
- package/dist/lib/utils/file-scanner.d.ts.map +1 -1
- package/dist/lib/utils/file-scanner.js +1 -16
- package/dist/lib/utils/file-scanner.js.map +1 -1
- package/dist/lib/utils/package-manager.d.ts +7 -0
- package/dist/lib/utils/package-manager.d.ts.map +1 -1
- package/dist/lib/utils/package-manager.js +15 -1
- package/dist/lib/utils/package-manager.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +2 -1
- package/dist/program.js.map +1 -1
- package/package.json +12 -8
- package/src/commands/add.ts +2 -1
- package/src/commands/cloud.test.ts +238 -0
- package/src/commands/cloud.ts +455 -0
- package/src/commands/create.ts +13 -3
- package/src/commands/init.ts +5 -2
- package/src/commands/mcp.ts +223 -56
- package/src/lib/agent-skill.ts +18 -44
- package/src/lib/cloud-abort.ts +12 -0
- package/src/lib/cloud-auth.test.ts +500 -0
- package/src/lib/cloud-auth.ts +273 -0
- package/src/lib/cloud-config.test.ts +82 -0
- package/src/lib/cloud-config.ts +138 -0
- package/src/lib/cloud-provision.test.ts +132 -0
- package/src/lib/cloud-provision.ts +93 -0
- package/src/lib/cloud-setup-login.test.ts +361 -0
- package/src/lib/cloud-setup-login.ts +240 -0
- package/src/lib/cloud-url.ts +19 -0
- package/src/lib/create-project.test.ts +0 -17
- package/src/lib/create-project.ts +33 -98
- package/src/lib/transform-files.test.ts +1 -3
- package/src/lib/transform.ts +6 -20
- package/src/lib/utils/download.ts +57 -0
- package/src/lib/utils/file-scanner.ts +0 -26
- package/src/lib/utils/package-manager.ts +26 -0
- package/src/lib/utils/registry.test.ts +0 -6
- package/src/program.ts +2 -0
- package/templates/cloud-harness/.assistant-ui/template.json +3 -0
- package/templates/cloud-harness/.env.example +1 -0
- package/templates/cloud-harness/.gitignore +42 -0
- package/templates/cloud-harness/README.md +28 -0
- package/templates/cloud-harness/app/api/chat/route.ts +14 -0
- package/templates/cloud-harness/app/api/credential/route.ts +14 -0
- package/templates/cloud-harness/app/assistant.tsx +83 -0
- package/templates/cloud-harness/app/favicon.ico +0 -0
- package/templates/cloud-harness/app/globals.css +139 -0
- package/templates/cloud-harness/app/layout.tsx +37 -0
- package/templates/cloud-harness/app/page.tsx +5 -0
- package/templates/cloud-harness/components/assistant-ui/elements/attachment.aui.tsx +279 -0
- package/templates/cloud-harness/components/assistant-ui/elements/collapsible-root.tsx +19 -0
- package/templates/cloud-harness/components/assistant-ui/elements/markdown-text.tsx +238 -0
- package/templates/cloud-harness/components/assistant-ui/elements/thread.aui.tsx +521 -0
- package/templates/cloud-harness/components/assistant-ui/elements/tool-fallback.aui.tsx +1321 -0
- package/templates/cloud-harness/components/assistant-ui/elements/tooltip-icon-button.tsx +49 -0
- package/templates/cloud-harness/components/ui/avatar.tsx +109 -0
- package/templates/cloud-harness/components/ui/button.tsx +58 -0
- package/templates/cloud-harness/components/ui/collapsible.tsx +21 -0
- package/templates/cloud-harness/components/ui/dialog.tsx +159 -0
- package/templates/cloud-harness/components/ui/textarea.tsx +18 -0
- package/templates/cloud-harness/components/ui/tooltip.tsx +69 -0
- package/templates/cloud-harness/components.json +24 -0
- package/templates/cloud-harness/hooks/use-attachment-src.ts +46 -0
- package/templates/cloud-harness/hooks/use-copy-to-clipboard.ts +54 -0
- package/templates/cloud-harness/lib/utils.ts +1 -0
- package/templates/cloud-harness/next.config.ts +6 -0
- package/templates/cloud-harness/package.json +51 -0
- package/templates/cloud-harness/postcss.config.mjs +5 -0
- package/templates/cloud-harness/tsconfig.json +33 -0
- package/templates/cloud-harness/vendor/README.md +13 -0
- package/templates/cloud-harness/vendor/assistant-ui-react-harness-sdk-0.0.2.tgz +0 -0
- package/templates/cloud-harness/vendor/harness-sdk-0.3.1.tgz +0 -0
- package/templates/cloud-harness/vendor/provenance.json +38 -0
- package/templates/cloud-harness/vendor/statewire-0.19.3.tgz +0 -0
- /package/{LICENSE → templates/cloud-harness/vendor/LICENSE} +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "tw-animate-css";
|
|
3
|
+
@import "tw-shimmer";
|
|
4
|
+
|
|
5
|
+
@custom-variant data-open (&:where([data-state="open"], [data-open]:not([data-open="false"])));
|
|
6
|
+
@custom-variant data-closed (&:where([data-state="closed"], [data-closed]:not([data-closed="false"])));
|
|
7
|
+
|
|
8
|
+
@theme inline {
|
|
9
|
+
@keyframes collapsible-down {
|
|
10
|
+
from {
|
|
11
|
+
height: 0;
|
|
12
|
+
}
|
|
13
|
+
to {
|
|
14
|
+
height: var(
|
|
15
|
+
--radix-collapsible-content-height,
|
|
16
|
+
var(--collapsible-panel-height, auto)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
@keyframes collapsible-up {
|
|
21
|
+
from {
|
|
22
|
+
height: var(
|
|
23
|
+
--radix-collapsible-content-height,
|
|
24
|
+
var(--collapsible-panel-height, auto)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
to {
|
|
28
|
+
height: 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@custom-variant dark (&:is(.dark *));
|
|
34
|
+
|
|
35
|
+
@theme inline {
|
|
36
|
+
--color-background: var(--background);
|
|
37
|
+
--color-foreground: var(--foreground);
|
|
38
|
+
--font-sans: var(--font-inter);
|
|
39
|
+
--font-mono: var(--font-ibm-plex-mono);
|
|
40
|
+
--color-chart-5: var(--chart-5);
|
|
41
|
+
--color-chart-4: var(--chart-4);
|
|
42
|
+
--color-chart-3: var(--chart-3);
|
|
43
|
+
--color-chart-2: var(--chart-2);
|
|
44
|
+
--color-chart-1: var(--chart-1);
|
|
45
|
+
--color-ring: var(--ring);
|
|
46
|
+
--color-input: var(--input);
|
|
47
|
+
--color-border: var(--border);
|
|
48
|
+
--color-destructive: var(--destructive);
|
|
49
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
50
|
+
--color-accent: var(--accent);
|
|
51
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
52
|
+
--color-muted: var(--muted);
|
|
53
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
54
|
+
--color-secondary: var(--secondary);
|
|
55
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
56
|
+
--color-primary: var(--primary);
|
|
57
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
58
|
+
--color-popover: var(--popover);
|
|
59
|
+
--color-card-foreground: var(--card-foreground);
|
|
60
|
+
--color-card: var(--card);
|
|
61
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
62
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
63
|
+
--radius-lg: var(--radius);
|
|
64
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
65
|
+
--radius-2xl: calc(var(--radius) + 8px);
|
|
66
|
+
--radius-3xl: 1.5rem;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
:root {
|
|
70
|
+
--radius: 0.625rem;
|
|
71
|
+
--background: oklch(1 0 0);
|
|
72
|
+
--foreground: oklch(0.141 0.005 285.823);
|
|
73
|
+
--card: oklch(1 0 0);
|
|
74
|
+
--card-foreground: oklch(0.141 0.005 285.823);
|
|
75
|
+
--popover: oklch(1 0 0);
|
|
76
|
+
--popover-foreground: oklch(0.141 0.005 285.823);
|
|
77
|
+
--primary: oklch(0.21 0.006 285.885);
|
|
78
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
79
|
+
--secondary: oklch(0.967 0.001 286.375);
|
|
80
|
+
--secondary-foreground: oklch(0.21 0.006 285.885);
|
|
81
|
+
--muted: oklch(0.967 0.001 286.375);
|
|
82
|
+
--muted-foreground: oklch(0.552 0.016 285.938);
|
|
83
|
+
--accent: oklch(0.967 0.001 286.375);
|
|
84
|
+
--accent-foreground: oklch(0.21 0.006 285.885);
|
|
85
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
86
|
+
--border: oklch(0.92 0.004 286.32);
|
|
87
|
+
--input: oklch(0.92 0.004 286.32);
|
|
88
|
+
--ring: oklch(0.705 0.015 286.067);
|
|
89
|
+
--chart-1: oklch(0.646 0.222 41.116);
|
|
90
|
+
--chart-2: oklch(0.6 0.118 184.704);
|
|
91
|
+
--chart-3: oklch(0.398 0.07 227.392);
|
|
92
|
+
--chart-4: oklch(0.828 0.189 84.429);
|
|
93
|
+
--chart-5: oklch(0.769 0.188 70.08);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.dark {
|
|
97
|
+
--background: oklch(0.141 0.005 285.823);
|
|
98
|
+
--foreground: oklch(0.985 0 0);
|
|
99
|
+
--card: oklch(0.21 0.006 285.885);
|
|
100
|
+
--card-foreground: oklch(0.985 0 0);
|
|
101
|
+
--popover: oklch(0.21 0.006 285.885);
|
|
102
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
103
|
+
--primary: oklch(0.92 0.004 286.32);
|
|
104
|
+
--primary-foreground: oklch(0.21 0.006 285.885);
|
|
105
|
+
--secondary: oklch(0.274 0.006 286.033);
|
|
106
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
107
|
+
--muted: oklch(0.274 0.006 286.033);
|
|
108
|
+
--muted-foreground: oklch(0.705 0.015 286.067);
|
|
109
|
+
--accent: oklch(0.274 0.006 286.033);
|
|
110
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
111
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
112
|
+
--border: oklch(1 0 0 / 10%);
|
|
113
|
+
--input: oklch(1 0 0 / 15%);
|
|
114
|
+
--ring: oklch(0.552 0.016 285.938);
|
|
115
|
+
--chart-1: oklch(0.488 0.243 264.376);
|
|
116
|
+
--chart-2: oklch(0.696 0.17 162.48);
|
|
117
|
+
--chart-3: oklch(0.769 0.188 70.08);
|
|
118
|
+
--chart-4: oklch(0.627 0.265 303.9);
|
|
119
|
+
--chart-5: oklch(0.645 0.246 16.439);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@layer base {
|
|
123
|
+
* {
|
|
124
|
+
@apply border-border;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
:root {
|
|
128
|
+
color-scheme: light;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
:root.dark {
|
|
132
|
+
color-scheme: dark;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
body {
|
|
136
|
+
@apply bg-background text-foreground;
|
|
137
|
+
font-optical-sizing: auto;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { IBM_Plex_Mono, Inter } from "next/font/google";
|
|
3
|
+
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
4
|
+
import "./globals.css";
|
|
5
|
+
|
|
6
|
+
const inter = Inter({
|
|
7
|
+
variable: "--font-inter",
|
|
8
|
+
subsets: ["latin"],
|
|
9
|
+
axes: ["opsz"],
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const ibmPlexMono = IBM_Plex_Mono({
|
|
13
|
+
variable: "--font-ibm-plex-mono",
|
|
14
|
+
subsets: ["latin"],
|
|
15
|
+
weight: ["400", "500", "600"],
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const metadata: Metadata = {
|
|
19
|
+
title: "Shared cloud chat",
|
|
20
|
+
description: "Generated by create-assistant-ui",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const RootLayout = ({
|
|
24
|
+
children,
|
|
25
|
+
}: Readonly<{
|
|
26
|
+
children: React.ReactNode;
|
|
27
|
+
}>) => {
|
|
28
|
+
return (
|
|
29
|
+
<html lang="en" className="dark">
|
|
30
|
+
<body className={`${inter.variable} ${ibmPlexMono.variable} antialiased`}>
|
|
31
|
+
<TooltipProvider>{children}</TooltipProvider>
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default RootLayout;
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type PropsWithChildren,
|
|
5
|
+
useState,
|
|
6
|
+
type FC,
|
|
7
|
+
isValidElement,
|
|
8
|
+
} from "react";
|
|
9
|
+
import {
|
|
10
|
+
XIcon,
|
|
11
|
+
PlusIcon,
|
|
12
|
+
FileText,
|
|
13
|
+
Loader2Icon,
|
|
14
|
+
AlertCircleIcon,
|
|
15
|
+
} from "lucide-react";
|
|
16
|
+
import {
|
|
17
|
+
AttachmentPrimitive,
|
|
18
|
+
ComposerPrimitive,
|
|
19
|
+
MessagePrimitive,
|
|
20
|
+
useAuiState,
|
|
21
|
+
useAui,
|
|
22
|
+
} from "@assistant-ui/react";
|
|
23
|
+
import {
|
|
24
|
+
Tooltip,
|
|
25
|
+
TooltipContent,
|
|
26
|
+
TooltipProvider,
|
|
27
|
+
TooltipTrigger,
|
|
28
|
+
} from "@/components/ui/tooltip";
|
|
29
|
+
import {
|
|
30
|
+
Dialog,
|
|
31
|
+
DialogTitle,
|
|
32
|
+
DialogContent,
|
|
33
|
+
DialogTrigger,
|
|
34
|
+
} from "@/components/ui/dialog";
|
|
35
|
+
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
|
36
|
+
import { TooltipIconButton } from "@/components/assistant-ui/elements/tooltip-icon-button";
|
|
37
|
+
import { useAttachmentSrc } from "@/hooks/use-attachment-src";
|
|
38
|
+
import { cn } from "@/lib/utils";
|
|
39
|
+
|
|
40
|
+
type AttachmentPreviewProps = {
|
|
41
|
+
src: string;
|
|
42
|
+
name: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const AttachmentPreview: FC<AttachmentPreviewProps> = ({ src, name }) => {
|
|
46
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
47
|
+
return (
|
|
48
|
+
<img
|
|
49
|
+
src={src}
|
|
50
|
+
alt={`Preview of ${name}`}
|
|
51
|
+
className={cn(
|
|
52
|
+
"block h-auto max-h-[80vh] w-auto max-w-full rounded-sm object-contain transition-opacity duration-300 motion-reduce:transition-none",
|
|
53
|
+
isLoaded
|
|
54
|
+
? "aui-attachment-preview-image-loaded opacity-100"
|
|
55
|
+
: "aui-attachment-preview-image-loading opacity-0",
|
|
56
|
+
)}
|
|
57
|
+
onLoad={() => setIsLoaded(true)}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type AttachmentPreviewDialogProps = PropsWithChildren<{
|
|
63
|
+
src: string | undefined;
|
|
64
|
+
name: string;
|
|
65
|
+
}>;
|
|
66
|
+
|
|
67
|
+
const AttachmentPreviewDialog: FC<AttachmentPreviewDialogProps> = ({
|
|
68
|
+
children,
|
|
69
|
+
src,
|
|
70
|
+
name,
|
|
71
|
+
}) => {
|
|
72
|
+
if (!src) return children;
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<Dialog>
|
|
76
|
+
<DialogTrigger
|
|
77
|
+
nativeButton={false}
|
|
78
|
+
className="aui-attachment-preview-trigger cursor-zoom-in"
|
|
79
|
+
render={
|
|
80
|
+
isValidElement(children) ? (
|
|
81
|
+
children
|
|
82
|
+
) : (
|
|
83
|
+
<button type="button">{children}</button>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
/>
|
|
87
|
+
<DialogContent className="aui-attachment-preview-dialog-content [&>button]:bg-foreground/60 [&>button]:hover:bg-foreground/80 [&_svg]:text-background p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:p-1 [&>button]:opacity-100 [&>button]:ring-0!">
|
|
88
|
+
<DialogTitle className="aui-sr-only sr-only">
|
|
89
|
+
Preview {name}
|
|
90
|
+
</DialogTitle>
|
|
91
|
+
<div className="aui-attachment-preview bg-background relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden rounded-sm">
|
|
92
|
+
<AttachmentPreview src={src} name={name} />
|
|
93
|
+
</div>
|
|
94
|
+
</DialogContent>
|
|
95
|
+
</Dialog>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const AttachmentThumb: FC<{ src: string | undefined }> = ({ src }) => {
|
|
100
|
+
return (
|
|
101
|
+
<Avatar className="aui-attachment-tile-avatar h-full w-full rounded-none after:hidden">
|
|
102
|
+
<AvatarImage
|
|
103
|
+
src={src}
|
|
104
|
+
alt=""
|
|
105
|
+
className="aui-attachment-tile-image rounded-none object-cover"
|
|
106
|
+
/>
|
|
107
|
+
<AvatarFallback>
|
|
108
|
+
<FileText className="aui-attachment-tile-fallback-icon text-muted-foreground/80 size-6 stroke-[1.5]" />
|
|
109
|
+
</AvatarFallback>
|
|
110
|
+
</Avatar>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const AttachmentUI: FC = () => {
|
|
115
|
+
const aui = useAui();
|
|
116
|
+
const isComposer = aui.attachment.source !== "message";
|
|
117
|
+
const src = useAttachmentSrc();
|
|
118
|
+
|
|
119
|
+
const isImage = useAuiState((s) => s.attachment.type === "image");
|
|
120
|
+
const name = useAuiState((s) => s.attachment.name);
|
|
121
|
+
const typeLabel = useAuiState((s) => {
|
|
122
|
+
const type = s.attachment.type;
|
|
123
|
+
switch (type) {
|
|
124
|
+
case "image":
|
|
125
|
+
return "Image";
|
|
126
|
+
case "document":
|
|
127
|
+
return "Document";
|
|
128
|
+
case "file":
|
|
129
|
+
return "File";
|
|
130
|
+
default:
|
|
131
|
+
return type;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// An attachment on a submission is still being prepared, whether or not the
|
|
136
|
+
// adapter reports progress while it uploads.
|
|
137
|
+
const uploadState = useAuiState((s) =>
|
|
138
|
+
s.attachment.status.type === "incomplete" &&
|
|
139
|
+
s.attachment.status.reason === "error"
|
|
140
|
+
? "error"
|
|
141
|
+
: s.attachment.status.type === "running" ||
|
|
142
|
+
(s.optional.message?.submission !== undefined &&
|
|
143
|
+
s.attachment.status.type !== "complete")
|
|
144
|
+
? "uploading"
|
|
145
|
+
: undefined,
|
|
146
|
+
);
|
|
147
|
+
const isUploading = uploadState === "uploading";
|
|
148
|
+
const isError = uploadState === "error";
|
|
149
|
+
|
|
150
|
+
const errorMessage = useAuiState((s) =>
|
|
151
|
+
s.attachment.status.type === "incomplete" &&
|
|
152
|
+
s.attachment.status.reason === "error"
|
|
153
|
+
? (s.attachment.status.message ?? "Upload failed")
|
|
154
|
+
: undefined,
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<TooltipProvider>
|
|
159
|
+
<Tooltip>
|
|
160
|
+
<AttachmentPrimitive.Root
|
|
161
|
+
className={cn(
|
|
162
|
+
"aui-attachment-root relative",
|
|
163
|
+
isComposer &&
|
|
164
|
+
"animate-in fade-in-0 zoom-in-95 duration-200 motion-reduce:animate-none",
|
|
165
|
+
isImage &&
|
|
166
|
+
!isComposer &&
|
|
167
|
+
"aui-attachment-root-message only:*:first:size-24",
|
|
168
|
+
)}
|
|
169
|
+
>
|
|
170
|
+
<AttachmentPreviewDialog src={src} name={name}>
|
|
171
|
+
<TooltipTrigger
|
|
172
|
+
render={
|
|
173
|
+
<div
|
|
174
|
+
className={cn(
|
|
175
|
+
"aui-attachment-tile bg-muted hover:after:bg-foreground/10 focus-visible:ring-ring/50 relative size-14 overflow-hidden rounded-[calc(var(--composer-radius,1rem)-var(--composer-padding,8px))] transition-transform outline-none after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:ring-1 after:ring-black/10 after:transition-colors after:ring-inset focus-visible:ring-1 motion-reduce:transition-none dark:after:ring-white/10",
|
|
176
|
+
src
|
|
177
|
+
? "cursor-zoom-in active:scale-[0.96]"
|
|
178
|
+
: "cursor-default",
|
|
179
|
+
isError &&
|
|
180
|
+
"after:ring-destructive/60 dark:after:ring-destructive/60",
|
|
181
|
+
)}
|
|
182
|
+
role={src ? "button" : "group"}
|
|
183
|
+
tabIndex={0}
|
|
184
|
+
aria-label={`${src ? `Preview ${name}` : `${typeLabel} attachment ${name}`}${
|
|
185
|
+
isError
|
|
186
|
+
? ", upload failed"
|
|
187
|
+
: isUploading
|
|
188
|
+
? ", uploading"
|
|
189
|
+
: ""
|
|
190
|
+
}`}
|
|
191
|
+
/>
|
|
192
|
+
}
|
|
193
|
+
>
|
|
194
|
+
<AttachmentThumb src={src} />
|
|
195
|
+
{isUploading && (
|
|
196
|
+
<div
|
|
197
|
+
aria-hidden="true"
|
|
198
|
+
className="aui-attachment-tile-uploading bg-background/60 animate-in fade-in-0 absolute inset-0 flex items-center justify-center backdrop-blur-[2px] motion-reduce:animate-none"
|
|
199
|
+
>
|
|
200
|
+
<Loader2Icon className="text-muted-foreground size-4 animate-spin" />
|
|
201
|
+
</div>
|
|
202
|
+
)}
|
|
203
|
+
{isError && (
|
|
204
|
+
<div
|
|
205
|
+
aria-hidden="true"
|
|
206
|
+
className="aui-attachment-tile-error bg-background/70 animate-in fade-in-0 absolute inset-0 flex items-center justify-center backdrop-blur-[2px] motion-reduce:animate-none"
|
|
207
|
+
>
|
|
208
|
+
<AlertCircleIcon className="text-destructive size-4" />
|
|
209
|
+
</div>
|
|
210
|
+
)}
|
|
211
|
+
</TooltipTrigger>
|
|
212
|
+
</AttachmentPreviewDialog>
|
|
213
|
+
{isComposer && <AttachmentRemove name={name} />}
|
|
214
|
+
</AttachmentPrimitive.Root>
|
|
215
|
+
<TooltipContent side="top">
|
|
216
|
+
<AttachmentPrimitive.Name />
|
|
217
|
+
{errorMessage && (
|
|
218
|
+
<p className="aui-attachment-error-message">{errorMessage}</p>
|
|
219
|
+
)}
|
|
220
|
+
</TooltipContent>
|
|
221
|
+
</Tooltip>
|
|
222
|
+
</TooltipProvider>
|
|
223
|
+
);
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const AttachmentRemove: FC<{ name: string }> = ({ name }) => {
|
|
227
|
+
return (
|
|
228
|
+
<AttachmentPrimitive.Remove
|
|
229
|
+
render={
|
|
230
|
+
<TooltipIconButton
|
|
231
|
+
tooltip={`Remove ${name}`}
|
|
232
|
+
className="aui-attachment-tile-remove absolute end-1 top-1 size-5 rounded-full bg-black/50! text-white after:absolute after:-inset-1.5 hover:bg-black/70! hover:text-white! active:scale-[0.96] motion-reduce:transition-none"
|
|
233
|
+
side="top"
|
|
234
|
+
/>
|
|
235
|
+
}
|
|
236
|
+
>
|
|
237
|
+
<XIcon className="aui-attachment-remove-icon size-3 stroke-[2.5]" />
|
|
238
|
+
</AttachmentPrimitive.Remove>
|
|
239
|
+
);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
export const UserMessageAttachments: FC = () => {
|
|
243
|
+
return (
|
|
244
|
+
<div className="aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2 empty:hidden">
|
|
245
|
+
<MessagePrimitive.Attachments>
|
|
246
|
+
{() => <AttachmentUI />}
|
|
247
|
+
</MessagePrimitive.Attachments>
|
|
248
|
+
</div>
|
|
249
|
+
);
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
export const ComposerAttachments: FC = () => {
|
|
253
|
+
return (
|
|
254
|
+
<div className="aui-composer-attachments flex w-full flex-row items-center gap-2 overflow-x-auto empty:hidden">
|
|
255
|
+
<ComposerPrimitive.Attachments>
|
|
256
|
+
{() => <AttachmentUI />}
|
|
257
|
+
</ComposerPrimitive.Attachments>
|
|
258
|
+
</div>
|
|
259
|
+
);
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export const ComposerAddAttachment: FC = () => {
|
|
263
|
+
return (
|
|
264
|
+
<ComposerPrimitive.AddAttachment
|
|
265
|
+
render={
|
|
266
|
+
<TooltipIconButton
|
|
267
|
+
tooltip="Add Attachment"
|
|
268
|
+
side="bottom"
|
|
269
|
+
variant="ghost"
|
|
270
|
+
size="icon"
|
|
271
|
+
className="aui-composer-add-attachment text-muted-foreground hover:text-foreground hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30 size-7 rounded-full active:scale-[0.96] motion-reduce:transition-none"
|
|
272
|
+
aria-label="Add Attachment"
|
|
273
|
+
/>
|
|
274
|
+
}
|
|
275
|
+
>
|
|
276
|
+
<PlusIcon className="aui-attachment-add-icon size-4" />
|
|
277
|
+
</ComposerPrimitive.AddAttachment>
|
|
278
|
+
);
|
|
279
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Collapsible } from "@base-ui/react/collapsible";
|
|
4
|
+
import { forwardRef } from "react";
|
|
5
|
+
|
|
6
|
+
export const CollapsibleRoot = forwardRef<
|
|
7
|
+
React.ComponentRef<typeof Collapsible.Root>,
|
|
8
|
+
React.ComponentPropsWithoutRef<typeof Collapsible.Root>
|
|
9
|
+
>(function CollapsibleRoot(props, ref) {
|
|
10
|
+
return <Collapsible.Root ref={ref} data-slot="collapsible" {...props} />;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export function CollapsibleTrigger({ ...props }: Collapsible.Trigger.Props) {
|
|
14
|
+
return <Collapsible.Trigger data-slot="collapsible-trigger" {...props} />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function CollapsibleContent({ ...props }: Collapsible.Panel.Props) {
|
|
18
|
+
return <Collapsible.Panel data-slot="collapsible-content" {...props} />;
|
|
19
|
+
}
|