@inkbar/core 0.10.0 → 0.12.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 { A as DocumentSource, Bn as Matrix, Cn as FormAction, D as InkStatus, E as InkDocument, Gt as LineEnding, Hn as Quad, L as FormController, Ln as PageInfo, Mn as Readable, Nt as FreeTextAnnotation, O as OpenOptions, Ot as AnnotationType, P as isBlankQuery, Qt as NoteAnnotation, Sn as FieldsMode, Un as Rect, Vn as Point, X as AnnotationEdit, Z as AnnotationStore, _ as ScopedToolStyle, _t as AnnotationDefaults, a as SignatureOptions, b as StyleProps, h as CurrentStyle, hn as TextMarkupAnnotation, i as SignatureLibrary, it as RecordStore, j as SearchHit, nt as RecordBase, o as SignatureStore, q as PluginHistory, rt as RecordChange, s as SignatureTemplate, t as signField, v as StyleGroup, vt as cssVariableDefaults, wt as AnnotationInput, x as ToolStyle, xt as Annotation, y as StyleKey, z as InkError, zn as PdfAssets } from "./sign-BTbtPHbM.mjs";
1
+ import { $n as Point, B as isBlankQuery, Bn as Destination, Bt as FreeTextAnnotation, F as OutlineItem, Ft as AnnotationType, I as DocumentSource, In as ViewerAction, K as InkError, L as SearchHit, M as InkStatus, N as OpenOptions, Ot as Annotation, Qn as Matrix, Qt as LineEnding, S as ToolStyle, Sn as TextMarkupAnnotation, T as InkStorage, Tt as cssVariableDefaults, U as PageLink, Vn as LinkTarget, W as FormController, Wn as Readable, Yn as PageInfo, Zn as PdfAssets, a as SignatureOptions, an as NoteAnnotation, b as StyleKey, dt as RecordStore, er as Quad, et as PluginHistory, g as CurrentStyle, i as SignatureLibrary, it as AnnotationStore, j as InkDocument, jt as AnnotationInput, kn as FieldsMode, lt as RecordBase, o as SignatureStore, rt as AnnotationEdit, s as SignatureTemplate, t as signField, tr as Rect, ut as RecordChange, v as ScopedToolStyle, wt as AnnotationDefaults, x as StyleProps, y as StyleGroup } from "./sign-UdMGeqRr.mjs";
2
2
  import { IconNode } from "@inkbar/icons";
3
3
  //#region src/dom/transform.d.ts
4
4
  type ViewRotation = 0 | 90 | 180 | 270;
