@inkbar/react 0.5.0 → 0.7.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.
@@ -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/useSearch.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/InkSearchButton.tsx","../src/components/InkFindBar.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":";;;;;;;;;;UA8BiB,mBAAmB;EAClC;EACA;EACA;EACA;EACA;;;;;;;EAOA,QAAQ;;UAGO;EACf,QAAQ;EACR,UAAU;;EAEV,QAAQ;EACR,sBAAsB;EACtB;;;;;;EAMA,YAAY;;;;;;EAMZ,QAAQ;;EAER,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;;;;;;;;wBC3GjC,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,11 +1,11 @@
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, createSearchController, createSignatureDraft, createToolOptions, cssVariableDefaults, findAnnouncer, findCountText, focusInitialMenuItem, fontFamilyValue, handleFindKey, handleMenuKeys, handleRadioKeys, handleTabKeys, highlightMenuModel, lineStyleMenuModel, menuItems, mountViewer, observeAnnotationElement, pageSelectionText, shapeMenuModel, shouldKeepOpenOnAnnotation, signatureMenuModel, signaturePreview, textStyleMenuModel, threadDeleteLabel, threadPopoverLabel, trackToolStyle, unknownCommand, viewerSearchOf } 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";
8
- import { ALargeSmall, AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold, Check, ChevronDown, ChevronLeft, ChevronRight, Highlighter, ICON_ATTRIBUTES, Italic, MessageSquare, Minus, PenLine, PenTool, Plus, Redo2, Signature, Square, SquareDashedMousePointer, TextCursor, Trash2, Type, Underline, Undo2, ZoomIn, ZoomOut } from "@inkbar/icons";
8
+ import { ALargeSmall, AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold, CaseSensitive, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Highlighter, ICON_ATTRIBUTES, Italic, MessageSquare, Minus, PenLine, PenTool, Plus, Redo2, Search, Signature, Square, SquareDashedMousePointer, TextCursor, Trash2, Type, Underline, Undo2, X, ZoomIn, ZoomOut } from "@inkbar/icons";
9
9
  //#region src/context.ts
10
10
  const InkContextObject = createContext(null);
11
11
  /**
@@ -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$2 = () => 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$2, [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);
@@ -147,6 +147,35 @@ function useZoom() {
147
147
  ]);
148
148
  }
149
149
  //#endregion
150
+ //#region src/hooks/useSearch.ts
151
+ const CLOSED = {
152
+ open: false,
153
+ query: "",
154
+ matchCase: false,
155
+ hits: [],
156
+ current: -1,
157
+ scanning: false
158
+ };
159
+ const noop$1 = () => void 0;
160
+ /**
161
+ * The document search for hosts building their own control: the state, and the actions the
162
+ * find bar uses. Search is set up once InkRoot has mounted, so until then (and on the server)
163
+ * the state is closed and the actions do nothing. `open()` runs the search and draws the
164
+ * highlights even when no find bar is mounted.
165
+ */
166
+ function useSearch() {
167
+ const search = useInkContext("useSearch()").search;
168
+ return {
169
+ state: useReadable(search?.state, CLOSED),
170
+ open: search ? (query) => search.open(query) : noop$1,
171
+ setQuery: search ? (query) => search.setQuery(query) : noop$1,
172
+ setMatchCase: search ? (on) => search.setMatchCase(on) : noop$1,
173
+ next: search ? () => search.next() : noop$1,
174
+ previous: search ? () => search.previous() : noop$1,
175
+ close: search ? () => search.close() : noop$1
176
+ };
177
+ }
178
+ //#endregion
150
179
  //#region src/hooks/usePage.ts
151
180
  function usePage() {
152
181
  const { viewport, document } = useInkContext("usePage()");
@@ -190,6 +219,40 @@ function useEmbedded() {
190
219
  }), [summary]);
191
220
  }
192
221
  //#endregion
