@inkbar/core 0.2.0 → 0.4.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 { $ as NoteAnnotation, Ct as Matrix, Et as Rect, L as Annotation, M as cssVariableDefaults, St as PdfAssets, Tt as Quad, W as ConfidenceBucket, a as OpenOptions, b as AnnotationStore, bt as PageInfo, ht as Readable, i as InkStatus, j as AnnotationDefaults, l as DocumentSource, ot as RedactAnnotation, r as InkDocument, u as InkError, ut as Suggestion, wt as Point } from "./document-Cywnv8Sz.mjs";
1
+ import { $ as AnnotationDefaults, D as OpenOptions, E as InkStatus, Et as LineEnding, H as AnnotationStore, M as InkError, Nt as NoteAnnotation, Qt as TextMarkupAnnotation, T as InkDocument, Ut as RedactAnnotation, Xt as Suggestion, _ as StyleGroup, a as SignatureStore, at as Annotation, b as ToolStyle, cn as PdfAssets, dn as Quad, et as cssVariableDefaults, fn as Rect, g as ScopedToolStyle, i as SignatureOptions, j as DocumentSource, ln as Matrix, m as CurrentStyle, mt as ConfidenceBucket, o as SignatureTemplate, on as PageInfo, r as SignatureLibrary, tn as Readable, un as Point, v as StyleKey, vt as FreeTextAnnotation, y as StyleProps } from "./signatures-BHYKTwYE.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,6 +249,13 @@ 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;
252
259
  }
