@opengeni/react 6.1.0-canary.2 → 6.1.0-canary.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +5 -0
  2. package/dist/{browser-viewer-NTD6UIPR.js → browser-viewer-LGH4IP47.js} +3 -3
  3. package/dist/chunk-BRM6FVZA.js +302 -0
  4. package/dist/chunk-BRM6FVZA.js.map +1 -0
  5. package/dist/{chunk-UWVY3OXF.js → chunk-EQEIQSRJ.js} +276 -454
  6. package/dist/chunk-EQEIQSRJ.js.map +1 -0
  7. package/dist/{chunk-NLTS7JHI.js → chunk-JPHDWKZE.js} +5 -5
  8. package/dist/{chunk-KZ4QDBGM.js → chunk-LVHCZABQ.js} +924 -1264
  9. package/dist/chunk-LVHCZABQ.js.map +1 -0
  10. package/dist/{chunk-L5VJYZIW.js → chunk-O53CQZ6T.js} +7 -7
  11. package/dist/{chunk-24M4YBCL.js → chunk-PNAVEK2U.js} +4 -4
  12. package/dist/{chunk-G5JFM6ZE.js → chunk-URNTAVGX.js} +429 -84
  13. package/dist/chunk-URNTAVGX.js.map +1 -0
  14. package/dist/composer.js +3 -3
  15. package/dist/connect.js +4 -3
  16. package/dist/connect.js.map +1 -1
  17. package/dist/index.js +26 -26
  18. package/dist/interaction.js +2 -2
  19. package/dist/machines.js +2 -2
  20. package/dist/plugin-discovery.d.ts +2 -0
  21. package/dist/session-ui.js +6 -6
  22. package/dist/session.js +2 -2
  23. package/package.json +3 -3
  24. package/src/components/markdown.tsx +10 -23
  25. package/src/plugin-discovery.tsx +10 -6
  26. package/styles/compiled.css +0 -8
  27. package/dist/chunk-G5JFM6ZE.js.map +0 -1
  28. package/dist/chunk-HQV2I5HV.js +0 -124
  29. package/dist/chunk-HQV2I5HV.js.map +0 -1
  30. package/dist/chunk-KZ4QDBGM.js.map +0 -1
  31. package/dist/chunk-UWVY3OXF.js.map +0 -1
  32. /package/dist/{browser-viewer-NTD6UIPR.js.map → browser-viewer-LGH4IP47.js.map} +0 -0
  33. /package/dist/{chunk-NLTS7JHI.js.map → chunk-JPHDWKZE.js.map} +0 -0
  34. /package/dist/{chunk-L5VJYZIW.js.map → chunk-O53CQZ6T.js.map} +0 -0
  35. /package/dist/{chunk-24M4YBCL.js.map → chunk-PNAVEK2U.js.map} +0 -0
package/README.md CHANGED
@@ -43,6 +43,11 @@ installation. `ConnectionCatalog` accepts the same states through each option's
43
43
  `state`. Older callers that omit `state` keep their visible status labels, so
44
44
  provider warnings are not hidden during migration.
45
45
 
