@ai-matrx/design-system 0.21.6 → 0.21.7

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.
@@ -269,6 +269,8 @@ interface ContentTransferMenuProps {
269
269
  }
270
270
  interface ContentTransferController {
271
271
  focusTrigger(): void;
272
+ /** Mount the one canonical Alchemy palette in a host-owned menu surface. */
273
+ mountPalette(target: HTMLElement | null, onClose?: () => void, restoreFocus?: () => void): void;
272
274
  preparePrimary(options?: {
273
275
  restoreFocus?: () => void;
274
276
  }): Promise<void>;
@@ -269,6 +269,8 @@ interface ContentTransferMenuProps {
269
269
  }
270
270
  interface ContentTransferController {
271
271
  focusTrigger(): void;
272
+ /** Mount the one canonical Alchemy palette in a host-owned menu surface. */
273
+ mountPalette(target: HTMLElement | null, onClose?: () => void, restoreFocus?: () => void): void;
272
274
  preparePrimary(options?: {
273
275
  restoreFocus?: () => void;
274
276
  }): Promise<void>;
@@ -2074,6 +2074,10 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
2074
2074
  const [notice, setNotice] = React10.useState(null);
2075
2075
  const [receiptTarget, setReceiptTarget] = React10.useState();
2076
2076
  const [paletteOpen, setPaletteOpen] = React10.useState(false);
2077
+ const [paletteTarget, setPaletteTarget] = React10.useState(null);
2078
+ const externalPaletteClose = React10.useRef(null);
2079
+ const externalPaletteRestoreFocus = React10.useRef(null);
2080
+ const feedbackDocument = React10.useRef(null);
2077
2081
  const [mode, setMode] = React10.useState("copy");
2078
2082
  const scopes = React10.useMemo(() => table?.availableScopes ?? ["target"], [table]);
2079
2083
  const [requestedScope, setRequestedScope] = React10.useState(table?.initialScope ?? "target");
@@ -2170,6 +2174,40 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
2170
2174
  fence.finish(controller);
2171
2175
  }
2172
2176
  }, [captureOne, fence, initialScope, primary]);
2177
+ const closePalette = React10.useCallback(() => {
2178
+ const onClose = externalPaletteClose.current;
2179
+ const restoreFocus = externalPaletteRestoreFocus.current;
2180
+ externalPaletteClose.current = null;
2181
+ externalPaletteRestoreFocus.current = null;
2182
+ onClose?.();
2183
+ restoreFocus?.();
2184
+ setPaletteTarget(null);
2185
+ setPaletteOpen(false);
2186
+ }, []);
2187
+ const mountPalette = React10.useCallback((target, onClose, restoreFocus) => {
2188
+ if (!target) {
2189
+ externalPaletteClose.current = null;
2190
+ externalPaletteRestoreFocus.current = null;
2191
+ setPaletteTarget(null);
2192
+ setPaletteOpen(false);
2193
+ return;
2194
+ }
2195
+ if (!enabled) throw new Error("Alchemy is not enabled for this record.");
2196
+ if (disabled) throw new Error("Alchemy is disabled for this record.");
2197
+ externalPaletteClose.current = onClose ?? null;
2198
+ externalPaletteRestoreFocus.current = restoreFocus ?? null;
2199
+ feedbackDocument.current = target.ownerDocument;
2200
+ restoreFocusRef.current = restoreFocus ?? (() => target.focus());
2201
+ setPaletteTarget(target);
2202
+ setPaletteOpen(true);
2203
+ setMode("copy");
2204
+ void preflight();
2205
+ }, [closePalette, disabled, enabled, preflight]);
2206
+ React10.useEffect(() => {
2207
+ if (!paletteTarget || !paletteOpen) return;
2208
+ const firstControl = paletteTarget.querySelector("button:not([disabled]), select:not([disabled]), input:not([disabled]), textarea:not([disabled]), [href]");
2209
+ firstControl?.focus();
2210
+ }, [paletteOpen, paletteTarget]);
2173
2211
  const transfer = React10.useCallback(async (format, download, alternate) => {
2174
2212
  const { controller, id } = fence.begin();
2175
2213
  try {
@@ -2310,6 +2348,7 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
2310
2348
  );
2311
2349
  React10.useImperativeHandle(controllerRef, () => ({
2312
2350
  focusTrigger: () => triggerRef.current?.focus(),
2351
+ mountPalette,
2313
2352
  preparePrimary: async (options) => {
2314
2353
  if (!enabled) throw new Error("Alchemy is not enabled for this record.");
2315
2354
  if (disabled) throw new Error("Alchemy is disabled for this record.");
@@ -2324,7 +2363,7 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
2324
2363
  externalWorkspaceKeys.current.add(requestedKey);
2325
2364
  await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
2326
2365
  }
2327
- }), [disabled, enabled, hide, openWorkspace, primary, primaryWorkspaceKey, sourceLabel]);
2366
+ }), [disabled, enabled, hide, mountPalette, openWorkspace, primary, primaryWorkspaceKey, sourceLabel]);
2328
2367
  const runAction = React10.useCallback(async (action) => {
2329
2368
  const { controller, id } = fence.begin();
2330
2369
  try {
@@ -2390,7 +2429,6 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
2390
2429
  return sealTransferArtifact3({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "ai-context", plainText: buildAgentPayload2({ kind: "matrx_content", location: sourceLabel, description: "Captured content for an assistant", data: JSON.parse(json.plainText), attributes: { source: draft.sourceId } }), omissions: [...json.omissions] });
2391
2430
  }
2392
2431
  };
2393
- const closePalette = () => setPaletteOpen(false);
2394
2432
  const tile = (id, label2, onClick, options = {}) => {
2395
2433
  const presentation = options.action;
2396
2434
  const Icon = presentation?.icon;
@@ -2406,122 +2444,125 @@ function ContentTransferMenuSession({ references = [], referenceActions = [], so
2406
2444
  ] })
2407
2445
  ] }, id);