253
260
  interface Overlay {
254
261
  readonly element: HTMLElement;
@@ -305,8 +312,22 @@ interface PageMount {
305
312
  /** Canvas, text layer and annotation overlay for one page, stacked in that order. */
306
313
  export declare function createPageMount(opts: PageMountOptions): PageMount;
307
314
  //#endregion
315
+ //#region src/dom/tools/options.d.ts
316
+ interface ToolOptions {
317
+ /** The tool's current options. Throws a `RangeError` for an id no tool registered. */
318
+ readable(id: ToolId): Readable<object>;
319
+ get(id: ToolId): object;
320
+ /** Merges `patch` into the tool's options. */
321
+ merge(id: ToolId, patch: object): void;
322
+ /** Registers tools not seen yet, seeded from their `defaultOptions`; known ids keep theirs. */
323
+ register(tools: readonly Tool[]): void;
324
+ }
325
+ export declare function createToolOptions(tools?: readonly Tool[]): ToolOptions;
326
+ //#endregion
308
327
  //#region src/dom/tools/controller.d.ts
309
- type ToolId = 'view' | 'select' | 'highlight' | 'redact-area' | 'note';
328
+ type BuiltinToolId = 'select-text' | 'select' | 'highlight' | 'redact-area' | 'note' | 'shape' | 'freetext' | 'draw' | 'sketch' | 'signature';
329
+ /** A built-in tool's id, or any id a host registers its own tool under. */
330
+ type ToolId = BuiltinToolId | (string & {});
310
331
  interface PageHit extends ViewportHit {
311
332
  /** Pointer position in user space. */
312
333
  user: Point;
@@ -322,18 +343,36 @@ interface ToolContext {
322
343
  selectionQuads(): SelectionQuads[];
323
344
  clearSelection(): void;
324
345
  onActivate?(id: string): void;
346
+ /** The style each group creates with, shared with the style controls. */
347
+ toolStyle: ToolStyle;
348
+ /** The active tool's current options. */
349
+ options<O extends object>(): O;
350
+ /**
351
+ * Groups a gesture's changes into one undo step (a group move). Without it each change is
352
+ * its own step.
353
+ */
354
+ history?: {
355
+ batch(fn: () => void): void;
356
+ };
357
+ /** The signature templates the `signature` tool places. Without it, it places nothing. */
358
+ signatures?: SignatureLibrary | undefined;
325
359
  }
326
- interface Tool {
360
+ interface Tool<O extends object = object> {
327
361
  id: ToolId;
328
362
  cursor: string;
363
+ /** Style group the tool creates into; select tools have none. */
364
+ styleGroup?: StyleGroup;
365
+ /** Option defaults. Options persist per tool for the viewer's life. */
366
+ defaultOptions?: O;
329
367
  activate(ctx: ToolContext): void;
330
368
  deactivate(): void;
331
369
  /**
332
370
  * 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.
371
+ * the press landed on an annotation; the overlay then selects and activates it (text markup
372
+ * on a click, other types on the press), so tools other than the select tools should ignore
373
+ * such presses. Calling `e.stopPropagation()` here keeps the overlay from handling it.
374
+ * Return true when the press starts a gesture: the controller then captures the pointer
375
+ * until it is released or cancelled.
337
376
  */
338
377
  onPointerDown?(e: PointerEvent, hit: PageHit | undefined, annotationId?: string): boolean | void;
339
378
  /**
@@ -348,14 +387,26 @@ interface Tool {
348
387
  }
349
388
  interface ToolController {
350
389
  readonly active: Readable<ToolId>;
351
- set(id: ToolId): void;
390
+ /** Switches to the tool, first merging `options` into its options. */
391
+ set(id: ToolId, options?: object): void;
392
+ /** Merges `patch` into a tool's options without switching to it. */
393
+ setOptions(id: ToolId, patch: object): void;
394
+ options(id: ToolId): Readable<object>;
352
395
  destroy(): void;
353
396
  }
354
397
  interface ToolControllerOptions {
355
- ctx: ToolContext;
356
- /** Default `'view'`. */
398
+ /** The controller adds `options`; `toolStyle` defaults to one of the controller's own. */
399
+ ctx: Omit<ToolContext, 'toolStyle' | 'options'> & {
400
+ toolStyle?: ToolStyle;
401
+ };
402
+ /** Default `'select-text'`. */
357
403
  initial?: ToolId;
358
404
  tools: Tool[];
405
+ /**
406
+ * Where options live. Pass the same registry to each controller that replaces another (a
407
+ * rebuild) so options persist; by default the controller keeps its own.
408
+ */
409
+ options?: ToolOptions;
359
410
  }
360
411
  /** The mounted page under a client point, with the point in CSS px and user space. */
361
412
  export declare function hitFor(ctx: ToolContext, e: {
@@ -363,12 +414,27 @@ export declare function hitFor(ctx: ToolContext, e: {
363
414
  clientY: number;
364
415
  }): PageHit | undefined;
365
416
  //#endregion
417
+ //#region src/dom/tools/freetext.d.ts
418
+ /** Width of a box placed with a click or Enter, user-space points. */
419
+ export declare const DEFAULT_FREETEXT_WIDTH = 144;
420
+ export declare function freetextTool(): Tool;
421
+ //#endregion
366
422
  //#region src/dom/tools/highlight.d.ts
423
+ type MarkupKind = TextMarkupAnnotation['type'];
424
+ /** The text markup kinds, in menu order. */
425
+ export declare const MARKUP_KINDS: readonly MarkupKind[];
426
+ interface HighlightOptions {
427
+ /** Which text markup the tool makes. */
428
+ kind: MarkupKind;
429
+ }
430
+ export declare const DEFAULT_HIGHLIGHT_OPTIONS: Readonly<HighlightOptions>;
367
431
  /**
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.
432
+ * Turns the text selection into one markup of the chosen kind per page when the pointer is
433
+ * released, or on Enter in the viewport (a keyboard selection), and selects what it made.
434
+ * Without a selection both do nothing. The markup's `contents` is left for a comment: hosts
435
+ * read the marked text with `doc.text(page)`.
370
436
  */
371
- export declare function highlightTool(): Tool;
437
+ export declare function highlightTool(): Tool<HighlightOptions>;
372
438
  //#endregion
373
439
  //#region src/dom/tools/note.d.ts
374
440
  /**
@@ -381,25 +447,286 @@ export declare function noteTool(): Tool;
381
447
  export declare function redactAreaTool(): Tool;
382
448
  //#endregion
383
449
  //#region src/dom/tools/select.d.ts
450
+ /**
451
+ * Rectangle select: a drag on empty space draws a marquee that selects the annotations it
452
+ * touches (`Shift` adds to the selection). Presses on annotations select, move and resize them
453
+ * as `select-text` does (selection-edit.ts).
454
+ */
384
455
  export declare function selectTool(): Tool;
385
456
  //#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;
457
+ //#region src/dom/tools/select-text.d.ts
458
+ /**
459
+ * The default tool. Text selection stays native: presses on text, and drags across text
460
+ * markup, select text. Presses on other annotations select them, and drags move and resize
461
+ * them (selection-edit.ts). There is no marquee.
462
+ */
463
+ export declare function selectTextTool(): Tool;
464
+ //#endregion
465
+ //#region src/model/annotations/shape-geometry.d.ts
466
+ /** Every kind the shape menu can offer. Kinds without a creator yet are not in `SHAPE_KINDS`. */
467
+ type ShapeKind = 'line' | 'arrow' | 'rectangle' | 'roundedRectangle' | 'ellipse' | 'bubble' | 'star' | 'polygon' | 'loupe' | 'mask' | 'ovalMask';
468
+ interface ShapeOptions {
469
+ kind: ShapeKind;
470
+ /** Points of a star. */
471
+ points: number;
472
+ /** Sides of a polygon. */
473
+ sides: number;
474
+ }
475
+ /** The kinds the shape menu offers today, in menu order. Later kinds extend this. */
476
+ export declare const SHAPE_KINDS: readonly ShapeKind[];
477
+ /** Side of the shape a click or Enter places, in points. */
478
+ export declare const DEFAULT_SHAPE_SIZE = 72;
479
+ /** Corner radius of a new rounded rectangle, in points. */
480
+ export declare const DEFAULT_CORNER_RADIUS = 8;
481
+ //#endregion
482
+ //#region src/dom/tools/shape.d.ts
483
+ export declare function shapeTool(): Tool<ShapeOptions>;
484
+ //#endregion
485
+ //#region src/dom/tools/signature.d.ts
486
+ export declare function signatureTool(): Tool<SignatureOptions>;
389
487
  //#endregion
390
488
  //#region src/dom/tools/index.d.ts
391
489
  /** Fresh instances of every built-in tool. */
392
490
  export declare function builtinTools(): Tool[];
491
+ /** The built-in tools with a host's tools added, a host tool replacing a built-in by id. */
492
+ export declare function withHostTools(host?: readonly Tool[]): Tool[];
393
493
  /** Listens on `ctx.root` and routes pointer and key events to the active tool. */
394
494
  export declare function createToolController(opts: Omit<ToolControllerOptions, 'tools'> & {
395
495
  tools?: Tool[];
396
496
  }): ToolController;
497
+ interface ToolStyleTracker {
498
+ readonly toolStyle: ToolStyle;
499
+ /** Call when the active tool changes: the style's active group follows it. */
500
+ setTool(id: ToolId): void;
501
+ }
502
+ /**
503
+ * A `ToolStyle` whose active group is the style group of the active tool among `tools` (the
504
+ * built-ins plus a host's). The engine makes one when it is not handed a style; a binding
505
+ * makes its own per document, so its style controls work before the viewport mounts.
506
+ */
507
+ export declare function trackToolStyle(opts: {
508
+ store: AnnotationStore;
509
+ history: {
510
+ batch(fn: () => void): void;
511
+ };
512
+ /** Host tools, as passed to `mountViewer`. */
513
+ tools?: readonly Tool[] | undefined;
514
+ tool?: ToolId | undefined;
515
+ }): ToolStyleTracker;
397
516
  //#endregion
398
517
  //#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>>;
518
+ /**
519
+ * Accessible names of the built-in tools, as the toolbar buttons announce them. A host tool has
520
+ * no entry: its button takes the host's `label`, else the tool id.
521
+ */
522
+ export declare const TOOL_LABELS: Readonly<Partial<Record<ToolId, string>>>;
523
+ /**
524
+ * The font families a text box offers by default: the PDF standard families, which a PDF
525
+ * writer can use without embedding a font. Hosts pass their own list as `fonts`.
526
+ */
527
+ export declare const FONT_FAMILIES: readonly string[];
528
+ /**
529
+ * The fonts a typed signature offers by default: the browser's own handwriting family. Hosts
530
+ * load handwriting fonts and pass them as `signatureFonts`.
531
+ */
532
+ export declare const SIGNATURE_FONTS: readonly string[];
401
533
  /** Zoom levels the zoom select offers, as scale factors. */
402
534
  export declare const ZOOM_LEVELS: readonly number[];
535
+ /** Stroke weights the line style menu offers, in points. */
536
+ export declare const LINE_WEIGHTS: readonly number[];
537
+ /** The dash pattern the menu's dashed choice writes, in points. */
538
+ export declare const DASH_PATTERN: readonly number[];
539
+ /** The ending the menu's arrowhead choices draw. */
540
+ export declare const ARROWHEAD_ENDING: LineEnding;
541
+ type ArrowheadChoice = 'none' | 'start' | 'end' | 'both';
542
+ /** The arrowhead choices in menu order, with the style each one writes (`head` is the start). */
543
+ export declare const ARROWHEAD_CHOICES: readonly {
544
+ value: ArrowheadChoice;
545
+ label: string;
546
+ patch: Pick<StyleProps, 'head' | 'tail'>;
547
+ }[];
548
+ /**
549
+ * Which arrowhead choice a style shows, `'mixed'` when the selection disagrees, else `undefined`.
550
+ * Only an ending Inkbar draws counts: one it does not know draws as `None`.
551
+ */
552
+ export declare function arrowheadChoice(head: LineEnding | 'mixed' | undefined, tail: LineEnding | 'mixed' | undefined): ArrowheadChoice | 'mixed' | undefined;
553
+ interface LineStyleMenuItem {
554
+ key: string;
555
+ label: string;
556
+ checked: boolean;
557
+ /** What choosing the item writes through the tool style. */
558
+ patch: StyleProps;
559
+ }
560
+ interface LineStyleMenuSection {
561
+ label: string;
562
+ /** The selection or active tool supports none of the section's props. */
563
+ disabled: boolean;
564
+ items: LineStyleMenuItem[];
565
+ }
566
+ interface LineStyleMenuModel {
567
+ /** False when nothing supports weight, pattern or endings: the trigger disables. */
568
+ enabled: boolean;
569
+ /** The selection disagrees on weight, pattern or endings. */
570
+ mixed: boolean;
571
+ sections: LineStyleMenuSection[];
572
+ }
573
+ /**
574
+ * What the line style menu shows for a style: sections of checkable items, each section
575
+ * disabled when `supported` lacks its props. A section whose value is mixed checks nothing.
576
+ * Shared by the bindings and the vanilla menu so they cannot drift apart.
577
+ */
578
+ export declare function lineStyleMenuModel(current: CurrentStyle, supported: ReadonlySet<StyleKey>): LineStyleMenuModel;
579
+ /** The colour props a colour menu can set. */
580
+ type ColorProperty = 'border' | 'fill' | 'textColor';
581
+ /** Accessible names of the colour menus, by property. */
582
+ export declare const COLOR_LABELS: Readonly<Record<ColorProperty, string>>;
583
+ /** Columns of the swatch grid: the arrow keys move by this much between rows. */
584
+ export declare const COLOR_COLUMNS = 12;
585
+ interface ColorMenuSwatch {
586
+ /** Unique within the menu. */
587
+ key: string;
588
+ /** The swatch's accessible name: its hex value. */
589
+ label: string;
590
+ color: string;
591
+ checked: boolean;
592
+ patch: StyleProps;
593
+ }
594
+ /** What the trigger's swatch shows. */
595
+ type ColorTrigger = {
596
+ kind: 'color';
597
+ color: string;
598
+ } |
599
+ /** No fill. */
600
+ {
601
+ kind: 'none';
602
+ } |
603
+ /** The selection disagrees. */
604
+ {
605
+ kind: 'mixed';
606
+ } |
607
+ /** Nothing to show: the menu is disabled or the style has no value. */
608
+ {
609
+ kind: 'empty';
610
+ };
611
+ interface ColorMenuModel {
612
+ label: string;
613
+ /** False when nothing supports the property: the trigger disables. */
614
+ enabled: boolean;
615
+ mixed: boolean;
616
+ trigger: ColorTrigger;
617
+ /** Common colours, greys, then the tonal grid, `COLOR_COLUMNS` to a row. */
618
+ swatches: ColorMenuSwatch[];
619
+ /** The "No fill" choice, for `fill` only. */
620
+ noFill: {
621
+ checked: boolean;
622
+ patch: StyleProps;
623
+ } | null;
624
+ /** The colour the custom picker starts on. */
625
+ customValue: string;
626
+ /** What picking `hex` in the custom picker writes. */
627
+ custom(hex: string): StyleProps;
628
+ }
629
+ /**
630
+ * What a colour menu shows for a style: the palette with the matching swatch checked, "No fill"
631
+ * for `fill`, and the trigger's swatch. Shared by the bindings and the vanilla menu.
632
+ */
633
+ export declare function colorMenuModel(property: ColorProperty, current: CurrentStyle, supported: ReadonlySet<StyleKey>): ColorMenuModel;
634
+ /** A typed size as the menu stores it: a whole number of points within the range. */
635
+ export declare function clampFontSize(size: number): number;
636
+ type TextToggleKey = 'bold' | 'italic' | 'underline';
637
+ type TextAlignKey = 'left' | 'center' | 'right' | 'justify';
638
+ interface TextStyleToggle {
639
+ key: TextToggleKey;
640
+ label: string;
641
+ /** `'mixed'` when the selection disagrees. */
642
+ pressed: boolean | 'mixed';
643
+ /** What pressing writes: the opposite of `pressed`, and on for a mix. */
644
+ patch: StyleProps;
645
+ }
646
+ interface TextAlignChoice {
647
+ key: TextAlignKey;
648
+ label: string;
649
+ checked: boolean;
650
+ /** The one radio in the Tab order: the checked one, else the first. */
651
+ tabStop: boolean;
652
+ patch: StyleProps;
653
+ }
654
+ interface TextStyleMenuModel {
655
+ label: string;
656
+ /** False when nothing supports text style: the trigger disables. */
657
+ enabled: boolean;
658
+ mixed: boolean;
659
+ font: {
660
+ label: string;
661
+ /** The family, or `''` when the selection disagrees. */
662
+ value: string;
663
+ /** The families on offer, each once; a current family outside the list is added. */
664
+ options: string[];
665
+ patch(family: string): StyleProps;
666
+ };
667
+ size: {
668
+ label: string;
669
+ /** The size, the default when the style sets none, or `null` when the selection disagrees. */
670
+ value: number | null;
671
+ min: number;
672
+ max: number;
673
+ step: number;
674
+ /** What committing a typed size writes, or `null` when it changes nothing. */
675
+ commit(raw: number): StyleProps | null;
676
+ /** What a stepper press writes, or `null` at the end of the range. */
677
+ nudge(direction: 1 | -1): StyleProps | null;
678
+ };
679
+ toggles: TextStyleToggle[];
680
+ align: {
681
+ label: string;
682
+ choices: TextAlignChoice[];
683
+ };
684
+ }
685
+ /**
686
+ * What the text style menu shows for a style: the font, size, bold/italic/underline and
687
+ * alignment, each with the patch choosing it. `fonts` is the list the host offers.
688
+ */
689
+ export declare function textStyleMenuModel(current: CurrentStyle, supported: ReadonlySet<StyleKey>, fonts: readonly string[]): TextStyleMenuModel;
690
+ /** Accessible names of the shape kinds, as the shape menu announces them. */
691
+ export declare const SHAPE_LABELS: Readonly<Record<ShapeKind, string>>;
692
+ /** Accessible names of the text markup kinds, as the highlight menu announces them. */
693
+ export declare const MARKUP_LABELS: Readonly<Record<MarkupKind, string>>;
694
+ interface HighlightMenuItem {
695
+ kind: MarkupKind;
696
+ label: string;
697
+ checked: boolean;
698
+ }
699
+ interface HighlightMenuModel {
700
+ /** The kind the main button makes. */
701
+ kind: MarkupKind;
702
+ /** The main button's accessible name. */
703
+ label: string;
704
+ /** The kinds on offer, in menu order, with the current one checked. */
705
+ items: HighlightMenuItem[];
706
+ }
707
+ /** What the highlight menu shows for the highlight tool's options. */
708
+ export declare function highlightMenuModel(options: Partial<HighlightOptions>, kinds: readonly MarkupKind[]): HighlightMenuModel;
709
+ /** Columns of the shape grid: the arrow keys move by this much between rows. */
710
+ export declare const SHAPE_COLUMNS = 2;
711
+ interface ShapeMenuItem {
712
+ kind: ShapeKind;
713
+ label: string;
714
+ checked: boolean;
715
+ }
716
+ interface ShapeMenuModel {
717
+ /** The kind the main button draws. */
718
+ kind: ShapeKind;
719
+ /** The main button's accessible name. */
720
+ label: string;
721
+ /** The kinds on offer, in menu order, with the current one checked. */
722
+ items: ShapeMenuItem[];
723
+ }
724
+ /**
725
+ * What the shape menu shows for the shape tool's options, over the kinds in `kinds`
726
+ * (`SHAPE_KINDS`). A kind that is not on offer falls back to `rectangle` when that is offered,
727
+ * else to the first.
728
+ */
729
+ export declare function shapeMenuModel(options: Partial<ShapeOptions>, kinds: readonly ShapeKind[]): ShapeMenuModel;
403
730
  /** The overlay's per-annotation state, as on its `data-state` attribute. */
404
731
  type AnnotationState = 'idle' | 'hover' | 'selected';
405
732
  /**
@@ -417,9 +744,16 @@ interface AnnotationSlotProps {
417
744
  /** Removes a suggested redaction. No-op for anything else. */
418
745
  dismiss: () => void;
419
746
  }
420
- /** What a host-rendered note thread receives. */
421
- interface NotePopoverSlotProps {
422
- note: NoteAnnotation;
747
+ /** The thread popover's accessible name: "Note thread" for a note, "Comment thread" for markup. */
748
+ export declare function threadPopoverLabel(root: Pick<Annotation, 'type'>): string;
749
+ /**
750
+ * The thread popover's delete button. It removes the root and its replies, so on text markup
751
+ * it says it deletes the highlight, not only the comment.
752
+ */
753
+ export declare function threadDeleteLabel(root: Pick<Annotation, 'type'>): string;
754
+ /** What a host-rendered comment thread receives: a note's, or text markup's. */
755
+ interface ThreadPopoverSlotProps {
756
+ root: NoteAnnotation | TextMarkupAnnotation;
423
757
  replies: Annotation[];
424
758
  reply: (text: string) => void;
425
759
  update: (contents: string) => void;
@@ -435,6 +769,109 @@ interface SuggestionCardSlotProps {
435
769
  dismiss: () => void;
436
770
  close: () => void;
437
771
  }
772
+ /** The signature controls' words, shared so every binding announces the same names. */
773
+ export declare const SIGNATURE_LABELS: {
774
+ /** The menu's group and main button. */
775
+ readonly sign: "Sign";
776
+ readonly trigger: "Choose signature";
777
+ readonly menu: "Signatures";
778
+ readonly saved: "Saved signatures";
779
+ readonly create: "Create signature";
780
+ /** The dialog's title. */
781
+ readonly dialog: "Create signature";
782
+ readonly tabs: "Signature source";
783
+ readonly draw: "Draw";
784
+ readonly type: "Type";
785
+ readonly image: "Image";
786
+ readonly pad: "Signature pad";
787
+ readonly clear: "Clear";
788
+ readonly name: "Name";
789
+ readonly namePlaceholder: "Your name";
790
+ readonly fonts: "Font";
791
+ readonly file: "Image file";
792
+ readonly cancel: "Cancel";
793
+ readonly save: "Save";
794
+ };
795
+ /** The dialog's tabs, in order. */
796
+ export declare const SIGNATURE_TABS: readonly ["draw", "type", "image"];
797
+ type SignatureTab = (typeof SIGNATURE_TABS)[number];
798
+ interface SignatureMenuItem {
799
+ id: string;
800
+ /** `Signature 1`, `Signature 2`… in saved order. */
801
+ label: string;
802
+ /** The remove button's accessible name. */
803
+ removeLabel: string;
804
+ checked: boolean;
805
+ template: SignatureTemplate;
806
+ }
807
+ interface SignatureMenuModel {
808
+ /** The template the tool places, when it is still saved. */
809
+ selected: SignatureTemplate | undefined;
810
+ items: SignatureMenuItem[];
811
+ }
812
+ /** What the signature menu shows for the saved templates and the signature tool's options. */
813
+ export declare function signatureMenuModel(templates: readonly SignatureTemplate[], options: SignatureOptions): SignatureMenuModel;
814
+ //#endregion
815
+ //#region src/dom/palette.d.ts
816
+ interface Palette {
817
+ /** 12 swatches, the top row. */
818
+ readonly common: readonly string[];
819
+ /** 12 greys, white to black. */
820
+ readonly greys: readonly string[];
821
+ /** 8 rows of 12 hue columns (red round to rose in 30 degree steps), dark to light. */
822
+ readonly grid: readonly (readonly string[])[];
823
+ }
824
+ export declare const PALETTE: Palette;
825
+ //#endregion
826
+ //#region src/dom/freetext-editor.d.ts
827
+ interface FreeTextEditor {
828
+ /** Closes the editor, handing its text to `commit` (true) or calling `cancel` (false). */
829
+ close(commit: boolean): void;
830
+ }
831
+ interface FreeTextEditorOptions {
832
+ transform: PageTransform;
833
+ /**
834
+ * The edited text and the box's rect, grown to fit it (`grownFreeText`), in user space.
835
+ * `grown` is the growth alone, in CSS px (0 when the box kept its height), for a caller whose
836
+ * box may have moved or been resized while the editor was open.
837
+ */
838
+ commit(contents: string, rect: Rect, grown: number): void;
839
+ cancel(): void;
840
+ }
841
+ /**
842
+ * Opens an editor on `el`, the overlay element showing `a` (or a stand-in for a box not in the
843
+ * store yet). `Escape` commits; a press outside the editor, or focus leaving it, commits too.
844
+ * Closing while the editor has focus hands focus to `el`. Keys typed in the
845
+ * editor stop there, so no viewport or tool shortcut sees them. Opening a second editor on the
846
+ * same element commits the first.
847
+ */
848
+ export declare function editFreeText(el: HTMLElement, a: FreeTextAnnotation, opts: FreeTextEditorOptions): FreeTextEditor;
849
+ //#endregion
850
+ //#region src/dom/menu-keys.d.ts
851
+ /** The menu's enabled items in document order. */
852
+ export declare function menuItems(root: ParentNode): HTMLElement[];
853
+ /** Focuses the first checked item, else the first enabled one. */
854
+ export declare function focusInitialMenuItem(root: ParentNode): void;
855
+ /**
856
+ * ArrowDown and ArrowUp move between enabled items and wrap; Home and End go to the ends.
857
+ * Inside a grid the arrow keys move in both directions.
858
+ */
859
+ export declare function handleMenuKeys(e: KeyboardEvent, root: ParentNode): void;
860
+ /**
861
+ * Arrow keys inside a `role="radiogroup"`: the next (or previous) enabled `role="radio"`
862
+ * takes focus and is chosen, wrapping at the ends, as a native radio group does.
863
+ */
864
+ export declare function handleRadioKeys(e: KeyboardEvent, group: ParentNode): void;
865
+ /**
866
+ * Arrow keys, Home and End inside a `role="tablist"`: the next (or previous) enabled
867
+ * `role="tab"` takes focus and is chosen, wrapping at the ends.
868
+ */
869
+ export declare function handleTabKeys(e: KeyboardEvent, tablist: ParentNode): void;
870
+ /**
871
+ * Keeps Tab inside `container`, a modal: Tab from its last stop goes to its first, and
872
+ * Shift+Tab from the first to the last.
873
+ */
874
+ export declare function trapTab(e: KeyboardEvent, container: HTMLElement): void;
438
875
  //#endregion
439
876
  //#region src/dom/annotation-element.d.ts
440
877
  /** The overlay element drawn for annotation `id` under `root`, if it is in the DOM. */
@@ -482,6 +919,53 @@ interface MountViewerOptions {
482
919
  gap?: number;
483
920
  buffer?: number;
484
921
  tool?: ToolId;
922
+ /**
923
+ * Host tools, added to the built-ins. A host tool with a built-in's id replaces it. The same
924
+ * instances are reused when the engine rebuilds.
925
+ */
926
+ tools?: Tool[];
927
+ /**
928
+ * The tools' options (the shape kind, the highlight kind…). A binding or `createViewer` passes
929
+ * one it keeps for its own life, so options persist across documents, as for the life of the
930
+ * viewer. By default the engine makes one, which lasts as long as the engine.
931
+ */
932
+ toolOptions?: ToolOptions;
933
+ /**
934
+ * The style the tools create with. A binding passes its own, made with `trackToolStyle` and
935
+ * its own history (and keeps its active group in step with the tool). By default the engine
936
+ * makes one over the document's history.
937
+ */
938
+ toolStyle?: ToolStyle;
939
+ /**
940
+ * The history the tools group a gesture's changes with (a group move, a sketch's swap to its
941
+ * shape). A binding passes its own, so a controlled host's undo steps match the gesture. By
942
+ * default the document's history.
943
+ */
944
+ toolHistory?: {
945
+ batch(fn: () => void): void;
946
+ };
947
+ /**
948
+ * The font families text boxes offer, replacing the default `FONT_FAMILIES` (the PDF
949
+ * standard families). Fonts beyond those are the PDF writer's to embed.
950
+ */
951
+ fonts?: string[];
952
+ /**
953
+ * Where signature templates live. Default: memory, gone on reload
954
+ * (`createMemorySignatureStore`). `createLocalSignatureStore` keeps them in the browser.
955
+ */
956
+ signatures?: SignatureStore;
957
+ /**
958
+ * The templates the `signature` tool and the signature controls share. A binding or
959
+ * `createViewer` passes its own, so they outlive one document; it wins over `signatures`.
960
+ * A function is read each time the library is needed, so a host that swaps its library
961
+ * after mount reaches the tool too.
962
+ */
963
+ signatureLibrary?: SignatureLibrary | (() => SignatureLibrary);
964
+ /**
965
+ * The handwriting fonts a typed signature offers. The host loads them (`@font-face`).
966
+ * Default `SIGNATURE_FONTS`.
967
+ */
968
+ signatureFonts?: string[];
485
969
  /** Annotation content is rendered by the host (custom slots). Changing it needs `rebuild`. */
486
970
  customAnnotations?: boolean;
487
971
  onActivate?(id: string): void;
@@ -510,6 +994,17 @@ interface MountViewerOptions {
510
994
  interface ViewerEngine {
511
995
  readonly viewport: Viewport;
512
996
  readonly tools: ToolController;
997
+ /**
998
+ * The style each group creates with, shared by the tools and the style controls. It lives as
999
+ * long as the engine, across rebuilds.
1000
+ */
1001
+ readonly toolStyle: ToolStyle;
1002
+ /** The font families text boxes offer: the `fonts` option, else `FONT_FAMILIES`. */
1003
+ readonly fonts: readonly string[];
1004
+ /** The signature templates: the host's current library, or the engine's own. */
1005
+ readonly signatures: SignatureLibrary;
1006
+ /** The fonts a typed signature offers: the `signatureFonts` option, else `SIGNATURE_FONTS`. */
1007
+ readonly signatureFonts: readonly string[];
513
1008
  readonly pages: ReadonlyMap<number, PageMount>;
514
1009
  /**
515
1010
  * Recreates the viewport for construction-only options, keeping zoom, page, mode, rotation
@@ -527,7 +1022,12 @@ interface ViewerEngine {
527
1022
  export declare function mountViewer(opts: MountViewerOptions): ViewerEngine;
528
1023
  //#endregion
529
1024
  //#region src/dom/viewer/create-viewer.d.ts
530
- interface CreateViewerOptions extends Omit<MountViewerOptions, 'container' | 'document'> {
1025
+ /**
1026
+ * The engine options, less what the viewer owns: the container, the document, the tool style
1027
+ * (bound to one document's store, so each engine makes its own), and the tool options and
1028
+ * signature library (one for the viewer's life).
1029
+ */
1030
+ interface CreateViewerOptions extends Omit<MountViewerOptions, 'container' | 'document' | 'toolStyle' | 'toolHistory' | 'toolOptions' | 'signatureLibrary'> {
531
1031
  source: DocumentSource;
532
1032
  assets: PdfAssets;
533
1033
  /** User password for encrypted files. `open` can pass its own for one load. */
@@ -535,8 +1035,8 @@ interface CreateViewerOptions extends Omit<MountViewerOptions, 'container' | 'do
535
1035
  /** Default: read from the theme's CSS variables on the viewer root. */
536
1036
  defaults?: AnnotationDefaults;
537
1037
  history?: OpenOptions['history'];
538
- /** Note thread popover. Default true. */
539
- notes?: boolean;
1038
+ /** The thread popover for notes and text markup. Default true. */
1039
+ threads?: boolean;
540
1040
  /** Suggested-redaction card. Default true. */
541
1041
  suggestions?: boolean;
542
1042
  onReady?(this: void, doc: InkDocument): void;
@@ -586,7 +1086,10 @@ export declare function createToolbarSeparator(): HTMLDivElement;
586
1086
  export declare function createUndo(viewer: Viewer): HTMLButtonElement;
587
1087
  /** Redoes the last undone change; disabled when there is none. */
588
1088
  export declare function createRedo(viewer: Viewer): HTMLButtonElement;
589
- /** Sets the tool; pressed while it is the active one. */
1089
+ /**
1090
+ * Sets the tool; pressed while it is the active one. A host tool's button has no icon (append
1091
+ * your own) and is named by `label`, else by the tool id.
1092
+ */
590
1093
  export declare function createToolButton(viewer: Viewer, tool: ToolId, opts?: {
591
1094
  label?: string;
592
1095
  }): HTMLButtonElement;
@@ -606,5 +1109,191 @@ export declare function createPrevPage(viewer: Viewer): HTMLButtonElement;
606
1109
  /** Disabled on the last page. */
607
1110
  export declare function createNextPage(viewer: Viewer): HTMLButtonElement;
608
1111
  //#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 };
1112
+ //#region src/dom/viewer/style-menu.d.ts
1113
+ /** A button that opens the line style menu: weight, solid or dashed, and arrowheads. */
1114
+ export declare function createLineStyleMenu(viewer: Viewer): HTMLButtonElement;
1115
+ //#endregion
1116
+ //#region src/dom/viewer/color-menu.d.ts
1117
+ interface ColorMenuOptions {
1118
+ property: ColorProperty;
1119
+ /** Accessible name; defaults to "Border colour", "Fill colour" or "Text colour". */
1120
+ label?: string;
1121
+ /**
1122
+ * Scopes the menu to one style group (`ToolStyle.scoped`): it shows and sets that group's
1123
+ * colour whatever tool is active, and recolours the selection only when it is all in the group.
1124
+ */
1125
+ group?: StyleGroup;
1126
+ }
1127
+ /** A button that opens a colour menu for one colour property of the selection or tool. */
1128
+ export declare function createColorMenu(viewer: Viewer, opts: ColorMenuOptions): HTMLButtonElement;
1129
+ //#endregion
1130
+ //#region src/dom/viewer/text-style-menu.d.ts
1131
+ /** A button that opens the text style menu: font, size, colour, emphasis and alignment. */
1132
+ export declare function createTextStyleMenu(viewer: Viewer): HTMLButtonElement;
1133
+ //#endregion
1134
+ //#region src/dom/viewer/shape-menu.d.ts
1135
+ /** A split button: the main part draws with the current shape kind, the chevron picks the kind. */
1136
+ export declare function createShapeMenu(viewer: Viewer): HTMLElement;
1137
+ //#endregion
1138
+ //#region src/dom/viewer/highlight-menu.d.ts
1139
+ /** A split button: the main part marks text with the current kind, the chevron picks it. */
1140
+ export declare function createHighlightMenu(viewer: Viewer): HTMLElement;
1141
+ //#endregion
1142
+ //#region src/dom/shape-icons.d.ts
1143
+ export declare const SHAPE_ICONS: Readonly<Record<ShapeKind, IconNode>>;
1144
+ //#endregion
1145
+ //#region src/dom/markup-icons.d.ts
1146
+ export declare const MARKUP_ICONS: Readonly<Record<MarkupKind, IconNode>>;
1147
+ //#endregion
1148
+ //#region src/dom/viewer/menu.d.ts
1149
+ interface MenuOptions {
1150
+ label: string;
1151
+ /** Extra attributes for the panel. */
1152
+ attrs?: Record<string, string>;
1153
+ /**
1154
+ * The panel's role. `menu` (the default) is a list of items with arrow-key movement; `dialog`
1155
+ * is for a panel of mixed widgets, which take Tab and their own keys, and opens on the first
1156
+ * focusable one.
1157
+ */
1158
+ role?: 'menu' | 'dialog';
1159
+ /**
1160
+ * Whether `target` belongs to a menu nested in this one (its panel sits outside this panel
1161
+ * in the DOM). Presses, focus and Escape inside it neither dismiss this menu nor close it.
1162
+ */
1163
+ owns?(target: Node): boolean;
1164
+ /** Builds the items on first call and updates them in place after; called on open and `refresh`. */
1165
+ render(menu: HTMLElement): void;
1166
+ }
1167
+ interface Menu {
1168
+ readonly isOpen: boolean;
1169
+ /** Re-renders an open menu, and closes it if the trigger has become disabled. */
1170
+ refresh(): void;
1171
+ close(restoreFocus?: boolean): void;
1172
+ }
1173
+ export declare function createMenu(trigger: HTMLButtonElement, opts: MenuOptions): Menu;
1174
+ //#endregion
1175
+ //#region src/dom/signature-pad.d.ts
1176
+ interface SignaturePad {
1177
+ /** The drawing surface, `svg.ink-signature-pad`, filling the host. */
1178
+ readonly element: SVGSVGElement;
1179
+ /** True while nothing is drawn. */
1180
+ readonly empty: Readable<boolean>;
1181
+ clear(): void;
1182
+ /** The drawing as an ink template with a new id; undefined while the pad is empty. */
1183
+ toTemplate(): SignatureTemplate | undefined;
1184
+ destroy(): void;
1185
+ }
1186
+ /**
1187
+ * A drawing pad in `host`. Each press-drag-release is a stroke; the theme colours it through
1188
+ * `path.ink-stroke` (`fill: currentColor` by default).
1189
+ */
1190
+ export declare function createSignaturePad(host: HTMLElement): SignaturePad;
1191
+ /** `font` as a CSS font-family value: quoted unless it is a generic family. */
1192
+ export declare function fontFamilyValue(font: string): string;
1193
+ interface TypedSignatureOptions {
1194
+ /** The image's height in pixels. Default 96. */
1195
+ height?: number;
1196
+ /** The ink colour. Default `#151820`, the theme's ink. */
1197
+ color?: string;
1198
+ }
1199
+ /**
1200
+ * `name` drawn in `font` on a transparent canvas, as a PNG data URL. Waits for the font to load
1201
+ * (`document.fonts.load`) first. Rejects with a RangeError for an empty name.
1202
+ */
1203
+ export declare function renderTypedSignature(name: string, font: string, opts?: TypedSignatureOptions): Promise<string>;
1204
+ /** A typed signature as an image template, with a new id. */
1205
+ export declare function createTypedSignature(name: string, font: string, opts?: TypedSignatureOptions): Promise<SignatureTemplate>;
1206
+ /** The image types a signature image may be. */
1207
+ export declare const SIGNATURE_IMAGE_TYPES: readonly string[];
1208
+ /** The longest side, in pixels, an image signature is stored at. */
1209
+ export declare const SIGNATURE_IMAGE_MAX_SIDE = 1000;
1210
+ /**
1211
+ * The longest data URL, in characters, an image signature may be once scaled. Templates live
1212
+ * in host storage (`localStorage` holds about 5 MB) and are copied into every placed stamp.
1213
+ */
1214
+ export declare const SIGNATURE_IMAGE_MAX_LENGTH = 3000000;
1215
+ /**
1216
+ * An image file (a scan of a signature) as an image template. The image is drawn again at no
1217
+ * more than `SIGNATURE_IMAGE_MAX_SIDE` pixels on its long side, as a PNG (a JPEG stays a JPEG,
1218
+ * as photos compress far better that way), so a phone photo does not fill the store. Rejects
1219
+ * with a TypeError for anything but a PNG or JPEG, and a RangeError when the result is still
1220
+ * longer than `SIGNATURE_IMAGE_MAX_LENGTH`.
1221
+ */
1222
+ export declare function createImageSignature(file: Blob): Promise<SignatureTemplate>;
1223
+ /**
1224
+ * An ink template drawn for a menu: one filled outline per stroke (the `draw` renderer) in a
1225
+ * `viewBox` of the template's aspect, with room for the stroke. Paint `paths` with
1226
+ * `fill: currentColor`.
1227
+ */
1228
+ export declare function signaturePreview(t: SignatureTemplate & {
1229
+ kind: 'ink';
1230
+ }): {
1231
+ viewBox: string;
1232
+ paths: string[];
1233
+ };
1234
+ //#endregion
1235
+ //#region src/dom/signature-draft.d.ts
1236
+ interface SignatureDraftState {
1237
+ tab: SignatureTab;
1238
+ /** True while the pad has nothing on it. */
1239
+ padEmpty: boolean;
1240
+ name: string;
1241
+ font: string;
1242
+ /** The chosen image, read and checked. */
1243
+ image: SignatureTemplate | undefined;
1244
+ /** Why the chosen file was refused, for the Image tab to show. */
1245
+ imageError: string | undefined;
1246
+ /** Why the last save failed (the store refused it, full or offline), for the dialog to show. */
1247
+ saveError: string | undefined;
1248
+ /** True when the open tab has something to save. */
1249
+ canSave: boolean;
1250
+ saving: boolean;
1251
+ }
1252
+ interface SignatureDraft {
1253
+ readonly state: Readable<SignatureDraftState>;
1254
+ readonly fonts: readonly string[];
1255
+ setTab(tab: SignatureTab): void;
1256
+ setName(name: string): void;
1257
+ setFont(font: string): void;
1258
+ /** Mounts the pad in `host`; returns its teardown. One pad at a time. */
1259
+ attachPad(host: HTMLElement): () => void;
1260
+ clearPad(): void;
1261
+ /** Reads an image file for the Image tab. */
1262
+ chooseFile(file: Blob | undefined): Promise<void>;
1263
+ /**
1264
+ * Builds the open tab's template and saves it to `library`. Resolves with it, or undefined
1265
+ * when there is nothing to save, the save failed (setting `saveError`), or the draft was
1266
+ * destroyed before the save finished.
1267
+ */
1268
+ save(library: SignatureLibrary): Promise<SignatureTemplate | undefined>;
1269
+ /** Back to an empty Draw tab. */
1270
+ reset(): void;
1271
+ destroy(): void;
1272
+ }
1273
+ export declare function createSignatureDraft(opts?: {
1274
+ fonts?: readonly string[];
1275
+ }): SignatureDraft;
1276
+ //#endregion
1277
+ //#region src/dom/viewer/signature-dialog.d.ts
1278
+ interface SignatureDialogOptions {
1279
+ /** The fonts the Type tab offers. Default: the viewer's `signatureFonts`. */
1280
+ fonts?: string[];
1281
+ }
1282
+ interface SignatureDialog {
1283
+ readonly isOpen: boolean;
1284
+ /** Opens the dialog. On close, focus goes to `returnFocus`, else to what had it before. */
1285
+ open(opts?: {
1286
+ returnFocus?: HTMLElement | null;
1287
+ }): void;
1288
+ close(): void;
1289
+ destroy(): void;
1290
+ }
1291
+ export declare function createSignatureDialog(viewer: Viewer, opts?: SignatureDialogOptions): SignatureDialog;
1292
+ //#endregion
1293
+ //#region src/dom/viewer/signature-menu.d.ts
1294
+ /** A template drawn small: ink as an SVG of filled outlines, an image as an `<img>`. */
1295
+ export declare function createSignaturePreview(t: SignatureTemplate): HTMLElement;
1296
+ export declare function createSignatureMenu(viewer: Viewer, opts?: SignatureDialogOptions): HTMLElement;
1297
+ //#endregion
1298
+ export { 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 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 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 SuggestionCardSlotProps, 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 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
1299
  //# sourceMappingURL=dom.d.mts.map