@inkbar/react 0.5.0 → 0.6.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/README.md CHANGED
@@ -151,11 +151,29 @@ The highlight tool leaves `contents` free for the comment. `doc.text(page)` retu
151
151
 
152
152
  `InkSignatureMenu` lists saved signatures, picks one for the `signature` tool, removes them, and opens `InkSignatureDialog` to draw, type or upload a new one. These are marks on the page, not cryptographic signatures. Pass `signatures` to `InkRoot` to keep them somewhere: `createLocalSignatureStore(key)` from `@inkbar/core` uses `localStorage`, and without it they last until reload. `signatureFonts` lists the handwriting fonts the Type tab offers; load them with `@font-face`. A placed signature keeps its aspect ratio when resized.
153
153
 
154
+ ## Plugins
155
+
156
+ A plugin from `definePlugin` (in `@inkbar/core/dom`) adds commands, tools, decorations, page layers and its own record stores. Pass plugins to `InkRoot` once: the prop is read when the root mounts. Nothing a plugin registers shows until you place it:
157
+
158
+ ```tsx
159
+ <InkRoot src={src} assets={assets} plugins={[suggestions]}>
160
+ <InkToolbar>
161
+ <InkCommand id="sandbox.suggest" />
162
+ <InkToolButton tool="sandbox.stamp" />
163
+ </InkToolbar>
164
+ <InkViewport />
165
+ </InkRoot>
166
+ ```
167
+
168
+ `InkCommand` is a button named by the command's label, disabled while the command is, and its status in a live region beside it. While the command runs, the button keeps focus and has `aria-busy` and `aria-disabled`, and pressing it does nothing. It shows the command's icon, or its label as text when the command has no icon. To build your own, `useCommand(id)` returns `run`, `enabled`, `busy`, `status`, `label` and `icon`. Plugins are set up once `InkRoot` has mounted in the browser, never on the server. Until then the command is disabled and has no label, and `InkCommand` keeps its button out of the accessibility tree (`aria-hidden`). An id no plugin registered stays that way: `InkCommand` and `useCommand` log an `InkError('UnknownCommand')` to the console once, naming the id and the registered ones, and nothing throws. `InkToolButton` takes a plugin tool's own label and icon.
169
+
170
+ Plugin stores undo with annotations. In controlled mode with `history`, each undo step also snapshots the plugin stores, so accepting something and undoing it restores both.
171
+
154
172
  ## Custom rendering
155
173
 
156
- Slots are render props. `InkViewport` takes `loading`, `empty`, `error`, `renderAnnotation` and `renderPageError`; `InkThreadPopover` takes a function as `children`; `InkToolButton` takes a node or a function of `{ active, label }`. The props each receives are typed as `AnnotationSlotProps` and `ThreadPopoverSlotProps`, the same types the Vue package exports.
174
+ Slots are render props. `InkViewport` takes `loading`, `empty`, `error`, `renderAnnotation` and `renderPageError`; `InkThreadPopover` takes a function as `children`; `InkToolButton` takes a node or a function of `{ active, label }`; `InkCommand` a node or a function of `{ label, busy }`. The props each receives are typed as `AnnotationSlotProps` and `ThreadPopoverSlotProps`, the same types the Vue package exports.
157
175
 
158
- `InkRoot`, `InkToolbar`, `InkToolButton`, `InkUndo`, `InkRedo`, `InkPrevPage`, `InkNextPage`, `InkZoomIn` and `InkZoomOut` take `asChild` to render your own element in place of theirs, such as a button from your design system. Pass that element as the only child. The control keeps its behaviour and accessible name.
176
+ `InkRoot`, `InkToolbar`, `InkToolButton`, `InkCommand`, `InkUndo`, `InkRedo`, `InkPrevPage`, `InkNextPage`, `InkZoomIn` and `InkZoomOut` take `asChild` to render your own element in place of theirs, such as a button from your design system. Pass that element as the only child. The control keeps its behaviour and accessible name.
159
177
 
160
178
  ## Keyboard
161
179
 