46
+ `PluginDiscovery` accepts `defaultProvider="openai"` or `"anthropic"` to choose
47
+ the initial registry. Omitting it starts with All. Users can still switch among
48
+ All, OpenAI, and Anthropic; changing the search preserves their selection. The
49
+ OpenGeni Plugins page starts with OpenAI.
50
+
46
51
  ```tsx
47
52
  import { ConnectPanel } from "@opengeni/react/connect";
48
53
  import "@opengeni/react/connect.css";
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  BrowserViewer
3
- } from "./chunk-24M4YBCL.js";
3
+ } from "./chunk-PNAVEK2U.js";
4
4
  import "./chunk-H5YGYNXS.js";
5
5
  import "./chunk-5YK2ZDIG.js";
6
6
  import "./chunk-JVYQRRC4.js";
7
- import "./chunk-PLYRL5ER.js";
8
7
  import "./chunk-KZ73RL76.js";
8
+ import "./chunk-PLYRL5ER.js";
9
9
  import "./chunk-NEXLLTP4.js";
10
10
  import "./chunk-22KP6LR5.js";
11
11
  export {
12
12
  BrowserViewer
13
13
  };
14
- //# sourceMappingURL=browser-viewer-NTD6UIPR.js.map
14
+ //# sourceMappingURL=browser-viewer-LGH4IP47.js.map
@@ -0,0 +1,302 @@
1
+ import {
2
+ usePortalTokenStyle
3
+ } from "./chunk-VZTQ73XT.js";
4
+ import {
5
+ cn
6
+ } from "./chunk-22KP6LR5.js";
7
+
8
+ // src/timeline/screenshot-lightbox.tsx
9
+ import { DownloadIcon, XIcon } from "lucide-react";
10
+ import { AnimatePresence, motion } from "motion/react";
11
+ import {
12
+ createContext,
13
+ useCallback,
14
+ useContext,
15
+ useEffect,
16
+ useMemo,
17
+ useState
18
+ } from "react";
19
+ import { Dialog } from "radix-ui";
20
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
21
+ var LightboxContext = createContext(null);
22
+ function useLightbox() {
23
+ return useContext(LightboxContext) ?? NOOP;
24
+ }
25
+ function useLightboxOptional() {
26
+ return useContext(LightboxContext);
27
+ }
28
+ var NOOP = { open: () => {
29
+ } };
30
+ function createLightboxSourceOwner() {
31
+ let releaseCurrent = null;
32
+ return {
33
+ replace(release) {
34
+ const previous = releaseCurrent;
35
+ releaseCurrent = release ?? null;
36
+ previous?.();
37
+ },
38
+ release() {
39
+ const release = releaseCurrent;
40
+ releaseCurrent = null;
41
+ release?.();
42
+ }
43
+ };
44
+ }
45
+ function LightboxProvider({ children }) {
46
+ const ancestor = useContext(LightboxContext);
47
+ if (ancestor) {
48
+ return /* @__PURE__ */ jsx(Fragment, { children });
49
+ }
50
+ return /* @__PURE__ */ jsx(LightboxRoot, { children });
51
+ }
52
+ function LightboxRoot({ children }) {
53
+ const [state, setState] = useState(null);
54
+ const [tokenSource, setTokenSource] = useState(null);
55
+ const sourceOwner = useMemo(() => createLightboxSourceOwner(), []);
56
+ const portalStyle = usePortalTokenStyle(tokenSource);
57
+ const releaseCurrentSource = useCallback(() => {
58
+ sourceOwner.release();
59
+ }, [sourceOwner]);
60
+ useEffect(() => releaseCurrentSource, [releaseCurrentSource]);
61
+ const open = useCallback(
62
+ (src, caption, source, label = "Screenshot", downloadFilename, controlLabels, releaseSource) => {
63
+ sourceOwner.replace(releaseSource);
64
+ setTokenSource(source ?? null);
65
+ setState({
66
+ src,
67
+ label,
68
+ ...caption ? { caption } : {},
69
+ ...downloadFilename ? { downloadFilename } : {},
70
+ ...controlLabels ? { controlLabels } : {}
71
+ });
72
+ },
73
+ [sourceOwner]
74
+ );
75
+ const close = useCallback(() => {
76
+ releaseCurrentSource();
77
+ setState(null);
78
+ setTokenSource(null);
79
+ }, [releaseCurrentSource]);
80
+ const controller = useMemo(() => ({ open }), [open]);
81
+ return /* @__PURE__ */ jsxs(LightboxContext.Provider, { value: controller, children: [
82
+ children,
83
+ /* @__PURE__ */ jsx(Dialog.Root, { open: state !== null, onOpenChange: (next) => !next && close(), children: /* @__PURE__ */ jsx(AnimatePresence, { children: state !== null ? /* @__PURE__ */ jsxs(Dialog.Portal, { forceMount: true, children: [
84
+ /* @__PURE__ */ jsx(Dialog.Overlay, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsx(
85
+ motion.div,
86
+ {
87
+ initial: { opacity: 0 },
88
+ animate: { opacity: 1 },
89
+ exit: { opacity: 0 },
90
+ transition: { duration: 0.15 },
91
+ className: "og-root fixed inset-0 z-50 bg-black/90 backdrop-blur-md",
92
+ style: portalStyle
93
+ }
94
+ ) }),
95
+ /* @__PURE__ */ jsx(
96
+ Dialog.Content,
97
+ {
98
+ asChild: true,
99
+ forceMount: true,
100
+ "aria-label": state.label,
101
+ onOpenAutoFocus: (event) => event.preventDefault(),
102
+ children: /* @__PURE__ */ jsxs(
103
+ motion.div,
104
+ {
105
+ initial: { opacity: 0, scale: 0.98 },
106
+ animate: { opacity: 1, scale: 1 },
107
+ exit: { opacity: 0, scale: 0.98 },
108
+ transition: { duration: 0.18, ease: [0.16, 1, 0.3, 1] },
109
+ onClick: (event) => {
110
+ if (event.target === event.currentTarget) {
111
+ close();
112
+ }
113
+ },
114
+ className: "og-root fixed inset-0 z-50 flex items-center justify-center p-6 sm:p-12",
115
+ style: portalStyle,
116
+ children: [
117
+ /* @__PURE__ */ jsx(Dialog.Title, { className: "sr-only", children: state.label }),
118
+ /* @__PURE__ */ jsx(Dialog.Description, { className: "sr-only", children: state.caption ?? `Expanded ${state.label.toLowerCase()}` }),
119
+ /* @__PURE__ */ jsxs("figure", { className: "m-0 flex max-h-full max-w-5xl flex-col items-center gap-3", children: [
120
+ /* @__PURE__ */ jsxs("div", { className: "relative flex min-h-0 w-fit max-w-full", children: [
121
+ /* @__PURE__ */ jsx(
122
+ "img",
123
+ {
124
+ src: state.src,
125
+ alt: state.caption ?? state.label,
126
+ className: "min-h-0 max-h-[82vh] w-auto max-w-full rounded-og-md border border-white/10 object-contain shadow-og-lg"
127
+ }
128
+ ),
129
+ /* @__PURE__ */ jsx(
130
+ ScreenshotLightboxControls,
131
+ {
132
+ src: state.src,
133
+ downloadFilename: state.downloadFilename,
134
+ controlLabels: state.controlLabels
135
+ }
136
+ )
137
+ ] }),
138
+ state.caption ? /* @__PURE__ */ jsx("figcaption", { className: "max-w-2xl text-center font-og-mono text-og-xs text-white/55", children: state.caption }) : /* @__PURE__ */ jsx("figcaption", { className: "font-og-mono text-og-xs uppercase tracking-[0.1em] text-white/35", children: "Esc or click outside to close" })
139
+ ] })
140
+ ]
141
+ }
142
+ )
143
+ }
144
+ )
145
+ ] }) : null }) })
146
+ ] });
147
+ }
148
+ function ScreenshotLightboxControls({
149
+ src,
150
+ downloadFilename,
151
+ controlLabels
152
+ }) {
153
+ return /* @__PURE__ */ jsxs("div", { className: "absolute -right-3 -top-3 flex items-center gap-2", children: [
154
+ downloadFilename ? /* @__PURE__ */ jsx(
155
+ "a",
156
+ {
157
+ href: src,
158
+ download: downloadFilename,
159
+ className: cn(
160
+ "inline-flex size-9 items-center justify-center rounded-full",
161
+ "border border-white/15 bg-black/60 text-white/70 backdrop-blur",
162
+ "transition-colors hover:border-white/30 hover:text-white"
163
+ ),
164
+ "aria-label": controlLabels?.download ?? `Download ${downloadFilename}`,
165
+ children: /* @__PURE__ */ jsx(DownloadIcon, { className: "size-4" })
166
+ }
167
+ ) : null,
168
+ /* @__PURE__ */ jsx(
169
+ Dialog.Close,
170
+ {
171
+ className: cn(
172
+ "inline-flex size-9 items-center justify-center rounded-full",
173
+ "border border-white/15 bg-black/60 text-white/70 backdrop-blur",
174
+ "transition-colors hover:border-white/30 hover:text-white"
175
+ ),
176
+ "aria-label": controlLabels?.close ?? "Close",
177
+ children: /* @__PURE__ */ jsx(XIcon, { className: "size-4" })
178
+ }
179
+ )
180
+ ] });
181
+ }
182
+
183
+ // src/components/tooltip.tsx
184
+ import { Tooltip as TooltipPrimitive } from "radix-ui";
185
+ import {
186
+ createContext as createContext2,
187
+ useContext as useContext2,
188
+ useLayoutEffect,
189
+ useMemo as useMemo2,
190
+ useRef,
191
+ useState as useState2
192
+ } from "react";
193
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
194
+ var TooltipSourceContext = createContext2(null);
195
+ function TooltipProvider({
196
+ delayDuration = 300,
197
+ ...props
198
+ }) {
199
+ return /* @__PURE__ */ jsx2(TooltipPrimitive.Provider, { delayDuration, ...props });
200
+ }
201
+ function Tooltip({ children, ...props }) {
202
+ const { onOpenChange, ...rootProps } = props;
203
+ const sourceRef = useRef(null);
204
+ const sourcePublishedRef = useRef(false);
205
+ const [source, setSource] = useState2(null);
206
+ const ref = useRef((node) => {
207
+ sourceRef.current = node;
208
+ if (sourcePublishedRef.current) setSource(node);
209
+ }).current;
210
+ useLayoutEffect(() => {
211
+ if (rootProps.open === true || rootProps.defaultOpen === true) {
212
+ sourcePublishedRef.current = true;
213
+ setSource(sourceRef.current);
214
+ }
215
+ }, [rootProps.defaultOpen, rootProps.open]);
216
+ const sourceContext = useMemo2(() => ({ source, ref }), [ref, source]);
217
+ return /* @__PURE__ */ jsx2(TooltipSourceContext.Provider, { value: sourceContext, children: /* @__PURE__ */ jsx2(
218
+ TooltipPrimitive.Root,
219
+ {
220
+ "data-slot": "tooltip",
221
+ onOpenChange: (open) => {
222
+ if (open) {
223
+ sourcePublishedRef.current = true;
224
+ setSource(sourceRef.current);
225
+ }
226
+ onOpenChange?.(open);
227
+ },
228
+ ...rootProps,
229
+ children
230
+ }
231
+ ) });
232
+ }
233
+ function TooltipTrigger({
234
+ asChild = true,
235
+ ...props
236
+ }) {
237
+ const sourceRef = useContext2(TooltipSourceContext);
238
+ return /* @__PURE__ */ jsx2(
239
+ TooltipPrimitive.Trigger,
240
+ {
241
+ "data-slot": "tooltip-trigger",
242
+ asChild,
243
+ ref: (node) => {
244
+ sourceRef?.ref(node);
245
+ },
246
+ ...props
247
+ }
248
+ );
249
+ }
250
+ var tooltipSurfaceStyle = {
251
+ backgroundColor: "var(--og-color-fg)",
252
+ color: "var(--og-color-bg)"
253
+ };
254
+ function TooltipContent({
255
+ className,
256
+ sideOffset = 6,
257
+ children,
258
+ style,
259
+ ...props
260
+ }) {
261
+ const source = useContext2(TooltipSourceContext);
262
+ const portalStyle = usePortalTokenStyle(source?.source ?? null);
263
+ return /* @__PURE__ */ jsx2(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs2(
264
+ TooltipPrimitive.Content,
265
+ {
266
+ "data-slot": "tooltip-content",
267
+ sideOffset,
268
+ className: cn(
269
+ "og-root z-50 w-fit max-w-xs origin-[var(--radix-tooltip-content-transform-origin)]",
270
+ "rounded-og-md px-2.5 py-1.5 text-og-xs leading-4 text-balance shadow-og-md",
271
+ "animate-og-enter data-[state=closed]:opacity-0 data-[state=closed]:transition-opacity",
272
+ className
273
+ ),
274
+ style: { ...portalStyle, ...tooltipSurfaceStyle, ...style },
275
+ ...props,
276
+ children: [
277
+ children,
278
+ /* @__PURE__ */ jsx2(
279
+ TooltipPrimitive.Arrow,
280
+ {
281
+ className: "z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]",
282
+ style: {
283
+ backgroundColor: "var(--og-color-fg)",
284
+ fill: "var(--og-color-fg)"
285
+ }
286
+ }
287
+ )
288
+ ]
289
+ }
290
+ ) });
291
+ }
292
+
293
+ export {
294
+ useLightbox,
295
+ useLightboxOptional,
296
+ LightboxProvider,
297
+ TooltipProvider,
298
+ Tooltip,
299
+ TooltipTrigger,
300
+ TooltipContent
301
+ };
302
+ //# sourceMappingURL=chunk-BRM6FVZA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/timeline/screenshot-lightbox.tsx","../src/components/tooltip.tsx"],"sourcesContent":["import { DownloadIcon, XIcon } from \"lucide-react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport { Dialog } from \"radix-ui\";\nimport { cn } from \"../lib/cn\";\nimport { usePortalTokenStyle } from \"../lib/use-portal-token-style\";\n\n/* ----------------------------------------------------------------------------\n Screenshot lightbox\n\n A single, app-level lightbox the computer_call / view_image renderers open by\n `src`. Built on Radix Dialog so it is focus-trapped, ESC-closable, and\n scroll-locked — fixing the v1 mockup's broken expand (an absolutely-positioned\n <img> that overflowed its row). The image is centered, constrained to the\n viewport (`max-w/max-h` + `object-contain`), and sits on a dimmed backdrop.\n\n Consumers render `<LightboxProvider>` once near the timeline; renderers call\n `useLightbox().open(src)`.\n -------------------------------------------------------------------------- */\n\ntype LightboxController = {\n open: (\n src: string,\n caption?: string,\n source?: HTMLElement | null,\n label?: string,\n downloadFilename?: string,\n controlLabels?: LightboxControlLabels,\n releaseSource?: () => void,\n ) => void;\n};\n\nexport type LightboxControlLabels = {\n download?: string | undefined;\n close?: string | undefined;\n};\n\nconst LightboxContext = createContext<LightboxController | null>(null);\n\n/** Open the app-level screenshot lightbox. No-op outside a `LightboxProvider`. */\nexport function useLightbox(): LightboxController {\n return useContext(LightboxContext) ?? NOOP;\n}\n\n/**\n * The lightbox controller when one is mounted, or `null` outside a\n * `LightboxProvider`. Lets a media primitive degrade to a non-interactive image\n * (rather than a dead \"Expand\" button that announces an action it cannot do).\n */\nexport function useLightboxOptional(): LightboxController | null {\n return useContext(LightboxContext);\n}\n\nconst NOOP: LightboxController = { open: () => {} };\n\n/** @internal Owns one optional retained lightbox source and releases it exactly once. */\nexport function createLightboxSourceOwner() {\n let releaseCurrent: (() => void) | null = null;\n return {\n replace(release?: (() => void) | undefined) {\n const previous = releaseCurrent;\n releaseCurrent = release ?? null;\n previous?.();\n },\n release() {\n const release = releaseCurrent;\n releaseCurrent = null;\n release?.();\n },\n };\n}\n\n/**\n * The app-level screenshot lightbox. Render once near the timeline; renderers\n * call `useLightbox().open(src)`.\n *\n * Idempotent by design: when an ancestor `LightboxProvider` already exists (e.g.\n * a `MessageTimeline` mounted inside an app that already wraps its shell), this\n * one becomes a pass-through and does NOT mount a second focus-trapping Dialog.\n * That keeps `MessageTimeline` self-sufficient (it owns its own provider) while\n * composing cleanly when nested.\n */\nexport function LightboxProvider({ children }: { children: ReactNode }) {\n const ancestor = useContext(LightboxContext);\n if (ancestor) {\n return <>{children}</>;\n }\n return <LightboxRoot>{children}</LightboxRoot>;\n}\n\nfunction LightboxRoot({ children }: { children: ReactNode }) {\n const [state, setState] = useState<{\n src: string;\n caption?: string;\n label: string;\n downloadFilename?: string;\n controlLabels?: LightboxControlLabels;\n } | null>(null);\n const [tokenSource, setTokenSource] = useState<HTMLElement | null>(null);\n const sourceOwner = useMemo(() => createLightboxSourceOwner(), []);\n const portalStyle = usePortalTokenStyle(tokenSource);\n\n const releaseCurrentSource = useCallback(() => {\n sourceOwner.release();\n }, [sourceOwner]);\n\n useEffect(() => releaseCurrentSource, [releaseCurrentSource]);\n\n const open = useCallback(\n (\n src: string,\n caption?: string,\n source?: HTMLElement | null,\n label = \"Screenshot\",\n downloadFilename?: string,\n controlLabels?: LightboxControlLabels,\n releaseSource?: () => void,\n ) => {\n sourceOwner.replace(releaseSource);\n setTokenSource(source ?? null);\n setState({\n src,\n label,\n ...(caption ? { caption } : {}),\n ...(downloadFilename ? { downloadFilename } : {}),\n ...(controlLabels ? { controlLabels } : {}),\n });\n },\n [sourceOwner],\n );\n\n const close = useCallback(() => {\n releaseCurrentSource();\n setState(null);\n setTokenSource(null);\n }, [releaseCurrentSource]);\n\n const controller = useMemo<LightboxController>(() => ({ open }), [open]);\n\n return (\n <LightboxContext.Provider value={controller}>\n {children}\n <Dialog.Root open={state !== null} onOpenChange={(next) => !next && close()}>\n <AnimatePresence>\n {state !== null ? (\n <Dialog.Portal forceMount>\n <Dialog.Overlay asChild forceMount>\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n className=\"og-root fixed inset-0 z-50 bg-black/90 backdrop-blur-md\"\n style={portalStyle}\n />\n </Dialog.Overlay>\n <Dialog.Content\n asChild\n forceMount\n aria-label={state.label}\n onOpenAutoFocus={(event) => event.preventDefault()}\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.98 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.98 }}\n transition={{ duration: 0.18, ease: [0.16, 1, 0.3, 1] }}\n // Content is a full-inset centering wrapper layered above the\n // Overlay, so Radix's own click-outside (which fires on the\n // Overlay) can never see a backdrop click — every click lands on\n // Content. We make Content's own backdrop dismiss: a click whose\n // target is the wrapper itself (not the figure) closes it, so the\n // figcaption's \"click outside to close\" affordance is real.\n onClick={(event) => {\n if (event.target === event.currentTarget) {\n close();\n }\n }}\n className=\"og-root fixed inset-0 z-50 flex items-center justify-center p-6 sm:p-12\"\n style={portalStyle}\n >\n <Dialog.Title className=\"sr-only\">{state.label}</Dialog.Title>\n <Dialog.Description className=\"sr-only\">\n {state.caption ?? `Expanded ${state.label.toLowerCase()}`}\n </Dialog.Description>\n {/* The figure is one self-contained object: image, caption, and\n its own close control. The close button anchors to a wrapper\n sized to the IMAGE (w-fit), so it hugs the real top-right\n corner regardless of aspect ratio — never floating into the\n empty space of a wide figure column. */}\n <figure className=\"m-0 flex max-h-full max-w-5xl flex-col items-center gap-3\">\n <div className=\"relative flex min-h-0 w-fit max-w-full\">\n {/* A plain <img>: this SDK is framework-agnostic, with no host Image component. */}\n <img\n src={state.src}\n alt={state.caption ?? state.label}\n className=\"min-h-0 max-h-[82vh] w-auto max-w-full rounded-og-md border border-white/10 object-contain shadow-og-lg\"\n />\n <ScreenshotLightboxControls\n src={state.src}\n downloadFilename={state.downloadFilename}\n controlLabels={state.controlLabels}\n />\n </div>\n {state.caption ? (\n <figcaption className=\"max-w-2xl text-center font-og-mono text-og-xs text-white/55\">\n {state.caption}\n </figcaption>\n ) : (\n <figcaption className=\"font-og-mono text-og-xs uppercase tracking-[0.1em] text-white/35\">\n Esc or click outside to close\n </figcaption>\n )}\n </figure>\n </motion.div>\n </Dialog.Content>\n </Dialog.Portal>\n ) : null}\n </AnimatePresence>\n </Dialog.Root>\n </LightboxContext.Provider>\n );\n}\n\n/** @internal Exact controls rendered by an open screenshot lightbox. */\nexport function ScreenshotLightboxControls({\n src,\n downloadFilename,\n controlLabels,\n}: {\n src: string;\n downloadFilename?: string | undefined;\n controlLabels?: LightboxControlLabels | undefined;\n}) {\n return (\n <div className=\"absolute -right-3 -top-3 flex items-center gap-2\">\n {downloadFilename ? (\n <a\n href={src}\n download={downloadFilename}\n className={cn(\n \"inline-flex size-9 items-center justify-center rounded-full\",\n \"border border-white/15 bg-black/60 text-white/70 backdrop-blur\",\n \"transition-colors hover:border-white/30 hover:text-white\",\n )}\n aria-label={controlLabels?.download ?? `Download ${downloadFilename}`}\n >\n <DownloadIcon className=\"size-4\" />\n </a>\n ) : null}\n <Dialog.Close\n className={cn(\n \"inline-flex size-9 items-center justify-center rounded-full\",\n \"border border-white/15 bg-black/60 text-white/70 backdrop-blur\",\n \"transition-colors hover:border-white/30 hover:text-white\",\n )}\n aria-label={controlLabels?.close ?? \"Close\"}\n >\n <XIcon className=\"size-4\" />\n </Dialog.Close>\n </div>\n );\n}\n","/**\n * Token-styled Radix tooltip — SDK counterpart to apps/web `components/ui/tooltip`.\n * Portals copy `--og-*` tokens so embeds keep the host theme outside `.og-root`.\n *\n * Background/foreground are applied as inline styles (not only Tailwind\n * utilities): `.og-root` sets `color: var(--og-color-fg)` after utilities in the\n * consumer CSS cascade, which would otherwise paint light-on-light inverted\n * tips and look like a blank white bubble.\n */\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\nimport {\n createContext,\n useContext,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type CSSProperties,\n} from \"react\";\n\nimport { cn } from \"../lib/cn\";\nimport { usePortalTokenStyle } from \"../lib/use-portal-token-style\";\n\ntype TooltipSourceContextValue = {\n source: HTMLElement | null;\n ref: (node: HTMLElement | null) => void;\n};\n\nconst TooltipSourceContext = createContext<TooltipSourceContextValue | null>(null);\n\nfunction TooltipProvider({\n delayDuration = 300,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Provider>) {\n return <TooltipPrimitive.Provider delayDuration={delayDuration} {...props} />;\n}\n\nfunction Tooltip({ children, ...props }: ComponentProps<typeof TooltipPrimitive.Root>) {\n const { onOpenChange, ...rootProps } = props;\n const sourceRef = useRef<HTMLElement | null>(null);\n const sourcePublishedRef = useRef(false);\n const [source, setSource] = useState<HTMLElement | null>(null);\n const ref = useRef((node: HTMLElement | null) => {\n sourceRef.current = node;\n if (sourcePublishedRef.current) setSource(node);\n }).current;\n useLayoutEffect(() => {\n if (rootProps.open === true || rootProps.defaultOpen === true) {\n sourcePublishedRef.current = true;\n setSource(sourceRef.current);\n }\n }, [rootProps.defaultOpen, rootProps.open]);\n const sourceContext = useMemo(() => ({ source, ref }), [ref, source]);\n return (\n <TooltipSourceContext.Provider value={sourceContext}>\n <TooltipPrimitive.Root\n data-slot=\"tooltip\"\n onOpenChange={(open) => {\n if (open) {\n sourcePublishedRef.current = true;\n setSource(sourceRef.current);\n }\n onOpenChange?.(open);\n }}\n {...rootProps}\n >\n {children}\n </TooltipPrimitive.Root>\n </TooltipSourceContext.Provider>\n );\n}\n\nfunction TooltipTrigger({\n asChild = true,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Trigger>) {\n const sourceRef = useContext(TooltipSourceContext);\n return (\n <TooltipPrimitive.Trigger\n data-slot=\"tooltip-trigger\"\n asChild={asChild}\n ref={(node) => {\n sourceRef?.ref(node);\n }}\n {...props}\n />\n );\n}\n\nconst tooltipSurfaceStyle: CSSProperties = {\n backgroundColor: \"var(--og-color-fg)\",\n color: \"var(--og-color-bg)\",\n};\n\nfunction TooltipContent({\n className,\n sideOffset = 6,\n children,\n style,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Content>) {\n const source = useContext(TooltipSourceContext);\n const portalStyle = usePortalTokenStyle(source?.source ?? null);\n\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"og-root z-50 w-fit max-w-xs origin-[var(--radix-tooltip-content-transform-origin)]\",\n \"rounded-og-md px-2.5 py-1.5 text-og-xs leading-4 text-balance shadow-og-md\",\n \"animate-og-enter data-[state=closed]:opacity-0 data-[state=closed]:transition-opacity\",\n className,\n )}\n style={{ ...portalStyle, ...tooltipSurfaceStyle, ...style }}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow\n className=\"z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\"\n style={{\n backgroundColor: \"var(--og-color-fg)\",\n fill: \"var(--og-color-fg)\",\n }}\n />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };\n"],"mappings":"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","names":["createContext","useContext","useMemo","useState","jsx","jsxs","createContext","useState","useMemo","useContext"]}