@inkbar/core 0.3.0 → 0.5.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/dist/dom.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Dt as Quad, Et as Point, L as Annotation, M as cssVariableDefaults, Ot as Rect, St as PageInfo, Tt as Matrix, W as ConfidenceBucket, _t as Readable, a as OpenOptions, b as AnnotationStore, ct as RedactAnnotation, ft as Suggestion, i as InkStatus, j as AnnotationDefaults, l as DocumentSource, r as InkDocument, tt as NoteAnnotation, u as InkError, wt as PdfAssets } from "./document-BftlPZKU.mjs";
1
+ import { D as OpenOptions, E as InkStatus, H as AnnotationStore, M as InkError, Rt as NoteAnnotation, T as InkDocument, _ as StyleGroup, a as SignatureStore, b as ToolStyle, cn as PageInfo, dn as Matrix, fn as Point, g as ScopedToolStyle, i as SignatureOptions, it as cssVariableDefaults, j as DocumentSource, jt as LineEnding, m as CurrentStyle, mn as Rect, o as SignatureTemplate, pn as Quad, r as SignatureLibrary, rn as Readable, rt as AnnotationDefaults, st as Annotation, tn as TextMarkupAnnotation, un as PdfAssets, v as StyleKey, y as StyleProps, yt as FreeTextAnnotation } from "./signatures-BwaXi7C8.mjs";
2
2
  import { IconNode } from "@inkbar/icons";
3
3
  //#region src/dom/transform.d.ts
4
4
  type ViewRotation = 0 | 90 | 180 | 270;
@@ -249,16 +249,45 @@ interface OverlayOptions {
249
249
  onActivate?(id: string): void;
250
250
  /** Return true to render only the positioned shell; the host (e.g. a Vue slot) fills it. */
251
251
  isCustom?(annotation: Annotation): boolean;
252
+ /**
253
+ * The document the page belongs to. Loupes magnify its page content; without it they show
254
+ * only their rim.
255
+ */
256
+ document?: InkDocument;
257
+ /** Fixed device pixel ratio for loupes; `window.devicePixelRatio` when omitted. */
258
+ devicePixelRatio?: number;
259
+ /**
260
+ * The app's own data attributes, classes and description for an annotation's element, read
261
+ * whenever the annotations change and on `redecorate`. Core's own attributes and `ink-`
262
+ * classes win over them.
263
+ */
264
+ decorate?: DecorateAnnotation;
265
+ }
266
+ /**
267
+ * Data attributes, classes and a description an app adds to an annotation's element, to style
268
+ * or find its own marks. Each `data` key is written as `data-<key>`.
269
+ */
270
+ interface AnnotationDecoration {
271
+ /** Written as data-<key>; keys are lower-case kebab (/^[a-z][a-z0-9-]*$/). */
272
+ data?: Readonly<Record<string, string>>;
273
+ classes?: readonly string[];
274
+ /**
275
+ * Extra words screen readers announce after the element's label, such as "Needs review".
276
+ * Written as `aria-description`.
277
+ */
278
+ description?: string;
252
279
  }
280
+ /** Returns the decoration for an annotation's element, or undefined for none. */
281
+ type DecorateAnnotation = (annotation: Annotation) => AnnotationDecoration | undefined;
253
282
  interface Overlay {
254
283
  readonly element: HTMLElement;
255
284
  /** Repositions every element and redraws content for a new zoom or rotation. */
256
285
  update(transform: PageTransform): void;
257
286
  elementFor(id: string): HTMLElement | undefined;
287
+ /** Runs `decorate` again for every element, for when its output changed but no annotation did. */
288
+ redecorate(): void;
258
289
  destroy(): void;
259
290
  }
260
- /** The `data-confidence` bucket for a suggested redaction; undefined for everything else. */
261
- export declare function confidenceAttr(a: Annotation): 'low' | 'medium' | 'high' | undefined;
262
291
  export declare function createOverlay(opts: OverlayOptions): Overlay;
263
292
  //#endregion
264
293
  //#region src/dom/overlay-render.d.ts
