@inkbar/react 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/index.d.mts +123 -81
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +238 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["noop","IDLE","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/usePage.ts","../src/hooks/useHistory.ts","../src/hooks/useEmbedded.ts","../src/hooks/useCommand.ts","../src/use-latest.ts","../src/components/InkRoot.tsx","../src/class-names.ts","../src/components/InkAnnotation.tsx","../src/components/InkPage.tsx","../src/components/InkViewport.tsx","../src/components/InkToolbar.tsx","../src/components/InkIcon.tsx","../src/components/InkToolButton.tsx","../src/components/InkCommand.tsx","../src/components/InkToolbarSeparator.tsx","../src/components/InkUndo.tsx","../src/components/InkRedo.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/InkSignatureDialog.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 InkDocument,\n InkStatus,\n PdfAssets,\n PluginHistory,\n SignatureLibrary,\n Writable,\n} from '@inkbar/core'\nimport type {\n DecorateAnnotation,\n PluginHost,\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 /** 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}\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 { 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 { 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 createPluginHost,\n createToolOptions,\n cssVariableDefaults,\n FONT_FAMILIES,\n SIGNATURE_FONTS,\n trackToolStyle,\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 InkDocument,\n PdfAssets,\n PluginHistory,\n SignatureStore,\n Writable,\n} from '@inkbar/core'\nimport type {\n DecorateAnnotation,\n InkPlugin,\n PluginHost,\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 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 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 whether it has been torn down. */\ninterface RootHost {\n host: PluginHost\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 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 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 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 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 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 })\n hostRef.current = { host, destroyed: false }\n setPluginHost(host)\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 })\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 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 })\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 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 if (s.state === 'ready') latest.current.onReady?.(doc)\n else if (s.state === 'error') latest.current.onError?.(s.error)\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 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])\n\n useLayoutEffect(() => {\n if (annotations && document?.annotations.mode === 'controlled')\n document.annotations.setControlledValue(annotations)\n }, [annotations, 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 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 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 viewportEl: plugins.root,\n history: inkHistory,\n rootEl,\n setViewport,\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 plugins,\n inkHistory,\n rootEl,\n setViewport,\n ]\n )\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 * 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 * 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 */\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 { InkPage } from './InkPage'\n\nimport type { InkError } from '@inkbar/core'\nimport type {\n AnnotationSlotProps,\n LayoutMode,\n PageMount,\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\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\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 // 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 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 }\n }, [ctx.document, ctx.status.state, ctx.pluginHost, 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 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 </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","/*\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","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 { 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 * \"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 selects it for\n * 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 /** Called with the new template once it is saved and selected. */\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 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 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 onSave,\n onClose,\n}: {\n fonts: readonly string[] | undefined\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 setOptions({ templateId: t.id })\n setTool('signature')\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 * 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 signaturePreview,\n} from '@inkbar/core/dom'\nimport { ChevronDown, Plus, Signature, Trash2 } 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'\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/** 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 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 removeError = useReadable(signatures.removeError, undefined)\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 /** The row of a removed signature, until focus lands on what took its place. */\n const removedRow = useRef<number | null>(null)\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 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])\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 <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 {model.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 {model.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={() => {\n setOptions({ templateId: item.id })\n setTool('signature')\n setOpen(false)\n }}\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={() => {\n toDialog.current = true\n setOpen(false)\n setCreating(true)\n }}\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 </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","noop","IDLE","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/use-latest.ts","../src/components/InkRoot.tsx","../src/class-names.ts","../src/components/InkAnnotation.tsx","../src/components/InkPage.tsx","../src/components/InkViewport.tsx","../src/components/InkToolbar.tsx","../src/components/InkIcon.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/InkSignatureDialog.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 InkDocument,\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}\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 { 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 createPluginHost,\n createSearchController,\n createToolOptions,\n cssVariableDefaults,\n FONT_FAMILIES,\n handleFindKey,\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 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 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 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 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 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 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 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 })\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 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 if (s.state === 'ready') latest.current.onReady?.(doc)\n else if (s.state === 'error') latest.current.onError?.(s.error)\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 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])\n\n useLayoutEffect(() => {\n if (annotations && document?.annotations.mode === 'controlled')\n document.annotations.setControlledValue(annotations)\n }, [annotations, 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 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 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 }),\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 ]\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 * 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 * 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 */\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 { InkPage } from './InkPage'\n\nimport type { InkError } from '@inkbar/core'\nimport type {\n AnnotationSlotProps,\n LayoutMode,\n PageMount,\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\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\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 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 }\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 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 </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","/*\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","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 * \"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 selects it for\n * 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 /** Called with the new template once it is saved and selected. */\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 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 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 onSave,\n onClose,\n}: {\n fonts: readonly string[] | undefined\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 setOptions({ templateId: t.id })\n setTool('signature')\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 * 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 signaturePreview,\n} from '@inkbar/core/dom'\nimport { ChevronDown, Plus, Signature, Trash2 } 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'\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/** 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 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 removeError = useReadable(signatures.removeError, undefined)\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 /** The row of a removed signature, until focus lands on what took its place. */\n const removedRow = useRef<number | null>(null)\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 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])\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 <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 {model.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 {model.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={() => {\n setOptions({ templateId: item.id })\n setTool('signature')\n setOpen(false)\n }}\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={() => {\n toDialog.current = true\n setOpen(false)\n setCreating(true)\n }}\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 </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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"}
|