@@ -108,6 +108,11 @@ interface ViewportOptions {
108
108
  minZoom?: number;
109
109
  /** Default 8. */
110
110
  maxZoom?: number;
111
+ /**
112
+ * Zoom the document when two fingers pinch over the container. Default `true`. When false the
113
+ * viewport leaves `touch-action` alone and the browser zooms the page as it would anyway.
114
+ */
115
+ pinchZoom?: boolean;
111
116
  onMount(page: number, host: HTMLElement, transform: PageTransform): void;
112
117
  onUpdate(page: number, host: HTMLElement, transform: PageTransform): void;
113
118
  onUnmount(page: number, host: HTMLElement): void;
@@ -139,6 +144,31 @@ interface Viewport {
139
144
  scrollToRect(page: number, rect: Rect, opts?: {
140
145
  behavior?: ScrollBehavior;
141
146
  }): void;
147
+ /**
148
+ * Scrolls to a PDF destination without touching zoom. The destination's own zoom is ignored.
149
+ * `xyz` puts (`left`, `top`) at the container's top-left; a missing `left` keeps the horizontal
150
+ * scroll and a missing `top` lands at the page top as `scrollToPage` does. `fith`/`fitbh` put
151
+ * `top` at the top, `fitv`/`fitbv` put `left` at the left, `fitr` centres the rect (always
152
+ * scrolling), and `fit`/`fitb` act as `scrollToPage`. Single-page mode switches page first.
153
+ * "Top" and "left" are those of the converted point, so a rotated page is framed as it looks.
154
+ */
155
+ scrollToDestination(dest: Destination, opts?: {
156
+ behavior?: ScrollBehavior;
157
+ }): void;
158
+ /**
159
+ * The layout-space CSS y (measured from the pages element, as `readingLine` is) that
160
+ * `scrollToDestination` puts at the container's top. `undefined` when the page has no box
161
+ * (another page in single-page mode, or out of range).
162
+ */
163
+ destinationY(dest: Destination): number | undefined;
164
+ /**
165
+ * Layout-space CSS y of the line one third down the visible area:
166
+ * `scrollTop + clientHeight / 3`, less where the pages element starts; at the bottom of the
167
+ * visible area instead while scrolled to the end, so the last destinations can be reached.
168
+ * Compare it with `destinationY` to tell which destination the reader has reached. Updates
169
+ * on scroll, resize and layout.
170
+ */
171
+ readonly readingLine: Readable<number>;
142
172
  transformFor(page: number): PageTransform;
143
173
  hostFor(page: number): HTMLElement | undefined;
144
174
  /** The mounted page under a viewport (client) point, if any. */
@@ -162,6 +192,103 @@ interface ViewportKeysOptions {
162
192
  */
163
193
  export declare function attachViewportKeys(el: HTMLElement, opts: ViewportKeysOptions): () => void;
164
194
  //#endregion
195
+ //#region src/dom/pinch.d.ts
196
+ interface PinchFrame {
197
+ /** The zoom the pinch has reached, clamped to the viewport's limits. */
198
+ zoom: number;
199
+ /** `zoom` over the zoom the pinch started at. */
200
+ factor: number;
201
+ /** The midpoint between the fingers when the pinch started. */
202
+ anchor: Point;
203
+ /** How far that midpoint has moved since. */
204
+ pan: Point;
205
+ }
206
+ export declare function pinchFrame(start: readonly [Point, Point], now: readonly [Point, Point], startScale: number, minZoom: number, maxZoom: number): PinchFrame;
207
+ interface ZoomPreview {
208
+ /** Scales the pages by `factor` around `anchor`, then moves them by `pan`. */
209
+ show(factor: number, anchor: Point, pan: Point): void;
210
+ clear(): void;
211
+ /** Shifts the pages by `offset`, then eases them back to where the layout puts them. */
212
+ settle(offset: Point): void;
213
+ destroy(): void;
214
+ }
215
+ /**
216
+ * The pinch preview: a transform on the pages element, which the browser composites without
217
+ * laying anything out. `settle` covers what a preview can show but the committed layout
218
+ * cannot reach (mainly scroll clamped at the content edges): the pages start where the fingers
219
+ * left them and slide into place.
220
+ */
221
+ export declare function createZoomPreview(container: HTMLElement, pagesEl: HTMLElement): ZoomPreview;
222
+ interface TouchPinchOptions {
223
+ container: HTMLElement;
224
+ preview: ZoomPreview;
225
+ /** The effective zoom when a pinch starts. */
226
+ scale(): number;
227
+ minZoom: number;
228
+ maxZoom: number;
229
+ /**
230
+ * Scrolls the container so the content moves by `delta`, and returns how much of it the
231
+ * scroll took: less than `delta` where the scroll stops at the content edges.
232
+ */
233
+ scrollBy(delta: Point): Point;
234
+ /**
235
+ * Called once per pinch, when either finger lifts or is cancelled, after the preview clears.
236
+ * The frame's `anchor` is where the point that started between the fingers sits now, after
237
+ * the scrolling, and its `pan` is only the travel the scroll could not take.
238
+ */
239
+ commit(frame: PinchFrame): void;
240
+ }
241
+ /**
242
+ * Tracks touches on the container with touch events, which every touch browser sends as one
243
+ * stream (pointer events may be cancelled once the browser decides to pan). The first two
244
+ * fingers down start a pinch; a third is ignored. The pinch ends when either of its fingers
245
+ * lifts or is cancelled, and any finger still down then starts nothing until every finger has
246
+ * lifted. While two fingers are down their moves are prevented, so the browser neither pans
247
+ * nor zooms underneath; one finger's moves never are, so a one-finger scroll stays native. A
248
+ * move the browser will not let us cancel means it is scrolling natively already: that travel
249
+ * is left to it, and only what the fingers do after it is scrolled here.
250
+ * The viewport claims pinch on the container (`touch-action: pan-x pan-y`), which keeps the
251
+ * page from zooming as well; the tool controller turns off one-finger panning on the pages
252
+ * element while a drag tool is ready, and two fingers still land here. A finger
253
+ * that lands alone starts afresh, so an end the browser never sent leaves nothing behind.
254
+ */
255
+ export declare function attachTouchPinch(opts: TouchPinchOptions): {
256
+ destroy(): void;
257
+ };
258
+ /**
259
+ * The zoom factor one wheel event stands for. A trackpad pinch arrives as ctrl+wheel events
260
+ * with small pixel deltas, which zoom smoothly. A mouse wheel notch with ctrl held arrives in
261
+ * line or page mode, or as one large pixel delta, and is one small step, whatever its size.
262
+ */
263
+ export declare function wheelFactor(e: {
264
+ deltaY: number;
265
+ deltaMode: number;
266
+ }): number;
267
+ interface TrackpadPinchOptions {
268
+ container: HTMLElement;
269
+ preview: ZoomPreview;
270
+ /** The effective zoom when a pinch starts. */
271
+ scale(): number;
272
+ minZoom: number;
273
+ maxZoom: number;
274
+ /** Called once per pinch, after the preview clears. */
275
+ commit(frame: PinchFrame): void;
276
+ }
277
+ /**
278
+ * A trackpad pinch over the container. Browsers report it as ctrl+wheel events, which are
279
+ * taken over so the page does not zoom; a run of them is one pinch, anchored at the pointer
280
+ * where it began and committed once the events stop, or as soon as the container scrolls (a
281
+ * plain wheel, a scroll bar), so the scroll moves the committed layout and not the preview.
282
+ * Safari also has gesture events, which give the scale directly; while one of those runs,
283
+ * ctrl+wheel is ignored so nothing counts twice. Safari on a touch screen sends gesture events
284
+ * for a touch pinch too, which `attachTouchPinch` already handles: while a finger is down on
285
+ * the container they are prevented and otherwise ignored. The wheel listener is non-passive
286
+ * because it has to call `preventDefault`.
287
+ */
288
+ export declare function attachTrackpadPinch(opts: TrackpadPinchOptions): {
289
+ destroy(): void;
290
+ };
291
+ //#endregion
165
292
  //#region src/dom/file-actions.d.ts
166
293
  interface DownloadOptions {
167
294
  /** The name to save under. Default: the document's `fileName`. */
@@ -208,9 +335,9 @@ interface HistoryKeysTarget {
208
335
  */
209
336
  export declare function attachHistoryKeys(el: HTMLElement, history: () => HistoryKeysTarget | null | undefined): () => void;
210
337
  /**
211
- * Keeps focus in the viewer when a focused Undo or Redo button inside `el` turns disabled
212
- * (it undid or redid the last step), which would otherwise drop focus to `<body>`, out of
213
- * reach of the undo and redo keys. Focus moves to `scroll()`, the viewer's scroll element,
338
+ * Keeps focus in the viewer when a focused Undo, Redo, Back or Forward button inside `el` turns
339
+ * disabled (it undid, redid or went back over the last step), which would otherwise drop focus
340
+ * to `<body>`, out of reach of the viewer's keys. Focus moves to `scroll()`, the viewer's scroll element,
214
341
  * without scrolling. Returns a function that removes the listeners.
215
342
  *
216
343
  * Chrome and Firefox blur the button as it is disabled: its `focusout` comes while the
@@ -610,6 +737,17 @@ interface ToolOptions {
610
737
  }
611
738
  export declare function createToolOptions(tools?: readonly Tool[]): ToolOptions;
612
739
  //#endregion
740
+ //#region src/dom/tools/press.d.ts
741
+ type PressKind = 'press' | 'long-press';
742
+ /** A press on a page that nothing in Inkbar acted on. */
743
+ interface PagePress {
744
+ /** Zero-based page index. */
745
+ page: number;
746
+ /** PDF user space on that page, points, origin bottom-left, before /Rotate. */
747
+ point: Point;
748
+ pointerType: 'mouse' | 'touch' | 'pen';
749
+ }
750
+ //#endregion
613
751
  //#region src/dom/tools/controller.d.ts
614
752
  /** The tools every viewer has. Creation tools are the host's to pass. */
615
753
  type CoreToolId = 'select-text' | 'select';
@@ -665,6 +803,12 @@ interface Tool<O extends object = object> {
665
803
  /** Default sticky. */
666
804
  kind?: ToolKind;
667
805
  cursor: string;
806
+ /**
807
+ * When true, one finger drags with the tool over the document instead of scrolling it,
808
+ * while the tool is active (and, for a one-shot tool, until it has made something). Two
809
+ * fingers still scroll and zoom.
810
+ */
811
+ claimsTouch?: boolean;
668
812
  /** Style group the tool creates into; select tools have none. */
669
813
  styleGroup?: StyleGroup;
670
814
  /** Option defaults. Options persist per tool for the viewer's life. */
@@ -715,6 +859,24 @@ interface ToolControllerOptions {
715
859
  * rebuild) so options persist; by default the controller keeps its own.
716
860
  */
717
861
  options?: ToolOptions;
862
+ /**
863
+ * A press or long press on a page that nothing in Inkbar acted on (see the top of
864
+ * controller.ts for which presses count).
865
+ */
866
+ onPress?(kind: PressKind, press: PagePress): void;
867
+ /**
868
+ * The link at a user-space point on a page, if one is followed there. Asked only under
869
+ * `select-text` and `select`.
870
+ */
871
+ linkAt?(page: number, point: Point): PageLink | undefined;
872
+ /** A still press or a tap on a link (see the top of controller.ts); it is not an `onPress`. */
873
+ onLink?(link: PageLink): void;
874
+ /**
875
+ * The link a press would follow is now `link`, or none: the pointer moved onto or off it,
876
+ * left the viewport, or the tool changed. Called once per change, and with `undefined` on
877
+ * destroy when a link was hovered.
878
+ */
879
+ onLinkHover?(link: PageLink | undefined): void;
718
880
  }
719
881
  /** The mounted page under a client point, with the point in CSS px and user space. */
720
882
  export declare function hitFor(ctx: ToolContext, e: {
@@ -812,6 +974,12 @@ interface PluginContext {
812
974
  * and `onChange` to load and save it.
813
975
  */
814
976
  store<T extends RecordBase>(name: string, opts?: PluginStoreOptions<T>): Readable<RecordStore<T> | null>;
977
+ /**
978
+ * Settings that outlive the document and the visit, kept in the viewer's `storage` under
979
+ * `plugin.<id>.<key>` and visible to no other plugin. Use `store()` for records that belong to
980
+ * a document and undo with edits; use this for preferences such as a panel width.
981
+ */
982
+ readonly storage: InkStorage;
815
983
  /** Runs for each document that opens; the returned function runs when it closes. */
816
984
  onDocument(fn: (doc: InkDocument) => void | (() => void)): void;
817
985
  /**
@@ -833,6 +1001,16 @@ interface PluginContext {
833
1001
  * hits) when the host has no search.
834
1002
  */
835
1003
  readonly search: ViewerSearch;
1004
+ /**
1005
+ * A press on a page that nothing in Inkbar acted on. Returns a function that stops listening.
1006
+ * Fires only under the text and rectangle select tools.
1007
+ */
1008
+ onPress(fn: (press: PagePress) => void): () => void;
1009
+ /**
1010
+ * A touch or pen held still on a page that nothing in Inkbar acted on. Returns a function that
1011
+ * stops listening. Fires only under the text and rectangle select tools.
1012
+ */
1013
+ onLongPress(fn: (press: PagePress) => void): () => void;
836
1014
  }
837
1015
  /** A factory's parameters: its options, optional only when `O` has no required field. */
838
1016
  type PluginFactoryArgs<O> = {} extends O ? [options?: O & PluginOptions] : [options: O & PluginOptions];
@@ -963,6 +1141,8 @@ interface PluginHostOptions {
963
1141
  viewport?: () => Viewport | null | undefined;
964
1142
  /** The viewer's search; without one, `ctx.search` is inert. */
965
1143
  search?: ViewerSearch;
1144
+ /** Where plugins keep settings, each under `plugin.<id>.`; memory when omitted. */
1145
+ storage?: InkStorage;
966
1146
  }
967
1147
  /**
968
1148
  * A plugin's records as the host app sees them: the plugin's own handle without `annotates`
@@ -998,6 +1178,14 @@ interface PluginHost extends LayerSource {
998
1178
  readonly layers: readonly PluginLayer[];
999
1179
  /** Calls `listener` on every `ctx.redecorate()`; returns a stop function. */
1000
1180
  watchRedecorate(listener: () => void): () => void;
1181
+ /**
1182
+ * Tells every `onPress` (or, for a long press, `onLongPress`) listener, in the order the
1183
+ * listeners were added, across plugins. A listener that throws is logged and the rest still
1184
+ * run.
1185
+ *
1186
+ * @internal For the viewer engine, which passes the tool controller's presses on.
1187
+ */
1188
+ emitPress(kind: PressKind, press: PagePress): void;
1001
1189
  destroy(): void;
1002
1190
  }
1003
1191
  /**
@@ -1039,6 +1227,59 @@ interface FormLayer {
1039
1227
  destroy(): void;
1040
1228
  }
1041
1229
  //#endregion
1230
+ //#region src/dom/navigation.d.ts
1231
+ /** Where a followed target comes from. */
1232
+ interface FollowOptions {
1233
+ /**
1234
+ * The page the target was pressed on: a link's own page. Next and previous page run from it,
1235
+ * as the link layer names them; without it they run from the current page, as an outline
1236
+ * item's do.
1237
+ */
1238
+ from?: number;
1239
+ }
1240
+ interface Navigation {
1241
+ /** Whether `back()` has somewhere to go. */
1242
+ readonly canGoBack: Readable<boolean>;
1243
+ /** Whether `forward()` has somewhere to go. */
1244
+ readonly canGoForward: Readable<boolean>;
1245
+ /** Returns to the position before the last jump, keeping the current one for `forward()`. */
1246
+ back(): void;
1247
+ /** Undoes the last `back()`. */
1248
+ forward(): void;
1249
+ /**
1250
+ * Records where the view is, then goes to `dest`. A page the document lacks does nothing, and
1251
+ * a jump that leaves the view where it was records nothing.
1252
+ */
1253
+ goTo(dest: Destination): void;
1254
+ /**
1255
+ * Resolves and follows any target. URLs go to `report` as `open-url` (only http, https,
1256
+ * mailto and tel); unsupported targets and destinations that resolve to nothing do nothing.
1257
+ */
1258
+ follow(target: LinkTarget, opts?: FollowOptions): Promise<void>;
1259
+ /** Forgets every position, as when another document opens. */
1260
+ clear(): void;
1261
+ }
1262
+ interface NavigationDeps {
1263
+ viewport: () => Viewport | undefined;
1264
+ document: () => InkDocument | undefined;
1265
+ /** Where the view is now, as a destination to come back to. */
1266
+ here: () => Destination | undefined;
1267
+ /** Hands a URL to the host: Inkbar never opens one itself. */
1268
+ report: (a: ViewerAction) => void;
1269
+ }
1270
+ //#endregion
1271
+ //#region src/dom/link-layer.d.ts
1272
+ interface LinkLayer {
1273
+ /** `div.ink-link-layer`, with `data-ink-link-layer`; never takes pointer events. */
1274
+ readonly element: HTMLElement;
1275
+ update(transform: PageTransform): void;
1276
+ /** The links Tab stops at, in the order the file lists them. */
1277
+ tabStops(): HTMLElement[];
1278
+ /** Reads each link's name from the text under it again, once the text layer has mounted. */
1279
+ relabel(): void;
1280
+ destroy(): void;
1281
+ }
1282
+ //#endregion
1042
1283
  //#region src/dom/search/highlights.d.ts
1043
1284
  /** The highlights of one viewer's pages; see `createSearchHighlights`. */
1044
1285
  interface SearchHighlights {
@@ -1071,6 +1312,8 @@ interface PageMountOptions {
1071
1312
  formActive?(): boolean;
1072
1313
  /** A signature field asked to be signed. */
1073
1314
  onSignField?(req: SignFieldRequest): void;
1315
+ /** A link was activated from the keyboard or by assistive technology. */
1316
+ followLink?(target: LinkTarget, opts: FollowOptions): void;
1074
1317
  /** Plugin layers, mounted above the overlay. The engine passes them for its pages only. */
1075
1318
  layers?: PluginLayers;
1076
1319
  /** Search match highlights, mounted below the overlay. */
@@ -1088,22 +1331,26 @@ interface PageMountOptions {
1088
1331
  onRendered?(layer: PageLayer): void;
1089
1332
  }
1090
1333
  /**
1091
- * The page layers that can fail and recover: the canvas, the text layer and the form layer's
1092
- * canvas of widget appearances.
1334
+ * The page's layers: the canvas, the text layer and the form layer's canvas of widget
1335
+ * appearances, which can fail and recover, and the links, which draw no pixels and never report.
1093
1336
  */
1094
- type PageLayer = 'canvas' | 'text' | 'form';
1337
+ type PageLayer = 'canvas' | 'text' | 'links' | 'form';
1095
1338
  interface PageMount {
1096
1339
  readonly renderer: PageRenderer;
1097
1340
  readonly textLayer: TextLayerHandle;
1098
1341
  readonly overlay: Overlay;
1099
1342
  /** The page's form fields; undefined when the document has none. */
1100
1343
  readonly form: FormLayer | undefined;
1344
+ /** The page's links; undefined when the page has none. */
1345
+ readonly links: LinkLayer | undefined;
1346
+ /** The page's fields and links Tab stops at, in the one order they share. */
1347
+ tabStops(): HTMLElement[];
1101
1348
  update(transform: PageTransform): void;
1102
1349
  destroy(): void;
1103
1350
  }
1104
1351
  /**
1105
- * Canvas, text layer, form layer, annotation overlay and any plugin layers for one page, stacked
1106
- * in that order.
1352
+ * Canvas, text layer, links, search highlights, form layer, annotation overlay and any plugin
1353
+ * layers for one page, stacked in that order.
1107
1354
  */
1108
1355
  export declare function createPageMount(opts: PageMountOptions): PageMount;
1109
1356
  //#endregion
@@ -1708,6 +1955,8 @@ interface MountViewerOptions {
1708
1955
  rotation?: ViewRotation;
1709
1956
  gap?: number;
1710
1957
  buffer?: number;
1958
+ /** Zoom the document on a two-finger pinch. Default `true`; see `ViewportOptions.pinchZoom`. */
1959
+ pinchZoom?: boolean;
1711
1960
  tool?: ToolId;
1712
1961
  /**
1713
1962
  * The creation tools (`allTools()`, or the ones the host imports); `select-text` and `select`
@@ -1741,10 +1990,16 @@ interface MountViewerOptions {
1741
1990
  */
1742
1991
  fonts?: string[];
1743
1992
  /**
1744
- * Where signature templates live. Default: memory, gone on reload
1745
- * (`createMemorySignatureStore`). `createLocalSignatureStore` keeps them in the browser.
1993
+ * Where signature templates live. Default: they go in `storage`.
1994
+ *
1995
+ * @deprecated Pass `storage` instead. When both are given, this wins.
1746
1996
  */
1747
1997
  signatures?: SignatureStore;
1998
+ /**
1999
+ * What the viewer keeps between visits, such as saved signatures. Default: memory, gone on
2000
+ * reload (`createMemoryStorage`). `createLocalStorage()` keeps it in the browser.
2001
+ */
2002
+ storage?: InkStorage;
1748
2003
  /**
1749
2004
  * The templates the `signature` tool and the signature controls share. A binding or
1750
2005
  * `createViewer` passes its own, so they outlive one document; it wins over `signatures`.
@@ -1769,10 +2024,12 @@ interface MountViewerOptions {
1769
2024
  */
1770
2025
  onSignField?(req: SignFieldRequest): void;
1771
2026
  /**
1772
- * The form asked the host to submit, open a link, send mail, print or prompt. Inkbar itself
1773
- * never does any of these.
2027
+ * The viewer asked the host to do something: a form's submit, mail, print or prompt, or a
2028
+ * link to a URL. Inkbar itself never does any of these.
1774
2029
  */
1775
- onFormAction?(action: FormAction): void;
2030
+ onAction?(action: ViewerAction): void;
2031
+ /** @deprecated Use `onAction`. Removed in 0.13.0. Ignored when `onAction` is given. */
2032
+ onFormAction?(action: ViewerAction): void;
1776
2033
  /** A form script called `app.alert`: show `message` (text, not markup) without blocking. */
1777
2034
  onFormAlert?(message: string): void;
1778
2035
  /** Annotation content is rendered by the host (custom slots). Changing it needs `rebuild`. */
@@ -1831,9 +2088,17 @@ interface ViewerEngine {
1831
2088
  readonly fonts: readonly string[];
1832
2089
  /** The signature templates: the host's current library, or the engine's own. */
1833
2090
  readonly signatures: SignatureLibrary;
2091
+ /** The `storage` option, or a new memory store. */
2092
+ readonly storage: InkStorage;
1834
2093
  /** The fonts a typed signature offers: the `signatureFonts` option, else `SIGNATURE_FONTS`. */
1835
2094
  readonly signatureFonts: readonly string[];
1836
2095
  readonly pages: ReadonlyMap<number, PageMount>;
2096
+ /**
2097
+ * Back and forward through the document's jumps: links, outline items and form buttons that
2098
+ * go to a page. It lasts as long as the engine, across rebuilds, and starts empty for each
2099
+ * document. URL targets reach `onAction`.
2100
+ */
2101
+ readonly navigation: Navigation;
1837
2102
  /**
1838
2103
  * Recreates the viewport for construction-only options, keeping zoom, page, mode, rotation
1839
2104
  * and tool. The scroll position is kept too: the user-space point at the top-left of the
@@ -1843,6 +2108,7 @@ interface ViewerEngine {
1843
2108
  rebuild(opts: {
1844
2109
  gap?: number;
1845
2110
  buffer?: number;
2111
+ pinchZoom?: boolean;
1846
2112
  customAnnotations?: boolean;
1847
2113
  }): void;
1848
2114
  /**
@@ -1937,6 +2203,23 @@ interface Viewer {
1937
2203
  * in place, and for the documents opened after it.
1938
2204
  */
1939
2205
  setFormHighlight(on: boolean): void;
2206
+ /**
2207
+ * Whether `back()` has somewhere to go: a link, outline item or form button jumped since the
2208
+ * document opened. False while no document is ready.
2209
+ */
2210
+ readonly canGoBack: Readable<boolean>;
2211
+ /** Whether `forward()` has somewhere to go. False while no document is ready. */
2212
+ readonly canGoForward: Readable<boolean>;
2213
+ /** Returns to where the view was before the last jump. History starts over with each document. */
2214
+ back(): void;
2215
+ /** Goes to where the last `back()` left from. */
2216
+ forward(): void;
2217
+ /**
2218
+ * Follows a link target as a click on the link would: a destination or Named page action
2219
+ * scrolls (zoom unchanged) and can be gone back from; a URL reaches `onAction` as
2220
+ * `open-url` and is never opened by the viewer. Does nothing while no document is ready.
2221
+ */
2222
+ follow(target: LinkTarget): Promise<void>;
1940
2223
  /** The plugins' commands by namespaced id (`sandbox.suggest`); place one with `createCommandButton`. */
1941
2224
  readonly commands: {
1942
2225
  get(id: string): Command | undefined;
@@ -2173,6 +2456,19 @@ interface SidebarControllerOptions {
2173
2456
  * and the client. Without it they come from a counter.
2174
2457
  */
2175
2458
  idPrefix?: string;
2459
+ /** Where the width is saved, under `sidebar.<name>.width`. Without it the width lasts the controller's life. */
2460
+ storage?: InkStorage;
2461
+ /** The key's middle part. Default: the side. Give two sidebars on one side different names. */
2462
+ name?: string;
2463
+ /** Default 320, in CSS px. */
2464
+ defaultWidth?: number;
2465
+ /** Default 240. */
2466
+ minWidth?: number;
2467
+ /** Default 480. The shown width also stays within half the sidebar's container. */
2468
+ maxWidth?: number;
2469
+ /** Controlled when given: drags and keys only report through `onWidthChange`, and storage is not read or written. */
2470
+ width?: number;
2471
+ onWidthChange?(width: number): void;
2176
2472
  }
2177
2473
  interface SidebarState {
2178
2474
  layout: SidebarLayout;
@@ -2181,13 +2477,17 @@ interface SidebarState {
2181
2477
  /** The open panels' ids, in panel order: at most one for rail and tabs. */
2182
2478
  open: readonly string[];
2183
2479
  visible: boolean;
2480
+ /** The wanted width: saved, dragged or default. `rootStyle()` gives the shown one. */
2481
+ width: number;
2482
+ /** True while the handle is dragged. */
2483
+ resizing: boolean;
2184
2484
  }
2185
2485
  interface SidebarController {
2186
2486
  readonly state: Readable<SidebarState>;
2187
2487
  /**
2188
2488
  * Takes new options. `open` given makes the sidebar controlled. When the panels no longer
2189
2489
  * hold an open one, rail and tabs open the first remaining and stack drops it; the new value
2190
- * goes to `onOpenChange`, controlled or not.
2490
+ * goes to `onOpenChange`, controlled or not. `width` given makes the width controlled.
2191
2491
  */
2192
2492
  update(opts: Partial<SidebarControllerOptions>): void;
2193
2493
  /** What activating `id`'s trigger does: rail opens or closes, tabs switch, stack expands or collapses. */
@@ -2199,6 +2499,16 @@ interface SidebarController {
2199
2499
  * `hidden` while it is not `visible`.
2200
2500
  */
2201
2501
  rootAttrs(): Record<string, string>;
2502
+ /** `--ink-sidebar-width` for the root: the shown width in px. */
2503
+ rootStyle(): Record<string, string>;
2504
+ /** The id of the element holding the panels, which the handle's `aria-controls` names. */
2505
+ panelsAttrs(): Record<string, string>;
2506
+ /** The separator's attributes; includes `hidden` while no panel is open or the sidebar is hidden. */
2507
+ handleAttrs(): Record<string, string>;
2508
+ /** Pointer drag, keys and double-click on the handle; observes the sidebar's container. Returns the unbind. */
2509
+ bindHandle(el: HTMLElement): () => void;
2510
+ /** Back to `defaultWidth`; removes the saved key. */
2511
+ resetWidth(): void;
2202
2512
  /** ARIA for the element holding the triggers: a tablist for rail and tabs. */
2203
2513
  tablistAttrs(): Record<string, string>;
2204
2514
  /** ARIA for the rail button / tab / stack header of `id`. */
@@ -2218,6 +2528,12 @@ interface SidebarController {
2218
2528
  }
2219
2529
  /** The text a badge shows, or null when it is hidden (empty or 0). */
2220
2530
  export declare function sidebarBadge(badge: string | number | undefined): string | null;
2531
+ /** The sidebar's widths in CSS px, unless the host gives its own. */
2532
+ export declare const SIDEBAR_WIDTH: {
2533
+ readonly default: 320;
2534
+ readonly min: 240;
2535
+ readonly max: 480;
2536
+ };
2221
2537
  export declare function createSidebarController(opts: SidebarControllerOptions): SidebarController;
2222
2538
  //#endregion
2223
2539
  //#region src/dom/sidebar/sidebar.d.ts
@@ -2345,6 +2661,102 @@ export declare function createThumbnailsController(deps: ThumbnailsDeps, initial
2345
2661
  */
2346
2662
  export declare function createThumbnails(viewer: Viewer, opts?: ThumbnailsOptions): HTMLElement;
2347
2663
  //#endregion
2664
+ //#region src/dom/outline/controller.d.ts
2665
+ interface OutlineControllerDeps {
2666
+ /** The open document; null while none is. */
2667
+ document: Readable<InkDocument | null>;
2668
+ /** The viewport whose reading line marks the current item; null while none is mounted. */
2669
+ viewport: Readable<Viewport | null>;
2670
+ /** Where activated items go, so jumps can be gone back from; null while no document is ready. */
2671
+ navigation: Readable<Navigation | null>;
2672
+ /** Prefix for the items' element ids. Pass one when the markup is rendered on the server. */
2673
+ idPrefix?: string | undefined;
2674
+ }
2675
+ interface OutlineController {
2676
+ /** The outline's top-level items; `[]` while loading and when the document has none. */
2677
+ readonly items: Readable<readonly OutlineItem[]>;
2678
+ /** True while the open document's outline is being read. */
2679
+ readonly loading: Readable<boolean>;
2680
+ /** The ids of the expanded items. Another document starts from its file's `open` flags. */
2681
+ readonly expanded: Readable<ReadonlySet<string>>;
2682
+ /**
2683
+ * The id of the item marked as where the reader is: the item reached, or its outermost
2684
+ * collapsed ancestor; the item last activated, until the reader scrolls away from it. Null
2685
+ * before the first item's destination.
2686
+ */
2687
+ readonly current: Readable<string | null>;
2688
+ /** The id of the item the user last moved to or activated; null until they do. */
2689
+ readonly focused: Readable<string | null>;
2690
+ /** Expands or collapses an item that has children. */
2691
+ toggle(id: string): void;
2692
+ expandAll(): void;
2693
+ collapseAll(): void;
2694
+ /**
2695
+ * Follows the item: a destination is scrolled to and recorded for Back, a URL goes to the host
2696
+ * through `onAction`, a page action navigates. An unsupported item does nothing.
2697
+ */
2698
+ activate(id: string): void;
2699
+ /** `role="tree"` and its label, for the element holding the items. */
2700
+ treeAttrs(): Record<string, string>;
2701
+ /**
2702
+ * For each item's element: `role="treeitem"`, its `id`, `aria-level`, `aria-setsize`,
2703
+ * `aria-posinset`, `aria-expanded` (items with children), `aria-current="location"` on the
2704
+ * current item, `aria-disabled` on items Inkbar cannot follow, `aria-labelledby` (its title)
2705
+ * and `tabindex` (one item has 0).
2706
+ *
2707
+ * The item element contains its own children, as the WAI-ARIA tree pattern has it, so it is
2708
+ * named by its title rather than by everything inside it:
2709
+ *
2710
+ * ```html
2711
+ * <ul class="ink-outline-tree" {...treeAttrs()} onkeydown>
2712
+ * <li class="ink-outline-item" {...itemAttrs(id)} style="--ink-outline-level: 0">
2713
+ * <div class="ink-outline-row" {...rowAttrs(id)}>
2714
+ * <span class="ink-outline-toggle" aria-hidden="true">chevron</span>
2715
+ * <span class="ink-outline-title" {...titleAttrs(id)}>Title</span>
2716
+ * </div>
2717
+ * <ul class="ink-outline-group" role="group">children, shown only while expanded</ul>
2718
+ * </li>
2719
+ * </ul>
2720
+ * ```
2721
+ *
2722
+ * An item without children has `ink-outline-spacer` in place of the toggle and no group.
2723
+ * `--ink-outline-level` is its depth, 0 at the top; `data-bold` and `data-italic` go on the
2724
+ * item. A click on the toggle calls `toggle(id)`, anywhere else on the row `activate(id)`.
2725
+ */
2726
+ itemAttrs(id: string): Record<string, string | undefined>;
2727
+ /** The `id` of an item's title element, which names the item. */
2728
+ titleAttrs(id: string): Record<string, string>;
2729
+ /**
2730
+ * The `id` of an item's row (its chevron and title, without its children), which `bindScroll`
2731
+ * measures to keep the current item in view.
2732
+ */
2733
+ rowAttrs(id: string): Record<string, string>;
2734
+ /** The tree's key handler: put it on the element with `treeAttrs()`. */
2735
+ onKeydown(e: KeyboardEvent): void;
2736
+ /** Scrolls the current item into view inside `scroller` unless focus is in the tree. */
2737
+ bindScroll(scroller: HTMLElement): () => void;
2738
+ destroy(): void;
2739
+ }
2740
+ /**
2741
+ * `role="tree"` and its label, for the element holding an outline's items. The same as a
2742
+ * controller's `treeAttrs()`, without one, so markup rendered on the server has them too.
2743
+ */
2744
+ export declare function outlineTreeAttrs(): Record<string, string>;
2745
+ export declare function createOutlineController(deps: OutlineControllerDeps): OutlineController;
2746
+ //#endregion
2747
+ //#region src/dom/outline/outline.d.ts
2748
+ interface OutlineOptions {
2749
+ /** Shown when the document has no outline. Default: "This document has no outline". */
2750
+ emptyText?: string | undefined;
2751
+ }
2752
+ /**
2753
+ * The open document's outline as a tree. Give it a height (it fills its parent's) and place it
2754
+ * anywhere, a sidebar panel for instance. Clicking an item, or Enter on it, follows it and can be
2755
+ * gone back from; its chevron expands and collapses it. The item the reader has reached is
2756
+ * marked and kept in view. It stops when the viewer is destroyed.
2757
+ */
2758
+ export declare function createOutline(viewer: Viewer, opts?: OutlineOptions): HTMLElement;
2759
+ //#endregion
2348
2760
  //#region src/dom/viewer/controls.d.ts
2349
2761
  /**
2350
2762
  * An `<svg>` drawing `icon` from `@inkbar/icons`, hidden from assistive technology: the
@@ -2380,6 +2792,13 @@ export declare function createPrintButton(viewer: Viewer): HTMLButtonElement;
2380
2792
  export declare function createUndo(viewer: Viewer): HTMLButtonElement;
2381
2793
  /** Redoes the last undone change; disabled when there is none. */
2382
2794
  export declare function createRedo(viewer: Viewer): HTMLButtonElement;
2795
+ /**
2796
+ * Returns to where the view was before the last jump (`viewer.back()`): a link, an outline
2797
+ * item or a form button that went to a page. Disabled while there is nowhere to go back to.
2798
+ */
2799
+ export declare function createBack(viewer: Viewer): HTMLButtonElement;
2800
+ /** Goes forward again after `createBack` (`viewer.forward()`); disabled until Back is used. */
2801
+ export declare function createForward(viewer: Viewer): HTMLButtonElement;
2383
2802
  /**
2384
2803
  * Sets the tool; pressed while it is the active one. A creation, host or plugin tool's button
2385
2804
  * takes the tool's own `label` and `icon`; `opts.label` wins, and without either it is named by
@@ -2653,5 +3072,5 @@ interface FormAlert {
2653
3072
  */
2654
3073
  export declare function createFormAlert(root: HTMLElement): FormAlert;
2655
3074
  //#endregion
2656
- export { type AnnotationDecoration, type AnnotationInputOf, type AnnotationLink, type AnnotationLinkSpec, type AnnotationSlotProps, type AnnotationState, type ArrowheadChoice, type CardSpec, type ColorMenuModel, type ColorMenuOptions, type ColorMenuSwatch, type ColorProperty, type ColorTrigger, type Command, type CommandOptions, type CommandRun, type CommandSpec, type CoreToolId, type CreateViewerOptions, type CssLayout, type CssLayoutInput, type CssPageBox, type CssRect, type CurrentStyle, type DecorateAnnotation, type DownloadOptions, type EditorCloseReason, type FocusReturn, type FocusReturnOptions, type FormAlert, type FormLayer, type FreeTextEditor, type FreeTextEditorOptions, type HighlightMenuItem, type HighlightMenuModel, type HighlightOptions, type HistoryKeysTarget, type HostRecords, type InkPlugin, type LayerEvent, type LayerSource, type LayerSpec, type LayoutMode, type LineStyleMenuItem, type LineStyleMenuModel, type LineStyleMenuSection, type ListItem, type MarksHandle, type MarksOptions, type MarksRegistration, type MarksRegistry, type MarkupKind, type Menu, type MenuOptions, type MountViewerOptions, type Overlay, type OverlayOptions, type PageHit, type PageLayer, type PageLayers, type PageMount, type PageMountOptions, type PageRenderer, type PageRendererOptions, type PageTransform, type Palette, type PluginApi, type PluginContext, type PluginHost, type PluginHostOptions, type PluginLayer, type PluginLayerHandle, type PluginLayers, type PluginOptions, type PluginStoreOptions, type Popover, type PopoverOptions, type RecordListController, type RecordListRow, type RecordListSource, type RecordSelection, type Records, type RecordsSourceDeps, type RecordsSourceOptions, type ScopedToolStyle, type SearchController, type SearchControllerOptions, type SearchResultsOptions, type SearchState, type SelectionQuads, type ShapeKind, type ShapeMenuItem, type ShapeMenuModel, type ShapeOptions, type SidebarController, type SidebarControllerOptions, type SidebarLayout, type SidebarOpen, type SidebarPanelInfo, type SidebarSide, type SidebarState, type SignFieldMenu, type SignFieldMenuOptions, type SignFieldRequest, 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 ThumbnailDeps, type ThumbnailOptions, type ThumbnailPainter, type ThumbnailsController, type ThumbnailsDeps, type ThumbnailsOptions, type ThumbnailsState, 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 ViewerSearch, type Viewport, type ViewportHit, type ViewportKeysOptions, type ViewportOptions, type ZoomValue, cssVariableDefaults, isBlankQuery, signField };
3075
+ export { type AnnotationDecoration, type AnnotationInputOf, type AnnotationLink, type AnnotationLinkSpec, type AnnotationSlotProps, type AnnotationState, type ArrowheadChoice, type CardSpec, type ColorMenuModel, type ColorMenuOptions, type ColorMenuSwatch, type ColorProperty, type ColorTrigger, type Command, type CommandOptions, type CommandRun, type CommandSpec, type CoreToolId, type CreateViewerOptions, type CssLayout, type CssLayoutInput, type CssPageBox, type CssRect, type CurrentStyle, type DecorateAnnotation, type DownloadOptions, type EditorCloseReason, type FocusReturn, type FocusReturnOptions, type FormAlert, type FormLayer, type FreeTextEditor, type FreeTextEditorOptions, type HighlightMenuItem, type HighlightMenuModel, type HighlightOptions, type HistoryKeysTarget, type HostRecords, type InkPlugin, type LayerEvent, type LayerSource, type LayerSpec, type LayoutMode, type LineStyleMenuItem, type LineStyleMenuModel, type LineStyleMenuSection, type ListItem, type MarksHandle, type MarksOptions, type MarksRegistration, type MarksRegistry, type MarkupKind, type Menu, type MenuOptions, type MountViewerOptions, type Navigation, type NavigationDeps, type OutlineController, type OutlineControllerDeps, type OutlineOptions, type Overlay, type OverlayOptions, type PageHit, type PageLayer, type PageLayers, type PageMount, type PageMountOptions, type PagePress, type PageRenderer, type PageRendererOptions, type PageTransform, type Palette, type PinchFrame, type PluginApi, type PluginContext, type PluginHost, type PluginHostOptions, type PluginLayer, type PluginLayerHandle, type PluginLayers, type PluginOptions, type PluginStoreOptions, type Popover, type PopoverOptions, type PressKind, type RecordListController, type RecordListRow, type RecordListSource, type RecordSelection, type Records, type RecordsSourceDeps, type RecordsSourceOptions, type ScopedToolStyle, type SearchController, type SearchControllerOptions, type SearchResultsOptions, type SearchState, type SelectionQuads, type ShapeKind, type ShapeMenuItem, type ShapeMenuModel, type ShapeOptions, type SidebarController, type SidebarControllerOptions, type SidebarLayout, type SidebarOpen, type SidebarPanelInfo, type SidebarSide, type SidebarState, type SignFieldMenu, type SignFieldMenuOptions, type SignFieldRequest, 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 ThumbnailDeps, type ThumbnailOptions, type ThumbnailPainter, type ThumbnailsController, type ThumbnailsDeps, type ThumbnailsOptions, type ThumbnailsState, type Tool, type ToolContext, type ToolController, type ToolControllerOptions, type ToolId, type ToolKind, type ToolOptions, type ToolStyle, type ToolStyleTracker, type TouchPinchOptions, type TrackpadPinchOptions, type TypedSignatureOptions, type ViewRotation, type Viewer, type ViewerEngine, type ViewerSearch, type Viewport, type ViewportHit, type ViewportKeysOptions, type ViewportOptions, type ZoomPreview, type ZoomValue, cssVariableDefaults, isBlankQuery, signField };
2657
3076
  //# sourceMappingURL=dom.d.mts.map