@ai-matrx/office 0.8.48 → 0.8.50

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/pdf.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ReactNode } from 'react';
2
+ import { ComponentType, ReactNode } from 'react';
3
3
  import { ComingSoonEntry } from '@ai-matrx/kit/coming-soon';
4
4
 
5
5
  /**
@@ -62,6 +62,8 @@ interface PdfViewerState {
62
62
  rotations: Record<number, number>;
63
63
  /** Changes when the file changed on the server: the viewer must load it again. */
64
64
  reloadKey: number;
65
+ /** The page the person is on (1-based), passed only while a host tool with `followsPage` is open; otherwise 1. */
66
+ currentPage: number;
65
67
  /** The document parsed with this many pages. */
66
68
  onDocumentLoad(pageCount: number): void;
67
69
  /** A page was measured, in PDF points (crop and fit-page need it). */
@@ -119,6 +121,38 @@ type PdfRunResult =
119
121
  rows: string[][];
120
122
  }>;
121
123
  };
124
+ /** What the shell tells a host tool's panel about the session it sits in. */
125
+ interface PdfHostToolContext {
126
+ currentPage: number;
127
+ pageCount: number;
128
+ /** Original page numbers selected in the page panel (empty when none). */
129
+ selected: number[];
130
+ goToPage(n: number): void;
131
+ /** The file changed under the same id: draw the viewer and thumbnails again. */
132
+ reload(): void;
133
+ }
134
+ /**
135
+ * A tool the host brings to the rail. The shell gives it a rail button, a place in "All tools", the
136
+ * tool search and the right panel; the host owns what is inside (its own server calls and state).
137
+ * This is how an app folds its older studios into the workspace without the package knowing them.
138
+ */
139
+ interface PdfHostTool {
140
+ /** Unique among the host's tools. */
141
+ id: string;
142
+ label: string;
143
+ /** One short line under the panel title. */
144
+ hint?: string;
145
+ icon: ComponentType<{
146
+ className?: string;
147
+ }>;
148
+ /** The viewer receives `currentPage` while this tool is open (a one-page-at-a-time canvas needs it). */
149
+ followsPage?: boolean;
150
+ /** A wide panel (28rem) instead of the standard one (18rem). */
151
+ wide?: boolean;
152
+ /** Rail group: 1 (default) sits with the document tools. */
153
+ group?: 0 | 1 | 2;
154
+ render(context: PdfHostToolContext): ReactNode;
155
+ }
122
156
  interface PdfWorkspaceHost {
123
157
  file: {
124
158
  id: string;
@@ -128,6 +162,8 @@ interface PdfWorkspaceHost {
128
162
  renderViewer(state: PdfViewerState): ReactNode;
129
163
  /** One page thumbnail (the left panel). Absent: the panel numbers its pages only. */
130
164
  renderThumbnail?(page: number, widthPx: number): ReactNode;
165
+ /** A small badge drawn in the corner of one page's thumbnail (the app's annotation count, for example). Null or absent: none. */
166
+ renderPageBadge?(page: number): ReactNode;
131
167
  /** Run one tool on the server. Rejects with a sentence on failure. */
132
168
  run(request: PdfRunRequest): Promise<PdfRunResult>;
133
169
  /** Open another page of the app for the same file (Scan, Sign). */
@@ -155,6 +191,8 @@ interface PdfWorkspaceHost {
155
191
  id: string;
156
192
  label: string;
157
193
  }>>;
194
+ /** Extra tools the host brings (see `PdfHostTool`). */
195
+ tools?: PdfHostTool[];
158
196
  /** False while the device is offline: the save pill says so and edits are not queued. */
159
197
  online?: boolean;
160
198
  /** Show a failure to the person (the host's toast). Defaults to an inline banner. */
@@ -252,4 +290,4 @@ declare const canRedo: (h: History<unknown>) => boolean;
252
290
  declare const undoLabel: (h: History<unknown>) => string;
253
291
  declare const redoLabel: (h: History<unknown>) => string;
254
292
 
255
- export { HISTORY_LIMIT, type History, type KeyLike, PDF_COMING_SOON, PDF_SHORTCUTS, PDF_TOOLS, type PageDecisions, type PageOp, type PdfActionId, type PdfRunRequest, type PdfRunResult, type PdfShortcut, type PdfToolDef, type PdfToolId, type PdfViewerState, PdfWorkspace, type PdfWorkspaceHost, type PdfWorkspaceProps, type Turn, canRedo, canUndo, comingSoonIdOf, compilePageOps, deletePages, formatKeys, freshDecisions, isDirty, keptOrder, matchShortcut, pdfTool, pushStep, redo, redoLabel, reorderPages, restorePages, startHistory, turnPages, undo, undoLabel };
293
+ export { HISTORY_LIMIT, type History, type KeyLike, PDF_COMING_SOON, PDF_SHORTCUTS, PDF_TOOLS, type PageDecisions, type PageOp, type PdfActionId, type PdfHostTool, type PdfHostToolContext, type PdfRunRequest, type PdfRunResult, type PdfShortcut, type PdfToolDef, type PdfToolId, type PdfViewerState, PdfWorkspace, type PdfWorkspaceHost, type PdfWorkspaceProps, type Turn, canRedo, canUndo, comingSoonIdOf, compilePageOps, deletePages, formatKeys, freshDecisions, isDirty, keptOrder, matchShortcut, pdfTool, pushStep, redo, redoLabel, reorderPages, restorePages, startHistory, turnPages, undo, undoLabel };
package/dist/pdf.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ReactNode } from 'react';
2
+ import { ComponentType, ReactNode } from 'react';
3
3
  import { ComingSoonEntry } from '@ai-matrx/kit/coming-soon';
4
4
 
5
5
  /**
@@ -62,6 +62,8 @@ interface PdfViewerState {
62
62
  rotations: Record<number, number>;
63
63
  /** Changes when the file changed on the server: the viewer must load it again. */
64
64
  reloadKey: number;
65
+ /** The page the person is on (1-based), passed only while a host tool with `followsPage` is open; otherwise 1. */
66
+ currentPage: number;
65
67
  /** The document parsed with this many pages. */
66
68
  onDocumentLoad(pageCount: number): void;
67
69
  /** A page was measured, in PDF points (crop and fit-page need it). */
@@ -119,6 +121,38 @@ type PdfRunResult =
119
121
  rows: string[][];
120
122
  }>;
121
123
  };
