@gram-ai/elements 1.27.4 → 1.27.6
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 +72 -60
- package/README.typedoc.md +6 -6
- package/bin/cli.js +74 -74
- package/dist/compat-shims-CO9JXXV4.cjs.map +1 -1
- package/dist/{compat-shims-BPJ7Q68c.js → compat-shims-DxtUrORi.js} +4 -2
- package/dist/compat-shims-DxtUrORi.js.map +1 -0
- package/dist/components/ShareButton/index.d.ts +2 -2
- package/dist/components/assistant-ui/message-feedback.d.ts +1 -1
- package/dist/components/assistant-ui/tooltip-icon-button.d.ts +2 -2
- package/dist/components/ui/avatar.d.ts +2 -2
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/calendar.d.ts +1 -1
- package/dist/components/ui/collapsible.d.ts +1 -1
- package/dist/components/ui/dialog.d.ts +4 -4
- package/dist/components/ui/popover.d.ts +2 -2
- package/dist/components/ui/skeleton.d.ts +1 -1
- package/dist/components/ui/time-range-picker.d.ts +1 -1
- package/dist/components/ui/tool-ui.d.ts +7 -7
- package/dist/components/ui/tooltip.d.ts +2 -2
- package/dist/contexts/ConnectionStatusContext.d.ts +1 -1
- package/dist/elements.cjs +1 -1
- package/dist/elements.css +1 -1
- package/dist/elements.js +2 -2
- package/dist/hooks/useDensity.d.ts +73 -73
- package/dist/hooks/useMCPTools.d.ts +1 -1
- package/dist/hooks/useRadius.d.ts +1 -1
- package/dist/{index-KSX4Qjip.cjs → index-A17b62wR.cjs} +10 -10
- package/dist/index-A17b62wR.cjs.map +1 -0
- package/dist/{index-BpJstUh1.cjs → index-C4bFBGfl.cjs} +4 -4
- package/dist/{index-BpJstUh1.cjs.map → index-C4bFBGfl.cjs.map} +1 -1
- package/dist/{index-CUitXazZ.js → index-D93pV0_o.js} +55 -55
- package/dist/{index-CUitXazZ.js.map → index-D93pV0_o.js.map} +1 -1
- package/dist/{index-D0bAYNQy.js → index-Dm2wLFTN.js} +304 -282
- package/dist/index-Dm2wLFTN.js.map +1 -0
- package/dist/lib/cassette.d.ts +4 -4
- package/dist/lib/errorTracking.d.ts +1 -1
- package/dist/lib/messageConverter.d.ts +1 -1
- package/dist/lib/models.d.ts +1 -1
- package/dist/plugins/chart/ui/bar-chart.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/accordion.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/action-button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/alert.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/avatar.d.ts +5 -5
- package/dist/plugins/generative-ui/ui/badge.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card.d.ts +8 -8
- package/dist/plugins/generative-ui/ui/checkbox.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/data-table.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/dialog.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/grid.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/input.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/label.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/metric.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/pagination.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/popover.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/progress.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/radio-group.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/select.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/separator.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/skeleton.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/stack.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/switch.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/table.d.ts +9 -9
- package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/tabs.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/text.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/textarea.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/tooltip.d.ts +1 -1
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.js +1 -1
- package/dist/{profiler-CyzxBxVz.cjs → profiler-Cbbf4eEX.cjs} +2 -2
- package/dist/{profiler-CyzxBxVz.cjs.map → profiler-Cbbf4eEX.cjs.map} +1 -1
- package/dist/{profiler-BFkhZRxj.js → profiler-mca4IXaY.js} +2 -2
- package/dist/{profiler-BFkhZRxj.js.map → profiler-mca4IXaY.js.map} +1 -1
- package/dist/react-shim.js +1 -1
- package/dist/server/express.cjs.map +1 -1
- package/dist/server/express.js.map +1 -1
- package/dist/{startRecording-C-PPAs_Z.js → startRecording-BCafdS7B.js} +2 -2
- package/dist/{startRecording-C-PPAs_Z.js.map → startRecording-BCafdS7B.js.map} +1 -1
- package/dist/{startRecording-Dq92sEHf.cjs → startRecording-Eb5f7wqP.cjs} +2 -2
- package/dist/{startRecording-Dq92sEHf.cjs.map → startRecording-Eb5f7wqP.cjs.map} +1 -1
- package/dist/types/index.d.ts +4 -4
- package/package.json +1 -5
- package/src/compat-plugin.ts +14 -14
- package/src/compat-shims.ts +33 -31
- package/src/compat.test.ts +48 -48
- package/src/compat.ts +6 -6
- package/src/components/Chat/index.tsx +17 -17
- package/src/components/Chat/stories/Charts.stories.tsx +98 -98
- package/src/components/Chat/stories/Composer.stories.tsx +15 -15
- package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +44 -44
- package/src/components/Chat/stories/CustomComponents.stories.tsx +17 -17
- package/src/components/Chat/stories/Density.stories.tsx +20 -20
- package/src/components/Chat/stories/ErrorBoundary.stories.tsx +47 -47
- package/src/components/Chat/stories/FrontendTools.stories.tsx +39 -39
- package/src/components/Chat/stories/GenerativeUI.stories.tsx +48 -48
- package/src/components/Chat/stories/MessageFeedback.stories.tsx +52 -52
- package/src/components/Chat/stories/Modal.stories.tsx +28 -28
- package/src/components/Chat/stories/Model.stories.tsx +11 -11
- package/src/components/Chat/stories/Radius.stories.tsx +20 -20
- package/src/components/Chat/stories/Sidecar.stories.tsx +13 -13
- package/src/components/Chat/stories/StyleIsolation.stories.tsx +11 -11
- package/src/components/Chat/stories/Theme.stories.tsx +25 -25
- package/src/components/Chat/stories/Thread.stories.tsx +25 -25
- package/src/components/Chat/stories/ToolApproval.stories.tsx +55 -55
- package/src/components/Chat/stories/ToolMentions.stories.tsx +17 -17
- package/src/components/Chat/stories/Tools.stories.tsx +88 -88
- package/src/components/Chat/stories/Variants.stories.tsx +32 -32
- package/src/components/Chat/stories/Welcome.stories.tsx +14 -14
- package/src/components/ChatHistory.tsx +7 -7
- package/src/components/FrontendTools/index.tsx +5 -5
- package/src/components/Replay.stories.tsx +157 -157
- package/src/components/Replay.tsx +76 -73
- package/src/components/ShadowRoot.tsx +40 -40
- package/src/components/ShareButton/index.tsx +32 -32
- package/src/components/assistant-ui/assistant-modal.tsx +92 -87
- package/src/components/assistant-ui/assistant-sidecar.tsx +35 -35
- package/src/components/assistant-ui/attachment.tsx +80 -80
- package/src/components/assistant-ui/connection-status-indicator.tsx +33 -33
- package/src/components/assistant-ui/error-boundary.tsx +34 -34
- package/src/components/assistant-ui/follow-on-suggestions.tsx +26 -26
- package/src/components/assistant-ui/markdown-text.tsx +69 -69
- package/src/components/assistant-ui/mentioned-tools-badges.tsx +38 -38
- package/src/components/assistant-ui/message-feedback.tsx +57 -50
- package/src/components/assistant-ui/reasoning.tsx +83 -83
- package/src/components/assistant-ui/thread-list.tsx +45 -45
- package/src/components/assistant-ui/thread.tsx +278 -278
- package/src/components/assistant-ui/tool-fallback.tsx +37 -37
- package/src/components/assistant-ui/tool-group.tsx +26 -26
- package/src/components/assistant-ui/tool-mention-autocomplete.tsx +122 -122
- package/src/components/assistant-ui/tooltip-icon-button.tsx +18 -18
- package/src/components/ui/avatar.tsx +12 -12
- package/src/components/ui/button.tsx +12 -12
- package/src/components/ui/buttonVariants.ts +17 -17
- package/src/components/ui/calendar.tsx +106 -106
- package/src/components/ui/charts.stories.tsx +56 -56
- package/src/components/ui/collapsible.tsx +5 -5
- package/src/components/ui/dialog.tsx +30 -30
- package/src/components/ui/generative-ui.stories.tsx +200 -200
- package/src/components/ui/generative-ui.tsx +26 -26
- package/src/components/ui/popover.tsx +14 -14
- package/src/components/ui/skeleton.tsx +5 -5
- package/src/components/ui/time-range-picker.stories.tsx +80 -80
- package/src/components/ui/time-range-picker.tsx +248 -246
- package/src/components/ui/tool-ui.stories.tsx +37 -37
- package/src/components/ui/tool-ui.tsx +221 -215
- package/src/components/ui/tooltip.tsx +15 -15
- package/src/constants/tailwind.ts +1 -1
- package/src/contexts/ChatIdContext.tsx +7 -7
- package/src/contexts/ConnectionStatusContext.tsx +64 -64
- package/src/contexts/ElementsProvider.tsx +214 -213
- package/src/contexts/ReplayContext.ts +3 -3
- package/src/contexts/ToolApprovalContext.tsx +54 -54
- package/src/contexts/ToolExecutionContext.tsx +34 -34
- package/src/contexts/contexts.ts +7 -7
- package/src/contexts/portal-container-context.ts +2 -2
- package/src/contexts/portal-container.tsx +7 -7
- package/src/embedded.ts +1 -1
- package/src/global.css +25 -25
- package/src/hooks/useAuth.ts +72 -72
- package/src/hooks/useDensity.ts +79 -79
- package/src/hooks/useElements.ts +6 -6
- package/src/hooks/useExpanded.ts +12 -12
- package/src/hooks/useFollowOnSuggestions.ts +83 -83
- package/src/hooks/useGramThreadListAdapter.tsx +99 -99
- package/src/hooks/useMCPTools.ts +47 -47
- package/src/hooks/useModel.ts +14 -14
- package/src/hooks/usePluginComponents.ts +11 -11
- package/src/hooks/usePortalContainer.ts +5 -5
- package/src/hooks/useRadius.ts +23 -23
- package/src/hooks/useRecordCassette.ts +34 -34
- package/src/hooks/useSession.ts +11 -11
- package/src/hooks/useThemeProps.ts +13 -13
- package/src/hooks/useThreadId.ts +4 -4
- package/src/hooks/useToolApproval.ts +7 -7
- package/src/hooks/useToolMentions.ts +40 -40
- package/src/index.ts +26 -26
- package/src/lib/api.test.ts +61 -61
- package/src/lib/api.ts +4 -3
- package/src/lib/auth.ts +13 -13
- package/src/lib/cassette.ts +84 -84
- package/src/lib/easing.ts +1 -1
- package/src/lib/errorTracking.config.ts +5 -5
- package/src/lib/errorTracking.ts +29 -29
- package/src/lib/generative-ui.ts +7 -7
- package/src/lib/humanize.ts +3 -3
- package/src/lib/messageConverter.test.ts +130 -127
- package/src/lib/messageConverter.ts +196 -196
- package/src/lib/models.ts +28 -20
- package/src/lib/token.test.ts +56 -56
- package/src/lib/token.ts +14 -14
- package/src/lib/tool-mentions.ts +45 -45
- package/src/lib/tools.ts +66 -62
- package/src/lib/utils.ts +5 -5
- package/src/lib.d.ts +1 -1
- package/src/plugins/README.md +5 -5
- package/src/plugins/chart/catalog.ts +18 -18
- package/src/plugins/chart/chart.test.ts +31 -31
- package/src/plugins/chart/component.tsx +34 -34
- package/src/plugins/chart/index.ts +4 -4
- package/src/plugins/chart/ui/area-chart.tsx +42 -42
- package/src/plugins/chart/ui/bar-chart.tsx +46 -46
- package/src/plugins/chart/ui/donut-chart.tsx +48 -48
- package/src/plugins/chart/ui/index.ts +7 -7
- package/src/plugins/chart/ui/line-chart.tsx +43 -43
- package/src/plugins/chart/ui/pie-chart.tsx +44 -44
- package/src/plugins/chart/ui/radar-chart.tsx +33 -33
- package/src/plugins/chart/ui/scatter-chart.tsx +43 -43
- package/src/plugins/components/MacOSWindowFrame.tsx +15 -15
- package/src/plugins/components/PluginLoadingState.tsx +10 -10
- package/src/plugins/components/index.ts +1 -1
- package/src/plugins/generative-ui/catalog.ts +54 -54
- package/src/plugins/generative-ui/component.tsx +85 -85
- package/src/plugins/generative-ui/index.ts +4 -4
- package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +16 -16
- package/src/plugins/generative-ui/ui/accordion.tsx +16 -16
- package/src/plugins/generative-ui/ui/action-button.tsx +28 -28
- package/src/plugins/generative-ui/ui/alert-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/alert.tsx +20 -20
- package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/avatar.tsx +30 -30
- package/src/plugins/generative-ui/ui/badge.tsx +22 -22
- package/src/plugins/generative-ui/ui/button-wrapper.tsx +12 -12
- package/src/plugins/generative-ui/ui/button.tsx +28 -28
- package/src/plugins/generative-ui/ui/card-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/card.tsx +27 -27
- package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +9 -9
- package/src/plugins/generative-ui/ui/checkbox.tsx +9 -9
- package/src/plugins/generative-ui/ui/data-table.tsx +8 -8
- package/src/plugins/generative-ui/ui/dialog.tsx +31 -31
- package/src/plugins/generative-ui/ui/dropdown-menu.tsx +44 -44
- package/src/plugins/generative-ui/ui/grid.tsx +12 -12
- package/src/plugins/generative-ui/ui/index.ts +40 -40
- package/src/plugins/generative-ui/ui/input-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/input.tsx +9 -9
- package/src/plugins/generative-ui/ui/label.tsx +8 -8
- package/src/plugins/generative-ui/ui/list.tsx +11 -11
- package/src/plugins/generative-ui/ui/metric.tsx +23 -23
- package/src/plugins/generative-ui/ui/pagination.tsx +28 -28
- package/src/plugins/generative-ui/ui/popover.tsx +21 -21
- package/src/plugins/generative-ui/ui/progress.tsx +13 -13
- package/src/plugins/generative-ui/ui/radio-group.tsx +12 -12
- package/src/plugins/generative-ui/ui/select-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/select.tsx +37 -37
- package/src/plugins/generative-ui/ui/separator.tsx +9 -9
- package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +10 -10
- package/src/plugins/generative-ui/ui/skeleton.tsx +5 -5
- package/src/plugins/generative-ui/ui/stack.tsx +28 -28
- package/src/plugins/generative-ui/ui/switch.tsx +11 -11
- package/src/plugins/generative-ui/ui/table.tsx +32 -32
- package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/tabs.tsx +26 -26
- package/src/plugins/generative-ui/ui/text.tsx +12 -12
- package/src/plugins/generative-ui/ui/textarea.tsx +7 -7
- package/src/plugins/generative-ui/ui/tooltip.tsx +12 -12
- package/src/plugins/index.ts +7 -7
- package/src/react-shim.ts +6 -6
- package/src/server/bun.ts +12 -12
- package/src/server/core.ts +25 -25
- package/src/server/express.ts +17 -15
- package/src/server/fastify.ts +14 -14
- package/src/server/hono.ts +9 -9
- package/src/server/nextjs.ts +12 -12
- package/src/server/tanstack-start.ts +12 -12
- package/src/server.ts +27 -27
- package/src/storybook.d.ts +4 -4
- package/src/types/index.ts +124 -124
- package/src/types/plugins.ts +7 -7
- package/src/vite-env.d.ts +12 -12
- package/dist/compat-shims-BPJ7Q68c.js.map +0 -1
- package/dist/index-D0bAYNQy.js.map +0 -1
- package/dist/index-KSX4Qjip.cjs.map +0 -1
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import { PropsWithChildren, useEffect, useState, type FC } from
|
|
4
|
-
import { XIcon, PlusIcon, FileText } from
|
|
3
|
+
import { PropsWithChildren, useEffect, useState, type FC } from "react";
|
|
4
|
+
import { XIcon, PlusIcon, FileText } from "lucide-react";
|
|
5
5
|
import {
|
|
6
6
|
AttachmentPrimitive,
|
|
7
7
|
ComposerPrimitive,
|
|
8
8
|
MessagePrimitive,
|
|
9
9
|
useAssistantState,
|
|
10
10
|
useAssistantApi,
|
|
11
|
-
} from
|
|
12
|
-
import { useShallow } from
|
|
11
|
+
} from "@assistant-ui/react";
|
|
12
|
+
import { useShallow } from "zustand/shallow";
|
|
13
13
|
import {
|
|
14
14
|
Tooltip,
|
|
15
15
|
TooltipContent,
|
|
16
16
|
TooltipTrigger,
|
|
17
|
-
} from
|
|
17
|
+
} from "@/components/ui/tooltip";
|
|
18
18
|
import {
|
|
19
19
|
Dialog,
|
|
20
20
|
DialogTitle,
|
|
21
21
|
DialogContent,
|
|
22
22
|
DialogTrigger,
|
|
23
|
-
} from
|
|
24
|
-
import { Avatar, AvatarImage, AvatarFallback } from
|
|
25
|
-
import { TooltipIconButton } from
|
|
26
|
-
import { cn } from
|
|
23
|
+
} from "@/components/ui/dialog";
|
|
24
|
+
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
|
25
|
+
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
26
|
+
import { cn } from "@/lib/utils";
|
|
27
27
|
|
|
28
28
|
const useFileSrc = (file: File | undefined) => {
|
|
29
|
-
const [src, setSrc] = useState<string | undefined>(undefined)
|
|
29
|
+
const [src, setSrc] = useState<string | undefined>(undefined);
|
|
30
30
|
|
|
31
31
|
useEffect(() => {
|
|
32
32
|
if (!file) {
|
|
33
|
-
setSrc(undefined)
|
|
34
|
-
return
|
|
33
|
+
setSrc(undefined);
|
|
34
|
+
return;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
const objectUrl = URL.createObjectURL(file)
|
|
38
|
-
setSrc(objectUrl)
|
|
37
|
+
const objectUrl = URL.createObjectURL(file);
|
|
38
|
+
setSrc(objectUrl);
|
|
39
39
|
|
|
40
40
|
return () => {
|
|
41
|
-
URL.revokeObjectURL(objectUrl)
|
|
42
|
-
}
|
|
43
|
-
}, [file])
|
|
41
|
+
URL.revokeObjectURL(objectUrl);
|
|
42
|
+
};
|
|
43
|
+
}, [file]);
|
|
44
44
|
|
|
45
|
-
return src
|
|
46
|
-
}
|
|
45
|
+
return src;
|
|
46
|
+
};
|
|
47
47
|
|
|
48
48
|
const useAttachmentSrc = () => {
|
|
49
49
|
const { file, src } = useAssistantState(
|
|
50
50
|
useShallow(({ attachment }): { file?: File; src?: string } => {
|
|
51
|
-
if (attachment.type !==
|
|
52
|
-
if (attachment.file) return { file: attachment.file }
|
|
53
|
-
const src = attachment.content?.filter((c) => c.type ===
|
|
54
|
-
?.image
|
|
55
|
-
if (!src) return {}
|
|
56
|
-
return { src }
|
|
57
|
-
})
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
return useFileSrc(file) ?? src
|
|
61
|
-
}
|
|
51
|
+
if (attachment.type !== "image") return {};
|
|
52
|
+
if (attachment.file) return { file: attachment.file };
|
|
53
|
+
const src = attachment.content?.filter((c) => c.type === "image")[0]
|
|
54
|
+
?.image;
|
|
55
|
+
if (!src) return {};
|
|
56
|
+
return { src };
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return useFileSrc(file) ?? src;
|
|
61
|
+
};
|
|
62
62
|
|
|
63
63
|
type AttachmentPreviewProps = {
|
|
64
|
-
src: string
|
|
65
|
-
}
|
|
64
|
+
src: string;
|
|
65
|
+
};
|
|
66
66
|
|
|
67
67
|
const AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {
|
|
68
|
-
const [isLoaded, setIsLoaded] = useState(false)
|
|
68
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
69
69
|
return (
|
|
70
70
|
<img
|
|
71
71
|
src={src}
|
|
72
72
|
alt="Image Preview"
|
|
73
73
|
className={
|
|
74
74
|
isLoaded
|
|
75
|
-
?
|
|
76
|
-
:
|
|
75
|
+
? "aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain"
|
|
76
|
+
: "aui-attachment-preview-image-loading hidden"
|
|
77
77
|
}
|
|
78
78
|
onLoad={() => setIsLoaded(true)}
|
|
79
79
|
/>
|
|
80
|
-
)
|
|
81
|
-
}
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
82
|
|
|
83
83
|
const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
|
|
84
|
-
const src = useAttachmentSrc()
|
|
84
|
+
const src = useAttachmentSrc();
|
|
85
85
|
|
|
86
|
-
if (!src) return children
|
|
86
|
+
if (!src) return children;
|
|
87
87
|
|
|
88
88
|
return (
|
|
89
89
|
<Dialog>
|
|
90
90
|
<DialogTrigger className="aui-attachment-preview-trigger" asChild>
|
|
91
91
|
{children}
|
|
92
92
|
</DialogTrigger>
|
|
93
|
-
<DialogContent className="aui-attachment-preview-dialog-content [&_svg]:text-background [&>button]:bg-foreground/60 [&>button]:
|
|
93
|
+
<DialogContent className="aui-attachment-preview-dialog-content p-2 sm:max-w-3xl [&_svg]:text-background [&>button]:rounded-full [&>button]:bg-foreground/60 [&>button]:p-1 [&>button]:opacity-100 [&>button]:!ring-0 [&>button]:hover:[&_svg]:text-destructive">
|
|
94
94
|
<DialogTitle className="aui-sr-only sr-only">
|
|
95
95
|
Image Attachment Preview
|
|
96
96
|
</DialogTitle>
|
|
97
|
-
<div className="aui-attachment-preview
|
|
97
|
+
<div className="aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background">
|
|
98
98
|
<AttachmentPreview src={src} />
|
|
99
99
|
</div>
|
|
100
100
|
</DialogContent>
|
|
101
101
|
</Dialog>
|
|
102
|
-
)
|
|
103
|
-
}
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
104
|
|
|
105
105
|
const AttachmentThumb: FC = () => {
|
|
106
106
|
const isImage = useAssistantState(
|
|
107
|
-
({ attachment }) => attachment.type ===
|
|
108
|
-
)
|
|
109
|
-
const src = useAttachmentSrc()
|
|
107
|
+
({ attachment }) => attachment.type === "image",
|
|
108
|
+
);
|
|
109
|
+
const src = useAttachmentSrc();
|
|
110
110
|
|
|
111
111
|
return (
|
|
112
112
|
<Avatar className="aui-attachment-tile-avatar h-full w-full rounded-none">
|
|
@@ -116,51 +116,51 @@ const AttachmentThumb: FC = () => {
|
|
|
116
116
|
className="aui-attachment-tile-image object-cover"
|
|
117
117
|
/>
|
|
118
118
|
<AvatarFallback delayMs={isImage ? 200 : 0}>
|
|
119
|
-
<FileText className="aui-attachment-tile-fallback-icon text-muted-foreground
|
|
119
|
+
<FileText className="aui-attachment-tile-fallback-icon size-8 text-muted-foreground" />
|
|
120
120
|
</AvatarFallback>
|
|
121
121
|
</Avatar>
|
|
122
|
-
)
|
|
123
|
-
}
|
|
122
|
+
);
|
|
123
|
+
};
|
|
124
124
|
|
|
125
125
|
const AttachmentUI: FC = () => {
|
|
126
|
-
const api = useAssistantApi()
|
|
127
|
-
const isComposer = api.attachment.source ===
|
|
126
|
+
const api = useAssistantApi();
|
|
127
|
+
const isComposer = api.attachment.source === "composer";
|
|
128
128
|
|
|
129
129
|
const isImage = useAssistantState(
|
|
130
|
-
({ attachment }) => attachment.type ===
|
|
131
|
-
)
|
|
130
|
+
({ attachment }) => attachment.type === "image",
|
|
131
|
+
);
|
|
132
132
|
const typeLabel = useAssistantState(({ attachment }) => {
|
|
133
|
-
const type = attachment.type
|
|
133
|
+
const type = attachment.type;
|
|
134
134
|
switch (type) {
|
|
135
|
-
case
|
|
136
|
-
return
|
|
137
|
-
case
|
|
138
|
-
return
|
|
139
|
-
case
|
|
140
|
-
return
|
|
135
|
+
case "image":
|
|
136
|
+
return "Image";
|
|
137
|
+
case "document":
|
|
138
|
+
return "Document";
|
|
139
|
+
case "file":
|
|
140
|
+
return "File";
|
|
141
141
|
default: {
|
|
142
|
-
const _exhaustiveCheck: never = type
|
|
143
|
-
throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`)
|
|
142
|
+
const _exhaustiveCheck: never = type;
|
|
143
|
+
throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
|
-
})
|
|
146
|
+
});
|
|
147
147
|
|
|
148
148
|
return (
|
|
149
149
|
<Tooltip>
|
|
150
150
|
<AttachmentPrimitive.Root
|
|
151
151
|
className={cn(
|
|
152
|
-
|
|
152
|
+
"aui-attachment-root relative",
|
|
153
153
|
isImage &&
|
|
154
|
-
|
|
154
|
+
"aui-attachment-root-composer only:[&>#attachment-tile]:size-24",
|
|
155
155
|
)}
|
|
156
156
|
>
|
|
157
157
|
<AttachmentPreviewDialog>
|
|
158
158
|
<TooltipTrigger asChild>
|
|
159
159
|
<div
|
|
160
160
|
className={cn(
|
|
161
|
-
|
|
161
|
+
"aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75",
|
|
162
162
|
isComposer &&
|
|
163
|
-
|
|
163
|
+
"aui-attachment-tile-composer border-foreground/20",
|
|
164
164
|
)}
|
|
165
165
|
role="button"
|
|
166
166
|
id="attachment-tile"
|
|
@@ -176,30 +176,30 @@ const AttachmentUI: FC = () => {
|
|
|
176
176
|
<AttachmentPrimitive.Name />
|
|
177
177
|
</TooltipContent>
|
|
178
178
|
</Tooltip>
|
|
179
|
-
)
|
|
180
|
-
}
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
181
|
|
|
182
182
|
const AttachmentRemove: FC = () => {
|
|
183
183
|
return (
|
|
184
184
|
<AttachmentPrimitive.Remove asChild>
|
|
185
185
|
<TooltipIconButton
|
|
186
186
|
tooltip="Remove file"
|
|
187
|
-
className="aui-attachment-tile-remove
|
|
187
|
+
className="aui-attachment-tile-remove absolute top-1.5 right-1.5 size-3.5 rounded-full bg-white text-muted-foreground opacity-100 shadow-sm hover:!bg-white [&_svg]:text-black hover:[&_svg]:text-destructive"
|
|
188
188
|
side="top"
|
|
189
189
|
>
|
|
190
190
|
<XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
|
|
191
191
|
</TooltipIconButton>
|
|
192
192
|
</AttachmentPrimitive.Remove>
|
|
193
|
-
)
|
|
194
|
-
}
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
195
|
|
|
196
196
|
export const UserMessageAttachments: FC = () => {
|
|
197
197
|
return (
|
|
198
198
|
<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">
|
|
199
199
|
<MessagePrimitive.Attachments components={{ Attachment: AttachmentUI }} />
|
|
200
200
|
</div>
|
|
201
|
-
)
|
|
202
|
-
}
|
|
201
|
+
);
|
|
202
|
+
};
|
|
203
203
|
|
|
204
204
|
export const ComposerAttachments: FC = () => {
|
|
205
205
|
return (
|
|
@@ -208,8 +208,8 @@ export const ComposerAttachments: FC = () => {
|
|
|
208
208
|
components={{ Attachment: AttachmentUI }}
|
|
209
209
|
/>
|
|
210
210
|
</div>
|
|
211
|
-
)
|
|
212
|
-
}
|
|
211
|
+
);
|
|
212
|
+
};
|
|
213
213
|
|
|
214
214
|
export const ComposerAddAttachment: FC = () => {
|
|
215
215
|
return (
|
|
@@ -220,11 +220,11 @@ export const ComposerAddAttachment: FC = () => {
|
|
|
220
220
|
variant="ghost"
|
|
221
221
|
size="icon"
|
|
222
222
|
align="start"
|
|
223
|
-
className="aui-composer-add-attachment hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30
|
|
223
|
+
className="aui-composer-add-attachment size-[34px] rounded-full p-1 text-xs font-semibold hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30"
|
|
224
224
|
aria-label="Add Attachment"
|
|
225
225
|
>
|
|
226
226
|
<PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
|
|
227
227
|
</TooltipIconButton>
|
|
228
228
|
</ComposerPrimitive.AddAttachment>
|
|
229
|
-
)
|
|
230
|
-
}
|
|
229
|
+
);
|
|
230
|
+
};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
useConnectionStatus,
|
|
5
5
|
useConnectionStatusOptional,
|
|
6
6
|
type ConnectionState,
|
|
7
|
-
} from
|
|
8
|
-
import { cn } from
|
|
9
|
-
import { Loader2Icon, WifiOffIcon } from
|
|
10
|
-
import { AnimatePresence, motion } from
|
|
11
|
-
import { FC } from
|
|
7
|
+
} from "@/contexts/ConnectionStatusContext";
|
|
8
|
+
import { cn } from "@/lib/utils";
|
|
9
|
+
import { Loader2Icon, WifiOffIcon } from "lucide-react";
|
|
10
|
+
import { AnimatePresence, motion } from "motion/react";
|
|
11
|
+
import { FC } from "react";
|
|
12
12
|
|
|
13
13
|
interface ConnectionStatusIndicatorProps {
|
|
14
|
-
className?: string
|
|
14
|
+
className?: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -21,9 +21,9 @@ interface ConnectionStatusIndicatorProps {
|
|
|
21
21
|
export const ConnectionStatusIndicator: FC<ConnectionStatusIndicatorProps> = ({
|
|
22
22
|
className,
|
|
23
23
|
}) => {
|
|
24
|
-
const { state, isOnline } = useConnectionStatus()
|
|
24
|
+
const { state, isOnline } = useConnectionStatus();
|
|
25
25
|
|
|
26
|
-
const shouldShow = state ===
|
|
26
|
+
const shouldShow = state === "reconnecting" || state === "disconnected";
|
|
27
27
|
|
|
28
28
|
return (
|
|
29
29
|
<AnimatePresence>
|
|
@@ -33,42 +33,42 @@ export const ConnectionStatusIndicator: FC<ConnectionStatusIndicatorProps> = ({
|
|
|
33
33
|
animate={{ opacity: 1, y: 0, scale: 1 }}
|
|
34
34
|
exit={{ opacity: 0, y: -20, scale: 0.95 }}
|
|
35
35
|
transition={{
|
|
36
|
-
type:
|
|
36
|
+
type: "spring",
|
|
37
37
|
stiffness: 500,
|
|
38
38
|
damping: 30,
|
|
39
39
|
}}
|
|
40
40
|
className={cn(
|
|
41
|
-
|
|
42
|
-
className
|
|
41
|
+
"pointer-events-none absolute top-4 right-0 left-0 z-50 flex justify-center",
|
|
42
|
+
className,
|
|
43
43
|
)}
|
|
44
44
|
>
|
|
45
45
|
<StatusPill state={state} isOnline={isOnline} />
|
|
46
46
|
</motion.div>
|
|
47
47
|
)}
|
|
48
48
|
</AnimatePresence>
|
|
49
|
-
)
|
|
50
|
-
}
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
51
|
|
|
52
52
|
const StatusPill: FC<{ state: ConnectionState; isOnline: boolean }> = ({
|
|
53
53
|
state,
|
|
54
54
|
isOnline,
|
|
55
55
|
}) => {
|
|
56
|
-
const isReconnecting = state ===
|
|
57
|
-
const isOffline = !isOnline
|
|
56
|
+
const isReconnecting = state === "reconnecting";
|
|
57
|
+
const isOffline = !isOnline;
|
|
58
58
|
|
|
59
59
|
// Show "Offline" when browser is offline, otherwise show connection state
|
|
60
|
-
const showOffline = isOffline && state ===
|
|
60
|
+
const showOffline = isOffline && state === "disconnected";
|
|
61
61
|
const showReconnecting =
|
|
62
|
-
isReconnecting || (isOffline && state !==
|
|
62
|
+
isReconnecting || (isOffline && state !== "connected");
|
|
63
63
|
|
|
64
64
|
return (
|
|
65
65
|
<div
|
|
66
66
|
className={cn(
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
"pointer-events-auto flex items-center gap-2 rounded-full px-4 py-2 shadow-lg backdrop-blur-md",
|
|
68
|
+
"border",
|
|
69
69
|
showOffline || showReconnecting
|
|
70
|
-
?
|
|
71
|
-
:
|
|
70
|
+
? "border-zinc-200 bg-white text-zinc-900 dark:border-zinc-700 dark:bg-zinc-900 dark:text-white"
|
|
71
|
+
: "border-red-200 bg-red-500/90 text-white dark:border-red-800 dark:bg-red-600/90",
|
|
72
72
|
)}
|
|
73
73
|
>
|
|
74
74
|
{showOffline ? (
|
|
@@ -88,8 +88,8 @@ const StatusPill: FC<{ state: ConnectionState; isOnline: boolean }> = ({
|
|
|
88
88
|
</>
|
|
89
89
|
)}
|
|
90
90
|
</div>
|
|
91
|
-
)
|
|
92
|
-
}
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
95
|
* Wrapper version that handles the case when ConnectionStatusProvider is not available.
|
|
@@ -99,15 +99,15 @@ const StatusPill: FC<{ state: ConnectionState; isOnline: boolean }> = ({
|
|
|
99
99
|
export const ConnectionStatusIndicatorSafe: FC<
|
|
100
100
|
ConnectionStatusIndicatorProps
|
|
101
101
|
> = ({ className }) => {
|
|
102
|
-
const connectionStatus = useConnectionStatusOptional()
|
|
102
|
+
const connectionStatus = useConnectionStatusOptional();
|
|
103
103
|
|
|
104
104
|
// Provider not available, render nothing
|
|
105
105
|
if (!connectionStatus) {
|
|
106
|
-
return null
|
|
106
|
+
return null;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
const { state, isOnline } = connectionStatus
|
|
110
|
-
const shouldShow = state ===
|
|
109
|
+
const { state, isOnline } = connectionStatus;
|
|
110
|
+
const shouldShow = state === "reconnecting" || state === "disconnected";
|
|
111
111
|
|
|
112
112
|
return (
|
|
113
113
|
<AnimatePresence>
|
|
@@ -117,18 +117,18 @@ export const ConnectionStatusIndicatorSafe: FC<
|
|
|
117
117
|
animate={{ opacity: 1, y: 0, scale: 1 }}
|
|
118
118
|
exit={{ opacity: 0, y: -20, scale: 0.95 }}
|
|
119
119
|
transition={{
|
|
120
|
-
type:
|
|
120
|
+
type: "spring",
|
|
121
121
|
stiffness: 500,
|
|
122
122
|
damping: 30,
|
|
123
123
|
}}
|
|
124
124
|
className={cn(
|
|
125
|
-
|
|
126
|
-
className
|
|
125
|
+
"pointer-events-none absolute top-4 right-0 left-0 z-50 flex justify-center",
|
|
126
|
+
className,
|
|
127
127
|
)}
|
|
128
128
|
>
|
|
129
129
|
<StatusPill state={state} isOnline={isOnline} />
|
|
130
130
|
</motion.div>
|
|
131
131
|
)}
|
|
132
132
|
</AnimatePresence>
|
|
133
|
-
)
|
|
134
|
-
}
|
|
133
|
+
);
|
|
134
|
+
};
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import { AlertCircle } from
|
|
4
|
-
import { Component, type ErrorInfo, type ReactNode } from
|
|
5
|
-
import { trackError } from
|
|
6
|
-
import { cn } from
|
|
7
|
-
import { Button } from
|
|
3
|
+
import { AlertCircle } from "lucide-react";
|
|
4
|
+
import { Component, type ErrorInfo, type ReactNode } from "react";
|
|
5
|
+
import { trackError } from "@/lib/errorTracking";
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
import { Button } from "../ui/button";
|
|
8
8
|
|
|
9
9
|
interface ErrorBoundaryProps {
|
|
10
|
-
children: ReactNode
|
|
11
|
-
fallback?: ReactNode
|
|
12
|
-
onError?: (error: Error, errorInfo: ErrorInfo) => void
|
|
13
|
-
onReset?: () => void
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
fallback?: ReactNode;
|
|
12
|
+
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
13
|
+
onReset?: () => void;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
interface ErrorBoundaryState {
|
|
17
|
-
hasError: boolean
|
|
18
|
-
error: Error | null
|
|
19
|
-
resetKey: number
|
|
17
|
+
hasError: boolean;
|
|
18
|
+
error: Error | null;
|
|
19
|
+
resetKey: number;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
interface ErrorFallbackProps {
|
|
23
|
-
error: Error | null
|
|
24
|
-
onRetry: () => void
|
|
23
|
+
error: Error | null;
|
|
24
|
+
onRetry: () => void;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// eslint-disable-next-line react-refresh/only-export-components
|
|
@@ -29,7 +29,7 @@ const ErrorFallback = ({ error, onRetry }: ErrorFallbackProps) => {
|
|
|
29
29
|
return (
|
|
30
30
|
<div
|
|
31
31
|
className={cn(
|
|
32
|
-
|
|
32
|
+
"aui-root aui-error-boundary flex h-full w-full flex-col items-center justify-center bg-background p-6",
|
|
33
33
|
)}
|
|
34
34
|
>
|
|
35
35
|
<div className="flex flex-col items-center gap-4 text-center">
|
|
@@ -37,14 +37,14 @@ const ErrorFallback = ({ error, onRetry }: ErrorFallbackProps) => {
|
|
|
37
37
|
<AlertCircle className="size-12 stroke-[1.5px]" />
|
|
38
38
|
</div>
|
|
39
39
|
<div className="flex flex-col gap-2">
|
|
40
|
-
<h3 className="text-
|
|
40
|
+
<h3 className="text-xl font-semibold text-foreground">
|
|
41
41
|
Something went wrong
|
|
42
42
|
</h3>
|
|
43
|
-
<p className="text-muted-foreground
|
|
43
|
+
<p className="text-base text-muted-foreground">
|
|
44
44
|
An error occurred while loading the chat.
|
|
45
45
|
</p>
|
|
46
46
|
{error && (
|
|
47
|
-
<p className="
|
|
47
|
+
<p className="max-w-md truncate text-sm text-muted-foreground/60">
|
|
48
48
|
{error.message}
|
|
49
49
|
</p>
|
|
50
50
|
)}
|
|
@@ -54,11 +54,11 @@ const ErrorFallback = ({ error, onRetry }: ErrorFallbackProps) => {
|
|
|
54
54
|
</Button>
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
57
|
-
)
|
|
58
|
-
}
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
59
|
|
|
60
60
|
// eslint-disable-next-line react-refresh/only-export-components
|
|
61
|
-
const Remounter = ({ children }: { children: ReactNode }) => <>{children}
|
|
61
|
+
const Remounter = ({ children }: { children: ReactNode }) => <>{children}</>;
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Global error boundary for the Elements library. Catches unexpected errors and renders a fallback UI.
|
|
@@ -73,21 +73,21 @@ export class ErrorBoundary extends Component<
|
|
|
73
73
|
ErrorBoundaryState
|
|
74
74
|
> {
|
|
75
75
|
constructor(props: ErrorBoundaryProps) {
|
|
76
|
-
super(props)
|
|
77
|
-
this.state = { hasError: false, error: null, resetKey: 0 }
|
|
76
|
+
super(props);
|
|
77
|
+
this.state = { hasError: false, error: null, resetKey: 0 };
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {
|
|
81
|
-
return { hasError: true, error }
|
|
81
|
+
return { hasError: true, error };
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
|
|
85
85
|
// Track error to Datadog RUM
|
|
86
86
|
trackError(error, {
|
|
87
|
-
source:
|
|
87
|
+
source: "error-boundary",
|
|
88
88
|
componentStack: errorInfo.componentStack ?? undefined,
|
|
89
|
-
})
|
|
90
|
-
this.props.onError?.(error, errorInfo)
|
|
89
|
+
});
|
|
90
|
+
this.props.onError?.(error, errorInfo);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
handleRetry = () => {
|
|
@@ -96,24 +96,24 @@ export class ErrorBoundary extends Component<
|
|
|
96
96
|
hasError: false,
|
|
97
97
|
error: null,
|
|
98
98
|
resetKey: state.resetKey + 1,
|
|
99
|
-
}))
|
|
100
|
-
this.props.onReset?.()
|
|
101
|
-
}
|
|
99
|
+
}));
|
|
100
|
+
this.props.onReset?.();
|
|
101
|
+
};
|
|
102
102
|
|
|
103
103
|
render(): ReactNode {
|
|
104
104
|
if (this.state.hasError) {
|
|
105
105
|
if (this.props.fallback) {
|
|
106
|
-
return this.props.fallback
|
|
106
|
+
return this.props.fallback;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
return (
|
|
110
110
|
<ErrorFallback error={this.state.error} onRetry={this.handleRetry} />
|
|
111
|
-
)
|
|
111
|
+
);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
// Use Remounter with key to force unmount/remount of children when retry is clicked
|
|
115
115
|
return (
|
|
116
116
|
<Remounter key={this.state.resetKey}>{this.props.children}</Remounter>
|
|
117
|
-
)
|
|
117
|
+
);
|
|
118
118
|
}
|
|
119
119
|
}
|