2408
2446
  };
2447
+ const palette = /* @__PURE__ */ jsxs6(Fragment2, { children: [
2448
+ menuStatus === "loading" ? /* @__PURE__ */ jsx11("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ jsx11("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
2449
+ table && scopes.length > 1 ? /* @__PURE__ */ jsxs6("label", { className: "matrx-alchemy-scope", children: [
2450
+ "Content scope",
2451
+ /* @__PURE__ */ jsx11("select", { "aria-label": "Content scope", value: initialScope, onChange: (event) => {
2452
+ const next = scopes.find((scope) => scope === event.target.value);
2453
+ if (next) {
2454
+ setRequestedScope(next);
2455
+ void preflight(next);
2456
+ }
2457
+ }, children: scopes.map((scope) => /* @__PURE__ */ jsx11("option", { value: scope, children: table.scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
2458
+ ] }) : null,
2459
+ copyAvailable || downloadAvailable ? /* @__PURE__ */ jsxs6("section", { className: "matrx-alchemy-output", children: [
2460
+ /* @__PURE__ */ jsx11("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
2461
+ copyAvailable && downloadAvailable ? /* @__PURE__ */ jsxs6("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
2462
+ /* @__PURE__ */ jsx11("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
2463
+ /* @__PURE__ */ jsx11("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
2464
+ ] }) : null,
2465
+ resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ jsxs6(Fragment2, { children: [
2466
+ /* @__PURE__ */ jsxs6("div", { className: "matrx-alchemy-palette-grid", children: [
2467
+ visibleCopies.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets" }[format], () => void transfer(format, false), { ariaLabel: `Copy ${LABEL[format]}` })),
2468
+ visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
2469
+ ] }),
2470
+ quickVariants("copy").length ? /* @__PURE__ */ jsx11(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
2471
+ closePalette();
2472
+ void transfer("markdown", false, variant);
2473
+ } }) : null
2474
+ ] }) : null,
2475
+ resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ jsx11(Fragment2, { children: /* @__PURE__ */ jsxs6("div", { className: "matrx-alchemy-palette-grid", children: [
2476
+ visibleDownloads.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets", xlsx: "Excel" }[format], () => void transfer(format, true), { ariaLabel: `Download ${LABEL[format]}` })),
2477
+ visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
2478
+ downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
2479
+ ] }) }) : null
2480
+ ] }) : null,
2481
+ prepareAvailable ? /* @__PURE__ */ jsxs6(Fragment2, { children: [
2482
+ /* @__PURE__ */ jsx11(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2483
+ closePalette();
2484
+ void transfer(nativeAiFormat, false);
2485
+ }, children: [
2486
+ /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "ai-copy" }),
2487
+ /* @__PURE__ */ jsxs6("span", { children: [
2488
+ "Copy with AI context",
2489
+ /* @__PURE__ */ jsx11("small", { className: "matrx-alchemy-menu-hint", children: "Include source context" })
2490
+ ] })
2491
+ ] }) : null, items: quickVariants("ai"), onRun: (variant) => {
2492
+ closePalette();
2493
+ void transfer("markdown", false, variant);
2494
+ } }),
2495
+ /* @__PURE__ */ jsx11(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
2496
+ closePalette();
2497
+ void openWorkspace();
2498
+ }, children: [
2499
+ /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "sliders" }),
2500
+ /* @__PURE__ */ jsxs6("span", { children: [
2501
+ "Prepare for AI",
2502
+ /* @__PURE__ */ jsx11("small", { className: "matrx-alchemy-menu-hint", children: "Trim, edit or summarize" })
2503
+ ] })
2504
+ ] }) })
2505
+ ] }) : null,
2506
+ prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ jsx11(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ jsxs6(Fragment2, { children: [
2507
+ nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2508
+ closePalette();
2509
+ void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
2510
+ }, children: [
2511
+ /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "surface" }),
2512
+ /* @__PURE__ */ jsx11("span", { children: "Prepare this page" })
2513
+ ] }) : null,
2514
+ variants.map((variant) => /* @__PURE__ */ jsx11("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
2515
+ closePalette();
2516
+ void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
2517
+ }, children: /* @__PURE__ */ jsx11(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
2518
+ ] }) }) : null,
2519
+ references.length || referenceActions.length ? /* @__PURE__ */ jsxs6("section", { className: "matrx-alchemy-palette-section", children: [
2520
+ /* @__PURE__ */ jsx11("h3", { children: "References" }),
2521
+ referenceActions.map((action) => /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void openReference(action), children: [
2522
+ /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "link" }),
2523
+ /* @__PURE__ */ jsx11("span", { children: action.label }),
2524
+ /* @__PURE__ */ jsx11("svg", { className: "matrx-alchemy-disclosure", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx11("path", { d: "m6 4 4 4-4 4" }) })
2525
+ ] }, action.id)),
2526
+ references.map((reference) => /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", title: "Copies a reference to saved data", onClick: () => void copyReference(reference), children: [
2527
+ /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "link" }),
2528
+ /* @__PURE__ */ jsx11("span", { children: reference.label })
2529
+ ] }, reference.id))
2530
+ ] }) : null,
2531
+ ["save", "chat", "email", "other"].map((group) => {
2532
+ const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
2533
+ return entries.length ? /* @__PURE__ */ jsxs6("details", { className: "matrx-alchemy-palette-destinations", children: [
2534
+ /* @__PURE__ */ jsxs6("summary", { children: [
2535
+ group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : group === "email" ? "Email to me" : "Actions",
2536
+ /* @__PURE__ */ jsxs6("span", { className: "matrx-alchemy-disclosure-meta", children: [
2537
+ /* @__PURE__ */ jsx11("span", { children: entries.length }),
2538
+ /* @__PURE__ */ jsx11("svg", { className: "matrx-alchemy-disclosure", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx11("path", { d: "m6 4 4 4-4 4" }) })
2539
+ ] })
2540
+ ] }),
2541
+ /* @__PURE__ */ jsx11("div", { children: entries.map((action) => /* @__PURE__ */ jsx11("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
2542
+ closePalette();
2543
+ void runAction(action);
2544
+ }, children: /* @__PURE__ */ jsx11(DestinationPresentation, { action }) }, action.id)) })
2545
+ ] }, group) : null;
2546
+ })
2547
+ ] });
2548
+ const feedbackOwner = paletteTarget ?? triggerRef.current ?? feedbackDocument.current?.body ?? null;
2409
2549
  return /* @__PURE__ */ jsxs6("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
2410
- !triggerHidden ? /* @__PURE__ */ jsxs6(Popover, { open: paletteOpen, onOpenChange: (open) => {
2411
- setPaletteOpen(open);
2550
+ !triggerHidden && !paletteTarget ? /* @__PURE__ */ jsxs6(Popover, { open: paletteOpen, onOpenChange: (open) => {
2412
2551
  if (open) {
2552
+ setPaletteOpen(true);
2413
2553
  setMode("copy");
2414
2554
  void preflight();
2415
- }
2555
+ } else closePalette();
2416
2556
  }, children: [
2417
2557
  /* @__PURE__ */ jsx11(PopoverTrigger, { asChild: true, children: triggerVariant === "outline" ? /* @__PURE__ */ jsx11(Button, { ref: triggerRef, variant: "outline", size: "icon-sm", "aria-label": `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "outline", disabled, children: /* @__PURE__ */ jsx11(AlchemyGlyph, { icon }) }) : triggerVariant === "glass" ? /* @__PURE__ */ jsx11(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ jsx11(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass", "data-alchemy-size": triggerSize, disabled }) : /* @__PURE__ */ jsx11(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ jsx11(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent", "data-alchemy-size": triggerSize, disabled }) }),
2418
- /* @__PURE__ */ jsxs6(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
2419
- menuStatus === "loading" ? /* @__PURE__ */ jsx11("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ jsx11("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
2420
- table && scopes.length > 1 ? /* @__PURE__ */ jsxs6("label", { className: "matrx-alchemy-scope", children: [
2421
- "Content scope",
2422
- /* @__PURE__ */ jsx11("select", { "aria-label": "Content scope", value: initialScope, onChange: (event) => {
2423
- const next = scopes.find((scope) => scope === event.target.value);
2424
- if (next) {
2425
- setRequestedScope(next);
2426
- void preflight(next);
2427
- }
2428
- }, children: scopes.map((scope) => /* @__PURE__ */ jsx11("option", { value: scope, children: table.scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
2429
- ] }) : null,
2430
- copyAvailable || downloadAvailable ? /* @__PURE__ */ jsxs6("section", { className: "matrx-alchemy-output", children: [
2431
- /* @__PURE__ */ jsx11("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
2432
- copyAvailable && downloadAvailable ? /* @__PURE__ */ jsxs6("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
2433
- /* @__PURE__ */ jsx11("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
2434
- /* @__PURE__ */ jsx11("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
2435
- ] }) : null,
2436
- resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ jsxs6(Fragment2, { children: [
2437
- /* @__PURE__ */ jsxs6("div", { className: "matrx-alchemy-palette-grid", children: [
2438
- visibleCopies.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets" }[format], () => void transfer(format, false), { ariaLabel: `Copy ${LABEL[format]}` })),
2439
- visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
2440
- ] }),
2441
- quickVariants("copy").length ? /* @__PURE__ */ jsx11(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
2442
- closePalette();
2443
- void transfer("markdown", false, variant);
2444
- } }) : null
2445
- ] }) : null,
2446
- resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ jsx11(Fragment2, { children: /* @__PURE__ */ jsxs6("div", { className: "matrx-alchemy-palette-grid", children: [
2447
- visibleDownloads.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets", xlsx: "Excel" }[format], () => void transfer(format, true), { ariaLabel: `Download ${LABEL[format]}` })),
2448
- visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
2449
- downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
2450
- ] }) }) : null
2451
- ] }) : null,
2452
- prepareAvailable ? /* @__PURE__ */ jsxs6(Fragment2, { children: [
2453
- /* @__PURE__ */ jsx11(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2454
- closePalette();
2455
- void transfer(nativeAiFormat, false);
2456
- }, children: [
2457
- /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "ai-copy" }),
2458
- /* @__PURE__ */ jsxs6("span", { children: [
2459
- "Copy with AI context",
2460
- /* @__PURE__ */ jsx11("small", { className: "matrx-alchemy-menu-hint", children: "Include source context" })
2461
- ] })
2462
- ] }) : null, items: quickVariants("ai"), onRun: (variant) => {
2463
- closePalette();
2464
- void transfer("markdown", false, variant);
2465
- } }),
2466
- /* @__PURE__ */ jsx11(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
2467
- closePalette();
2468
- void openWorkspace();
2469
- }, children: [
2470
- /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "sliders" }),
2471
- /* @__PURE__ */ jsxs6("span", { children: [
2472
- "Prepare for AI",
2473
- /* @__PURE__ */ jsx11("small", { className: "matrx-alchemy-menu-hint", children: "Trim, edit or summarize" })
2474
- ] })
2475
- ] }) })
2476
- ] }) : null,
2477
- prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ jsx11(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ jsxs6(Fragment2, { children: [
2478
- nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
2479
- closePalette();
2480
- void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
2481
- }, children: [
2482
- /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "surface" }),
2483
- /* @__PURE__ */ jsx11("span", { children: "Prepare this page" })
2484
- ] }) : null,
2485
- variants.map((variant) => /* @__PURE__ */ jsx11("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
2486
- closePalette();
2487
- void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
2488
- }, children: /* @__PURE__ */ jsx11(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
2489
- ] }) }) : null,
2490
- references.length || referenceActions.length ? /* @__PURE__ */ jsxs6("section", { className: "matrx-alchemy-palette-section", children: [
2491
- /* @__PURE__ */ jsx11("h3", { children: "References" }),
2492
- referenceActions.map((action) => /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void openReference(action), children: [
2493
- /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "link" }),
2494
- /* @__PURE__ */ jsx11("span", { children: action.label }),
2495
- /* @__PURE__ */ jsx11("svg", { className: "matrx-alchemy-disclosure", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx11("path", { d: "m6 4 4 4-4 4" }) })
2496
- ] }, action.id)),
2497
- references.map((reference) => /* @__PURE__ */ jsxs6("button", { type: "button", className: "matrx-alchemy-palette-row", title: "Copies a reference to saved data", onClick: () => void copyReference(reference), children: [
2498
- /* @__PURE__ */ jsx11(PaletteGlyph, { kind: "link" }),
2499
- /* @__PURE__ */ jsx11("span", { children: reference.label })
2500
- ] }, reference.id))
2501
- ] }) : null,
2502
- ["save", "chat", "email", "other"].map((group) => {
2503
- const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
2504
- return entries.length ? /* @__PURE__ */ jsxs6("details", { className: "matrx-alchemy-palette-destinations", children: [
2505
- /* @__PURE__ */ jsxs6("summary", { children: [
2506
- group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : group === "email" ? "Email to me" : "Actions",
2507
- /* @__PURE__ */ jsxs6("span", { className: "matrx-alchemy-disclosure-meta", children: [
2508
- /* @__PURE__ */ jsx11("span", { children: entries.length }),
2509
- /* @__PURE__ */ jsx11("svg", { className: "matrx-alchemy-disclosure", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", "aria-hidden": "true", children: /* @__PURE__ */ jsx11("path", { d: "m6 4 4 4-4 4" }) })
2510
- ] })
2511
- ] }),
2512
- /* @__PURE__ */ jsx11("div", { children: entries.map((action) => /* @__PURE__ */ jsx11("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
2513
- closePalette();
2514
- void runAction(action);
2515
- }, children: /* @__PURE__ */ jsx11(DestinationPresentation, { action }) }, action.id)) })
2516
- ] }, group) : null;
2517
- })
2518
- ] })
2558
+ /* @__PURE__ */ jsx11(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: palette })
2519
2559
  ] }) : null,
2520
- notice && triggerRef.current ? createPortal(/* @__PURE__ */ jsxs6("div", { className: "matrx-alchemy-feedback", children: [
2560
+ paletteTarget && paletteOpen ? createPortal(/* @__PURE__ */ jsx11("div", { className: "matrx-alchemy-menu matrx-alchemy-palette", role: "dialog", "aria-label": "Alchemy output options", children: palette }), paletteTarget) : null,
2561
+ notice && feedbackOwner ? createPortal(/* @__PURE__ */ jsxs6("div", { className: "matrx-alchemy-feedback", children: [
2521
2562
  /* @__PURE__ */ jsx11("span", { role: "status", children: notice }),
2522
2563
  /* @__PURE__ */ jsx11(ReceiptLink, { target: receiptTarget }),
2523
2564
  /* @__PURE__ */ jsx11("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
2524
- ] }), triggerRef.current.ownerDocument.body) : null,
2565
+ ] }), feedbackOwner.ownerDocument.body) : null,
2525
2566
  Object.values(workspaces).map((saved) => /* @__PURE__ */ jsx11(PreparationWorkspace, { restoreFocus: () => restoreFocusRef.current?.() ?? triggerRef.current?.focus(), open: workspaceOpen && workspaceKey === saved.key, state: saved, scopes, scopeLabels: table?.scopeLabels, onClose: () => setWorkspaceOpen(false), onChange: (next) => setWorkspaces((current) => ({ ...current, [saved.key]: next })), transport, adapters, actions: preparedActions, captureScope: workspaceCaptures.current.get(saved.key) ?? capturePrimary, ...ai ? { ai } : {}, onOutcome: report }, saved.key)),
2526
2567
  emailReview
2527
2568
  ] });