222
+ //#region src/hooks/useCommand.ts
223
+ /**
224
+ * A plugin command by its namespaced id (`sandbox.suggest`), for hosts building their own
225
+ * control. Plugins are set up once InkRoot has mounted, so until then (and on the server) the
226
+ * command is disabled with no label; it fills in then. Once they are set up, an id no plugin
227
+ * passed to InkRoot registered stays that way, and logs `InkError('UnknownCommand')` to the
228
+ * console once.
229
+ */
230
+ function useCommand(id) {
231
+ const { pluginHost } = useInkContext("useCommand()");
232
+ const command = pluginHost?.command(id);
233
+ const logged = useRef(false);
234
+ useEffect(() => {
235
+ if (!pluginHost || command || logged.current) return;
236
+ logged.current = true;
237
+ console.error(unknownCommand(id, [...pluginHost.commands.keys()]));
238
+ }, [
239
+ pluginHost,
240
+ command,
241
+ id
242
+ ]);
243
+ const enabled = useReadable(command?.enabled, false);
244
+ const busy = useReadable(command?.busy, false);
245
+ const status = useReadable(command?.status, "");
246
+ return {
247
+ run: useCallback(async () => command?.run(), [command]),
248
+ enabled,
249
+ busy,
250
+ status,
251
+ label: command?.label ?? "",
252
+ icon: command?.icon
253
+ };
254
+ }
255
+ //#endregion
193
256
  //#region src/use-latest.ts
194
257
  /**
195
258
  * A ref that always holds the latest render's value, for callbacks that outlive a render
@@ -209,6 +272,7 @@ function useLatest(value) {
209
272
  const IDLE$1 = { state: "idle" };
210
273
  const NO_ANNOTATIONS = [];
211
274
  const NO_IDS = [];
275
+ const noop = () => void 0;
212
276
  /** Signed URLs change; the key does not. Bytes and Blobs are their own identity. */