@@ -181,7 +199,7 @@ Components carry state on data attributes, for example `[data-annotation][data-s
181
199
 
182
200
  ## Hooks
183
201
 
184
- `useDocument`, `useAnnotations`, `useTool`, `useSelection`, `useZoom`, `usePage`, `useHistory` and `useEmbedded` read the state of the nearest `InkRoot`. Build your own toolbar or side panel from them. Tool options, such as the shape kind, last as long as `InkRoot`. The tool style that `useToolStyle` reads and sets (colours, line style, text style) belongs to the document: opening another one starts again from the theme's defaults.
202
+ `useDocument`, `useAnnotations`, `useTool`, `useSelection`, `useZoom`, `usePage`, `useHistory`, `useEmbedded` and `useCommand` read the state of the nearest `InkRoot`. Build your own toolbar or side panel from them. Tool options, such as the shape kind, last as long as `InkRoot`. The tool style that `useToolStyle` reads and sets (colours, line style, text style) belongs to the document: opening another one starts again from the theme's defaults.
185
203
 
186
204
  ## Licence
187
205
 
package/dist/index.d.mts CHANGED
@@ -1,11 +1,14 @@
1
1
  import { ComponentPropsWithoutRef, ReactNode, Ref } from "react";
2
- import { Annotation, AnnotationChange, AnnotationDefaults, AnnotationDocument, AnnotationInput, AnnotationPatch, CurrentStyle, DocumentSource, ImportOptions, InkDocument, InkError, InkStatus, PageInfo, PdfAssets, Readable, SignatureLibrary, SignatureStore, SignatureTemplate, StyleGroup, StyleKey, StyleProps } from "@inkbar/core";
3
- import { AnnotationDecoration, AnnotationSlotProps, AnnotationSlotProps as AnnotationSlotProps$1, AnnotationState, ColorProperty, DecorateAnnotation, DecorateAnnotation as DecorateAnnotation$1, LayoutMode, PageMount, ThreadPopoverSlotProps, ThreadPopoverSlotProps as ThreadPopoverSlotProps$1, Tool, ToolController, ToolId, ToolOptions, ToolStyle, ViewRotation, Viewport, ZoomValue } from "@inkbar/core/dom";
2
+ import { Annotation, AnnotationChange, AnnotationDefaults, AnnotationDocument, AnnotationInput, AnnotationPatch, CurrentStyle, DocumentSource, ImportOptions, InkDocument, InkError, InkStatus, PageInfo, PdfAssets, PluginHistory, Readable, SignatureLibrary, SignatureStore, SignatureTemplate, StyleGroup, StyleKey, StyleProps, Writable } from "@inkbar/core";
3
+ import { AnnotationDecoration, AnnotationSlotProps, AnnotationSlotProps as AnnotationSlotProps$1, AnnotationState, ColorProperty, DecorateAnnotation, DecorateAnnotation as DecorateAnnotation$1, InkPlugin, InkPlugin as InkPlugin$1, LayoutMode, PageMount, PluginHost, ThreadPopoverSlotProps, ThreadPopoverSlotProps as ThreadPopoverSlotProps$1, Tool, ToolController, ToolId, ToolOptions, ToolStyle, ViewRotation, Viewport, ZoomValue } from "@inkbar/core/dom";
4
4
  import { Select } from "radix-ui";
5
5
  import { IconNode } from "@inkbar/icons";
6
6
  //#region src/context.d.ts
7
- /** Undo and redo for the current document, whichever mode its annotations are in. */
8
- interface InkHistory {
7
+ /**
8
+ * Undo and redo for the current document, whichever mode its annotations are in. `track` and
9
+ * `react` (from `PluginHistory`) reach the same history, so plugin stores undo with the edits.
10
+ */
11
+ interface InkHistory extends PluginHistory {
9
12
  canUndo: boolean;
10
13
  canRedo: boolean;
11
14
  undo: () => void;
@@ -26,6 +29,14 @@ interface InkContext {
26
29
  status: InkStatus;
27
30
  annotations: readonly Annotation[];
28
31
  selection: readonly string[];
32
+ /**
33
+ * The plugins from InkRoot's `plugins` prop, set up once the root has mounted and kept for
34
+ * its life; `null` before that, and on the server. InkViewport hands it to the engine;
35
+ * InkCommand places its commands.
36
+ */
37
+ pluginHost: PluginHost | null;
38
+ /** InkViewport's scroll element while it is mounted: the plugins' `root`. */
39
+ viewportEl: Writable<HTMLElement | null>;
29
40
  /** Set by InkViewport once it has built its viewport and tool controller. */
30
41
  viewport: Viewport | null;
31
42
  tools: ToolController | null;
@@ -2620,6 +2631,28 @@ export declare function useEmbedded(): {
2620
2631
  hasAny: boolean;
2621
2632
  };
2622
2633
  //#endregion
2634
+ //#region src/hooks/useCommand.d.ts
2635
+ interface CommandHandle {
2636
+ /** Runs the command; does nothing while it is busy or disabled. Never rejects. */
2637
+ run: () => Promise<void>;
2638
+ /** A ready document (or the plugin's own condition), and not busy. */
2639
+ enabled: boolean;
2640
+ busy: boolean;
2641
+ /** The command's progress or result message, `''` without one. */
2642
+ status: string;
2643
+ /** `''` until the plugins are set up. */
2644
+ label: string;
2645
+ icon: IconNode | undefined;
2646
+ }
2647
+ /**
2648
+ * A plugin command by its namespaced id (`sandbox.suggest`), for hosts building their own
2649
+ * control. Plugins are set up once InkRoot has mounted, so until then (and on the server) the
2650
+ * command is disabled with no label; it fills in then. Once they are set up, an id no plugin
2651
+ * passed to InkRoot registered stays that way, and logs `InkError('UnknownCommand')` to the
2652
+ * console once.
2653
+ */
2654
+ export declare function useCommand(id: string): CommandHandle;
2655
+ //#endregion
2623
2656
  //#region src/components/InkRoot.d.ts
2624
2657
  interface InkRootHandle {
2625
2658
  readonly document: InkDocument | null;
@@ -2649,6 +2682,12 @@ interface InkRootProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'
2649
2682
  * document opens.
2650
2683
  */
2651
2684
  tools?: Tool[] | undefined;
2685
+ /**
2686
+ * Plugins, set up once when the root mounts; a later change to this prop is not applied.
2687
+ * Their tools join `tools`, their decoration and page layers apply to every document, and
2688
+ * their commands are placed with `InkCommand` or `useCommand`.
2689
+ */
2690
+ plugins?: InkPlugin$1[] | undefined;
2652
2691
  /**
2653
2692
  * Adds `data-*` attributes, classes and a screen-reader description to each annotation's
2654
2693
  * element (see `DecorateAnnotation`). Decorations re-apply whenever the annotations change
@@ -2685,7 +2724,7 @@ interface InkRootProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'
2685
2724
  }) => ReactNode);
2686
2725
  ref?: Ref<InkRootHandle>;
2687
2726
  }
2688
- export declare function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsChange, onChange, tool, onToolChange, tools: hostTools, decorateAnnotation, fonts: fontsProp, signatures: signatureStore, signatureFonts: signatureFontsProp, page, onPageChange, zoom, onZoomChange, history, asChild, onReady, onError, onActivate, children, ref, ...rest }: InkRootProps): import("react").JSX.Element;
2727
+ export declare function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsChange, onChange, tool, onToolChange, tools: hostTools, plugins: pluginsProp, decorateAnnotation, fonts: fontsProp, signatures: signatureStore, signatureFonts: signatureFontsProp, page, onPageChange, zoom, onZoomChange, history, asChild, onReady, onError, onActivate, children, ref, ...rest }: InkRootProps): import("react").JSX.Element;
2689
2728
  //#endregion
2690
2729
  //#region src/components/InkViewport.d.ts
2691
2730
  interface InkViewportProps extends ComponentPropsWithoutRef<'div'> {
@@ -2764,6 +2803,18 @@ interface InkToolButtonProps extends Omit<ComponentPropsWithoutRef<'button'>, 'c
2764
2803
  }
2765
2804
  export declare function InkToolButton({ tool, label, asChild, className, children, onClick, ...rest }: InkToolButtonProps): import("react").JSX.Element;
2766
2805
  //#endregion
2806
+ //#region src/components/InkCommand.d.ts
2807
+ interface InkCommandProps extends Omit<ComponentPropsWithoutRef<'button'>, 'id' | 'children'> {
2808
+ /** The command's namespaced id, such as `sandbox.suggest`. */
2809
+ id: string;
2810
+ asChild?: boolean;
2811
+ children?: ReactNode | ((props: {
2812
+ label: string;
2813
+ busy: boolean;
2814
+ }) => ReactNode);
2815
+ }
2816
+ export declare function InkCommand({ id, asChild, children, disabled, onClick, ...rest }: InkCommandProps): import("react").JSX.Element;
2817
+ //#endregion
2767
2818
  //#region src/components/InkToolbarSeparator.d.ts
2768
2819
  type InkToolbarSeparatorProps = ComponentPropsWithoutRef<'div'>;
2769
2820
  /**
@@ -2898,5 +2949,5 @@ interface InkThreadPopoverProps {
2898
2949
  }
2899
2950
  export declare function InkThreadPopover({ children }: InkThreadPopoverProps): import("react").JSX.Element;
2900
2951
  //#endregion
2901
- export type { AnnotationDecoration, AnnotationSlotProps, AnnotationState, DecorateAnnotation, InkAnnotationProps, InkColorMenuProps, InkContext, InkHighlightMenuProps, InkHistory, InkHistoryButtonProps, InkIconProps, InkLineStyleMenuProps, InkPageButtonProps, InkPageInputProps, InkPageProps, InkRootHandle, InkRootProps, InkShapeMenuProps, InkSignatureDialogProps, InkSignatureMenuProps, InkStatus, InkTextStyleMenuProps, InkThreadPopoverProps, InkToolButtonProps, InkToolbarProps, InkToolbarSeparatorProps, InkViewportProps, InkZoomButtonProps, InkZoomSelectProps, ScopedToolStyleHandle, ThreadPopoverSlotProps, ToolStyleHandle };
2952
+ export type { AnnotationDecoration, AnnotationSlotProps, AnnotationState, CommandHandle, DecorateAnnotation, InkAnnotationProps, InkColorMenuProps, InkCommandProps, InkContext, InkHighlightMenuProps, InkHistory, InkHistoryButtonProps, InkIconProps, InkLineStyleMenuProps, InkPageButtonProps, InkPageInputProps, InkPageProps, InkPlugin, InkRootHandle, InkRootProps, InkShapeMenuProps, InkSignatureDialogProps, InkSignatureMenuProps, InkStatus, InkTextStyleMenuProps, InkThreadPopoverProps, InkToolButtonProps, InkToolbarProps, InkToolbarSeparatorProps, InkViewportProps, InkZoomButtonProps, InkZoomSelectProps, ScopedToolStyleHandle, ThreadPopoverSlotProps, ToolStyleHandle };
2902
2953
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":["DecorateAnnotation","DecorateAnnotation","AnnotationSlotProps","AnnotationSlotProps","AnnotationSlotProps","ThreadPopoverSlotProps"],"sources":["../src/context.ts","../src/use-readable.ts","../src/hooks/useDocument.ts","../src/hooks/useAnnotations.ts","../src/hooks/useTool.ts","../src/hooks/useToolStyle.ts","../src/hooks/useToolOptions.ts","../src/hooks/useSelection.ts","../src/hooks/useZoom.ts","../src/hooks/usePage.ts","../src/hooks/useHistory.ts","../src/hooks/useEmbedded.ts","../src/components/InkRoot.tsx","../src/components/InkViewport.tsx","../src/components/InkPage.tsx","../src/components/InkAnnotation.tsx","../src/components/InkToolbar.tsx","../src/components/InkIcon.tsx","../src/components/InkToolButton.tsx","../src/components/InkToolbarSeparator.tsx","../src/components/history-button.ts","../src/components/InkUndo.tsx","../src/components/InkRedo.tsx","../src/components/zoom-button.ts","../src/components/InkZoomIn.tsx","../src/components/InkZoomOut.tsx","../src/components/InkZoomSelect.tsx","../src/components/InkPageInput.tsx","../src/components/InkPageCount.tsx","../src/components/page-button.ts","../src/components/InkPrevPage.tsx","../src/components/InkNextPage.tsx","../src/components/InkColorMenu.tsx","../src/components/InkShapeMenu.tsx","../src/components/InkSignatureMenu.tsx","../src/components/InkSignatureDialog.tsx","../src/components/InkHighlightMenu.tsx","../src/components/InkTextStyleMenu.tsx","../src/components/InkLineStyleMenu.tsx","../src/components/InkThreadPopover.tsx"],"mappings":";;;;;;;UAuBiB;EACf;EACA;EACA;EACA;EACA;;;;;;;EAOA,QAAQ;;UAGO;EACf,QAAQ;EACR,UAAU;;EAEV,QAAQ;EACR,sBAAsB;EACtB;;EAEA,UAAU;EACV,OAAO;;EAEP,MAAM;EACN,UAAU,IAAI;;EAEd,WAAW;;;;;EAKX,oBAAoBA;;;;;EAKpB,6BAA6B;;EAE7B;;EAEA,aAAa;;EAEb,YAAY;;EAEZ;;EAEA,WAAW;;EAEX,WAAW;EACX;EACA,aAAa,GAAG;EAChB,aAAa;;EAEb;;;;;;EAMA,eAAe;EACf,SAAS;EACT,QAAQ;EACR,cAAc,UAAU,iBAAiB,OAAO;;;;;;wBASlC,cAAc,mBAAmB;;;;;;;;wBCtFjC,YAAY,GAAG,UAAU,SAAS,uBAAuB,UAAU,IAAI;;;wBCHvE;;;;;;;;EAYgB,oBAAA,MAAA,6BAA2B,OAAS,yCAAa;;;;wBCbjE;EAcG,MAAA,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EACA,SAAA,YAAM,OAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EACf,SAAA;EACC,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASC,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
1
+ {"version":3,"file":"index.d.mts","names":["DecorateAnnotation","InkPlugin","DecorateAnnotation","AnnotationSlotProps","AnnotationSlotProps","AnnotationSlotProps","ThreadPopoverSlotProps"],"sources":["../src/context.ts","../src/use-readable.ts","../src/hooks/useDocument.ts","../src/hooks/useAnnotations.ts","../src/hooks/useTool.ts","../src/hooks/useToolStyle.ts","../src/hooks/useToolOptions.ts","../src/hooks/useSelection.ts","../src/hooks/useZoom.ts","../src/hooks/usePage.ts","../src/hooks/useHistory.ts","../src/hooks/useEmbedded.ts","../src/hooks/useCommand.ts","../src/components/InkRoot.tsx","../src/components/InkViewport.tsx","../src/components/InkPage.tsx","../src/components/InkAnnotation.tsx","../src/components/InkToolbar.tsx","../src/components/InkIcon.tsx","../src/components/InkToolButton.tsx","../src/components/InkCommand.tsx","../src/components/InkToolbarSeparator.tsx","../src/components/history-button.ts","../src/components/InkUndo.tsx","../src/components/InkRedo.tsx","../src/components/zoom-button.ts","../src/components/InkZoomIn.tsx","../src/components/InkZoomOut.tsx","../src/components/InkZoomSelect.tsx","../src/components/InkPageInput.tsx","../src/components/InkPageCount.tsx","../src/components/page-button.ts","../src/components/InkPrevPage.tsx","../src/components/InkNextPage.tsx","../src/components/InkColorMenu.tsx","../src/components/InkShapeMenu.tsx","../src/components/InkSignatureMenu.tsx","../src/components/InkSignatureDialog.tsx","../src/components/InkHighlightMenu.tsx","../src/components/InkTextStyleMenu.tsx","../src/components/InkLineStyleMenu.tsx","../src/components/InkThreadPopover.tsx"],"mappings":";;;;;;;;;;UA6BiB,mBAAmB;EAClC;EACA;EACA;EACA;EACA;;;;;;;EAOA,QAAQ;;UAGO;EACf,QAAQ;EACR,UAAU;;EAEV,QAAQ;EACR,sBAAsB;EACtB;;;;;;EAMA,YAAY;;EAEZ,YAAY,SAAS;;EAErB,UAAU;EACV,OAAO;;EAEP,MAAM;EACN,UAAU,IAAI;;EAEd,WAAW;;;;;EAKX,oBAAoBA;;;;;EAKpB,6BAA6B;;EAE7B;;EAEA,aAAa;;EAEb,YAAY;;EAEZ;;EAEA,WAAW;;EAEX,WAAW;EACX;EACA,aAAa,GAAG;EAChB,aAAa;;EAEb;;;;;;EAMA,eAAe;EACf,SAAS;EACT,QAAQ;EACR,cAAc,UAAU,iBAAiB,OAAO;;;;;;wBASlC,cAAc,mBAAmB;;;;;;;;wBCpGjC,YAAY,GAAG,UAAU,SAAS,uBAAuB,UAAU,IAAI;;;wBCHvE;;;;;;;;EAYgB,oBAAA,MAAA,6BAA2B,OAAS,yCAAa;;;;wBCbjE;EAcG,MAAA,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EACA,SAAA,YAAM,OAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EACf,SAAA;EACC,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASC,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Fragment, createContext, createElement, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
3
- import { InkError, createMemorySignatureStore, createSignatureLibrary, createSnapshotHistory, isAbandonedNote, openDocument, repliesTo, threadOf, threadRoot } from "@inkbar/core";
4
- import { COLOR_COLUMNS, FONT_FAMILIES, MARKUP_ICONS, MARKUP_KINDS, SHAPE_COLUMNS, SHAPE_ICONS, SHAPE_KINDS, SIGNATURE_FONTS, SIGNATURE_LABELS, SIGNATURE_TABS, TOOL_LABELS, ZOOM_LEVELS, colorMenuModel, createFocusReturn, createSignatureDraft, createToolOptions, cssVariableDefaults, focusInitialMenuItem, fontFamilyValue, handleMenuKeys, handleRadioKeys, handleTabKeys, highlightMenuModel, lineStyleMenuModel, menuItems, mountViewer, observeAnnotationElement, shapeMenuModel, shouldKeepOpenOnAnnotation, signatureMenuModel, signaturePreview, textStyleMenuModel, threadDeleteLabel, threadPopoverLabel, trackToolStyle } from "@inkbar/core/dom";
3
+ import { InkError, createMemorySignatureStore, createSignatureLibrary, createSnapshotHistory, isAbandonedNote, openDocument, readonly, repliesTo, threadOf, threadRoot, writable } from "@inkbar/core";
4
+ import { COLOR_COLUMNS, FONT_FAMILIES, MARKUP_ICONS, MARKUP_KINDS, SHAPE_COLUMNS, SHAPE_ICONS, SHAPE_KINDS, SIGNATURE_FONTS, SIGNATURE_LABELS, SIGNATURE_TABS, TOOL_LABELS, ZOOM_LEVELS, colorMenuModel, createFocusReturn, createPluginHost, createSignatureDraft, createToolOptions, cssVariableDefaults, focusInitialMenuItem, fontFamilyValue, handleMenuKeys, handleRadioKeys, handleTabKeys, highlightMenuModel, lineStyleMenuModel, menuItems, mountViewer, observeAnnotationElement, shapeMenuModel, shouldKeepOpenOnAnnotation, signatureMenuModel, signaturePreview, textStyleMenuModel, threadDeleteLabel, threadPopoverLabel, trackToolStyle, unknownCommand } from "@inkbar/core/dom";
5
5
  import { Dialog, Popover, Select, Slot, Toolbar } from "radix-ui";
6
6
  import { createPortal, flushSync } from "react-dom";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -19,14 +19,14 @@ function useInkContext(consumer) {
19
19
  }
20
20
  //#endregion
21
21
  //#region src/use-readable.ts
22
- const noop = () => void 0;
22
+ const noop$1 = () => void 0;
23
23
  /**
24
24
  * Mirrors a core `Readable` into React. A missing readable yields `fallback`, which must be a
25
25
  * stable reference (a module constant): `useSyncExternalStore` compares snapshots by identity
26
26
  * and loops on a fresh value. On the server the fallback is rendered.
27
27
  */
28
28
  function useReadable(readable, fallback) {
29
- const subscribe = useCallback((onChange) => readable ? readable.subscribe(() => onChange()) : noop, [readable]);
29
+ const subscribe = useCallback((onChange) => readable ? readable.subscribe(() => onChange()) : noop$1, [readable]);
30
30
  const get = useCallback(() => readable ? readable.get() : fallback, [readable, fallback]);
31
31
  const server = useCallback(() => fallback, [fallback]);
32
32
  return useSyncExternalStore(subscribe, get, server);
@@ -190,6 +190,40 @@ function useEmbedded() {
190
190
  }), [summary]);
191
191
  }
192
192
  //#endregion
193
+ //#region src/hooks/useCommand.ts
194
+ /**
195
+ * A plugin command by its namespaced id (`sandbox.suggest`), for hosts building their own
196
+ * control. Plugins are set up once InkRoot has mounted, so until then (and on the server) the
197
+ * command is disabled with no label; it fills in then. Once they are set up, an id no plugin
198
+ * passed to InkRoot registered stays that way, and logs `InkError('UnknownCommand')` to the
199
+ * console once.
200
+ */
201
+ function useCommand(id) {
202
+ const { pluginHost } = useInkContext("useCommand()");
203
+ const command = pluginHost?.command(id);
204
+ const logged = useRef(false);
205
+ useEffect(() => {
206
+ if (!pluginHost || command || logged.current) return;
207
+ logged.current = true;
208
+ console.error(unknownCommand(id, [...pluginHost.commands.keys()]));
209
+ }, [
210
+ pluginHost,
211
+ command,
212
+ id
213
+ ]);
214
+ const enabled = useReadable(command?.enabled, false);
215
+ const busy = useReadable(command?.busy, false);
216
+ const status = useReadable(command?.status, "");
217
+ return {
218
+ run: useCallback(async () => command?.run(), [command]),
219
+ enabled,
220
+ busy,
221
+ status,
222
+ label: command?.label ?? "",
223
+ icon: command?.icon
224
+ };
225
+ }
226
+ //#endregion
193
227
  //#region src/use-latest.ts
194
228
  /**
195
229
  * A ref that always holds the latest render's value, for callbacks that outlive a render
@@ -209,6 +243,7 @@ function useLatest(value) {
209
243
  const IDLE$1 = { state: "idle" };
210
244
  const NO_ANNOTATIONS = [];
211
245
  const NO_IDS = [];
246
+ const noop = () => void 0;
212
247
  /** Signed URLs change; the key does not. Bytes and Blobs are their own identity. */
213
248
  function identity(src) {
214
249
  if (src === null) return null;
@@ -226,7 +261,7 @@ function isDevelopment() {
226
261
  function setTestHook(el, doc) {
227
262
  if (el && isDevelopment()) el.__inkDocument = doc;
228
263
  }
229
- function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsChange, onChange, tool, onToolChange, tools: hostTools, decorateAnnotation, fonts: fontsProp, signatures: signatureStore, signatureFonts: signatureFontsProp, page, onPageChange, zoom, onZoomChange, history, asChild = false, onReady, onError, onActivate, children, ref, ...rest }) {
264
+ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsChange, onChange, tool, onToolChange, tools: hostTools, plugins: pluginsProp, decorateAnnotation, fonts: fontsProp, signatures: signatureStore, signatureFonts: signatureFontsProp, page, onPageChange, zoom, onZoomChange, history, asChild = false, onReady, onError, onActivate, children, ref, ...rest }) {
230
265
  const rootElRef = useRef(null);
231
266
  const [rootEl, setRootElState] = useState(null);
232
267
  const setRootEl = useCallback((el) => {
@@ -240,6 +275,8 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
240
275
  const [internalTool, setInternalTool] = useState(tool ?? "select-text");
241
276
  const [activated, setActivatedState] = useState(null);
242
277
  const [viewport, setViewportState] = useState(null);
278
+ /** The viewport as of the last `setViewport`, for the plugin host's `scrollTo`. */
279
+ const viewportRef = useRef(null);
243
280
  const [tools, setToolsState] = useState(null);
244
281
  const documentStatus = useReadable(document?.status, IDLE$1);
245
282
  const status = override ?? documentStatus;
@@ -265,6 +302,7 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
265
302
  onPageChange,
266
303
  onZoomChange,
267
304
  hostTools,
305
+ plugins: pluginsProp,
268
306
  decorateAnnotation,
269
307
  tool: internalTool,
270
308
  tools
@@ -276,6 +314,71 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
276
314
  useLayoutEffect(() => {
277
315
  snapshotHistory.observe(annotations);
278
316
  }, [annotations, snapshotHistory]);
317
+ /** What the plugin host follows; plain readables, so StrictMode's second render is harmless. */
318
+ const [plugins] = useState(() => ({
319
+ document: writable(null),
320
+ root: writable(null),
321
+ activated: writable(null)
322
+ }));
323
+ const setActivated = useCallback((id) => {
324
+ setActivatedState(id);
325
+ plugins.activated.set(id);
326
+ if (id) latest.current.onActivate?.(id);
327
+ }, [latest, plugins]);
328
+ /**
329
+ * The history the plugins reach, picked by the open document's mode when they call: the host
330
+ * reads it as soon as a document opens, before this root has rendered with that document.
331
+ */
332
+ const pluginHistory = useMemo(() => {
333
+ const active = () => {
334
+ const doc = documentRef.current;
335
+ if (!doc) return void 0;
336
+ return doc.annotations.mode === "controlled" ? snapshotHistory : doc.history;
337
+ };
338
+ return {
339
+ batch: (fn) => {
340
+ const h = active();
341
+ if (h) h.batch(fn);
342
+ else fn();
343
+ },
344
+ track: (store) => active()?.track(store) ?? noop,
345
+ react: (fn) => active()?.react(fn) ?? noop
346
+ };
347
+ }, [snapshotHistory]);
348
+ const hostRef = useRef(null);
349
+ const [pluginHost, setPluginHost] = useState(null);
350
+ const hostMounts = useRef(0);
351
+ useLayoutEffect(() => {
352
+ hostMounts.current += 1;
353
+ if (!hostRef.current || hostRef.current.destroyed) {
354
+ const host = createPluginHost({
355
+ plugins: latest.current.plugins ?? [],
356
+ document: readonly(plugins.document),
357
+ history: () => pluginHistory,
358
+ activated: readonly(plugins.activated),
359
+ setActivated: (id) => {
360
+ if (id === null || documentRef.current?.annotations.get(id)) setActivated(id);
361
+ },
362
+ root: readonly(plugins.root),
363
+ decorate: () => latest.current.decorateAnnotation,
364
+ viewport: () => viewportRef.current
365
+ });
366
+ hostRef.current = {
367
+ host,
368
+ destroyed: false
369
+ };
370
+ setPluginHost(host);
371
+ }
372
+ return () => {
373
+ hostMounts.current -= 1;
374
+ queueMicrotask(() => {
375
+ const current = hostRef.current;
376
+ if (hostMounts.current > 0 || !current || current.destroyed) return;
377
+ current.destroyed = true;
378
+ current.host.destroy();
379
+ });
380
+ };
381
+ }, []);
279
382
  const srcIdentity = identity(src);
280
383
  useEffect(() => {
281
384
  let cancelled = false;
@@ -287,6 +390,9 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
287
390
  }
288
391
  setOverride({ state: "loading" });
289
392
  let opened = null;
393
+ /** The plugins told of `opened`, and the snapshot history's hold on its store. */
394
+ let told = null;
395
+ let detach = noop;
290
396
  const run = async () => {
291
397
  try {
292
398
  const doc = await openDocument(source, {
@@ -316,6 +422,9 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
316
422
  const current = latest.current.annotations;
317
423
  if (doc.annotations.mode === "controlled" && current !== void 0) doc.annotations.setControlledValue(current);
318
424
  documentRef.current = doc;
425
+ if (doc.annotations.mode === "controlled") detach = snapshotHistory.attach(doc.annotations);
426
+ told = plugins;
427
+ told.document.set(doc);
319
428
  setDocument(doc);
320
429
  setOverride(null);
321
430
  setTestHook(rootElRef.current, doc);
@@ -337,6 +446,8 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
337
446
  });
338
447
  return () => {
339
448
  cancelled = true;
449
+ told?.document.set(null);
450
+ detach();
340
451
  opened?.destroy();
341
452
  documentRef.current = null;
342
453
  setDocument(null);
@@ -346,7 +457,8 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
346
457
  srcIdentity,
347
458
  password,
348
459
  snapshotHistory,
349
- latest
460
+ latest,
461
+ plugins
350
462
  ]);
351
463
  useLayoutEffect(() => {
352
464
  if (annotations && document?.annotations.mode === "controlled") document.annotations.setControlledValue(annotations);
@@ -360,13 +472,10 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
360
472
  setInternalTool(id);
361
473
  latest.current.onToolChange?.(id);
362
474
  }, [latest]);
363
- const setActivated = useCallback((id) => {
364
- setActivatedState(id);
365
- if (id) latest.current.onActivate?.(id);
366
- }, [latest]);
367
475
  const reportZoom = useCallback((z) => latest.current.onZoomChange?.(z), [latest]);
368
476
  const reportPage = useCallback((p) => latest.current.onPageChange?.(p), [latest]);
369
477
  const setViewport = useCallback((vp, tc) => {
478
+ viewportRef.current = vp;
370
479
  setViewportState(vp);
371
480
  setToolsState(tc);
372
481
  }, []);
@@ -384,7 +493,9 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
384
493
  if (controlled) snapshotHistory.batch(fn);
385
494
  else if (documentRef.current) documentRef.current.history.batch(fn);
386
495
  else fn();
387
- }
496
+ },
497
+ track: (store) => pluginHistory.track(store),
498
+ react: (fn) => pluginHistory.react(fn)
388
499
  }), [
389
500
  controlled,
390
501
  historyEnabled,
@@ -392,19 +503,21 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
392
503
  snapCanRedo,
393
504
  coreCanUndo,
394
505
  coreCanRedo,
395
- snapshotHistory
506
+ snapshotHistory,
507
+ pluginHistory
396
508
  ]);
397
509
  const latestHistory = useLatest(inkHistory);
398
510
  /** The document's tool style; it batches through `history`, whichever mode is on. */
399
511
  const styleTracker = useMemo(() => document ? trackToolStyle({
400
512
  store: document.annotations,
401
513
  history: { batch: (fn) => latestHistory.current.batch(fn) },
402
- tools: latest.current.hostTools,
514
+ tools: [...latest.current.hostTools ?? [], ...pluginHost?.tools ?? []],
403
515
  tool: latest.current.tool
404
516
  }) : null, [
405
517
  document,
406
518
  latest,
407
- latestHistory
519
+ latestHistory,
520
+ pluginHost
408
521
  ]);
409
522
  useEffect(() => {
410
523
  styleTracker?.setTool(internalTool);
@@ -468,6 +581,8 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
468
581
  reportPage,
469
582
  activated,
470
583
  setActivated,
584
+ pluginHost,
585
+ viewportEl: plugins.root,
471
586
  history: inkHistory,
472
587
  rootEl,
473
588
  setViewport
@@ -495,6 +610,8 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
495
610
  reportPage,
496
611
  activated,
497
612
  setActivated,
613
+ pluginHost,
614
+ plugins,
498
615
  inkHistory,
499
616
  rootEl,
500
617
  setViewport
@@ -670,6 +787,7 @@ function InkViewport({ mode = "continuous", rotation = 0, gap = 16, buffer = 2,
670
787
  buffer: b,
671
788
  tool: c.tool,
672
789
  ...c.hostTools ? { tools: c.hostTools } : {},
790
+ ...c.pluginHost ? { plugins: c.pluginHost } : {},
673
791
  decorateAnnotation: (a) => latest.current.ctx.decorateAnnotation(a),
674
792
  ...c.toolStyle ? { toolStyle: c.toolStyle } : {},
675
793
  toolHistory: { batch: (fn) => latest.current.ctx.history.batch(fn) },
@@ -737,8 +855,17 @@ function InkViewport({ mode = "continuous", rotation = 0, gap = 16, buffer = 2,
737
855
  }, [
738
856
  ctx.document,
739
857
  ctx.status.state,
858
+ ctx.pluginHost,
740
859
  latest
741
860
  ]);
861
+ const { viewportEl } = ctx;
862
+ useLayoutEffect(() => {
863
+ const el = scroll.current;
864
+ viewportEl.set(el);
865
+ return () => {
866
+ if (viewportEl.get() === el) viewportEl.set(null);
867
+ };
868
+ }, [viewportEl]);
742
869
  const { onDecorateAnnotationChange } = ctx;
743
870
  useEffect(() => onDecorateAnnotationChange(() => engine.current?.redecorate()), [onDecorateAnnotationChange]);
744
871
  useEffect(() => {
@@ -877,10 +1004,13 @@ const ICONS = {
877
1004
  signature: Signature
878
1005
  };
879
1006
  function InkToolButton({ tool, label, asChild = false, className, children, onClick, ...rest }) {
1007
+ const { hostTools, pluginHost } = useInkContext("InkToolButton");
880
1008
  const { tool: current, setTool } = useTool();
881
1009
  const active = current === tool;
882
- const name = label ?? TOOL_LABELS[tool] ?? tool;
883
- const icon = ICONS[tool];
1010
+ /** A host or plugin tool by this id, for the name and icon core has none for. */
1011
+ const own = [...hostTools ?? [], ...pluginHost?.tools ?? []].find((t) => t.id === tool);
1012
+ const name = label ?? TOOL_LABELS[tool] ?? own?.label ?? tool;
1013
+ const icon = ICONS[tool] ?? own?.icon;
884
1014
  return /* @__PURE__ */ jsx(Toolbar.Button, {
885
1015
  asChild,
886
1016
  className: cx("ink-tool-button", className),
@@ -902,6 +1032,38 @@ function InkToolButton({ tool, label, asChild = false, className, children, onCl
902
1032
  });
903
1033
  }
904
1034
  //#endregion
1035
+ //#region src/components/InkCommand.tsx
1036
+ function InkCommand({ id, asChild = false, children, disabled, onClick, ...rest }) {
1037
+ const { run, enabled, busy, status, label, icon } = useCommand(id);
1038
+ return /* @__PURE__ */ jsxs("div", {
1039
+ className: "ink-command",
1040
+ children: [/* @__PURE__ */ jsx(Toolbar.Button, {
1041
+ asChild,
1042
+ type: "button",
1043
+ "data-command": id,
1044
+ "aria-label": label || void 0,
1045
+ title: label || void 0,
1046
+ "aria-hidden": label ? void 0 : true,
1047
+ "aria-busy": busy,
1048
+ "aria-disabled": busy || void 0,
1049
+ ...rest,
1050
+ disabled: disabled === true || !enabled && !busy,
1051
+ onClick: (e) => {
1052
+ onClick?.(e);
1053
+ if (!e.defaultPrevented) run();
1054
+ },
1055
+ children: typeof children === "function" ? children({
1056
+ label,
1057
+ busy
1058
+ }) : children ?? (icon ? /* @__PURE__ */ jsx(InkIcon, { icon }) : label)
1059
+ }), /* @__PURE__ */ jsx("span", {
1060
+ className: "ink-command-status",
1061
+ role: "status",
1062
+ children: status
1063
+ })]
1064
+ });
1065
+ }
1066
+ //#endregion
905
1067
  //#region src/components/InkToolbarSeparator.tsx
906
1068
  /**
907
1069
  * A divider between groups of controls in a horizontal toolbar. Not focusable. A plain div
@@ -2472,6 +2634,6 @@ function ThreadForm({ editingRoot, locked, deleteLabel, onSubmit, onRemove, onCl
2472
2634
  });
2473
2635
  }
2474
2636
  //#endregion
2475
- export { InkAnnotation, InkColorMenu, InkHighlightMenu, InkIcon, InkLineStyleMenu, InkNextPage, InkPage, InkPageCount, InkPageInput, InkPrevPage, InkRedo, InkRoot, InkShapeMenu, InkSignatureDialog, InkSignatureMenu, InkTextStyleMenu, InkThreadPopover, InkToolButton, InkToolbar, InkToolbarSeparator, InkUndo, InkViewport, InkZoomIn, InkZoomOut, InkZoomSelect, useAnnotations, useDocument, useEmbedded, useHistory, useInkContext, usePage, useReadable, useSelection, useTool, useToolOptions, useToolStyle, useZoom };
2637
+ export { InkAnnotation, InkColorMenu, InkCommand, InkHighlightMenu, InkIcon, InkLineStyleMenu, InkNextPage, InkPage, InkPageCount, InkPageInput, InkPrevPage, InkRedo, InkRoot, InkShapeMenu, InkSignatureDialog, InkSignatureMenu, InkTextStyleMenu, InkThreadPopover, InkToolButton, InkToolbar, InkToolbarSeparator, InkUndo, InkViewport, InkZoomIn, InkZoomOut, InkZoomSelect, useAnnotations, useCommand, useDocument, useEmbedded, useHistory, useInkContext, usePage, useReadable, useSelection, useTool, useToolOptions, useToolStyle, useZoom };
2476
2638
 
2477
2639
  //# sourceMappingURL=index.mjs.map