@gram-ai/elements 1.33.2 → 1.35.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/dist/compat-shims-CO9JXXV4.cjs.map +1 -1
- package/dist/compat-shims-DxtUrORi.js.map +1 -1
- package/dist/compat-shims.d.ts +9 -8
- package/dist/components/Chat/index.d.ts +2 -1
- package/dist/components/ChatHistory.d.ts +1 -1
- package/dist/components/FrontendTools/index.d.ts +1 -1
- package/dist/components/Replay.d.ts +1 -1
- package/dist/components/Replay.stories.d.ts +2 -2
- package/dist/components/ShadowRoot.d.ts +1 -1
- package/dist/components/ShareButton/index.d.ts +1 -1
- package/dist/components/ui/avatar.d.ts +3 -3
- package/dist/components/ui/button.d.ts +2 -2
- package/dist/components/ui/buttonVariants.d.ts +2 -2
- package/dist/components/ui/calendar.d.ts +2 -1
- package/dist/components/ui/collapsible.d.ts +3 -3
- package/dist/components/ui/dialog.d.ts +10 -10
- package/dist/components/ui/popover.d.ts +4 -4
- package/dist/components/ui/skeleton.d.ts +1 -1
- package/dist/components/ui/time-range-picker.d.ts +18 -1
- package/dist/components/ui/time-range-picker.test.d.ts +1 -0
- package/dist/components/ui/tool-ui.d.ts +7 -7
- package/dist/components/ui/tooltip.d.ts +4 -4
- package/dist/contexts/ConnectionStatusContext.d.ts +1 -1
- package/dist/contexts/ElementsProvider.d.ts +1 -1
- package/dist/contexts/ToolApprovalContext.d.ts +2 -2
- package/dist/contexts/ToolExecutionContext.d.ts +1 -1
- package/dist/contexts/portal-container.d.ts +1 -1
- package/dist/elements.cjs +1 -1
- package/dist/elements.css +1 -1
- package/dist/elements.js +19 -16
- package/dist/hooks/useDensity.d.ts +1 -1
- package/dist/hooks/useElements.d.ts +2 -1
- package/dist/hooks/useGramThreadListAdapter.d.ts +26 -0
- package/dist/hooks/useRadius.d.ts +1 -1
- package/dist/hooks/useThemeProps.d.ts +1 -1
- package/dist/hooks/useToolApproval.d.ts +2 -1
- package/dist/{index-reVrRxP1.js → index-BhIowiZF.js} +9744 -9493
- package/dist/index-BhIowiZF.js.map +1 -0
- package/dist/{index-DAWGW1Nj.cjs → index-D0jIGQr7.cjs} +43 -43
- package/dist/index-D0jIGQr7.cjs.map +1 -0
- package/dist/{index-CGoLfO5p.js → index-Dz13dSDa.js} +108 -51
- package/dist/index-Dz13dSDa.js.map +1 -0
- package/dist/index-PXd3rs95.cjs +194 -0
- package/dist/index-PXd3rs95.cjs.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/lib/errorTracking.d.ts +1 -1
- package/dist/lib/messageConverter.d.ts +58 -8
- package/dist/lib/models.d.ts +1 -1
- package/dist/lib/tools.d.ts +11 -10
- package/dist/lib/utils.d.ts +2 -0
- package/dist/plugins/generative-ui/catalog.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/accordion.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/action-button.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +2 -1
- package/dist/plugins/generative-ui/ui/alert.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/avatar-wrapper.d.ts +2 -1
- package/dist/plugins/generative-ui/ui/avatar.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/badge.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +2 -1
- package/dist/plugins/generative-ui/ui/button.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/card.d.ts +7 -7
- package/dist/plugins/generative-ui/ui/checkbox-wrapper.d.ts +2 -1
- package/dist/plugins/generative-ui/ui/checkbox.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/data-table.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/dialog.d.ts +10 -10
- package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +15 -15
- package/dist/plugins/generative-ui/ui/grid.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/index.d.ts +57 -40
- package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +2 -1
- package/dist/plugins/generative-ui/ui/input.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/label.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/list.d.ts +2 -1
- package/dist/plugins/generative-ui/ui/metric.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/pagination.d.ts +7 -7
- package/dist/plugins/generative-ui/ui/popover.d.ts +7 -7
- package/dist/plugins/generative-ui/ui/progress.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/radio-group.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/select-wrapper.d.ts +2 -1
- package/dist/plugins/generative-ui/ui/select.d.ts +10 -10
- package/dist/plugins/generative-ui/ui/separator.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/skeleton-wrapper.d.ts +2 -1
- package/dist/plugins/generative-ui/ui/skeleton.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/stack.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/switch.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/table.d.ts +8 -8
- package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/tabs.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/text.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/textarea.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/tooltip.d.ts +4 -4
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.js +1 -1
- package/dist/{profiler-noho3NG9.js → profiler-CtGKTWWP.js} +2 -2
- package/dist/{profiler-noho3NG9.js.map → profiler-CtGKTWWP.js.map} +1 -1
- package/dist/{profiler-B3tfiOx4.cjs → profiler-l7_HjTyw.cjs} +2 -2
- package/dist/{profiler-B3tfiOx4.cjs.map → profiler-l7_HjTyw.cjs.map} +1 -1
- package/dist/react-shim.cjs.map +1 -1
- package/dist/react-shim.d.ts +1 -1
- package/dist/react-shim.js +1 -4
- package/dist/react-shim.js.map +1 -1
- package/dist/server/bun.cjs.map +1 -1
- package/dist/server/bun.js.map +1 -1
- package/dist/server/express.cjs.map +1 -1
- package/dist/server/express.js.map +1 -1
- package/dist/server/fastify.cjs.map +1 -1
- package/dist/server/fastify.js.map +1 -1
- package/dist/server/hono.cjs.map +1 -1
- package/dist/server/hono.js.map +1 -1
- package/dist/server/nextjs.cjs.map +1 -1
- package/dist/server/nextjs.js.map +1 -1
- package/dist/server/tanstack-start.cjs.map +1 -1
- package/dist/server/tanstack-start.js.map +1 -1
- package/dist/{startRecording-7Oy6wM18.cjs → startRecording-DEw2Aeq4.cjs} +2 -2
- package/dist/{startRecording-7Oy6wM18.cjs.map → startRecording-DEw2Aeq4.cjs.map} +1 -1
- package/dist/{startRecording-mkmig-2n.js → startRecording-iYEL0-vr.js} +2 -2
- package/dist/{startRecording-mkmig-2n.js.map → startRecording-iYEL0-vr.js.map} +1 -1
- package/dist/types/index.d.ts +93 -4
- package/package.json +8 -9
- package/src/compat-shims.ts +16 -2
- package/src/components/Chat/index.tsx +4 -1
- package/src/components/Chat/stories/FrontendTools.stories.tsx +1 -1
- package/src/components/Chat/stories/ToolApproval.stories.tsx +2 -2
- package/src/components/Chat/stories/Tools.stories.tsx +13 -5
- package/src/components/ChatHistory.tsx +3 -1
- package/src/components/FrontendTools/index.tsx +1 -1
- package/src/components/MessageContent.tsx +1 -0
- package/src/components/Replay.stories.tsx +2 -3
- package/src/components/Replay.tsx +17 -10
- package/src/components/ShadowRoot.tsx +2 -2
- package/src/components/ShareButton/index.tsx +4 -2
- package/src/components/assistant-ui/assistant-modal.tsx +5 -3
- package/src/components/assistant-ui/attachment.tsx +1 -1
- package/src/components/assistant-ui/error-boundary.tsx +1 -1
- package/src/components/assistant-ui/markdown-text.tsx +1 -1
- package/src/components/assistant-ui/thread.tsx +256 -14
- package/src/components/assistant-ui/tool-mention-autocomplete.tsx +1 -1
- package/src/components/ui/avatar.tsx +3 -3
- package/src/components/ui/calendar.tsx +1 -1
- package/src/components/ui/collapsible.tsx +7 -3
- package/src/components/ui/dialog.tsx +18 -10
- package/src/components/ui/generative-ui.tsx +9 -4
- package/src/components/ui/popover.tsx +4 -4
- package/src/components/ui/skeleton.tsx +4 -1
- package/src/components/ui/time-range-picker.stories.tsx +164 -154
- package/src/components/ui/time-range-picker.test.ts +57 -0
- package/src/components/ui/time-range-picker.tsx +40 -9
- package/src/components/ui/tool-ui.tsx +18 -9
- package/src/components/ui/tooltip.tsx +4 -4
- package/src/contexts/ChatIdContext.tsx +1 -1
- package/src/contexts/ConnectionStatusContext.tsx +6 -5
- package/src/contexts/ElementsProvider.tsx +109 -37
- package/src/contexts/ReplayContext.ts +1 -1
- package/src/contexts/ToolApprovalContext.tsx +5 -1
- package/src/contexts/ToolExecutionContext.tsx +1 -1
- package/src/contexts/portal-container.tsx +1 -1
- package/src/hooks/useAuth.ts +2 -1
- package/src/hooks/useDensity.ts +1 -1
- package/src/hooks/useElements.ts +2 -1
- package/src/hooks/useFollowOnSuggestions.ts +3 -6
- package/src/hooks/useGramThreadListAdapter.tsx +118 -9
- package/src/hooks/useMCPTools.ts +2 -2
- package/src/hooks/useModel.ts +1 -3
- package/src/hooks/usePluginComponents.ts +3 -1
- package/src/hooks/useRadius.ts +1 -1
- package/src/hooks/useSession.ts +3 -1
- package/src/hooks/useThemeProps.ts +5 -5
- package/src/hooks/useToolApproval.ts +2 -1
- package/src/index.ts +16 -0
- package/src/lib/cassette.ts +21 -27
- package/src/lib/contextCompaction.test.ts +2 -2
- package/src/lib/contextCompaction.ts +20 -8
- package/src/lib/errorTracking.ts +1 -4
- package/src/lib/messageConverter.test.ts +11 -13
- package/src/lib/messageConverter.ts +105 -58
- package/src/lib/models.ts +19 -7
- package/src/lib/token.ts +2 -5
- package/src/lib/tool-mentions.ts +5 -2
- package/src/lib/tools.byte-cap.test.ts +1 -1
- package/src/lib/tools.test.ts +1 -1
- package/src/lib/tools.ts +15 -5
- package/src/lib/utils.ts +22 -2
- package/src/lib.d.ts +8 -1
- package/src/plugins/chart/chart.test.ts +3 -4
- package/src/plugins/chart/component.tsx +7 -6
- package/src/plugins/chart/ui/area-chart.tsx +1 -1
- package/src/plugins/chart/ui/line-chart.tsx +1 -1
- package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +2 -2
- package/src/plugins/generative-ui/ui/accordion.tsx +4 -4
- package/src/plugins/generative-ui/ui/action-button.tsx +4 -2
- package/src/plugins/generative-ui/ui/alert-wrapper.tsx +1 -1
- package/src/plugins/generative-ui/ui/alert.tsx +7 -3
- package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +5 -1
- package/src/plugins/generative-ui/ui/avatar.tsx +12 -6
- package/src/plugins/generative-ui/ui/badge.tsx +1 -1
- package/src/plugins/generative-ui/ui/button-wrapper.tsx +1 -1
- package/src/plugins/generative-ui/ui/button.tsx +1 -1
- package/src/plugins/generative-ui/ui/card-wrapper.tsx +1 -1
- package/src/plugins/generative-ui/ui/card.tsx +28 -7
- package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +1 -1
- package/src/plugins/generative-ui/ui/checkbox.tsx +1 -1
- package/src/plugins/generative-ui/ui/data-table.tsx +1 -1
- package/src/plugins/generative-ui/ui/dialog.tsx +15 -10
- package/src/plugins/generative-ui/ui/dropdown-menu.tsx +33 -15
- package/src/plugins/generative-ui/ui/grid.tsx +1 -1
- package/src/plugins/generative-ui/ui/index.ts +154 -40
- package/src/plugins/generative-ui/ui/input-wrapper.tsx +1 -1
- package/src/plugins/generative-ui/ui/input.tsx +5 -1
- package/src/plugins/generative-ui/ui/label.tsx +1 -1
- package/src/plugins/generative-ui/ui/list.tsx +5 -1
- package/src/plugins/generative-ui/ui/metric.tsx +2 -1
- package/src/plugins/generative-ui/ui/pagination.tsx +12 -7
- package/src/plugins/generative-ui/ui/popover.tsx +13 -7
- package/src/plugins/generative-ui/ui/progress.tsx +1 -1
- package/src/plugins/generative-ui/ui/radio-group.tsx +2 -2
- package/src/plugins/generative-ui/ui/select-wrapper.tsx +1 -1
- package/src/plugins/generative-ui/ui/select.tsx +14 -10
- package/src/plugins/generative-ui/ui/separator.tsx +1 -1
- package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +1 -1
- package/src/plugins/generative-ui/ui/skeleton.tsx +4 -1
- package/src/plugins/generative-ui/ui/stack.tsx +1 -1
- package/src/plugins/generative-ui/ui/switch.tsx +1 -1
- package/src/plugins/generative-ui/ui/table.tsx +29 -8
- package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +5 -2
- package/src/plugins/generative-ui/ui/tabs.tsx +4 -4
- package/src/plugins/generative-ui/ui/text.tsx +1 -1
- package/src/plugins/generative-ui/ui/textarea.tsx +4 -1
- package/src/plugins/generative-ui/ui/tooltip.tsx +4 -4
- package/src/react-shim.ts +9 -4
- package/src/server/bun.ts +1 -1
- package/src/server/express.ts +1 -1
- package/src/server/fastify.ts +1 -1
- package/src/server/hono.ts +1 -1
- package/src/server/nextjs.ts +1 -1
- package/src/server/tanstack-start.ts +1 -1
- package/src/storybook.d.ts +5 -0
- package/src/types/index.ts +112 -4
- package/dist/index-BCV7Zf9E.cjs +0 -194
- package/dist/index-BCV7Zf9E.cjs.map +0 -1
- package/dist/index-CGoLfO5p.js.map +0 -1
- package/dist/index-DAWGW1Nj.cjs.map +0 -1
- package/dist/index-reVrRxP1.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ArrowDownIcon,
|
|
3
3
|
ArrowUpIcon,
|
|
4
|
+
AtSign,
|
|
4
5
|
CheckIcon,
|
|
5
6
|
ChevronLeftIcon,
|
|
6
7
|
ChevronRightIcon,
|
|
@@ -8,8 +9,10 @@ import {
|
|
|
8
9
|
CopyIcon,
|
|
9
10
|
DownloadIcon,
|
|
10
11
|
PencilIcon,
|
|
12
|
+
Search,
|
|
11
13
|
Settings2,
|
|
12
14
|
Square,
|
|
15
|
+
Wrench,
|
|
13
16
|
} from "lucide-react";
|
|
14
17
|
|
|
15
18
|
import {
|
|
@@ -20,6 +23,7 @@ import {
|
|
|
20
23
|
ImageMessagePartProps,
|
|
21
24
|
MessagePrimitive,
|
|
22
25
|
ThreadPrimitive,
|
|
26
|
+
useAssistantApi,
|
|
23
27
|
useAssistantState,
|
|
24
28
|
} from "@assistant-ui/react";
|
|
25
29
|
|
|
@@ -68,6 +72,10 @@ import { useToolMentions } from "@/hooks/useToolMentions";
|
|
|
68
72
|
import { getApiUrl } from "@/lib/api";
|
|
69
73
|
import { EASE_OUT_QUINT } from "@/lib/easing";
|
|
70
74
|
import { MODELS } from "@/lib/models";
|
|
75
|
+
import {
|
|
76
|
+
type MentionableTool,
|
|
77
|
+
toolSetToMentionableTools,
|
|
78
|
+
} from "@/lib/tool-mentions";
|
|
71
79
|
import { cn } from "@/lib/utils";
|
|
72
80
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
|
73
81
|
import {
|
|
@@ -262,7 +270,7 @@ const ThreadScrollToBottom: FC = () => {
|
|
|
262
270
|
const ThreadWelcome: FC = () => {
|
|
263
271
|
const { config } = useElements();
|
|
264
272
|
const d = useDensity();
|
|
265
|
-
const { title, subtitle } = config.welcome ?? {};
|
|
273
|
+
const { logo, title, subtitle } = config.welcome ?? {};
|
|
266
274
|
const isStandalone = config.variant === "standalone";
|
|
267
275
|
|
|
268
276
|
return (
|
|
@@ -288,6 +296,19 @@ const ThreadWelcome: FC = () => {
|
|
|
288
296
|
!isStandalone && d("py-md"),
|
|
289
297
|
)}
|
|
290
298
|
>
|
|
299
|
+
{logo && (
|
|
300
|
+
<m.img
|
|
301
|
+
src={logo}
|
|
302
|
+
alt=""
|
|
303
|
+
initial={{ opacity: 0, y: 10 }}
|
|
304
|
+
animate={{ opacity: 1, y: 0 }}
|
|
305
|
+
exit={{ opacity: 0, y: 10 }}
|
|
306
|
+
transition={{ duration: 0.25, ease: EASE_OUT_QUINT }}
|
|
307
|
+
className={cn(
|
|
308
|
+
"aui-thread-welcome-logo mb-2 size-12 object-contain",
|
|
309
|
+
)}
|
|
310
|
+
/>
|
|
311
|
+
)}
|
|
291
312
|
<m.div
|
|
292
313
|
initial={{ opacity: 0, y: 10 }}
|
|
293
314
|
animate={{ opacity: 1, y: 0 }}
|
|
@@ -524,7 +545,9 @@ const ComposerFeedback: FC = () => {
|
|
|
524
545
|
<MessageFeedback
|
|
525
546
|
className="mx-auto"
|
|
526
547
|
onResolved={setResolved}
|
|
527
|
-
onFeedback={
|
|
548
|
+
onFeedback={(type) => {
|
|
549
|
+
void handleFeedback(type);
|
|
550
|
+
}}
|
|
528
551
|
/>
|
|
529
552
|
</m.div>
|
|
530
553
|
)}
|
|
@@ -794,6 +817,218 @@ const ComposerCassetteRecorder: FC = () => {
|
|
|
794
817
|
);
|
|
795
818
|
};
|
|
796
819
|
|
|
820
|
+
// Sentinel for the "All" pseudo-category in the tool-mention picker.
|
|
821
|
+
const TOOL_MENTION_ALL_CATEGORY = "__all__";
|
|
822
|
+
|
|
823
|
+
function humanizeToolCategory(raw: string): string {
|
|
824
|
+
const cleaned = raw.replace(/[-_]+/g, " ").trim();
|
|
825
|
+
if (!cleaned) return "Tools";
|
|
826
|
+
return cleaned.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// Derive a grouping label for a tool. Tools from multiple MCP servers are
|
|
830
|
+
// namespaced as `<server>__<tool>`; otherwise group by the first
|
|
831
|
+
// underscore-delimited segment (e.g. `platform_search_logs` -> "Platform"),
|
|
832
|
+
// falling back to a single "Tools" bucket.
|
|
833
|
+
function deriveToolCategory(name: string): string {
|
|
834
|
+
const namespaceIdx = name.indexOf("__");
|
|
835
|
+
if (namespaceIdx > 0)
|
|
836
|
+
return humanizeToolCategory(name.slice(0, namespaceIdx));
|
|
837
|
+
const underscoreIdx = name.indexOf("_");
|
|
838
|
+
if (underscoreIdx > 0)
|
|
839
|
+
return humanizeToolCategory(name.slice(0, underscoreIdx));
|
|
840
|
+
return "Tools";
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
interface ToolCategory {
|
|
844
|
+
name: string;
|
|
845
|
+
tools: MentionableTool[];
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// A discoverable counterpart to the type-`@` autocomplete: a composer button
|
|
849
|
+
// that opens a searchable, category-grouped picker of the available tools and
|
|
850
|
+
// inserts an @mention for the chosen one. Inserts through the composer runtime
|
|
851
|
+
// so it stays in sync with the autocomplete's own textarea handling. Hidden when
|
|
852
|
+
// tool mentions are disabled or there are no tools.
|
|
853
|
+
const ComposerToolMentionPicker: FC = () => {
|
|
854
|
+
const { config, mcpTools, mcpToolsLoading } = useElements();
|
|
855
|
+
const api = useAssistantApi();
|
|
856
|
+
// Read the composer text from the same reactive source the tool-mention
|
|
857
|
+
// badges parse, so an inserted mention renders a pill just like the type-`@`
|
|
858
|
+
// autocomplete does.
|
|
859
|
+
const composerText = useAssistantState(({ composer }) => composer.text);
|
|
860
|
+
const [open, setOpen] = useState(false);
|
|
861
|
+
const [query, setQuery] = useState("");
|
|
862
|
+
const [activeCategory, setActiveCategory] = useState(
|
|
863
|
+
TOOL_MENTION_ALL_CATEGORY,
|
|
864
|
+
);
|
|
865
|
+
|
|
866
|
+
const composerConfig = config.composer;
|
|
867
|
+
const toolMentionsEnabled =
|
|
868
|
+
composerConfig?.toolMentions === undefined ||
|
|
869
|
+
composerConfig.toolMentions === true ||
|
|
870
|
+
(typeof composerConfig.toolMentions === "object" &&
|
|
871
|
+
composerConfig.toolMentions.enabled !== false);
|
|
872
|
+
|
|
873
|
+
const tools = useMemo(() => toolSetToMentionableTools(mcpTools), [mcpTools]);
|
|
874
|
+
|
|
875
|
+
const categories = useMemo<ToolCategory[]>(() => {
|
|
876
|
+
const grouped = new Map<string, MentionableTool[]>();
|
|
877
|
+
for (const tool of tools) {
|
|
878
|
+
const category = deriveToolCategory(tool.name);
|
|
879
|
+
const existing = grouped.get(category);
|
|
880
|
+
if (existing) {
|
|
881
|
+
existing.push(tool);
|
|
882
|
+
} else {
|
|
883
|
+
grouped.set(category, [tool]);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
return [...grouped.entries()]
|
|
887
|
+
.map(([name, categoryTools]) => ({ name, tools: categoryTools }))
|
|
888
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
889
|
+
}, [tools]);
|
|
890
|
+
|
|
891
|
+
// Show the button while tools are still loading (so it appears immediately
|
|
892
|
+
// rather than popping in once the async MCP list resolves) or once there are
|
|
893
|
+
// tools — but hide it when the list has loaded and is empty, so we don't
|
|
894
|
+
// expose a dead-end control.
|
|
895
|
+
if (!toolMentionsEnabled || (!mcpToolsLoading && tools.length === 0)) {
|
|
896
|
+
return null;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
900
|
+
const inActiveCategory =
|
|
901
|
+
activeCategory === TOOL_MENTION_ALL_CATEGORY
|
|
902
|
+
? tools
|
|
903
|
+
: (categories.find((c) => c.name === activeCategory)?.tools ?? []);
|
|
904
|
+
const visibleTools = normalizedQuery
|
|
905
|
+
? inActiveCategory.filter(
|
|
906
|
+
(tool) =>
|
|
907
|
+
tool.name.toLowerCase().includes(normalizedQuery) ||
|
|
908
|
+
(tool.description?.toLowerCase().includes(normalizedQuery) ?? false),
|
|
909
|
+
)
|
|
910
|
+
: inActiveCategory;
|
|
911
|
+
|
|
912
|
+
const insertMention = (toolName: string) => {
|
|
913
|
+
const base =
|
|
914
|
+
composerText && !/\s$/.test(composerText)
|
|
915
|
+
? `${composerText} `
|
|
916
|
+
: composerText;
|
|
917
|
+
api.composer().setText(`${base}@${toolName} `);
|
|
918
|
+
setOpen(false);
|
|
919
|
+
setQuery("");
|
|
920
|
+
};
|
|
921
|
+
|
|
922
|
+
const handleOpenChange = (next: boolean) => {
|
|
923
|
+
setOpen(next);
|
|
924
|
+
if (!next) {
|
|
925
|
+
setQuery("");
|
|
926
|
+
setActiveCategory(TOOL_MENTION_ALL_CATEGORY);
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
|
|
930
|
+
return (
|
|
931
|
+
<Popover open={open} onOpenChange={handleOpenChange}>
|
|
932
|
+
<PopoverTrigger asChild>
|
|
933
|
+
<Button
|
|
934
|
+
variant="ghost"
|
|
935
|
+
size="icon"
|
|
936
|
+
data-state={open ? "open" : "closed"}
|
|
937
|
+
className="aui-composer-tool-mention-picker flex w-fit items-center gap-2 rounded-full px-2.5 py-1 text-xs font-semibold data-[state=open]:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30"
|
|
938
|
+
aria-label="Mention a tool"
|
|
939
|
+
>
|
|
940
|
+
<AtSign className="size-5 stroke-[1.5px]" />
|
|
941
|
+
</Button>
|
|
942
|
+
</PopoverTrigger>
|
|
943
|
+
<PopoverContent
|
|
944
|
+
side="top"
|
|
945
|
+
align="start"
|
|
946
|
+
className="aui-composer-tool-mention-popover w-[420px] overflow-hidden p-0"
|
|
947
|
+
>
|
|
948
|
+
<div className="flex items-center gap-2 border-b border-input px-3 py-2">
|
|
949
|
+
<Search className="size-4 shrink-0 text-muted-foreground" />
|
|
950
|
+
<input
|
|
951
|
+
autoFocus
|
|
952
|
+
value={query}
|
|
953
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
954
|
+
placeholder="Search tools…"
|
|
955
|
+
className="w-full bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground"
|
|
956
|
+
aria-label="Search tools"
|
|
957
|
+
/>
|
|
958
|
+
</div>
|
|
959
|
+
<div className="flex h-72">
|
|
960
|
+
<div className="w-36 shrink-0 overflow-y-auto border-r border-input p-2">
|
|
961
|
+
<div className="px-2 pb-1 text-[10px] font-semibold tracking-wide text-muted-foreground uppercase">
|
|
962
|
+
Categories
|
|
963
|
+
</div>
|
|
964
|
+
<button
|
|
965
|
+
type="button"
|
|
966
|
+
onClick={() => setActiveCategory(TOOL_MENTION_ALL_CATEGORY)}
|
|
967
|
+
className={cn(
|
|
968
|
+
"flex w-full items-center justify-between rounded px-2 py-1 text-left text-xs transition-colors",
|
|
969
|
+
activeCategory === TOOL_MENTION_ALL_CATEGORY
|
|
970
|
+
? "bg-muted font-medium text-foreground"
|
|
971
|
+
: "text-muted-foreground hover:bg-muted/60",
|
|
972
|
+
)}
|
|
973
|
+
>
|
|
974
|
+
<span className="truncate">All</span>
|
|
975
|
+
<span className="ml-2 shrink-0 tabular-nums opacity-60">
|
|
976
|
+
{tools.length}
|
|
977
|
+
</span>
|
|
978
|
+
</button>
|
|
979
|
+
{categories.map((category) => (
|
|
980
|
+
<button
|
|
981
|
+
key={category.name}
|
|
982
|
+
type="button"
|
|
983
|
+
onClick={() => setActiveCategory(category.name)}
|
|
984
|
+
className={cn(
|
|
985
|
+
"flex w-full items-center justify-between rounded px-2 py-1 text-left text-xs transition-colors",
|
|
986
|
+
activeCategory === category.name
|
|
987
|
+
? "bg-muted font-medium text-foreground"
|
|
988
|
+
: "text-muted-foreground hover:bg-muted/60",
|
|
989
|
+
)}
|
|
990
|
+
>
|
|
991
|
+
<span className="truncate">{category.name}</span>
|
|
992
|
+
<span className="ml-2 shrink-0 tabular-nums opacity-60">
|
|
993
|
+
{category.tools.length}
|
|
994
|
+
</span>
|
|
995
|
+
</button>
|
|
996
|
+
))}
|
|
997
|
+
</div>
|
|
998
|
+
<div className="min-w-0 flex-1 overflow-y-auto p-2">
|
|
999
|
+
{visibleTools.length === 0 ? (
|
|
1000
|
+
<div className="px-2 py-6 text-center text-xs text-muted-foreground">
|
|
1001
|
+
{mcpToolsLoading ? "Loading tools…" : "No tools found"}
|
|
1002
|
+
</div>
|
|
1003
|
+
) : (
|
|
1004
|
+
visibleTools.map((tool) => (
|
|
1005
|
+
<button
|
|
1006
|
+
key={tool.id}
|
|
1007
|
+
type="button"
|
|
1008
|
+
onClick={() => insertMention(tool.name)}
|
|
1009
|
+
className="flex w-full items-start gap-2 rounded px-2 py-1.5 text-left transition-colors hover:bg-muted"
|
|
1010
|
+
>
|
|
1011
|
+
<Wrench className="mt-0.5 size-4 shrink-0 text-muted-foreground" />
|
|
1012
|
+
<span className="min-w-0 flex-1">
|
|
1013
|
+
<span className="block truncate text-sm font-medium text-foreground">
|
|
1014
|
+
{tool.name}
|
|
1015
|
+
</span>
|
|
1016
|
+
{tool.description && (
|
|
1017
|
+
<span className="line-clamp-2 text-xs text-muted-foreground">
|
|
1018
|
+
{tool.description}
|
|
1019
|
+
</span>
|
|
1020
|
+
)}
|
|
1021
|
+
</span>
|
|
1022
|
+
</button>
|
|
1023
|
+
))
|
|
1024
|
+
)}
|
|
1025
|
+
</div>
|
|
1026
|
+
</div>
|
|
1027
|
+
</PopoverContent>
|
|
1028
|
+
</Popover>
|
|
1029
|
+
);
|
|
1030
|
+
};
|
|
1031
|
+
|
|
797
1032
|
const ComposerAction: FC = () => {
|
|
798
1033
|
const { config } = useElements();
|
|
799
1034
|
const r = useRadius();
|
|
@@ -807,6 +1042,8 @@ const ComposerAction: FC = () => {
|
|
|
807
1042
|
<div className="aui-composer-add-attachment-placeholder" />
|
|
808
1043
|
)}
|
|
809
1044
|
|
|
1045
|
+
<ComposerToolMentionPicker />
|
|
1046
|
+
|
|
810
1047
|
{config.model?.showModelPicker && !config.languageModel && (
|
|
811
1048
|
<ComposerModelPicker />
|
|
812
1049
|
)}
|
|
@@ -879,21 +1116,22 @@ const ToolCallStreamingIndicator: FC = () => {
|
|
|
879
1116
|
const AssistantMessage: FC = () => {
|
|
880
1117
|
const { config } = useElements();
|
|
881
1118
|
const toolsConfig = config.tools ?? {};
|
|
882
|
-
const components = config.components
|
|
1119
|
+
const components = config.components;
|
|
1120
|
+
const toolsComponents = toolsConfig.components;
|
|
883
1121
|
|
|
884
1122
|
const partsComponents = useMemo(
|
|
885
1123
|
() => ({
|
|
886
|
-
Text: components
|
|
887
|
-
Image: components
|
|
1124
|
+
Text: components?.Text ?? MarkdownText,
|
|
1125
|
+
Image: components?.Image ?? Image,
|
|
888
1126
|
tools: {
|
|
889
|
-
by_name:
|
|
890
|
-
Fallback: components
|
|
1127
|
+
by_name: toolsComponents,
|
|
1128
|
+
Fallback: components?.ToolFallback ?? ToolFallback,
|
|
891
1129
|
},
|
|
892
|
-
Reasoning: components
|
|
893
|
-
ReasoningGroup: components
|
|
894
|
-
ToolGroup: components
|
|
1130
|
+
Reasoning: components?.Reasoning ?? Reasoning,
|
|
1131
|
+
ReasoningGroup: components?.ReasoningGroup ?? ReasoningGroup,
|
|
1132
|
+
ToolGroup: components?.ToolGroup ?? ToolGroup,
|
|
895
1133
|
}),
|
|
896
|
-
[components,
|
|
1134
|
+
[components, toolsComponents],
|
|
897
1135
|
);
|
|
898
1136
|
|
|
899
1137
|
return (
|
|
@@ -950,6 +1188,8 @@ const AssistantActionBar: FC = () => {
|
|
|
950
1188
|
|
|
951
1189
|
const UserMessage: FC = () => {
|
|
952
1190
|
const r = useRadius();
|
|
1191
|
+
const { config } = useElements();
|
|
1192
|
+
const allowEdit = config.allowMessageEdit !== false;
|
|
953
1193
|
return (
|
|
954
1194
|
<MessagePrimitive.Root asChild>
|
|
955
1195
|
<div
|
|
@@ -967,9 +1207,11 @@ const UserMessage: FC = () => {
|
|
|
967
1207
|
>
|
|
968
1208
|
<MessagePrimitive.Parts />
|
|
969
1209
|
</div>
|
|
970
|
-
|
|
971
|
-
<
|
|
972
|
-
|
|
1210
|
+
{allowEdit && (
|
|
1211
|
+
<div className="aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2">
|
|
1212
|
+
<UserActionBar />
|
|
1213
|
+
</div>
|
|
1214
|
+
)}
|
|
973
1215
|
</div>
|
|
974
1216
|
|
|
975
1217
|
<BranchPicker className="aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
|
|
@@ -74,7 +74,7 @@ export const ToolMentionAutocomplete: FC<ToolMentionAutocompleteProps> = ({
|
|
|
74
74
|
onValueChange(result.text, result.cursorPosition);
|
|
75
75
|
setIsVisible(false);
|
|
76
76
|
},
|
|
77
|
-
[mentionContext, value, cursorPosition, onValueChange
|
|
77
|
+
[mentionContext, value, cursorPosition, onValueChange],
|
|
78
78
|
);
|
|
79
79
|
|
|
80
80
|
useEffect(() => {
|
|
@@ -6,7 +6,7 @@ import { cn } from "@/lib/utils";
|
|
|
6
6
|
function Avatar({
|
|
7
7
|
className,
|
|
8
8
|
...props
|
|
9
|
-
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
|
|
9
|
+
}: React.ComponentProps<typeof AvatarPrimitive.Root>): React.JSX.Element {
|
|
10
10
|
return (
|
|
11
11
|
<AvatarPrimitive.Root
|
|
12
12
|
data-slot="avatar"
|
|
@@ -22,7 +22,7 @@ function Avatar({
|
|
|
22
22
|
function AvatarImage({
|
|
23
23
|
className,
|
|
24
24
|
...props
|
|
25
|
-
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
|
|
25
|
+
}: React.ComponentProps<typeof AvatarPrimitive.Image>): React.JSX.Element {
|
|
26
26
|
return (
|
|
27
27
|
<AvatarPrimitive.Image
|
|
28
28
|
data-slot="avatar-image"
|
|
@@ -35,7 +35,7 @@ function AvatarImage({
|
|
|
35
35
|
function AvatarFallback({
|
|
36
36
|
className,
|
|
37
37
|
...props
|
|
38
|
-
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
|
|
38
|
+
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>): React.JSX.Element {
|
|
39
39
|
return (
|
|
40
40
|
<AvatarPrimitive.Fallback
|
|
41
41
|
data-slot="avatar-fallback"
|
|
@@ -130,7 +130,7 @@ function Calendar({
|
|
|
130
130
|
minDate,
|
|
131
131
|
maxDate,
|
|
132
132
|
className,
|
|
133
|
-
}: CalendarProps) {
|
|
133
|
+
}: CalendarProps): React.JSX.Element {
|
|
134
134
|
const [viewDate, setViewDate] = React.useState(() => {
|
|
135
135
|
if (selected.start) return new Date(selected.start);
|
|
136
136
|
return new Date();
|
|
@@ -2,13 +2,15 @@ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
|
2
2
|
|
|
3
3
|
function Collapsible({
|
|
4
4
|
...props
|
|
5
|
-
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
|
|
5
|
+
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>): React.JSX.Element {
|
|
6
6
|
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
function CollapsibleTrigger({
|
|
10
10
|
...props
|
|
11
|
-
}: React.ComponentProps<
|
|
11
|
+
}: React.ComponentProps<
|
|
12
|
+
typeof CollapsiblePrimitive.CollapsibleTrigger
|
|
13
|
+
>): React.JSX.Element {
|
|
12
14
|
return (
|
|
13
15
|
<CollapsiblePrimitive.CollapsibleTrigger
|
|
14
16
|
data-slot="collapsible-trigger"
|
|
@@ -19,7 +21,9 @@ function CollapsibleTrigger({
|
|
|
19
21
|
|
|
20
22
|
function CollapsibleContent({
|
|
21
23
|
...props
|
|
22
|
-
}: React.ComponentProps<
|
|
24
|
+
}: React.ComponentProps<
|
|
25
|
+
typeof CollapsiblePrimitive.CollapsibleContent
|
|
26
|
+
>): React.JSX.Element {
|
|
23
27
|
return (
|
|
24
28
|
<CollapsiblePrimitive.CollapsibleContent
|
|
25
29
|
data-slot="collapsible-content"
|
|
@@ -7,20 +7,20 @@ import { usePortalContainer } from "@/hooks/usePortalContainer";
|
|
|
7
7
|
|
|
8
8
|
function Dialog({
|
|
9
9
|
...props
|
|
10
|
-
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
10
|
+
}: React.ComponentProps<typeof DialogPrimitive.Root>): React.JSX.Element {
|
|
11
11
|
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
function DialogTrigger({
|
|
15
15
|
...props
|
|
16
|
-
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
16
|
+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>): React.JSX.Element {
|
|
17
17
|
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
function DialogPortal({
|
|
21
21
|
container,
|
|
22
22
|
...props
|
|
23
|
-
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
23
|
+
}: React.ComponentProps<typeof DialogPrimitive.Portal>): React.JSX.Element {
|
|
24
24
|
const portalContainer = usePortalContainer();
|
|
25
25
|
return (
|
|
26
26
|
<DialogPrimitive.Portal
|
|
@@ -33,14 +33,14 @@ function DialogPortal({
|
|
|
33
33
|
|
|
34
34
|
function DialogClose({
|
|
35
35
|
...props
|
|
36
|
-
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
36
|
+
}: React.ComponentProps<typeof DialogPrimitive.Close>): React.JSX.Element {
|
|
37
37
|
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function DialogOverlay({
|
|
41
41
|
className,
|
|
42
42
|
...props
|
|
43
|
-
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
43
|
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>): React.JSX.Element {
|
|
44
44
|
return (
|
|
45
45
|
<DialogPrimitive.Overlay
|
|
46
46
|
data-slot="dialog-overlay"
|
|
@@ -60,7 +60,7 @@ function DialogContent({
|
|
|
60
60
|
...props
|
|
61
61
|
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
|
62
62
|
showCloseButton?: boolean;
|
|
63
|
-
}) {
|
|
63
|
+
}): React.JSX.Element {
|
|
64
64
|
return (
|
|
65
65
|
<DialogPortal data-slot="dialog-portal">
|
|
66
66
|
<DialogOverlay />
|
|
@@ -87,7 +87,10 @@ function DialogContent({
|
|
|
87
87
|
);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
function DialogHeader({
|
|
90
|
+
function DialogHeader({
|
|
91
|
+
className,
|
|
92
|
+
...props
|
|
93
|
+
}: React.ComponentProps<"div">): React.JSX.Element {
|
|
91
94
|
return (
|
|
92
95
|
<div
|
|
93
96
|
data-slot="dialog-header"
|
|
@@ -97,7 +100,10 @@ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
97
100
|
);
|
|
98
101
|
}
|
|
99
102
|
|
|
100
|
-
function DialogFooter({
|
|
103
|
+
function DialogFooter({
|
|
104
|
+
className,
|
|
105
|
+
...props
|
|
106
|
+
}: React.ComponentProps<"div">): React.JSX.Element {
|
|
101
107
|
return (
|
|
102
108
|
<div
|
|
103
109
|
data-slot="dialog-footer"
|
|
@@ -113,7 +119,7 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
113
119
|
function DialogTitle({
|
|
114
120
|
className,
|
|
115
121
|
...props
|
|
116
|
-
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
122
|
+
}: React.ComponentProps<typeof DialogPrimitive.Title>): React.JSX.Element {
|
|
117
123
|
return (
|
|
118
124
|
<DialogPrimitive.Title
|
|
119
125
|
data-slot="dialog-title"
|
|
@@ -126,7 +132,9 @@ function DialogTitle({
|
|
|
126
132
|
function DialogDescription({
|
|
127
133
|
className,
|
|
128
134
|
...props
|
|
129
|
-
}: React.ComponentProps<
|
|
135
|
+
}: React.ComponentProps<
|
|
136
|
+
typeof DialogPrimitive.Description
|
|
137
|
+
>): React.JSX.Element {
|
|
130
138
|
return (
|
|
131
139
|
<DialogPrimitive.Description
|
|
132
140
|
data-slot="dialog-description"
|
|
@@ -4,7 +4,7 @@ import { useDensity } from "@/hooks/useDensity";
|
|
|
4
4
|
import { cn } from "@/lib/utils";
|
|
5
5
|
import { isJsonRenderTree, type JsonRenderNode } from "@/lib/generative-ui";
|
|
6
6
|
import { AlertCircleIcon } from "lucide-react";
|
|
7
|
-
import { FC, useMemo } from "react";
|
|
7
|
+
import { ElementType, FC, useMemo } from "react";
|
|
8
8
|
|
|
9
9
|
// Import all components from the generative-ui plugin ui directory
|
|
10
10
|
import {
|
|
@@ -42,9 +42,10 @@ interface GenerativeUIProps {
|
|
|
42
42
|
/**
|
|
43
43
|
* Built-in components for rendering json-render trees.
|
|
44
44
|
* These provide a default set of UI primitives for tool results.
|
|
45
|
+
* Each entry has its own prop shape; the registry erases those generics via
|
|
46
|
+
* `ElementType` so heterogeneous components can coexist under one map.
|
|
45
47
|
*/
|
|
46
|
-
|
|
47
|
-
const components: Record<string, FC<any>> = {
|
|
48
|
+
const components: Record<string, ElementType> = {
|
|
48
49
|
// Layout
|
|
49
50
|
Card: CardWrapper,
|
|
50
51
|
Grid,
|
|
@@ -98,7 +99,11 @@ function renderNode(node: JsonRenderNode, key?: number): React.ReactNode {
|
|
|
98
99
|
? node.children.map((child, i) => renderNode(child, i))
|
|
99
100
|
: undefined;
|
|
100
101
|
|
|
101
|
-
return
|
|
102
|
+
return (
|
|
103
|
+
<Component key={key} {...(node.props ?? {})}>
|
|
104
|
+
{children}
|
|
105
|
+
</Component>
|
|
106
|
+
);
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
/**
|
|
@@ -6,13 +6,13 @@ import { usePortalContainer } from "@/hooks/usePortalContainer";
|
|
|
6
6
|
|
|
7
7
|
function Popover({
|
|
8
8
|
...props
|
|
9
|
-
}: React.ComponentProps<typeof PopoverPrimitive.Root>) {
|
|
9
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Root>): React.JSX.Element {
|
|
10
10
|
return <PopoverPrimitive.Root data-slot="popover" {...props} />;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
function PopoverTrigger({
|
|
14
14
|
...props
|
|
15
|
-
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
|
15
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>): React.JSX.Element {
|
|
16
16
|
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -24,7 +24,7 @@ function PopoverContent({
|
|
|
24
24
|
...props
|
|
25
25
|
}: React.ComponentProps<typeof PopoverPrimitive.Content> & {
|
|
26
26
|
container?: HTMLElement | null;
|
|
27
|
-
}) {
|
|
27
|
+
}): React.JSX.Element {
|
|
28
28
|
const portalContainer = usePortalContainer();
|
|
29
29
|
return (
|
|
30
30
|
<PopoverPrimitive.Portal container={container ?? portalContainer}>
|
|
@@ -44,7 +44,7 @@ function PopoverContent({
|
|
|
44
44
|
|
|
45
45
|
function PopoverAnchor({
|
|
46
46
|
...props
|
|
47
|
-
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
|
|
47
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>): React.JSX.Element {
|
|
48
48
|
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
|
|
49
49
|
}
|
|
50
50
|
|