213
277
  function identity(src) {
214
278
  if (src === null) return null;
@@ -226,7 +290,7 @@ function isDevelopment() {
226
290
  function setTestHook(el, doc) {
227
291
  if (el && isDevelopment()) el.__inkDocument = doc;
228
292
  }
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 }) {
293
+ 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
294
  const rootElRef = useRef(null);
231
295
  const [rootEl, setRootElState] = useState(null);
232
296
  const setRootEl = useCallback((el) => {
@@ -240,6 +304,8 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
240
304
  const [internalTool, setInternalTool] = useState(tool ?? "select-text");
241
305
  const [activated, setActivatedState] = useState(null);
242
306
  const [viewport, setViewportState] = useState(null);
307
+ /** The viewport as of the last `setViewport`, for the plugin host's `scrollTo`. */
308
+ const viewportRef = useRef(null);
243
309
  const [tools, setToolsState] = useState(null);
244
310
  const documentStatus = useReadable(document?.status, IDLE$1);
245
311
  const status = override ?? documentStatus;
@@ -265,6 +331,7 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
265
331
  onPageChange,
266
332
  onZoomChange,
267
333
  hostTools,
334
+ plugins: pluginsProp,
268
335
  decorateAnnotation,
269
336
  tool: internalTool,
270
337
  tools
@@ -276,6 +343,80 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
276
343
  useLayoutEffect(() => {
277
344
  snapshotHistory.observe(annotations);
278
345
  }, [annotations, snapshotHistory]);
346
+ /** What the plugin host follows; plain readables, so StrictMode's second render is harmless. */
347
+ const [plugins] = useState(() => ({
348
+ document: writable(null),
349
+ root: writable(null),
350
+ activated: writable(null)
351
+ }));
352
+ const setActivated = useCallback((id) => {
353
+ setActivatedState(id);
354
+ plugins.activated.set(id);
355
+ if (id) latest.current.onActivate?.(id);
356
+ }, [latest, plugins]);
357
+ /**
358
+ * The history the plugins reach, picked by the open document's mode when they call: the host
359
+ * reads it as soon as a document opens, before this root has rendered with that document.
360
+ */
361
+ const pluginHistory = useMemo(() => {
362
+ const active = () => {
363
+ const doc = documentRef.current;
364
+ if (!doc) return void 0;
365
+ return doc.annotations.mode === "controlled" ? snapshotHistory : doc.history;
366
+ };
367
+ return {
368
+ batch: (fn) => {
369
+ const h = active();
370
+ if (h) h.batch(fn);
371
+ else fn();
372
+ },
373
+ track: (store) => active()?.track(store) ?? noop,
374
+ react: (fn) => active()?.react(fn) ?? noop
375
+ };
376
+ }, [snapshotHistory]);
377
+ const hostRef = useRef(null);
378
+ const [pluginHost, setPluginHost] = useState(null);
379
+ const [search, setSearch] = useState(null);
380
+ const hostMounts = useRef(0);
381
+ useLayoutEffect(() => {
382
+ hostMounts.current += 1;
383
+ if (!hostRef.current || hostRef.current.destroyed) {
384
+ const search = createSearchController({
385
+ document: readonly(plugins.document),
386
+ viewport: () => viewportRef.current
387
+ });
388
+ const host = createPluginHost({
389
+ plugins: latest.current.plugins ?? [],
390
+ document: readonly(plugins.document),
391
+ history: () => pluginHistory,
392
+ activated: readonly(plugins.activated),
393
+ setActivated: (id) => {
394
+ if (id === null || documentRef.current?.annotations.get(id)) setActivated(id);
395
+ },
396
+ root: readonly(plugins.root),
397
+ decorate: () => latest.current.decorateAnnotation,
398
+ viewport: () => viewportRef.current,
399
+ search: viewerSearchOf(search)
400
+ });
401
+ hostRef.current = {
402
+ host,
403
+ search,
404
+ destroyed: false
405
+ };
406
+ setPluginHost(host);
407
+ setSearch(search);
408
+ }
409
+ return () => {
410
+ hostMounts.current -= 1;
411
+ queueMicrotask(() => {
412
+ const current = hostRef.current;
413
+ if (hostMounts.current > 0 || !current || current.destroyed) return;
414
+ current.destroyed = true;
415
+ current.host.destroy();
416
+ current.search.destroy();
417
+ });
418
+ };
419
+ }, []);
279
420
  const srcIdentity = identity(src);
280
421
  useEffect(() => {
281
422
  let cancelled = false;
@@ -287,6 +428,9 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
287
428
  }
288
429
  setOverride({ state: "loading" });
289
430
  let opened = null;
431
+ /** The plugins told of `opened`, and the snapshot history's hold on its store. */
432
+ let told = null;
433
+ let detach = noop;
290
434
  const run = async () => {
291
435
  try {
292
436
  const doc = await openDocument(source, {
@@ -316,6 +460,9 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
316
460
  const current = latest.current.annotations;
317
461
  if (doc.annotations.mode === "controlled" && current !== void 0) doc.annotations.setControlledValue(current);
318
462
  documentRef.current = doc;
463
+ if (doc.annotations.mode === "controlled") detach = snapshotHistory.attach(doc.annotations);
464
+ told = plugins;
465
+ told.document.set(doc);
319
466
  setDocument(doc);
320
467
  setOverride(null);
321
468
  setTestHook(rootElRef.current, doc);
@@ -337,6 +484,8 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
337
484
  });
338
485
  return () => {
339
486
  cancelled = true;
487
+ told?.document.set(null);
488
+ detach();
340
489
  opened?.destroy();
341
490
  documentRef.current = null;
342
491
  setDocument(null);
@@ -346,7 +495,8 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
346
495
  srcIdentity,
347
496
  password,
348
497
  snapshotHistory,
349
- latest
498
+ latest,
499
+ plugins
350
500
  ]);
351
501
  useLayoutEffect(() => {
352
502
  if (annotations && document?.annotations.mode === "controlled") document.annotations.setControlledValue(annotations);
@@ -360,13 +510,10 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
360
510
  setInternalTool(id);
361
511
  latest.current.onToolChange?.(id);
362
512
  }, [latest]);
363
- const setActivated = useCallback((id) => {
364
- setActivatedState(id);
365
- if (id) latest.current.onActivate?.(id);
366
- }, [latest]);
367
513
  const reportZoom = useCallback((z) => latest.current.onZoomChange?.(z), [latest]);
368
514
  const reportPage = useCallback((p) => latest.current.onPageChange?.(p), [latest]);
369
515
  const setViewport = useCallback((vp, tc) => {
516
+ viewportRef.current = vp;
370
517
  setViewportState(vp);
371
518
  setToolsState(tc);
372
519
  }, []);
@@ -384,7 +531,9 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
384
531
  if (controlled) snapshotHistory.batch(fn);
385
532
  else if (documentRef.current) documentRef.current.history.batch(fn);
386
533
  else fn();
387
- }
534
+ },
535
+ track: (store) => pluginHistory.track(store),
536
+ react: (fn) => pluginHistory.react(fn)
388
537
  }), [
389
538
  controlled,
390
539
  historyEnabled,
@@ -392,19 +541,21 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
392
541
  snapCanRedo,
393
542
  coreCanUndo,
394
543
  coreCanRedo,
395
- snapshotHistory
544
+ snapshotHistory,
545
+ pluginHistory
396
546
  ]);