@@ -280,6 +309,8 @@ interface PageMountOptions {
280
309
  store: AnnotationStore;
281
310
  onActivate?(id: string): void;
282
311
  isCustom?(a: Annotation): boolean;
312
+ /** The app's data attributes and classes for each annotation element (see `OverlayOptions`). */
313
+ decorate?: DecorateAnnotation;
283
314
  /** Defaults to `window.devicePixelRatio`. */
284
315
  devicePixelRatio?: number;
285
316
  /**
@@ -305,8 +336,27 @@ interface PageMount {
305
336
  /** Canvas, text layer and annotation overlay for one page, stacked in that order. */
306
337
  export declare function createPageMount(opts: PageMountOptions): PageMount;
307
338
  //#endregion
339
+ //#region src/dom/tools/options.d.ts
340
+ interface ToolOptions {
341
+ /** The tool's current options. Throws a `RangeError` for an id no tool registered. */
342
+ readable(id: ToolId): Readable<object>;
343
+ get(id: ToolId): object;
344
+ /** Merges `patch` into the tool's options. */
345
+ merge(id: ToolId, patch: object): void;
346
+ /** Registers tools not seen yet, seeded from their `defaultOptions`; known ids keep theirs. */
347
+ register(tools: readonly Tool[]): void;
348
+ }
349
+ export declare function createToolOptions(tools?: readonly Tool[]): ToolOptions;
350
+ //#endregion
308
351
  //#region src/dom/tools/controller.d.ts
309
- type ToolId = 'view' | 'select' | 'highlight' | 'redact-area' | 'note';
352
+ type BuiltinToolId = 'select-text' | 'select' | 'highlight' | 'redact-area' | 'note' | 'shape' | 'freetext' | 'draw' | 'sketch' | 'signature';
353
+ /** A built-in tool's id, or any id a host registers its own tool under. */
354
+ type ToolId = BuiltinToolId | (string & {});
355
+ /**
356
+ * A one-shot tool switches back to `select-text` once it has made something and the user moves
357
+ * on; a sticky tool stays on. A tool without a kind is sticky.
358
+ */
359
+ type ToolKind = 'one-shot' | 'sticky';
310
360
  interface PageHit extends ViewportHit {
311
361
  /** Pointer position in user space. */
312
362
  user: Point;
@@ -322,18 +372,45 @@ interface ToolContext {
322
372
  selectionQuads(): SelectionQuads[];
323
373
  clearSelection(): void;
324
374
  onActivate?(id: string): void;
375
+ /** The style each group creates with, shared with the style controls. */
376
+ toolStyle: ToolStyle;
377
+ /** The active tool's current options. */
378
+ options<O extends object>(): O;
379
+ /**
380
+ * Groups a gesture's changes into one undo step (a group move). Without it each change is
381
+ * its own step.
382
+ */
383
+ history?: {
384
+ batch(fn: () => void): void;
385
+ };
386
+ /** The signature templates the `signature` tool places. Without it, it places nothing. */
387
+ signatures?: SignatureLibrary | undefined;
388
+ /**
389
+ * A one-shot tool reports what it just made, already added and selected. Does nothing under
390
+ * a sticky tool or with an empty list.
391
+ */
392
+ made(ids: readonly string[]): void;
393
+ /** Clears the selection and switches to `select-text`. */
394
+ done(): void;
325
395
  }
326
- interface Tool {
396
+ interface Tool<O extends object = object> {
327
397
  id: ToolId;
398
+ /** Default sticky. */
399
+ kind?: ToolKind;
328
400
  cursor: string;
401
+ /** Style group the tool creates into; select tools have none. */
402
+ styleGroup?: StyleGroup;
403
+ /** Option defaults. Options persist per tool for the viewer's life. */
404
+ defaultOptions?: O;
329
405
  activate(ctx: ToolContext): void;
330
406
  deactivate(): void;
331
407
  /**
332
408
  * Runs in the capture phase, before the overlay sees the press. `annotationId` is set when
333
- * the press landed on an annotation; the overlay then selects and activates it, so tools
334
- * other than `select` should ignore such presses. Calling `e.stopPropagation()` here keeps
335
- * the overlay from handling it. Return true when the press starts a gesture: the controller
336
- * then captures the pointer until it is released or cancelled.
409
+ * the press landed on an annotation; the overlay then selects and activates it (text markup
410
+ * on a click, other types on the press), so tools other than the select tools should ignore
411
+ * such presses. Calling `e.stopPropagation()` here keeps the overlay from handling it.
412
+ * Return true when the press starts a gesture: the controller then captures the pointer
413
+ * until it is released or cancelled.
337
414
  */
338
415
  onPointerDown?(e: PointerEvent, hit: PageHit | undefined, annotationId?: string): boolean | void;
339
416
  /**
@@ -348,14 +425,29 @@ interface Tool {
348
425
  }
349
426
  interface ToolController {
350
427
  readonly active: Readable<ToolId>;
351
- set(id: ToolId): void;
428
+ /** Switches to the tool, first merging `options` into its options. */
429
+ set(id: ToolId, options?: object): void;
430
+ /** Merges `patch` into a tool's options without switching to it. */
431
+ setOptions(id: ToolId, patch: object): void;
432
+ options(id: ToolId): Readable<object>;
352
433
  destroy(): void;
353
434
  }
354
435
  interface ToolControllerOptions {
355
- ctx: ToolContext;
356
- /** Default `'view'`. */
436
+ /**
437
+ * The controller adds `options`, `made` and `done`; `toolStyle` defaults to one of the
438
+ * controller's own.
439
+ */
440
+ ctx: Omit<ToolContext, 'toolStyle' | 'options' | 'made' | 'done'> & {
441
+ toolStyle?: ToolStyle;
442
+ };
443
+ /** Default `'select-text'`. */
357
444
  initial?: ToolId;
358
445
  tools: Tool[];
446
+ /**
447
+ * Where options live. Pass the same registry to each controller that replaces another (a
448
+ * rebuild) so options persist; by default the controller keeps its own.
449
+ */
450
+ options?: ToolOptions;
359
451
  }
360
452
  /** The mounted page under a client point, with the point in CSS px and user space. */
361
453
  export declare function hitFor(ctx: ToolContext, e: {
@@ -363,12 +455,27 @@ export declare function hitFor(ctx: ToolContext, e: {
363
455
  clientY: number;
364
456
  }): PageHit | undefined;
365
457
  //#endregion
458
+ //#region src/dom/tools/freetext.d.ts
459
+ /** Width of a box placed with a click or Enter, user-space points. */
460
+ export declare const DEFAULT_FREETEXT_WIDTH = 144;
461
+ export declare function freetextTool(): Tool;
462
+ //#endregion
366
463
  //#region src/dom/tools/highlight.d.ts
464
+ type MarkupKind = TextMarkupAnnotation['type'];
465
+ /** The text markup kinds, in menu order. */
466
+ export declare const MARKUP_KINDS: readonly MarkupKind[];
467
+ interface HighlightOptions {
468
+ /** Which text markup the tool makes. */
469
+ kind: MarkupKind;
470
+ }
471
+ export declare const DEFAULT_HIGHLIGHT_OPTIONS: Readonly<HighlightOptions>;
367
472
  /**
368
- * Turns the text selection into one highlight per page when the pointer is released, or on
369
- * Enter in the viewport (a keyboard selection). Without a selection both do nothing.
473
+ * Turns the text selection into one markup of the chosen kind per page when the pointer is
474
+ * released, or on Enter in the viewport (a keyboard selection), and selects what it made.
475
+ * Without a selection both do nothing. The markup's `contents` is left for a comment: hosts
476
+ * read the marked text with `doc.text(page)`.
370
477
  */
371
- export declare function highlightTool(): Tool;
478
+ export declare function highlightTool(): Tool<HighlightOptions>;
372
479
  //#endregion
373
480
  //#region src/dom/tools/note.d.ts
374
481
  /**
@@ -381,25 +488,288 @@ export declare function noteTool(): Tool;
381
488
  export declare function redactAreaTool(): Tool;
382
489
  //#endregion
383
490
  //#region src/dom/tools/select.d.ts
491
+ /**
492
+ * Rectangle select: a drag on empty space draws a marquee that selects the annotations it
493
+ * touches (`Shift` adds to the selection). Presses on annotations select, move and resize them
494
+ * as `select-text` does (selection-edit.ts).
495
+ */
384
496
  export declare function selectTool(): Tool;
385
497
  //#endregion
386
- //#region src/dom/tools/view.d.ts
387
- /** Reading only: text selection stays native and the overlay still selects annotations. */
388
- export declare function viewTool(): Tool;
498
+ //#region src/dom/tools/select-text.d.ts
499
+ /**
500
+ * The default tool. Text selection stays native: presses on text, and drags across text
501
+ * markup, select text. Presses on other annotations select them, and drags move and resize
502
+ * them (selection-edit.ts). There is no marquee.
503
+ */
504
+ export declare function selectTextTool(): Tool;
505
+ //#endregion
506
+ //#region src/model/annotations/shape-geometry.d.ts
507
+ /** Every kind the shape menu can offer. Kinds without a creator yet are not in `SHAPE_KINDS`. */
508
+ type ShapeKind = 'line' | 'arrow' | 'rectangle' | 'roundedRectangle' | 'ellipse' | 'bubble' | 'star' | 'polygon' | 'loupe' | 'mask' | 'ovalMask';
509
+ interface ShapeOptions {
510
+ kind: ShapeKind;
511
+ /** Points of a star. */
512
+ points: number;
513
+ /** Sides of a polygon. */
514
+ sides: number;
515
+ }
516
+ /** The kinds the shape menu offers today, in menu order. Later kinds extend this. */
517
+ export declare const SHAPE_KINDS: readonly ShapeKind[];
518
+ /** Side of the shape a click or Enter places, in points. */
519
+ export declare const DEFAULT_SHAPE_SIZE = 72;
520
+ /** Corner radius of a new rounded rectangle, in points. */
521
+ export declare const DEFAULT_CORNER_RADIUS = 8;
522
+ //#endregion
523
+ //#region src/dom/tools/shape.d.ts
524
+ export declare function shapeTool(): Tool<ShapeOptions>;
525
+ //#endregion
526
+ //#region src/dom/tools/signature.d.ts
527
+ export declare function signatureTool(): Tool<SignatureOptions>;
389
528
  //#endregion
390
529
  //#region src/dom/tools/index.d.ts
391
530
  /** Fresh instances of every built-in tool. */
392
531
  export declare function builtinTools(): Tool[];
532
+ /** The built-in tools with a host's tools added, a host tool replacing a built-in by id. */
533
+ export declare function withHostTools(host?: readonly Tool[]): Tool[];
393
534
  /** Listens on `ctx.root` and routes pointer and key events to the active tool. */
394
535
  export declare function createToolController(opts: Omit<ToolControllerOptions, 'tools'> & {
395
536
  tools?: Tool[];
396
537
  }): ToolController;
538
+ interface ToolStyleTracker {
539
+ readonly toolStyle: ToolStyle;
540
+ /** Call when the active tool changes: the style's active group follows it. */
541
+ setTool(id: ToolId): void;
542
+ }
543
+ /**
544
+ * A `ToolStyle` whose active group is the style group of the active tool among `tools` (the
545
+ * built-ins plus a host's). The engine makes one when it is not handed a style; a binding
546
+ * makes its own per document, so its style controls work before the viewport mounts.
547
+ */
548
+ export declare function trackToolStyle(opts: {
549
+ store: AnnotationStore;
550
+ history: {
551
+ batch(fn: () => void): void;
552
+ };
553
+ /** Host tools, as passed to `mountViewer`. */
554
+ tools?: readonly Tool[] | undefined;
555
+ tool?: ToolId | undefined;
556
+ }): ToolStyleTracker;
397
557
  //#endregion
398
558
  //#region src/dom/ui.d.ts
399
- /** Accessible names of the built-in tools, as the toolbar buttons announce them. */
400
- export declare const TOOL_LABELS: Readonly<Record<ToolId, string>>;
559
+ /**
560
+ * Accessible names of the built-in tools, as the toolbar buttons announce them. A host tool has
561
+ * no entry: its button takes the host's `label`, else the tool id.
562
+ */
563
+ export declare const TOOL_LABELS: Readonly<Partial<Record<ToolId, string>>>;
564
+ /**
565
+ * The font families a text box offers by default: the PDF standard families, which a PDF
566
+ * writer can use without embedding a font. Hosts pass their own list as `fonts`.
567
+ */
568
+ export declare const FONT_FAMILIES: readonly string[];
569
+ /**
570
+ * The fonts a typed signature offers by default: the browser's own handwriting family. Hosts
571
+ * load handwriting fonts and pass them as `signatureFonts`.
572
+ */
573
+ export declare const SIGNATURE_FONTS: readonly string[];
401
574
  /** Zoom levels the zoom select offers, as scale factors. */
402
575
  export declare const ZOOM_LEVELS: readonly number[];
576
+ /** Stroke weights the line style menu offers, in points. */
577
+ export declare const LINE_WEIGHTS: readonly number[];
578
+ /** The dash pattern the menu's dashed choice writes, in points. */
579
+ export declare const DASH_PATTERN: readonly number[];
580
+ /** The ending the menu's arrowhead choices draw. */
581
+ export declare const ARROWHEAD_ENDING: LineEnding;
582
+ type ArrowheadChoice = 'none' | 'start' | 'end' | 'both';
583
+ /** The arrowhead choices in menu order, with the style each one writes (`head` is the start). */
584
+ export declare const ARROWHEAD_CHOICES: readonly {
585
+ value: ArrowheadChoice;
586
+ label: string;
587
+ patch: Pick<StyleProps, 'head' | 'tail'>;
588
+ }[];
589
+ /**
590
+ * Which arrowhead choice a style shows, `'mixed'` when the selection disagrees, else `undefined`.
591
+ * Only an ending Inkbar draws counts: one it does not know draws as `None`.
592
+ */
593
+ export declare function arrowheadChoice(head: LineEnding | 'mixed' | undefined, tail: LineEnding | 'mixed' | undefined): ArrowheadChoice | 'mixed' | undefined;
594
+ interface LineStyleMenuItem {
595
+ key: string;
596
+ label: string;
597
+ checked: boolean;
598
+ /** What choosing the item writes through the tool style. */
599
+ patch: StyleProps;
600
+ }
601
+ interface LineStyleMenuSection {
602
+ label: string;
603
+ /** The selection or active tool supports none of the section's props. */
604
+ disabled: boolean;
605
+ items: LineStyleMenuItem[];
606
+ }
607
+ interface LineStyleMenuModel {
608
+ /** False when nothing supports weight, pattern or endings: the trigger disables. */
609
+ enabled: boolean;
610
+ /** The selection disagrees on weight, pattern or endings. */
611
+ mixed: boolean;
612
+ sections: LineStyleMenuSection[];
613
+ }
614
+ /**
615
+ * What the line style menu shows for a style: sections of checkable items, each section
616
+ * disabled when `supported` lacks its props. A section whose value is mixed checks nothing.
617
+ * Shared by the bindings and the vanilla menu so they cannot drift apart.
618
+ */
619
+ export declare function lineStyleMenuModel(current: CurrentStyle, supported: ReadonlySet<StyleKey>): LineStyleMenuModel;
620
+ /** The colour props a colour menu can set. */
621
+ type ColorProperty = 'border' | 'fill' | 'textColor';
622
+ /** Accessible names of the colour menus, by property. */
623
+ export declare const COLOR_LABELS: Readonly<Record<ColorProperty, string>>;
624
+ /** Columns of the swatch grid: the arrow keys move by this much between rows. */
625
+ export declare const COLOR_COLUMNS = 12;
626
+ interface ColorMenuSwatch {
627
+ /** Unique within the menu. */
628
+ key: string;
629
+ /** The swatch's accessible name: its hex value. */
630
+ label: string;
631
+ color: string;
632
+ checked: boolean;
633
+ patch: StyleProps;
634
+ }
635
+ /** What the trigger's swatch shows. */
636
+ type ColorTrigger = {
637
+ kind: 'color';
638
+ color: string;
639
+ } |
640
+ /** No fill. */
641
+ {
642
+ kind: 'none';
643
+ } |
644
+ /** The selection disagrees. */
645
+ {
646
+ kind: 'mixed';
647
+ } |
648
+ /** Nothing to show: the menu is disabled or the style has no value. */
649
+ {
650
+ kind: 'empty';
651
+ };
652
+ interface ColorMenuModel {
653
+ label: string;
654
+ /** False when nothing supports the property: the trigger disables. */
655
+ enabled: boolean;
656
+ mixed: boolean;
657
+ trigger: ColorTrigger;
658
+ /** Common colours, greys, then the tonal grid, `COLOR_COLUMNS` to a row. */
659
+ swatches: ColorMenuSwatch[];
660
+ /** The "No fill" choice, for `fill` only. */
661
+ noFill: {
662
+ checked: boolean;
663
+ patch: StyleProps;
664
+ } | null;
665
+ /** The colour the custom picker starts on. */
666
+ customValue: string;
667
+ /** What picking `hex` in the custom picker writes. */
668
+ custom(hex: string): StyleProps;
669
+ }
670
+ /**
671
+ * What a colour menu shows for a style: the palette with the matching swatch checked, "No fill"
672
+ * for `fill`, and the trigger's swatch. Shared by the bindings and the vanilla menu. `fallback`
673
+ * is the colour new annotations get while the style leaves it unset: the trigger shows it
674
+ * rather than an empty swatch.
675
+ */
676
+ export declare function colorMenuModel(property: ColorProperty, current: CurrentStyle, supported: ReadonlySet<StyleKey>, fallback?: string): ColorMenuModel;
677
+ /** A typed size as the menu stores it: a whole number of points within the range. */
678
+ export declare function clampFontSize(size: number): number;
679
+ type TextToggleKey = 'bold' | 'italic' | 'underline';
680
+ type TextAlignKey = 'left' | 'center' | 'right' | 'justify';
681
+ interface TextStyleToggle {
682
+ key: TextToggleKey;
683
+ label: string;
684
+ /** `'mixed'` when the selection disagrees. */
685
+ pressed: boolean | 'mixed';
686
+ /** What pressing writes: the opposite of `pressed`, and on for a mix. */
687
+ patch: StyleProps;
688
+ }
689
+ interface TextAlignChoice {
690
+ key: TextAlignKey;
691
+ label: string;
692
+ checked: boolean;
693
+ /** The one radio in the Tab order: the checked one, else the first. */
694
+ tabStop: boolean;
695
+ patch: StyleProps;
696
+ }
697
+ interface TextStyleMenuModel {
698
+ label: string;
699
+ /** False when nothing supports text style: the trigger disables. */
700
+ enabled: boolean;
701
+ mixed: boolean;
702
+ font: {
703
+ label: string;
704
+ /** The family, or `''` when the selection disagrees. */
705
+ value: string;
706
+ /** The families on offer, each once; a current family outside the list is added. */
707
+ options: string[];
708
+ patch(family: string): StyleProps;
709
+ };
710
+ size: {
711
+ label: string;
712
+ /** The size, the default when the style sets none, or `null` when the selection disagrees. */
713
+ value: number | null;
714
+ min: number;
715
+ max: number;
716
+ step: number;
717
+ /** What committing a typed size writes, or `null` when it changes nothing. */
718
+ commit(raw: number): StyleProps | null;
719
+ /** What a stepper press writes, or `null` at the end of the range. */
720
+ nudge(direction: 1 | -1): StyleProps | null;
721
+ };
722
+ toggles: TextStyleToggle[];
723
+ align: {
724
+ label: string;
725
+ choices: TextAlignChoice[];
726
+ };
727
+ }
728
+ /**
729
+ * What the text style menu shows for a style: the font, size, bold/italic/underline and
730
+ * alignment, each with the patch choosing it. `fonts` is the list the host offers.
731
+ */
732
+ export declare function textStyleMenuModel(current: CurrentStyle, supported: ReadonlySet<StyleKey>, fonts: readonly string[]): TextStyleMenuModel;
733
+ /** Accessible names of the shape kinds, as the shape menu announces them. */
734
+ export declare const SHAPE_LABELS: Readonly<Record<ShapeKind, string>>;
735
+ /** Accessible names of the text markup kinds, as the highlight menu announces them. */
736
+ export declare const MARKUP_LABELS: Readonly<Record<MarkupKind, string>>;
737
+ interface HighlightMenuItem {
738
+ kind: MarkupKind;
739
+ label: string;
740
+ checked: boolean;
741
+ }
742
+ interface HighlightMenuModel {
743
+ /** The kind the main button makes. */
744
+ kind: MarkupKind;
745
+ /** The main button's accessible name. */
746
+ label: string;
747
+ /** The kinds on offer, in menu order, with the current one checked. */
748
+ items: HighlightMenuItem[];
749
+ }
750
+ /** What the highlight menu shows for the highlight tool's options. */
751
+ export declare function highlightMenuModel(options: Partial<HighlightOptions>, kinds: readonly MarkupKind[]): HighlightMenuModel;
752
+ /** Columns of the shape grid: the arrow keys move by this much between rows. */
753
+ export declare const SHAPE_COLUMNS = 2;
754
+ interface ShapeMenuItem {
755
+ kind: ShapeKind;
756
+ label: string;
757
+ checked: boolean;
758
+ }
759
+ interface ShapeMenuModel {
760
+ /** The kind the main button draws. */
761
+ kind: ShapeKind;
762
+ /** The main button's accessible name. */
763
+ label: string;
764
+ /** The kinds on offer, in menu order, with the current one checked. */
765
+ items: ShapeMenuItem[];
766
+ }
767
+ /**
768
+ * What the shape menu shows for the shape tool's options, over the kinds in `kinds`
769
+ * (`SHAPE_KINDS`). A kind that is not on offer falls back to `rectangle` when that is offered,
770
+ * else to the first.
771
+ */
772
+ export declare function shapeMenuModel(options: Partial<ShapeOptions>, kinds: readonly ShapeKind[]): ShapeMenuModel;
403
773
  /** The overlay's per-annotation state, as on its `data-state` attribute. */
404
774
  type AnnotationState = 'idle' | 'hover' | 'selected';
405
775
  /**
@@ -412,29 +782,137 @@ interface AnnotationSlotProps {
412
782
  locked: boolean;
413
783
  select: () => void;
414
784
  remove: () => void;
415
- /** Turns a suggested redaction into the user's own. No-op for anything else. */
416
- accept: () => void;
417
- /** Removes a suggested redaction. No-op for anything else. */
418
- dismiss: () => void;
419
- }
420
- /** What a host-rendered note thread receives. */
421
- interface NotePopoverSlotProps {
422
- note: NoteAnnotation;
785
+ }
786
+ /** The thread popover's accessible name: "Note thread" for a note, "Comment thread" for markup. */
787
+ export declare function threadPopoverLabel(root: Pick<Annotation, 'type'>): string;
788
+ /**
789
+ * The thread popover's delete button. It removes the root and its replies, so on text markup
790
+ * it says it deletes the highlight, not only the comment.
791
+ */
792
+ export declare function threadDeleteLabel(root: Pick<Annotation, 'type'>): string;
793
+ /** What a host-rendered comment thread receives: a note's, or text markup's. */
794
+ interface ThreadPopoverSlotProps {
795
+ root: NoteAnnotation | TextMarkupAnnotation;
423
796
  replies: Annotation[];
424
797
  reply: (text: string) => void;
425
798
  update: (contents: string) => void;
426
799
  remove: () => void;
427
800
  close: () => void;
428
801
  }
429
- /** What a host-rendered suggestion card receives. */
430
- interface SuggestionCardSlotProps {
431
- annotation: RedactAnnotation;
432
- suggestion: Suggestion | undefined;
433
- bucket: ConfidenceBucket | undefined;
434
- accept: () => void;
435
- dismiss: () => void;
436
- close: () => void;
802
+ /** The signature controls' words, shared so every binding announces the same names. */
803
+ export declare const SIGNATURE_LABELS: {
804
+ /** The menu's group and main button. */
805
+ readonly sign: "Sign";
806
+ readonly trigger: "Choose signature";
807
+ readonly menu: "Signatures";
808
+ readonly saved: "Saved signatures";
809
+ readonly create: "Create signature";
810
+ /** The dialog's title. */
811
+ readonly dialog: "Create signature";
812
+ readonly tabs: "Signature source";
813
+ readonly draw: "Draw";
814
+ readonly type: "Type";
815
+ readonly image: "Image";
816
+ readonly pad: "Signature pad";
817
+ readonly clear: "Clear";
818
+ readonly name: "Name";
819
+ readonly namePlaceholder: "Your name";
820
+ readonly fonts: "Font";
821
+ readonly file: "Image file";
822
+ readonly cancel: "Cancel";
823
+ readonly save: "Save";
824
+ };
825
+ /** The dialog's tabs, in order. */
826
+ export declare const SIGNATURE_TABS: readonly ["draw", "type", "image"];
827
+ type SignatureTab = (typeof SIGNATURE_TABS)[number];
828
+ interface SignatureMenuItem {
829
+ id: string;
830
+ /** `Signature 1`, `Signature 2`… in saved order. */
831
+ label: string;
832
+ /** The remove button's accessible name. */
833
+ removeLabel: string;
834
+ checked: boolean;
835
+ template: SignatureTemplate;
437
836
  }
837
+ interface SignatureMenuModel {
838
+ /** The template the tool places, when it is still saved. */
839
+ selected: SignatureTemplate | undefined;
840
+ items: SignatureMenuItem[];
841
+ }
842
+ /** What the signature menu shows for the saved templates and the signature tool's options. */
843
+ export declare function signatureMenuModel(templates: readonly SignatureTemplate[], options: SignatureOptions): SignatureMenuModel;
844
+ //#endregion
845
+ //#region src/dom/palette.d.ts
846
+ interface Palette {
847
+ /** 12 swatches, the top row. */
848
+ readonly common: readonly string[];
849
+ /** 12 greys, white to black. */
850
+ readonly greys: readonly string[];
851
+ /** 8 rows of 12 hue columns (red round to rose in 30 degree steps), dark to light. */
852
+ readonly grid: readonly (readonly string[])[];
853
+ }
854
+ export declare const PALETTE: Palette;
855
+ //#endregion
856
+ //#region src/dom/freetext-editor.d.ts
857
+ interface FreeTextEditor {
858
+ /** Closes the editor, handing its text to `commit` (true) or calling `cancel` (false). */
859
+ close(commit: boolean): void;
860
+ }
861
+ /**
862
+ * What closed an editor: Escape, a press outside it, focus leaving it, or a call to `close`
863
+ * (a redraw, the page unmounting, the box being removed, a tool switch).
864
+ */
865
+ type EditorCloseReason = 'escape' | 'press' | 'focus' | 'api';
866
+ interface FreeTextEditorOptions {
867
+ transform: PageTransform;
868
+ /**
869
+ * The edited text and the box's rect, grown to fit it (`grownFreeText`), in user space.
870
+ * `grown` is the growth alone, in CSS px (0 when the box kept its height), for a caller whose
871
+ * box may have moved or been resized while the editor was open. `how` says what closed it.
872
+ */
873
+ commit(contents: string, rect: Rect, grown: number, how: EditorCloseReason): void;
874
+ cancel(): void;
875
+ /** Where to put the caret, a client point (a click on the box); at the end when absent. */
876
+ caret?: {
877
+ clientX: number;
878
+ clientY: number;
879
+ } | undefined;
880
+ }
881
+ /**
882
+ * Opens an editor on `el`, the overlay element showing `a` (or a stand-in for a box not in the
883
+ * store yet), with the caret at `opts.caret` or after the text. `Escape` commits; a press
884
+ * outside the editor, or focus leaving it, commits too.
885
+ * Closing while the editor has focus hands focus to `el`. Keys typed in the
886
+ * editor stop there, so no viewport or tool shortcut sees them. Opening a second editor on the
887
+ * same element commits the first.
888
+ */
889
+ export declare function editFreeText(el: HTMLElement, a: FreeTextAnnotation, opts: FreeTextEditorOptions): FreeTextEditor;
890
+ //#endregion
891
+ //#region src/dom/menu-keys.d.ts
892
+ /** The menu's enabled items in document order. */
893
+ export declare function menuItems(root: ParentNode): HTMLElement[];
894
+ /** Focuses the first checked item, else the first enabled one. */
895
+ export declare function focusInitialMenuItem(root: ParentNode): void;
896
+ /**
897
+ * ArrowDown and ArrowUp move between enabled items and wrap; Home and End go to the ends.
898
+ * Inside a grid the arrow keys move in both directions.
899
+ */
900
+ export declare function handleMenuKeys(e: KeyboardEvent, root: ParentNode): void;
901
+ /**
902
+ * Arrow keys inside a `role="radiogroup"`: the next (or previous) enabled `role="radio"`
903
+ * takes focus and is chosen, wrapping at the ends, as a native radio group does.
904
+ */
905
+ export declare function handleRadioKeys(e: KeyboardEvent, group: ParentNode): void;
906
+ /**
907
+ * Arrow keys, Home and End inside a `role="tablist"`: the next (or previous) enabled
908
+ * `role="tab"` takes focus and is chosen, wrapping at the ends.
909
+ */
910
+ export declare function handleTabKeys(e: KeyboardEvent, tablist: ParentNode): void;
911
+ /**
912
+ * Keeps Tab inside `container`, a modal: Tab from its last stop goes to its first, and
913
+ * Shift+Tab from the first to the last.
914
+ */
915
+ export declare function trapTab(e: KeyboardEvent, container: HTMLElement): void;
438
916
  //#endregion
439
917
  //#region src/dom/annotation-element.d.ts
440
918
  /** The overlay element drawn for annotation `id` under `root`, if it is in the DOM. */
@@ -471,6 +949,54 @@ interface FocusReturn {
471
949
  }
472
950
  export declare function createFocusReturn(opts: FocusReturnOptions): FocusReturn;
473
951
  //#endregion
952
+ //#region src/dom/viewer/popover.d.ts
953
+ /** Options for `createPopover`. */
954
+ interface PopoverOptions {
955
+ /** The viewer root (`[data-ink-root]`): anchors are looked up and focus returns inside it. */
956
+ root: HTMLElement;
957
+ /**
958
+ * Attributes for the panel, such as `class`, `aria-label` or the app's own `data-*` keys.
959
+ * `role` and `data-ink-popover` are always set by `createPopover`.
960
+ */
961
+ attrs: Record<string, string>;
962
+ /** Where focus goes when the panel hides: `createFocusReturn` over the same root. */
963
+ focusReturn: FocusReturn;
964
+ /**
965
+ * Called on Escape inside the panel or the viewer, and on a press outside the panel that will
966
+ * not activate another annotation. Hide the panel (or clear the activation) here.
967
+ */
968
+ onDismiss(): void;
969
+ }
970
+ /** A panel anchored to one annotation at a time; see `createPopover`. */
971
+ interface Popover {
972
+ /** The panel element, on `<body>`. Fill it with the card's content. */
973
+ readonly panel: HTMLElement;
974
+ /** The anchored annotation's element, or null while it is not in the DOM (page unmounted). */
975
+ readonly anchor: HTMLElement | null;
976
+ /**
977
+ * Anchors the panel to annotation `id`. The panel shows whenever that annotation's element
978
+ * is in the DOM, and follows it when it is replaced.
979
+ */
980
+ show(id: string): void;
981
+ /** Hides the panel, then returns focus through `focusReturn`. */
982
+ hide(): void;
983
+ /** Removes the panel and its listeners. */
984
+ destroy(): void;
985
+ }
986
+ /**
987
+ * Positions `panel` (fixed) below the `anchor` rectangle, or above it when only that fits,
988
+ * kept inside the window. For panels anchored to something other than an annotation.
989
+ */
990
+ export declare function placePanel(panel: HTMLElement, anchor: DOMRect): void;
991
+ /**
992
+ * Creates a non-modal `role="dialog"` panel on `<body>`, marked `data-ink-popover` so the theme
993
+ * gives it its tokens, that an app anchors to an annotation with `show(id)` (for instance on
994
+ * `viewer.activated`). The panel follows the annotation's element as pages mount and unmount:
995
+ * it hides while the element is gone and comes back with it. Tab loops inside the panel, and
996
+ * Escape or a press outside calls `onDismiss`. Call `destroy` when done.
997
+ */
998
+ export declare function createPopover(opts: PopoverOptions): Popover;
999
+ //#endregion
474
1000
  //#region src/dom/viewer-engine.d.ts
475
1001
  interface MountViewerOptions {
476
1002
  container: HTMLElement;
@@ -482,8 +1008,63 @@ interface MountViewerOptions {
482
1008
  gap?: number;
483
1009
  buffer?: number;
484
1010
  tool?: ToolId;
1011
+ /**
1012
+ * Host tools, added to the built-ins. A host tool with a built-in's id replaces it. The same
1013
+ * instances are reused when the engine rebuilds.
1014
+ */
1015
+ tools?: Tool[];
1016
+ /**
1017
+ * The tools' options (the shape kind, the highlight kind…). A binding or `createViewer` passes
1018
+ * one it keeps for its own life, so options persist across documents, as for the life of the
1019
+ * viewer. By default the engine makes one, which lasts as long as the engine.
1020
+ */
1021
+ toolOptions?: ToolOptions;
1022
+ /**
1023
+ * The style the tools create with. A binding passes its own, made with `trackToolStyle` and
1024
+ * its own history (and keeps its active group in step with the tool). By default the engine
1025
+ * makes one over the document's history.
1026
+ */
1027
+ toolStyle?: ToolStyle;
1028
+ /**
1029
+ * The history the tools group a gesture's changes with (a group move, a sketch's swap to its
1030
+ * shape). A binding passes its own, so a controlled host's undo steps match the gesture. By
1031
+ * default the document's history.
1032
+ */
1033
+ toolHistory?: {
1034
+ batch(fn: () => void): void;
1035
+ };
1036
+ /**
1037
+ * The font families text boxes offer, replacing the default `FONT_FAMILIES` (the PDF
1038
+ * standard families). Fonts beyond those are the PDF writer's to embed.
1039
+ */
1040
+ fonts?: string[];
1041
+ /**
1042
+ * Where signature templates live. Default: memory, gone on reload
1043
+ * (`createMemorySignatureStore`). `createLocalSignatureStore` keeps them in the browser.
1044
+ */
1045
+ signatures?: SignatureStore;
1046
+ /**
1047
+ * The templates the `signature` tool and the signature controls share. A binding or
1048
+ * `createViewer` passes its own, so they outlive one document; it wins over `signatures`.
1049
+ * A function is read each time the library is needed, so a host that swaps its library
1050
+ * after mount reaches the tool too.
1051
+ */
1052
+ signatureLibrary?: SignatureLibrary | (() => SignatureLibrary);
1053
+ /**
1054
+ * The handwriting fonts a typed signature offers. The host loads them (`@font-face`).
1055
+ * Default `SIGNATURE_FONTS`.
1056
+ */
1057
+ signatureFonts?: string[];
485
1058
  /** Annotation content is rendered by the host (custom slots). Changing it needs `rebuild`. */
486
1059
  customAnnotations?: boolean;
1060
+ /**
1061
+ * The app's own data attributes, classes and description for each annotation element, to
1062
+ * style or find its marks: `{ data: { 'my-flag': 'on' } }` writes `data-my-flag="on"`.
1063
+ * Decorations re-apply whenever the annotations change; when the function's output changes
1064
+ * for another reason (app state it reads), call `redecorate()`. Core's attributes and `ink-`
1065
+ * classes cannot be overridden.
1066
+ */
1067
+ decorateAnnotation?: DecorateAnnotation;
487
1068
  onActivate?(id: string): void;
488
1069
  /**
489
1070
  * After every (re)build: subscribe to the new viewport and controller here. It fires inside
@@ -510,6 +1091,17 @@ interface MountViewerOptions {
510
1091
  interface ViewerEngine {
511
1092
  readonly viewport: Viewport;
512
1093
  readonly tools: ToolController;
1094
+ /**
1095
+ * The style each group creates with, shared by the tools and the style controls. It lives as
1096
+ * long as the engine, across rebuilds.
1097
+ */
1098
+ readonly toolStyle: ToolStyle;
1099
+ /** The font families text boxes offer: the `fonts` option, else `FONT_FAMILIES`. */
1100
+ readonly fonts: readonly string[];
1101
+ /** The signature templates: the host's current library, or the engine's own. */
1102
+ readonly signatures: SignatureLibrary;
1103
+ /** The fonts a typed signature offers: the `signatureFonts` option, else `SIGNATURE_FONTS`. */
1104
+ readonly signatureFonts: readonly string[];
513
1105
  readonly pages: ReadonlyMap<number, PageMount>;
514
1106
  /**
515
1107
  * Recreates the viewport for construction-only options, keeping zoom, page, mode, rotation
@@ -522,12 +1114,22 @@ interface ViewerEngine {
522
1114
  buffer?: number;
523
1115
  customAnnotations?: boolean;
524
1116
  }): void;
1117
+ /**
1118
+ * Runs `decorateAnnotation` again for every mounted annotation element, without re-rendering
1119
+ * anything else. Call it when the decorations would change but no annotation did.
1120
+ */
1121
+ redecorate(): void;
525
1122
  destroy(): void;
526
1123
  }
527
1124
  export declare function mountViewer(opts: MountViewerOptions): ViewerEngine;
528
1125
  //#endregion
529
1126
  //#region src/dom/viewer/create-viewer.d.ts
530
- interface CreateViewerOptions extends Omit<MountViewerOptions, 'container' | 'document'> {
1127
+ /**
1128
+ * The engine options, less what the viewer owns: the container, the document, the tool style
1129
+ * (bound to one document's store, so each engine makes its own), and the tool options and
1130
+ * signature library (one for the viewer's life).
1131
+ */
1132
+ interface CreateViewerOptions extends Omit<MountViewerOptions, 'container' | 'document' | 'toolStyle' | 'toolHistory' | 'toolOptions' | 'signatureLibrary'> {
531
1133
  source: DocumentSource;
532
1134
  assets: PdfAssets;
533
1135
  /** User password for encrypted files. `open` can pass its own for one load. */
@@ -535,10 +1137,8 @@ interface CreateViewerOptions extends Omit<MountViewerOptions, 'container' | 'do
535
1137
  /** Default: read from the theme's CSS variables on the viewer root. */
536
1138
  defaults?: AnnotationDefaults;
537
1139
  history?: OpenOptions['history'];
538
- /** Note thread popover. Default true. */
539
- notes?: boolean;
540
- /** Suggested-redaction card. Default true. */
541
- suggestions?: boolean;
1140
+ /** The thread popover for notes and text markup. Default true. */
1141
+ threads?: boolean;
542
1142
  onReady?(this: void, doc: InkDocument): void;
543
1143
  onError?(this: void, error: InkError): void;
544
1144
  }
@@ -555,6 +1155,18 @@ interface Viewer {
555
1155
  */
556
1156
  readonly viewport: Readable<Viewport | null>;
557
1157
  readonly tools: Readable<ToolController | null>;
1158
+ /**
1159
+ * The activated annotation's id: the one last clicked, or activated with Enter or Space.
1160
+ * The note thread opens from it, and an app can anchor its own popover (`createPopover`) to
1161
+ * it. `null` when none is, and again once that annotation is removed or the document closes.
1162
+ */
1163
+ readonly activated: Readable<string | null>;
1164
+ /**
1165
+ * Activates annotation `id`, or clears the activation with `null` (closing the thread
1166
+ * popover). Unlike a click, it does not select the annotation or call `onActivate`. An id
1167
+ * not in the open document's annotations is ignored.
1168
+ */
1169
+ setActivated(id: string | null): void;
558
1170
  /**
559
1171
  * Opens another document in place; the previous one is destroyed. Latest call wins.
560
1172
  * `password` is used for this load only; without it, the constructor's `password` applies.
@@ -586,7 +1198,10 @@ export declare function createToolbarSeparator(): HTMLDivElement;
586
1198
  export declare function createUndo(viewer: Viewer): HTMLButtonElement;
587
1199
  /** Redoes the last undone change; disabled when there is none. */
588
1200
  export declare function createRedo(viewer: Viewer): HTMLButtonElement;
589
- /** Sets the tool; pressed while it is the active one. */
1201
+ /**
1202
+ * Sets the tool; pressed while it is the active one. A host tool's button has no icon (append
1203
+ * your own) and is named by `label`, else by the tool id.
1204
+ */
590
1205
  export declare function createToolButton(viewer: Viewer, tool: ToolId, opts?: {
591
1206
  label?: string;
592
1207
  }): HTMLButtonElement;
@@ -606,5 +1221,195 @@ export declare function createPrevPage(viewer: Viewer): HTMLButtonElement;
606
1221
  /** Disabled on the last page. */
607
1222
  export declare function createNextPage(viewer: Viewer): HTMLButtonElement;
608
1223
  //#endregion
609
- export { type AnnotationSlotProps, type AnnotationState, type CreateViewerOptions, type CssLayout, type CssLayoutInput, type CssPageBox, type CssRect, type FocusReturn, type FocusReturnOptions, type LayoutMode, type MountViewerOptions, type NotePopoverSlotProps, type Overlay, type OverlayOptions, type PageHit, type PageLayer, type PageMount, type PageMountOptions, type PageRenderer, type PageRendererOptions, type PageTransform, type SelectionQuads, type SuggestionCardSlotProps, type TextLayerHandle, type TextLayerOptions, type Tool, type ToolContext, type ToolController, type ToolControllerOptions, type ToolId, type ViewRotation, type Viewer, type ViewerEngine, type Viewport, type ViewportHit, type ViewportKeysOptions, type ViewportOptions, type ZoomValue, cssVariableDefaults };
1224
+ //#region src/dom/viewer/style-menu.d.ts
1225
+ /** A button that opens the line style menu: weight, solid or dashed, and arrowheads. */
1226
+ export declare function createLineStyleMenu(viewer: Viewer): HTMLButtonElement;
1227
+ //#endregion
1228
+ //#region src/dom/viewer/color-menu.d.ts
1229
+ interface ColorMenuOptions {
1230
+ property: ColorProperty;
1231
+ /** Accessible name; defaults to "Border colour", "Fill colour" or "Text colour". */
1232
+ label?: string;
1233
+ /**
1234
+ * Scopes the menu to one style group (`ToolStyle.scoped`): it shows and sets that group's
1235
+ * colour whatever tool is active, and recolours the selection only when it is all in the group.
1236
+ */
1237
+ group?: StyleGroup;
1238
+ /** The colour new annotations get while the style leaves it unset; the trigger shows it. */
1239
+ fallback?: Readable<string | undefined>;
1240
+ }
1241
+ /** A button that opens a colour menu for one colour property of the selection or tool. */
1242
+ export declare function createColorMenu(viewer: Viewer, opts: ColorMenuOptions): HTMLButtonElement;
1243
+ //#endregion
1244
+ //#region src/dom/viewer/text-style-menu.d.ts
1245
+ /** A button that opens the text style menu: font, size, colour, emphasis and alignment. */
1246
+ export declare function createTextStyleMenu(viewer: Viewer): HTMLButtonElement;
1247
+ //#endregion
1248
+ //#region src/dom/viewer/shape-menu.d.ts
1249
+ /** A split button: the main part draws with the current shape kind, the chevron picks the kind. */
1250
+ export declare function createShapeMenu(viewer: Viewer): HTMLElement;
1251
+ //#endregion
1252
+ //#region src/dom/viewer/highlight-menu.d.ts
1253
+ /** A split button: the main part marks text with the current kind, the chevron picks it. */
1254
+ export declare function createHighlightMenu(viewer: Viewer): HTMLElement;
1255
+ //#endregion
1256
+ //#region src/dom/shape-icons.d.ts
1257
+ export declare const SHAPE_ICONS: Readonly<Record<ShapeKind, IconNode>>;
1258
+ //#endregion
1259
+ //#region src/dom/markup-icons.d.ts
1260
+ export declare const MARKUP_ICONS: Readonly<Record<MarkupKind, IconNode>>;
1261
+ //#endregion
1262
+ //#region src/dom/viewer/menu.d.ts
1263
+ interface MenuOptions {
1264
+ label: string;
1265
+ /** Extra attributes for the panel. */
1266
+ attrs?: Record<string, string>;
1267
+ /**
1268
+ * The panel's role. `menu` (the default) is a list of items with arrow-key movement; `dialog`
1269
+ * is for a panel of mixed widgets, which take Tab and their own keys, and opens on the first
1270
+ * focusable one.
1271
+ */
1272
+ role?: 'menu' | 'dialog';
1273
+ /** The element the panel lines up under. Default `trigger`; a split button passes itself. */
1274
+ anchor?: HTMLElement;
1275
+ /**
1276
+ * Whether `target` belongs to a menu nested in this one (its panel sits outside this panel
1277
+ * in the DOM). Presses, focus and Escape inside it neither dismiss this menu nor close it.
1278
+ */
1279
+ owns?(target: Node): boolean;
1280
+ /** Builds the items on first call and updates them in place after; called on open and `refresh`. */
1281
+ render(menu: HTMLElement): void;
1282
+ }
1283
+ interface Menu {
1284
+ readonly isOpen: boolean;
1285
+ /** Re-renders an open menu, and closes it if the trigger has become disabled. */
1286
+ refresh(): void;
1287
+ close(restoreFocus?: boolean): void;
1288
+ }
1289
+ export declare function createMenu(trigger: HTMLButtonElement, opts: MenuOptions): Menu;
1290
+ //#endregion
1291
+ //#region src/dom/signature-pad.d.ts
1292
+ interface SignaturePad {
1293
+ /** The drawing surface, `svg.ink-signature-pad`, filling the host. */
1294
+ readonly element: SVGSVGElement;
1295
+ /** True while nothing is drawn. */
1296
+ readonly empty: Readable<boolean>;
1297
+ clear(): void;
1298
+ /** The drawing as an ink template with a new id; undefined while the pad is empty. */
1299
+ toTemplate(): SignatureTemplate | undefined;
1300
+ destroy(): void;
1301
+ }
1302
+ /**
1303
+ * A drawing pad in `host`. Each press-drag-release is a stroke; the theme colours it through
1304
+ * `path.ink-stroke` (`fill: currentColor` by default).
1305
+ */
1306
+ export declare function createSignaturePad(host: HTMLElement): SignaturePad;
1307
+ /** `font` as a CSS font-family value: quoted unless it is a generic family. */
1308
+ export declare function fontFamilyValue(font: string): string;
1309
+ interface TypedSignatureOptions {
1310
+ /** The image's height in pixels. Default 96. */
1311
+ height?: number;
1312
+ /** The ink colour. Default `#151820`, the theme's ink. */
1313
+ color?: string;
1314
+ }
1315
+ /**
1316
+ * `name` drawn in `font` on a transparent canvas, as a PNG data URL. Waits for the font to load
1317
+ * (`document.fonts.load`) first. Rejects with a RangeError for an empty name.
1318
+ */
1319
+ export declare function renderTypedSignature(name: string, font: string, opts?: TypedSignatureOptions): Promise<string>;
1320
+ /** A typed signature as an image template, with a new id. */
1321
+ export declare function createTypedSignature(name: string, font: string, opts?: TypedSignatureOptions): Promise<SignatureTemplate>;
1322
+ /** The image types a signature image may be. */
1323
+ export declare const SIGNATURE_IMAGE_TYPES: readonly string[];
1324
+ /** The longest side, in pixels, an image signature is stored at. */
1325
+ export declare const SIGNATURE_IMAGE_MAX_SIDE = 1000;
1326
+ /**
1327
+ * The longest data URL, in characters, an image signature may be once scaled. Templates live
1328
+ * in host storage (`localStorage` holds about 5 MB) and are copied into every placed stamp.
1329
+ */
1330
+ export declare const SIGNATURE_IMAGE_MAX_LENGTH = 3000000;
1331
+ /**
1332
+ * An image file (a scan of a signature) as an image template. The image is drawn again at no
1333
+ * more than `SIGNATURE_IMAGE_MAX_SIDE` pixels on its long side, as a PNG (a JPEG stays a JPEG,
1334
+ * as photos compress far better that way), so a phone photo does not fill the store. Rejects
1335
+ * with a TypeError for anything but a PNG or JPEG, and a RangeError when the result is still
1336
+ * longer than `SIGNATURE_IMAGE_MAX_LENGTH`.
1337
+ */
1338
+ export declare function createImageSignature(file: Blob): Promise<SignatureTemplate>;
1339
+ /**
1340
+ * An ink template drawn for a menu: one filled outline per stroke (the `draw` renderer) in a
1341
+ * `viewBox` of the template's aspect, with room for the stroke. Paint `paths` with
1342
+ * `fill: currentColor`.
1343
+ */
1344
+ export declare function signaturePreview(t: SignatureTemplate & {
1345
+ kind: 'ink';
1346
+ }): {
1347
+ viewBox: string;
1348
+ paths: string[];
1349
+ };
1350
+ //#endregion
1351
+ //#region src/dom/signature-draft.d.ts
1352
+ interface SignatureDraftState {
1353
+ tab: SignatureTab;
1354
+ /** True while the pad has nothing on it. */
1355
+ padEmpty: boolean;
1356
+ name: string;
1357
+ font: string;
1358
+ /** The chosen image, read and checked. */
1359
+ image: SignatureTemplate | undefined;
1360
+ /** Why the chosen file was refused, for the Image tab to show. */
1361
+ imageError: string | undefined;
1362
+ /** Why the last save failed (the store refused it, full or offline), for the dialog to show. */
1363
+ saveError: string | undefined;
1364
+ /** True when the open tab has something to save. */
1365
+ canSave: boolean;
1366
+ saving: boolean;
1367
+ }
1368
+ interface SignatureDraft {
1369
+ readonly state: Readable<SignatureDraftState>;
1370
+ readonly fonts: readonly string[];
1371
+ setTab(tab: SignatureTab): void;
1372
+ setName(name: string): void;
1373
+ setFont(font: string): void;
1374
+ /** Mounts the pad in `host`; returns its teardown. One pad at a time. */
1375
+ attachPad(host: HTMLElement): () => void;
1376
+ clearPad(): void;
1377
+ /** Reads an image file for the Image tab. */
1378
+ chooseFile(file: Blob | undefined): Promise<void>;
1379
+ /**
1380
+ * Builds the open tab's template and saves it to `library`. Resolves with it, or undefined
1381
+ * when there is nothing to save, the save failed (setting `saveError`), or the draft was
1382
+ * destroyed before the save finished.
1383
+ */
1384
+ save(library: SignatureLibrary): Promise<SignatureTemplate | undefined>;
1385
+ /** Back to an empty Draw tab. */
1386
+ reset(): void;
1387
+ destroy(): void;
1388
+ }
1389
+ export declare function createSignatureDraft(opts?: {
1390
+ fonts?: readonly string[];
1391
+ }): SignatureDraft;
1392
+ //#endregion
1393
+ //#region src/dom/viewer/signature-dialog.d.ts
1394
+ interface SignatureDialogOptions {
1395
+ /** The fonts the Type tab offers. Default: the viewer's `signatureFonts`. */
1396
+ fonts?: string[];
1397
+ }
1398
+ interface SignatureDialog {
1399
+ readonly isOpen: boolean;
1400
+ /** Opens the dialog. On close, focus goes to `returnFocus`, else to what had it before. */
1401
+ open(opts?: {
1402
+ returnFocus?: HTMLElement | null;
1403
+ }): void;
1404
+ close(): void;
1405
+ destroy(): void;
1406
+ }
1407
+ export declare function createSignatureDialog(viewer: Viewer, opts?: SignatureDialogOptions): SignatureDialog;
1408
+ //#endregion
1409
+ //#region src/dom/viewer/signature-menu.d.ts
1410
+ /** A template drawn small: ink as an SVG of filled outlines, an image as an `<img>`. */
1411
+ export declare function createSignaturePreview(t: SignatureTemplate): HTMLElement;
1412
+ export declare function createSignatureMenu(viewer: Viewer, opts?: SignatureDialogOptions): HTMLElement;
1413
+ //#endregion
1414
+ export { type AnnotationDecoration, type AnnotationSlotProps, type AnnotationState, type ArrowheadChoice, type BuiltinToolId, type ColorMenuModel, type ColorMenuOptions, type ColorMenuSwatch, type ColorProperty, type ColorTrigger, type CreateViewerOptions, type CssLayout, type CssLayoutInput, type CssPageBox, type CssRect, type CurrentStyle, type DecorateAnnotation, type EditorCloseReason, type FocusReturn, type FocusReturnOptions, type FreeTextEditor, type FreeTextEditorOptions, type HighlightMenuItem, type HighlightMenuModel, type HighlightOptions, type LayoutMode, type LineStyleMenuItem, type LineStyleMenuModel, type LineStyleMenuSection, type MarkupKind, type Menu, type MenuOptions, type MountViewerOptions, type Overlay, type OverlayOptions, type PageHit, type PageLayer, type PageMount, type PageMountOptions, type PageRenderer, type PageRendererOptions, type PageTransform, type Palette, type Popover, type PopoverOptions, type ScopedToolStyle, type SelectionQuads, type ShapeKind, type ShapeMenuItem, type ShapeMenuModel, type ShapeOptions, type SignatureDialog, type SignatureDialogOptions, type SignatureDraft, type SignatureDraftState, type SignatureMenuItem, type SignatureMenuModel, type SignatureOptions, type SignaturePad, type SignatureTab, type StyleGroup, type StyleKey, type StyleProps, type TextAlignChoice, type TextAlignKey, type TextLayerHandle, type TextLayerOptions, type TextStyleMenuModel, type TextStyleToggle, type TextToggleKey, type ThreadPopoverSlotProps, type Tool, type ToolContext, type ToolController, type ToolControllerOptions, type ToolId, type ToolKind, type ToolOptions, type ToolStyle, type ToolStyleTracker, type TypedSignatureOptions, type ViewRotation, type Viewer, type ViewerEngine, type Viewport, type ViewportHit, type ViewportKeysOptions, type ViewportOptions, type ZoomValue, cssVariableDefaults };
610
1415
  //# sourceMappingURL=dom.d.mts.map