@inkbar/react 0.8.0 → 0.10.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.mjs","names":["noop","noop","IDLE","NO_TEMPLATES","NO_TEMPLATES","Item"],"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/hooks/useForm.ts","../src/use-latest.ts","../src/components/InkRoot.tsx","../src/class-names.ts","../src/components/InkFormAlert.tsx","../src/components/InkAnnotation.tsx","../src/components/InkPage.tsx","../src/components/InkSignatureDialog.tsx","../src/components/InkIcon.tsx","../src/components/SignatureMenuPanel.tsx","../src/components/InkSignFieldPopover.tsx","../src/components/InkViewport.tsx","../src/components/InkToolbar.tsx","../src/components/InkToolButton.tsx","../src/components/InkCommand.tsx","../src/components/InkToolbarSeparator.tsx","../src/components/InkUndo.tsx","../src/components/InkRedo.tsx","../src/components/InkSearchButton.tsx","../src/components/InkFindBar.tsx","../src/components/InkZoomIn.tsx","../src/components/InkZoomOut.tsx","../src/components/InkZoomSelect.tsx","../src/components/InkPageInput.tsx","../src/components/InkPageCount.tsx","../src/components/InkPrevPage.tsx","../src/components/InkNextPage.tsx","../src/components/InkColorMenu.tsx","../src/components/InkShapeMenu.tsx","../src/components/InkSignatureMenu.tsx","../src/components/InkHighlightMenu.tsx","../src/components/InkTextStyleMenu.tsx","../src/components/InkLineStyleMenu.tsx","../src/components/annotation-element.ts","../src/components/popover-focus.ts","../src/components/InkThreadPopover.tsx"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nimport type {\n Annotation,\n FormAction,\n InkDocument,\n InkError,\n InkStatus,\n PdfAssets,\n PluginHistory,\n SignatureLibrary,\n Writable,\n} from '@inkbar/core'\nimport type {\n DecorateAnnotation,\n PluginHost,\n SearchController,\n Tool,\n ToolController,\n ToolId,\n ToolOptions,\n ToolStyle,\n Viewport,\n ZoomValue,\n} from '@inkbar/core/dom'\n\nexport type { InkStatus }\n\n/**\n * Undo and redo for the current document, whichever mode its annotations are in. `track` and\n * `react` (from `PluginHistory`) reach the same history, so plugin stores undo with the edits.\n */\nexport interface InkHistory extends PluginHistory {\n canUndo: boolean\n canRedo: boolean\n undo: () => void\n redo: () => void\n clear: () => void\n /**\n * Runs `fn` and records what it changes as one undo step. The host still receives one change\n * per add. Controlled, the history groups the resulting list changes into one step, and\n * `canUndo` updates once the current task ends. Any other change the host applies in that\n * same window joins the step.\n */\n batch: (fn: () => void) => void\n}\n\nexport interface InkContext {\n assets: PdfAssets\n document: InkDocument | null\n /** `loading` from the moment a document starts opening, then the document's own status. */\n status: InkStatus\n annotations: readonly Annotation[]\n selection: readonly string[]\n /**\n * The plugins from InkRoot's `plugins` prop, set up once the root has mounted and kept for\n * its life; `null` before that, and on the server. InkViewport hands it to the engine;\n * InkCommand places its commands.\n */\n pluginHost: PluginHost | null\n /**\n * The search controller from the same set-up as `pluginHost`: shared by the find bar, the\n * search button, the engine's highlights and the plugins. `null` before the root has\n * mounted, and on the server.\n */\n search: SearchController | null\n /** InkViewport's scroll element while it is mounted: the plugins' `root`. */\n viewportEl: Writable<HTMLElement | null>\n /** Set by InkViewport once it has built its viewport and tool controller. */\n viewport: Viewport | null\n tools: ToolController | null\n /** Desired tool; InkViewport applies it to the controller. */\n tool: ToolId\n setTool: (id: ToolId) => void\n /** Host tools from InkRoot's `tools` prop; InkViewport registers them. */\n hostTools: Tool[] | undefined\n /**\n * Calls InkRoot's current `decorateAnnotation` prop. The function itself stays the same\n * across renders, so a new prop does not re-render the context's consumers.\n */\n decorateAnnotation: DecorateAnnotation\n /**\n * Calls `listener` after InkRoot's `decorateAnnotation` prop changes; InkViewport re-applies\n * the decorations then. Returns the unsubscribe.\n */\n onDecorateAnnotationChange: (listener: () => void) => () => void\n /** The font families text boxes offer: InkRoot's `fonts`, else `FONT_FAMILIES`. */\n fonts: readonly string[]\n /** The tools' options for InkRoot's life, so they persist across documents. */\n toolOptions: ToolOptions\n /** The saved signatures, from InkRoot's `signatures` store (memory by default). */\n signatures: SignatureLibrary\n /** The fonts a typed signature offers: InkRoot's `signatureFonts`, else `SIGNATURE_FONTS`. */\n signatureFonts: readonly string[]\n /** The open document's tool style; `null` while no document is open. */\n toolStyle: ToolStyle | null\n /** Desired zoom and page from the host's props; InkViewport applies and reports back. */\n zoomModel: ZoomValue | undefined\n pageModel: number | undefined\n reportZoom: (z: ZoomValue) => void\n reportPage: (p: number) => void\n /** Last activated annotation (Enter, click with the note tool, etc.). Popovers key off this. */\n activated: string | null\n /**\n * Activates annotation `id`, or clears the activation with `null`. This is the context's\n * own: unlike core's `Viewer.setActivated`, it calls InkRoot's `onActivate` for an id, and\n * it does not check that the id is in the document.\n */\n setActivated: (id: string | null) => void\n history: InkHistory\n rootEl: HTMLElement | null\n setViewport: (viewport: Viewport | null, tools: ToolController | null) => void\n /** InkRoot's `formHighlight`; InkViewport reads it when it builds the viewer. */\n formHighlight: boolean | undefined\n /** Calls InkRoot's `onFormAction`, one microtask later. */\n reportFormAction: (action: FormAction) => void\n /** Calls InkRoot's `onError`, for failures after the document opened (a refused signing). */\n reportError: (error: InkError) => void\n}\n\nexport const InkContextObject = createContext<InkContext | null>(null)\n\n/**\n * The context for hooks: throws a readable error when called outside a component rendered\n * inside `InkRoot`.\n */\nexport function useInkContext(consumer: string): InkContext {\n const ctx = useContext(InkContextObject)\n if (!ctx)\n throw new Error(\n `[inkbar] ${consumer} must be called in a component inside <InkRoot>.`\n )\n return ctx\n}\n","import { useCallback, useSyncExternalStore } from 'react'\n\nimport type { Readable } from '@inkbar/core'\n\nconst noop = (): void => undefined\n\n/**\n * Mirrors a core `Readable` into React. A missing readable yields `fallback`, which must be a\n * stable reference (a module constant): `useSyncExternalStore` compares snapshots by identity\n * and loops on a fresh value. On the server the fallback is rendered.\n */\nexport function useReadable<T>(readable: Readable<T> | null | undefined, fallback: T): T {\n const subscribe = useCallback(\n (onChange: () => void) => (readable ? readable.subscribe(() => onChange()) : noop),\n [readable]\n )\n const get = useCallback(\n () => (readable ? readable.get() : fallback),\n [readable, fallback]\n )\n const server = useCallback(() => fallback, [fallback])\n return useSyncExternalStore(subscribe, get, server)\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nimport type { AnnotationDocument, ImportOptions, PageInfo } from '@inkbar/core'\n\nconst NO_PAGES: readonly PageInfo[] = []\n\nexport function useDocument() {\n const ctx = useInkContext('useDocument()')\n const { document, status } = ctx\n return useMemo(\n () => ({\n document,\n status,\n isReady: status.state === 'ready',\n error: status.state === 'error' ? status.error : null,\n pages: document?.pages ?? NO_PAGES,\n info: document?.info ?? null,\n exportAnnotations: () => document?.exportAnnotations('json'),\n importAnnotations: (data: AnnotationDocument | string, opts?: ImportOptions) =>\n document?.importAnnotations(data, opts),\n }),\n [document, status]\n )\n}\n","import { repliesTo } from '@inkbar/core'\nimport { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nimport type { Annotation, AnnotationInput, AnnotationPatch } from '@inkbar/core'\n\nexport function useAnnotations() {\n const ctx = useInkContext('useAnnotations()')\n const { annotations, selection, document } = ctx\n const store = document?.annotations\n const selected = useMemo(\n () =>\n selection\n .map((id) => annotations.find((a) => a.id === id))\n .filter((a): a is Annotation => !!a),\n [annotations, selection]\n )\n // Stable for the life of the document, so hosts can pass them as props or effect deps.\n const actions = useMemo(\n () => ({\n add: (input: AnnotationInput) => store?.add(input),\n update: (id: string, patch: AnnotationPatch) => store?.update(id, patch),\n remove: (id: string) => store?.remove(id) ?? false,\n select: (ids: string[]) => store?.select(ids),\n }),\n [store]\n )\n return useMemo(\n () => ({\n annotations,\n selection,\n selected,\n byPage: (page: number) => annotations.filter((a) => a.page === page),\n /** Replies in creation order for a note id. */\n replies: (id: string) => repliesTo(annotations, id),\n ...actions,\n }),\n [annotations, selection, selected, actions]\n )\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nexport function useTool() {\n const ctx = useInkContext('useTool()')\n const { tool, setTool } = ctx\n return useMemo(() => ({ tool, setTool }), [tool, setTool])\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { CurrentStyle, StyleGroup, StyleKey, StyleProps } from '@inkbar/core'\n\nconst NO_STYLE: CurrentStyle = {}\nconst NO_PROPS: ReadonlySet<StyleKey> = new Set()\nconst EMPTY: Readonly<StyleProps> = {}\n\ninterface ToolStyleView {\n current: CurrentStyle\n supported: ReadonlySet<StyleKey>\n /** A group's own style. */\n get: (group: StyleGroup) => Readonly<StyleProps>\n}\n\n/** The tool style for the active tool or the selection. */\nexport interface ToolStyleHandle extends ToolStyleView {\n set: (patch: StyleProps, opts?: { group?: StyleGroup; apply?: boolean }) => void\n}\n\n/** The tool style scoped to one group: `set` writes that group, so it takes no options. */\nexport interface ScopedToolStyleHandle extends ToolStyleView {\n set: (patch: StyleProps) => void\n}\n\n/**\n * The tool style the style controls read and write: `current` shows the selection's values\n * (`'mixed'` where they differ), else the active tool's group; `supported` names the props\n * the active tool or the selection has. `set` updates the group and the selected annotations.\n *\n * With `group`, the style as a control for that group sees it, whatever tool is active: the\n * selection's when it is all in the group, else the group's own; `set` updates the group, and\n * the selection only when it is all in the group.\n */\nexport function useToolStyle(): ToolStyleHandle\nexport function useToolStyle(group: StyleGroup | undefined): ScopedToolStyleHandle\nexport function useToolStyle(group?: StyleGroup): ToolStyleHandle {\n const ctx = useInkContext('useToolStyle()')\n const style = ctx.toolStyle\n const scope = group && style ? style.scoped(group) : undefined\n const view = scope ?? style\n const current = useReadable(view?.current, NO_STYLE)\n const supported = useReadable(view?.supported, NO_PROPS)\n return useMemo(\n () => ({\n current,\n supported,\n set: (patch: StyleProps, opts?: { group?: StyleGroup; apply?: boolean }) =>\n scope ? scope.set(patch) : style?.set(patch, opts),\n get: (g: StyleGroup): Readonly<StyleProps> => style?.get(g) ?? EMPTY,\n }),\n [current, supported, style, scope]\n )\n}\n","import { useCallback } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { ToolId } from '@inkbar/core/dom'\n\nconst NO_OPTIONS: object = {}\n\n/**\n * A tool's options and a setter that merges a patch into them without switching tools.\n * Options are empty, and the setter does nothing, until the viewport has mounted.\n */\nexport function useToolOptions<O extends object = object>(\n id: ToolId\n): [O, (patch: Partial<O>) => void] {\n const ctx = useInkContext('useToolOptions()')\n const tools = ctx.tools\n const options = useReadable(tools?.options(id), NO_OPTIONS) as O\n const setOptions = useCallback(\n (patch: Partial<O>) => tools?.setOptions(id, patch),\n [tools, id]\n )\n return [options, setOptions]\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nexport function useSelection() {\n const ctx = useInkContext('useSelection()')\n const { selection, document } = ctx\n const store = document?.annotations\n return useMemo(\n () => ({\n selection,\n select: (ids: string[]) => store?.select(ids),\n clear: () => store?.select([]),\n }),\n [selection, store]\n )\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { ZoomValue } from '@inkbar/core/dom'\n\nexport function useZoom() {\n const ctx = useInkContext('useZoom()')\n const { viewport } = ctx\n const zoom = useReadable<ZoomValue>(viewport?.zoom, 'fit-width')\n const scale = useReadable<number>(viewport?.scale, 1)\n return useMemo(\n () => ({\n zoom,\n scale,\n setZoom: (z: ZoomValue) => viewport?.setZoom(z),\n zoomIn: () => viewport?.zoomBy(1.25),\n zoomOut: () => viewport?.zoomBy(0.8),\n }),\n [viewport, zoom, scale]\n )\n}\n","import { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { SearchState, ViewerSearch } from '@inkbar/core/dom'\n\nconst CLOSED: SearchState = {\n open: false,\n query: '',\n matchCase: false,\n hits: [],\n current: -1,\n scanning: false,\n}\n\nconst noop = (): void => undefined\n\n/**\n * The document search for hosts building their own control: the state, and the actions the\n * find bar uses. Search is set up once InkRoot has mounted, so until then (and on the server)\n * the state is closed and the actions do nothing. `open()` runs the search and draws the\n * highlights even when no find bar is mounted.\n */\nexport function useSearch(): { state: SearchState } & Omit<ViewerSearch, 'state'> {\n const search = useInkContext('useSearch()').search\n const state = useReadable<SearchState>(search?.state, CLOSED)\n return {\n state,\n open: search ? (query) => search.open(query) : noop,\n setQuery: search ? (query) => search.setQuery(query) : noop,\n setMatchCase: search ? (on) => search.setMatchCase(on) : noop,\n next: search ? () => search.next() : noop,\n previous: search ? () => search.previous() : noop,\n close: search ? () => search.close() : noop,\n }\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nexport function usePage() {\n const ctx = useInkContext('usePage()')\n const { viewport, document } = ctx\n const current = useReadable<number>(viewport?.currentPage, 0)\n return useMemo(\n () => ({\n /** 0-based. */\n current,\n count: document?.pages.length ?? 0,\n goTo: (index: number) => viewport?.scrollToPage(index),\n // Read the live page, so these stay the same functions as the reader scrolls.\n next: () => viewport?.scrollToPage(viewport.currentPage.get() + 1),\n previous: () => viewport?.scrollToPage(viewport.currentPage.get() - 1),\n scrollToAnnotation(id: string) {\n const a = document?.annotations.get(id)\n if (a) viewport?.scrollToRect(a.page, a.rect)\n },\n }),\n [viewport, document, current]\n )\n}\n","import { useInkContext, type InkHistory } from '../context'\n\n/**\n * Undo and redo. Uncontrolled documents use the core history; controlled hosts that pass\n * `history` to InkRoot get a snapshot stack over their own list, applied through\n * `onAnnotationsChange`.\n */\nexport function useHistory(): InkHistory {\n return useInkContext('useHistory()').history\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nconst NONE: readonly never[] = []\n\nexport function useEmbedded() {\n const ctx = useInkContext('useEmbedded()')\n const summary = ctx.document?.embedded ?? NONE\n return useMemo(\n () => ({\n summary,\n total: summary.reduce((n, s) => n + s.count, 0),\n hasAny: summary.length > 0,\n }),\n [summary]\n )\n}\n","import { unknownCommand } from '@inkbar/core/dom'\nimport { useCallback, useEffect, useRef } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { IconNode } from '@inkbar/icons'\n\nexport interface CommandHandle {\n /** Runs the command; does nothing while it is busy or disabled. Never rejects. */\n run: () => Promise<void>\n /** A ready document (or the plugin's own condition), and not busy. */\n enabled: boolean\n busy: boolean\n /** The command's progress or result message, `''` without one. */\n status: string\n /** `''` until the plugins are set up. */\n label: string\n icon: IconNode | undefined\n}\n\n/**\n * A plugin command by its namespaced id (`sandbox.suggest`), for hosts building their own\n * control. Plugins are set up once InkRoot has mounted, so until then (and on the server) the\n * command is disabled with no label; it fills in then. Once they are set up, an id no plugin\n * passed to InkRoot registered stays that way, and logs `InkError('UnknownCommand')` to the\n * console once.\n */\nexport function useCommand(id: string): CommandHandle {\n const { pluginHost } = useInkContext('useCommand()')\n const command = pluginHost?.command(id)\n const logged = useRef(false)\n useEffect(() => {\n if (!pluginHost || command || logged.current) return\n logged.current = true\n console.error(unknownCommand(id, [...pluginHost.commands.keys()]))\n }, [pluginHost, command, id])\n const enabled = useReadable(command?.enabled, false)\n const busy = useReadable(command?.busy, false)\n const status = useReadable(command?.status, '')\n const run = useCallback(async () => command?.run(), [command])\n return { run, enabled, busy, status, label: command?.label ?? '', icon: command?.icon }\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { FieldValues, FormField, FormSetResult } from '@inkbar/core'\n\nconst NO_FIELDS: readonly FormField[] = []\nconst NO_VALUES: FieldValues = Object.freeze({})\n\nexport interface FormHandle {\n /** The open document's form fields; empty while none is open or it has none. */\n fields: readonly FormField[]\n /** What the fields hold now, keyed by full name. */\n values: FieldValues\n /**\n * Commits values as a person would: scripts run, and the call is one undo step. Returns the\n * names applied and rejected, or `undefined` while no document is open.\n */\n set: (values: FieldValues) => FormSetResult | undefined\n /** Restores the PDF's default values of `names`, or of every field. */\n reset: (names?: string[]) => void\n}\n\n/** The open document's form: its fields, their values, and `set` and `reset`. */\nexport function useForm(): FormHandle {\n const { document } = useInkContext('useForm()')\n const form = document?.form\n const fields = useReadable(form?.fields, NO_FIELDS)\n const values = useReadable(form?.values, NO_VALUES)\n // Stable for the life of the document, so hosts can pass them as props or effect deps.\n const actions = useMemo(\n () => ({\n set: (v: FieldValues) => form?.set(v),\n reset: (names?: string[]) => form?.reset(names),\n }),\n [form]\n )\n return useMemo(() => ({ fields, values, ...actions }), [fields, values, actions])\n}\n","import { useLayoutEffect, useRef, type RefObject } from 'react'\n\n/**\n * A ref that always holds the latest render's value, for callbacks that outlive a render\n * (core's `onChange`, effects keyed on something else). Updated in a layout effect, so it is\n * current before the parent's own layout and passive effects and before any callback fired\n * after commit; declare it before the effects that read it.\n */\nexport function useLatest<T>(value: T): RefObject<T> {\n const ref = useRef(value)\n useLayoutEffect(() => {\n ref.current = value\n })\n return ref\n}\n","import {\n createMemorySignatureStore,\n createSignatureLibrary,\n createSnapshotHistory,\n InkError,\n openDocument,\n readonly,\n writable,\n} from '@inkbar/core'\nimport {\n attachHistoryKeys,\n createPluginHost,\n createSearchController,\n createToolOptions,\n cssVariableDefaults,\n FONT_FAMILIES,\n handleFindKey,\n keepHistoryFocus,\n pageSelectionText,\n SIGNATURE_FONTS,\n trackToolStyle,\n viewerSearchOf,\n} from '@inkbar/core/dom'\nimport { Slot } from 'radix-ui'\nimport {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n type Ref,\n} from 'react'\nimport { flushSync } from 'react-dom'\n\nimport {\n InkContextObject,\n type InkContext,\n type InkHistory,\n type InkStatus,\n} from '../context'\nimport { useLatest } from '../use-latest'\nimport { useReadable } from '../use-readable'\n\nimport type {\n Annotation,\n AnnotationChange,\n AnnotationDefaults,\n DocumentSource,\n FieldsChange,\n FieldValues,\n FormAction,\n InkDocument,\n PdfAssets,\n PluginHistory,\n SignatureStore,\n Writable,\n} from '@inkbar/core'\nimport type {\n DecorateAnnotation,\n InkPlugin,\n PluginHost,\n SearchController,\n Tool,\n ToolController,\n ToolId,\n Viewport,\n ZoomValue,\n} from '@inkbar/core/dom'\n\nexport interface InkRootHandle {\n readonly document: InkDocument | null\n readonly status: InkStatus\n readonly rootEl: HTMLElement | null\n /** What `useHistory()` returns inside the root. A controlled host calls `clear()` after loading its saved list. */\n readonly history: InkHistory\n}\n\nexport interface InkRootProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children' | 'onChange' | 'onError'\n> {\n src: DocumentSource | null\n assets: PdfAssets\n password?: string | undefined\n /** Colour defaults. Without it, the theme's CSS variables on the root element apply. */\n defaults?: AnnotationDefaults | undefined\n /**\n * Pass (with `onAnnotationsChange`) to put annotations under the host's control. The mode\n * is fixed when a document opens: passing or dropping this prop later takes effect on the\n * next open.\n */\n annotations?: Annotation[] | undefined\n onAnnotationsChange?: ((next: Annotation[]) => void) | undefined\n onChange?: ((change: AnnotationChange) => void) | undefined\n /**\n * Pass (with `onFieldsChange`) to put the form's field values under the host's control. A\n * commit shows at once and is reported after; the host's push wins. The mode is fixed when\n * a document opens, as for `annotations`.\n */\n fields?: FieldValues | undefined\n /**\n * Committed field values, in full, with what changed them, one microtask after the commit.\n * Called only while the fields are controlled.\n */\n onFieldsChange?: ((next: FieldValues, change: FieldsChange) => void) | undefined\n /** The form asked to submit, open a link, send mail, print or prompt. Inkbar does none. */\n onFormAction?: ((action: FormAction) => void) | undefined\n /** Tints fillable form fields. Default true. A change applies to the open document in place. */\n formHighlight?: boolean | undefined\n tool?: ToolId | undefined\n onToolChange?: ((tool: ToolId) => void) | undefined\n /**\n * Host tools, added to the built-ins; one with a built-in's id replaces it. Read when a\n * document opens.\n */\n tools?: Tool[] | undefined\n /**\n * Plugins, set up once when the root mounts; a later change to this prop is not applied.\n * Their tools join `tools`, their decoration and page layers apply to every document, and\n * their commands are placed with `InkCommand` or `useCommand`.\n */\n plugins?: InkPlugin[] | undefined\n /**\n * Adds `data-*` attributes, classes and a screen-reader description to each annotation's\n * element (see `DecorateAnnotation`). Decorations re-apply whenever the annotations change\n * and when this prop changes, without rebuilding the viewer. Pass a new function when its\n * output would change for any other reason.\n */\n decorateAnnotation?: DecorateAnnotation | undefined\n /**\n * The font families text boxes offer, replacing the PDF standard families\n * (`FONT_FAMILIES`). Fonts beyond those are the PDF writer's to embed.\n */\n fonts?: string[] | undefined\n /**\n * Where saved signatures live. Default: memory, gone on reload. `createLocalSignatureStore`\n * keeps them in the browser; a host can keep them anywhere. A new store takes effect at\n * once, for the menus and the `signature` tool alike.\n */\n signatures?: SignatureStore | undefined\n /** The handwriting fonts a typed signature offers; the host loads them. */\n signatureFonts?: string[] | undefined\n page?: number | undefined\n onPageChange?: ((page: number) => void) | undefined\n zoom?: ZoomValue | undefined\n onZoomChange?: ((zoom: ZoomValue) => void) | undefined\n /** Undo history. Defaults to on for uncontrolled, off for controlled. */\n history?: boolean | undefined\n asChild?: boolean | undefined\n onReady?: ((doc: InkDocument) => void) | undefined\n /**\n * Opening failed, or later: a form script failed (`FormScriptError`; the form stays\n * fillable), or a signature field refused its signing (`FieldSigned`, `FieldReadOnly`).\n * A later error arrives one microtask after it happened, as `onFieldsChange` does; one from\n * while the document opened arrives after `onReady`.\n */\n onError?: ((error: InkError) => void) | undefined\n onActivate?: ((id: string) => void) | undefined\n children?:\n | ReactNode\n | ((props: { status: InkStatus; document: InkDocument | null }) => ReactNode)\n ref?: Ref<InkRootHandle>\n}\n\ntype TestHookElement = HTMLElement & { __inkDocument?: InkDocument | undefined }\n\nconst IDLE: InkStatus = { state: 'idle' }\nconst NO_ANNOTATIONS: readonly Annotation[] = []\nconst NO_IDS: readonly string[] = []\nconst noop = (): void => undefined\n\n/** The readables the plugin host follows, for the root's life. */\ninterface RootPlugins {\n /** Set once the document is current, so the host reads the history that goes with it. */\n document: Writable<InkDocument | null>\n /** InkViewport's scroll element while it is mounted. */\n root: Writable<HTMLElement | null>\n activated: Writable<string | null>\n}\n\n/** A plugin host and the search controller it shares, and whether they have been torn down. */\ninterface RootHost {\n host: PluginHost\n search: SearchController\n destroyed: boolean\n}\n\n/** Signed URLs change; the key does not. Bytes and Blobs are their own identity. */\nfunction identity(src: DocumentSource | null): unknown {\n if (src === null) return null\n if (typeof src === 'string') return src\n if ('key' in src) return src.key\n return src\n}\n\nfunction isDevelopment(): boolean {\n // Bundlers replace the expression with a literal; raw browser ESM has no `process`.\n try {\n return process.env.NODE_ENV !== 'production'\n } catch {\n return false\n }\n}\n\nfunction setTestHook(el: HTMLElement | null, doc: InkDocument | undefined): void {\n if (el && isDevelopment()) (el as TestHookElement).__inkDocument = doc\n}\n\nexport function InkRoot({\n src,\n assets,\n password,\n defaults,\n annotations,\n onAnnotationsChange,\n onChange,\n fields,\n onFieldsChange,\n onFormAction,\n formHighlight,\n tool,\n onToolChange,\n tools: hostTools,\n plugins: pluginsProp,\n decorateAnnotation,\n fonts: fontsProp,\n signatures: signatureStore,\n signatureFonts: signatureFontsProp,\n page,\n onPageChange,\n zoom,\n onZoomChange,\n history,\n asChild = false,\n onReady,\n onError,\n onActivate,\n children,\n ref,\n ...rest\n}: InkRootProps) {\n const rootElRef = useRef<HTMLElement | null>(null)\n const [rootEl, setRootElState] = useState<HTMLElement | null>(null)\n const setRootEl = useCallback((el: HTMLElement | null) => {\n rootElRef.current = el\n setRootElState(el)\n }, [])\n\n const documentRef = useRef<InkDocument | null>(null)\n const [document, setDocument] = useState<InkDocument | null>(null)\n /** Overrides the document's status while opening, and when opening itself failed. */\n const [override, setOverride] = useState<InkStatus | null>(null)\n const [internalTool, setInternalTool] = useState<ToolId>(tool ?? 'select-text')\n const [activated, setActivatedState] = useState<string | null>(null)\n const [viewport, setViewportState] = useState<Viewport | null>(null)\n /** The viewport as of the last `setViewport`, for the plugin host's `scrollTo`. */\n const viewportRef = useRef<Viewport | null>(null)\n const [tools, setToolsState] = useState<ToolController | null>(null)\n\n const documentStatus = useReadable<InkStatus>(document?.status, IDLE)\n const status = override ?? documentStatus\n const annotationList = useReadable(document?.annotations.list, NO_ANNOTATIONS)\n const selection = useReadable(document?.annotations.selection, NO_IDS)\n\n // What the next open will do follows the prop; the open document's mode is fixed.\n const controlledProp = annotations !== undefined\n const controlled = document\n ? document.annotations.mode === 'controlled'\n : controlledProp\n const historyEnabled = controlled && history === true\n // Callbacks and options read later than the render that passed them.\n const latest = useLatest({\n src,\n assets,\n defaults,\n annotations,\n controlled: controlledProp,\n fields,\n onFieldsChange,\n onFormAction,\n history,\n historyEnabled,\n onAnnotationsChange,\n onChange,\n onReady,\n onError,\n onActivate,\n onToolChange,\n onPageChange,\n onZoomChange,\n hostTools,\n plugins: pluginsProp,\n decorateAnnotation,\n tool: internalTool,\n tools,\n })\n\n /**\n * Hands `e` to `onError` one microtask later, as `onFieldsChange` and `onFormAction` are: a\n * script or a press reports from inside its own work. Dropped once `doc` is no longer open.\n */\n const reportErrorFor = useCallback(\n (doc: InkDocument, e: InkError) => {\n queueMicrotask(() => {\n if (documentRef.current !== doc) return\n flushSync(() => latest.current.onError?.(e))\n })\n },\n [latest]\n )\n\n const snapshotHistory = useMemo(\n () =>\n createSnapshotHistory({\n apply: (list) => documentRef.current?.annotations.replaceAll(list, 'history'),\n enabled: () => latest.current.historyEnabled,\n }),\n [latest]\n )\n // A layout effect, like the one that pushes the list into the store below: history sees each\n // list in the same commit the store does, so a change made once the store has a list (a\n // sketch swapping its stroke for a shape) is never folded into the step before it.\n useLayoutEffect(() => {\n snapshotHistory.observe(annotations)\n }, [annotations, snapshotHistory])\n\n /** What the plugin host follows; plain readables, so StrictMode's second render is harmless. */\n const [plugins] = useState<RootPlugins>(() => ({\n document: writable<InkDocument | null>(null),\n root: writable<HTMLElement | null>(null),\n activated: writable<string | null>(null),\n }))\n const setActivated = useCallback(\n (id: string | null) => {\n setActivatedState(id)\n plugins.activated.set(id)\n if (id) latest.current.onActivate?.(id)\n },\n [latest, plugins]\n )\n\n /**\n * The history the plugins reach, picked by the open document's mode when they call: the host\n * reads it as soon as a document opens, before this root has rendered with that document.\n */\n const pluginHistory = useMemo<PluginHistory>(() => {\n const active = (): PluginHistory | undefined => {\n const doc = documentRef.current\n if (!doc) return undefined\n return doc.annotations.mode === 'controlled' ? snapshotHistory : doc.history\n }\n return {\n batch: (fn) => {\n const h = active()\n if (h) h.batch(fn)\n else fn()\n },\n track: (store) => active()?.track(store) ?? noop,\n react: (fn) => active()?.react(fn) ?? noop,\n }\n }, [snapshotHistory])\n\n /*\n * One plugin host for the root's life, built in a layout effect so that no `setup` runs on\n * the server, where nothing would clean it up, and the browser never paints the commands\n * without it. Until then `pluginHost` is null and InkCommand renders its command disabled.\n * Layout effects run before the passive effect that opens the document, so the first\n * document opens with the plugins' stores and reactions.\n */\n const hostRef = useRef<RootHost | null>(null)\n const [pluginHost, setPluginHost] = useState<PluginHost | null>(null)\n const [search, setSearch] = useState<SearchController | null>(null)\n const hostMounts = useRef(0)\n useLayoutEffect(() => {\n hostMounts.current += 1\n // StrictMode's simulated unmount mounts again at once, and then the host from the first\n // mount stays. Shown again after it was destroyed (an `<Activity>` hidden and shown), or\n // mounted for the first time: start anew.\n if (!hostRef.current || hostRef.current.destroyed) {\n const search = createSearchController({\n document: readonly(plugins.document),\n viewport: () => viewportRef.current,\n })\n const host = createPluginHost({\n plugins: latest.current.plugins ?? [],\n document: readonly(plugins.document),\n history: () => pluginHistory,\n activated: readonly(plugins.activated),\n // As in `createViewer`: an id not in the open document is ignored.\n setActivated: (id) => {\n if (id === null || documentRef.current?.annotations.get(id)) setActivated(id)\n },\n root: readonly(plugins.root),\n decorate: () => latest.current.decorateAnnotation,\n viewport: () => viewportRef.current,\n search: viewerSearchOf(search),\n })\n hostRef.current = { host, search, destroyed: false }\n setPluginHost(host)\n setSearch(search)\n }\n return () => {\n hostMounts.current -= 1\n // After the rest of this commit's cleanups, so InkViewport's engine and its plugin layers\n // go first, as in `createViewer`.\n queueMicrotask(() => {\n const current = hostRef.current\n if (hostMounts.current > 0 || !current || current.destroyed) return\n current.destroyed = true\n current.host.destroy()\n current.search.destroy()\n })\n }\n // Once per mount; the host reads only stable values and refs.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const srcIdentity = identity(src)\n useEffect(() => {\n let cancelled = false\n snapshotHistory.clear()\n const source = latest.current.src\n if (source === null) {\n setOverride(null)\n return\n }\n setOverride({ state: 'loading' })\n let opened: InkDocument | null = null\n /** The plugins told of `opened`, and the snapshot history's hold on its store. */\n let told: RootPlugins | null = null\n let detach: () => void = noop\n let stopFormErrors: () => void = noop\n const run = async () => {\n try {\n const doc = await openDocument(source, {\n assets: latest.current.assets,\n password,\n defaults:\n latest.current.defaults ??\n (rootElRef.current ? cssVariableDefaults(rootElRef.current) : undefined),\n // Controlled hosts get the snapshot history below; core's own stack stays off.\n history: latest.current.controlled ? false : (latest.current.history ?? true),\n annotations: latest.current.controlled\n ? {\n mode: 'controlled',\n initial: latest.current.annotations ?? [],\n onChange: (next, change) => {\n // Apply the host's state update, its render and the layout effect that pushes\n // the list back before core's development check expires. The microtask\n // leaves React's render, commit and passive-effect contexts, where a host\n // may call the store, so `flushSync` is always legal; the host sees the\n // proposal one microtask after the store returned. A proposal made in the\n // tick this root unmounts or reopens never reaches the host.\n queueMicrotask(() => {\n if (cancelled) return\n flushSync(() => {\n latest.current.onAnnotationsChange?.(next)\n latest.current.onChange?.(change)\n })\n })\n },\n }\n : { mode: 'uncontrolled' },\n fields:\n latest.current.fields !== undefined\n ? {\n mode: 'controlled',\n initial: latest.current.fields,\n // Deferred and flushed as annotation proposals are, for the same reasons.\n onChange: (next, change) => {\n queueMicrotask(() => {\n if (cancelled) return\n flushSync(() => latest.current.onFieldsChange?.(next, change))\n })\n },\n }\n : { mode: 'uncontrolled' },\n })\n if (cancelled) {\n doc.destroy()\n return\n }\n opened = doc\n // The prop may have changed while the file loaded, when there was no store to apply it to.\n const current = latest.current.annotations\n if (doc.annotations.mode === 'controlled' && current !== undefined)\n doc.annotations.setControlledValue(current)\n // The same for the fields; a document whose fields opened uncontrolled ignores the push.\n const currentFields = latest.current.fields\n if (currentFields !== undefined) doc.form.setControlledValue(currentFields)\n // A form script that fails leaves the form fillable; the failure goes to `onError`.\n // Subscribed before anyone hears of the document, so the form replays the errors from\n // while it opened here; they are held until `onReady` has run.\n let held: InkError[] | undefined = []\n stopFormErrors = doc.form.on('error', (e) => {\n if (held) held.push(e)\n else reportErrorFor(doc, e)\n })\n documentRef.current = doc\n // Controlled edits run the plugins' reactions inside their own snapshot step.\n if (doc.annotations.mode === 'controlled')\n detach = snapshotHistory.attach(doc.annotations)\n // The document is current, so the host reads its history when it hears of it.\n told = plugins\n told.document.set(doc)\n setDocument(doc)\n setOverride(null)\n setTestHook(rootElRef.current, doc)\n const s = doc.status.get()\n try {\n if (s.state === 'ready') latest.current.onReady?.(doc)\n else if (s.state === 'error') latest.current.onError?.(s.error)\n } finally {\n // A host whose `onReady` throws still hears the held errors and every later one.\n const early = held\n held = undefined\n for (const e of early) reportErrorFor(doc, e)\n }\n } catch (cause) {\n if (cancelled) return\n const error =\n cause instanceof InkError\n ? cause\n : new InkError(\n 'InvalidPdf',\n cause instanceof Error ? cause.message : String(cause),\n {},\n cause\n )\n setOverride({ state: 'error', error })\n latest.current.onError?.(error)\n }\n }\n // StrictMode's simulated cleanup runs synchronously in the same commit, so deferring one\n // microtask means the discarded first attempt never starts a fetch.\n void Promise.resolve().then(() => {\n if (!cancelled) return run()\n })\n return () => {\n cancelled = true\n // Cleared first, so the plugins close their stores while the document is still alive.\n told?.document.set(null)\n detach()\n stopFormErrors()\n opened?.destroy()\n documentRef.current = null\n setDocument(null)\n setTestHook(rootElRef.current, undefined)\n }\n // `srcIdentity` stands in for `src`: a new URL with the same key is the same document.\n }, [srcIdentity, password, snapshotHistory, latest, plugins, reportErrorFor])\n\n useLayoutEffect(() => {\n if (annotations && document?.annotations.mode === 'controlled')\n document.annotations.setControlledValue(annotations)\n }, [annotations, document])\n\n useLayoutEffect(() => {\n if (fields && document) document.form.setControlledValue(fields)\n }, [fields, document])\n\n useEffect(() => {\n if (tool) setInternalTool(tool)\n }, [tool])\n\n const setTool = useCallback(\n (id: ToolId) => {\n // Picking the active tool again starts it afresh, as after a one-shot tool's use.\n const tc = latest.current.tools\n if (latest.current.tool === id && tc?.active.get() === id) tc.set(id)\n setInternalTool(id)\n latest.current.onToolChange?.(id)\n },\n [latest]\n )\n const reportZoom = useCallback(\n (z: ZoomValue) => latest.current.onZoomChange?.(z),\n [latest]\n )\n const reportPage = useCallback(\n (p: number) => latest.current.onPageChange?.(p),\n [latest]\n )\n const reportFormAction = useCallback(\n (a: FormAction) => {\n // As for `onFieldsChange`: the engine reports from inside a press or a script.\n const doc = documentRef.current\n queueMicrotask(() => {\n if (documentRef.current !== doc) return\n flushSync(() => latest.current.onFormAction?.(a))\n })\n },\n [latest]\n )\n const reportError = useCallback(\n (e: InkError) => {\n if (documentRef.current) reportErrorFor(documentRef.current, e)\n },\n [reportErrorFor]\n )\n const setViewport = useCallback((vp: Viewport | null, tc: ToolController | null) => {\n viewportRef.current = vp\n setViewportState(vp)\n setToolsState(tc)\n }, [])\n\n const snapCanUndo = useReadable(snapshotHistory.canUndo, false)\n const snapCanRedo = useReadable(snapshotHistory.canRedo, false)\n const coreCanUndo = useReadable(document?.history.canUndo, false)\n const coreCanRedo = useReadable(document?.history.canRedo, false)\n const inkHistory = useMemo<InkHistory>(\n () => ({\n canUndo: controlled ? historyEnabled && snapCanUndo : coreCanUndo,\n canRedo: controlled ? historyEnabled && snapCanRedo : coreCanRedo,\n undo: () =>\n controlled ? snapshotHistory.undo() : documentRef.current?.history.undo(),\n redo: () =>\n controlled ? snapshotHistory.redo() : documentRef.current?.history.redo(),\n clear: () =>\n controlled ? snapshotHistory.clear() : documentRef.current?.history.clear(),\n batch: (fn) => {\n if (controlled) snapshotHistory.batch(fn)\n else if (documentRef.current) documentRef.current.history.batch(fn)\n else fn()\n },\n track: (store) => pluginHistory.track(store),\n react: (fn) => pluginHistory.react(fn),\n }),\n [\n controlled,\n historyEnabled,\n snapCanUndo,\n snapCanRedo,\n coreCanUndo,\n coreCanRedo,\n snapshotHistory,\n pluginHistory,\n ]\n )\n\n const latestHistory = useLatest(inkHistory)\n\n // The undo and redo keys anywhere in the root do what InkUndo and InkRedo do. When either\n // button undoes or redoes the last step and disables itself, focus goes back to the document.\n useEffect(() => {\n if (!rootEl) return\n // The flags are read from the stacks, not from the last render: a held key repeats before\n // React renders again, and a stale `canUndo` would prevent a key that undoes nothing.\n const stopKeys = attachHistoryKeys(rootEl, () => {\n const doc = documentRef.current\n if (!doc) return null\n const snap = doc.annotations.mode === 'controlled'\n const on = latest.current.historyEnabled\n return {\n canUndo: snap ? on && snapshotHistory.canUndo.get() : doc.history.canUndo.get(),\n canRedo: snap ? on && snapshotHistory.canRedo.get() : doc.history.canRedo.get(),\n undo: () => latestHistory.current.undo(),\n redo: () => latestHistory.current.redo(),\n }\n })\n const stopFocus = keepHistoryFocus(rootEl, () =>\n rootEl.querySelector<HTMLElement>('[data-ink-scroll]')\n )\n return () => {\n stopKeys()\n stopFocus()\n }\n }, [rootEl, latestHistory, latest, snapshotHistory])\n\n /** The document's tool style; it batches through `history`, whichever mode is on. */\n const styleTracker = useMemo(\n () =>\n document\n ? trackToolStyle({\n store: document.annotations,\n history: { batch: (fn) => latestHistory.current.batch(fn) },\n // The plugins' tools too, so a plugin tool's style group applies.\n tools: [...(latest.current.hostTools ?? []), ...(pluginHost?.tools ?? [])],\n tool: latest.current.tool,\n })\n : null,\n [document, latest, latestHistory, pluginHost]\n )\n useEffect(() => {\n styleTracker?.setTool(internalTool)\n }, [styleTracker, internalTool])\n\n useImperativeHandle(ref, () => ({ document, status, rootEl, history: inkHistory }), [\n document,\n status,\n rootEl,\n inkHistory,\n ])\n\n // Stable while the host passes the same list.\n const fonts = useMemo<readonly string[]>(() => fontsProp ?? FONT_FAMILIES, [fontsProp])\n const signatureFonts = useMemo<readonly string[]>(\n () => signatureFontsProp ?? SIGNATURE_FONTS,\n [signatureFontsProp]\n )\n const signatures = useMemo(\n () => createSignatureLibrary(signatureStore ?? createMemorySignatureStore()),\n [signatureStore]\n )\n useEffect(() => {\n void signatures.refresh()\n }, [signatures])\n /** Tool options last as long as the root; the tool style is per document. */\n const [toolOptions] = useState(createToolOptions)\n\n // The prop is read through a stable function and kept out of the context's dependencies, so\n // an inline arrow does not re-render every consumer. InkViewport hears of a change instead.\n const decorate = useCallback<DecorateAnnotation>(\n (a) => latest.current.decorateAnnotation?.(a),\n [latest]\n )\n const [decorateListeners] = useState(() => new Set<() => void>())\n const onDecorateAnnotationChange = useCallback(\n (listener: () => void) => {\n decorateListeners.add(listener)\n return () => {\n decorateListeners.delete(listener)\n }\n },\n [decorateListeners]\n )\n const decoratedOnce = useRef(false)\n useEffect(() => {\n // The first build reads the prop itself.\n if (!decoratedOnce.current) {\n decoratedOnce.current = true\n return\n }\n for (const listener of decorateListeners) listener()\n }, [decorateAnnotation, decorateListeners])\n\n const ctx = useMemo<InkContext>(\n () => ({\n assets,\n document,\n status,\n annotations: annotationList,\n selection,\n viewport,\n tools,\n tool: internalTool,\n setTool,\n hostTools,\n decorateAnnotation: decorate,\n onDecorateAnnotationChange,\n fonts,\n toolOptions,\n signatures,\n signatureFonts,\n toolStyle: styleTracker?.toolStyle ?? null,\n zoomModel: zoom,\n pageModel: page,\n reportZoom,\n reportPage,\n activated,\n setActivated,\n pluginHost,\n search,\n viewportEl: plugins.root,\n history: inkHistory,\n rootEl,\n setViewport,\n formHighlight,\n reportFormAction,\n reportError,\n }),\n [\n assets,\n document,\n status,\n annotationList,\n selection,\n viewport,\n tools,\n internalTool,\n setTool,\n hostTools,\n decorate,\n onDecorateAnnotationChange,\n fonts,\n toolOptions,\n signatures,\n signatureFonts,\n styleTracker,\n zoom,\n page,\n reportZoom,\n reportPage,\n activated,\n setActivated,\n pluginHost,\n search,\n plugins,\n inkHistory,\n rootEl,\n setViewport,\n formHighlight,\n reportFormAction,\n reportError,\n ]\n )\n\n /*\n * Ctrl/Cmd+F while focus is in the root and a find bar is mounted; else the browser's. A\n * native listener: the handler reads the event's `currentTarget`, which React's delegated\n * synthetic events do not leave on the root.\n */\n useEffect(() => {\n if (!rootEl || !search) return\n const onKeyDown = (e: globalThis.KeyboardEvent): void => {\n handleFindKey(e, search, () => pageSelectionText(rootEl))\n }\n rootEl.addEventListener('keydown', onKeyDown)\n return () => rootEl.removeEventListener('keydown', onKeyDown)\n }, [rootEl, search])\n\n const Comp = asChild ? Slot.Root : 'div'\n return (\n <InkContextObject.Provider value={ctx}>\n <Comp ref={setRootEl} data-ink-root=\"\" data-state={status.state} {...rest}>\n {typeof children === 'function' ? children({ status, document }) : children}\n </Comp>\n </InkContextObject.Provider>\n )\n}\n","/** Joins class names, dropping empties. */\nexport function cx(...parts: (string | undefined | false)[]): string | undefined {\n const out = parts.filter(Boolean).join(' ')\n return out === '' ? undefined : out\n}\n","/*\n * A form script's `app.alert`: the message and OK, shown without blocking (no overlay, not\n * modal), so the form stays usable around it. InkViewport mounts it; hosts compose nothing.\n * OK, or Escape while focus is in the alert, closes it, and focus goes back where it was. A\n * press outside leaves it open, and Escape anywhere else stays with the viewer. A new message\n * replaces the one shown.\n *\n * The markup is core's `createFormAlert`, portalled to `<body>`. It is not a Radix dialog:\n * Radix's dismissable layer takes every Escape on the page while it is open, which would end\n * the viewer's own use of the key.\n */\nimport { FORM_LABELS } from '@inkbar/core/dom'\nimport { useId, useLayoutEffect, useRef } from 'react'\nimport { createPortal } from 'react-dom'\n\nexport function InkFormAlert({\n message,\n shown,\n fallback,\n onClose,\n}: {\n /** The message to show (text, not markup); `null` while none is. */\n message: string | null\n /** Counts the times a message was shown, so the same text shown again takes focus again. */\n shown: number\n /** Where focus goes when nothing it can return to is left. */\n fallback: () => HTMLElement | null\n onClose: () => void\n}) {\n const uid = useId()\n const panel = useRef<HTMLDivElement>(null)\n const ok = useRef<HTMLButtonElement>(null)\n /** Where focus was when the alert opened. */\n const returnTo = useRef<HTMLElement | null>(null)\n const open = message !== null\n const wasOpen = useRef(false)\n\n // Before paint, so focus is read before it moves to OK.\n useLayoutEffect(() => {\n if (!open) {\n wasOpen.current = false\n return\n }\n if (!wasOpen.current) {\n wasOpen.current = true\n const active = document.activeElement\n returnTo.current =\n active instanceof HTMLElement && active !== document.body ? active : null\n }\n ok.current?.focus({ preventScroll: true })\n }, [open, shown])\n\n const close = (): void => {\n // Focus that moved elsewhere while the alert showed stays there.\n const hadFocus = !!panel.current?.contains(document.activeElement)\n onClose()\n if (!hadFocus) return\n const back = returnTo.current?.isConnected === true ? returnTo.current : fallback()\n back?.focus({ preventScroll: true })\n }\n\n if (!open) return null\n return createPortal(\n <div\n ref={panel}\n role=\"alertdialog\"\n aria-labelledby={`${uid}-title`}\n aria-describedby={`${uid}-message`}\n className=\"ink-dialog ink-form-alert\"\n data-ink-form-alert=\"\"\n data-state=\"open\"\n tabIndex={-1}\n onKeyDown={(e) => {\n if (e.key !== 'Escape' || e.defaultPrevented) return\n e.preventDefault()\n e.stopPropagation()\n close()\n }}\n >\n <h2 id={`${uid}-title`} className=\"ink-dialog-title\">\n {FORM_LABELS.alert}\n </h2>\n <p\n id={`${uid}-message`}\n className=\"ink-form-alert-message\"\n data-ink-form-alert-message=\"\"\n >\n {message}\n </p>\n <div className=\"ink-dialog-actions\">\n <button\n ref={ok}\n type=\"button\"\n className=\"ink-button\"\n data-variant=\"primary\"\n data-ink-form-alert-ok=\"\"\n onClick={close}\n >\n {FORM_LABELS.ok}\n </button>\n </div>\n </div>,\n document.body\n )\n}\n","/*\n * Slot props for one annotation. It renders only its children: the overlay already draws the\n * default visual for every annotation that is not custom, so this never draws a second one.\n * InkPage portals it into the annotation's overlay element.\n */\nimport { useEffect, useMemo, useState, type ReactNode } from 'react'\n\nimport { useInkContext } from '../context'\n\nimport type { Annotation } from '@inkbar/core'\nimport type { AnnotationSlotProps, AnnotationState } from '@inkbar/core/dom'\n\nexport interface InkAnnotationProps {\n annotation: Annotation\n /** The overlay element; its `data-state` (which includes hover) drives `state`. */\n element?: HTMLElement | undefined\n children: (props: AnnotationSlotProps) => ReactNode\n}\n\nfunction readState(el: HTMLElement): AnnotationState | null {\n const s = el.dataset.state\n return s === 'idle' || s === 'hover' || s === 'selected' ? s : null\n}\n\nexport function InkAnnotation({ annotation, element, children }: InkAnnotationProps) {\n const ctx = useInkContext('InkAnnotation')\n const [observed, setObserved] = useState<AnnotationState | null>(() =>\n element ? readState(element) : null\n )\n useEffect(() => {\n if (!element) {\n setObserved(null)\n return\n }\n setObserved(readState(element))\n const observer = new MutationObserver(() => setObserved(readState(element)))\n observer.observe(element, { attributes: true, attributeFilter: ['data-state'] })\n return () => observer.disconnect()\n }, [element])\n\n const { id } = annotation\n const locked = annotation.locked === true\n const selected = ctx.selection.includes(id)\n const store = ctx.document?.annotations\n const slotProps = useMemo<AnnotationSlotProps>(\n () => ({\n annotation,\n state: observed ?? (selected ? 'selected' : 'idle'),\n locked,\n select: () => store?.select([id]),\n remove: () => void store?.remove(id),\n }),\n [annotation, observed, selected, locked, store, id]\n )\n return <>{children(slotProps)}</>\n}\n","/*\n * One page the viewer engine mounted. Renders nothing in place; portals go into the host\n * (page error) and into each annotation's overlay element (custom annotations).\n *\n * The overlay creates and removes those elements as the annotation list changes, outside\n * React. So the portal targets come from a list read after every overlay render: this\n * component subscribes to the store after the overlay does (the engine created the mount\n * first), and core notifies subscribers in order, so the elements already exist when the list\n * arrives here.\n *\n * The engine tracks page errors and sets `data-state=\"error\"` on the host; this component\n * portals the page-error slot into it while `error` is set.\n */\nimport { useEffect, useState, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { useInkContext } from '../context'\n\nimport { InkAnnotation } from './InkAnnotation'\n\nimport type { Annotation, InkError } from '@inkbar/core'\nimport type { AnnotationSlotProps, PageMount } from '@inkbar/core/dom'\n\nexport interface InkPageProps {\n page: number\n host: HTMLElement\n /** The engine's page mount in `host`. */\n mount: PageMount\n /** The engine's error for this page, `null` while it renders. */\n error: InkError | null\n /** Fixed for the life of the mount: the engine rebuilds when it changes. */\n customAnnotations?: boolean\n renderAnnotation?: ((props: AnnotationSlotProps) => ReactNode) | undefined\n renderPageError?: ((props: { error: InkError; page: number }) => ReactNode) | undefined\n}\n\ninterface Target {\n annotation: Annotation\n el: HTMLElement\n}\n\nfunction sameTargets(a: readonly Target[], b: readonly Target[]): boolean {\n return (\n a.length === b.length &&\n a.every((t, i) => t.annotation === b[i]!.annotation && t.el === b[i]!.el)\n )\n}\n\nexport function InkPage({\n page,\n host,\n mount,\n error,\n customAnnotations = false,\n renderAnnotation,\n renderPageError,\n}: InkPageProps) {\n const doc = useInkContext('InkPage').document\n const [targets, setTargets] = useState<Target[]>([])\n\n useEffect(() => {\n if (!doc || !customAnnotations) return\n const read = (): void => {\n const next = doc.annotations.byPage(page).flatMap((annotation) => {\n const el = mount.overlay.elementFor(annotation.id)\n return el ? [{ annotation, el }] : []\n })\n // A change elsewhere in the document leaves this page's targets as they were.\n setTargets((prev) => (sameTargets(prev, next) ? prev : next))\n }\n const stop = doc.annotations.list.subscribe(read)\n read()\n return () => {\n stop()\n setTargets([])\n }\n }, [doc, page, mount, customAnnotations])\n\n return (\n <>\n {error\n ? createPortal(\n <div className=\"ink-page-error\" data-ink-page-error=\"\" role=\"alert\">\n {renderPageError ? (\n renderPageError({ error, page })\n ) : (\n <>\n <p>Page {page + 1} could not be shown.</p>\n <code className=\"ink-error-code\">{error.code}</code>\n </>\n )}\n </div>,\n host\n )\n : null}\n {renderAnnotation\n ? targets.map((t) =>\n createPortal(\n <InkAnnotation annotation={t.annotation} element={t.el}>\n {renderAnnotation}\n </InkAnnotation>,\n t.el,\n t.annotation.id\n )\n )\n : null}\n </>\n )\n}\n","/*\n * \"Create signature\": a modal with Draw, Type and Image tabs. Draw is a pad with the draw\n * tool's renderer; Type sets a name in one of the host's handwriting fonts; Image takes a PNG\n * or JPEG scan. Save stores the template through InkRoot's signature store and, unless `select`\n * is false, selects it for the `signature` tool. Escape, Cancel or a press outside closes it.\n */\nimport {\n createSignatureDraft,\n fontFamilyValue,\n handleRadioKeys,\n handleTabKeys,\n SIGNATURE_LABELS,\n SIGNATURE_TABS,\n type SignatureDraft,\n type SignatureDraftState,\n type SignatureTab,\n} from '@inkbar/core/dom'\nimport { Dialog } from 'radix-ui'\nimport { useEffect, useId, useRef, useState } from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useTool } from '../hooks/useTool'\nimport { useToolOptions } from '../hooks/useToolOptions'\nimport { useReadable } from '../use-readable'\n\nimport type { SignatureOptions, SignatureTemplate } from '@inkbar/core'\n\nexport interface InkSignatureDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n /** The fonts the Type tab offers. Default: InkRoot's `signatureFonts`. */\n fonts?: readonly string[] | undefined\n /**\n * Whether saving selects the new signature for the `signature` tool. Default true. False\n * leaves the tool alone, for a dialog that signs a field with it through `onSave`.\n */\n select?: boolean | undefined\n /** Called with the new template once it is saved (and selected, with `select`). */\n onSave?: ((template: SignatureTemplate) => void) | undefined\n /** Where focus goes on close; by default, back to what had it before. */\n onCloseAutoFocus?: ((event: Event) => void) | undefined\n className?: string | undefined\n}\n\nexport function InkSignatureDialog({\n open,\n onOpenChange,\n fonts,\n select = true,\n onSave,\n onCloseAutoFocus,\n className,\n}: InkSignatureDialogProps) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"ink-dialog-overlay\" data-ink-dialog-overlay=\"\" />\n <Dialog.Content\n className={cx('ink-dialog ink-signature-dialog', className)}\n data-ink-signature-dialog=\"\"\n aria-modal=\"true\"\n aria-describedby={undefined}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n ;(e.currentTarget as HTMLElement)\n .querySelector<HTMLElement>('[role=\"tab\"][aria-selected=\"true\"]')\n ?.focus({ preventScroll: true })\n }}\n onCloseAutoFocus={onCloseAutoFocus}\n >\n <Dialog.Title className=\"ink-dialog-title\">\n {SIGNATURE_LABELS.dialog}\n </Dialog.Title>\n <SignatureForm\n fonts={fonts}\n select={select}\n onSave={onSave}\n onClose={() => onOpenChange(false)}\n />\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n\nconst IDLE: SignatureDraftState = {\n tab: 'draw',\n padEmpty: true,\n name: '',\n font: '',\n image: undefined,\n imageError: undefined,\n saveError: undefined,\n canSave: false,\n saving: false,\n}\n\n/** The dialog's body, mounted while it is open: one draft per opening. */\nfunction SignatureForm({\n fonts,\n select,\n onSave,\n onClose,\n}: {\n fonts: readonly string[] | undefined\n select: boolean\n onSave: ((t: SignatureTemplate) => void) | undefined\n onClose: () => void\n}) {\n const ctx = useInkContext('InkSignatureDialog')\n const { setTool } = useTool()\n const [, setOptions] = useToolOptions<SignatureOptions>('signature')\n const [draft] = useState<SignatureDraft>(() =>\n createSignatureDraft({ fonts: fonts ?? ctx.signatureFonts })\n )\n const s = useReadable(draft.state, IDLE)\n const uid = useId()\n const padHost = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const host = padHost.current\n const detach = host ? draft.attachPad(host) : undefined\n return () => {\n detach?.()\n draft.destroy()\n }\n }, [draft])\n\n const save = (): void => {\n draft.save(ctx.signatures).then(\n (t) => {\n if (!t) return\n if (select) {\n setOptions({ templateId: t.id })\n setTool('signature')\n }\n onSave?.(t)\n onClose()\n },\n () => {\n // The host's store refused it: the dialog stays open to try again.\n }\n )\n }\n\n const tabId = (tab: SignatureTab) => `${uid}-tab-${tab}`\n const panelId = (tab: SignatureTab) => `${uid}-panel-${tab}`\n const panel = (tab: SignatureTab) => ({\n role: 'tabpanel',\n id: panelId(tab),\n 'aria-labelledby': tabId(tab),\n className: 'ink-tab-panel',\n 'data-key': tab,\n hidden: s.tab !== tab,\n })\n const shown = s.name.trim() || SIGNATURE_LABELS.namePlaceholder\n\n return (\n <>\n <div\n role=\"tablist\"\n aria-label={SIGNATURE_LABELS.tabs}\n className=\"ink-tabs\"\n onKeyDown={(e) => handleTabKeys(e.nativeEvent, e.currentTarget)}\n >\n {SIGNATURE_TABS.map((tab) => (\n <button\n key={tab}\n type=\"button\"\n role=\"tab\"\n id={tabId(tab)}\n aria-controls={panelId(tab)}\n aria-selected={s.tab === tab}\n tabIndex={s.tab === tab ? 0 : -1}\n className=\"ink-tab\"\n data-key={tab}\n data-state={s.tab === tab ? 'active' : 'inactive'}\n onClick={() => draft.setTab(tab)}\n >\n {SIGNATURE_LABELS[tab]}\n </button>\n ))}\n </div>\n <div {...panel('draw')}>\n <div\n ref={padHost}\n className=\"ink-signature-pad-host\"\n data-ink-signature-pad-host=\"\"\n role=\"img\"\n aria-label={SIGNATURE_LABELS.pad}\n />\n <div className=\"ink-dialog-row\">\n <button\n type=\"button\"\n className=\"ink-button\"\n data-ink-signature-clear=\"\"\n disabled={s.padEmpty}\n onClick={() => draft.clearPad()}\n >\n {SIGNATURE_LABELS.clear}\n </button>\n </div>\n </div>\n <div {...panel('type')}>\n <label className=\"ink-field\">\n <span>{SIGNATURE_LABELS.name}</span>\n <input\n type=\"text\"\n className=\"ink-input\"\n data-ink-signature-name=\"\"\n autoComplete=\"name\"\n placeholder={SIGNATURE_LABELS.namePlaceholder}\n value={s.name}\n onChange={(e) => draft.setName(e.target.value)}\n />\n </label>\n <div\n role=\"radiogroup\"\n aria-label={SIGNATURE_LABELS.fonts}\n className=\"ink-signature-fonts\"\n onKeyDown={(e) => handleRadioKeys(e.nativeEvent, e.currentTarget)}\n >\n {draft.fonts.map((font) => (\n <button\n key={font}\n type=\"button\"\n role=\"radio\"\n aria-checked={s.font === font}\n aria-label={font}\n tabIndex={s.font === font ? 0 : -1}\n className=\"ink-signature-font\"\n data-key={font}\n data-state={s.font === font ? 'checked' : 'unchecked'}\n onClick={() => draft.setFont(font)}\n >\n {/* The font is the option itself, so it is set here, not left to the theme. */}\n <span\n className=\"ink-signature-font-sample\"\n style={{ fontFamily: fontFamilyValue(font) }}\n >\n {shown}\n </span>\n </button>\n ))}\n </div>\n </div>\n <div {...panel('image')}>\n <label className=\"ink-field\">\n <span>{SIGNATURE_LABELS.file}</span>\n <input\n type=\"file\"\n accept=\"image/png,image/jpeg\"\n className=\"ink-input\"\n data-ink-signature-file=\"\"\n onChange={(e) => void draft.chooseFile(e.target.files?.[0])}\n />\n </label>\n {s.image?.kind === 'image' ? (\n <img className=\"ink-signature-image\" src={s.image.imagedata} alt=\"\" />\n ) : null}\n {s.imageError ? (\n <p className=\"ink-field-error\" role=\"alert\">\n {s.imageError}\n </p>\n ) : null}\n </div>\n {s.saveError ? (\n <p className=\"ink-field-error\" role=\"alert\" data-ink-signature-save-error=\"\">\n {s.saveError}\n </p>\n ) : null}\n <div className=\"ink-dialog-actions\">\n <Dialog.Close asChild>\n <button type=\"button\" className=\"ink-button\" data-ink-signature-cancel=\"\">\n {SIGNATURE_LABELS.cancel}\n </button>\n </Dialog.Close>\n <button\n type=\"button\"\n className=\"ink-button\"\n data-variant=\"primary\"\n data-ink-signature-save=\"\"\n disabled={!s.canSave}\n onClick={save}\n >\n {SIGNATURE_LABELS.save}\n </button>\n </div>\n </>\n )\n}\n","/*\n * An icon from `@inkbar/icons`, hidden from assistive technology: the control it sits in\n * carries the name. The theme sizes it with `--ink-icon-size`.\n */\nimport { ICON_ATTRIBUTES } from '@inkbar/icons'\nimport { createElement, type SVGProps } from 'react'\n\nimport type { IconNode } from '@inkbar/icons'\n\nexport interface InkIconProps {\n icon: IconNode\n size?: number\n}\n\n/** `stroke-width` to `strokeWidth`: React names SVG attributes in camelCase. */\nconst camel = (name: string) =>\n name.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase())\n\nconst SVG_ATTRIBUTES = Object.fromEntries(\n Object.entries(ICON_ATTRIBUTES).map(([k, v]) => [camel(k), v])\n) as SVGProps<SVGSVGElement>\n\nexport function InkIcon({ icon, size = 18 }: InkIconProps) {\n return (\n <svg\n {...SVG_ATTRIBUTES}\n width={size}\n height={size}\n className=\"ink-icon\"\n aria-hidden=\"true\"\n >\n {icon.map(([tag, attrs], i) => createElement(tag, { key: i, ...attrs }))}\n </svg>\n )\n}\n","/*\n * The signature menu's items: the saved signatures as previews, each with a remove button,\n * then \"Create signature\", and the store's removal error. The toolbar's `InkSignatureMenu`\n * and a signature field's `InkSignFieldPopover` both render it inside their `role=\"menu\"`\n * content, which `menu` points at.\n */\nimport { signaturePreview, SIGNATURE_LABELS } from '@inkbar/core/dom'\nimport { Plus, Trash2 } from '@inkbar/icons'\nimport { useEffect, useRef, type RefObject } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { SignatureTemplate } from '@inkbar/core'\nimport type { SignatureMenuItem } from '@inkbar/core/dom'\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\n/** A saved signature drawn small: ink as filled outlines, an image as itself. */\nfunction SignaturePreview({ template }: { template: SignatureTemplate }) {\n if (template.kind === 'image')\n return (\n <span className=\"ink-signature-preview\" data-kind=\"image\">\n <img src={template.imagedata} alt=\"\" draggable={false} />\n </span>\n )\n const { viewBox, paths } = signaturePreview(template)\n return (\n <span className=\"ink-signature-preview\" data-kind=\"ink\">\n <svg viewBox={viewBox} aria-hidden=\"true\">\n {paths.map((d, i) => (\n <path key={i} d={d} fill=\"currentColor\" />\n ))}\n </svg>\n </span>\n )\n}\n\nexport function SignatureMenuPanel({\n items,\n menu,\n onChoose,\n onCreate,\n}: {\n items: readonly SignatureMenuItem[]\n /** The menu element the items sit in, for moving focus after a removal. */\n menu: RefObject<HTMLElement | null>\n onChoose: (template: SignatureTemplate) => void\n onCreate: () => void\n}) {\n const { signatures } = useInkContext('SignatureMenuPanel')\n const templates = useReadable(signatures.templates, NO_TEMPLATES)\n const removeError = useReadable(signatures.removeError, undefined)\n /** The row of a removed signature, until focus lands on what took its place. */\n const removedRow = useRef<number | null>(null)\n\n useEffect(() => {\n const row = removedRow.current\n const panel = menu.current\n if (row === null || !panel) return\n removedRow.current = null\n const rows = panel.querySelectorAll<HTMLElement>('.ink-signature-item')\n const next =\n rows[Math.min(row, rows.length - 1)] ??\n panel.querySelector<HTMLElement>('[data-ink-signature-create]')\n next?.focus({ preventScroll: true })\n }, [templates, menu])\n\n const remove = (id: string, row: number): void => {\n // Set first: the list may re-render before the removal's promise settles.\n removedRow.current = row\n signatures.remove(id).catch(() => {\n // The host's store refused: the signature stays.\n removedRow.current = null\n })\n }\n\n return (\n <>\n {items.length > 0 ? (\n <>\n <div\n role=\"group\"\n aria-label={SIGNATURE_LABELS.saved}\n className=\"ink-signature-list\"\n data-ink-menu-columns={2}\n >\n {items.map((item, row) => [\n <button\n key={`${item.id}-choose`}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={item.checked}\n aria-label={item.label}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item ink-signature-item\"\n data-ink-select-item=\"\"\n data-key={item.id}\n data-state={item.checked ? 'checked' : 'unchecked'}\n onClick={() => onChoose(item.template)}\n >\n <SignaturePreview template={item.template} />\n </button>,\n <button\n key={`${item.id}-remove`}\n type=\"button\"\n role=\"menuitem\"\n aria-label={item.removeLabel}\n title={item.removeLabel}\n tabIndex={-1}\n className=\"ink-menu-item ink-signature-remove\"\n data-ink-signature-remove=\"\"\n data-key={item.id}\n onClick={() => remove(item.id, row)}\n >\n <InkIcon icon={Trash2} size={16} />\n </button>,\n ])}\n </div>\n <div role=\"separator\" className=\"ink-select-separator\" />\n </>\n ) : null}\n <button\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item ink-signature-create\"\n data-ink-select-item=\"\"\n data-ink-signature-create=\"\"\n onClick={onCreate}\n >\n <InkIcon icon={Plus} size={16} />\n {SIGNATURE_LABELS.create}\n </button>\n {removeError ? (\n <p\n className=\"ink-field-error ink-signature-remove-error\"\n role=\"alert\"\n data-ink-signature-remove-error=\"\"\n >\n {removeError}\n </p>\n ) : null}\n </>\n )\n}\n","/*\n * The signature menu for a signature field, opened from the field's \"Sign\" button and anchored\n * to its box. It lists the saved signatures and \"Create signature\", as `InkSignatureMenu`\n * does. Picking one signs the field with it (`signField`); a signature made in\n * `InkSignatureDialog` signs the field once saved, without picking the signature tool. Focus\n * returns to the field. InkViewport mounts it, one per document; hosts compose nothing.\n */\nimport { InkError, signField, type SignatureTemplate } from '@inkbar/core'\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n SIGNATURE_LABELS,\n signatureMenuModel,\n watchDetached,\n type SignFieldRequest,\n} from '@inkbar/core/dom'\nimport { Popover } from 'radix-ui'\nimport { useEffect, useMemo, useRef, useState } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useLatest } from '../use-latest'\nimport { useReadable } from '../use-readable'\n\nimport { InkSignatureDialog } from './InkSignatureDialog'\nimport { SignatureMenuPanel } from './SignatureMenuPanel'\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\n/** The field's own button, which focus returns to. */\nconst control = (req: SignFieldRequest | null): HTMLElement | null =>\n req?.anchor.querySelector<HTMLElement>('button.ink-form-control') ?? null\n\nexport function InkSignFieldPopover({\n request,\n onClose,\n}: {\n /** The field to sign; `null` while the menu is closed. */\n request: SignFieldRequest | null\n onClose: () => void\n}) {\n const ctx = useInkContext('InkSignFieldPopover')\n const { signatures, reportError } = ctx\n const templates = useReadable(signatures.templates, NO_TEMPLATES)\n // No signature is \"chosen\" here: each signing picks its own.\n const model = useMemo(() => signatureMenuModel(templates, {}), [templates])\n /** The field the dialog signs once its signature is saved. */\n const [creatingFor, setCreatingFor] = useState<SignFieldRequest | null>(null)\n const menu = useRef<HTMLDivElement>(null)\n /**\n * The request the menu was last open for, kept to return focus once it closes. A request\n * that replaces the open one takes over, so focus returns to the field asked for last.\n */\n const last = useRef<SignFieldRequest | null>(null)\n /** Set while the menu closes for the dialog, which takes focus instead of the field. */\n const toDialog = useRef(false)\n const anchor = useMemo(() => ({ current: request?.anchor ?? null }), [request])\n const doc = ctx.document\n\n // An old removal error is not news when the menu opens again.\n useEffect(() => {\n if (request) signatures.clearRemoveError()\n }, [request, signatures])\n\n // The field's box went (its page unmounted, its layer rebuilt): the menu has nothing to\n // stand by.\n const close = useLatest(onClose)\n useEffect(() => {\n if (!request) return\n last.current = request\n return watchDetached(request.anchor, () => close.current())\n }, [request, close])\n\n /** Focus goes back to the field's button, or to the scroll element once the field's box has gone. */\n const returnFocus = (req: SignFieldRequest | null): void => {\n const c = control(req)\n ;(c?.isConnected ? c : ctx.viewportEl.get())?.focus({ preventScroll: true })\n }\n\n /** Signs the request's field with `t`; a refusal (signed, read-only by now) goes to `onError`. */\n const sign = (req: SignFieldRequest, t: SignatureTemplate): void => {\n if (!doc) return\n try {\n signField(doc, req.field, req.widget, t)\n } catch (e) {\n if (!(e instanceof InkError)) throw e\n reportError(e)\n }\n }\n\n return (\n <>\n <Popover.Root open={request !== null} onOpenChange={(next) => !next && onClose()}>\n <Popover.Anchor virtualRef={anchor} />\n <Popover.Portal>\n {request ? (\n <Popover.Content\n ref={menu}\n role=\"menu\"\n aria-label={SIGNATURE_LABELS.menu}\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"signature\"\n data-ink-sign-field-menu={request.field}\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n focusInitialMenuItem(e.currentTarget as HTMLElement)\n }}\n onCloseAutoFocus={(e) => {\n e.preventDefault()\n if (!toDialog.current) returnFocus(last.current)\n toDialog.current = false\n }}\n onInteractOutside={(e) => {\n // A press on this field's own button toggles the menu through the engine; it\n // must not also close it here first, or the click would open it again.\n const target = e.detail.originalEvent.target\n if (target instanceof Node && request.anchor.contains(target))\n e.preventDefault()\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n <SignatureMenuPanel\n items={model.items}\n menu={menu}\n onChoose={(t) => {\n onClose()\n sign(request, t)\n }}\n onCreate={() => {\n toDialog.current = true\n setCreatingFor(request)\n onClose()\n }}\n />\n </Popover.Content>\n ) : null}\n </Popover.Portal>\n </Popover.Root>\n <InkSignatureDialog\n open={creatingFor !== null}\n onOpenChange={(next) => {\n if (!next) setCreatingFor(null)\n }}\n select={false}\n onSave={(t) => {\n if (creatingFor) sign(creatingFor, t)\n }}\n onCloseAutoFocus={(e) => {\n e.preventDefault()\n returnFocus(last.current)\n }}\n />\n </>\n )\n}\n","/*\n * The scroll element is handed to core's `mountViewer`, which builds the viewport, the page\n * layers, the tool controller and the keyboard shortcuts in it; React never renders children\n * into it. The engine reports each page host it mounts, and InkPage components rendered here\n * portal the page-error and custom-annotation slots into them.\n *\n * Two-way zoom and page: the viewport's own changes are reported through the context, and\n * the host's props are applied only when they differ from the viewport's state, so the echo\n * of a reported value does nothing.\n *\n * Form fields render in the engine's form layer. A signature field's \"Sign\" opens\n * `InkSignFieldPopover`, and a form script's alert shows in `InkFormAlert`; both are mounted\n * here, so hosts compose nothing for them.\n */\nimport { mountViewer } from '@inkbar/core/dom'\nimport {\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useLatest } from '../use-latest'\n\nimport { InkFormAlert } from './InkFormAlert'\nimport { InkPage } from './InkPage'\nimport { InkSignFieldPopover } from './InkSignFieldPopover'\n\nimport type { InkDocument, InkError } from '@inkbar/core'\nimport type {\n AnnotationSlotProps,\n LayoutMode,\n PageMount,\n SignFieldRequest,\n ToolId,\n ViewerEngine,\n ViewRotation,\n ZoomValue,\n} from '@inkbar/core/dom'\n\nexport interface InkViewportProps extends ComponentPropsWithoutRef<'div'> {\n mode?: LayoutMode\n rotation?: ViewRotation\n /** Gap between pages, CSS px. */\n gap?: number\n /** Pages kept mounted either side of the visible ones. */\n buffer?: number\n loading?: ReactNode\n empty?: ReactNode\n error?: ReactNode | ((props: { error: InkError }) => ReactNode)\n renderAnnotation?: ((props: AnnotationSlotProps) => ReactNode) | undefined\n /** Shown inside a page that failed to render. The rest of the document stays usable. */\n renderPageError?: ((props: { error: InkError; page: number }) => ReactNode) | undefined\n}\n\ninterface MountedPage {\n /** The engine build the host belongs to; part of the InkPage key. */\n build: number\n page: number\n host: HTMLElement\n mount: PageMount\n error: InkError | null\n /** Whether the build that mounted the page renders the annotation slot. */\n custom: boolean\n}\n\n/** A key per document, so the field menu and its dialog start afresh for each one. */\nconst documentKeys = new WeakMap<InkDocument, number>()\nlet documentKeyCount = 0\nfunction documentKey(doc: InkDocument | null): number {\n if (!doc) return 0\n let key = documentKeys.get(doc)\n if (key === undefined) {\n key = ++documentKeyCount\n documentKeys.set(doc, key)\n }\n return key\n}\n\nexport function InkViewport({\n mode = 'continuous',\n rotation = 0,\n gap = 16,\n buffer = 2,\n loading,\n empty,\n error,\n renderAnnotation,\n renderPageError,\n className,\n ...rest\n}: InkViewportProps) {\n const ctx = useInkContext('InkViewport')\n const scroll = useRef<HTMLDivElement>(null)\n const custom = !!renderAnnotation\n const latest = useLatest({ ctx, mode, rotation, gap, buffer, custom })\n\n const engine = useRef<ViewerEngine | null>(null)\n /** Page hosts, mounts and errors the engine reported; InkPage renders portals for them. */\n const [pages, setPages] = useState<MountedPage[]>([])\n /**\n * Numbered before each build starts, so the pages a build mounts carry its own number. A\n * rebuild gives each page a new host and mount, so pages from an earlier build must remount,\n * not be reused.\n */\n const buildCount = useRef(0)\n /** The construction options the engine was last built with, so a rebuild runs only on a change. */\n const builtWith = useRef<{ gap: number; buffer: number; custom: boolean } | null>(null)\n /** The zoom and page last reported to the host. */\n const lastReportedZoom = useRef<ZoomValue | undefined>(undefined)\n const lastReportedPage = useRef<number | undefined>(undefined)\n /** The signature field whose menu is open. */\n const [signRequest, setSignRequest] = useState<SignFieldRequest | null>(null)\n /** The form script's message on show, and how many have been shown. */\n const [alert, setAlert] = useState<{ message: string; shown: number } | null>(null)\n\n // Build for a new document or status; tear down on the next change and on unmount.\n useEffect(() => {\n const { ctx: c, mode: m, rotation: r, gap: g, buffer: b, custom: cu } = latest.current\n const doc = c.document\n const el = scroll.current\n lastReportedZoom.current = undefined\n lastReportedPage.current = undefined\n if (!doc || !el || c.status.state !== 'ready') return\n let first = true\n let stops: (() => void)[] = []\n buildCount.current += 1\n builtWith.current = { gap: g, buffer: b, custom: cu }\n const e = mountViewer({\n container: el,\n document: doc,\n zoom: c.zoomModel ?? 'fit-width',\n ...(c.pageModel === undefined ? {} : { page: c.pageModel }),\n mode: m,\n rotation: r,\n gap: g,\n buffer: b,\n tool: c.tool,\n ...(c.hostTools ? { tools: c.hostTools } : {}),\n // The engine adds the plugins' tools and layers, and decorates through the host, which\n // reads `decorateAnnotation` first.\n ...(c.pluginHost ? { plugins: c.pluginHost } : {}),\n // The highlights draw from the shared search.\n ...(c.search ? { search: c.search } : {}),\n // Reads InkRoot's current prop; the effect below re-applies it when it changes.\n decorateAnnotation: (a) => latest.current.ctx.decorateAnnotation(a),\n ...(c.toolStyle ? { toolStyle: c.toolStyle } : {}),\n toolHistory: { batch: (fn) => latest.current.ctx.history.batch(fn) },\n toolOptions: c.toolOptions,\n fonts: [...c.fonts],\n // Read through, so a new `signatures` store reaches the tool as well as the menus.\n signatureLibrary: () => latest.current.ctx.signatures,\n customAnnotations: cu,\n ...(c.formHighlight === undefined ? {} : { formHighlight: c.formHighlight }),\n // The field's own button again, while its menu is open, closes the menu.\n onSignField: (req) =>\n setSignRequest((open) => (open?.widget === req.widget ? null : req)),\n onFormAction: (a) => latest.current.ctx.reportFormAction(a),\n onFormAlert: (message) =>\n setAlert((prev) => ({ message, shown: (prev?.shown ?? 0) + 1 })),\n onActivate: (id) => latest.current.ctx.setActivated(id),\n onBuild: (vp, tc) => {\n latest.current.ctx.setViewport(vp, tc)\n if (first) {\n // A new document starts from where the viewport opens (its zoom, on the first page);\n // only later changes are reported, the restored page among them.\n first = false\n lastReportedZoom.current = vp.zoom.get()\n lastReportedPage.current = 0\n }\n for (const stop of stops) stop()\n const reportZoom = (z: ZoomValue): void => {\n if (z === lastReportedZoom.current) return\n lastReportedZoom.current = z\n latest.current.ctx.reportZoom(z)\n }\n const reportPage = (p: number): void => {\n if (p === lastReportedPage.current) return\n lastReportedPage.current = p\n latest.current.ctx.reportPage(p)\n }\n // A tool that switches itself (a one-shot tool once used) is reported as a pick.\n const followTool = (id: ToolId): void => {\n if (id !== latest.current.ctx.tool) latest.current.ctx.setTool(id)\n }\n stops = [\n vp.zoom.subscribe(reportZoom),\n vp.currentPage.subscribe(reportPage),\n tc.active.subscribe(followTool),\n ]\n // Whatever the build restored is reported once; nothing is when it matched.\n reportZoom(vp.zoom.get())\n reportPage(vp.currentPage.get())\n },\n onPageMount: (page, mount, host) => {\n // `buildCount` and `builtWith` belong to the build in progress: both are set before it starts.\n const build = buildCount.current\n const custom = builtWith.current?.custom ?? false\n setPages((prev) => [...prev, { build, page, host, mount, error: null, custom }])\n },\n onPageUnmount: (page) => setPages((prev) => prev.filter((p) => p.page !== page)),\n onPageError: (page, err) =>\n setPages((prev) => prev.map((p) => (p.page === page ? { ...p, error: err } : p))),\n })\n engine.current = e\n return () => {\n for (const stop of stops) stop()\n e.destroy()\n engine.current = null\n builtWith.current = null\n c.setViewport(null, null)\n setPages((prev) => (prev.length === 0 ? prev : []))\n // Their fields and the document they came from are gone.\n setSignRequest(null)\n setAlert(null)\n }\n }, [ctx.document, ctx.status.state, ctx.pluginHost, ctx.search, latest])\n\n // The plugins' `root`. A layout effect, so it is set before the build above runs.\n const { viewportEl } = ctx\n useLayoutEffect(() => {\n const el = scroll.current\n viewportEl.set(el)\n return () => {\n if (viewportEl.get() === el) viewportEl.set(null)\n }\n }, [viewportEl])\n\n // A new decorateAnnotation re-applies to the mounted annotation elements at once.\n const { onDecorateAnnotationChange } = ctx\n useEffect(\n () => onDecorateAnnotationChange(() => engine.current?.redecorate()),\n [onDecorateAnnotationChange]\n )\n\n // Construction-only options rebuild the engine for the same document, keeping zoom and page.\n useEffect(() => {\n const built = builtWith.current\n if (!engine.current || !built) return\n if (built.gap === gap && built.buffer === buffer && built.custom === custom) return\n buildCount.current += 1\n builtWith.current = { gap, buffer, custom }\n engine.current.rebuild({ gap, buffer, customAnnotations: custom })\n }, [gap, buffer, custom])\n\n useEffect(() => {\n const vp = engine.current?.viewport\n const z = ctx.zoomModel\n if (vp && z !== undefined && z !== vp.zoom.get()) vp.setZoom(z)\n }, [ctx.zoomModel])\n useEffect(() => {\n const vp = engine.current?.viewport\n const p = ctx.pageModel\n if (!vp || p === undefined || p === lastReportedPage.current) return\n if (p !== vp.currentPage.get()) vp.scrollToPage(p)\n }, [ctx.pageModel])\n useEffect(() => {\n const tc = engine.current?.tools\n if (tc && tc.active.get() !== ctx.tool) tc.set(ctx.tool)\n }, [ctx.tool])\n // The tint follows `formHighlight` in place, without a new document.\n useEffect(() => {\n engine.current?.setFormHighlight(ctx.formHighlight ?? true)\n }, [ctx.formHighlight])\n // The build applied both; these only act on a later change, not on mount.\n useEffect(() => {\n const vp = engine.current?.viewport\n if (vp && vp.mode.get() !== mode) vp.setMode(mode)\n }, [mode])\n useEffect(() => {\n const vp = engine.current?.viewport\n if (vp && vp.rotation.get() !== rotation) vp.setRotation(rotation)\n }, [rotation])\n\n const state = ctx.status.state\n const err = ctx.status.state === 'error' ? ctx.status.error : null\n\n return (\n <div\n {...rest}\n className={cx('ink-viewport-root', className)}\n data-ink-viewport-root=\"\"\n data-state={state}\n >\n {state === 'loading' ? (\n <div className=\"ink-status\" role=\"status\" aria-live=\"polite\">\n {loading === undefined ? 'Loading document…' : loading}\n </div>\n ) : err ? (\n <div className=\"ink-status ink-error\" role=\"alert\">\n {typeof error === 'function' ? (\n error({ error: err })\n ) : error !== undefined ? (\n error\n ) : (\n <>\n <p className=\"ink-error-title\">This document could not be opened.</p>\n {/* The message comes from the PDF engine and is not written for readers: it stays\n off the page, on the code's tooltip. */}\n <p>\n <code className=\"ink-error-code\" title={err.message}>\n {err.code}\n </code>\n </p>\n </>\n )}\n </div>\n ) : state === 'idle' ? (\n <div className=\"ink-status ink-empty\">{empty}</div>\n ) : null}\n <div\n ref={scroll}\n className=\"ink-scroll\"\n data-ink-scroll=\"\"\n tabIndex={0}\n role=\"document\"\n aria-label=\"Document\"\n />\n {pages.map((p) => (\n <InkPage\n key={`${p.build}:${p.page}`}\n page={p.page}\n host={p.host}\n mount={p.mount}\n error={p.error}\n customAnnotations={p.custom}\n renderAnnotation={renderAnnotation}\n renderPageError={renderPageError}\n />\n ))}\n <InkSignFieldPopover\n key={documentKey(ctx.document)}\n request={signRequest}\n onClose={() => setSignRequest(null)}\n />\n <InkFormAlert\n message={alert?.message ?? null}\n shown={alert?.shown ?? 0}\n fallback={() => scroll.current}\n onClose={() => setAlert(null)}\n />\n </div>\n )\n}\n","import { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport interface InkToolbarProps extends Omit<ComponentPropsWithoutRef<'div'>, 'dir'> {\n /** Radix narrows text direction to these two values. */\n dir?: 'ltr' | 'rtl'\n label?: string\n asChild?: boolean\n}\n\nexport function InkToolbar({\n label = 'Document tools',\n asChild = false,\n className,\n children,\n ...rest\n}: InkToolbarProps) {\n return (\n <Toolbar.Root\n asChild={asChild}\n orientation=\"horizontal\"\n aria-label={label}\n data-ink-toolbar=\"\"\n className={cx('ink-toolbar', className)}\n {...rest}\n >\n {children}\n </Toolbar.Root>\n )\n}\n","import { TOOL_LABELS, type ToolId } from '@inkbar/core/dom'\nimport {\n Highlighter,\n MessageSquare,\n PenLine,\n PenTool,\n Signature,\n Square,\n SquareDashedMousePointer,\n TextCursor,\n Type,\n} from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useTool } from '../hooks/useTool'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { IconNode } from '@inkbar/icons'\nimport type { ComponentPropsWithoutRef, ReactNode } from 'react'\n\nconst ICONS: Readonly<Partial<Record<ToolId, IconNode>>> = {\n 'select-text': TextCursor,\n select: SquareDashedMousePointer,\n highlight: Highlighter,\n 'redact-area': Square,\n sketch: PenTool,\n draw: PenLine,\n note: MessageSquare,\n freetext: Type,\n signature: Signature,\n}\n\nexport interface InkToolButtonProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n tool: ToolId\n label?: string | undefined\n asChild?: boolean\n children?: ReactNode | ((props: { active: boolean; label: string }) => ReactNode)\n}\n\nexport function InkToolButton({\n tool,\n label,\n asChild = false,\n className,\n children,\n onClick,\n ...rest\n}: InkToolButtonProps) {\n const { hostTools, pluginHost } = useInkContext('InkToolButton')\n const { tool: current, setTool } = useTool()\n const active = current === tool\n /** A host or plugin tool by this id, for the name and icon core has none for. */\n const own = [...(hostTools ?? []), ...(pluginHost?.tools ?? [])].find(\n (t) => t.id === tool\n )\n // `label` and `children` win; then core's name and icon; then the tool's own.\n const name = label ?? TOOL_LABELS[tool] ?? own?.label ?? tool\n const icon = ICONS[tool] ?? own?.icon\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-tool-button', className)}\n data-ink-tool-button=\"\"\n data-tool={tool}\n data-state={active ? 'on' : 'off'}\n aria-pressed={active}\n aria-label={name}\n title={name}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) setTool(tool)\n }}\n {...rest}\n >\n {typeof children === 'function'\n ? children({ active, label: name })\n : (children ?? (icon ? <InkIcon icon={icon} /> : null))}\n </Toolbar.Button>\n )\n}\n","/*\n * A plugin command as a toolbar button with its status beside it: the markup of core's\n * `createCommandButton`, so the theme styles both alike. The button is named by the command's\n * label and disabled while the command is, except while it runs: then it keeps focus, with\n * `aria-busy` and `aria-disabled`, and a press does nothing. The status is a live region. A command without an icon shows its label as the button's text. Until the plugins\n * are set up (once InkRoot has mounted; never on the server) the button is disabled and\n * `aria-hidden`. An id no plugin registered stays that way and logs `InkError('UnknownCommand')`\n * to the console once.\n */\nimport { Toolbar } from 'radix-ui'\n\nimport { useCommand } from '../hooks/useCommand'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { ComponentPropsWithoutRef, ReactNode } from 'react'\n\nexport interface InkCommandProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'id' | 'children'\n> {\n /** The command's namespaced id, such as `sandbox.suggest`. */\n id: string\n asChild?: boolean\n children?: ReactNode | ((props: { label: string; busy: boolean }) => ReactNode)\n}\n\nexport function InkCommand({\n id,\n asChild = false,\n children,\n disabled,\n onClick,\n ...rest\n}: InkCommandProps) {\n const { run, enabled, busy, status, label, icon } = useCommand(id)\n return (\n <div className=\"ink-command\">\n <Toolbar.Button\n asChild={asChild}\n type=\"button\"\n data-command={id}\n // No label until the plugins are set up: the disabled button stays out of the\n // accessibility tree rather than go unnamed.\n aria-label={label || undefined}\n title={label || undefined}\n aria-hidden={label ? undefined : true}\n aria-busy={busy}\n // Disabled while it runs, but not `disabled`, so the button keeps focus.\n aria-disabled={busy || undefined}\n {...rest}\n disabled={disabled === true || (!enabled && !busy)}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) void run()\n }}\n >\n {typeof children === 'function'\n ? children({ label, busy })\n : (children ?? (icon ? <InkIcon icon={icon} /> : label))}\n </Toolbar.Button>\n <span className=\"ink-command-status\" role=\"status\">\n {status}\n </span>\n </div>\n )\n}\n","import { cx } from '../class-names'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport type InkToolbarSeparatorProps = ComponentPropsWithoutRef<'div'>\n\n/**\n * A divider between groups of controls in a horizontal toolbar. Not focusable. A plain div\n * rather than Radix's separator, which reads as horizontal inside a horizontal toolbar.\n */\nexport function InkToolbarSeparator({ className, ...rest }: InkToolbarSeparatorProps) {\n return (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n className={cx('ink-toolbar-separator', className)}\n data-ink-toolbar-separator=\"\"\n {...rest}\n />\n )\n}\n","import { Undo2 } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useHistory } from '../hooks/useHistory'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkHistoryButtonProps } from './history-button'\n\nexport function InkUndo({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkHistoryButtonProps) {\n const { canUndo, undo } = useHistory()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-undo', className)}\n data-ink-undo=\"\"\n aria-label=\"Undo\"\n title=\"Undo\"\n {...rest}\n disabled={disabled === true || !canUndo}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) undo()\n }}\n >\n {children ?? <InkIcon icon={Undo2} />}\n </Toolbar.Button>\n )\n}\n","import { Redo2 } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useHistory } from '../hooks/useHistory'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkHistoryButtonProps } from './history-button'\n\nexport function InkRedo({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkHistoryButtonProps) {\n const { canRedo, redo } = useHistory()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-redo', className)}\n data-ink-redo=\"\"\n aria-label=\"Redo\"\n title=\"Redo\"\n {...rest}\n disabled={disabled === true || !canRedo}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) redo()\n }}\n >\n {children ?? <InkIcon icon={Redo2} />}\n </Toolbar.Button>\n )\n}\n","import { Search } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\nimport { flushSync } from 'react-dom'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useDocument } from '../hooks/useDocument'\nimport { useSearch } from '../hooks/useSearch'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport type InkSearchButtonProps = ComponentPropsWithoutRef<typeof Toolbar.Button>\n\n/**\n * Opens the find bar; pressed while it is open. Pressing it again focuses the field. Place it\n * in a toolbar next to `InkFindBar`, which it needs for the field to focus. Disabled until a\n * document is open.\n */\nexport function InkSearchButton({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkSearchButtonProps) {\n const { rootEl } = useInkContext('InkSearchButton')\n const { state, open } = useSearch()\n const { isReady } = useDocument()\n return (\n <Toolbar.Button\n {...rest}\n asChild={asChild}\n className={cx('ink-search-button', className)}\n data-ink-search-button=\"\"\n aria-label=\"Find\"\n title=\"Find\"\n aria-pressed={state.open}\n data-state={state.open ? 'on' : 'off'}\n disabled={!isReady || !!disabled}\n onClick={(e) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n // The bar shows once this render commits; its field takes focus then.\n flushSync(() => open())\n const field = rootEl?.querySelector<HTMLInputElement>('[data-ink-find-bar] input')\n field?.focus()\n field?.select()\n }}\n >\n {children ?? <InkIcon icon={Search} />}\n </Toolbar.Button>\n )\n}\n","import { findAnnouncer, findCountText } from '@inkbar/core/dom'\nimport { CaseSensitive, ChevronDown, ChevronUp, X } from '@inkbar/icons'\nimport { useEffect, useLayoutEffect, useRef, type ComponentPropsWithoutRef } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useSearch } from '../hooks/useSearch'\nimport { useReadable } from '../use-readable'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { SearchState } from '@inkbar/core/dom'\n\nexport type InkFindBarProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'>\n\n/**\n * The find bar: a field, the match count, previous and next, a match-case toggle and close,\n * a view of the root's search state. Place it anywhere inside `InkRoot`: it portals itself\n * into `[data-ink-viewport-root]`, the positioned ancestor the theme floats it from over the\n * top-right of the pages (as `InkThreadPopover` anchors to the root's overlay rather than\n * where it is written). It renders nothing until `InkViewport` has mounted, and is hidden\n * while the search is closed. While it is mounted it registers with the search controller,\n * which is what lets Ctrl/Cmd+F open it.\n *\n * Enter in the field steps to the next match, Shift+Enter to the previous, Escape closes.\n * Closing returns focus to where it was before the bar opened, else to the document.\n */\nexport function InkFindBar({ className, ...rest }: InkFindBarProps) {\n const ctx = useInkContext('InkFindBar')\n const { state, setQuery, setMatchCase, next, previous, close } = useSearch()\n const scroll = useReadable(ctx.viewportEl, null)\n /** The viewport root: the scroll element's parent, once InkViewport has mounted. */\n const target = scroll?.parentElement ?? null\n const bar = useRef<HTMLDivElement>(null)\n const field = useRef<HTMLInputElement>(null)\n const live = useRef<HTMLDivElement>(null)\n /** Where focus was when the bar opened, and whether it was open on the last pass. */\n const before = useRef<HTMLElement | null>(null)\n const wasOpen = useRef(false)\n\n // After the commit, so the bar is shown (and can take focus) when it opens.\n useLayoutEffect(() => {\n const el = bar.current\n const input = field.current\n if (!el || !input) return\n if (state.open !== wasOpen.current) {\n wasOpen.current = state.open\n const doc = el.ownerDocument\n if (state.open) {\n const active = doc.activeElement\n before.current =\n active instanceof HTMLElement && active !== doc.body && !el.contains(active)\n ? active\n : null\n input.focus()\n input.select()\n } else {\n // Focus inside the bar is about to be lost with it; focus elsewhere is left alone.\n const hadFocus = el.contains(doc.activeElement) || doc.activeElement === doc.body\n if (hadFocus) {\n const to =\n before.current?.isConnected && !el.contains(before.current)\n ? before.current\n : scroll\n to?.focus({ preventScroll: true })\n }\n before.current = null\n }\n }\n if (input.value !== state.query) {\n input.value = state.query\n // A query set from code arrives after the bar opened: keep the new text selected.\n if (el.ownerDocument.activeElement === input) input.select()\n }\n }, [state.open, state.query, scroll])\n\n // Registered while mounted.\n const { search } = ctx\n useEffect(() => {\n if (!search || !target) return\n return search.attachBar()\n }, [search, target])\n\n // The live region follows the controller's state change by change, as the vanilla bar does,\n // and is written directly. A render shows only the last of the changes batched into it, so\n // two steps in one task that end where they began would otherwise say nothing.\n useEffect(() => {\n const el = live.current\n if (!search || !el) return\n const announce = findAnnouncer()\n const say = (s: SearchState): void => {\n const text = announce(s)\n if (el.textContent !== text) el.textContent = text\n }\n say(search.state.get())\n return search.state.subscribe(say)\n }, [search, target])\n\n // A native listener, so Escape stops at the bar as it does in the vanilla and Vue bars;\n // React's delegated events would stop it only after the root's own listeners saw it.\n useEffect(() => {\n const el = bar.current\n if (!search || !el) return\n const onKeyDown = (e: globalThis.KeyboardEvent): void => {\n if (e.key !== 'Escape' || e.defaultPrevented || e.isComposing) return\n e.preventDefault()\n e.stopPropagation()\n search.close()\n }\n el.addEventListener('keydown', onKeyDown)\n return () => el.removeEventListener('keydown', onKeyDown)\n }, [search, target])\n\n if (!target) return null\n\n return createPortal(\n <div\n {...rest}\n ref={bar}\n className={cx('ink-find-bar', className)}\n data-ink-find-bar=\"\"\n role=\"search\"\n hidden={!state.open}\n >\n <input\n ref={field}\n type=\"text\"\n aria-label=\"Find in document\"\n autoComplete=\"off\"\n spellCheck={false}\n onInput={(e) => setQuery(e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' || e.nativeEvent.isComposing) return\n e.preventDefault()\n if (e.shiftKey) previous()\n else next()\n }}\n />\n <span className=\"ink-find-count\" data-ink-find-count=\"\">\n {findCountText(state)}\n </span>\n <button\n type=\"button\"\n data-ink-find-previous=\"\"\n aria-label=\"Previous match\"\n title=\"Previous match\"\n onClick={() => previous()}\n >\n <InkIcon icon={ChevronUp} />\n </button>\n <button\n type=\"button\"\n data-ink-find-next=\"\"\n aria-label=\"Next match\"\n title=\"Next match\"\n onClick={() => next()}\n >\n <InkIcon icon={ChevronDown} />\n </button>\n <button\n type=\"button\"\n data-ink-find-match-case=\"\"\n aria-label=\"Match case\"\n title=\"Match case\"\n aria-pressed={state.matchCase}\n onClick={() => setMatchCase(!state.matchCase)}\n >\n <InkIcon icon={CaseSensitive} />\n </button>\n <button\n type=\"button\"\n data-ink-find-close=\"\"\n aria-label=\"Close find\"\n title=\"Close find\"\n onClick={() => close()}\n >\n <InkIcon icon={X} />\n </button>\n <div\n ref={live}\n className=\"ink-visually-hidden\"\n data-ink-find-status=\"\"\n aria-live=\"polite\"\n />\n </div>,\n target\n )\n}\n","import { ZoomIn } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useZoom } from '../hooks/useZoom'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkZoomButtonProps } from './zoom-button'\n\nexport function InkZoomIn({\n asChild = false,\n className,\n children,\n onClick,\n ...rest\n}: InkZoomButtonProps) {\n const { zoomIn } = useZoom()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-zoom-in', className)}\n data-ink-zoom-in=\"\"\n aria-label=\"Zoom in\"\n title=\"Zoom in\"\n {...rest}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) zoomIn()\n }}\n >\n {children ?? <InkIcon icon={ZoomIn} />}\n </Toolbar.Button>\n )\n}\n","import { ZoomOut } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useZoom } from '../hooks/useZoom'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkZoomButtonProps } from './zoom-button'\n\nexport function InkZoomOut({\n asChild = false,\n className,\n children,\n onClick,\n ...rest\n}: InkZoomButtonProps) {\n const { zoomOut } = useZoom()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-zoom-out', className)}\n data-ink-zoom-out=\"\"\n aria-label=\"Zoom out\"\n title=\"Zoom out\"\n {...rest}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) zoomOut()\n }}\n >\n {children ?? <InkIcon icon={ZoomOut} />}\n </Toolbar.Button>\n )\n}\n","import { ZOOM_LEVELS, type ZoomValue } from '@inkbar/core/dom'\nimport { Check, ChevronDown } from '@inkbar/icons'\nimport { Select } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useZoom } from '../hooks/useZoom'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nconst CUSTOM = 'custom:'\nconst level = (z: number) => ZOOM_LEVELS.find((l) => Math.abs(l - z) < 0.001)\nconst percent = (z: number) => `${Math.round(z * 100)}%`\n\nconst FITS = [\n { value: 'fit-width', label: 'Fit width' },\n { value: 'fit-page', label: 'Fit page' },\n]\n\n/** Props of the select's trigger button; the options come from the zoom levels. */\nexport type InkZoomSelectProps = Omit<\n ComponentPropsWithoutRef<typeof Select.Trigger>,\n 'children' | 'asChild'\n>\n\nfunction Item({ value, label }: { value: string; label: string }) {\n return (\n <Select.Item value={value} className=\"ink-select-item\" data-ink-select-item=\"\">\n <Select.ItemText>{label}</Select.ItemText>\n <Select.ItemIndicator className=\"ink-select-indicator\">\n <InkIcon icon={Check} size={16} />\n </Select.ItemIndicator>\n </Select.Item>\n )\n}\n\nexport function InkZoomSelect({ className, ...rest }: InkZoomSelectProps) {\n const { zoom, scale, setZoom } = useZoom()\n /** A numeric zoom that is not one of the levels (zoom in and out multiply). */\n const custom = typeof zoom === 'number' && level(zoom) === undefined ? zoom : null\n const value =\n typeof zoom !== 'number'\n ? zoom\n : custom === null\n ? String(level(zoom))\n : `${CUSTOM}${zoom}`\n /** The levels, with a custom zoom in its place among them. */\n const levels = ZOOM_LEVELS.map((l) => ({ z: l, value: String(l), label: percent(l) }))\n if (custom !== null)\n levels.push({ z: custom, value: `${CUSTOM}${custom}`, label: percent(scale) })\n levels.sort((a, b) => a.z - b.z)\n\n function onValueChange(v: string): void {\n if (v === value) return\n const next: ZoomValue =\n v === 'fit-width' || v === 'fit-page' ? v : Number(v.replace(CUSTOM, ''))\n setZoom(next)\n }\n return (\n <Select.Root value={value} onValueChange={onValueChange}>\n <Select.Trigger\n className={cx('ink-zoom-select ink-select-trigger', className)}\n data-ink-zoom-select=\"\"\n aria-label=\"Zoom\"\n {...rest}\n >\n <Select.Value className=\"ink-select-value\" />\n <Select.Icon className=\"ink-select-icon\">\n <InkIcon icon={ChevronDown} size={16} />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n className=\"ink-select-content\"\n data-ink-select-content=\"\"\n position=\"popper\"\n side=\"top\"\n sideOffset={4}\n >\n <Select.Viewport>\n {FITS.map((o) => (\n <Item key={o.value} value={o.value} label={o.label} />\n ))}\n <Select.Separator className=\"ink-select-separator\" />\n {levels.map((o) => (\n <Item key={o.value} value={o.value} label={o.label} />\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n )\n}\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { usePage } from '../hooks/usePage'\nimport { useLatest } from '../use-latest'\n\nexport type InkPageInputProps = Omit<\n ComponentPropsWithoutRef<'input'>,\n 'value' | 'onChange' | 'type' | 'min' | 'max'\n>\n\nexport function InkPageInput({\n className,\n onKeyDown: onKeyDownProp,\n ...rest\n}: InkPageInputProps) {\n const { current, count, goTo } = usePage()\n const [draft, setDraft] = useState(String(current + 1))\n useEffect(() => {\n setDraft(String(current + 1))\n }, [current])\n const input = useRef<HTMLInputElement>(null)\n const latest = useLatest({ current, count, goTo })\n\n /** 1-based in the input, 0-based in the viewport. Out of range resets to the current page. */\n const commit = useCallback(\n (value: string) => {\n const { current: page, count: total, goTo: go } = latest.current\n const n = Number(value)\n if (Number.isInteger(n) && n >= 1 && n <= total) {\n if (n - 1 !== page) go(n - 1)\n } else setDraft(String(page + 1))\n },\n [latest]\n )\n // The native `change` event fires when an edit is committed: on blur after typing, and on\n // each step of the spinner or the arrow keys. React's `onChange` is the `input` event, which\n // fires for every keystroke, so the commit listens to the DOM event itself.\n useEffect(() => {\n const el = input.current\n if (!el) return\n const onNativeChange = (): void => commit(el.value)\n el.addEventListener('change', onNativeChange)\n return () => el.removeEventListener('change', onNativeChange)\n }, [commit])\n\n function onKeyDown(e: KeyboardEvent<HTMLInputElement>): void {\n onKeyDownProp?.(e)\n if (e.defaultPrevented || e.key !== 'Enter') return\n e.preventDefault()\n commit(draft)\n }\n return (\n <input\n ref={input}\n className={cx('ink-page-input', className)}\n data-ink-page-input=\"\"\n type=\"number\"\n inputMode=\"numeric\"\n aria-label=\"Page\"\n min={1}\n max={count}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={onKeyDown}\n {...rest}\n />\n )\n}\n","import { cx } from '../class-names'\nimport { usePage } from '../hooks/usePage'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport function InkPageCount({ className, ...rest }: ComponentPropsWithoutRef<'span'>) {\n const { count } = usePage()\n return (\n <span\n className={cx('ink-page-count', className)}\n data-ink-page-count=\"\"\n aria-live=\"polite\"\n {...rest}\n >\n {`of ${count}`}\n </span>\n )\n}\n","import { ChevronLeft } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { usePage } from '../hooks/usePage'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkPageButtonProps } from './page-button'\n\nexport function InkPrevPage({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkPageButtonProps) {\n const { current, previous } = usePage()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-prev-page', className)}\n data-ink-prev-page=\"\"\n aria-label=\"Previous page\"\n title=\"Previous page\"\n disabled={disabled === true || current <= 0}\n {...rest}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) previous()\n }}\n >\n {children ?? <InkIcon icon={ChevronLeft} />}\n </Toolbar.Button>\n )\n}\n","import { ChevronRight } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { usePage } from '../hooks/usePage'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkPageButtonProps } from './page-button'\n\nexport function InkNextPage({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkPageButtonProps) {\n const { current, count, next } = usePage()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-next-page', className)}\n data-ink-next-page=\"\"\n aria-label=\"Next page\"\n title=\"Next page\"\n disabled={disabled === true || current >= count - 1}\n {...rest}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) next()\n }}\n >\n {children ?? <InkIcon icon={ChevronRight} />}\n </Toolbar.Button>\n )\n}\n","/*\n * A colour menu for one colour property (border, fill or text) of the selection or the active\n * tool. The trigger shows the current colour as a swatch: split when the selection disagrees,\n * slashed for no fill. The panel is a palette grid, plus \"No fill\" for `fill` and \"Custom…\",\n * which opens a native colour input. The menu disables when nothing supports the property.\n */\nimport {\n COLOR_COLUMNS,\n colorMenuModel,\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n type ColorProperty,\n} from '@inkbar/core/dom'\nimport { Check } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport {\n Fragment,\n useCallback,\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type CSSProperties,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useToolStyle } from '../hooks/useToolStyle'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { StyleGroup } from '@inkbar/core'\n\nexport interface InkColorMenuProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n /** The colour this menu sets. */\n property: ColorProperty\n /** Accessible name; defaults to \"Border colour\", \"Fill colour\" or \"Text colour\". */\n label?: string\n /** Replaces the swatch. */\n children?: ReactNode\n /**\n * Renders the trigger outside the toolbar's roving focus, for a menu nested in another\n * panel (the text style menu's text colour).\n */\n standalone?: boolean\n /**\n * Scopes the menu to one style group: it shows and sets that group's colour whatever tool\n * is active, and recolours the selection only when it is all in the group.\n */\n group?: StyleGroup\n /** The colour new annotations get while the style leaves it unset; the swatch shows it. */\n fallback?: string | undefined\n}\n\nexport function InkColorMenu({\n property,\n label,\n className,\n children,\n standalone = false,\n group,\n fallback,\n disabled,\n ...rest\n}: InkColorMenuProps) {\n const Wrap = standalone ? Fragment : Toolbar.Button\n const { current, supported, set } = useToolStyle(group)\n const [open, setOpen] = useState(false)\n const model = colorMenuModel(property, current, supported, fallback)\n const name = label ?? model.label\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n const input = useRef<HTMLInputElement | null>(null)\n // The native `change` fires once the picker commits; React's `onChange` fires on every drag.\n const apply = useRef((_hex: string) => {})\n apply.current = (hex) => set(model.custom(hex))\n const bindInput = useCallback((el: HTMLInputElement | null) => {\n input.current = el\n el?.addEventListener('change', () => apply.current(el.value))\n }, [])\n // The input outlives the panel, so it follows the current colour rather than mount time.\n useEffect(() => {\n if (input.current) input.current.value = model.customValue.toLowerCase()\n }, [model.customValue])\n // The menu closes when the control disables (the selection cleared while it was open).\n useEffect(() => {\n if (!model.enabled) setOpen(false)\n }, [model.enabled])\n const trigger = model.trigger\n const swatchStyle =\n trigger.kind === 'color'\n ? ({ '--ink-swatch': trigger.color } as CSSProperties)\n : undefined\n return (\n <>\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Wrap {...(standalone ? {} : { asChild: true })}>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className={cx('ink-menu-trigger ink-color-menu', className)}\n data-ink-color-menu={property}\n data-state={open ? 'open' : 'closed'}\n data-mixed={model.mixed ? '' : undefined}\n aria-label={name}\n title={name}\n aria-haspopup=\"menu\"\n disabled={disabled === true || !model.enabled}\n {...rest}\n onKeyDown={(e) => {\n rest.onKeyDown?.(e)\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open || !model.enabled)\n return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n {children ?? (\n <span\n className=\"ink-swatch\"\n data-ink-swatch=\"\"\n data-property={property}\n data-kind={trigger.kind}\n data-color={trigger.kind === 'color' ? trigger.color : undefined}\n style={swatchStyle}\n aria-hidden=\"true\"\n />\n )}\n </button>\n </Popover.Trigger>\n </Wrap>\n <Popover.Portal>\n <Popover.Content\n role=\"menu\"\n aria-label={name}\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu={`color-${property}`}\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const menu = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n focusFirst.current = false\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n {model.noFill ? (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={model.noFill.checked}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item\"\n data-ink-select-item=\"\"\n data-state={model.noFill.checked ? 'checked' : 'unchecked'}\n onClick={() => set(model.noFill!.patch)}\n >\n No fill\n {model.noFill.checked ? (\n <span className=\"ink-select-indicator\">\n <InkIcon icon={Check} size={16} />\n </span>\n ) : null}\n </button>\n ) : null}\n <div\n role=\"group\"\n aria-label=\"Colours\"\n className=\"ink-color-grid\"\n data-ink-menu-columns={COLOR_COLUMNS}\n >\n {model.swatches.map((sw) => (\n <button\n key={sw.key}\n type=\"button\"\n role=\"menuitemradio\"\n aria-label={sw.label}\n aria-checked={sw.checked}\n tabIndex={-1}\n className=\"ink-swatch-item\"\n data-state={sw.checked ? 'checked' : 'unchecked'}\n style={{ '--ink-swatch': sw.color } as CSSProperties}\n onClick={() => set(sw.patch)}\n />\n ))}\n </div>\n <button\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item\"\n data-ink-select-item=\"\"\n onClick={() => input.current?.click()}\n >\n Custom…\n </button>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n <input\n ref={bindInput}\n type=\"color\"\n className=\"ink-color-input\"\n aria-label=\"Custom colour\"\n data-ink-color-input={property}\n tabIndex={-1}\n defaultValue={model.customValue.toLowerCase()}\n />\n </>\n )\n}\n","/*\n * A split button for the shape tool. The main part activates the tool with the current\n * kind and draws that kind's icon; the chevron opens a two-column grid of kinds. Choosing a\n * kind switches to the tool with it.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n SHAPE_COLUMNS,\n SHAPE_ICONS,\n SHAPE_KINDS,\n shapeMenuModel,\n type ShapeOptions,\n} from '@inkbar/core/dom'\nimport { ChevronDown } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport { useRef, useState, type ComponentPropsWithoutRef, type ReactNode } from 'react'\n\nimport { cx } from '../class-names'\nimport { useTool } from '../hooks/useTool'\nimport { useToolOptions } from '../hooks/useToolOptions'\n\nimport { InkIcon } from './InkIcon'\n\nexport interface InkShapeMenuProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** Replaces the main button's icon. */\n children?: ReactNode\n}\n\nexport function InkShapeMenu({ className, children, ...rest }: InkShapeMenuProps) {\n const { tool, setTool } = useTool()\n const [options, setOptions] = useToolOptions<ShapeOptions>('shape')\n const [open, setOpen] = useState(false)\n const model = shapeMenuModel(options, SHAPE_KINDS)\n const active = tool === 'shape'\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Anchor asChild>\n <div\n role=\"group\"\n aria-label=\"Shape\"\n className={cx('ink-split-button ink-shape-menu', className)}\n data-ink-shape-menu=\"\"\n {...rest}\n >\n <Toolbar.Button\n className=\"ink-tool-button ink-shape-button\"\n data-ink-tool-button=\"\"\n data-ink-shape-button=\"\"\n data-tool=\"shape\"\n data-kind={model.kind}\n data-state={active ? 'on' : 'off'}\n aria-pressed={active}\n aria-label={model.label}\n title={model.label}\n onClick={() => setTool('shape')}\n >\n {children ?? <InkIcon icon={SHAPE_ICONS[model.kind]} />}\n </Toolbar.Button>\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className=\"ink-menu-trigger ink-shape-menu-trigger\"\n data-ink-shape-menu-trigger=\"\"\n data-state={open ? 'open' : 'closed'}\n aria-label=\"Choose shape\"\n title=\"Choose shape\"\n aria-haspopup=\"menu\"\n onKeyDown={(e) => {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open) return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n <InkIcon icon={ChevronDown} />\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n role=\"menu\"\n aria-label=\"Shapes\"\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"shape\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const menu = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n focusFirst.current = false\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n <div\n role=\"group\"\n aria-label=\"Shapes\"\n className=\"ink-shape-grid\"\n data-ink-menu-columns={SHAPE_COLUMNS}\n >\n {model.items.map((item) => (\n <button\n key={item.kind}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={item.checked}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item ink-shape-item\"\n data-ink-select-item=\"\"\n data-key={item.kind}\n data-state={item.checked ? 'checked' : 'unchecked'}\n onClick={() => {\n setOptions({ kind: item.kind })\n setTool('shape')\n setOpen(false)\n }}\n >\n <InkIcon icon={SHAPE_ICONS[item.kind]} size={16} />\n {item.label}\n </button>\n ))}\n </div>\n </Popover.Content>\n </Popover.Portal>\n </div>\n </Popover.Anchor>\n </Popover.Root>\n )\n}\n","/*\n * A split button for the signature tool. The main part activates the tool with the chosen\n * signature, or opens the menu when none is chosen; the chevron opens the saved signatures as\n * previews, each with a remove button, and \"Create signature\", which opens\n * `InkSignatureDialog`. Choosing a signature switches to the tool with it.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n SIGNATURE_LABELS,\n signatureMenuModel,\n} from '@inkbar/core/dom'\nimport { ChevronDown, Signature } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport {\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useTool } from '../hooks/useTool'\nimport { useToolOptions } from '../hooks/useToolOptions'\nimport { useReadable } from '../use-readable'\n\nimport { InkIcon } from './InkIcon'\nimport { InkSignatureDialog } from './InkSignatureDialog'\nimport { SignatureMenuPanel } from './SignatureMenuPanel'\n\nimport type { SignatureOptions, SignatureTemplate } from '@inkbar/core'\n\nexport interface InkSignatureMenuProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** Replaces the main button's icon. */\n children?: ReactNode\n /** The fonts the dialog's Type tab offers. Default: InkRoot's `signatureFonts`. */\n fonts?: readonly string[] | undefined\n}\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\nexport function InkSignatureMenu({\n className,\n children,\n fonts,\n ...rest\n}: InkSignatureMenuProps) {\n const { tool, setTool } = useTool()\n const [options, setOptions] = useToolOptions<SignatureOptions>('signature')\n const { signatures } = useInkContext('InkSignatureMenu')\n const templates = useReadable(signatures.templates, NO_TEMPLATES)\n const model = signatureMenuModel(templates, options)\n const [open, setOpen] = useState(false)\n const [creating, setCreating] = useState(false)\n const active = tool === 'signature'\n const main = useRef<HTMLButtonElement>(null)\n const menu = useRef<HTMLDivElement>(null)\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n /** Set while the menu closes for the dialog, which takes focus instead of the trigger. */\n const toDialog = useRef(false)\n\n // An old removal error is not news when the menu opens again.\n useEffect(() => {\n if (open) signatures.clearRemoveError()\n }, [open, signatures])\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Anchor asChild>\n <div\n role=\"group\"\n aria-label={SIGNATURE_LABELS.sign}\n className={cx('ink-split-button ink-signature-menu', className)}\n data-ink-signature-menu=\"\"\n {...rest}\n >\n <Toolbar.Button\n ref={main}\n className=\"ink-tool-button ink-signature-button\"\n data-ink-tool-button=\"\"\n data-ink-signature-button=\"\"\n data-tool=\"signature\"\n data-state={active ? 'on' : 'off'}\n aria-pressed={active}\n aria-label={SIGNATURE_LABELS.sign}\n title={SIGNATURE_LABELS.sign}\n onClick={() => {\n if (model.selected) setTool('signature')\n else setOpen(true)\n }}\n >\n {children ?? <InkIcon icon={Signature} />}\n </Toolbar.Button>\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className=\"ink-menu-trigger ink-signature-menu-trigger\"\n data-ink-signature-menu-trigger=\"\"\n data-state={open ? 'open' : 'closed'}\n aria-label={SIGNATURE_LABELS.trigger}\n title={SIGNATURE_LABELS.trigger}\n aria-haspopup=\"menu\"\n onKeyDown={(e) => {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open) return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n <InkIcon icon={ChevronDown} />\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n ref={menu}\n role=\"menu\"\n aria-label={SIGNATURE_LABELS.menu}\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"signature\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const el = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(el)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(el)\n focusFirst.current = false\n }}\n onCloseAutoFocus={(e) => {\n if (toDialog.current) e.preventDefault()\n toDialog.current = false\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n <SignatureMenuPanel\n items={model.items}\n menu={menu}\n onChoose={(t) => {\n setOptions({ templateId: t.id })\n setTool('signature')\n setOpen(false)\n }}\n onCreate={() => {\n toDialog.current = true\n setOpen(false)\n setCreating(true)\n }}\n />\n </Popover.Content>\n </Popover.Portal>\n <InkSignatureDialog\n open={creating}\n onOpenChange={setCreating}\n fonts={fonts}\n onCloseAutoFocus={(e) => {\n e.preventDefault()\n main.current?.focus({ preventScroll: true })\n }}\n />\n </div>\n </Popover.Anchor>\n </Popover.Root>\n )\n}\n","/*\n * A split button for the highlight tool. The main part activates the tool with the current\n * markup kind and draws that kind's icon; the chevron opens a menu of the four kinds plus\n * the markup colour. Choosing a kind switches to the tool with it. The colour is a nested\n * `InkColorMenu` scoped to the `markup` style group, so it works whatever tool is active.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n highlightMenuModel,\n MARKUP_ICONS,\n MARKUP_KINDS,\n menuItems,\n type HighlightOptions,\n} from '@inkbar/core/dom'\nimport { ChevronDown } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport { useRef, useState, type ComponentPropsWithoutRef, type ReactNode } from 'react'\n\nimport { cx } from '../class-names'\nimport { useDocument } from '../hooks/useDocument'\nimport { useTool } from '../hooks/useTool'\nimport { useToolOptions } from '../hooks/useToolOptions'\n\nimport { InkColorMenu } from './InkColorMenu'\nimport { InkIcon } from './InkIcon'\n\nexport interface InkHighlightMenuProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** Replaces the main button's icon. */\n children?: ReactNode\n}\n\nexport function InkHighlightMenu({\n className,\n children,\n ...rest\n}: InkHighlightMenuProps) {\n const { tool, setTool } = useTool()\n const [options, setOptions] = useToolOptions<HighlightOptions>('highlight')\n const { document: doc } = useDocument()\n const [open, setOpen] = useState(false)\n const model = highlightMenuModel(options, MARKUP_KINDS)\n const active = tool === 'highlight'\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Anchor asChild>\n <div\n role=\"group\"\n aria-label=\"Highlight\"\n className={cx('ink-split-button ink-highlight-menu', className)}\n data-ink-highlight-menu=\"\"\n {...rest}\n >\n <Toolbar.Button\n className=\"ink-tool-button ink-highlight-button\"\n data-ink-tool-button=\"\"\n data-ink-highlight-button=\"\"\n data-tool=\"highlight\"\n data-kind={model.kind}\n data-state={active ? 'on' : 'off'}\n aria-pressed={active}\n aria-label={model.label}\n title={model.label}\n onClick={() => setTool('highlight')}\n >\n {children ?? <InkIcon icon={MARKUP_ICONS[model.kind]} />}\n </Toolbar.Button>\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className=\"ink-menu-trigger ink-highlight-menu-trigger\"\n data-ink-highlight-menu-trigger=\"\"\n data-state={open ? 'open' : 'closed'}\n aria-label=\"Choose highlight\"\n title=\"Choose highlight\"\n aria-haspopup=\"menu\"\n onKeyDown={(e) => {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open) return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n <InkIcon icon={ChevronDown} />\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n role=\"menu\"\n aria-label=\"Highlights\"\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"highlight\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const menu = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n focusFirst.current = false\n }}\n // Capture, so the arrow keys move on from the colour item before its own\n // ArrowDown opens the nested menu; keys from that menu's portalled panel, which\n // bubble here through React, are its own.\n onKeyDownCapture={(e) => {\n if (e.currentTarget.contains(e.target as Node))\n handleMenuKeys(e.nativeEvent, e.currentTarget)\n }}\n >\n <div role=\"group\" aria-label=\"Kinds\" className=\"ink-highlight-kinds\">\n {model.items.map((item) => (\n <button\n key={item.kind}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={item.checked}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item ink-highlight-item\"\n data-ink-select-item=\"\"\n data-key={item.kind}\n data-state={item.checked ? 'checked' : 'unchecked'}\n onClick={() => {\n setOptions({ kind: item.kind })\n setTool('highlight')\n setOpen(false)\n }}\n >\n <InkIcon icon={MARKUP_ICONS[item.kind]} size={16} />\n {item.label}\n </button>\n ))}\n </div>\n <div role=\"separator\" className=\"ink-select-separator\" />\n <div role=\"group\" aria-label=\"Colour\" className=\"ink-highlight-colour\">\n <span className=\"ink-highlight-colour-label\" aria-hidden=\"true\">\n Colour\n </span>\n <InkColorMenu\n property=\"border\"\n group=\"markup\"\n label=\"Highlight colour\"\n standalone\n fallback={doc?.annotations.defaults.color(model.kind)}\n role=\"menuitem\"\n tabIndex={-1}\n />\n </div>\n </Popover.Content>\n </Popover.Portal>\n </div>\n </Popover.Anchor>\n </Popover.Root>\n )\n}\n","/*\n * Font, size, text colour, bold, italic, underline and alignment for the selected text boxes or\n * the text tool. A popover panel rather than a menu list: it holds a select, a number input\n * with a stepper, toggle buttons and a radio group, each named and operable on its own. The\n * trigger carries `data-mixed` when the selection disagrees on any of them.\n */\nimport { handleRadioKeys, textStyleMenuModel } from '@inkbar/core/dom'\nimport {\n ALargeSmall,\n AlignCenter,\n AlignJustify,\n AlignLeft,\n AlignRight,\n Bold,\n Italic,\n Minus,\n Plus,\n Underline,\n} from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport { useEffect, useState, type ComponentPropsWithoutRef, type ReactNode } from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useToolStyle } from '../hooks/useToolStyle'\n\nimport { InkColorMenu } from './InkColorMenu'\nimport { InkIcon } from './InkIcon'\n\nexport interface InkTextStyleMenuProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n children?: ReactNode\n}\n\nconst TOGGLE_ICONS = { bold: Bold, italic: Italic, underline: Underline }\nconst ALIGN_ICONS = {\n left: AlignLeft,\n center: AlignCenter,\n right: AlignRight,\n justify: AlignJustify,\n}\n\nexport function InkTextStyleMenu({\n className,\n children,\n disabled,\n ...rest\n}: InkTextStyleMenuProps) {\n const { fonts } = useInkContext('InkTextStyleMenu')\n const { current, supported, set } = useToolStyle()\n const [open, setOpen] = useState(false)\n /** The size as typed, until it is committed with Enter or blur. */\n const [draft, setDraft] = useState<string | null>(null)\n const model = textStyleMenuModel(current, supported, fonts)\n // The menu closes when the control disables (the selection cleared while it was open).\n useEffect(() => {\n if (model.enabled) return\n setOpen(false)\n setDraft(null)\n }, [model.enabled])\n\n const commitSize = () => {\n if (draft === null) return\n if (draft.trim() !== '') {\n const patch = model.size.commit(Number(draft))\n if (patch) set(patch)\n }\n setDraft(null)\n }\n const nudge = (direction: 1 | -1) => {\n const patch = model.size.nudge(direction)\n if (patch) set(patch)\n setDraft(null)\n }\n const sizeShown = draft ?? (model.size.value === null ? '' : String(model.size.value))\n\n return (\n <Popover.Root\n open={open}\n onOpenChange={(next) => {\n // Closing commits a typed size, as the field's blur would.\n if (!next) commitSize()\n setOpen(next)\n }}\n >\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className={cx('ink-menu-trigger ink-text-style-menu', className)}\n data-ink-text-style-menu=\"\"\n data-state={open ? 'open' : 'closed'}\n data-mixed={model.mixed ? '' : undefined}\n aria-label={model.label}\n title={model.label}\n aria-haspopup=\"dialog\"\n disabled={disabled === true || !model.enabled}\n {...rest}\n onKeyDown={(e) => {\n rest.onKeyDown?.(e)\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open || !model.enabled)\n return\n e.preventDefault()\n setOpen(true)\n }}\n >\n {children ?? <InkIcon icon={ALargeSmall} />}\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n aria-label={model.label}\n className=\"ink-select-content ink-menu-content ink-text-style-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"text-style\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n >\n <select\n className=\"ink-text-style-font\"\n aria-label={model.font.label}\n value={model.font.value}\n onChange={(e) => set(model.font.patch(e.target.value))}\n >\n {model.font.value === '' ? (\n <option value=\"\" disabled hidden>\n Mixed\n </option>\n ) : null}\n {model.font.options.map((f) => (\n <option key={f} value={f}>\n {f}\n </option>\n ))}\n </select>\n <div className=\"ink-text-style-row\">\n <InkColorMenu property=\"textColor\" standalone />\n <div className=\"ink-text-style-size\" role=\"group\" aria-label=\"Size\">\n <button\n type=\"button\"\n className=\"ink-text-style-button\"\n aria-label=\"Decrease font size\"\n onClick={() => nudge(-1)}\n >\n <InkIcon icon={Minus} size={16} />\n </button>\n <input\n type=\"number\"\n className=\"ink-text-style-input\"\n aria-label={model.size.label}\n min={model.size.min}\n max={model.size.max}\n step={model.size.step}\n value={sizeShown}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={commitSize}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n commitSize()\n }\n }}\n />\n <button\n type=\"button\"\n className=\"ink-text-style-button\"\n aria-label=\"Increase font size\"\n onClick={() => nudge(1)}\n >\n <InkIcon icon={Plus} size={16} />\n </button>\n </div>\n </div>\n <div className=\"ink-text-style-row\" role=\"group\" aria-label=\"Emphasis\">\n {model.toggles.map((t) => (\n <button\n key={t.key}\n type=\"button\"\n className=\"ink-text-style-button\"\n aria-label={t.label}\n title={t.label}\n aria-pressed={t.pressed}\n data-state={t.pressed === true ? 'on' : 'off'}\n data-mixed={t.pressed === 'mixed' ? '' : undefined}\n onClick={() => set(t.patch)}\n >\n <InkIcon icon={TOGGLE_ICONS[t.key]} size={16} />\n </button>\n ))}\n </div>\n <div\n className=\"ink-text-style-row\"\n role=\"radiogroup\"\n aria-label={model.align.label}\n onKeyDown={(e) => handleRadioKeys(e.nativeEvent, e.currentTarget)}\n >\n {model.align.choices.map((c) => (\n <button\n key={c.key}\n type=\"button\"\n role=\"radio\"\n className=\"ink-text-style-button\"\n aria-label={c.label}\n title={c.label}\n aria-checked={c.checked}\n tabIndex={c.tabStop ? 0 : -1}\n data-state={c.checked ? 'on' : 'off'}\n onClick={() => set(c.patch)}\n >\n <InkIcon icon={ALIGN_ICONS[c.key]} size={16} />\n </button>\n ))}\n </div>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n )\n}\n","/*\n * Line weight, solid or dashed, and arrowheads, for the selection or the active tool. Each\n * section disables when nothing selected (or no active tool) supports its props. The trigger\n * carries `data-mixed` when the selection disagrees on any of them; a section with no single\n * value shows no checkmark.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n lineStyleMenuModel,\n menuItems,\n} from '@inkbar/core/dom'\nimport { Check, Minus } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport {\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useToolStyle } from '../hooks/useToolStyle'\n\nimport { InkIcon } from './InkIcon'\n\nexport interface InkLineStyleMenuProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n children?: ReactNode\n}\n\ninterface ItemProps {\n label: string\n checked: boolean\n disabled: boolean\n onSelect: () => void\n children?: ReactNode\n}\n\nfunction Item({ label, checked, disabled, onSelect, children }: ItemProps) {\n return (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={checked}\n disabled={disabled}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item\"\n data-ink-select-item=\"\"\n data-state={checked ? 'checked' : 'unchecked'}\n onClick={onSelect}\n >\n {children ?? label}\n {checked ? (\n <span className=\"ink-select-indicator\">\n <InkIcon icon={Check} size={16} />\n </span>\n ) : null}\n </button>\n )\n}\n\nfunction Group({\n label,\n disabled,\n children,\n}: {\n label: string\n disabled: boolean\n children: ReactNode\n}) {\n return (\n <div\n role=\"group\"\n aria-label={label}\n aria-disabled={disabled || undefined}\n data-disabled={disabled ? '' : undefined}\n className=\"ink-menu-group\"\n >\n <div className=\"ink-menu-label\" aria-hidden=\"true\">\n {label}\n </div>\n {children}\n </div>\n )\n}\n\nexport function InkLineStyleMenu({\n className,\n children,\n disabled,\n ...rest\n}: InkLineStyleMenuProps) {\n const { current, supported, set } = useToolStyle()\n const [open, setOpen] = useState(false)\n const model = lineStyleMenuModel(current, supported)\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n // The menu closes when the control disables (the selection cleared while it was open).\n useEffect(() => {\n if (!model.enabled) setOpen(false)\n }, [model.enabled])\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className={cx('ink-menu-trigger ink-line-style-menu', className)}\n data-ink-line-style-menu=\"\"\n data-state={open ? 'open' : 'closed'}\n data-mixed={model.mixed ? '' : undefined}\n aria-label=\"Line style\"\n title=\"Line style\"\n aria-haspopup=\"menu\"\n disabled={disabled === true || !model.enabled}\n {...rest}\n onKeyDown={(e) => {\n rest.onKeyDown?.(e)\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open || !model.enabled)\n return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n {children ?? <InkIcon icon={Minus} />}\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n role=\"menu\"\n aria-label=\"Line style\"\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"line-style\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const menu = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n focusFirst.current = false\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n {model.sections.map((section) => (\n <Group key={section.label} label={section.label} disabled={section.disabled}>\n {section.items.map((item) => (\n <Item\n key={item.key}\n label={item.label}\n checked={item.checked}\n disabled={section.disabled}\n onSelect={() => set(item.patch)}\n />\n ))}\n </Group>\n ))}\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n )\n}\n","import { observeAnnotationElement } from '@inkbar/core/dom'\nimport { useEffect, useState } from 'react'\n\n/**\n * The overlay element core draws for an annotation, for anchoring a popover to it. Core\n * creates and removes these elements outside React, so this follows the root's subtree while\n * an id is wanted.\n */\nexport function useAnnotationElement(\n root: HTMLElement | null,\n id: string | null\n): HTMLElement | null {\n const [element, setElement] = useState<HTMLElement | null>(null)\n useEffect(() => {\n if (!root || !id) {\n setElement(null)\n return\n }\n return observeAnnotationElement(root, id, setElement)\n }, [root, id])\n return element\n}\n","import {\n createFocusReturn,\n shouldKeepOpenOnAnnotation,\n type FocusReturn,\n} from '@inkbar/core/dom'\nimport { useMemo } from 'react'\n\nimport { useLatest } from '../use-latest'\n\nimport type { InkContext } from '../context'\n\nexport type { FocusReturn }\n\n/** Radix's `onInteractOutside` handler: a press that will activate an annotation keeps the popover open. */\nexport function keepOpenOnAnnotation(event: CustomEvent<{ originalEvent: Event }>): void {\n if (shouldKeepOpenOnAnnotation(event.detail.originalEvent.target))\n event.preventDefault()\n}\n\nexport function useFocusReturn(ctx: InkContext): FocusReturn {\n const latest = useLatest(ctx)\n return useMemo(\n () =>\n createFocusReturn({\n root: () => latest.current.rootEl,\n activated: () => latest.current.activated,\n }),\n [latest]\n )\n}\n","/*\n * The thread for the activated note or text markup, anchored to the root's overlay element.\n * Activating a reply opens the whole thread from its root. Closing (Close, Escape, a press\n * outside) clears `activated`.\n *\n * A new note, or a highlight, has no text. While its root is empty (and unlocked) the default\n * form writes the root's own `contents`, labelled \"Comment\", and the thread list stays hidden\n * until there is something in it; after that the form adds replies. Closing a note that is\n * still empty and has no replies removes it, so an abandoned note does not stay on the page.\n * Markup stays: the mark is the point.\n */\nimport { isAbandonedNote, threadOf, threadRoot } from '@inkbar/core'\nimport { threadDeleteLabel, threadPopoverLabel } from '@inkbar/core/dom'\nimport { Popover } from 'radix-ui'\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type FormEvent,\n type ReactNode,\n} from 'react'\n\nimport { useInkContext } from '../context'\nimport { useAnnotations } from '../hooks/useAnnotations'\nimport { useLatest } from '../use-latest'\n\nimport { useAnnotationElement } from './annotation-element'\nimport { keepOpenOnAnnotation, useFocusReturn } from './popover-focus'\n\nimport type { Annotation, ThreadRoot } from '@inkbar/core'\nimport type { ThreadPopoverSlotProps } from '@inkbar/core/dom'\n\nexport interface InkThreadPopoverProps {\n children?: ((props: ThreadPopoverSlotProps) => ReactNode) | undefined\n}\n\nexport function InkThreadPopover({ children }: InkThreadPopoverProps) {\n const ctx = useInkContext('InkThreadPopover')\n const { annotations, add, update, remove } = useAnnotations()\n\n const note = useMemo<ThreadRoot | null>(() => {\n const a = ctx.activated ? annotations.find((x) => x.id === ctx.activated) : undefined\n return a ? threadRoot(annotations, a) : null\n }, [annotations, ctx.activated])\n const anchor = useAnnotationElement(ctx.rootEl, note?.id ?? null)\n const anchorRef = useMemo(() => ({ current: anchor }), [anchor])\n const focusReturn = useFocusReturn(ctx)\n const open = note !== null && anchor !== null\n /** The root, then every reply below it, depth first, each level in creation order. */\n const thread = useMemo<Annotation[]>(\n () => (note ? threadOf(annotations, note) : []),\n [annotations, note]\n )\n /** True while the default form writes the root's own text rather than a reply. */\n const editingRoot = note !== null && !note.locked && !note.contents?.trim()\n\n /**\n * Roots this popover wrote text or a reply for. In controlled mode the write is a proposal\n * the host may not have applied yet, so the applied list still shows the note empty; these\n * are never dropped as abandoned.\n */\n const written = useRef(new Set<string>())\n /** Notes this popover has already asked to remove, so a slow host is asked once. */\n const dropped = useRef(new Set<string>())\n const latest = useLatest({ annotations, remove })\n\n function dropIfEmpty(id: string): boolean {\n const list = latest.current.annotations\n const a = list.find((x) => x.id === id)\n if (\n !a ||\n dropped.current.has(id) ||\n written.current.has(id) ||\n !isAbandonedNote(a, list)\n )\n return false\n dropped.current.add(id)\n latest.current.remove(id)\n return true\n }\n\n // Activation moved on from a note that never got any text: drop it.\n const noteId = note?.id\n const previousId = useRef<string | undefined>(undefined)\n useEffect(() => {\n const previous = previousId.current\n if (previous === noteId) return\n previousId.current = noteId\n if (previous !== undefined) dropIfEmpty(previous)\n // dropIfEmpty reads through `latest`; it is stable for the effect's purposes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [noteId])\n\n function reply(text: string): void {\n const root = note\n const contents = text.trim()\n if (!root || !contents) return\n written.current.add(root.id)\n add({ type: 'text', page: root.page, rect: root.rect, contents, inReplyTo: root.id })\n }\n /** A note that closing now would remove. */\n function isEmptyRoot(root: ThreadRoot): boolean {\n return !written.current.has(root.id) && isAbandonedNote(root, annotations)\n }\n function close(): void {\n const root = note\n if (root && annotations.some((a) => a.id === root.id) && isEmptyRoot(root)) {\n focusReturn.beforeRemove(anchor)\n dropIfEmpty(root.id)\n }\n ctx.setActivated(null)\n }\n function updateContents(contents: string): void {\n if (!note || note.locked) return\n if (contents.trim()) written.current.add(note.id)\n update(note.id, { contents })\n }\n /** Locked roots cannot be removed: removing one does nothing and keeps the popover. */\n function removeThread(): void {\n const root = note\n if (!root || root.locked) return\n focusReturn.beforeRemove(anchor)\n // Under a slow controlled host the root stays listed for a while; it is not asked for again.\n dropped.current.add(root.id)\n remove(root.id)\n ctx.setActivated(null)\n }\n\n return (\n <Popover.Root open={open} onOpenChange={(next) => !next && close()}>\n <Popover.Anchor virtualRef={anchorRef} />\n <Popover.Portal>\n {note && anchor ? (\n <Popover.Content\n className=\"ink-thread-popover\"\n data-ink-thread-popover=\"\"\n side=\"right\"\n sideOffset={8}\n collisionPadding={8}\n aria-label={threadPopoverLabel(note)}\n onInteractOutside={keepOpenOnAnnotation}\n onCloseAutoFocus={(e) => focusReturn.onCloseAutoFocus(e, anchor)}\n >\n {children ? (\n children({\n root: note,\n replies: thread.slice(1),\n reply,\n update: updateContents,\n remove: removeThread,\n close,\n })\n ) : (\n <>\n {!editingRoot || thread.length > 1 ? (\n <ol className=\"ink-thread\" data-ink-thread=\"\">\n {thread.map((item) => (\n <li\n key={item.id}\n className=\"ink-thread-item\"\n data-ink-thread-item=\"\"\n data-reply={item.inReplyTo ? '' : undefined}\n >\n <span className=\"ink-thread-author\">\n {item.author ?? 'Anonymous'}\n </span>\n <time className=\"ink-thread-time\" dateTime={item.createdAt}>\n {new Date(item.createdAt).toLocaleString()}\n </time>\n <p className=\"ink-thread-text\">{item.contents}</p>\n </li>\n ))}\n </ol>\n ) : null}\n <ThreadForm\n // Keyed by root: moving to another thread starts with an empty draft at once.\n key={note.id}\n editingRoot={editingRoot}\n locked={!!note.locked}\n deleteLabel={threadDeleteLabel(note)}\n onSubmit={(text) => (editingRoot ? updateContents(text) : reply(text))}\n onRemove={removeThread}\n onClose={close}\n />\n </>\n )}\n </Popover.Content>\n ) : null}\n </Popover.Portal>\n </Popover.Root>\n )\n}\n\n/** The default form: the root's own text while it is empty, replies after that. */\nfunction ThreadForm({\n editingRoot,\n locked,\n deleteLabel,\n onSubmit,\n onRemove,\n onClose,\n}: {\n editingRoot: boolean\n locked: boolean\n deleteLabel: string\n onSubmit: (text: string) => void\n onRemove: () => void\n onClose: () => void\n}) {\n const [draft, setDraft] = useState('')\n function submit(e: FormEvent): void {\n e.preventDefault()\n const text = draft.trim()\n if (!text) return\n onSubmit(text)\n setDraft('')\n }\n return (\n <form className=\"ink-thread-reply\" data-ink-thread-reply=\"\" onSubmit={submit}>\n <textarea\n aria-label={editingRoot ? 'Comment' : 'Reply'}\n rows={2}\n placeholder={editingRoot ? 'Comment' : 'Reply'}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n />\n <div className=\"ink-thread-actions\">\n <button type=\"submit\" disabled={!draft.trim()}>\n {editingRoot ? 'Comment' : 'Reply'}\n </button>\n {!locked ? (\n <button type=\"button\" onClick={onRemove}>\n {deleteLabel}\n </button>\n ) : null}\n <button type=\"button\" onClick={onClose}>\n Close\n </button>\n </div>\n </form>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["noop","EMPTY","noop","NONE","noop","IDLE","isDevelopment","NO_TEMPLATES","NO_TEMPLATES","Item"],"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/hooks/useForm.ts","../src/hooks/useRecords.ts","../src/hooks/useRecordSelection.ts","../src/use-latest.ts","../src/hooks/useRegisteredTool.ts","../src/components/InkRoot.tsx","../src/class-names.ts","../src/components/InkFormAlert.tsx","../src/components/InkAnnotation.tsx","../src/components/InkPage.tsx","../src/components/InkSignatureDialog.tsx","../src/components/InkIcon.tsx","../src/components/SignatureMenuPanel.tsx","../src/components/InkSignFieldPopover.tsx","../src/components/InkViewport.tsx","../src/components/InkToolbar.tsx","../src/components/InkToolButton.tsx","../src/components/InkCommand.tsx","../src/components/InkToolbarButton.tsx","../src/components/InkToolbarSeparator.tsx","../src/components/InkUndo.tsx","../src/components/InkDownloadButton.tsx","../src/components/InkPrintButton.tsx","../src/components/InkRedo.tsx","../src/components/InkSearchButton.tsx","../src/components/InkFindBar.tsx","../src/components/InkZoomIn.tsx","../src/components/InkZoomOut.tsx","../src/components/InkZoomSelect.tsx","../src/components/InkPageInput.tsx","../src/components/InkPageCount.tsx","../src/components/InkPrevPage.tsx","../src/components/InkNextPage.tsx","../src/components/InkColorMenu.tsx","../src/components/InkShapeMenu.tsx","../src/components/InkSignatureMenu.tsx","../src/components/InkHighlightMenu.tsx","../src/components/InkTextStyleMenu.tsx","../src/components/InkLineStyleMenu.tsx","../src/components/annotation-element.ts","../src/components/popover-focus.ts","../src/components/InkThreadPopover.tsx","../src/dom-attrs.ts","../src/components/sidebar-context.ts","../src/components/SidebarTrigger.tsx","../src/components/InkSidebar.tsx","../src/components/InkPanel.tsx","../src/to-readable.ts","../src/components/InkThumbnail.tsx","../src/components/InkThumbnails.tsx","../src/components/RecordCards.tsx","../src/components/InkRecordList.tsx","../src/components/InkSearchResults.tsx"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nimport type {\n Annotation,\n FormAction,\n InkDocument,\n InkError,\n InkStatus,\n PdfAssets,\n PluginHistory,\n SignatureLibrary,\n Writable,\n} from '@inkbar/core'\nimport type {\n DecorateAnnotation,\n PluginHost,\n SearchController,\n Tool,\n ToolController,\n ToolId,\n ToolOptions,\n ToolStyle,\n Viewport,\n ZoomValue,\n} from '@inkbar/core/dom'\n\nexport type { InkStatus }\n\n/**\n * Undo and redo for the current document, whichever mode its annotations are in. `track` and\n * `react` (from `PluginHistory`) reach the same history, so plugin stores undo with the edits.\n */\nexport interface InkHistory extends PluginHistory {\n canUndo: boolean\n canRedo: boolean\n undo: () => void\n redo: () => void\n clear: () => void\n /**\n * Runs `fn` and records what it changes as one undo step. The host still receives one change\n * per add. Controlled, the history groups the resulting list changes into one step, and\n * `canUndo` updates once the current task ends. Any other change the host applies in that\n * same window joins the step.\n */\n batch: (fn: () => void) => void\n}\n\nexport interface InkContext {\n assets: PdfAssets\n document: InkDocument | null\n /** `loading` from the moment a document starts opening, then the document's own status. */\n status: InkStatus\n annotations: readonly Annotation[]\n selection: readonly string[]\n /**\n * The plugins from InkRoot's `plugins` prop, set up once the root has mounted and kept for\n * its life; `null` before that, and on the server. InkViewport hands it to the engine;\n * InkCommand places its commands.\n */\n pluginHost: PluginHost | null\n /**\n * The search controller from the same set-up as `pluginHost`: shared by the find bar, the\n * search button, the engine's highlights and the plugins. `null` before the root has\n * mounted, and on the server.\n */\n search: SearchController | null\n /** InkViewport's scroll element while it is mounted: the plugins' `root`. */\n viewportEl: Writable<HTMLElement | null>\n /** Set by InkViewport once it has built its viewport and tool controller. */\n viewport: Viewport | null\n tools: ToolController | null\n /** Desired tool; InkViewport applies it to the controller. */\n tool: ToolId\n setTool: (id: ToolId) => void\n /** Host tools from InkRoot's `tools` prop; InkViewport registers them. */\n hostTools: Tool[] | undefined\n /**\n * The ids of the tools the current viewer was built with, set by InkViewport through\n * `setOpenedToolIds`; `null` while there is none. A tool added to `tools` later is\n * registered from the next build.\n */\n openedToolIds: readonly ToolId[] | null\n setOpenedToolIds: (ids: readonly ToolId[] | null) => void\n /**\n * Calls InkRoot's current `decorateAnnotation` prop. The function itself stays the same\n * across renders, so a new prop does not re-render the context's consumers.\n */\n decorateAnnotation: DecorateAnnotation\n /**\n * Calls `listener` after InkRoot's `decorateAnnotation` prop changes; InkViewport re-applies\n * the decorations then. Returns the unsubscribe.\n */\n onDecorateAnnotationChange: (listener: () => void) => () => void\n /** The font families text boxes offer: InkRoot's `fonts`, else `FONT_FAMILIES`. */\n fonts: readonly string[]\n /** The tools' options for InkRoot's life, so they persist across documents. */\n toolOptions: ToolOptions\n /** The saved signatures, from InkRoot's `signatures` store (memory by default). */\n signatures: SignatureLibrary\n /** The fonts a typed signature offers: InkRoot's `signatureFonts`, else `SIGNATURE_FONTS`. */\n signatureFonts: readonly string[]\n /** The open document's tool style; `null` while no document is open. */\n toolStyle: ToolStyle | null\n /** Desired zoom and page from the host's props; InkViewport applies and reports back. */\n zoomModel: ZoomValue | undefined\n pageModel: number | undefined\n reportZoom: (z: ZoomValue) => void\n reportPage: (p: number) => void\n /** Last activated annotation (Enter, click with the note tool, etc.). Popovers key off this. */\n activated: string | null\n /**\n * Activates annotation `id`, or clears the activation with `null`. This is the context's\n * own: unlike core's `Viewer.setActivated`, it calls InkRoot's `onActivate` for an id, and\n * it does not check that the id is in the document.\n */\n setActivated: (id: string | null) => void\n history: InkHistory\n rootEl: HTMLElement | null\n setViewport: (viewport: Viewport | null, tools: ToolController | null) => void\n /** InkRoot's `formHighlight`; InkViewport reads it when it builds the viewer. */\n formHighlight: boolean | undefined\n /** Calls InkRoot's `onFormAction`, one microtask later. */\n reportFormAction: (action: FormAction) => void\n /** Calls InkRoot's `onError`, for failures after the document opened (a refused signing). */\n reportError: (error: InkError) => void\n}\n\nexport const InkContextObject = createContext<InkContext | null>(null)\n\n/**\n * The context for hooks: throws a readable error when called outside a component rendered\n * inside `InkRoot`.\n */\nexport function useInkContext(consumer: string): InkContext {\n const ctx = useContext(InkContextObject)\n if (!ctx)\n throw new Error(\n `[inkbar] ${consumer} must be called in a component inside <InkRoot>.`\n )\n return ctx\n}\n","import { useCallback, useSyncExternalStore } from 'react'\n\nimport type { Readable } from '@inkbar/core'\n\nconst noop = (): void => undefined\n\n/**\n * Mirrors a core `Readable` into React. A missing readable yields `fallback`, which must be a\n * stable reference (a module constant): `useSyncExternalStore` compares snapshots by identity\n * and loops on a fresh value. On the server the fallback is rendered.\n */\nexport function useReadable<T>(readable: Readable<T> | null | undefined, fallback: T): T {\n const subscribe = useCallback(\n (onChange: () => void) => (readable ? readable.subscribe(() => onChange()) : noop),\n [readable]\n )\n const get = useCallback(\n () => (readable ? readable.get() : fallback),\n [readable, fallback]\n )\n const server = useCallback(() => fallback, [fallback])\n return useSyncExternalStore(subscribe, get, server)\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nimport type { AnnotationDocument, ImportOptions, PageInfo } from '@inkbar/core'\n\nconst NO_PAGES: readonly PageInfo[] = []\n\nexport function useDocument() {\n const ctx = useInkContext('useDocument()')\n const { document, status } = ctx\n return useMemo(\n () => ({\n document,\n status,\n isReady: status.state === 'ready',\n error: status.state === 'error' ? status.error : null,\n pages: document?.pages ?? NO_PAGES,\n info: document?.info ?? null,\n exportAnnotations: () => document?.exportAnnotations('json'),\n importAnnotations: (data: AnnotationDocument | string, opts?: ImportOptions) =>\n document?.importAnnotations(data, opts),\n }),\n [document, status]\n )\n}\n","import { repliesTo } from '@inkbar/core'\nimport { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nimport type { Annotation, AnnotationInput, AnnotationPatch } from '@inkbar/core'\n\nexport function useAnnotations() {\n const ctx = useInkContext('useAnnotations()')\n const { annotations, selection, document } = ctx\n const store = document?.annotations\n const selected = useMemo(\n () =>\n selection\n .map((id) => annotations.find((a) => a.id === id))\n .filter((a): a is Annotation => !!a),\n [annotations, selection]\n )\n // Stable for the life of the document, so hosts can pass them as props or effect deps.\n const actions = useMemo(\n () => ({\n add: (input: AnnotationInput) => store?.add(input),\n update: (id: string, patch: AnnotationPatch) => store?.update(id, patch),\n remove: (id: string) => store?.remove(id) ?? false,\n select: (ids: string[]) => store?.select(ids),\n }),\n [store]\n )\n return useMemo(\n () => ({\n annotations,\n selection,\n selected,\n byPage: (page: number) => annotations.filter((a) => a.page === page),\n /** Replies in creation order for a note id. */\n replies: (id: string) => repliesTo(annotations, id),\n ...actions,\n }),\n [annotations, selection, selected, actions]\n )\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nexport function useTool() {\n const ctx = useInkContext('useTool()')\n const { tool, setTool } = ctx\n return useMemo(() => ({ tool, setTool }), [tool, setTool])\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { CurrentStyle, StyleGroup, StyleKey, StyleProps } from '@inkbar/core'\n\nconst NO_STYLE: CurrentStyle = {}\nconst NO_PROPS: ReadonlySet<StyleKey> = new Set()\nconst EMPTY: Readonly<StyleProps> = {}\n\ninterface ToolStyleView {\n current: CurrentStyle\n supported: ReadonlySet<StyleKey>\n /** A group's own style. */\n get: (group: StyleGroup) => Readonly<StyleProps>\n}\n\n/** The tool style for the active tool or the selection. */\nexport interface ToolStyleHandle extends ToolStyleView {\n set: (patch: StyleProps, opts?: { group?: StyleGroup; apply?: boolean }) => void\n}\n\n/** The tool style scoped to one group: `set` writes that group, so it takes no options. */\nexport interface ScopedToolStyleHandle extends ToolStyleView {\n set: (patch: StyleProps) => void\n}\n\n/**\n * The tool style the style controls read and write: `current` shows the selection's values\n * (`'mixed'` where they differ), else the active tool's group; `supported` names the props\n * the active tool or the selection has. `set` updates the group and the selected annotations.\n *\n * With `group`, the style as a control for that group sees it, whatever tool is active: the\n * selection's when it is all in the group, else the group's own; `set` updates the group, and\n * the selection only when it is all in the group.\n */\nexport function useToolStyle(): ToolStyleHandle\nexport function useToolStyle(group: StyleGroup | undefined): ScopedToolStyleHandle\nexport function useToolStyle(group?: StyleGroup): ToolStyleHandle {\n const ctx = useInkContext('useToolStyle()')\n const style = ctx.toolStyle\n const scope = group && style ? style.scoped(group) : undefined\n const view = scope ?? style\n const current = useReadable(view?.current, NO_STYLE)\n const supported = useReadable(view?.supported, NO_PROPS)\n return useMemo(\n () => ({\n current,\n supported,\n set: (patch: StyleProps, opts?: { group?: StyleGroup; apply?: boolean }) =>\n scope ? scope.set(patch) : style?.set(patch, opts),\n get: (g: StyleGroup): Readonly<StyleProps> => style?.get(g) ?? EMPTY,\n }),\n [current, supported, style, scope]\n )\n}\n","import { useCallback } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { ToolId } from '@inkbar/core/dom'\n\nconst NO_OPTIONS: object = {}\n\n/**\n * A tool's options and a setter that merges a patch into them without switching tools.\n * Options are empty, and the setter does nothing, until the viewport has mounted.\n */\nexport function useToolOptions<O extends object = object>(\n id: ToolId\n): [O, (patch: Partial<O>) => void] {\n const ctx = useInkContext('useToolOptions()')\n const tools = ctx.tools\n const options = useReadable(tools?.options(id), NO_OPTIONS) as O\n const setOptions = useCallback(\n (patch: Partial<O>) => tools?.setOptions(id, patch),\n [tools, id]\n )\n return [options, setOptions]\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nexport function useSelection() {\n const ctx = useInkContext('useSelection()')\n const { selection, document } = ctx\n const store = document?.annotations\n return useMemo(\n () => ({\n selection,\n select: (ids: string[]) => store?.select(ids),\n clear: () => store?.select([]),\n }),\n [selection, store]\n )\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { ZoomValue } from '@inkbar/core/dom'\n\nexport function useZoom() {\n const ctx = useInkContext('useZoom()')\n const { viewport } = ctx\n const zoom = useReadable<ZoomValue>(viewport?.zoom, 'fit-width')\n const scale = useReadable<number>(viewport?.scale, 1)\n return useMemo(\n () => ({\n zoom,\n scale,\n setZoom: (z: ZoomValue) => viewport?.setZoom(z),\n zoomIn: () => viewport?.zoomBy(1.25),\n zoomOut: () => viewport?.zoomBy(0.8),\n }),\n [viewport, zoom, scale]\n )\n}\n","import { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { SearchState, ViewerSearch } from '@inkbar/core/dom'\n\nconst CLOSED: SearchState = {\n open: false,\n query: '',\n matchCase: false,\n hits: [],\n current: -1,\n scanning: false,\n}\n\nconst noop = (): void => undefined\n\n/**\n * The document search for hosts building their own control: the state, and the actions the\n * find bar uses. Search is set up once InkRoot has mounted, so until then (and on the server)\n * the state is closed and the actions do nothing. `open()` runs the search and draws the\n * highlights even when no find bar is mounted.\n */\nexport function useSearch(): { state: SearchState } & Omit<ViewerSearch, 'state'> {\n const search = useInkContext('useSearch()').search\n const state = useReadable<SearchState>(search?.state, CLOSED)\n return {\n state,\n open: search ? (query) => search.open(query) : noop,\n setQuery: search ? (query) => search.setQuery(query) : noop,\n setMatchCase: search ? (on) => search.setMatchCase(on) : noop,\n next: search ? () => search.next() : noop,\n previous: search ? () => search.previous() : noop,\n select: search ? (index) => search.select(index) : noop,\n close: search ? () => search.close() : noop,\n }\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nexport function usePage() {\n const ctx = useInkContext('usePage()')\n const { viewport, document } = ctx\n const current = useReadable<number>(viewport?.currentPage, 0)\n return useMemo(\n () => ({\n /** 0-based. */\n current,\n count: document?.pages.length ?? 0,\n goTo: (index: number) => viewport?.scrollToPage(index),\n // Read the live page, so these stay the same functions as the reader scrolls.\n next: () => viewport?.scrollToPage(viewport.currentPage.get() + 1),\n previous: () => viewport?.scrollToPage(viewport.currentPage.get() - 1),\n scrollToAnnotation(id: string) {\n const a = document?.annotations.get(id)\n if (a) viewport?.scrollToRect(a.page, a.rect)\n },\n }),\n [viewport, document, current]\n )\n}\n","import { useInkContext, type InkHistory } from '../context'\n\n/**\n * Undo and redo. Uncontrolled documents use the core history; controlled hosts that pass\n * `history` to InkRoot get a snapshot stack over their own list, applied through\n * `onAnnotationsChange`.\n */\nexport function useHistory(): InkHistory {\n return useInkContext('useHistory()').history\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\n\nconst NONE: readonly never[] = []\n\nexport function useEmbedded() {\n const ctx = useInkContext('useEmbedded()')\n const summary = ctx.document?.embedded ?? NONE\n return useMemo(\n () => ({\n summary,\n total: summary.reduce((n, s) => n + s.count, 0),\n hasAny: summary.length > 0,\n }),\n [summary]\n )\n}\n","import { unknownCommand } from '@inkbar/core/dom'\nimport { useCallback, useEffect, useRef } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { IconNode } from '@inkbar/icons'\n\nexport interface CommandHandle {\n /** Runs the command; does nothing while it is busy or disabled. Never rejects. */\n run: () => Promise<void>\n /** A ready document (or the plugin's own condition), and not busy. */\n enabled: boolean\n busy: boolean\n /** The command's progress or result message, `''` without one. */\n status: string\n /** `''` until the plugins are set up. */\n label: string\n icon: IconNode | undefined\n}\n\n/**\n * A plugin command by its namespaced id (`sandbox.suggest`), for hosts building their own\n * control. Plugins are set up once InkRoot has mounted, so until then (and on the server) the\n * command is disabled with no label; it fills in then. Once they are set up, an id no plugin\n * passed to InkRoot registered stays that way, and logs `InkError('UnknownCommand')` to the\n * console once.\n */\nexport function useCommand(id: string): CommandHandle {\n const { pluginHost } = useInkContext('useCommand()')\n const command = pluginHost?.command(id)\n const logged = useRef(false)\n useEffect(() => {\n if (!pluginHost || command || logged.current) return\n logged.current = true\n console.error(unknownCommand(id, [...pluginHost.commands.keys()]))\n }, [pluginHost, command, id])\n const enabled = useReadable(command?.enabled, false)\n const busy = useReadable(command?.busy, false)\n const status = useReadable(command?.status, '')\n const run = useCallback(async () => command?.run(), [command])\n return { run, enabled, busy, status, label: command?.label ?? '', icon: command?.icon }\n}\n","import { useMemo } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { FieldValues, FormField, FormSetResult } from '@inkbar/core'\n\nconst NO_FIELDS: readonly FormField[] = []\nconst NO_VALUES: FieldValues = Object.freeze({})\n\nexport interface FormHandle {\n /** The open document's form fields; empty while none is open or it has none. */\n fields: readonly FormField[]\n /** What the fields hold now, keyed by full name. */\n values: FieldValues\n /**\n * Commits values as a person would: scripts run, and the call is one undo step. Returns the\n * names applied and rejected, or `undefined` while no document is open.\n */\n set: (values: FieldValues) => FormSetResult | undefined\n /** Restores the PDF's default values of `names`, or of every field. */\n reset: (names?: string[]) => void\n}\n\n/** The open document's form: its fields, their values, and `set` and `reset`. */\nexport function useForm(): FormHandle {\n const { document } = useInkContext('useForm()')\n const form = document?.form\n const fields = useReadable(form?.fields, NO_FIELDS)\n const values = useReadable(form?.values, NO_VALUES)\n // Stable for the life of the document, so hosts can pass them as props or effect deps.\n const actions = useMemo(\n () => ({\n set: (v: FieldValues) => form?.set(v),\n reset: (names?: string[]) => form?.reset(names),\n }),\n [form]\n )\n return useMemo(() => ({ fields, values, ...actions }), [fields, values, actions])\n}\n","import { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport type { RecordBase } from '@inkbar/core'\nimport type { HostRecords } from '@inkbar/core/dom'\n\nconst NONE: readonly never[] = Object.freeze([])\n\n/**\n * The records a plugin keeps under `key` (`<plugin>.<name>`), for host components: the live list\n * for the open document, and the handle to read and write them, each write one undo step.\n * Plugins are set up once InkRoot has mounted, so until then (and on the server) `handle` is\n * null and `records` is empty. `T` is the plugin's record type.\n */\nexport function useRecords<T extends RecordBase>(\n key: string\n): { records: readonly T[]; handle: HostRecords<T> | null } {\n const { pluginHost } = useInkContext('useRecords()')\n // The host keeps one handle per key, so this is the same object on every render.\n const handle = pluginHost?.records<T>(key) ?? null\n return { records: useReadable<readonly T[]>(handle?.list, NONE), handle }\n}\n","import { useCallback } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nconst noop = (): void => undefined\n\n/**\n * The selected record under `key` (`<plugin>.<name>`): the one selection the marks and every\n * record list over those records share. `select` takes an id, or null to clear; an id that has\n * no mark changes nothing. Until InkRoot has mounted (and on the server) nothing is selected\n * and `select` does nothing.\n */\nexport function useRecordSelection(key: string): {\n selected: string | null\n select: (id: string | null) => void\n} {\n const { pluginHost } = useInkContext('useRecordSelection()')\n // The host keeps one selection per key, so `select` keeps its identity across renders.\n const selection = pluginHost?.selection(key) ?? null\n const select = useCallback(\n (id: string | null) => (selection ? selection.select(id) : noop()),\n [selection]\n )\n return { selected: useReadable(selection?.selected, null), select }\n}\n","import { useLayoutEffect, useRef, type RefObject } from 'react'\n\n/**\n * A ref that always holds the latest render's value, for callbacks that outlive a render\n * (core's `onChange`, effects keyed on something else). Updated in a layout effect, so it is\n * current before the parent's own layout and passive effects and before any callback fired\n * after commit; declare it before the effects that read it.\n */\nexport function useLatest<T>(value: T): RefObject<T> {\n const ref = useRef(value)\n useLayoutEffect(() => {\n ref.current = value\n })\n return ref\n}\n","import { unknownTool, withHostTools } from '@inkbar/core/dom'\nimport { useEffect, useRef } from 'react'\n\nimport { useInkContext, type InkContext } from '../context'\nimport { useLatest } from '../use-latest'\n\nimport type { PluginHost, Tool, ToolId } from '@inkbar/core/dom'\n\n/** `select-text` and `select`, then the host's tools, then the plugins' tools, by id. */\nexport function toolIdsOf(\n hostTools: readonly Tool[] | undefined,\n pluginHost: PluginHost | null\n): ToolId[] {\n return withHostTools([...(hostTools ?? []), ...(pluginHost?.tools ?? [])]).map(\n (t) => t.id\n )\n}\n\n/**\n * The tools a control may use: those in `tools` and the plugins now that the open viewer was\n * also built with, so a control never offers a tool the viewer would refuse. A tool added to\n * `tools` counts from the next open; one removed stops at once. With no viewer, `tools` and\n * the plugins alone.\n */\nexport function registeredToolIds(\n hostTools: readonly Tool[] | undefined,\n pluginHost: PluginHost | null,\n opened: readonly ToolId[] | null\n): ToolId[] {\n const ids = toolIdsOf(hostTools, pluginHost)\n return opened ? ids.filter((id) => opened.includes(id)) : ids\n}\n\nconst idsIn = (ctx: InkContext): ToolId[] =>\n registeredToolIds(ctx.hostTools, ctx.pluginHost, ctx.openedToolIds)\n\n/** Whether a tool by this id is registered, without logging anything when it is not. */\nexport function useHasTool(id: ToolId): boolean {\n return idsIn(useInkContext('useHasTool()')).includes(id)\n}\n\n/**\n * Whether a tool by this id is registered: always for `select-text` and `select`, else when\n * InkRoot's `tools` or a plugin has it. When it is not, once the plugins are set up, this logs\n * `InkError('UnknownTool')` to the console, once per component.\n */\nexport function useRegisteredTool(id: ToolId): boolean {\n const ctx = useInkContext('useRegisteredTool()')\n const ids = idsIn(ctx)\n const registered = ids.includes(id)\n // The plugins' tools are known once InkRoot has mounted and set up its plugin host.\n const ready = ctx.pluginHost !== null\n const logged = useRef(false)\n const latestIds = useLatest(ids)\n useEffect(() => {\n if (!ready || registered || logged.current) return\n logged.current = true\n console.error(unknownTool(id, latestIds.current))\n }, [ready, registered, id, latestIds])\n return registered\n}\n","import {\n createMemorySignatureStore,\n createSignatureLibrary,\n createSnapshotHistory,\n InkError,\n openDocument,\n readonly,\n writable,\n} from '@inkbar/core'\nimport {\n attachFileKeys,\n attachHistoryKeys,\n createPluginHost,\n createSearchController,\n createToolOptions,\n cssVariableDefaults,\n FONT_FAMILIES,\n handleFindKey,\n keepHistoryFocus,\n pageSelectionText,\n SIGNATURE_FONTS,\n trackToolStyle,\n unknownTool,\n viewerSearchOf,\n} from '@inkbar/core/dom'\nimport { Slot } from 'radix-ui'\nimport {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n type Ref,\n} from 'react'\nimport { flushSync } from 'react-dom'\n\nimport {\n InkContextObject,\n type InkContext,\n type InkHistory,\n type InkStatus,\n} from '../context'\nimport { registeredToolIds } from '../hooks/useRegisteredTool'\nimport { useLatest } from '../use-latest'\nimport { useReadable } from '../use-readable'\n\nimport type {\n Annotation,\n AnnotationChange,\n AnnotationDefaults,\n DocumentSource,\n FieldsChange,\n FieldValues,\n FormAction,\n InkDocument,\n PdfAssets,\n PluginHistory,\n SignatureStore,\n Writable,\n} from '@inkbar/core'\nimport type {\n DecorateAnnotation,\n InkPlugin,\n PluginHost,\n SearchController,\n Tool,\n ToolController,\n ToolId,\n Viewport,\n ZoomValue,\n} from '@inkbar/core/dom'\n\nexport interface InkRootHandle {\n readonly document: InkDocument | null\n readonly status: InkStatus\n readonly rootEl: HTMLElement | null\n /** What `useHistory()` returns inside the root. A controlled host calls `clear()` after loading its saved list. */\n readonly history: InkHistory\n}\n\nexport interface InkRootProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children' | 'onChange' | 'onError'\n> {\n src: DocumentSource | null\n assets: PdfAssets\n password?: string | undefined\n /** Colour defaults. Without it, the theme's CSS variables on the root element apply. */\n defaults?: AnnotationDefaults | undefined\n /**\n * Pass (with `onAnnotationsChange`) to put annotations under the host's control. The mode\n * is fixed when a document opens: passing or dropping this prop later takes effect on the\n * next open.\n */\n annotations?: Annotation[] | undefined\n onAnnotationsChange?: ((next: Annotation[]) => void) | undefined\n onChange?: ((change: AnnotationChange) => void) | undefined\n /**\n * Pass (with `onFieldsChange`) to put the form's field values under the host's control. A\n * commit shows at once and is reported after; the host's push wins. The mode is fixed when\n * a document opens, as for `annotations`.\n */\n fields?: FieldValues | undefined\n /**\n * Committed field values, in full, with what changed them, one microtask after the commit.\n * Called only while the fields are controlled.\n */\n onFieldsChange?: ((next: FieldValues, change: FieldsChange) => void) | undefined\n /** The form asked to submit, open a link, send mail, print or prompt. Inkbar does none. */\n onFormAction?: ((action: FormAction) => void) | undefined\n /** Tints fillable form fields. Default true. A change applies to the open document in place. */\n formHighlight?: boolean | undefined\n tool?: ToolId | undefined\n onToolChange?: ((tool: ToolId) => void) | undefined\n /**\n * The creation tools, such as `allTools()` or a pick of the tool factories. `select-text`\n * and `select` are always present; a tool with either id replaces it. They are read when a\n * document opens: a tool added later is usable from the next open, one removed stops at\n * once. When the active tool goes, the viewer switches to `select-text` and calls\n * `onToolChange`. A controlled `tool` naming a missing tool is reported back as\n * `select-text` and is not applied again when the tool appears later. Each mounted control\n * for a missing tool logs its own `UnknownTool`.\n */\n tools?: Tool[] | undefined\n /**\n * Plugins, set up once when the root mounts; a later change to this prop is not applied.\n * Their tools join `tools`, their decoration and page layers apply to every document, and\n * their commands are placed with `InkCommand` or `useCommand`.\n */\n plugins?: InkPlugin[] | undefined\n /**\n * Adds `data-*` attributes, classes and a screen-reader description to each annotation's\n * element (see `DecorateAnnotation`). Decorations re-apply whenever the annotations change\n * and when this prop changes, without rebuilding the viewer. Pass a new function when its\n * output would change for any other reason.\n */\n decorateAnnotation?: DecorateAnnotation | undefined\n /**\n * The font families text boxes offer, replacing the PDF standard families\n * (`FONT_FAMILIES`). Fonts beyond those are the PDF writer's to embed.\n */\n fonts?: string[] | undefined\n /**\n * Where saved signatures live. Default: memory, gone on reload. `createLocalSignatureStore`\n * keeps them in the browser; a host can keep them anywhere. A new store takes effect at\n * once, for the menus and the `signature` tool alike.\n */\n signatures?: SignatureStore | undefined\n /** The handwriting fonts a typed signature offers; the host loads them. */\n signatureFonts?: string[] | undefined\n page?: number | undefined\n onPageChange?: ((page: number) => void) | undefined\n zoom?: ZoomValue | undefined\n onZoomChange?: ((zoom: ZoomValue) => void) | undefined\n /** Undo history. Defaults to on for uncontrolled, off for controlled. */\n history?: boolean | undefined\n asChild?: boolean | undefined\n onReady?: ((doc: InkDocument) => void) | undefined\n /**\n * Opening failed, or later: a form script failed (`FormScriptError`; the form stays\n * fillable), or a signature field refused its signing (`FieldSigned`, `FieldReadOnly`).\n * A later error arrives one microtask after it happened, as `onFieldsChange` does; one from\n * while the document opened arrives after `onReady`.\n */\n onError?: ((error: InkError) => void) | undefined\n onActivate?: ((id: string) => void) | undefined\n children?:\n | ReactNode\n | ((props: { status: InkStatus; document: InkDocument | null }) => ReactNode)\n ref?: Ref<InkRootHandle>\n}\n\ntype TestHookElement = HTMLElement & { __inkDocument?: InkDocument | undefined }\n\nconst IDLE: InkStatus = { state: 'idle' }\nconst NO_ANNOTATIONS: readonly Annotation[] = []\nconst NO_IDS: readonly string[] = []\nconst noop = (): void => undefined\n\n/** The readables the plugin host follows, for the root's life. */\ninterface RootPlugins {\n /** Set once the document is current, so the host reads the history that goes with it. */\n document: Writable<InkDocument | null>\n /** InkViewport's scroll element while it is mounted. */\n root: Writable<HTMLElement | null>\n activated: Writable<string | null>\n}\n\n/** A plugin host and the search controller it shares, and whether they have been torn down. */\ninterface RootHost {\n host: PluginHost\n search: SearchController\n destroyed: boolean\n}\n\n/** Signed URLs change; the key does not. Bytes and Blobs are their own identity. */\nfunction identity(src: DocumentSource | null): unknown {\n if (src === null) return null\n if (typeof src === 'string') return src\n if ('key' in src) return src.key\n return src\n}\n\nfunction isDevelopment(): boolean {\n // Bundlers replace the expression with a literal; raw browser ESM has no `process`.\n try {\n return process.env.NODE_ENV !== 'production'\n } catch {\n return false\n }\n}\n\nfunction setTestHook(el: HTMLElement | null, doc: InkDocument | undefined): void {\n if (el && isDevelopment()) (el as TestHookElement).__inkDocument = doc\n}\n\nexport function InkRoot({\n src,\n assets,\n password,\n defaults,\n annotations,\n onAnnotationsChange,\n onChange,\n fields,\n onFieldsChange,\n onFormAction,\n formHighlight,\n tool,\n onToolChange,\n tools: hostTools,\n plugins: pluginsProp,\n decorateAnnotation,\n fonts: fontsProp,\n signatures: signatureStore,\n signatureFonts: signatureFontsProp,\n page,\n onPageChange,\n zoom,\n onZoomChange,\n history,\n asChild = false,\n onReady,\n onError,\n onActivate,\n children,\n ref,\n ...rest\n}: InkRootProps) {\n const rootElRef = useRef<HTMLElement | null>(null)\n const [rootEl, setRootElState] = useState<HTMLElement | null>(null)\n const setRootEl = useCallback((el: HTMLElement | null) => {\n rootElRef.current = el\n setRootElState(el)\n }, [])\n\n const documentRef = useRef<InkDocument | null>(null)\n const [document, setDocument] = useState<InkDocument | null>(null)\n /** Overrides the document's status while opening, and when opening itself failed. */\n const [override, setOverride] = useState<InkStatus | null>(null)\n const [internalTool, setInternalTool] = useState<ToolId>(tool ?? 'select-text')\n const [activated, setActivatedState] = useState<string | null>(null)\n const [viewport, setViewportState] = useState<Viewport | null>(null)\n /** The viewport as of the last `setViewport`, for the plugin host's `scrollTo`. */\n const viewportRef = useRef<Viewport | null>(null)\n const [tools, setToolsState] = useState<ToolController | null>(null)\n\n const documentStatus = useReadable<InkStatus>(document?.status, IDLE)\n const status = override ?? documentStatus\n const annotationList = useReadable(document?.annotations.list, NO_ANNOTATIONS)\n const selection = useReadable(document?.annotations.selection, NO_IDS)\n\n // What the next open will do follows the prop; the open document's mode is fixed.\n const controlledProp = annotations !== undefined\n const controlled = document\n ? document.annotations.mode === 'controlled'\n : controlledProp\n const historyEnabled = controlled && history === true\n // Callbacks and options read later than the render that passed them.\n const latest = useLatest({\n src,\n assets,\n defaults,\n annotations,\n controlled: controlledProp,\n fields,\n onFieldsChange,\n onFormAction,\n history,\n historyEnabled,\n onAnnotationsChange,\n onChange,\n onReady,\n onError,\n onActivate,\n onToolChange,\n onPageChange,\n onZoomChange,\n hostTools,\n plugins: pluginsProp,\n decorateAnnotation,\n tool: internalTool,\n tools,\n })\n\n /**\n * Hands `e` to `onError` one microtask later, as `onFieldsChange` and `onFormAction` are: a\n * script or a press reports from inside its own work. Dropped once `doc` is no longer open.\n */\n const reportErrorFor = useCallback(\n (doc: InkDocument, e: InkError) => {\n queueMicrotask(() => {\n if (documentRef.current !== doc) return\n flushSync(() => latest.current.onError?.(e))\n })\n },\n [latest]\n )\n\n const snapshotHistory = useMemo(\n () =>\n createSnapshotHistory({\n apply: (list) => documentRef.current?.annotations.replaceAll(list, 'history'),\n enabled: () => latest.current.historyEnabled,\n }),\n [latest]\n )\n // A layout effect, like the one that pushes the list into the store below: history sees each\n // list in the same commit the store does, so a change made once the store has a list (a\n // sketch swapping its stroke for a shape) is never folded into the step before it.\n useLayoutEffect(() => {\n snapshotHistory.observe(annotations)\n }, [annotations, snapshotHistory])\n\n /** What the plugin host follows; plain readables, so StrictMode's second render is harmless. */\n const [plugins] = useState<RootPlugins>(() => ({\n document: writable<InkDocument | null>(null),\n root: writable<HTMLElement | null>(null),\n activated: writable<string | null>(null),\n }))\n const setActivated = useCallback(\n (id: string | null) => {\n setActivatedState(id)\n plugins.activated.set(id)\n if (id) latest.current.onActivate?.(id)\n },\n [latest, plugins]\n )\n\n /**\n * The history the plugins reach, picked by the open document's mode when they call: the host\n * reads it as soon as a document opens, before this root has rendered with that document.\n */\n const pluginHistory = useMemo<PluginHistory>(() => {\n const active = (): PluginHistory | undefined => {\n const doc = documentRef.current\n if (!doc) return undefined\n return doc.annotations.mode === 'controlled' ? snapshotHistory : doc.history\n }\n return {\n batch: (fn) => {\n const h = active()\n if (h) h.batch(fn)\n else fn()\n },\n track: (store) => active()?.track(store) ?? noop,\n react: (fn) => active()?.react(fn) ?? noop,\n }\n }, [snapshotHistory])\n\n /*\n * One plugin host for the root's life, built in a layout effect so that no `setup` runs on\n * the server, where nothing would clean it up, and the browser never paints the commands\n * without it. Until then `pluginHost` is null and InkCommand renders its command disabled.\n * Layout effects run before the passive effect that opens the document, so the first\n * document opens with the plugins' stores and reactions.\n */\n const hostRef = useRef<RootHost | null>(null)\n const [pluginHost, setPluginHost] = useState<PluginHost | null>(null)\n const [search, setSearch] = useState<SearchController | null>(null)\n const hostMounts = useRef(0)\n useLayoutEffect(() => {\n hostMounts.current += 1\n // StrictMode's simulated unmount mounts again at once, and then the host from the first\n // mount stays. Shown again after it was destroyed (an `<Activity>` hidden and shown), or\n // mounted for the first time: start anew.\n if (!hostRef.current || hostRef.current.destroyed) {\n const search = createSearchController({\n document: readonly(plugins.document),\n viewport: () => viewportRef.current,\n })\n const host = createPluginHost({\n plugins: latest.current.plugins ?? [],\n document: readonly(plugins.document),\n history: () => pluginHistory,\n activated: readonly(plugins.activated),\n // As in `createViewer`: an id not in the open document is ignored.\n setActivated: (id) => {\n if (id === null || documentRef.current?.annotations.get(id)) setActivated(id)\n },\n root: readonly(plugins.root),\n decorate: () => latest.current.decorateAnnotation,\n viewport: () => viewportRef.current,\n search: viewerSearchOf(search),\n })\n hostRef.current = { host, search, destroyed: false }\n setPluginHost(host)\n setSearch(search)\n }\n return () => {\n hostMounts.current -= 1\n // After the rest of this commit's cleanups, so InkViewport's engine and its plugin layers\n // go first, as in `createViewer`.\n queueMicrotask(() => {\n const current = hostRef.current\n if (hostMounts.current > 0 || !current || current.destroyed) return\n current.destroyed = true\n current.host.destroy()\n current.search.destroy()\n })\n }\n // Once per mount; the host reads only stable values and refs.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n const srcIdentity = identity(src)\n useEffect(() => {\n let cancelled = false\n snapshotHistory.clear()\n const source = latest.current.src\n if (source === null) {\n setOverride(null)\n return\n }\n setOverride({ state: 'loading' })\n let opened: InkDocument | null = null\n /** The plugins told of `opened`, and the snapshot history's hold on its store. */\n let told: RootPlugins | null = null\n let detach: () => void = noop\n let stopFormErrors: () => void = noop\n const run = async () => {\n try {\n const doc = await openDocument(source, {\n assets: latest.current.assets,\n password,\n defaults:\n latest.current.defaults ??\n (rootElRef.current ? cssVariableDefaults(rootElRef.current) : undefined),\n // Controlled hosts get the snapshot history below; core's own stack stays off.\n history: latest.current.controlled ? false : (latest.current.history ?? true),\n annotations: latest.current.controlled\n ? {\n mode: 'controlled',\n initial: latest.current.annotations ?? [],\n onChange: (next, change) => {\n // Apply the host's state update, its render and the layout effect that pushes\n // the list back before core's development check expires. The microtask\n // leaves React's render, commit and passive-effect contexts, where a host\n // may call the store, so `flushSync` is always legal; the host sees the\n // proposal one microtask after the store returned. A proposal made in the\n // tick this root unmounts or reopens never reaches the host.\n queueMicrotask(() => {\n if (cancelled) return\n flushSync(() => {\n latest.current.onAnnotationsChange?.(next)\n latest.current.onChange?.(change)\n })\n })\n },\n }\n : { mode: 'uncontrolled' },\n fields:\n latest.current.fields !== undefined\n ? {\n mode: 'controlled',\n initial: latest.current.fields,\n // Deferred and flushed as annotation proposals are, for the same reasons.\n onChange: (next, change) => {\n queueMicrotask(() => {\n if (cancelled) return\n flushSync(() => latest.current.onFieldsChange?.(next, change))\n })\n },\n }\n : { mode: 'uncontrolled' },\n })\n if (cancelled) {\n doc.destroy()\n return\n }\n opened = doc\n // The prop may have changed while the file loaded, when there was no store to apply it to.\n const current = latest.current.annotations\n if (doc.annotations.mode === 'controlled' && current !== undefined)\n doc.annotations.setControlledValue(current)\n // The same for the fields; a document whose fields opened uncontrolled ignores the push.\n const currentFields = latest.current.fields\n if (currentFields !== undefined) doc.form.setControlledValue(currentFields)\n // A form script that fails leaves the form fillable; the failure goes to `onError`.\n // Subscribed before anyone hears of the document, so the form replays the errors from\n // while it opened here; they are held until `onReady` has run.\n let held: InkError[] | undefined = []\n stopFormErrors = doc.form.on('error', (e) => {\n if (held) held.push(e)\n else reportErrorFor(doc, e)\n })\n documentRef.current = doc\n // Controlled edits run the plugins' reactions inside their own snapshot step.\n if (doc.annotations.mode === 'controlled')\n detach = snapshotHistory.attach(doc.annotations)\n // The document is current, so the host reads its history when it hears of it.\n told = plugins\n told.document.set(doc)\n setDocument(doc)\n setOverride(null)\n setTestHook(rootElRef.current, doc)\n const s = doc.status.get()\n try {\n if (s.state === 'ready') latest.current.onReady?.(doc)\n else if (s.state === 'error') latest.current.onError?.(s.error)\n } finally {\n // A host whose `onReady` throws still hears the held errors and every later one.\n const early = held\n held = undefined\n for (const e of early) reportErrorFor(doc, e)\n }\n } catch (cause) {\n if (cancelled) return\n const error =\n cause instanceof InkError\n ? cause\n : new InkError(\n 'InvalidPdf',\n cause instanceof Error ? cause.message : String(cause),\n {},\n cause\n )\n setOverride({ state: 'error', error })\n latest.current.onError?.(error)\n }\n }\n // StrictMode's simulated cleanup runs synchronously in the same commit, so deferring one\n // microtask means the discarded first attempt never starts a fetch.\n void Promise.resolve().then(() => {\n if (!cancelled) return run()\n })\n return () => {\n cancelled = true\n // Cleared first, so the plugins close their stores while the document is still alive.\n told?.document.set(null)\n detach()\n stopFormErrors()\n opened?.destroy()\n documentRef.current = null\n setDocument(null)\n setTestHook(rootElRef.current, undefined)\n }\n // `srcIdentity` stands in for `src`: a new URL with the same key is the same document.\n }, [srcIdentity, password, snapshotHistory, latest, plugins, reportErrorFor])\n\n useLayoutEffect(() => {\n if (annotations && document?.annotations.mode === 'controlled')\n document.annotations.setControlledValue(annotations)\n }, [annotations, document])\n\n useLayoutEffect(() => {\n if (fields && document) document.form.setControlledValue(fields)\n }, [fields, document])\n\n /*\n * The tools are known once the plugin host is set up on mount. A tool id nobody registered is\n * logged as `UnknownTool`; as the active tool, from a `tool` prop or because it left `tools`,\n * it falls back to `select-text`, reported through `onToolChange`. A controlled `tool` that\n * stays on the missing id is not applied again: only a change to the prop is.\n */\n const ready = pluginHost !== null\n /** The ids of the tools the current viewer was built with; InkViewport sets them. */\n const [openedToolIds, setOpenedToolIds] = useState<readonly ToolId[] | null>(null)\n // Keyed by the ids, so a host that passes a new array of the same tools changes nothing.\n const toolKey = registeredToolIds(hostTools, pluginHost, openedToolIds).join('\\n')\n const toolIds = useMemo(() => toolKey.split('\\n'), [toolKey])\n const registration = useLatest({ ready, toolIds })\n const isRegistered = useCallback(\n (id: ToolId): boolean => {\n const r = registration.current\n return !r.ready || r.toolIds.includes(id)\n },\n [registration]\n )\n const logUnknownTool = useCallback(\n (id: ToolId) => console.error(unknownTool(id, registration.current.toolIds)),\n [registration]\n )\n const fallBack = useCallback(\n (id: ToolId) => {\n logUnknownTool(id)\n setInternalTool('select-text')\n latest.current.onToolChange?.('select-text')\n },\n [latest, logUnknownTool]\n )\n\n /** The `tool` prop last applied, so a host that keeps passing it does not apply it again. */\n const appliedTool = useRef<ToolId | undefined>(tool)\n // One check for a new `tool` prop, a bad first one once the plugins are known, and an active\n // tool that left `tools`, so a commit that changes several reports once. A new prop is\n // checked before it is applied, so a missing id never reaches the engine.\n useEffect(() => {\n let next = internalTool\n if (tool !== appliedTool.current) {\n appliedTool.current = tool\n if (tool) next = tool\n }\n if (!isRegistered(next)) fallBack(next)\n else if (next !== internalTool) setInternalTool(next)\n }, [tool, ready, toolIds, internalTool, isRegistered, fallBack])\n\n const setTool = useCallback(\n (id: ToolId) => {\n // As the tool controller does: a missing tool is logged and nothing changes.\n if (!isRegistered(id)) {\n logUnknownTool(id)\n return\n }\n // Picking the active tool again starts it afresh, as after a one-shot tool's use.\n const tc = latest.current.tools\n if (latest.current.tool === id && tc?.active.get() === id) tc.set(id)\n setInternalTool(id)\n latest.current.onToolChange?.(id)\n },\n [latest, isRegistered, logUnknownTool]\n )\n const reportZoom = useCallback(\n (z: ZoomValue) => latest.current.onZoomChange?.(z),\n [latest]\n )\n const reportPage = useCallback(\n (p: number) => latest.current.onPageChange?.(p),\n [latest]\n )\n const reportFormAction = useCallback(\n (a: FormAction) => {\n // As for `onFieldsChange`: the engine reports from inside a press or a script.\n const doc = documentRef.current\n queueMicrotask(() => {\n if (documentRef.current !== doc) return\n flushSync(() => latest.current.onFormAction?.(a))\n })\n },\n [latest]\n )\n const reportError = useCallback(\n (e: InkError) => {\n if (documentRef.current) reportErrorFor(documentRef.current, e)\n },\n [reportErrorFor]\n )\n const setViewport = useCallback((vp: Viewport | null, tc: ToolController | null) => {\n viewportRef.current = vp\n setViewportState(vp)\n setToolsState(tc)\n }, [])\n\n const snapCanUndo = useReadable(snapshotHistory.canUndo, false)\n const snapCanRedo = useReadable(snapshotHistory.canRedo, false)\n const coreCanUndo = useReadable(document?.history.canUndo, false)\n const coreCanRedo = useReadable(document?.history.canRedo, false)\n const inkHistory = useMemo<InkHistory>(\n () => ({\n canUndo: controlled ? historyEnabled && snapCanUndo : coreCanUndo,\n canRedo: controlled ? historyEnabled && snapCanRedo : coreCanRedo,\n undo: () =>\n controlled ? snapshotHistory.undo() : documentRef.current?.history.undo(),\n redo: () =>\n controlled ? snapshotHistory.redo() : documentRef.current?.history.redo(),\n clear: () =>\n controlled ? snapshotHistory.clear() : documentRef.current?.history.clear(),\n batch: (fn) => {\n if (controlled) snapshotHistory.batch(fn)\n else if (documentRef.current) documentRef.current.history.batch(fn)\n else fn()\n },\n track: (store) => pluginHistory.track(store),\n react: (fn) => pluginHistory.react(fn),\n }),\n [\n controlled,\n historyEnabled,\n snapCanUndo,\n snapCanRedo,\n coreCanUndo,\n coreCanRedo,\n snapshotHistory,\n pluginHistory,\n ]\n )\n\n const latestHistory = useLatest(inkHistory)\n\n // The undo and redo keys anywhere in the root do what InkUndo and InkRedo do. When either\n // button undoes or redoes the last step and disables itself, focus goes back to the document.\n useEffect(() => {\n if (!rootEl) return\n // The flags are read from the stacks, not from the last render: a held key repeats before\n // React renders again, and a stale `canUndo` would prevent a key that undoes nothing.\n const stopKeys = attachHistoryKeys(rootEl, () => {\n const doc = documentRef.current\n if (!doc) return null\n const snap = doc.annotations.mode === 'controlled'\n const on = latest.current.historyEnabled\n return {\n canUndo: snap ? on && snapshotHistory.canUndo.get() : doc.history.canUndo.get(),\n canRedo: snap ? on && snapshotHistory.canRedo.get() : doc.history.canRedo.get(),\n undo: () => latestHistory.current.undo(),\n redo: () => latestHistory.current.redo(),\n }\n })\n const stopFocus = keepHistoryFocus(rootEl, () =>\n rootEl.querySelector<HTMLElement>('[data-ink-scroll]')\n )\n // Ctrl or Cmd+P prints and +S downloads, as InkPrintButton and InkDownloadButton do.\n const stopFileKeys = attachFileKeys(rootEl, () => documentRef.current)\n return () => {\n stopKeys()\n stopFocus()\n stopFileKeys()\n }\n }, [rootEl, latestHistory, latest, snapshotHistory])\n\n /** The document's tool style; it batches through `history`, whichever mode is on. */\n const styleTracker = useMemo(\n () =>\n document\n ? trackToolStyle({\n store: document.annotations,\n history: { batch: (fn) => latestHistory.current.batch(fn) },\n // The plugins' tools too, so a plugin tool's style group applies.\n tools: [...(latest.current.hostTools ?? []), ...(pluginHost?.tools ?? [])],\n tool: latest.current.tool,\n })\n : null,\n [document, latest, latestHistory, pluginHost]\n )\n useEffect(() => {\n styleTracker?.setTool(internalTool)\n }, [styleTracker, internalTool])\n\n useImperativeHandle(ref, () => ({ document, status, rootEl, history: inkHistory }), [\n document,\n status,\n rootEl,\n inkHistory,\n ])\n\n // Stable while the host passes the same list.\n const fonts = useMemo<readonly string[]>(() => fontsProp ?? FONT_FAMILIES, [fontsProp])\n const signatureFonts = useMemo<readonly string[]>(\n () => signatureFontsProp ?? SIGNATURE_FONTS,\n [signatureFontsProp]\n )\n const signatures = useMemo(\n () => createSignatureLibrary(signatureStore ?? createMemorySignatureStore()),\n [signatureStore]\n )\n useEffect(() => {\n void signatures.refresh()\n }, [signatures])\n /** Tool options last as long as the root; the tool style is per document. */\n const [toolOptions] = useState(createToolOptions)\n\n // The prop is read through a stable function and kept out of the context's dependencies, so\n // an inline arrow does not re-render every consumer. InkViewport hears of a change instead.\n const decorate = useCallback<DecorateAnnotation>(\n (a) => latest.current.decorateAnnotation?.(a),\n [latest]\n )\n const [decorateListeners] = useState(() => new Set<() => void>())\n const onDecorateAnnotationChange = useCallback(\n (listener: () => void) => {\n decorateListeners.add(listener)\n return () => {\n decorateListeners.delete(listener)\n }\n },\n [decorateListeners]\n )\n const decoratedOnce = useRef(false)\n useEffect(() => {\n // The first build reads the prop itself.\n if (!decoratedOnce.current) {\n decoratedOnce.current = true\n return\n }\n for (const listener of decorateListeners) listener()\n }, [decorateAnnotation, decorateListeners])\n\n const ctx = useMemo<InkContext>(\n () => ({\n assets,\n document,\n status,\n annotations: annotationList,\n selection,\n viewport,\n tools,\n tool: internalTool,\n setTool,\n hostTools,\n openedToolIds,\n setOpenedToolIds,\n decorateAnnotation: decorate,\n onDecorateAnnotationChange,\n fonts,\n toolOptions,\n signatures,\n signatureFonts,\n toolStyle: styleTracker?.toolStyle ?? null,\n zoomModel: zoom,\n pageModel: page,\n reportZoom,\n reportPage,\n activated,\n setActivated,\n pluginHost,\n search,\n viewportEl: plugins.root,\n history: inkHistory,\n rootEl,\n setViewport,\n formHighlight,\n reportFormAction,\n reportError,\n }),\n [\n assets,\n document,\n status,\n annotationList,\n selection,\n viewport,\n tools,\n internalTool,\n setTool,\n hostTools,\n openedToolIds,\n decorate,\n onDecorateAnnotationChange,\n fonts,\n toolOptions,\n signatures,\n signatureFonts,\n styleTracker,\n zoom,\n page,\n reportZoom,\n reportPage,\n activated,\n setActivated,\n pluginHost,\n search,\n plugins,\n inkHistory,\n rootEl,\n setViewport,\n formHighlight,\n reportFormAction,\n reportError,\n ]\n )\n\n /*\n * Ctrl/Cmd+F while focus is in the root and a find bar is mounted; else the browser's. A\n * native listener: the handler reads the event's `currentTarget`, which React's delegated\n * synthetic events do not leave on the root.\n */\n useEffect(() => {\n if (!rootEl || !search) return\n const onKeyDown = (e: globalThis.KeyboardEvent): void => {\n handleFindKey(e, search, () => pageSelectionText(rootEl))\n }\n rootEl.addEventListener('keydown', onKeyDown)\n return () => rootEl.removeEventListener('keydown', onKeyDown)\n }, [rootEl, search])\n\n const Comp = asChild ? Slot.Root : 'div'\n return (\n <InkContextObject.Provider value={ctx}>\n <Comp ref={setRootEl} data-ink-root=\"\" data-state={status.state} {...rest}>\n {typeof children === 'function' ? children({ status, document }) : children}\n </Comp>\n </InkContextObject.Provider>\n )\n}\n","/** Joins class names, dropping empties. */\nexport function cx(...parts: (string | undefined | false)[]): string | undefined {\n const out = parts.filter(Boolean).join(' ')\n return out === '' ? undefined : out\n}\n","/*\n * A form script's `app.alert`: the message and OK, shown without blocking (no overlay, not\n * modal), so the form stays usable around it. InkViewport mounts it; hosts compose nothing.\n * OK, or Escape while focus is in the alert, closes it, and focus goes back where it was. A\n * press outside leaves it open, and Escape anywhere else stays with the viewer. A new message\n * replaces the one shown.\n *\n * The markup is core's `createFormAlert`, portalled to `<body>`. It is not a Radix dialog:\n * Radix's dismissable layer takes every Escape on the page while it is open, which would end\n * the viewer's own use of the key.\n */\nimport { FORM_LABELS } from '@inkbar/core/dom'\nimport { useId, useLayoutEffect, useRef } from 'react'\nimport { createPortal } from 'react-dom'\n\nexport function InkFormAlert({\n message,\n shown,\n fallback,\n onClose,\n}: {\n /** The message to show (text, not markup); `null` while none is. */\n message: string | null\n /** Counts the times a message was shown, so the same text shown again takes focus again. */\n shown: number\n /** Where focus goes when nothing it can return to is left. */\n fallback: () => HTMLElement | null\n onClose: () => void\n}) {\n const uid = useId()\n const panel = useRef<HTMLDivElement>(null)\n const ok = useRef<HTMLButtonElement>(null)\n /** Where focus was when the alert opened. */\n const returnTo = useRef<HTMLElement | null>(null)\n const open = message !== null\n const wasOpen = useRef(false)\n\n // Before paint, so focus is read before it moves to OK.\n useLayoutEffect(() => {\n if (!open) {\n wasOpen.current = false\n return\n }\n if (!wasOpen.current) {\n wasOpen.current = true\n const active = document.activeElement\n returnTo.current =\n active instanceof HTMLElement && active !== document.body ? active : null\n }\n ok.current?.focus({ preventScroll: true })\n }, [open, shown])\n\n const close = (): void => {\n // Focus that moved elsewhere while the alert showed stays there.\n const hadFocus = !!panel.current?.contains(document.activeElement)\n onClose()\n if (!hadFocus) return\n const back = returnTo.current?.isConnected === true ? returnTo.current : fallback()\n back?.focus({ preventScroll: true })\n }\n\n if (!open) return null\n return createPortal(\n <div\n ref={panel}\n role=\"alertdialog\"\n aria-labelledby={`${uid}-title`}\n aria-describedby={`${uid}-message`}\n className=\"ink-dialog ink-form-alert\"\n data-ink-form-alert=\"\"\n data-state=\"open\"\n tabIndex={-1}\n onKeyDown={(e) => {\n if (e.key !== 'Escape' || e.defaultPrevented) return\n e.preventDefault()\n e.stopPropagation()\n close()\n }}\n >\n <h2 id={`${uid}-title`} className=\"ink-dialog-title\">\n {FORM_LABELS.alert}\n </h2>\n <p\n id={`${uid}-message`}\n className=\"ink-form-alert-message\"\n data-ink-form-alert-message=\"\"\n >\n {message}\n </p>\n <div className=\"ink-dialog-actions\">\n <button\n ref={ok}\n type=\"button\"\n className=\"ink-button\"\n data-variant=\"primary\"\n data-ink-form-alert-ok=\"\"\n onClick={close}\n >\n {FORM_LABELS.ok}\n </button>\n </div>\n </div>,\n document.body\n )\n}\n","/*\n * Slot props for one annotation. It renders only its children: the overlay already draws the\n * default visual for every annotation that is not custom, so this never draws a second one.\n * InkPage portals it into the annotation's overlay element.\n */\nimport { useEffect, useMemo, useState, type ReactNode } from 'react'\n\nimport { useInkContext } from '../context'\n\nimport type { Annotation } from '@inkbar/core'\nimport type { AnnotationSlotProps, AnnotationState } from '@inkbar/core/dom'\n\nexport interface InkAnnotationProps {\n annotation: Annotation\n /** The overlay element; its `data-state` (which includes hover) drives `state`. */\n element?: HTMLElement | undefined\n children: (props: AnnotationSlotProps) => ReactNode\n}\n\nfunction readState(el: HTMLElement): AnnotationState | null {\n const s = el.dataset.state\n return s === 'idle' || s === 'hover' || s === 'selected' ? s : null\n}\n\nexport function InkAnnotation({ annotation, element, children }: InkAnnotationProps) {\n const ctx = useInkContext('InkAnnotation')\n const [observed, setObserved] = useState<AnnotationState | null>(() =>\n element ? readState(element) : null\n )\n useEffect(() => {\n if (!element) {\n setObserved(null)\n return\n }\n setObserved(readState(element))\n const observer = new MutationObserver(() => setObserved(readState(element)))\n observer.observe(element, { attributes: true, attributeFilter: ['data-state'] })\n return () => observer.disconnect()\n }, [element])\n\n const { id } = annotation\n const locked = annotation.locked === true\n const selected = ctx.selection.includes(id)\n const store = ctx.document?.annotations\n const slotProps = useMemo<AnnotationSlotProps>(\n () => ({\n annotation,\n state: observed ?? (selected ? 'selected' : 'idle'),\n locked,\n select: () => store?.select([id]),\n remove: () => void store?.remove(id),\n }),\n [annotation, observed, selected, locked, store, id]\n )\n return <>{children(slotProps)}</>\n}\n","/*\n * One page the viewer engine mounted. Renders nothing in place; portals go into the host\n * (page error) and into each annotation's overlay element (custom annotations).\n *\n * The overlay creates and removes those elements as the annotation list changes, outside\n * React. So the portal targets come from a list read after every overlay render: this\n * component subscribes to the store after the overlay does (the engine created the mount\n * first), and core notifies subscribers in order, so the elements already exist when the list\n * arrives here.\n *\n * The engine tracks page errors and sets `data-state=\"error\"` on the host; this component\n * portals the page-error slot into it while `error` is set.\n */\nimport { useEffect, useState, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { useInkContext } from '../context'\n\nimport { InkAnnotation } from './InkAnnotation'\n\nimport type { Annotation, InkError } from '@inkbar/core'\nimport type { AnnotationSlotProps, PageMount } from '@inkbar/core/dom'\n\nexport interface InkPageProps {\n page: number\n host: HTMLElement\n /** The engine's page mount in `host`. */\n mount: PageMount\n /** The engine's error for this page, `null` while it renders. */\n error: InkError | null\n /** Fixed for the life of the mount: the engine rebuilds when it changes. */\n customAnnotations?: boolean\n renderAnnotation?: ((props: AnnotationSlotProps) => ReactNode) | undefined\n renderPageError?: ((props: { error: InkError; page: number }) => ReactNode) | undefined\n}\n\ninterface Target {\n annotation: Annotation\n el: HTMLElement\n}\n\nfunction sameTargets(a: readonly Target[], b: readonly Target[]): boolean {\n return (\n a.length === b.length &&\n a.every((t, i) => t.annotation === b[i]!.annotation && t.el === b[i]!.el)\n )\n}\n\nexport function InkPage({\n page,\n host,\n mount,\n error,\n customAnnotations = false,\n renderAnnotation,\n renderPageError,\n}: InkPageProps) {\n const doc = useInkContext('InkPage').document\n const [targets, setTargets] = useState<Target[]>([])\n\n useEffect(() => {\n if (!doc || !customAnnotations) return\n const read = (): void => {\n const next = doc.annotations.byPage(page).flatMap((annotation) => {\n const el = mount.overlay.elementFor(annotation.id)\n return el ? [{ annotation, el }] : []\n })\n // A change elsewhere in the document leaves this page's targets as they were.\n setTargets((prev) => (sameTargets(prev, next) ? prev : next))\n }\n const stop = doc.annotations.list.subscribe(read)\n read()\n return () => {\n stop()\n setTargets([])\n }\n }, [doc, page, mount, customAnnotations])\n\n return (\n <>\n {error\n ? createPortal(\n <div className=\"ink-page-error\" data-ink-page-error=\"\" role=\"alert\">\n {renderPageError ? (\n renderPageError({ error, page })\n ) : (\n <>\n <p>Page {page + 1} could not be shown.</p>\n <code className=\"ink-error-code\">{error.code}</code>\n </>\n )}\n </div>,\n host\n )\n : null}\n {renderAnnotation\n ? targets.map((t) =>\n createPortal(\n <InkAnnotation annotation={t.annotation} element={t.el}>\n {renderAnnotation}\n </InkAnnotation>,\n t.el,\n t.annotation.id\n )\n )\n : null}\n </>\n )\n}\n","/*\n * \"Create signature\": a modal with Draw, Type and Image tabs. Draw is a pad with the draw\n * tool's renderer; Type sets a name in one of the host's handwriting fonts; Image takes a PNG\n * or JPEG scan. Save stores the template through InkRoot's signature store and, unless `select`\n * is false or no `signature` tool is registered, selects it for that tool. Escape, Cancel or a\n * press outside closes it.\n */\nimport {\n createSignatureDraft,\n fontFamilyValue,\n handleRadioKeys,\n handleTabKeys,\n SIGNATURE_LABELS,\n SIGNATURE_TABS,\n type SignatureDraft,\n type SignatureDraftState,\n type SignatureTab,\n} from '@inkbar/core/dom'\nimport { Dialog } from 'radix-ui'\nimport { useEffect, useId, useRef, useState } from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useHasTool } from '../hooks/useRegisteredTool'\nimport { useTool } from '../hooks/useTool'\nimport { useReadable } from '../use-readable'\n\nimport type { SignatureOptions, SignatureTemplate } from '@inkbar/core'\n\nexport interface InkSignatureDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n /** The fonts the Type tab offers. Default: InkRoot's `signatureFonts`. */\n fonts?: readonly string[] | undefined\n /**\n * Whether saving selects the new signature for the `signature` tool, when one is registered.\n * Default true. False leaves the tool alone, for a dialog that signs a field with it through\n * `onSave`.\n */\n select?: boolean | undefined\n /** Called with the new template once it is saved (and selected, with `select`). */\n onSave?: ((template: SignatureTemplate) => void) | undefined\n /** Where focus goes on close; by default, back to what had it before. */\n onCloseAutoFocus?: ((event: Event) => void) | undefined\n className?: string | undefined\n}\n\nexport function InkSignatureDialog({\n open,\n onOpenChange,\n fonts,\n select = true,\n onSave,\n onCloseAutoFocus,\n className,\n}: InkSignatureDialogProps) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className=\"ink-dialog-overlay\" data-ink-dialog-overlay=\"\" />\n <Dialog.Content\n className={cx('ink-dialog ink-signature-dialog', className)}\n data-ink-signature-dialog=\"\"\n aria-modal=\"true\"\n aria-describedby={undefined}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n ;(e.currentTarget as HTMLElement)\n .querySelector<HTMLElement>('[role=\"tab\"][aria-selected=\"true\"]')\n ?.focus({ preventScroll: true })\n }}\n onCloseAutoFocus={onCloseAutoFocus}\n >\n <Dialog.Title className=\"ink-dialog-title\">\n {SIGNATURE_LABELS.dialog}\n </Dialog.Title>\n <SignatureForm\n fonts={fonts}\n select={select}\n onSave={onSave}\n onClose={() => onOpenChange(false)}\n />\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n\nconst IDLE: SignatureDraftState = {\n tab: 'draw',\n padEmpty: true,\n name: '',\n font: '',\n image: undefined,\n imageError: undefined,\n saveError: undefined,\n canSave: false,\n saving: false,\n}\n\n/** The dialog's body, mounted while it is open: one draft per opening. */\nfunction SignatureForm({\n fonts,\n select,\n onSave,\n onClose,\n}: {\n fonts: readonly string[] | undefined\n select: boolean\n onSave: ((t: SignatureTemplate) => void) | undefined\n onClose: () => void\n}) {\n const ctx = useInkContext('InkSignatureDialog')\n const { setTool } = useTool()\n // Without the signature tool, Save only stores the template, as signing a form field needs;\n // its options are never read, which would log the missing tool.\n const hasSignatureTool = useHasTool('signature')\n const [draft] = useState<SignatureDraft>(() =>\n createSignatureDraft({ fonts: fonts ?? ctx.signatureFonts })\n )\n const s = useReadable(draft.state, IDLE)\n const uid = useId()\n const padHost = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const host = padHost.current\n const detach = host ? draft.attachPad(host) : undefined\n return () => {\n detach?.()\n draft.destroy()\n }\n }, [draft])\n\n const save = (): void => {\n draft.save(ctx.signatures).then(\n (t) => {\n if (!t) return\n if (select && hasSignatureTool) {\n const patch: Partial<SignatureOptions> = { templateId: t.id }\n ctx.tools?.setOptions('signature', patch)\n setTool('signature')\n }\n onSave?.(t)\n onClose()\n },\n () => {\n // The host's store refused it: the dialog stays open to try again.\n }\n )\n }\n\n const tabId = (tab: SignatureTab) => `${uid}-tab-${tab}`\n const panelId = (tab: SignatureTab) => `${uid}-panel-${tab}`\n const panel = (tab: SignatureTab) => ({\n role: 'tabpanel',\n id: panelId(tab),\n 'aria-labelledby': tabId(tab),\n className: 'ink-tab-panel',\n 'data-key': tab,\n hidden: s.tab !== tab,\n })\n const shown = s.name.trim() || SIGNATURE_LABELS.namePlaceholder\n\n return (\n <>\n <div\n role=\"tablist\"\n aria-label={SIGNATURE_LABELS.tabs}\n className=\"ink-tabs\"\n onKeyDown={(e) => handleTabKeys(e.nativeEvent, e.currentTarget)}\n >\n {SIGNATURE_TABS.map((tab) => (\n <button\n key={tab}\n type=\"button\"\n role=\"tab\"\n id={tabId(tab)}\n aria-controls={panelId(tab)}\n aria-selected={s.tab === tab}\n tabIndex={s.tab === tab ? 0 : -1}\n className=\"ink-tab\"\n data-key={tab}\n data-state={s.tab === tab ? 'active' : 'inactive'}\n onClick={() => draft.setTab(tab)}\n >\n {SIGNATURE_LABELS[tab]}\n </button>\n ))}\n </div>\n <div {...panel('draw')}>\n <div\n ref={padHost}\n className=\"ink-signature-pad-host\"\n data-ink-signature-pad-host=\"\"\n role=\"img\"\n aria-label={SIGNATURE_LABELS.pad}\n />\n <div className=\"ink-dialog-row\">\n <button\n type=\"button\"\n className=\"ink-button\"\n data-ink-signature-clear=\"\"\n disabled={s.padEmpty}\n onClick={() => draft.clearPad()}\n >\n {SIGNATURE_LABELS.clear}\n </button>\n </div>\n </div>\n <div {...panel('type')}>\n <label className=\"ink-field\">\n <span>{SIGNATURE_LABELS.name}</span>\n <input\n type=\"text\"\n className=\"ink-input\"\n data-ink-signature-name=\"\"\n autoComplete=\"name\"\n placeholder={SIGNATURE_LABELS.namePlaceholder}\n value={s.name}\n onChange={(e) => draft.setName(e.target.value)}\n />\n </label>\n <div\n role=\"radiogroup\"\n aria-label={SIGNATURE_LABELS.fonts}\n className=\"ink-signature-fonts\"\n onKeyDown={(e) => handleRadioKeys(e.nativeEvent, e.currentTarget)}\n >\n {draft.fonts.map((font) => (\n <button\n key={font}\n type=\"button\"\n role=\"radio\"\n aria-checked={s.font === font}\n aria-label={font}\n tabIndex={s.font === font ? 0 : -1}\n className=\"ink-signature-font\"\n data-key={font}\n data-state={s.font === font ? 'checked' : 'unchecked'}\n onClick={() => draft.setFont(font)}\n >\n {/* The font is the option itself, so it is set here, not left to the theme. */}\n <span\n className=\"ink-signature-font-sample\"\n style={{ fontFamily: fontFamilyValue(font) }}\n >\n {shown}\n </span>\n </button>\n ))}\n </div>\n </div>\n <div {...panel('image')}>\n <label className=\"ink-field\">\n <span>{SIGNATURE_LABELS.file}</span>\n <input\n type=\"file\"\n accept=\"image/png,image/jpeg\"\n className=\"ink-input\"\n data-ink-signature-file=\"\"\n onChange={(e) => void draft.chooseFile(e.target.files?.[0])}\n />\n </label>\n {s.image?.kind === 'image' ? (\n <img className=\"ink-signature-image\" src={s.image.imagedata} alt=\"\" />\n ) : null}\n {s.imageError ? (\n <p className=\"ink-field-error\" role=\"alert\">\n {s.imageError}\n </p>\n ) : null}\n </div>\n {s.saveError ? (\n <p className=\"ink-field-error\" role=\"alert\" data-ink-signature-save-error=\"\">\n {s.saveError}\n </p>\n ) : null}\n <div className=\"ink-dialog-actions\">\n <Dialog.Close asChild>\n <button type=\"button\" className=\"ink-button\" data-ink-signature-cancel=\"\">\n {SIGNATURE_LABELS.cancel}\n </button>\n </Dialog.Close>\n <button\n type=\"button\"\n className=\"ink-button\"\n data-variant=\"primary\"\n data-ink-signature-save=\"\"\n disabled={!s.canSave}\n onClick={save}\n >\n {SIGNATURE_LABELS.save}\n </button>\n </div>\n </>\n )\n}\n","/*\n * An icon from `@inkbar/icons`, hidden from assistive technology: the control it sits in\n * carries the name. The theme sizes it with `--ink-icon-size`.\n */\nimport { ICON_ATTRIBUTES } from '@inkbar/icons'\nimport { createElement, type SVGProps } from 'react'\n\nimport type { IconNode } from '@inkbar/icons'\n\nexport interface InkIconProps {\n icon: IconNode\n size?: number\n}\n\n/** `stroke-width` to `strokeWidth`: React names SVG attributes in camelCase. */\nconst camel = (name: string) =>\n name.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase())\n\nconst SVG_ATTRIBUTES = Object.fromEntries(\n Object.entries(ICON_ATTRIBUTES).map(([k, v]) => [camel(k), v])\n) as SVGProps<SVGSVGElement>\n\nexport function InkIcon({ icon, size = 18 }: InkIconProps) {\n return (\n <svg\n {...SVG_ATTRIBUTES}\n width={size}\n height={size}\n className=\"ink-icon\"\n aria-hidden=\"true\"\n >\n {icon.map(([tag, attrs], i) => createElement(tag, { key: i, ...attrs }))}\n </svg>\n )\n}\n","/*\n * The signature menu's items: the saved signatures as previews, each with a remove button,\n * then \"Create signature\", and the store's removal error. The toolbar's `InkSignatureMenu`\n * and a signature field's `InkSignFieldPopover` both render it inside their `role=\"menu\"`\n * content, which `menu` points at.\n */\nimport { signaturePreview, SIGNATURE_LABELS } from '@inkbar/core/dom'\nimport { Plus, Trash2 } from '@inkbar/icons'\nimport { useEffect, useRef, type RefObject } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { SignatureTemplate } from '@inkbar/core'\nimport type { SignatureMenuItem } from '@inkbar/core/dom'\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\n/** A saved signature drawn small: ink as filled outlines, an image as itself. */\nfunction SignaturePreview({ template }: { template: SignatureTemplate }) {\n if (template.kind === 'image')\n return (\n <span className=\"ink-signature-preview\" data-kind=\"image\">\n <img src={template.imagedata} alt=\"\" draggable={false} />\n </span>\n )\n const { viewBox, paths } = signaturePreview(template)\n return (\n <span className=\"ink-signature-preview\" data-kind=\"ink\">\n <svg viewBox={viewBox} aria-hidden=\"true\">\n {paths.map((d, i) => (\n <path key={i} d={d} fill=\"currentColor\" />\n ))}\n </svg>\n </span>\n )\n}\n\nexport function SignatureMenuPanel({\n items,\n menu,\n onChoose,\n onCreate,\n}: {\n items: readonly SignatureMenuItem[]\n /** The menu element the items sit in, for moving focus after a removal. */\n menu: RefObject<HTMLElement | null>\n onChoose: (template: SignatureTemplate) => void\n onCreate: () => void\n}) {\n const { signatures } = useInkContext('SignatureMenuPanel')\n const templates = useReadable(signatures.templates, NO_TEMPLATES)\n const removeError = useReadable(signatures.removeError, undefined)\n /** The row of a removed signature, until focus lands on what took its place. */\n const removedRow = useRef<number | null>(null)\n\n useEffect(() => {\n const row = removedRow.current\n const panel = menu.current\n if (row === null || !panel) return\n removedRow.current = null\n const rows = panel.querySelectorAll<HTMLElement>('.ink-signature-item')\n const next =\n rows[Math.min(row, rows.length - 1)] ??\n panel.querySelector<HTMLElement>('[data-ink-signature-create]')\n next?.focus({ preventScroll: true })\n }, [templates, menu])\n\n const remove = (id: string, row: number): void => {\n // Set first: the list may re-render before the removal's promise settles.\n removedRow.current = row\n signatures.remove(id).catch(() => {\n // The host's store refused: the signature stays.\n removedRow.current = null\n })\n }\n\n return (\n <>\n {items.length > 0 ? (\n <>\n <div\n role=\"group\"\n aria-label={SIGNATURE_LABELS.saved}\n className=\"ink-signature-list\"\n data-ink-menu-columns={2}\n >\n {items.map((item, row) => [\n <button\n key={`${item.id}-choose`}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={item.checked}\n aria-label={item.label}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item ink-signature-item\"\n data-ink-select-item=\"\"\n data-key={item.id}\n data-state={item.checked ? 'checked' : 'unchecked'}\n onClick={() => onChoose(item.template)}\n >\n <SignaturePreview template={item.template} />\n </button>,\n <button\n key={`${item.id}-remove`}\n type=\"button\"\n role=\"menuitem\"\n aria-label={item.removeLabel}\n title={item.removeLabel}\n tabIndex={-1}\n className=\"ink-menu-item ink-signature-remove\"\n data-ink-signature-remove=\"\"\n data-key={item.id}\n onClick={() => remove(item.id, row)}\n >\n <InkIcon icon={Trash2} size={16} />\n </button>,\n ])}\n </div>\n <div role=\"separator\" className=\"ink-select-separator\" />\n </>\n ) : null}\n <button\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item ink-signature-create\"\n data-ink-select-item=\"\"\n data-ink-signature-create=\"\"\n onClick={onCreate}\n >\n <InkIcon icon={Plus} size={16} />\n {SIGNATURE_LABELS.create}\n </button>\n {removeError ? (\n <p\n className=\"ink-field-error ink-signature-remove-error\"\n role=\"alert\"\n data-ink-signature-remove-error=\"\"\n >\n {removeError}\n </p>\n ) : null}\n </>\n )\n}\n","/*\n * The signature menu for a signature field, opened from the field's \"Sign\" button and anchored\n * to its box. It lists the saved signatures and \"Create signature\", as `InkSignatureMenu`\n * does. Picking one signs the field with it (`signField`); a signature made in\n * `InkSignatureDialog` signs the field once saved, without picking the signature tool. Focus\n * returns to the field. InkViewport mounts it, one per document; hosts compose nothing.\n */\nimport { InkError, signField, type SignatureTemplate } from '@inkbar/core'\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n SIGNATURE_LABELS,\n signatureMenuModel,\n watchDetached,\n type SignFieldRequest,\n} from '@inkbar/core/dom'\nimport { Popover } from 'radix-ui'\nimport { useEffect, useMemo, useRef, useState } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useLatest } from '../use-latest'\nimport { useReadable } from '../use-readable'\n\nimport { InkSignatureDialog } from './InkSignatureDialog'\nimport { SignatureMenuPanel } from './SignatureMenuPanel'\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\n/** The field's own button, which focus returns to. */\nconst control = (req: SignFieldRequest | null): HTMLElement | null =>\n req?.anchor.querySelector<HTMLElement>('button.ink-form-control') ?? null\n\nexport function InkSignFieldPopover({\n request,\n onClose,\n}: {\n /** The field to sign; `null` while the menu is closed. */\n request: SignFieldRequest | null\n onClose: () => void\n}) {\n const ctx = useInkContext('InkSignFieldPopover')\n const { signatures, reportError } = ctx\n const templates = useReadable(signatures.templates, NO_TEMPLATES)\n // No signature is \"chosen\" here: each signing picks its own.\n const model = useMemo(() => signatureMenuModel(templates, {}), [templates])\n /** The field the dialog signs once its signature is saved. */\n const [creatingFor, setCreatingFor] = useState<SignFieldRequest | null>(null)\n const menu = useRef<HTMLDivElement>(null)\n /**\n * The request the menu was last open for, kept to return focus once it closes. A request\n * that replaces the open one takes over, so focus returns to the field asked for last.\n */\n const last = useRef<SignFieldRequest | null>(null)\n /** Set while the menu closes for the dialog, which takes focus instead of the field. */\n const toDialog = useRef(false)\n const anchor = useMemo(() => ({ current: request?.anchor ?? null }), [request])\n const doc = ctx.document\n\n // An old removal error is not news when the menu opens again.\n useEffect(() => {\n if (request) signatures.clearRemoveError()\n }, [request, signatures])\n\n // The field's box went (its page unmounted, its layer rebuilt): the menu has nothing to\n // stand by.\n const close = useLatest(onClose)\n useEffect(() => {\n if (!request) return\n last.current = request\n return watchDetached(request.anchor, () => close.current())\n }, [request, close])\n\n /** Focus goes back to the field's button, or to the scroll element once the field's box has gone. */\n const returnFocus = (req: SignFieldRequest | null): void => {\n const c = control(req)\n ;(c?.isConnected ? c : ctx.viewportEl.get())?.focus({ preventScroll: true })\n }\n\n /** Signs the request's field with `t`; a refusal (signed, read-only by now) goes to `onError`. */\n const sign = (req: SignFieldRequest, t: SignatureTemplate): void => {\n if (!doc) return\n try {\n signField(doc, req.field, req.widget, t)\n } catch (e) {\n if (!(e instanceof InkError)) throw e\n reportError(e)\n }\n }\n\n return (\n <>\n <Popover.Root open={request !== null} onOpenChange={(next) => !next && onClose()}>\n <Popover.Anchor virtualRef={anchor} />\n <Popover.Portal>\n {request ? (\n <Popover.Content\n ref={menu}\n role=\"menu\"\n aria-label={SIGNATURE_LABELS.menu}\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"signature\"\n data-ink-sign-field-menu={request.field}\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n focusInitialMenuItem(e.currentTarget as HTMLElement)\n }}\n onCloseAutoFocus={(e) => {\n e.preventDefault()\n if (!toDialog.current) returnFocus(last.current)\n toDialog.current = false\n }}\n onInteractOutside={(e) => {\n // A press on this field's own button toggles the menu through the engine; it\n // must not also close it here first, or the click would open it again.\n const target = e.detail.originalEvent.target\n if (target instanceof Node && request.anchor.contains(target))\n e.preventDefault()\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n <SignatureMenuPanel\n items={model.items}\n menu={menu}\n onChoose={(t) => {\n onClose()\n sign(request, t)\n }}\n onCreate={() => {\n toDialog.current = true\n setCreatingFor(request)\n onClose()\n }}\n />\n </Popover.Content>\n ) : null}\n </Popover.Portal>\n </Popover.Root>\n <InkSignatureDialog\n open={creatingFor !== null}\n onOpenChange={(next) => {\n if (!next) setCreatingFor(null)\n }}\n select={false}\n onSave={(t) => {\n if (creatingFor) sign(creatingFor, t)\n }}\n onCloseAutoFocus={(e) => {\n e.preventDefault()\n returnFocus(last.current)\n }}\n />\n </>\n )\n}\n","/*\n * The scroll element is handed to core's `mountViewer`, which builds the viewport, the page\n * layers, the tool controller and the keyboard shortcuts in it; React never renders children\n * into it. The engine reports each page host it mounts, and InkPage components rendered here\n * portal the page-error and custom-annotation slots into them.\n *\n * Two-way zoom and page: the viewport's own changes are reported through the context, and\n * the host's props are applied only when they differ from the viewport's state, so the echo\n * of a reported value does nothing.\n *\n * Form fields render in the engine's form layer. A signature field's \"Sign\" opens\n * `InkSignFieldPopover`, and a form script's alert shows in `InkFormAlert`; both are mounted\n * here, so hosts compose nothing for them.\n */\nimport { mountViewer } from '@inkbar/core/dom'\nimport {\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { toolIdsOf } from '../hooks/useRegisteredTool'\nimport { useLatest } from '../use-latest'\n\nimport { InkFormAlert } from './InkFormAlert'\nimport { InkPage } from './InkPage'\nimport { InkSignFieldPopover } from './InkSignFieldPopover'\n\nimport type { InkDocument, InkError } from '@inkbar/core'\nimport type {\n AnnotationSlotProps,\n LayoutMode,\n PageMount,\n SignFieldRequest,\n ToolId,\n ViewerEngine,\n ViewRotation,\n ZoomValue,\n} from '@inkbar/core/dom'\n\nexport interface InkViewportProps extends ComponentPropsWithoutRef<'div'> {\n mode?: LayoutMode\n rotation?: ViewRotation\n /** Gap between pages, CSS px. */\n gap?: number\n /** Pages kept mounted either side of the visible ones. */\n buffer?: number\n loading?: ReactNode\n empty?: ReactNode\n error?: ReactNode | ((props: { error: InkError }) => ReactNode)\n renderAnnotation?: ((props: AnnotationSlotProps) => ReactNode) | undefined\n /** Shown inside a page that failed to render. The rest of the document stays usable. */\n renderPageError?: ((props: { error: InkError; page: number }) => ReactNode) | undefined\n}\n\ninterface MountedPage {\n /** The engine build the host belongs to; part of the InkPage key. */\n build: number\n page: number\n host: HTMLElement\n mount: PageMount\n error: InkError | null\n /** Whether the build that mounted the page renders the annotation slot. */\n custom: boolean\n}\n\n/** A key per document, so the field menu and its dialog start afresh for each one. */\nconst documentKeys = new WeakMap<InkDocument, number>()\nlet documentKeyCount = 0\nfunction documentKey(doc: InkDocument | null): number {\n if (!doc) return 0\n let key = documentKeys.get(doc)\n if (key === undefined) {\n key = ++documentKeyCount\n documentKeys.set(doc, key)\n }\n return key\n}\n\nexport function InkViewport({\n mode = 'continuous',\n rotation = 0,\n gap = 16,\n buffer = 2,\n loading,\n empty,\n error,\n renderAnnotation,\n renderPageError,\n className,\n ...rest\n}: InkViewportProps) {\n const ctx = useInkContext('InkViewport')\n const scroll = useRef<HTMLDivElement>(null)\n const custom = !!renderAnnotation\n const latest = useLatest({ ctx, mode, rotation, gap, buffer, custom })\n\n const engine = useRef<ViewerEngine | null>(null)\n /** Page hosts, mounts and errors the engine reported; InkPage renders portals for them. */\n const [pages, setPages] = useState<MountedPage[]>([])\n /**\n * Numbered before each build starts, so the pages a build mounts carry its own number. A\n * rebuild gives each page a new host and mount, so pages from an earlier build must remount,\n * not be reused.\n */\n const buildCount = useRef(0)\n /** The construction options the engine was last built with, so a rebuild runs only on a change. */\n const builtWith = useRef<{ gap: number; buffer: number; custom: boolean } | null>(null)\n /** The zoom and page last reported to the host. */\n const lastReportedZoom = useRef<ZoomValue | undefined>(undefined)\n const lastReportedPage = useRef<number | undefined>(undefined)\n /** The signature field whose menu is open. */\n const [signRequest, setSignRequest] = useState<SignFieldRequest | null>(null)\n /** The form script's message on show, and how many have been shown. */\n const [alert, setAlert] = useState<{ message: string; shown: number } | null>(null)\n\n // Build for a new document or status; tear down on the next change and on unmount.\n useEffect(() => {\n const { ctx: c, mode: m, rotation: r, gap: g, buffer: b, custom: cu } = latest.current\n const doc = c.document\n const el = scroll.current\n lastReportedZoom.current = undefined\n lastReportedPage.current = undefined\n if (!doc || !el || c.status.state !== 'ready') return\n let first = true\n let stops: (() => void)[] = []\n buildCount.current += 1\n builtWith.current = { gap: g, buffer: b, custom: cu }\n // The tools this viewer registers, from the same inputs; a later `tools` waits for a rebuild.\n c.setOpenedToolIds(toolIdsOf(c.hostTools, c.pluginHost))\n const e = mountViewer({\n container: el,\n document: doc,\n zoom: c.zoomModel ?? 'fit-width',\n ...(c.pageModel === undefined ? {} : { page: c.pageModel }),\n mode: m,\n rotation: r,\n gap: g,\n buffer: b,\n tool: c.tool,\n ...(c.hostTools ? { tools: c.hostTools } : {}),\n // The engine adds the plugins' tools and layers, and decorates through the host, which\n // reads `decorateAnnotation` first.\n ...(c.pluginHost ? { plugins: c.pluginHost } : {}),\n // The highlights draw from the shared search.\n ...(c.search ? { search: c.search } : {}),\n // Reads InkRoot's current prop; the effect below re-applies it when it changes.\n decorateAnnotation: (a) => latest.current.ctx.decorateAnnotation(a),\n ...(c.toolStyle ? { toolStyle: c.toolStyle } : {}),\n toolHistory: { batch: (fn) => latest.current.ctx.history.batch(fn) },\n toolOptions: c.toolOptions,\n fonts: [...c.fonts],\n // Read through, so a new `signatures` store reaches the tool as well as the menus.\n signatureLibrary: () => latest.current.ctx.signatures,\n customAnnotations: cu,\n ...(c.formHighlight === undefined ? {} : { formHighlight: c.formHighlight }),\n // The field's own button again, while its menu is open, closes the menu.\n onSignField: (req) =>\n setSignRequest((open) => (open?.widget === req.widget ? null : req)),\n onFormAction: (a) => latest.current.ctx.reportFormAction(a),\n onFormAlert: (message) =>\n setAlert((prev) => ({ message, shown: (prev?.shown ?? 0) + 1 })),\n onActivate: (id) => latest.current.ctx.setActivated(id),\n onBuild: (vp, tc) => {\n latest.current.ctx.setViewport(vp, tc)\n if (first) {\n // A new document starts from where the viewport opens (its zoom, on the first page);\n // only later changes are reported, the restored page among them.\n first = false\n lastReportedZoom.current = vp.zoom.get()\n lastReportedPage.current = 0\n }\n for (const stop of stops) stop()\n const reportZoom = (z: ZoomValue): void => {\n if (z === lastReportedZoom.current) return\n lastReportedZoom.current = z\n latest.current.ctx.reportZoom(z)\n }\n const reportPage = (p: number): void => {\n if (p === lastReportedPage.current) return\n lastReportedPage.current = p\n latest.current.ctx.reportPage(p)\n }\n // A tool that switches itself (a one-shot tool once used) is reported as a pick.\n const followTool = (id: ToolId): void => {\n if (id !== latest.current.ctx.tool) latest.current.ctx.setTool(id)\n }\n stops = [\n vp.zoom.subscribe(reportZoom),\n vp.currentPage.subscribe(reportPage),\n tc.active.subscribe(followTool),\n ]\n // Whatever the build restored is reported once; nothing is when it matched.\n reportZoom(vp.zoom.get())\n reportPage(vp.currentPage.get())\n },\n onPageMount: (page, mount, host) => {\n // `buildCount` and `builtWith` belong to the build in progress: both are set before it starts.\n const build = buildCount.current\n const custom = builtWith.current?.custom ?? false\n setPages((prev) => [...prev, { build, page, host, mount, error: null, custom }])\n },\n onPageUnmount: (page) => setPages((prev) => prev.filter((p) => p.page !== page)),\n onPageError: (page, err) =>\n setPages((prev) => prev.map((p) => (p.page === page ? { ...p, error: err } : p))),\n })\n engine.current = e\n return () => {\n for (const stop of stops) stop()\n e.destroy()\n engine.current = null\n builtWith.current = null\n c.setViewport(null, null)\n c.setOpenedToolIds(null)\n setPages((prev) => (prev.length === 0 ? prev : []))\n // Their fields and the document they came from are gone.\n setSignRequest(null)\n setAlert(null)\n }\n }, [ctx.document, ctx.status.state, ctx.pluginHost, ctx.search, latest])\n\n // The plugins' `root`. A layout effect, so it is set before the build above runs.\n const { viewportEl } = ctx\n useLayoutEffect(() => {\n const el = scroll.current\n viewportEl.set(el)\n return () => {\n if (viewportEl.get() === el) viewportEl.set(null)\n }\n }, [viewportEl])\n\n // A new decorateAnnotation re-applies to the mounted annotation elements at once.\n const { onDecorateAnnotationChange } = ctx\n useEffect(\n () => onDecorateAnnotationChange(() => engine.current?.redecorate()),\n [onDecorateAnnotationChange]\n )\n\n // Construction-only options rebuild the engine for the same document, keeping zoom and page.\n useEffect(() => {\n const built = builtWith.current\n if (!engine.current || !built) return\n if (built.gap === gap && built.buffer === buffer && built.custom === custom) return\n buildCount.current += 1\n builtWith.current = { gap, buffer, custom }\n engine.current.rebuild({ gap, buffer, customAnnotations: custom })\n }, [gap, buffer, custom])\n\n useEffect(() => {\n const vp = engine.current?.viewport\n const z = ctx.zoomModel\n if (vp && z !== undefined && z !== vp.zoom.get()) vp.setZoom(z)\n }, [ctx.zoomModel])\n useEffect(() => {\n const vp = engine.current?.viewport\n const p = ctx.pageModel\n if (!vp || p === undefined || p === lastReportedPage.current) return\n if (p !== vp.currentPage.get()) vp.scrollToPage(p)\n }, [ctx.pageModel])\n useEffect(() => {\n const tc = engine.current?.tools\n if (tc && tc.active.get() !== ctx.tool) tc.set(ctx.tool)\n }, [ctx.tool])\n // The tint follows `formHighlight` in place, without a new document.\n useEffect(() => {\n engine.current?.setFormHighlight(ctx.formHighlight ?? true)\n }, [ctx.formHighlight])\n // The build applied both; these only act on a later change, not on mount.\n useEffect(() => {\n const vp = engine.current?.viewport\n if (vp && vp.mode.get() !== mode) vp.setMode(mode)\n }, [mode])\n useEffect(() => {\n const vp = engine.current?.viewport\n if (vp && vp.rotation.get() !== rotation) vp.setRotation(rotation)\n }, [rotation])\n\n const state = ctx.status.state\n const err = ctx.status.state === 'error' ? ctx.status.error : null\n\n return (\n <div\n {...rest}\n className={cx('ink-viewport-root', className)}\n data-ink-viewport-root=\"\"\n data-state={state}\n >\n {state === 'loading' ? (\n <div className=\"ink-status\" role=\"status\" aria-live=\"polite\">\n {loading === undefined ? 'Loading document…' : loading}\n </div>\n ) : err ? (\n <div className=\"ink-status ink-error\" role=\"alert\">\n {typeof error === 'function' ? (\n error({ error: err })\n ) : error !== undefined ? (\n error\n ) : (\n <>\n <p className=\"ink-error-title\">This document could not be opened.</p>\n {/* The message comes from the PDF engine and is not written for readers: it stays\n off the page, on the code's tooltip. */}\n <p>\n <code className=\"ink-error-code\" title={err.message}>\n {err.code}\n </code>\n </p>\n </>\n )}\n </div>\n ) : state === 'idle' ? (\n <div className=\"ink-status ink-empty\">{empty}</div>\n ) : null}\n <div\n ref={scroll}\n className=\"ink-scroll\"\n data-ink-scroll=\"\"\n tabIndex={0}\n role=\"document\"\n aria-label=\"Document\"\n />\n {pages.map((p) => (\n <InkPage\n key={`${p.build}:${p.page}`}\n page={p.page}\n host={p.host}\n mount={p.mount}\n error={p.error}\n customAnnotations={p.custom}\n renderAnnotation={renderAnnotation}\n renderPageError={renderPageError}\n />\n ))}\n <InkSignFieldPopover\n key={documentKey(ctx.document)}\n request={signRequest}\n onClose={() => setSignRequest(null)}\n />\n <InkFormAlert\n message={alert?.message ?? null}\n shown={alert?.shown ?? 0}\n fallback={() => scroll.current}\n onClose={() => setAlert(null)}\n />\n </div>\n )\n}\n","import { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport interface InkToolbarProps extends Omit<ComponentPropsWithoutRef<'div'>, 'dir'> {\n /** Radix narrows text direction to these two values. */\n dir?: 'ltr' | 'rtl'\n label?: string\n asChild?: boolean\n}\n\nexport function InkToolbar({\n label = 'Document tools',\n asChild = false,\n className,\n children,\n ...rest\n}: InkToolbarProps) {\n return (\n <Toolbar.Root\n asChild={asChild}\n orientation=\"horizontal\"\n aria-label={label}\n data-ink-toolbar=\"\"\n className={cx('ink-toolbar', className)}\n {...rest}\n >\n {children}\n </Toolbar.Root>\n )\n}\n","import { TOOL_LABELS, withHostTools, type ToolId } from '@inkbar/core/dom'\nimport { SquareDashedMousePointer, TextCursor } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useRegisteredTool } from '../hooks/useRegisteredTool'\nimport { useTool } from '../hooks/useTool'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { IconNode } from '@inkbar/icons'\nimport type { ComponentPropsWithoutRef, ReactNode } from 'react'\n\nconst ICONS: Readonly<Partial<Record<ToolId, IconNode>>> = {\n 'select-text': TextCursor,\n select: SquareDashedMousePointer,\n}\n\nconst MISSING = {\n disabled: true,\n 'aria-hidden': true,\n 'aria-pressed': undefined,\n 'aria-label': undefined,\n title: undefined,\n onClick: undefined,\n} as const\n\nexport interface InkToolButtonProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n tool: ToolId\n label?: string | undefined\n asChild?: boolean\n children?: ReactNode | ((props: { active: boolean; label: string }) => ReactNode)\n}\n\nexport function InkToolButton({\n tool,\n label,\n asChild = false,\n className,\n children,\n onClick,\n ...rest\n}: InkToolButtonProps) {\n const { hostTools, pluginHost } = useInkContext('InkToolButton')\n const { tool: current, setTool } = useTool()\n const active = current === tool\n const registered = useRegisteredTool(tool)\n /** The registered tool by this id, for the name and icon core has none for. */\n const own = withHostTools([...(hostTools ?? []), ...(pluginHost?.tools ?? [])]).find(\n (t) => t.id === tool\n )\n // `label` and `children` win; then core's name and icon; then the tool's own.\n const name = label ?? TOOL_LABELS[tool] ?? own?.label ?? tool\n const icon = ICONS[tool] ?? own?.icon\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-tool-button', className)}\n data-ink-tool-button=\"\"\n data-tool={tool}\n data-state={active ? 'on' : 'off'}\n aria-pressed={active}\n aria-label={name}\n title={name}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) setTool(tool)\n }}\n {...rest}\n // A tool nobody registered leaves the button disabled, hidden from assistive tech and\n // unnamed, whatever the host passed.\n {...(registered ? {} : MISSING)}\n >\n {!registered\n ? null\n : typeof children === 'function'\n ? children({ active, label: name })\n : (children ?? (icon ? <InkIcon icon={icon} /> : null))}\n </Toolbar.Button>\n )\n}\n","/*\n * A plugin command as a toolbar button with its status beside it: the markup of core's\n * `createCommandButton`, so the theme styles both alike. The button is named by the command's\n * label and disabled while the command is, except while it runs: then it keeps focus, with\n * `aria-busy` and `aria-disabled`, and a press does nothing. The status is a live region. A command without an icon shows its label as the button's text. Until the plugins\n * are set up (once InkRoot has mounted; never on the server) the button is disabled and\n * `aria-hidden`. An id no plugin registered stays that way and logs `InkError('UnknownCommand')`\n * to the console once.\n */\nimport { Toolbar } from 'radix-ui'\n\nimport { useCommand } from '../hooks/useCommand'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { ComponentPropsWithoutRef, ReactNode } from 'react'\n\nexport interface InkCommandProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'id' | 'children'\n> {\n /** The command's namespaced id, such as `sandbox.suggest`. */\n id: string\n asChild?: boolean\n children?: ReactNode | ((props: { label: string; busy: boolean }) => ReactNode)\n}\n\nexport function InkCommand({\n id,\n asChild = false,\n children,\n disabled,\n onClick,\n ...rest\n}: InkCommandProps) {\n const { run, enabled, busy, status, label, icon } = useCommand(id)\n return (\n <div className=\"ink-command\">\n <Toolbar.Button\n asChild={asChild}\n type=\"button\"\n data-command={id}\n // No label until the plugins are set up: the disabled button stays out of the\n // accessibility tree rather than go unnamed.\n aria-label={label || undefined}\n title={label || undefined}\n aria-hidden={label ? undefined : true}\n aria-busy={busy}\n // Disabled while it runs, but not `disabled`, so the button keeps focus.\n aria-disabled={busy || undefined}\n {...rest}\n disabled={disabled === true || (!enabled && !busy)}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) void run()\n }}\n >\n {typeof children === 'function'\n ? children({ label, busy })\n : (children ?? (icon ? <InkIcon icon={icon} /> : label))}\n </Toolbar.Button>\n <span className=\"ink-command-status\" role=\"status\">\n {status}\n </span>\n </div>\n )\n}\n","import { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport interface InkToolbarButtonProps extends ComponentPropsWithoutRef<'button'> {\n asChild?: boolean\n}\n\n/**\n * Your own button in an `InkToolbar`. It joins the toolbar's arrow-key focus and takes the\n * theme's toolbar button styles; what it shows and does is up to you.\n */\nexport function InkToolbarButton({\n asChild = false,\n type = 'button',\n className,\n ...rest\n}: InkToolbarButtonProps) {\n return (\n <Toolbar.Button\n asChild={asChild}\n type={type}\n className={cx('ink-toolbar-button', className)}\n data-ink-toolbar-button=\"\"\n {...rest}\n />\n )\n}\n","import { cx } from '../class-names'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport type InkToolbarSeparatorProps = ComponentPropsWithoutRef<'div'>\n\n/**\n * A divider between groups of controls in a horizontal toolbar. Not focusable. A plain div\n * rather than Radix's separator, which reads as horizontal inside a horizontal toolbar.\n */\nexport function InkToolbarSeparator({ className, ...rest }: InkToolbarSeparatorProps) {\n return (\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n className={cx('ink-toolbar-separator', className)}\n data-ink-toolbar-separator=\"\"\n {...rest}\n />\n )\n}\n","import { Undo2 } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useHistory } from '../hooks/useHistory'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkHistoryButtonProps } from './history-button'\n\nexport function InkUndo({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkHistoryButtonProps) {\n const { canUndo, undo } = useHistory()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-undo', className)}\n data-ink-undo=\"\"\n aria-label=\"Undo\"\n title=\"Undo\"\n {...rest}\n disabled={disabled === true || !canUndo}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) undo()\n }}\n >\n {children ?? <InkIcon icon={Undo2} />}\n </Toolbar.Button>\n )\n}\n","import { downloadDocument } from '@inkbar/core/dom'\nimport { Download } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport interface InkDownloadButtonProps extends ComponentPropsWithoutRef<'button'> {\n asChild?: boolean\n /** The name to save under. Default: the document's `fileName`. */\n filename?: string | undefined\n}\n\n/**\n * Saves the open document's file through the browser's download, under its `fileName` or\n * `filename`. Disabled until the document is ready. Today that is the file as it was opened,\n * without this session's annotations.\n */\nexport function InkDownloadButton({\n asChild = false,\n filename,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkDownloadButtonProps) {\n const { document: doc, status } = useInkContext('InkDownloadButton')\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-download', className)}\n data-ink-download=\"\"\n aria-label=\"Download\"\n title=\"Download\"\n {...rest}\n disabled={disabled === true || doc === null || status.state !== 'ready'}\n onClick={(e) => {\n onClick?.(e)\n if (e.defaultPrevented || !doc) return\n void downloadDocument(doc, filename === undefined ? {} : { filename }).catch(\n () => undefined\n )\n }}\n >\n {children ?? <InkIcon icon={Download} />}\n </Toolbar.Button>\n )\n}\n","import { printDocument } from '@inkbar/core/dom'\nimport { Printer } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport interface InkPrintButtonProps extends ComponentPropsWithoutRef<'button'> {\n asChild?: boolean\n}\n\n/**\n * Prints the open document's file with the browser's own PDF viewer (on iOS, in a new tab).\n * Disabled until the document is ready. Today that is the file as it was opened, without this\n * session's annotations.\n */\nexport function InkPrintButton({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkPrintButtonProps) {\n const { document: doc, status } = useInkContext('InkPrintButton')\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-print', className)}\n data-ink-print=\"\"\n aria-label=\"Print\"\n title=\"Print\"\n {...rest}\n disabled={disabled === true || doc === null || status.state !== 'ready'}\n onClick={(e) => {\n onClick?.(e)\n if (e.defaultPrevented || !doc) return\n void printDocument(doc).catch(() => undefined)\n }}\n >\n {children ?? <InkIcon icon={Printer} />}\n </Toolbar.Button>\n )\n}\n","import { Redo2 } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useHistory } from '../hooks/useHistory'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkHistoryButtonProps } from './history-button'\n\nexport function InkRedo({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkHistoryButtonProps) {\n const { canRedo, redo } = useHistory()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-redo', className)}\n data-ink-redo=\"\"\n aria-label=\"Redo\"\n title=\"Redo\"\n {...rest}\n disabled={disabled === true || !canRedo}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) redo()\n }}\n >\n {children ?? <InkIcon icon={Redo2} />}\n </Toolbar.Button>\n )\n}\n","import { Search } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\nimport { flushSync } from 'react-dom'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useDocument } from '../hooks/useDocument'\nimport { useSearch } from '../hooks/useSearch'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport type InkSearchButtonProps = ComponentPropsWithoutRef<typeof Toolbar.Button>\n\n/**\n * Opens the find bar; pressed while it is open. Pressing it again focuses the field. Place it\n * in a toolbar next to `InkFindBar`, which it needs for the field to focus. Disabled until a\n * document is open.\n */\nexport function InkSearchButton({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkSearchButtonProps) {\n const { rootEl } = useInkContext('InkSearchButton')\n const { state, open } = useSearch()\n const { isReady } = useDocument()\n return (\n <Toolbar.Button\n {...rest}\n asChild={asChild}\n className={cx('ink-search-button', className)}\n data-ink-search-button=\"\"\n aria-label=\"Find\"\n title=\"Find\"\n aria-pressed={state.open}\n data-state={state.open ? 'on' : 'off'}\n disabled={!isReady || !!disabled}\n onClick={(e) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n // The bar shows once this render commits; its field takes focus then.\n flushSync(() => open())\n const field = rootEl?.querySelector<HTMLInputElement>('[data-ink-find-bar] input')\n field?.focus()\n field?.select()\n }}\n >\n {children ?? <InkIcon icon={Search} />}\n </Toolbar.Button>\n )\n}\n","import { findAnnouncer, findCountText } from '@inkbar/core/dom'\nimport { CaseSensitive, ChevronDown, ChevronUp, Search, X } from '@inkbar/icons'\nimport { useEffect, useLayoutEffect, useRef, type ComponentPropsWithoutRef } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useSearch } from '../hooks/useSearch'\nimport { useReadable } from '../use-readable'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { SearchState } from '@inkbar/core/dom'\n\nexport type InkFindBarProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'>\n\n/**\n * The find bar: a field, the match count, previous and next, a match-case toggle and close,\n * a view of the root's search state. Place it anywhere inside `InkRoot`: it portals itself\n * into `[data-ink-viewport-root]`, the positioned ancestor the theme floats it from over the\n * top-right of the pages (as `InkThreadPopover` anchors to the root's overlay rather than\n * where it is written). It renders nothing until `InkViewport` has mounted, and is hidden\n * while the search is closed. While it is mounted it registers with the search controller,\n * which is what lets Ctrl/Cmd+F open it.\n *\n * Enter in the field steps to the next match, Shift+Enter to the previous, Escape closes.\n * Closing returns focus to where it was before the bar opened, else to the document.\n */\nexport function InkFindBar({ className, ...rest }: InkFindBarProps) {\n const ctx = useInkContext('InkFindBar')\n const { state, setQuery, setMatchCase, next, previous, close } = useSearch()\n const scroll = useReadable(ctx.viewportEl, null)\n /** The viewport root: the scroll element's parent, once InkViewport has mounted. */\n const target = scroll?.parentElement ?? null\n const bar = useRef<HTMLDivElement>(null)\n const field = useRef<HTMLInputElement>(null)\n const live = useRef<HTMLDivElement>(null)\n /** Where focus was when the bar opened, and whether it was open on the last pass. */\n const before = useRef<HTMLElement | null>(null)\n const wasOpen = useRef(false)\n\n // After the commit, so the bar is shown (and can take focus) when it opens.\n useLayoutEffect(() => {\n const el = bar.current\n const input = field.current\n if (!el || !input) return\n if (state.open !== wasOpen.current) {\n wasOpen.current = state.open\n const doc = el.ownerDocument\n if (state.open) {\n const active = doc.activeElement\n before.current =\n active instanceof HTMLElement && active !== doc.body && !el.contains(active)\n ? active\n : null\n input.focus()\n input.select()\n } else {\n // Focus inside the bar is about to be lost with it; focus elsewhere is left alone.\n const hadFocus = el.contains(doc.activeElement) || doc.activeElement === doc.body\n if (hadFocus) {\n const to =\n before.current?.isConnected && !el.contains(before.current)\n ? before.current\n : scroll\n to?.focus({ preventScroll: true })\n }\n before.current = null\n }\n }\n if (input.value !== state.query) {\n input.value = state.query\n // A query set from code arrives after the bar opened: keep the new text selected.\n if (el.ownerDocument.activeElement === input) input.select()\n }\n }, [state.open, state.query, scroll])\n\n // Registered while mounted.\n const { search } = ctx\n useEffect(() => {\n if (!search || !target) return\n return search.attachBar()\n }, [search, target])\n\n // The live region follows the controller's state change by change, as the vanilla bar does,\n // and is written directly. A render shows only the last of the changes batched into it, so\n // two steps in one task that end where they began would otherwise say nothing.\n useEffect(() => {\n const el = live.current\n if (!search || !el) return\n const announce = findAnnouncer()\n const say = (s: SearchState): void => {\n const text = announce(s)\n if (el.textContent !== text) el.textContent = text\n }\n say(search.state.get())\n return search.state.subscribe(say)\n }, [search, target])\n\n // A native listener, so Escape stops at the bar as it does in the vanilla and Vue bars;\n // React's delegated events would stop it only after the root's own listeners saw it.\n useEffect(() => {\n const el = bar.current\n if (!search || !el) return\n const onKeyDown = (e: globalThis.KeyboardEvent): void => {\n if (e.key !== 'Escape' || e.defaultPrevented || e.isComposing) return\n e.preventDefault()\n e.stopPropagation()\n search.close()\n }\n el.addEventListener('keydown', onKeyDown)\n return () => el.removeEventListener('keydown', onKeyDown)\n }, [search, target])\n\n if (!target) return null\n\n return createPortal(\n <div\n {...rest}\n ref={bar}\n className={cx('ink-find-bar', className)}\n data-ink-find-bar=\"\"\n role=\"search\"\n hidden={!state.open}\n >\n <div className=\"ink-input-group\">\n <span className=\"ink-input-accessory\">\n <InkIcon icon={Search} />\n </span>\n <input\n ref={field}\n type=\"text\"\n aria-label=\"Find in document\"\n autoComplete=\"off\"\n spellCheck={false}\n onInput={(e) => setQuery(e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key !== 'Enter' || e.nativeEvent.isComposing) return\n e.preventDefault()\n if (e.shiftKey) previous()\n else next()\n }}\n />\n </div>\n <span className=\"ink-find-count\" data-ink-find-count=\"\">\n {findCountText(state)}\n </span>\n <button\n type=\"button\"\n data-ink-find-previous=\"\"\n aria-label=\"Previous match\"\n title=\"Previous match\"\n onClick={() => previous()}\n >\n <InkIcon icon={ChevronUp} />\n </button>\n <button\n type=\"button\"\n data-ink-find-next=\"\"\n aria-label=\"Next match\"\n title=\"Next match\"\n onClick={() => next()}\n >\n <InkIcon icon={ChevronDown} />\n </button>\n <button\n type=\"button\"\n data-ink-find-match-case=\"\"\n aria-label=\"Match case\"\n title=\"Match case\"\n aria-pressed={state.matchCase}\n onClick={() => setMatchCase(!state.matchCase)}\n >\n <InkIcon icon={CaseSensitive} />\n </button>\n <button\n type=\"button\"\n data-ink-find-close=\"\"\n aria-label=\"Close find\"\n title=\"Close find\"\n onClick={() => close()}\n >\n <InkIcon icon={X} />\n </button>\n <div\n ref={live}\n className=\"ink-visually-hidden\"\n data-ink-find-status=\"\"\n aria-live=\"polite\"\n />\n </div>,\n target\n )\n}\n","import { ZoomIn } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useZoom } from '../hooks/useZoom'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkZoomButtonProps } from './zoom-button'\n\nexport function InkZoomIn({\n asChild = false,\n className,\n children,\n onClick,\n ...rest\n}: InkZoomButtonProps) {\n const { zoomIn } = useZoom()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-zoom-in', className)}\n data-ink-zoom-in=\"\"\n aria-label=\"Zoom in\"\n title=\"Zoom in\"\n {...rest}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) zoomIn()\n }}\n >\n {children ?? <InkIcon icon={ZoomIn} />}\n </Toolbar.Button>\n )\n}\n","import { ZoomOut } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useZoom } from '../hooks/useZoom'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkZoomButtonProps } from './zoom-button'\n\nexport function InkZoomOut({\n asChild = false,\n className,\n children,\n onClick,\n ...rest\n}: InkZoomButtonProps) {\n const { zoomOut } = useZoom()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-zoom-out', className)}\n data-ink-zoom-out=\"\"\n aria-label=\"Zoom out\"\n title=\"Zoom out\"\n {...rest}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) zoomOut()\n }}\n >\n {children ?? <InkIcon icon={ZoomOut} />}\n </Toolbar.Button>\n )\n}\n","import { ZOOM_LEVELS, type ZoomValue } from '@inkbar/core/dom'\nimport { Check, ChevronDown } from '@inkbar/icons'\nimport { Select } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { useZoom } from '../hooks/useZoom'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nconst CUSTOM = 'custom:'\nconst level = (z: number) => ZOOM_LEVELS.find((l) => Math.abs(l - z) < 0.001)\nconst percent = (z: number) => `${Math.round(z * 100)}%`\n\nconst FITS = [\n { value: 'fit-width', label: 'Fit width' },\n { value: 'fit-page', label: 'Fit page' },\n]\n\n/** Props of the select's trigger button; the options come from the zoom levels. */\nexport type InkZoomSelectProps = Omit<\n ComponentPropsWithoutRef<typeof Select.Trigger>,\n 'children' | 'asChild'\n>\n\nfunction Item({ value, label }: { value: string; label: string }) {\n return (\n <Select.Item value={value} className=\"ink-select-item\" data-ink-select-item=\"\">\n <Select.ItemText>{label}</Select.ItemText>\n <Select.ItemIndicator className=\"ink-select-indicator\">\n <InkIcon icon={Check} size={16} />\n </Select.ItemIndicator>\n </Select.Item>\n )\n}\n\nexport function InkZoomSelect({ className, ...rest }: InkZoomSelectProps) {\n const { zoom, scale, setZoom } = useZoom()\n /** A numeric zoom that is not one of the levels (zoom in and out multiply). */\n const custom = typeof zoom === 'number' && level(zoom) === undefined ? zoom : null\n const value =\n typeof zoom !== 'number'\n ? zoom\n : custom === null\n ? String(level(zoom))\n : `${CUSTOM}${zoom}`\n /** The levels, with a custom zoom in its place among them. */\n const levels = ZOOM_LEVELS.map((l) => ({ z: l, value: String(l), label: percent(l) }))\n if (custom !== null)\n levels.push({ z: custom, value: `${CUSTOM}${custom}`, label: percent(scale) })\n levels.sort((a, b) => a.z - b.z)\n\n function onValueChange(v: string): void {\n if (v === value) return\n const next: ZoomValue =\n v === 'fit-width' || v === 'fit-page' ? v : Number(v.replace(CUSTOM, ''))\n setZoom(next)\n }\n return (\n <Select.Root value={value} onValueChange={onValueChange}>\n <Select.Trigger\n className={cx('ink-select ink-select-trigger ink-zoom-select', className)}\n data-ink-zoom-select=\"\"\n aria-label=\"Zoom\"\n {...rest}\n >\n <Select.Value className=\"ink-select-value\" />\n <Select.Icon className=\"ink-select-icon\">\n <InkIcon icon={ChevronDown} size={16} />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n className=\"ink-select-content\"\n data-ink-select-content=\"\"\n position=\"popper\"\n side=\"top\"\n sideOffset={4}\n >\n <Select.Viewport>\n {FITS.map((o) => (\n <Item key={o.value} value={o.value} label={o.label} />\n ))}\n <Select.Separator className=\"ink-select-separator\" />\n {levels.map((o) => (\n <Item key={o.value} value={o.value} label={o.label} />\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n )\n}\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { usePage } from '../hooks/usePage'\nimport { useLatest } from '../use-latest'\n\nexport type InkPageInputProps = Omit<\n ComponentPropsWithoutRef<'input'>,\n 'value' | 'onChange' | 'type' | 'min' | 'max'\n>\n\nexport function InkPageInput({\n className,\n onKeyDown: onKeyDownProp,\n ...rest\n}: InkPageInputProps) {\n const { current, count, goTo } = usePage()\n const [draft, setDraft] = useState(String(current + 1))\n useEffect(() => {\n setDraft(String(current + 1))\n }, [current])\n const input = useRef<HTMLInputElement>(null)\n const latest = useLatest({ current, count, goTo })\n\n /** 1-based in the input, 0-based in the viewport. Out of range resets to the current page. */\n const commit = useCallback(\n (value: string) => {\n const { current: page, count: total, goTo: go } = latest.current\n const n = Number(value)\n if (Number.isInteger(n) && n >= 1 && n <= total) {\n if (n - 1 !== page) go(n - 1)\n } else setDraft(String(page + 1))\n },\n [latest]\n )\n // The native `change` event fires when an edit is committed: on blur after typing, and on\n // each step of the spinner or the arrow keys. React's `onChange` is the `input` event, which\n // fires for every keystroke, so the commit listens to the DOM event itself.\n useEffect(() => {\n const el = input.current\n if (!el) return\n const onNativeChange = (): void => commit(el.value)\n el.addEventListener('change', onNativeChange)\n return () => el.removeEventListener('change', onNativeChange)\n }, [commit])\n\n function onKeyDown(e: KeyboardEvent<HTMLInputElement>): void {\n onKeyDownProp?.(e)\n if (e.defaultPrevented || e.key !== 'Enter') return\n e.preventDefault()\n commit(draft)\n }\n return (\n <input\n ref={input}\n className={cx('ink-page-input', className)}\n data-ink-page-input=\"\"\n type=\"number\"\n inputMode=\"numeric\"\n aria-label=\"Page\"\n min={1}\n max={count}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={onKeyDown}\n {...rest}\n />\n )\n}\n","import { cx } from '../class-names'\nimport { usePage } from '../hooks/usePage'\n\nimport type { ComponentPropsWithoutRef } from 'react'\n\nexport function InkPageCount({ className, ...rest }: ComponentPropsWithoutRef<'span'>) {\n const { count } = usePage()\n return (\n <span\n className={cx('ink-page-count', className)}\n data-ink-page-count=\"\"\n aria-live=\"polite\"\n {...rest}\n >\n {`of ${count}`}\n </span>\n )\n}\n","import { ChevronLeft } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { usePage } from '../hooks/usePage'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkPageButtonProps } from './page-button'\n\nexport function InkPrevPage({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkPageButtonProps) {\n const { current, previous } = usePage()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-prev-page', className)}\n data-ink-prev-page=\"\"\n aria-label=\"Previous page\"\n title=\"Previous page\"\n disabled={disabled === true || current <= 0}\n {...rest}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) previous()\n }}\n >\n {children ?? <InkIcon icon={ChevronLeft} />}\n </Toolbar.Button>\n )\n}\n","import { ChevronRight } from '@inkbar/icons'\nimport { Toolbar } from 'radix-ui'\n\nimport { cx } from '../class-names'\nimport { usePage } from '../hooks/usePage'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { InkPageButtonProps } from './page-button'\n\nexport function InkNextPage({\n asChild = false,\n className,\n children,\n disabled,\n onClick,\n ...rest\n}: InkPageButtonProps) {\n const { current, count, next } = usePage()\n return (\n <Toolbar.Button\n asChild={asChild}\n className={cx('ink-next-page', className)}\n data-ink-next-page=\"\"\n aria-label=\"Next page\"\n title=\"Next page\"\n disabled={disabled === true || current >= count - 1}\n {...rest}\n onClick={(e) => {\n onClick?.(e)\n if (!e.defaultPrevented) next()\n }}\n >\n {children ?? <InkIcon icon={ChevronRight} />}\n </Toolbar.Button>\n )\n}\n","/*\n * A colour menu for one colour property (border, fill or text) of the selection or the active\n * tool. The trigger shows the current colour as a swatch: split when the selection disagrees,\n * slashed for no fill. The panel is a palette grid, plus \"No fill\" for `fill` and \"Custom…\",\n * which opens a native colour input. The menu disables when nothing supports the property.\n */\nimport {\n COLOR_COLUMNS,\n colorMenuModel,\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n type ColorProperty,\n} from '@inkbar/core/dom'\nimport { Check } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport {\n Fragment,\n useCallback,\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type CSSProperties,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useToolStyle } from '../hooks/useToolStyle'\n\nimport { InkIcon } from './InkIcon'\n\nimport type { StyleGroup } from '@inkbar/core'\n\nexport interface InkColorMenuProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n /** The colour this menu sets. */\n property: ColorProperty\n /** Accessible name; defaults to \"Border colour\", \"Fill colour\" or \"Text colour\". */\n label?: string\n /** Replaces the swatch. */\n children?: ReactNode\n /**\n * Renders the trigger outside the toolbar's roving focus, for a menu nested in another\n * panel (the text style menu's text colour).\n */\n standalone?: boolean\n /**\n * Scopes the menu to one style group: it shows and sets that group's colour whatever tool\n * is active, and recolours the selection only when it is all in the group.\n */\n group?: StyleGroup\n /** The colour new annotations get while the style leaves it unset; the swatch shows it. */\n fallback?: string | undefined\n}\n\nexport function InkColorMenu({\n property,\n label,\n className,\n children,\n standalone = false,\n group,\n fallback,\n disabled,\n ...rest\n}: InkColorMenuProps) {\n const Wrap = standalone ? Fragment : Toolbar.Button\n const { current, supported, set } = useToolStyle(group)\n const [open, setOpen] = useState(false)\n const model = colorMenuModel(property, current, supported, fallback)\n const name = label ?? model.label\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n const input = useRef<HTMLInputElement | null>(null)\n // The native `change` fires once the picker commits; React's `onChange` fires on every drag.\n const apply = useRef((_hex: string) => {})\n apply.current = (hex) => set(model.custom(hex))\n const bindInput = useCallback((el: HTMLInputElement | null) => {\n input.current = el\n el?.addEventListener('change', () => apply.current(el.value))\n }, [])\n // The input outlives the panel, so it follows the current colour rather than mount time.\n useEffect(() => {\n if (input.current) input.current.value = model.customValue.toLowerCase()\n }, [model.customValue])\n // The menu closes when the control disables (the selection cleared while it was open).\n useEffect(() => {\n if (!model.enabled) setOpen(false)\n }, [model.enabled])\n const trigger = model.trigger\n const swatchStyle =\n trigger.kind === 'color'\n ? ({ '--ink-swatch': trigger.color } as CSSProperties)\n : undefined\n return (\n <>\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Wrap {...(standalone ? {} : { asChild: true })}>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className={cx('ink-menu-trigger ink-color-menu', className)}\n data-ink-color-menu={property}\n data-state={open ? 'open' : 'closed'}\n data-mixed={model.mixed ? '' : undefined}\n aria-label={name}\n title={name}\n aria-haspopup=\"menu\"\n disabled={disabled === true || !model.enabled}\n {...rest}\n onKeyDown={(e) => {\n rest.onKeyDown?.(e)\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open || !model.enabled)\n return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n {children ?? (\n <span\n className=\"ink-swatch\"\n data-ink-swatch=\"\"\n data-property={property}\n data-kind={trigger.kind}\n data-color={trigger.kind === 'color' ? trigger.color : undefined}\n style={swatchStyle}\n aria-hidden=\"true\"\n />\n )}\n </button>\n </Popover.Trigger>\n </Wrap>\n <Popover.Portal>\n <Popover.Content\n role=\"menu\"\n aria-label={name}\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu={`color-${property}`}\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const menu = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n focusFirst.current = false\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n {model.noFill ? (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={model.noFill.checked}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item\"\n data-ink-select-item=\"\"\n data-state={model.noFill.checked ? 'checked' : 'unchecked'}\n onClick={() => set(model.noFill!.patch)}\n >\n No fill\n {model.noFill.checked ? (\n <span className=\"ink-select-indicator\">\n <InkIcon icon={Check} size={16} />\n </span>\n ) : null}\n </button>\n ) : null}\n <div\n role=\"group\"\n aria-label=\"Colours\"\n className=\"ink-color-grid\"\n data-ink-menu-columns={COLOR_COLUMNS}\n >\n {model.swatches.map((sw) => (\n <button\n key={sw.key}\n type=\"button\"\n role=\"menuitemradio\"\n aria-label={sw.label}\n aria-checked={sw.checked}\n tabIndex={-1}\n className=\"ink-swatch-item\"\n data-state={sw.checked ? 'checked' : 'unchecked'}\n style={{ '--ink-swatch': sw.color } as CSSProperties}\n onClick={() => set(sw.patch)}\n />\n ))}\n </div>\n <button\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item\"\n data-ink-select-item=\"\"\n onClick={() => input.current?.click()}\n >\n Custom…\n </button>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n <input\n ref={bindInput}\n type=\"color\"\n className=\"ink-color-input\"\n aria-label=\"Custom colour\"\n data-ink-color-input={property}\n tabIndex={-1}\n defaultValue={model.customValue.toLowerCase()}\n />\n </>\n )\n}\n","/*\n * A split button for the shape tool. The main part activates the tool with the current\n * kind and draws that kind's icon; the chevron opens a two-column grid of kinds. Choosing a\n * kind switches to the tool with it.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n SHAPE_COLUMNS,\n SHAPE_ICONS,\n SHAPE_KINDS,\n shapeMenuModel,\n type ShapeOptions,\n} from '@inkbar/core/dom'\nimport { ChevronDown } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport { useRef, useState, type ComponentPropsWithoutRef, type ReactNode } from 'react'\n\nimport { cx } from '../class-names'\nimport { useRegisteredTool } from '../hooks/useRegisteredTool'\nimport { useTool } from '../hooks/useTool'\nimport { useToolOptions } from '../hooks/useToolOptions'\n\nimport { InkIcon } from './InkIcon'\n\nexport interface InkShapeMenuProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** Replaces the main button's icon. */\n children?: ReactNode\n}\n\n/** Renders nothing while no `shape` tool is registered. */\nexport function InkShapeMenu(props: InkShapeMenuProps) {\n // The inner menu reads the tool's options, which would log a missing tool a second time.\n return useRegisteredTool('shape') ? <ShapeMenu {...props} /> : null\n}\n\nfunction ShapeMenu({ className, children, ...rest }: InkShapeMenuProps) {\n const { tool, setTool } = useTool()\n const [options, setOptions] = useToolOptions<ShapeOptions>('shape')\n const [open, setOpen] = useState(false)\n const model = shapeMenuModel(options, SHAPE_KINDS)\n const active = tool === 'shape'\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Anchor asChild>\n <div\n role=\"group\"\n aria-label=\"Shape\"\n className={cx('ink-split-button ink-shape-menu', className)}\n data-ink-shape-menu=\"\"\n {...rest}\n >\n <Toolbar.Button\n className=\"ink-tool-button ink-shape-button\"\n data-ink-tool-button=\"\"\n data-ink-shape-button=\"\"\n data-tool=\"shape\"\n data-kind={model.kind}\n data-state={active ? 'on' : 'off'}\n aria-pressed={active}\n aria-label={model.label}\n title={model.label}\n onClick={() => setTool('shape')}\n >\n {children ?? <InkIcon icon={SHAPE_ICONS[model.kind]} />}\n </Toolbar.Button>\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className=\"ink-menu-trigger ink-shape-menu-trigger\"\n data-ink-shape-menu-trigger=\"\"\n data-state={open ? 'open' : 'closed'}\n aria-label=\"Choose shape\"\n title=\"Choose shape\"\n aria-haspopup=\"menu\"\n onKeyDown={(e) => {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open) return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n <InkIcon icon={ChevronDown} />\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n role=\"menu\"\n aria-label=\"Shapes\"\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"shape\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const menu = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n focusFirst.current = false\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n <div\n role=\"group\"\n aria-label=\"Shapes\"\n className=\"ink-shape-grid\"\n data-ink-menu-columns={SHAPE_COLUMNS}\n >\n {model.items.map((item) => (\n <button\n key={item.kind}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={item.checked}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item ink-shape-item\"\n data-ink-select-item=\"\"\n data-key={item.kind}\n data-state={item.checked ? 'checked' : 'unchecked'}\n onClick={() => {\n setOptions({ kind: item.kind })\n setTool('shape')\n setOpen(false)\n }}\n >\n <InkIcon icon={SHAPE_ICONS[item.kind]} size={16} />\n {item.label}\n </button>\n ))}\n </div>\n </Popover.Content>\n </Popover.Portal>\n </div>\n </Popover.Anchor>\n </Popover.Root>\n )\n}\n","/*\n * A split button for the signature tool. The main part activates the tool with the chosen\n * signature, or opens the menu when none is chosen; the chevron opens the saved signatures as\n * previews, each with a remove button, and \"Create signature\", which opens\n * `InkSignatureDialog`. Choosing a signature switches to the tool with it.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n SIGNATURE_LABELS,\n signatureMenuModel,\n} from '@inkbar/core/dom'\nimport { ChevronDown, Signature } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport {\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useRegisteredTool } from '../hooks/useRegisteredTool'\nimport { useTool } from '../hooks/useTool'\nimport { useToolOptions } from '../hooks/useToolOptions'\nimport { useReadable } from '../use-readable'\n\nimport { InkIcon } from './InkIcon'\nimport { InkSignatureDialog } from './InkSignatureDialog'\nimport { SignatureMenuPanel } from './SignatureMenuPanel'\n\nimport type { SignatureOptions, SignatureTemplate } from '@inkbar/core'\n\nexport interface InkSignatureMenuProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** Replaces the main button's icon. */\n children?: ReactNode\n /** The fonts the dialog's Type tab offers. Default: InkRoot's `signatureFonts`. */\n fonts?: readonly string[] | undefined\n}\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\n/** Renders nothing while no `signature` tool is registered. */\nexport function InkSignatureMenu(props: InkSignatureMenuProps) {\n // The inner menu reads the tool's options, which would log a missing tool a second time.\n return useRegisteredTool('signature') ? <SignatureMenu {...props} /> : null\n}\n\nfunction SignatureMenu({ className, children, fonts, ...rest }: InkSignatureMenuProps) {\n const { tool, setTool } = useTool()\n const [options, setOptions] = useToolOptions<SignatureOptions>('signature')\n const { signatures } = useInkContext('InkSignatureMenu')\n const templates = useReadable(signatures.templates, NO_TEMPLATES)\n const model = signatureMenuModel(templates, options)\n const [open, setOpen] = useState(false)\n const [creating, setCreating] = useState(false)\n const active = tool === 'signature'\n const main = useRef<HTMLButtonElement>(null)\n const menu = useRef<HTMLDivElement>(null)\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n /** Set while the menu closes for the dialog, which takes focus instead of the trigger. */\n const toDialog = useRef(false)\n\n // An old removal error is not news when the menu opens again.\n useEffect(() => {\n if (open) signatures.clearRemoveError()\n }, [open, signatures])\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Anchor asChild>\n <div\n role=\"group\"\n aria-label={SIGNATURE_LABELS.sign}\n className={cx('ink-split-button ink-signature-menu', className)}\n data-ink-signature-menu=\"\"\n {...rest}\n >\n <Toolbar.Button\n ref={main}\n className=\"ink-tool-button ink-signature-button\"\n data-ink-tool-button=\"\"\n data-ink-signature-button=\"\"\n data-tool=\"signature\"\n data-state={active ? 'on' : 'off'}\n aria-pressed={active}\n aria-label={SIGNATURE_LABELS.sign}\n title={SIGNATURE_LABELS.sign}\n onClick={() => {\n if (model.selected) setTool('signature')\n else setOpen(true)\n }}\n >\n {children ?? <InkIcon icon={Signature} />}\n </Toolbar.Button>\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className=\"ink-menu-trigger ink-signature-menu-trigger\"\n data-ink-signature-menu-trigger=\"\"\n data-state={open ? 'open' : 'closed'}\n aria-label={SIGNATURE_LABELS.trigger}\n title={SIGNATURE_LABELS.trigger}\n aria-haspopup=\"menu\"\n onKeyDown={(e) => {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open) return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n <InkIcon icon={ChevronDown} />\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n ref={menu}\n role=\"menu\"\n aria-label={SIGNATURE_LABELS.menu}\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"signature\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const el = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(el)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(el)\n focusFirst.current = false\n }}\n onCloseAutoFocus={(e) => {\n if (toDialog.current) e.preventDefault()\n toDialog.current = false\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n <SignatureMenuPanel\n items={model.items}\n menu={menu}\n onChoose={(t) => {\n setOptions({ templateId: t.id })\n setTool('signature')\n setOpen(false)\n }}\n onCreate={() => {\n toDialog.current = true\n setOpen(false)\n setCreating(true)\n }}\n />\n </Popover.Content>\n </Popover.Portal>\n <InkSignatureDialog\n open={creating}\n onOpenChange={setCreating}\n fonts={fonts}\n onCloseAutoFocus={(e) => {\n e.preventDefault()\n main.current?.focus({ preventScroll: true })\n }}\n />\n </div>\n </Popover.Anchor>\n </Popover.Root>\n )\n}\n","/*\n * A split button for the highlight tool. The main part activates the tool with the current\n * markup kind and draws that kind's icon; the chevron opens a menu of the four kinds plus\n * the markup colour. Choosing a kind switches to the tool with it. The colour is a nested\n * `InkColorMenu` scoped to the `markup` style group, so it works whatever tool is active.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n highlightMenuModel,\n MARKUP_ICONS,\n MARKUP_KINDS,\n menuItems,\n type HighlightOptions,\n} from '@inkbar/core/dom'\nimport { ChevronDown } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport { useRef, useState, type ComponentPropsWithoutRef, type ReactNode } from 'react'\n\nimport { cx } from '../class-names'\nimport { useDocument } from '../hooks/useDocument'\nimport { useRegisteredTool } from '../hooks/useRegisteredTool'\nimport { useTool } from '../hooks/useTool'\nimport { useToolOptions } from '../hooks/useToolOptions'\n\nimport { InkColorMenu } from './InkColorMenu'\nimport { InkIcon } from './InkIcon'\n\nexport interface InkHighlightMenuProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** Replaces the main button's icon. */\n children?: ReactNode\n}\n\n/** Renders nothing while no `highlight` tool is registered. */\nexport function InkHighlightMenu(props: InkHighlightMenuProps) {\n // The inner menu reads the tool's options, which would log a missing tool a second time.\n return useRegisteredTool('highlight') ? <HighlightMenu {...props} /> : null\n}\n\nfunction HighlightMenu({ className, children, ...rest }: InkHighlightMenuProps) {\n const { tool, setTool } = useTool()\n const [options, setOptions] = useToolOptions<HighlightOptions>('highlight')\n const { document: doc } = useDocument()\n const [open, setOpen] = useState(false)\n const model = highlightMenuModel(options, MARKUP_KINDS)\n const active = tool === 'highlight'\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Popover.Anchor asChild>\n <div\n role=\"group\"\n aria-label=\"Highlight\"\n className={cx('ink-split-button ink-highlight-menu', className)}\n data-ink-highlight-menu=\"\"\n {...rest}\n >\n <Toolbar.Button\n className=\"ink-tool-button ink-highlight-button\"\n data-ink-tool-button=\"\"\n data-ink-highlight-button=\"\"\n data-tool=\"highlight\"\n data-kind={model.kind}\n data-state={active ? 'on' : 'off'}\n aria-pressed={active}\n aria-label={model.label}\n title={model.label}\n onClick={() => setTool('highlight')}\n >\n {children ?? <InkIcon icon={MARKUP_ICONS[model.kind]} />}\n </Toolbar.Button>\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className=\"ink-menu-trigger ink-highlight-menu-trigger\"\n data-ink-highlight-menu-trigger=\"\"\n data-state={open ? 'open' : 'closed'}\n aria-label=\"Choose highlight\"\n title=\"Choose highlight\"\n aria-haspopup=\"menu\"\n onKeyDown={(e) => {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open) return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n <InkIcon icon={ChevronDown} />\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n role=\"menu\"\n aria-label=\"Highlights\"\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"highlight\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const menu = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n focusFirst.current = false\n }}\n // Capture, so the arrow keys move on from the colour item before its own\n // ArrowDown opens the nested menu; keys from that menu's portalled panel, which\n // bubble here through React, are its own.\n onKeyDownCapture={(e) => {\n if (e.currentTarget.contains(e.target as Node))\n handleMenuKeys(e.nativeEvent, e.currentTarget)\n }}\n >\n <div role=\"group\" aria-label=\"Kinds\" className=\"ink-highlight-kinds\">\n {model.items.map((item) => (\n <button\n key={item.kind}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={item.checked}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item ink-highlight-item\"\n data-ink-select-item=\"\"\n data-key={item.kind}\n data-state={item.checked ? 'checked' : 'unchecked'}\n onClick={() => {\n setOptions({ kind: item.kind })\n setTool('highlight')\n setOpen(false)\n }}\n >\n <InkIcon icon={MARKUP_ICONS[item.kind]} size={16} />\n {item.label}\n </button>\n ))}\n </div>\n <div role=\"separator\" className=\"ink-select-separator\" />\n <div role=\"group\" aria-label=\"Colour\" className=\"ink-highlight-colour\">\n <span className=\"ink-highlight-colour-label\" aria-hidden=\"true\">\n Colour\n </span>\n <InkColorMenu\n property=\"border\"\n group=\"markup\"\n label=\"Highlight colour\"\n standalone\n fallback={doc?.annotations.defaults.color(model.kind)}\n role=\"menuitem\"\n tabIndex={-1}\n />\n </div>\n </Popover.Content>\n </Popover.Portal>\n </div>\n </Popover.Anchor>\n </Popover.Root>\n )\n}\n","/*\n * Font, size, text colour, bold, italic, underline and alignment for the selected text boxes or\n * the text tool. A popover panel rather than a menu list: it holds a select, a number input\n * with a stepper, toggle buttons and a radio group, each named and operable on its own. The\n * trigger carries `data-mixed` when the selection disagrees on any of them.\n */\nimport { handleRadioKeys, textStyleMenuModel } from '@inkbar/core/dom'\nimport {\n ALargeSmall,\n AlignCenter,\n AlignJustify,\n AlignLeft,\n AlignRight,\n Bold,\n Italic,\n Minus,\n Plus,\n Underline,\n} from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport { useEffect, useState, type ComponentPropsWithoutRef, type ReactNode } from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useToolStyle } from '../hooks/useToolStyle'\n\nimport { InkColorMenu } from './InkColorMenu'\nimport { InkIcon } from './InkIcon'\n\nexport interface InkTextStyleMenuProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n children?: ReactNode\n}\n\nconst TOGGLE_ICONS = { bold: Bold, italic: Italic, underline: Underline }\nconst ALIGN_ICONS = {\n left: AlignLeft,\n center: AlignCenter,\n right: AlignRight,\n justify: AlignJustify,\n}\n\nexport function InkTextStyleMenu({\n className,\n children,\n disabled,\n ...rest\n}: InkTextStyleMenuProps) {\n const { fonts } = useInkContext('InkTextStyleMenu')\n const { current, supported, set } = useToolStyle()\n const [open, setOpen] = useState(false)\n /** The size as typed, until it is committed with Enter or blur. */\n const [draft, setDraft] = useState<string | null>(null)\n const model = textStyleMenuModel(current, supported, fonts)\n // The menu closes when the control disables (the selection cleared while it was open).\n useEffect(() => {\n if (model.enabled) return\n setOpen(false)\n setDraft(null)\n }, [model.enabled])\n\n const commitSize = () => {\n if (draft === null) return\n if (draft.trim() !== '') {\n const patch = model.size.commit(Number(draft))\n if (patch) set(patch)\n }\n setDraft(null)\n }\n const nudge = (direction: 1 | -1) => {\n const patch = model.size.nudge(direction)\n if (patch) set(patch)\n setDraft(null)\n }\n const sizeShown = draft ?? (model.size.value === null ? '' : String(model.size.value))\n\n return (\n <Popover.Root\n open={open}\n onOpenChange={(next) => {\n // Closing commits a typed size, as the field's blur would.\n if (!next) commitSize()\n setOpen(next)\n }}\n >\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className={cx('ink-menu-trigger ink-text-style-menu', className)}\n data-ink-text-style-menu=\"\"\n data-state={open ? 'open' : 'closed'}\n data-mixed={model.mixed ? '' : undefined}\n aria-label={model.label}\n title={model.label}\n aria-haspopup=\"dialog\"\n disabled={disabled === true || !model.enabled}\n {...rest}\n onKeyDown={(e) => {\n rest.onKeyDown?.(e)\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open || !model.enabled)\n return\n e.preventDefault()\n setOpen(true)\n }}\n >\n {children ?? <InkIcon icon={ALargeSmall} />}\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n aria-label={model.label}\n className=\"ink-select-content ink-menu-content ink-text-style-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"text-style\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n >\n <select\n className=\"ink-text-style-font\"\n aria-label={model.font.label}\n value={model.font.value}\n onChange={(e) => set(model.font.patch(e.target.value))}\n >\n {model.font.value === '' ? (\n <option value=\"\" disabled hidden>\n Mixed\n </option>\n ) : null}\n {model.font.options.map((f) => (\n <option key={f} value={f}>\n {f}\n </option>\n ))}\n </select>\n <div className=\"ink-text-style-row\">\n <InkColorMenu property=\"textColor\" standalone />\n <div className=\"ink-text-style-size\" role=\"group\" aria-label=\"Size\">\n <button\n type=\"button\"\n className=\"ink-text-style-button\"\n aria-label=\"Decrease font size\"\n onClick={() => nudge(-1)}\n >\n <InkIcon icon={Minus} size={16} />\n </button>\n <input\n type=\"number\"\n className=\"ink-text-style-input\"\n aria-label={model.size.label}\n min={model.size.min}\n max={model.size.max}\n step={model.size.step}\n value={sizeShown}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={commitSize}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n commitSize()\n }\n }}\n />\n <button\n type=\"button\"\n className=\"ink-text-style-button\"\n aria-label=\"Increase font size\"\n onClick={() => nudge(1)}\n >\n <InkIcon icon={Plus} size={16} />\n </button>\n </div>\n </div>\n <div className=\"ink-text-style-row\" role=\"group\" aria-label=\"Emphasis\">\n {model.toggles.map((t) => (\n <button\n key={t.key}\n type=\"button\"\n className=\"ink-text-style-button\"\n aria-label={t.label}\n title={t.label}\n aria-pressed={t.pressed}\n data-state={t.pressed === true ? 'on' : 'off'}\n data-mixed={t.pressed === 'mixed' ? '' : undefined}\n onClick={() => set(t.patch)}\n >\n <InkIcon icon={TOGGLE_ICONS[t.key]} size={16} />\n </button>\n ))}\n </div>\n <div\n className=\"ink-text-style-row\"\n role=\"radiogroup\"\n aria-label={model.align.label}\n onKeyDown={(e) => handleRadioKeys(e.nativeEvent, e.currentTarget)}\n >\n {model.align.choices.map((c) => (\n <button\n key={c.key}\n type=\"button\"\n role=\"radio\"\n className=\"ink-text-style-button\"\n aria-label={c.label}\n title={c.label}\n aria-checked={c.checked}\n tabIndex={c.tabStop ? 0 : -1}\n data-state={c.checked ? 'on' : 'off'}\n onClick={() => set(c.patch)}\n >\n <InkIcon icon={ALIGN_ICONS[c.key]} size={16} />\n </button>\n ))}\n </div>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n )\n}\n","/*\n * Line weight, solid or dashed, and arrowheads, for the selection or the active tool. Each\n * section disables when nothing selected (or no active tool) supports its props. The trigger\n * carries `data-mixed` when the selection disagrees on any of them; a section with no single\n * value shows no checkmark.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n lineStyleMenuModel,\n menuItems,\n} from '@inkbar/core/dom'\nimport { Check, Minus } from '@inkbar/icons'\nimport { Popover, Toolbar } from 'radix-ui'\nimport {\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useToolStyle } from '../hooks/useToolStyle'\n\nimport { InkIcon } from './InkIcon'\n\nexport interface InkLineStyleMenuProps extends Omit<\n ComponentPropsWithoutRef<'button'>,\n 'children'\n> {\n children?: ReactNode\n}\n\ninterface ItemProps {\n label: string\n checked: boolean\n disabled: boolean\n onSelect: () => void\n children?: ReactNode\n}\n\nfunction Item({ label, checked, disabled, onSelect, children }: ItemProps) {\n return (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={checked}\n disabled={disabled}\n tabIndex={-1}\n className=\"ink-select-item ink-menu-item\"\n data-ink-select-item=\"\"\n data-state={checked ? 'checked' : 'unchecked'}\n onClick={onSelect}\n >\n {children ?? label}\n {checked ? (\n <span className=\"ink-select-indicator\">\n <InkIcon icon={Check} size={16} />\n </span>\n ) : null}\n </button>\n )\n}\n\nfunction Group({\n label,\n disabled,\n children,\n}: {\n label: string\n disabled: boolean\n children: ReactNode\n}) {\n return (\n <div\n role=\"group\"\n aria-label={label}\n aria-disabled={disabled || undefined}\n data-disabled={disabled ? '' : undefined}\n className=\"ink-menu-group\"\n >\n <div className=\"ink-menu-label\" aria-hidden=\"true\">\n {label}\n </div>\n {children}\n </div>\n )\n}\n\nexport function InkLineStyleMenu({\n className,\n children,\n disabled,\n ...rest\n}: InkLineStyleMenuProps) {\n const { current, supported, set } = useToolStyle()\n const [open, setOpen] = useState(false)\n const model = lineStyleMenuModel(current, supported)\n /** ArrowDown opens on the first item; a click opens on the checked one. */\n const focusFirst = useRef(false)\n // The menu closes when the control disables (the selection cleared while it was open).\n useEffect(() => {\n if (!model.enabled) setOpen(false)\n }, [model.enabled])\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <Toolbar.Button asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n className={cx('ink-menu-trigger ink-line-style-menu', className)}\n data-ink-line-style-menu=\"\"\n data-state={open ? 'open' : 'closed'}\n data-mixed={model.mixed ? '' : undefined}\n aria-label=\"Line style\"\n title=\"Line style\"\n aria-haspopup=\"menu\"\n disabled={disabled === true || !model.enabled}\n {...rest}\n onKeyDown={(e) => {\n rest.onKeyDown?.(e)\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open || !model.enabled)\n return\n e.preventDefault()\n focusFirst.current = true\n setOpen(true)\n }}\n >\n {children ?? <InkIcon icon={Minus} />}\n </button>\n </Popover.Trigger>\n </Toolbar.Button>\n <Popover.Portal>\n <Popover.Content\n role=\"menu\"\n aria-label=\"Line style\"\n className=\"ink-select-content ink-menu-content\"\n data-ink-select-content=\"\"\n data-ink-menu=\"line-style\"\n side=\"bottom\"\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n const menu = e.currentTarget as HTMLElement\n if (focusFirst.current) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n focusFirst.current = false\n }}\n onKeyDown={(e) => handleMenuKeys(e.nativeEvent, e.currentTarget)}\n >\n {model.sections.map((section) => (\n <Group key={section.label} label={section.label} disabled={section.disabled}>\n {section.items.map((item) => (\n <Item\n key={item.key}\n label={item.label}\n checked={item.checked}\n disabled={section.disabled}\n onSelect={() => set(item.patch)}\n />\n ))}\n </Group>\n ))}\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n )\n}\n","import { observeAnnotationElement } from '@inkbar/core/dom'\nimport { useEffect, useState } from 'react'\n\n/**\n * The overlay element core draws for an annotation, for anchoring a popover to it. Core\n * creates and removes these elements outside React, so this follows the root's subtree while\n * an id is wanted.\n */\nexport function useAnnotationElement(\n root: HTMLElement | null,\n id: string | null\n): HTMLElement | null {\n const [element, setElement] = useState<HTMLElement | null>(null)\n useEffect(() => {\n if (!root || !id) {\n setElement(null)\n return\n }\n return observeAnnotationElement(root, id, setElement)\n }, [root, id])\n return element\n}\n","import {\n createFocusReturn,\n shouldKeepOpenOnAnnotation,\n type FocusReturn,\n} from '@inkbar/core/dom'\nimport { useMemo } from 'react'\n\nimport { useLatest } from '../use-latest'\n\nimport type { InkContext } from '../context'\n\nexport type { FocusReturn }\n\n/** Radix's `onInteractOutside` handler: a press that will activate an annotation keeps the popover open. */\nexport function keepOpenOnAnnotation(event: CustomEvent<{ originalEvent: Event }>): void {\n if (shouldKeepOpenOnAnnotation(event.detail.originalEvent.target))\n event.preventDefault()\n}\n\nexport function useFocusReturn(ctx: InkContext): FocusReturn {\n const latest = useLatest(ctx)\n return useMemo(\n () =>\n createFocusReturn({\n root: () => latest.current.rootEl,\n activated: () => latest.current.activated,\n }),\n [latest]\n )\n}\n","/*\n * The thread for the activated note or text markup, anchored to the root's overlay element.\n * Activating a reply opens the whole thread from its root. Closing (Close, Escape, a press\n * outside) clears `activated`.\n *\n * A new note, or a highlight, has no text. While its root is empty (and unlocked) the default\n * form writes the root's own `contents`, labelled \"Comment\", and the thread list stays hidden\n * until there is something in it; after that the form adds replies. Closing a note that is\n * still empty and has no replies removes it, so an abandoned note does not stay on the page.\n * Markup stays: the mark is the point.\n */\nimport { isAbandonedNote, threadOf, threadRoot } from '@inkbar/core'\nimport { threadDeleteLabel, threadPopoverLabel } from '@inkbar/core/dom'\nimport { Popover } from 'radix-ui'\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type FormEvent,\n type ReactNode,\n} from 'react'\n\nimport { useInkContext } from '../context'\nimport { useAnnotations } from '../hooks/useAnnotations'\nimport { useLatest } from '../use-latest'\n\nimport { useAnnotationElement } from './annotation-element'\nimport { keepOpenOnAnnotation, useFocusReturn } from './popover-focus'\n\nimport type { Annotation, ThreadRoot } from '@inkbar/core'\nimport type { ThreadPopoverSlotProps } from '@inkbar/core/dom'\n\nexport interface InkThreadPopoverProps {\n children?: ((props: ThreadPopoverSlotProps) => ReactNode) | undefined\n}\n\nexport function InkThreadPopover({ children }: InkThreadPopoverProps) {\n const ctx = useInkContext('InkThreadPopover')\n const { annotations, add, update, remove } = useAnnotations()\n\n const note = useMemo<ThreadRoot | null>(() => {\n const a = ctx.activated ? annotations.find((x) => x.id === ctx.activated) : undefined\n return a ? threadRoot(annotations, a) : null\n }, [annotations, ctx.activated])\n const anchor = useAnnotationElement(ctx.rootEl, note?.id ?? null)\n const anchorRef = useMemo(() => ({ current: anchor }), [anchor])\n const focusReturn = useFocusReturn(ctx)\n const open = note !== null && anchor !== null\n /** The root, then every reply below it, depth first, each level in creation order. */\n const thread = useMemo<Annotation[]>(\n () => (note ? threadOf(annotations, note) : []),\n [annotations, note]\n )\n /** True while the default form writes the root's own text rather than a reply. */\n const editingRoot = note !== null && !note.locked && !note.contents?.trim()\n\n /**\n * Roots this popover wrote text or a reply for. In controlled mode the write is a proposal\n * the host may not have applied yet, so the applied list still shows the note empty; these\n * are never dropped as abandoned.\n */\n const written = useRef(new Set<string>())\n /** Notes this popover has already asked to remove, so a slow host is asked once. */\n const dropped = useRef(new Set<string>())\n const latest = useLatest({ annotations, remove })\n\n function dropIfEmpty(id: string): boolean {\n const list = latest.current.annotations\n const a = list.find((x) => x.id === id)\n if (\n !a ||\n dropped.current.has(id) ||\n written.current.has(id) ||\n !isAbandonedNote(a, list)\n )\n return false\n dropped.current.add(id)\n latest.current.remove(id)\n return true\n }\n\n // Activation moved on from a note that never got any text: drop it.\n const noteId = note?.id\n const previousId = useRef<string | undefined>(undefined)\n useEffect(() => {\n const previous = previousId.current\n if (previous === noteId) return\n previousId.current = noteId\n if (previous !== undefined) dropIfEmpty(previous)\n // dropIfEmpty reads through `latest`; it is stable for the effect's purposes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [noteId])\n\n function reply(text: string): void {\n const root = note\n const contents = text.trim()\n if (!root || !contents) return\n written.current.add(root.id)\n add({ type: 'text', page: root.page, rect: root.rect, contents, inReplyTo: root.id })\n }\n /** A note that closing now would remove. */\n function isEmptyRoot(root: ThreadRoot): boolean {\n return !written.current.has(root.id) && isAbandonedNote(root, annotations)\n }\n function close(): void {\n const root = note\n if (root && annotations.some((a) => a.id === root.id) && isEmptyRoot(root)) {\n focusReturn.beforeRemove(anchor)\n dropIfEmpty(root.id)\n }\n ctx.setActivated(null)\n }\n function updateContents(contents: string): void {\n if (!note || note.locked) return\n if (contents.trim()) written.current.add(note.id)\n update(note.id, { contents })\n }\n /** Locked roots cannot be removed: removing one does nothing and keeps the popover. */\n function removeThread(): void {\n const root = note\n if (!root || root.locked) return\n focusReturn.beforeRemove(anchor)\n // Under a slow controlled host the root stays listed for a while; it is not asked for again.\n dropped.current.add(root.id)\n remove(root.id)\n ctx.setActivated(null)\n }\n\n return (\n <Popover.Root open={open} onOpenChange={(next) => !next && close()}>\n <Popover.Anchor virtualRef={anchorRef} />\n <Popover.Portal>\n {note && anchor ? (\n <Popover.Content\n className=\"ink-thread-popover\"\n data-ink-thread-popover=\"\"\n side=\"right\"\n sideOffset={8}\n collisionPadding={8}\n aria-label={threadPopoverLabel(note)}\n onInteractOutside={keepOpenOnAnnotation}\n onCloseAutoFocus={(e) => focusReturn.onCloseAutoFocus(e, anchor)}\n >\n {children ? (\n children({\n root: note,\n replies: thread.slice(1),\n reply,\n update: updateContents,\n remove: removeThread,\n close,\n })\n ) : (\n <>\n {!editingRoot || thread.length > 1 ? (\n <ol className=\"ink-thread\" data-ink-thread=\"\">\n {thread.map((item) => (\n <li\n key={item.id}\n className=\"ink-thread-item\"\n data-ink-thread-item=\"\"\n data-reply={item.inReplyTo ? '' : undefined}\n >\n <span className=\"ink-thread-author\">\n {item.author ?? 'Anonymous'}\n </span>\n <time className=\"ink-thread-time\" dateTime={item.createdAt}>\n {new Date(item.createdAt).toLocaleString()}\n </time>\n <p className=\"ink-thread-text\">{item.contents}</p>\n </li>\n ))}\n </ol>\n ) : null}\n <ThreadForm\n // Keyed by root: moving to another thread starts with an empty draft at once.\n key={note.id}\n editingRoot={editingRoot}\n locked={!!note.locked}\n deleteLabel={threadDeleteLabel(note)}\n onSubmit={(text) => (editingRoot ? updateContents(text) : reply(text))}\n onRemove={removeThread}\n onClose={close}\n />\n </>\n )}\n </Popover.Content>\n ) : null}\n </Popover.Portal>\n </Popover.Root>\n )\n}\n\n/** The default form: the root's own text while it is empty, replies after that. */\nfunction ThreadForm({\n editingRoot,\n locked,\n deleteLabel,\n onSubmit,\n onRemove,\n onClose,\n}: {\n editingRoot: boolean\n locked: boolean\n deleteLabel: string\n onSubmit: (text: string) => void\n onRemove: () => void\n onClose: () => void\n}) {\n const [draft, setDraft] = useState('')\n function submit(e: FormEvent): void {\n e.preventDefault()\n const text = draft.trim()\n if (!text) return\n onSubmit(text)\n setDraft('')\n }\n return (\n <form className=\"ink-thread-reply\" data-ink-thread-reply=\"\" onSubmit={submit}>\n <textarea\n aria-label={editingRoot ? 'Comment' : 'Reply'}\n rows={2}\n placeholder={editingRoot ? 'Comment' : 'Reply'}\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n />\n <div className=\"ink-thread-actions\">\n <button type=\"submit\" disabled={!draft.trim()}>\n {editingRoot ? 'Comment' : 'Reply'}\n </button>\n {!locked ? (\n <button type=\"button\" onClick={onRemove}>\n {deleteLabel}\n </button>\n ) : null}\n <button type=\"button\" onClick={onClose}>\n Close\n </button>\n </div>\n </form>\n )\n}\n","/**\n * Core's attributes (`rootAttrs()`, `triggerAttrs(id)`, `panelAttrs(id)` and the like) as React\n * props. Core names them as the DOM does; React wants `hidden` as a boolean and `tabindex` as\n * `tabIndex`. `aria-*`, `data-*`, `id`, `role`, `type` and `title` pass through as they are.\n * Every component that spreads core's attributes goes through this, so the mapping lives once.\n */\nexport function domAttrs(attrs: Readonly<Record<string, string>>): DomProps {\n const out: DomProps = {}\n for (const [name, value] of Object.entries(attrs)) {\n if (name === 'hidden') out.hidden = true\n else if (name === 'tabindex') out.tabIndex = Number(value)\n else out[name] = value\n }\n return out\n}\n\n/** What `domAttrs` returns, to spread on an element. */\nexport interface DomProps {\n hidden?: boolean\n tabIndex?: number\n [name: string]: string | number | boolean | undefined\n}\n","import { createContext, useCallback, useContext, useSyncExternalStore } from 'react'\n\nimport type { SidebarController, SidebarPanelInfo, SidebarState } from '@inkbar/core/dom'\n\n/** A panel as `InkPanel` registers it. */\nexport interface SidebarPanelEntry {\n /** The panel's props as they were last committed. */\n info: SidebarPanelInfo\n /** The panel's element once mounted, to keep the panels in DOM order. */\n element(): HTMLElement | null\n}\n\n/** What `InkSidebar` gives its panels. */\nexport interface SidebarContext {\n controller: SidebarController\n /**\n * Before the sidebar has mounted (on the server, and in the browser's first render), adds or\n * replaces the panel in render order, so the controller knows the panels that render first\n * and the markup shows the right one open. A no-op once mounted.\n */\n preregister(info: SidebarPanelInfo): void\n /** Adds a mounted panel; returns the function that removes it. */\n register(entry: SidebarPanelEntry): () => void\n /** Tells the sidebar a registered panel's props changed. */\n changed(): void\n}\n\nexport const SidebarContextObject = createContext<SidebarContext | null>(null)\n\n/** The sidebar context: throws a readable error outside `InkSidebar`. */\nexport function useSidebarContext(consumer: string): SidebarContext {\n const ctx = useContext(SidebarContextObject)\n if (!ctx) throw new Error(`[inkbar] ${consumer} must be rendered inside <InkSidebar>.`)\n return ctx\n}\n\n/**\n * The controller's state, re-rendering as it changes. Unlike `useReadable` it reads the live\n * state on the server too: the sidebar works without a document, so its markup is known there.\n */\nexport function useSidebarState(controller: SidebarController): SidebarState {\n const { state } = controller\n const subscribe = useCallback(\n (onChange: () => void) => state.subscribe(() => onChange()),\n [state]\n )\n const get = useCallback(() => state.get(), [state])\n return useSyncExternalStore(subscribe, get, get)\n}\n","import { sidebarBadge, type SidebarPanelInfo } from '@inkbar/core/dom'\n\nimport { InkIcon } from './InkIcon'\n\n/**\n * A sidebar trigger's content: `createSidebar`'s markup, so the theme styles both alike. The\n * rail shows the icon alone (the trigger's `title` carries the label); tabs and stack headers\n * show the label too. The badge is hidden from assistive technology: the trigger's name has it.\n */\nexport function SidebarTrigger({\n panel,\n rail,\n}: {\n panel: SidebarPanelInfo\n rail: boolean\n}) {\n const badge = sidebarBadge(panel.badge)\n return (\n <>\n {panel.icon ? <InkIcon icon={panel.icon} /> : null}\n {!panel.icon || !rail ? (\n <span className=\"ink-sidebar-label\">{panel.label}</span>\n ) : null}\n <span className=\"ink-sidebar-badge\" aria-hidden=\"true\" hidden={badge === null}>\n {badge}\n </span>\n </>\n )\n}\n","import {\n createSidebarController,\n type SidebarController,\n type SidebarLayout,\n type SidebarOpen,\n type SidebarPanelInfo,\n type SidebarSide,\n} from '@inkbar/core/dom'\nimport {\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { domAttrs } from '../dom-attrs'\nimport { useLatest } from '../use-latest'\n\nimport {\n SidebarContextObject,\n useSidebarState,\n type SidebarContext,\n type SidebarPanelEntry,\n} from './sidebar-context'\nimport { SidebarTrigger } from './SidebarTrigger'\n\nexport interface InkSidebarProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** Which edge the rail and border sit on. Default `'left'`. */\n side?: SidebarSide | undefined\n /** `'rail'` (default), `'tabs'` or `'stack'`. */\n layout?: SidebarLayout | undefined\n /** Default true. False hides the whole sidebar and keeps its open panel, content and scroll for when it shows again. */\n visible?: boolean | undefined\n /**\n * Controlled: the open panel's id (or null) for rail and tabs, the expanded ids for stack.\n * Leave it out for an uncontrolled sidebar.\n */\n open?: SidebarOpen | undefined\n /** Uncontrolled: what starts open. Left out, the first panel does. */\n defaultOpen?: SidebarOpen | undefined\n /** Called with the new value when a trigger is activated or the open panel goes. */\n onOpenChange?: ((open: SidebarOpen) => void) | undefined\n /** The `InkPanel`s. */\n children?: ReactNode\n}\n\n/** Sorts the panels by where their elements sit in the DOM. */\nfunction inDomOrder(entries: readonly SidebarPanelEntry[]): SidebarPanelEntry[] {\n return [...entries].sort((a, b) => {\n const x = a.element()\n const y = b.element()\n if (!x || !y || x === y) return 0\n return x.compareDocumentPosition(y) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1\n })\n}\n\n/**\n * The panels' registry around the controller. Before the first mount, panels preregister as\n * they render, in render order, so the server and the browser's first render show the panel\n * core opens. From then on they register from layout effects, ordered by DOM position. A\n * removal is applied a microtask later: a panel remounted in the same commit (a new `key`) is\n * back by then, so its open state does not fall back. While the sidebar itself is unmounted\n * (on its way out, or StrictMode and `<Activity>` replaying effects) nothing is applied.\n */\nfunction createRegistry(controller: SidebarController) {\n let mounted = false\n let started = false\n const early: SidebarPanelInfo[] = []\n let entries: SidebarPanelEntry[] = []\n\n const flush = (): void => {\n if (!mounted) return\n controller.update({ panels: inDomOrder(entries).map((e) => e.info) })\n }\n\n const context: SidebarContext = {\n controller,\n preregister(info) {\n if (started) return\n const at = early.findIndex((p) => p.id === info.id)\n if (at < 0) early.push(info)\n else early[at] = info\n controller.update({ panels: [...early] })\n },\n register(entry) {\n entries = [...entries, entry]\n flush()\n return () => {\n entries = entries.filter((e) => e !== entry)\n queueMicrotask(flush)\n }\n },\n changed: flush,\n }\n\n /** Binds the triggers and ends the controller's pending state; returns the unbind. */\n function mount(el: HTMLElement): () => void {\n mounted = true\n started = true\n const unbind = controller.bindTriggers(el)\n controller.update({\n panels: inDomOrder(entries).map((e) => e.info),\n pending: false,\n })\n return () => {\n mounted = false\n unbind()\n }\n }\n\n return { context, mount }\n}\n\n/**\n * A sidebar of `InkPanel`s: `createSidebar`'s markup on core's sidebar controller, which holds\n * the open state, the ARIA, the keys and the clicks. Rail and tabs render their triggers here;\n * in a stack each panel renders its own header. Panels take their place in DOM order, so a\n * panel rendered later slots in where it stands. A closed panel stays mounted and hidden, and\n * the panels' content stays in place across layouts, so its state survives switching.\n *\n * `open` with `onOpenChange` controls it; `defaultOpen` starts it uncontrolled; with neither,\n * the first panel starts open. It needs no document, so it works outside `InkRoot`. The server\n * renders the root, the panels (the open one shown) and the stack headers; rail and tab\n * buttons follow once mounted.\n */\nexport function InkSidebar({\n side = 'left',\n layout = 'rail',\n visible = true,\n open,\n defaultOpen,\n onOpenChange,\n className,\n children,\n ...rest\n}: InkSidebarProps) {\n const controlled = open !== undefined\n // Uncontrolled with `defaultOpen`, or once anything changed: the value we pass back.\n const [inner, setInner] = useState<SidebarOpen | undefined>(defaultOpen)\n const value = controlled ? open : inner\n const latest = useLatest({ controlled, onOpenChange })\n // The same ids on the server and the client.\n const idPrefix = useId()\n const [{ context, mount }] = useState(() =>\n createRegistry(\n // Pending until mounted: an open id not registered yet is not a removed panel.\n createSidebarController({\n layout,\n side,\n visible,\n panels: [],\n ...(value !== undefined && { open: value }),\n pending: true,\n idPrefix,\n onOpenChange: (next) => {\n if (!latest.current.controlled) setInner(next)\n latest.current.onOpenChange?.(next)\n },\n })\n )\n )\n const { controller } = context\n const state = useSidebarState(controller)\n\n // A no-op change publishes nothing, so this cannot loop.\n useLayoutEffect(() => {\n controller.update({\n layout,\n side,\n visible,\n ...(value !== undefined && { open: value }),\n })\n }, [controller, layout, side, visible, value])\n\n // After the panels' own layout effects: they are registered by now. The controller handles\n // the triggers' clicks and keys, stack headers included.\n const root = useRef<HTMLDivElement>(null)\n useLayoutEffect(() => mount(root.current!), [mount])\n\n const rail = state.layout === 'rail'\n return (\n <div\n {...rest}\n ref={root}\n className={cx('ink-sidebar', className)}\n {...domAttrs(controller.rootAttrs())}\n >\n {state.layout !== 'stack' ? (\n <div\n className={rail ? 'ink-sidebar-rail' : 'ink-sidebar-tabs'}\n {...domAttrs(controller.tablistAttrs())}\n >\n {state.panels.map((panel) => (\n <button key={panel.id} {...domAttrs(controller.triggerAttrs(panel.id))}>\n <SidebarTrigger panel={panel} rail={rail} />\n </button>\n ))}\n </div>\n ) : null}\n {/* One element in every layout, so the panels are never remounted. */}\n <div className={state.layout !== 'stack' ? 'ink-sidebar-panels' : undefined}>\n <SidebarContextObject.Provider value={context}>\n {children}\n </SidebarContextObject.Provider>\n </div>\n </div>\n )\n}\n","import { useLayoutEffect, useMemo, useRef, useState, type ReactNode } from 'react'\n\nimport { cx } from '../class-names'\nimport { domAttrs } from '../dom-attrs'\n\nimport {\n useSidebarContext,\n useSidebarState,\n type SidebarPanelEntry,\n} from './sidebar-context'\nimport { SidebarTrigger } from './SidebarTrigger'\n\nimport type { SidebarPanelInfo } from '@inkbar/core/dom'\nimport type { IconNode } from '@inkbar/icons'\n\nexport interface InkPanelProps {\n /** Names the panel in the sidebar's `open`. */\n id: string\n /** Names its trigger. */\n label: string\n /** An `@inkbar/icons` node, shown on the rail. */\n icon?: IconNode | undefined\n /** A count or short text beside it, hidden when empty or 0. */\n badge?: string | number | undefined\n children?: ReactNode\n}\n\n/**\n * One panel of an `InkSidebar`, holding `children` as its content. Closed, the panel stays\n * mounted and hidden. In a stack it renders its own header above its content.\n */\nexport function InkPanel({ id, label, icon, badge, children }: InkPanelProps) {\n const ctx = useSidebarContext('InkPanel')\n const { controller } = ctx\n const info = useMemo<SidebarPanelInfo>(\n () => ({\n id,\n label,\n ...(icon !== undefined && { icon }),\n ...(badge !== undefined && { badge }),\n }),\n [id, label, icon, badge]\n )\n // Before the sidebar mounts, so this render already shows whether the panel is open.\n ctx.preregister(info)\n const state = useSidebarState(controller)\n\n const wrapper = useRef<HTMLDivElement>(null)\n const [entry] = useState<SidebarPanelEntry>(() => ({\n info,\n element: () => wrapper.current,\n }))\n useLayoutEffect(() => ctx.register(entry), [ctx, entry])\n useLayoutEffect(() => {\n if (entry.info === info) return\n entry.info = info\n ctx.changed()\n }, [ctx, entry, info])\n\n const stack = state.layout === 'stack'\n return (\n // A section in a stack; in rail and tabs the theme leaves the layout to the panel. Kept in\n // every layout, so the content is never remounted.\n <div ref={wrapper} className={cx('ink-sidebar-slot', stack && 'ink-sidebar-section')}>\n {stack ? (\n <button className=\"ink-sidebar-header\" {...domAttrs(controller.triggerAttrs(id))}>\n <SidebarTrigger panel={info} rail={false} />\n </button>\n ) : null}\n <div className=\"ink-sidebar-panel\" {...domAttrs(controller.panelAttrs(id))}>\n {/* The rail button names the panel for assistive technology; this repeats it on screen. */}\n <div className=\"ink-sidebar-panel-title\" aria-hidden=\"true\">\n {label}\n </div>\n <div className=\"ink-sidebar-panel-body\">{children}</div>\n </div>\n </div>\n )\n}\n","import { readonly, writable, type Readable } from '@inkbar/core'\nimport { useLayoutEffect, useState } from 'react'\n\n/**\n * A core `Readable` that follows a React value, for the core controllers and painters that\n * components build on. The same readable for the component's life; it takes each new value in\n * a layout effect, so declare it before the effects that hand it to core.\n */\nexport function useToReadable<T>(value: T): Readable<T> {\n const [store] = useState(() => writable(value))\n useLayoutEffect(() => {\n store.set(value)\n }, [store, value])\n const [view] = useState(() => readonly(store))\n return view\n}\n","import { createThumbnailPainter, type ThumbnailPainter } from '@inkbar/core/dom'\nimport { useLayoutEffect, useMemo, useRef, type ComponentPropsWithoutRef } from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useToReadable } from '../to-readable'\nimport { useLatest } from '../use-latest'\n\nexport interface InkThumbnailProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** 0-based. */\n page: number\n /** Width in CSS pixels; the height follows the page. Default 120 unless `height` is given. */\n width?: number | undefined\n /** Height in CSS pixels; the width follows the page. */\n height?: number | undefined\n /** Draw the page's annotations. Default true. */\n annotations?: boolean | undefined\n /** Draw plugin marks. Default true. */\n marks?: boolean | undefined\n /** The accessible name. Default \"Page N\". */\n label?: string | undefined\n}\n\n/**\n * One page as a static image, with its live annotations and plugin marks: core's thumbnail\n * painter on this element, which sizes it, names it (\"Page N\" unless `label` says otherwise)\n * and draws it once it nears the visible area. It is not focusable and does nothing on click:\n * wrap it in the control you need. Inside `InkRoot`; it renders empty on the server.\n */\nexport function InkThumbnail({\n page,\n width,\n height,\n annotations = true,\n marks = true,\n label,\n className,\n ...rest\n}: InkThumbnailProps) {\n const ctx = useInkContext('InkThumbnail')\n const document = useToReadable(ctx.document)\n const pluginHost = useToReadable(ctx.pluginHost)\n const options = useMemo(\n () => ({ page, width, height, annotations, marks, label }),\n [page, width, height, annotations, marks, label]\n )\n const latest = useLatest(options)\n\n const el = useRef<HTMLDivElement>(null)\n const painter = useRef<ThumbnailPainter | null>(null)\n // Before the painter is made, so a new painter does not take its first options twice.\n useLayoutEffect(() => {\n painter.current?.update(options)\n }, [options])\n useLayoutEffect(() => {\n const p = createThumbnailPainter(\n el.current!,\n { document, pluginHost },\n latest.current\n )\n painter.current = p\n return () => {\n p.destroy()\n painter.current = null\n }\n }, [document, pluginHost, latest])\n\n // The class is the painter's too: kept here, a re-render never drops it.\n return <div {...rest} ref={el} className={cx('ink-thumbnail', className)} />\n}\n","import {\n createThumbnailsController,\n THUMBNAIL_WIDTH,\n type ThumbnailsController,\n type ThumbnailsState,\n} from '@inkbar/core/dom'\nimport {\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { domAttrs } from '../dom-attrs'\nimport { useToReadable } from '../to-readable'\nimport { useLatest } from '../use-latest'\nimport { useReadable } from '../use-readable'\n\nimport { InkThumbnail } from './InkThumbnail'\n\nexport interface InkThumbnailsProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** 0-based pages to list, in order. Default: every page. */\n pages?: readonly number[] | undefined\n /** Thumbnail width in CSS pixels. Default: the list's width less a 16px gutter each side. */\n width?: number | undefined\n /** Draw each page's annotations. Default true. */\n annotations?: boolean | undefined\n /** Draw plugin marks. Default true. */\n marks?: boolean | undefined\n /**\n * Renders inside each item, after its page number. The item's height is fixed from the\n * page's, so keep what you add out of the flow (position it absolutely) or small.\n */\n renderItem?: ((item: { page: number; current: boolean }) => ReactNode) | undefined\n}\n\n/** Until the list mounts, and on the server: nothing listed. */\nconst EMPTY: ThumbnailsState = {\n pages: [],\n current: -1,\n window: { start: 0, end: 0 },\n offsets: [0],\n width: THUMBNAIL_WIDTH,\n}\n\n/**\n * The pages as a list of thumbnails: `createThumbnails`' markup on core's thumbnails\n * controller, which holds the current page, the keys, the clicks, the Tab stop and the window.\n * Only the items near the visible part are mounted, each placed at its offset over a spacer of\n * the full height, and each holds an `InkThumbnail`. An item is a button that scrolls the\n * viewport to its page; the current page's has `aria-current=\"page\"`. Inside `InkRoot`; it\n * renders empty on the server.\n */\nexport function InkThumbnails({\n pages,\n width,\n annotations = true,\n marks = true,\n renderItem,\n className,\n ...rest\n}: InkThumbnailsProps) {\n const ctx = useInkContext('InkThumbnails')\n const document = useToReadable(ctx.document)\n const pluginHost = useToReadable(ctx.pluginHost)\n const viewport = useToReadable(ctx.viewport)\n const options = useMemo(\n () => ({ pages, width, annotations, marks }),\n [pages, width, annotations, marks]\n )\n const latest = useLatest(options)\n\n const scroller = useRef<HTMLDivElement>(null)\n const [controller, setController] = useState<ThumbnailsController | null>(null)\n // A list unchanged in content publishes nothing, so an inline `pages` array cannot loop.\n useLayoutEffect(() => {\n controller?.update(options)\n }, [controller, options])\n useLayoutEffect(() => {\n const c = createThumbnailsController(\n { document, pluginHost, viewport },\n latest.current\n )\n setController(c)\n c.attach(scroller.current!)\n return () => {\n c.destroy()\n setController(null)\n }\n }, [document, pluginHost, viewport, latest])\n const state = useReadable(controller?.state, EMPTY)\n\n const { window: win, offsets } = state\n const items = state.pages.slice(win.start, win.end).map((page, k) => {\n const top = offsets[win.start + k]!\n const bottom = offsets[win.start + k + 1]!\n // Only a mounted controller has a window, so `controller` is set here.\n const attrs = controller?.itemAttrs(win.start + k) ?? {}\n return { page, current: page === state.current, top, height: bottom - top, attrs }\n })\n\n return (\n <div\n {...rest}\n ref={scroller}\n className={cx('ink-thumbnails', className)}\n data-ink-thumbnails=\"\"\n role=\"list\"\n >\n <div\n className=\"ink-thumbnails-spacer\"\n aria-hidden=\"true\"\n style={{ height: `${offsets.at(-1) ?? 0}px` }}\n />\n {items.map((item) => (\n <div\n key={item.page}\n className=\"ink-thumbnails-entry\"\n {...domAttrs(item.attrs)}\n style={{ top: `${item.top}px`, height: `${item.height}px` }}\n >\n {/* The controller sets the tabindex. The thumbnail names the button \"Page N\"; the\n visible number repeats it. */}\n <button\n type=\"button\"\n className=\"ink-thumbnails-item\"\n data-ink-thumbnail-item={item.page}\n aria-current={item.current ? 'page' : undefined}\n >\n <InkThumbnail\n page={item.page}\n width={state.width}\n annotations={annotations}\n marks={marks}\n />\n <span className=\"ink-thumbnails-label\" aria-hidden=\"true\">\n {item.page + 1}\n </span>\n {renderItem?.({ page: item.page, current: item.current })}\n </button>\n </div>\n ))}\n </div>\n )\n}\n","import {\n createRecordListController,\n type RecordListController,\n type RecordListRow,\n type RecordListSource,\n} from '@inkbar/core/dom'\nimport {\n useLayoutEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react'\n\nimport { cx } from '../class-names'\nimport { useLatest } from '../use-latest'\nimport { useReadable } from '../use-readable'\n\nexport interface RecordCardsProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n source: RecordListSource | null\n /** Whether the empty text shows when there are no rows. Default true. */\n emptyShown?: boolean | undefined\n /** Replaces \"Nothing here yet.\"; null shows nothing. */\n empty?: ReactNode\n /** Called with the number listed whenever it changes. */\n onCountChange?: ((count: number) => void) | undefined\n}\n\nconst NO_ROWS: readonly RecordListRow[] = Object.freeze([])\n\n/** A focused action button whose row re-renders: where to put focus back if it goes. */\ninterface HeldFocus {\n button: HTMLElement\n id: string\n index: number\n}\n\nconst actionButtons = (row: Element): HTMLElement[] => [\n ...row.querySelectorAll<HTMLElement>('.ink-card-actions > button'),\n]\n\n/**\n * A record list's markup on core's record list controller, shared by `InkRecordList` and\n * `InkSearchResults`: `createRecordList`'s `div.ink-records` holding `ul.ink-record-list` with\n * one `li.ink-record` card per row, the empty text and a polite live region. The controller\n * holds the rows, the count and the announcement, and handles the clicks, keys, Tab stop,\n * focus and scrolling. Empty, with no empty text, until there is a source.\n */\nexport function RecordCards({\n source,\n emptyShown = true,\n empty,\n onCountChange,\n className,\n ...rest\n}: RecordCardsProps) {\n const root = useRef<HTMLDivElement>(null)\n const [controller, setController] = useState<RecordListController | null>(null)\n const latest = useLatest(onCountChange)\n /** The count last reported, across sources and StrictMode's replayed effects. */\n const reported = useRef<number | null>(null)\n const held = useRef<HeldFocus | null>(null)\n\n useLayoutEffect(() => {\n const el = root.current\n if (!source || !el) return\n const c = createRecordListController(source)\n const report = (count: number): void => {\n if (count === reported.current) return\n reported.current = count\n latest.current?.(count)\n }\n /**\n * Before the rows re-render under a focused action whose button goes (its card lost that\n * action), note where it was; the layout effect below focuses the same place in the card,\n * else the row. A row that goes is the controller's to re-home.\n */\n const holdActionFocus = (): void => {\n const active = el.ownerDocument.activeElement\n if (!(active instanceof HTMLButtonElement) || !el.contains(active)) return\n const row = active.closest<HTMLElement>('[data-ink-record]')\n const id = row?.dataset.inkRecord\n if (!row || id === undefined) return\n held.current = { button: active, id, index: actionButtons(row).indexOf(active) }\n }\n setController(c)\n report(c.count.get())\n const stops = [c.rows.subscribe(holdActionFocus), c.count.subscribe(report)]\n const detach = c.attach(el)\n return () => {\n for (const stop of stops) stop()\n detach()\n c.destroy()\n setController(null)\n }\n }, [source, latest])\n\n const rows = useReadable(controller?.rows, NO_ROWS)\n const announcement = useReadable(controller?.announcement, '')\n const showEmpty = controller !== null && rows.length === 0 && emptyShown\n\n useLayoutEffect(() => {\n const focus = held.current\n const el = root.current\n held.current = null\n if (!focus || !el || focus.button.isConnected) return\n const row = [...el.querySelectorAll<HTMLElement>('[data-ink-record]')].find(\n (r) => r.dataset.inkRecord === focus.id\n )\n if (row) (actionButtons(row)[focus.index] ?? row).focus({ preventScroll: true })\n }, [rows])\n\n return (\n <div\n {...rest}\n ref={root}\n className={cx('ink-records', className)}\n data-ink-records=\"\"\n tabIndex={-1}\n >\n <ul className=\"ink-record-list\" role=\"list\" hidden={rows.length === 0}>\n {/* The controller sets each row's tabindex. */}\n {rows.map(({ item, card, selected }) => (\n <li\n key={item.id}\n className=\"ink-record\"\n data-ink-record={item.id}\n aria-current={selected ? 'true' : undefined}\n data-selected={selected ? '' : undefined}\n >\n <div className={cx('ink-card', card?.className)}>\n {card ? (\n <>\n <p className=\"ink-card-title\">{card.title}</p>\n {card.meta !== undefined ? (\n <p className=\"ink-card-meta\">\n {card.swatch !== undefined ? (\n <span\n className=\"ink-card-swatch\"\n style={{ background: card.swatch }}\n />\n ) : null}\n {card.meta}\n </p>\n ) : null}\n {card.body !== undefined ? (\n <p className=\"ink-card-body\">{card.body}</p>\n ) : null}\n {card.excerpt !== undefined ? (\n <p className=\"ink-card-excerpt\">\n {card.excerpt.before}\n <mark>{card.excerpt.match}</mark>\n {card.excerpt.after}\n </p>\n ) : null}\n <div className=\"ink-card-actions\">\n {Object.keys(card.actions).map((label) => (\n <button\n key={label}\n type=\"button\"\n onClick={() => controller?.act(item.id, label)}\n >\n {label}\n </button>\n ))}\n </div>\n </>\n ) : null}\n </div>\n </li>\n ))}\n </ul>\n <p className=\"ink-record-list-empty\" hidden={!showEmpty}>\n {empty === undefined ? 'Nothing here yet.' : empty}\n </p>\n <div className=\"ink-visually-hidden\" aria-live=\"polite\" data-ink-record-status=\"\">\n {announcement}\n </div>\n </div>\n )\n}\n","import {\n recordsSource,\n type CardSpec,\n type RecordListSource,\n type RecordsSourceOptions,\n} from '@inkbar/core/dom'\nimport { useEffect, useMemo, type ComponentPropsWithoutRef, type ReactNode } from 'react'\n\nimport { useInkContext } from '../context'\nimport { useToReadable } from '../to-readable'\n\nimport { RecordCards } from './RecordCards'\n\nimport type { RecordBase } from '@inkbar/core'\n\nexport interface InkRecordListProps<\n T extends RecordBase & { page: number } = RecordBase & { page: number },\n> extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {\n /** The records to list, as `<plugin>.<name>`. */\n records?: string | undefined\n /**\n * A host's own source, listed in place of `records` with the same controller and cards.\n * `card`, `where` and `sort` do not apply to it.\n */\n source?: RecordListSource | undefined\n /** The card each record shows. Default: its mark's card. */\n card?: ((record: T) => CardSpec) | undefined\n /** Which records to list. Default: those that have a mark. */\n where?: ((record: T) => boolean) | undefined\n /** The order. Default: reading order by the marks' rects. */\n sort?: ((a: T, b: T) => number) | undefined\n /** Called with the number listed whenever it changes. */\n onCountChange?: ((count: number) => void) | undefined\n /** Replaces \"Nothing here yet.\"; null shows nothing. */\n empty?: ReactNode\n}\n\nfunction isDevelopment(): boolean {\n // Bundlers replace the expression with a literal; raw browser ESM has no `process`.\n try {\n return process.env.NODE_ENV !== 'production'\n } catch {\n return false\n }\n}\n\n/**\n * The records a plugin keeps under `records` (`<plugin>.<name>`) as a list of cards, the same\n * cards their marks open, with the same actions: `createRecordList` on core's record list\n * controller. The list, the marks and `useRecordSelection` share one selection. `card`, `where`\n * and `sort` replace the marks' card, filter and reading order; a new function rebuilds the\n * list, so keep them stable (`useCallback`, or defined outside the component).\n * `onCountChange` gets the number listed whenever it changes; `empty` replaces \"Nothing here\n * yet.\". It fills its parent's height. Inside `InkRoot`; it renders empty on the server.\n *\n * In place of `records`, `source` takes a host's own `RecordListSource` and lists it with the\n * same controller and cards. Give one of the two: with both, `source` wins and a development\n * build warns.\n */\nexport function InkRecordList<\n T extends RecordBase & { page: number } = RecordBase & { page: number },\n>({\n records,\n source,\n card,\n where,\n sort,\n onCountChange,\n empty,\n ...rest\n}: InkRecordListProps<T>) {\n const ctx = useInkContext('InkRecordList')\n const viewport = useToReadable(ctx.viewport)\n const { pluginHost } = ctx\n\n const both = records !== undefined && source !== undefined\n useEffect(() => {\n if (both && isDevelopment())\n console.warn(\n '[inkbar] InkRecordList takes `records` or `source`, not both: it lists `source`.'\n )\n }, [both])\n\n const listed = useMemo((): RecordListSource | null => {\n if (source) return source\n if (!pluginHost || records === undefined) return null\n const opts: RecordsSourceOptions<T> = {}\n if (card) opts.card = card\n if (where) opts.where = where\n if (sort) opts.sort = sort\n return recordsSource<T>({ pluginHost, viewport }, records, opts)\n }, [source, pluginHost, records, card, where, sort, viewport])\n\n return (\n <RecordCards {...rest} source={listed} onCountChange={onCountChange} empty={empty} />\n )\n}\n","import {\n findCountText,\n handleResultsFieldKey,\n isBlankQuery,\n searchSource,\n} from '@inkbar/core/dom'\nimport { Search } from '@inkbar/icons'\nimport { useLayoutEffect, useMemo, useRef, type ComponentPropsWithoutRef } from 'react'\n\nimport { cx } from '../class-names'\nimport { useInkContext } from '../context'\nimport { useSearch } from '../hooks/useSearch'\n\nimport { InkIcon } from './InkIcon'\nimport { RecordCards } from './RecordCards'\n\nexport interface InkSearchResultsProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'children'\n> {\n /** Show the query field. Default true; turn it off when a find bar is on the page. */\n field?: boolean | undefined\n}\n\n/**\n * The search hits as a list of cards, for a sidebar panel: `createSearchResults` on core's\n * record list controller over the root's search. One card per hit, with its page and the text\n * around it. Choosing a card makes its hit current, as the find bar's next and previous do, and\n * the current hit is the selected card. Above the cards, a query field (`field={false}`\n * leaves it out when a find bar is on the page); under them, the find bar's match count.\n * Field and find bar share the search state, so they never disagree. It fills its parent's\n * height. Inside `InkRoot`; it renders empty on the server.\n */\nexport function InkSearchResults({\n field = true,\n className,\n ...rest\n}: InkSearchResultsProps) {\n const ctx = useInkContext('InkSearchResults')\n const search = useSearch()\n const { state } = search\n const source = useMemo(\n () => (ctx.search ? searchSource(ctx.search) : null),\n [ctx.search]\n )\n const input = useRef<HTMLInputElement>(null)\n\n // The field is the search state's: a query typed in the find bar shows here.\n useLayoutEffect(() => {\n const el = input.current\n if (el && el.value !== state.query) el.value = state.query\n }, [state.query, field])\n\n return (\n <div\n {...rest}\n className={cx('ink-search-results', className)}\n data-ink-search-results=\"\"\n >\n {field ? (\n <div className=\"ink-search-results-bar\" role=\"search\">\n <div className=\"ink-input-group\">\n <span className=\"ink-input-accessory\">\n <InkIcon icon={Search} />\n </span>\n <input\n ref={input}\n type=\"text\"\n aria-label=\"Find in document\"\n placeholder=\"Search for a word or phrase\"\n autoComplete=\"off\"\n spellCheck={false}\n defaultValue={state.query}\n onInput={(e) => search.setQuery(e.currentTarget.value)}\n onKeyDown={(e) => handleResultsFieldKey(e.nativeEvent, search)}\n />\n </div>\n </div>\n ) : null}\n {/* Nothing found yet is the count's to say while a query is in: \"No results\", or a scan. */}\n <RecordCards\n source={source}\n emptyShown={isBlankQuery(state.query)}\n empty=\"Search to list every match.\"\n />\n {/* A footer under the cards, hidden while empty. */}\n <div className=\"ink-search-results-count\" data-ink-search-results-count=\"\">\n {findCountText(state)}\n </div>\n </div>\n )\n}\n"],"mappings":"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"}