397
547
  const latestHistory = useLatest(inkHistory);
398
548
  /** The document's tool style; it batches through `history`, whichever mode is on. */
399
549
  const styleTracker = useMemo(() => document ? trackToolStyle({
400
550
  store: document.annotations,
401
551
  history: { batch: (fn) => latestHistory.current.batch(fn) },
402
- tools: latest.current.hostTools,
552
+ tools: [...latest.current.hostTools ?? [], ...pluginHost?.tools ?? []],
403
553
  tool: latest.current.tool
404
554
  }) : null, [
405
555
  document,
406
556
  latest,
407
- latestHistory
557
+ latestHistory,
558
+ pluginHost
408
559
  ]);
409
560
  useEffect(() => {
410
561
  styleTracker?.setTool(internalTool);
@@ -468,6 +619,9 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
468
619
  reportPage,
469
620
  activated,
470
621
  setActivated,
622
+ pluginHost,
623
+ search,
624
+ viewportEl: plugins.root,
471
625
  history: inkHistory,
472
626
  rootEl,
473
627
  setViewport
@@ -495,10 +649,21 @@ function InkRoot({ src, assets, password, defaults, annotations, onAnnotationsCh
495
649
  reportPage,
496
650
  activated,
497
651
  setActivated,
652
+ pluginHost,
653
+ search,
654
+ plugins,
498
655
  inkHistory,
499
656
  rootEl,
500
657
  setViewport
501
658
  ]);
659
+ useEffect(() => {
660
+ if (!rootEl || !search) return;
661
+ const onKeyDown = (e) => {
662
+ handleFindKey(e, search, () => pageSelectionText(rootEl));
663
+ };
664
+ rootEl.addEventListener("keydown", onKeyDown);
665
+ return () => rootEl.removeEventListener("keydown", onKeyDown);
666
+ }, [rootEl, search]);
502
667
  const Comp = asChild ? Slot.Root : "div";
503
668
  return /* @__PURE__ */ jsx(InkContextObject.Provider, {
504
669
  value: ctx,
@@ -670,6 +835,8 @@ function InkViewport({ mode = "continuous", rotation = 0, gap = 16, buffer = 2,
670
835
  buffer: b,
671
836
  tool: c.tool,
672
837
  ...c.hostTools ? { tools: c.hostTools } : {},
838
+ ...c.pluginHost ? { plugins: c.pluginHost } : {},
839
+ ...c.search ? { search: c.search } : {},
673
840
  decorateAnnotation: (a) => latest.current.ctx.decorateAnnotation(a),
674
841
  ...c.toolStyle ? { toolStyle: c.toolStyle } : {},
675
842
  toolHistory: { batch: (fn) => latest.current.ctx.history.batch(fn) },
@@ -737,8 +904,18 @@ function InkViewport({ mode = "continuous", rotation = 0, gap = 16, buffer = 2,
737
904
  }, [
738
905
  ctx.document,
739
906
  ctx.status.state,
907
+ ctx.pluginHost,
908
+ ctx.search,
740
909
  latest
741
910
  ]);
911
+ const { viewportEl } = ctx;
912
+ useLayoutEffect(() => {
913
+ const el = scroll.current;
914
+ viewportEl.set(el);
915
+ return () => {
916
+ if (viewportEl.get() === el) viewportEl.set(null);
917
+ };
918
+ }, [viewportEl]);
742
919
  const { onDecorateAnnotationChange } = ctx;
743
920
  useEffect(() => onDecorateAnnotationChange(() => engine.current?.redecorate()), [onDecorateAnnotationChange]);
744
921
  useEffect(() => {
@@ -877,10 +1054,13 @@ const ICONS = {
877
1054
  signature: Signature
878
1055
  };
879
1056
  function InkToolButton({ tool, label, asChild = false, className, children, onClick, ...rest }) {
1057
+ const { hostTools, pluginHost } = useInkContext("InkToolButton");
880
1058
  const { tool: current, setTool } = useTool();
881
1059
  const active = current === tool;
882
- const name = label ?? TOOL_LABELS[tool] ?? tool;
883
- const icon = ICONS[tool];
1060
+ /** A host or plugin tool by this id, for the name and icon core has none for. */
1061
+ const own = [...hostTools ?? [], ...pluginHost?.tools ?? []].find((t) => t.id === tool);
1062
+ const name = label ?? TOOL_LABELS[tool] ?? own?.label ?? tool;
1063
+ const icon = ICONS[tool] ?? own?.icon;
884
1064
  return /* @__PURE__ */ jsx(Toolbar.Button, {
885
1065
  asChild,
886
1066
  className: cx("ink-tool-button", className),
@@ -902,6 +1082,38 @@ function InkToolButton({ tool, label, asChild = false, className, children, onCl
902
1082
  });
903
1083
  }
904
1084
  //#endregion
1085
+ //#region src/components/InkCommand.tsx
1086
+ function InkCommand({ id, asChild = false, children, disabled, onClick, ...rest }) {
1087
+ const { run, enabled, busy, status, label, icon } = useCommand(id);
1088
+ return /* @__PURE__ */ jsxs("div", {
1089
+ className: "ink-command",
1090
+ children: [/* @__PURE__ */ jsx(Toolbar.Button, {
1091
+ asChild,
1092
+ type: "button",
1093
+ "data-command": id,
1094
+ "aria-label": label || void 0,
1095
+ title: label || void 0,
1096
+ "aria-hidden": label ? void 0 : true,
1097
+ "aria-busy": busy,
1098
+ "aria-disabled": busy || void 0,
1099
+ ...rest,
1100
+ disabled: disabled === true || !enabled && !busy,
1101
+ onClick: (e) => {
1102
+ onClick?.(e);
1103
+ if (!e.defaultPrevented) run();
1104
+ },
1105
+ children: typeof children === "function" ? children({
1106
+ label,
1107
+ busy
1108
+ }) : children ?? (icon ? /* @__PURE__ */ jsx(InkIcon, { icon }) : label)
1109
+ }), /* @__PURE__ */ jsx("span", {
1110
+ className: "ink-command-status",
1111
+ role: "status",
1112
+ children: status
1113
+ })]
1114
+ });
1115
+ }
1116
+ //#endregion
905
1117
  //#region src/components/InkToolbarSeparator.tsx
906
1118
  /**
907
1119
  * A divider between groups of controls in a horizontal toolbar. Not focusable. A plain div
@@ -955,6 +1167,188 @@ function InkRedo({ asChild = false, className, children, disabled, onClick, ...r
955
1167
  });
956
1168
  }
957
1169
  //#endregion
1170
+ //#region src/components/InkSearchButton.tsx
1171
+ /**
1172
+ * Opens the find bar; pressed while it is open. Pressing it again focuses the field. Place it
1173
+ * in a toolbar next to `InkFindBar`, which it needs for the field to focus. Disabled until a
1174
+ * document is open.
1175
+ */
1176
+ function InkSearchButton({ asChild = false, className, children, disabled, onClick, ...rest }) {
1177
+ const { rootEl } = useInkContext("InkSearchButton");
1178
+ const { state, open } = useSearch();
1179
+ const { isReady } = useDocument();
1180
+ return /* @__PURE__ */ jsx(Toolbar.Button, {
1181
+ ...rest,
1182
+ asChild,
1183
+ className: cx("ink-search-button", className),
1184
+ "data-ink-search-button": "",
1185
+ "aria-label": "Find",
1186
+ title: "Find",
1187
+ "aria-pressed": state.open,
1188
+ "data-state": state.open ? "on" : "off",
1189
+ disabled: !isReady || !!disabled,
1190
+ onClick: (e) => {
1191
+ onClick?.(e);
1192
+ if (e.defaultPrevented) return;
1193
+ flushSync(() => open());
1194
+ const field = rootEl?.querySelector("[data-ink-find-bar] input");
1195
+ field?.focus();
1196
+ field?.select();
1197
+ },
1198
+ children: children ?? /* @__PURE__ */ jsx(InkIcon, { icon: Search })
1199
+ });
1200
+ }
1201
+ //#endregion
1202
+ //#region src/components/InkFindBar.tsx
1203
+ /**
1204
+ * The find bar: a field, the match count, previous and next, a match-case toggle and close,
1205
+ * a view of the root's search state. Place it anywhere inside `InkRoot`: it portals itself
1206
+ * into `[data-ink-viewport-root]`, the positioned ancestor the theme floats it from over the
1207
+ * top-right of the pages (as `InkThreadPopover` anchors to the root's overlay rather than
1208
+ * where it is written). It renders nothing until `InkViewport` has mounted, and is hidden
1209
+ * while the search is closed. While it is mounted it registers with the search controller,
1210
+ * which is what lets Ctrl/Cmd+F open it.
1211
+ *
1212
+ * Enter in the field steps to the next match, Shift+Enter to the previous, Escape closes.
1213
+ * Closing returns focus to where it was before the bar opened, else to the document.
1214
+ */
1215
+ function InkFindBar({ className, ...rest }) {
1216
+ const ctx = useInkContext("InkFindBar");
1217
+ const { state, setQuery, setMatchCase, next, previous, close } = useSearch();
1218
+ const scroll = useReadable(ctx.viewportEl, null);
1219
+ /** The viewport root: the scroll element's parent, once InkViewport has mounted. */
1220
+ const target = scroll?.parentElement ?? null;
1221
+ const bar = useRef(null);
1222
+ const field = useRef(null);
1223
+ const live = useRef(null);
1224
+ /** Where focus was when the bar opened, and whether it was open on the last pass. */
1225
+ const before = useRef(null);
1226
+ const wasOpen = useRef(false);
1227
+ useLayoutEffect(() => {
1228
+ const el = bar.current;
1229
+ const input = field.current;
1230
+ if (!el || !input) return;
1231
+ if (state.open !== wasOpen.current) {
1232
+ wasOpen.current = state.open;
1233
+ const doc = el.ownerDocument;
1234
+ if (state.open) {
1235
+ const active = doc.activeElement;
1236
+ before.current = active instanceof HTMLElement && active !== doc.body && !el.contains(active) ? active : null;
1237
+ input.focus();
1238
+ input.select();
1239
+ } else {
1240
+ if (el.contains(doc.activeElement) || doc.activeElement === doc.body) (before.current?.isConnected && !el.contains(before.current) ? before.current : scroll)?.focus({ preventScroll: true });
1241
+ before.current = null;
1242
+ }
1243
+ }
1244
+ if (input.value !== state.query) {
1245
+ input.value = state.query;
1246
+ if (el.ownerDocument.activeElement === input) input.select();
1247
+ }
1248
+ }, [
1249
+ state.open,
1250
+ state.query,
1251
+ scroll
1252
+ ]);
1253
+ const { search } = ctx;
1254
+ useEffect(() => {
1255
+ if (!search || !target) return;
1256
+ return search.attachBar();
1257
+ }, [search, target]);
1258
+ useEffect(() => {
1259
+ const el = live.current;
1260
+ if (!search || !el) return;
1261
+ const announce = findAnnouncer();
1262
+ const say = (s) => {
1263
+ const text = announce(s);
1264
+ if (el.textContent !== text) el.textContent = text;
1265
+ };
1266
+ say(search.state.get());
1267
+ return search.state.subscribe(say);
1268
+ }, [search, target]);
1269
+ useEffect(() => {
1270
+ const el = bar.current;
1271
+ if (!search || !el) return;
1272
+ const onKeyDown = (e) => {
1273
+ if (e.key !== "Escape" || e.defaultPrevented || e.isComposing) return;
1274
+ e.preventDefault();
1275
+ e.stopPropagation();
1276
+ search.close();
1277
+ };
1278
+ el.addEventListener("keydown", onKeyDown);
1279
+ return () => el.removeEventListener("keydown", onKeyDown);
1280
+ }, [search, target]);
1281
+ if (!target) return null;
1282
+ return createPortal(/* @__PURE__ */ jsxs("div", {
1283
+ ...rest,
1284
+ ref: bar,
1285
+ className: cx("ink-find-bar", className),
1286
+ "data-ink-find-bar": "",
1287
+ role: "search",
1288
+ hidden: !state.open,
1289
+ children: [
1290
+ /* @__PURE__ */ jsx("input", {
1291
+ ref: field,
1292
+ type: "text",
1293
+ "aria-label": "Find in document",
1294
+ autoComplete: "off",
1295
+ spellCheck: false,
1296
+ onInput: (e) => setQuery(e.currentTarget.value),
1297
+ onKeyDown: (e) => {
1298
+ if (e.key !== "Enter" || e.nativeEvent.isComposing) return;
1299
+ e.preventDefault();
1300
+ if (e.shiftKey) previous();
1301
+ else next();
1302
+ }
1303
+ }),
1304
+ /* @__PURE__ */ jsx("span", {
1305
+ className: "ink-find-count",
1306
+ "data-ink-find-count": "",
1307
+ children: findCountText(state)
1308
+ }),
1309
+ /* @__PURE__ */ jsx("button", {
1310
+ type: "button",
1311
+ "data-ink-find-previous": "",
1312
+ "aria-label": "Previous match",
1313
+ title: "Previous match",
1314
+ onClick: () => previous(),
1315
+ children: /* @__PURE__ */ jsx(InkIcon, { icon: ChevronUp })
1316
+ }),
1317
+ /* @__PURE__ */ jsx("button", {
1318
+ type: "button",
1319
+ "data-ink-find-next": "",
1320
+ "aria-label": "Next match",
1321
+ title: "Next match",
1322
+ onClick: () => next(),
1323
+ children: /* @__PURE__ */ jsx(InkIcon, { icon: ChevronDown })
1324
+ }),
1325
+ /* @__PURE__ */ jsx("button", {
1326
+ type: "button",
1327
+ "data-ink-find-match-case": "",
1328
+ "aria-label": "Match case",
1329
+ title: "Match case",
1330
+ "aria-pressed": state.matchCase,
1331
+ onClick: () => setMatchCase(!state.matchCase),
1332
+ children: /* @__PURE__ */ jsx(InkIcon, { icon: CaseSensitive })
1333
+ }),
1334
+ /* @__PURE__ */ jsx("button", {
1335
+ type: "button",
1336
+ "data-ink-find-close": "",
1337
+ "aria-label": "Close find",
1338
+ title: "Close find",
1339
+ onClick: () => close(),
1340
+ children: /* @__PURE__ */ jsx(InkIcon, { icon: X })
1341
+ }),
1342
+ /* @__PURE__ */ jsx("div", {
1343
+ ref: live,
1344
+ className: "ink-visually-hidden",
1345
+ "data-ink-find-status": "",
1346
+ "aria-live": "polite"
1347
+ })
1348
+ ]
1349
+ }), target);
1350
+ }
1351
+ //#endregion
958
1352
  //#region src/components/InkZoomIn.tsx
959
1353
  function InkZoomIn({ asChild = false, className, children, onClick, ...rest }) {
960
1354
  const { zoomIn } = useZoom();
@@ -2472,6 +2866,6 @@ function ThreadForm({ editingRoot, locked, deleteLabel, onSubmit, onRemove, onCl
2472
2866
  });
2473
2867
  }
2474
2868
  //#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 };
2869
+ export { InkAnnotation, InkColorMenu, InkCommand, InkFindBar, InkHighlightMenu, InkIcon, InkLineStyleMenu, InkNextPage, InkPage, InkPageCount, InkPageInput, InkPrevPage, InkRedo, InkRoot, InkSearchButton, InkShapeMenu, InkSignatureDialog, InkSignatureMenu, InkTextStyleMenu, InkThreadPopover, InkToolButton, InkToolbar, InkToolbarSeparator, InkUndo, InkViewport, InkZoomIn, InkZoomOut, InkZoomSelect, useAnnotations, useCommand, useDocument, useEmbedded, useHistory, useInkContext, usePage, useReadable, useSearch, useSelection, useTool, useToolOptions, useToolStyle, useZoom };
2476
2870
 
2477
2871
  //# sourceMappingURL=index.mjs.map