124
+ /** What the shell tells a host tool's panel about the session it sits in. */
125
+ interface PdfHostToolContext {
126
+ currentPage: number;
127
+ pageCount: number;
128
+ /** Original page numbers selected in the page panel (empty when none). */
129
+ selected: number[];
130
+ goToPage(n: number): void;
131
+ /** The file changed under the same id: draw the viewer and thumbnails again. */
132
+ reload(): void;
133
+ }
134
+ /**
135
+ * A tool the host brings to the rail. The shell gives it a rail button, a place in "All tools", the
136
+ * tool search and the right panel; the host owns what is inside (its own server calls and state).
137
+ * This is how an app folds its older studios into the workspace without the package knowing them.
138
+ */
139
+ interface PdfHostTool {
140
+ /** Unique among the host's tools. */
141
+ id: string;
142
+ label: string;
143
+ /** One short line under the panel title. */
144
+ hint?: string;
145
+ icon: ComponentType<{
146
+ className?: string;
147
+ }>;
148
+ /** The viewer receives `currentPage` while this tool is open (a one-page-at-a-time canvas needs it). */
149
+ followsPage?: boolean;
150
+ /** A wide panel (28rem) instead of the standard one (18rem). */
151
+ wide?: boolean;
152
+ /** Rail group: 1 (default) sits with the document tools. */
153
+ group?: 0 | 1 | 2;
154
+ render(context: PdfHostToolContext): ReactNode;
155
+ }
122
156
  interface PdfWorkspaceHost {
123
157
  file: {
124
158
  id: string;
@@ -128,6 +162,8 @@ interface PdfWorkspaceHost {
128
162
  renderViewer(state: PdfViewerState): ReactNode;
129
163
  /** One page thumbnail (the left panel). Absent: the panel numbers its pages only. */
130
164
  renderThumbnail?(page: number, widthPx: number): ReactNode;
165
+ /** A small badge drawn in the corner of one page's thumbnail (the app's annotation count, for example). Null or absent: none. */
166
+ renderPageBadge?(page: number): ReactNode;
131
167
  /** Run one tool on the server. Rejects with a sentence on failure. */
132
168
  run(request: PdfRunRequest): Promise<PdfRunResult>;
133
169
  /** Open another page of the app for the same file (Scan, Sign). */
@@ -155,6 +191,8 @@ interface PdfWorkspaceHost {
155
191
  id: string;
156
192
  label: string;
157
193
  }>>;
194
+ /** Extra tools the host brings (see `PdfHostTool`). */
195
+ tools?: PdfHostTool[];
158
196
  /** False while the device is offline: the save pill says so and edits are not queued. */
159
197
  online?: boolean;
160
198
  /** Show a failure to the person (the host's toast). Defaults to an inline banner. */
@@ -252,4 +290,4 @@ declare const canRedo: (h: History<unknown>) => boolean;
252
290
  declare const undoLabel: (h: History<unknown>) => string;
253
291
  declare const redoLabel: (h: History<unknown>) => string;
254
292
 
255
- export { HISTORY_LIMIT, type History, type KeyLike, PDF_COMING_SOON, PDF_SHORTCUTS, PDF_TOOLS, type PageDecisions, type PageOp, type PdfActionId, type PdfRunRequest, type PdfRunResult, type PdfShortcut, type PdfToolDef, type PdfToolId, type PdfViewerState, PdfWorkspace, type PdfWorkspaceHost, type PdfWorkspaceProps, type Turn, canRedo, canUndo, comingSoonIdOf, compilePageOps, deletePages, formatKeys, freshDecisions, isDirty, keptOrder, matchShortcut, pdfTool, pushStep, redo, redoLabel, reorderPages, restorePages, startHistory, turnPages, undo, undoLabel };
293
+ export { HISTORY_LIMIT, type History, type KeyLike, PDF_COMING_SOON, PDF_SHORTCUTS, PDF_TOOLS, type PageDecisions, type PageOp, type PdfActionId, type PdfHostTool, type PdfHostToolContext, type PdfRunRequest, type PdfRunResult, type PdfShortcut, type PdfToolDef, type PdfToolId, type PdfViewerState, PdfWorkspace, type PdfWorkspaceHost, type PdfWorkspaceProps, type Turn, canRedo, canUndo, comingSoonIdOf, compilePageOps, deletePages, formatKeys, freshDecisions, isDirty, keptOrder, matchShortcut, pdfTool, pushStep, redo, redoLabel, reorderPages, restorePages, startHistory, turnPages, undo, undoLabel };
package/dist/pdf.js CHANGED
@@ -118,6 +118,7 @@ function LeftPanel(p) {
118
118
  const turn = p.decisions.turns[page] ?? 0;
119
119
  return /* @__PURE__ */ jsxs("div", { className: "relative flex h-full w-full items-center justify-center overflow-hidden bg-card", children: [
120
120
  /* @__PURE__ */ jsx("div", { style: { transform: turn ? `rotate(${turn}deg)` : void 0 }, className: "flex h-full w-full items-center justify-center", children: p.host.renderThumbnail ? p.host.renderThumbnail(page, THUMB_W) : /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: page }) }),
121
+ p.host.renderPageBadge ? /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute right-1 top-1 z-10", "data-pdf-page-badge": page, children: p.host.renderPageBadge(page) }) : null,
121
122
  page === p.currentPage ? /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute inset-0 border-2 border-primary" }) : null,
122
123
  gone.has(page) ? /* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center bg-background/80 text-xs font-medium text-destructive", children: "Deleted" }) : null
123
124
  ] });
@@ -564,25 +565,41 @@ function useWidth(ref) {
564
565
  }, [ref]);
565
566
  return size;
566
567
  }
567
- function ToolRows({ tool, onPick }) {
568
- return /* @__PURE__ */ jsx3(Fragment3, { children: PDF_TOOLS.filter((t) => t.id !== "browse").map((t) => {
569
- const Icon = PDF_TOOL_ICONS[t.id];
570
- return /* @__PURE__ */ jsx3("li", { role: "none", children: /* @__PURE__ */ jsxs3(
568
+ function ToolRows({ tool, hostTools, onPick }) {
569
+ return /* @__PURE__ */ jsxs3(Fragment3, { children: [
570
+ hostTools.map((t) => /* @__PURE__ */ jsx3("li", { role: "none", children: /* @__PURE__ */ jsxs3(
571
571
  "button",
572
572
  {
573
573
  type: "button",
574
574
  role: "menuitem",
575
- "aria-current": t.id === tool ? "true" : void 0,
576
- className: cn("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", t.id === tool && "bg-accent"),
577
- onClick: () => onPick(t.id),
575
+ "aria-current": tool === `host:${t.id}` ? "true" : void 0,
576
+ className: cn("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", tool === `host:${t.id}` && "bg-accent"),
577
+ onClick: () => onPick(`host:${t.id}`),
578
578
  children: [
579
- /* @__PURE__ */ jsx3(Icon, { className: "size-4 shrink-0" }),
580
- /* @__PURE__ */ jsx3("span", { className: "flex-1 whitespace-nowrap", children: t.label }),
581
- t.status === "soon" ? /* @__PURE__ */ jsx3("span", { className: "text-muted-foreground", children: "Coming soon" }) : null
579
+ /* @__PURE__ */ jsx3(t.icon, { className: "size-4 shrink-0" }),
580
+ /* @__PURE__ */ jsx3("span", { className: "flex-1 whitespace-nowrap", children: t.label })
582
581
  ]
583
582
  }
584
- ) }, t.id);
585
- }) });
583
+ ) }, `host:${t.id}`)),
584
+ PDF_TOOLS.filter((t) => t.id !== "browse").map((t) => {
585
+ const Icon = PDF_TOOL_ICONS[t.id];
586
+ return /* @__PURE__ */ jsx3("li", { role: "none", children: /* @__PURE__ */ jsxs3(
587
+ "button",
588
+ {
589
+ type: "button",
590
+ role: "menuitem",
591
+ "aria-current": t.id === tool ? "true" : void 0,
592
+ className: cn("flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", t.id === tool && "bg-accent"),
593
+ onClick: () => onPick(t.id),
594
+ children: [
595
+ /* @__PURE__ */ jsx3(Icon, { className: "size-4 shrink-0" }),
596
+ /* @__PURE__ */ jsx3("span", { className: "flex-1 whitespace-nowrap", children: t.label }),
597
+ t.status === "soon" ? /* @__PURE__ */ jsx3("span", { className: "text-muted-foreground", children: "Coming soon" }) : null
598
+ ]
599
+ }
600
+ ) }, t.id);
601
+ })
602
+ ] });
586
603
  }
587
604
  function PdfWorkspace({ host, className }) {
588
605
  const rootRef = useRef2(null);
@@ -596,6 +613,10 @@ function PdfWorkspace({ host, className }) {
596
613
  const decisions = history.present.value;
597
614
  const dirty = isDirty(decisions);
598
615
  const [tool, setTool] = useState3("browse");
616
+ const [hostToolId, setHostToolId] = useState3(null);
617
+ const hostTools = useMemo2(() => host.tools ?? [], [host.tools]);
618
+ const hostTool = hostToolId ? hostTools.find((t) => t.id === hostToolId) ?? null : null;
619
+ const activeToolKey = hostTool ? `host:${hostTool.id}` : tool;
599
620
  const [leftOpen, setLeftOpen] = useState3(true);
600
621
  const [rightOpen, setRightOpen] = useState3(true);
601
622
  const [leftTab, setLeftTab] = useState3("pages");
@@ -748,8 +769,17 @@ function PdfWorkspace({ host, className }) {
748
769
  const discard = useCallback(() => setHistory(startHistory(freshDecisions(pageCount))), [pageCount]);
749
770
  const chooseTool = useCallback(
750
771
  (id) => {
772
+ if (id.startsWith("host:")) {
773
+ setHostToolId(id.slice(5));
774
+ setResult(null);
775
+ setError(null);
776
+ setRightOpen(true);
777
+ if (compact) setSheet("tools");
778
+ return;
779
+ }
751
780
  const def = pdfTool(id);
752
781
  if (!def) return;
782
+ setHostToolId(null);
753
783
  if (def.status === "soon") {
754
784
  announceSoon(comingSoonIdOf(def.id)).catch(fail);
755
785
  return;
@@ -772,9 +802,10 @@ function PdfWorkspace({ host, className }) {
772
802
  if (t.status !== "ready") continue;
773
803
  groups[t.group].push({ id: t.id, label: t.label, icon: PDF_TOOL_ICONS[t.id], ...t.key ? { shortcut: t.key.toUpperCase() } : null });
774
804
  }
805
+ for (const t of hostTools) groups[t.group ?? 1].push({ id: `host:${t.id}`, label: t.label, icon: t.icon });
775
806
  groups[2].push({ id: ALL_TOOLS, label: "All tools", icon: MoreHorizontalIcon });
776
807
  return groups.filter((g) => g.length);
777
- }, []);
808
+ }, [hostTools]);
778
809
  const runAction = useCallback(
779
810
  (action) => {
780
811
  if (action.startsWith("tool:")) return chooseTool(action.slice(5));
@@ -862,7 +893,10 @@ function PdfWorkspace({ host, className }) {
862
893
  }
863
894
  );
864
895
  const iconBtn = (label, icon, onClick, opts) => /* @__PURE__ */ jsx3(Button2, { variant: "quiet", icon, "aria-label": label, title: label, onClick, ...opts?.disabled !== void 0 ? { disabled: opts.disabled } : null, ...opts?.pressed !== void 0 ? { pressed: opts.pressed } : null });
865
- const toolHits = toolQuery.trim() ? PDF_TOOLS.filter((t) => t.label.toLowerCase().includes(toolQuery.trim().toLowerCase())) : [];
896
+ const toolHits = toolQuery.trim() ? [
897
+ ...hostTools.map((t) => ({ id: `host:${t.id}`, label: t.label, status: "ready" })),
898
+ ...PDF_TOOLS
899
+ ].filter((t) => t.label.toLowerCase().includes(toolQuery.trim().toLowerCase())) : [];
866
900
  const nameNode = editingName && host.rename ? /* @__PURE__ */ jsx3(
867
901
  Field2,
868
902
  {
@@ -893,7 +927,13 @@ function PdfWorkspace({ host, className }) {
893
927
  children: host.file.name
894
928
  }
895
929
  );
896
- const rightPanel = /* @__PURE__ */ jsxs3("div", { className: "flex h-full min-h-0 flex-col", children: [
930
+ const rightPanel = hostTool ? /* @__PURE__ */ jsxs3("div", { className: "flex h-full min-h-0 flex-col", "data-pdf-host-tool": hostTool.id, children: [
931
+ /* @__PURE__ */ jsxs3("div", { className: "shrink-0 border-b border-border px-3 py-2", children: [
932
+ /* @__PURE__ */ jsx3("div", { className: "text-sm font-medium", children: hostTool.label }),
933
+ hostTool.hint ? /* @__PURE__ */ jsx3("div", { className: "text-xs text-muted-foreground", children: hostTool.hint }) : null
934
+ ] }),
935
+ /* @__PURE__ */ jsx3("div", { className: "min-h-0 flex-1 overflow-hidden", children: hostTool.render({ currentPage, pageCount, selected: selectedPages, goToPage, reload: () => setReloadKey((k) => k + 1) }) })
936
+ ] }) : /* @__PURE__ */ jsxs3("div", { className: "flex h-full min-h-0 flex-col", children: [
897
937
  /* @__PURE__ */ jsxs3("div", { className: "shrink-0 border-b border-border px-3 py-2", children: [
898
938
  /* @__PURE__ */ jsx3("div", { className: "text-sm font-medium", children: toolDef.label }),
899
939
  toolDef.hint ? /* @__PURE__ */ jsx3("div", { className: "text-xs text-muted-foreground", children: toolDef.hint }) : null
@@ -940,9 +980,10 @@ function PdfWorkspace({ host, className }) {
940
980
  onLayersSoon: () => void announceSoon("pdf.layers").catch(fail)
941
981
  }
942
982
  );
983
+ const viewerPage = hostTool?.followsPage ? currentPage : 1;
943
984
  const viewer = useMemo2(
944
- () => /* @__PURE__ */ jsx3(Fragment2, { children: host.renderViewer({ zoom, spread, rotations: decisions.turns, reloadKey, onDocumentLoad, onPageSize }) }, reloadKey),
945
- [host, reloadKey, zoom, spread, decisions.turns, onDocumentLoad, onPageSize]
985
+ () => /* @__PURE__ */ jsx3(Fragment2, { children: host.renderViewer({ zoom, spread, rotations: decisions.turns, reloadKey, currentPage: viewerPage, onDocumentLoad, onPageSize }) }, reloadKey),
986
+ [host, reloadKey, zoom, spread, decisions.turns, viewerPage, onDocumentLoad, onPageSize]
946
987
  );
947
988
  const showChrome = !read;
948
989
  const popCard = "absolute right-2 top-11 z-30 rounded-lg border border-border bg-popover p-3 text-popover-foreground shadow-lg";
@@ -1055,15 +1096,15 @@ function PdfWorkspace({ host, className }) {
1055
1096
  iconBtn("Reading mode", /* @__PURE__ */ jsx3(ExpandIcon, {}), () => setRead(true))
1056
1097
  ] }) : null,
1057
1098
  /* @__PURE__ */ jsxs3("div", { className: "relative flex min-h-0 flex-1", children: [
1058
- showChrome && !compact ? /* @__PURE__ */ jsx3("div", { className: "flex w-10 shrink-0 flex-col items-center border-r border-border bg-background py-2", "data-pdf-rail": "", children: /* @__PURE__ */ jsx3(ToolRail, { groups: railGroups, value: pop === "all-tools" ? ALL_TOOLS : tool, onValueChange: (id) => id === ALL_TOOLS ? setPop((p) => p === "all-tools" ? null : "all-tools") : id && chooseTool(id), "aria-label": "PDF tools" }) }) : null,
1099
+ showChrome && !compact ? /* @__PURE__ */ jsx3("div", { className: "flex w-10 shrink-0 flex-col items-center border-r border-border bg-background py-2", "data-pdf-rail": "", children: /* @__PURE__ */ jsx3(ToolRail, { groups: railGroups, value: pop === "all-tools" ? ALL_TOOLS : activeToolKey, onValueChange: (id) => id === ALL_TOOLS ? setPop((p) => p === "all-tools" ? null : "all-tools") : id && chooseTool(id), "aria-label": "PDF tools" }) }) : null,
1059
1100
  showChrome && !compact && leftOpen ? /* @__PURE__ */ jsx3("aside", { className: "w-56 shrink-0 border-r border-border bg-background", "aria-label": "Pages", "data-pdf-left": "", children: leftPanel }) : null,
1060
1101
  /* @__PURE__ */ jsxs3("main", { className: "relative flex min-w-0 flex-1 flex-col", children: [
1061
1102
  findOpen ? /* @__PURE__ */ jsx3("div", { className: "absolute right-4 top-2 z-20", children: /* @__PURE__ */ jsx3(RenderedFindBar, { rootRef: scrollerRef, onClose: () => setFindOpen(false), label: "Find in document", focusRequest: findFocus, compact: true }) }) : null,
1062
1103
  /* @__PURE__ */ jsx3("div", { ref: scrollerRef, tabIndex: 0, "data-pdf-scroller": "", className: "min-h-0 flex-1 overflow-auto bg-muted outline-none", children: viewer }),
1063
1104
  read ? /* @__PURE__ */ jsx3("div", { className: "absolute right-3 top-3 z-20", children: /* @__PURE__ */ jsx3(Button2, { variant: "outline", icon: /* @__PURE__ */ jsx3(XIcon, {}), onClick: () => setRead(false), children: "Exit reading mode" }) }) : null
1064
1105
  ] }),
1065
- showChrome && !compact && rightOpen ? /* @__PURE__ */ jsx3("aside", { className: "w-72 shrink-0 border-l border-border bg-background", "aria-label": "Properties", "data-pdf-right": "", children: rightPanel }) : null,
1066
- pop === "all-tools" ? /* @__PURE__ */ jsx3("ul", { role: "menu", "aria-label": "All tools", className: "absolute left-12 top-2 z-30 w-72 rounded-lg border border-border bg-popover p-1 shadow-lg", "data-pdf-all-tools": "", children: /* @__PURE__ */ jsx3(ToolRows, { tool, onPick: (id) => {
1106
+ showChrome && !compact && rightOpen ? /* @__PURE__ */ jsx3("aside", { className: cn("shrink-0 border-l border-border bg-background", hostTool?.wide ? "w-[28rem]" : "w-72"), "aria-label": "Properties", "data-pdf-right": "", children: rightPanel }) : null,
1107
+ pop === "all-tools" ? /* @__PURE__ */ jsx3("ul", { role: "menu", "aria-label": "All tools", className: "absolute left-12 top-2 z-30 w-72 rounded-lg border border-border bg-popover p-1 shadow-lg", "data-pdf-all-tools": "", children: /* @__PURE__ */ jsx3(ToolRows, { tool: activeToolKey, hostTools, onPick: (id) => {
1067
1108
  setPop(null);
1068
1109
  chooseTool(id);
1069
1110
  } }) }) : null,
@@ -1094,7 +1135,7 @@ function PdfWorkspace({ host, className }) {
1094
1135
  compact && sheet ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
1095
1136
  /* @__PURE__ */ jsx3("button", { type: "button", "aria-label": "Close", className: "absolute inset-0 z-30 bg-background/60", onClick: () => setSheet(null) }),
1096
1137
  /* @__PURE__ */ jsx3("div", { className: "absolute inset-x-0 bottom-0 z-40 flex max-h-[75%] flex-col rounded-t-xl border-t border-border bg-background", role: "dialog", "aria-label": sheet === "pages" ? "Pages" : "Tools", children: sheet === "pages" ? /* @__PURE__ */ jsx3("div", { className: "h-[60vh] min-h-0", children: leftPanel }) : /* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 flex-col overflow-y-auto", children: [
1097
- /* @__PURE__ */ jsx3("ul", { className: "p-2", role: "menu", "aria-label": "Tools", children: /* @__PURE__ */ jsx3(ToolRows, { tool, onPick: chooseTool }) }),
1138
+ /* @__PURE__ */ jsx3("ul", { className: "p-2", role: "menu", "aria-label": "Tools", children: /* @__PURE__ */ jsx3(ToolRows, { tool: activeToolKey, hostTools, onPick: chooseTool }) }),
1098
1139
  /* @__PURE__ */ jsx3("div", { className: "border-t border-border", children: rightPanel })
1099
1140
  ] }) })
1100
1141
  ] }) : null