@inkbar/svelte 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -30,7 +30,7 @@ Annotations are plain typed objects. Bind them with `bind:annotations` to keep t
30
30
  pnpm add @inkbar/svelte @inkbar/core @inkbar/theme
31
31
  ```
32
32
 
33
- Svelte 5.46.4 or later is a peer dependency. Add the Vite plugin from `@inkbar/core/vite` so PDF.js can load its worker and fonts; the [`@inkbar/core` README](https://github.com/inkbar/inkbar/tree/main/packages/core#serving-pdfjs-assets) covers it. The package ships `.svelte` sources, so your bundler compiles them for your target, including the server.
33
+ `@inkbar/core` (installed above, at the same version) and Svelte 5.46.4 or later are peer dependencies. Add the Vite plugin from `@inkbar/core/vite` so PDF.js can load its worker and fonts; the [`@inkbar/core` README](https://github.com/inkbar/inkbar/tree/main/packages/core#serving-pdfjs-assets) covers it. The package ships `.svelte` sources, so your bundler compiles them for your target, including the server.
34
34
 
35
35
  ## Usage
36
36
 
@@ -64,7 +64,7 @@ Svelte 5.46.4 or later is a peer dependency. Add the Vite plugin from `@inkbar/c
64
64
  const tools = [highlightTool(), redactAreaTool(), noteTool()]
65
65
  </script>
66
66
 
67
- <InkRoot src={{ url: signedUrl, key: documentId }} {assets} {tools} bind:annotations>
67
+ <InkRoot src={{ url: signedUrl, key: documentId }} {assets} {tools} bind:annotations history={true}>
68
68
  <InkToolbar>
69
69
  <InkToolButton tool="select-text" />
70
70
  <InkToolButton tool="select" />
@@ -89,9 +89,9 @@ Svelte 5.46.4 or later is a peer dependency. Add the Vite plugin from `@inkbar/c
89
89
  </InkRoot>
90
90
  ```
91
91
 
92
- `select-text` and `select` are always there. Every other tool is opt-in: pass the ones you offer through `tools`, from the tool factories in `@inkbar/core/dom`, or `allTools()` for all of them. A button for a tool you did not pass renders disabled and hidden, a tool menu renders nothing, and each logs an `InkError('UnknownTool')` to the console once. If the active tool leaves `tools`, the viewer switches to `select-text` and reports it through `onToolChange`.
92
+ `select-text` and `select` are always there. Every other tool is opt-in: pass the ones you offer through `tools`, from the tool factories in `@inkbar/core/dom`, or `allTools()` for all of them. A button for a tool you did not pass renders empty, disabled and `aria-hidden`, the highlight, shape and signature menus render nothing, and each logs an `InkError('UnknownTool')` to the console once. If the active tool leaves `tools`, the viewer switches to `select-text` and reports it through `onToolChange`.
93
93
 
94
- Each toolbar control is a component, so keep the ones you need and put them where you like. Buttons show icons from `@inkbar/icons`. Pass your own as `children` to replace one, and use `InkIcon` to put the same icons on your own buttons. For a button of your own, such as `<InkToolbarButton onclick={download}>Download</InkToolbarButton>`, use `InkToolbarButton`: it joins the toolbar's arrow-key focus and looks like the other buttons. `bind:annotations` makes your list the source of truth. Leave it off and Inkbar keeps the state itself, with undo and redo.
94
+ Each toolbar control is a component, so keep the ones you need and put them where you like. Buttons show icons from `@inkbar/icons`. Pass your own as `children` to replace one, and use `InkIcon` to put the same icons on your own buttons. For a button of your own, such as `<InkToolbarButton onclick={download}>Download</InkToolbarButton>`, use `InkToolbarButton`: it joins the toolbar's arrow-key focus and looks like the other buttons. `bind:annotations` makes your list the source of truth, and `history={true}` keeps undo and redo working with it. Leave the binding off and Inkbar keeps the state itself, with undo and redo on by default.
95
95
 
96
96
  ## Controlled mode
97
97
 
@@ -149,9 +149,17 @@ Inside `InkRoot`, `useHistory()` returns the same object. Its `batch(fn)` runs `
149
149
 
150
150
  `key` identifies the document. Reuse the same key when only the signed URL changes and the document is not reloaded.
151
151
 
152
+ `InkRoot` takes a few more options. `password` opens an encrypted PDF. `storage` sets what the viewer keeps between visits (see [Storage](#storage)). `minDocumentWidth` sets how narrow the document may get before a rail sidebar's panel floats over it (see [Sidebars](#sidebars)). `defaults` sets annotation colours; without it the theme's CSS variables apply. `fonts` sets the families the text style menu offers. `decorateAnnotation` adds attributes, classes and a screen-reader description to each annotation. `bind:page` and `bind:zoom` (or `onPageChange` and `onZoomChange`) follow and drive the viewport, and `bind:tool` (or `onToolChange`) does the same for the active tool. `onError` hears failed opens, form script errors and refused signings. `onActivate` hears the id of each activated annotation. `onFieldsChange` hears form value changes.
153
+
154
+ ## Viewport
155
+
156
+ `InkViewport` takes `mode`, `rotation`, `gap` (CSS pixels between pages, default 16), `buffer` (pages kept mounted either side of the visible ones, default 2) and `pinchZoom` (default `true`; `false` leaves pinches to the browser, which zooms the whole page). A change to `gap`, `buffer` or `pinchZoom` rebuilds the engine.
157
+
158
+ On a touch screen, two fingers pinch to zoom the document and scroll it. With `draw`, `sketch`, `shape`, `redact-area` and `freetext`, one finger draws; a finger tap draws nothing, and a pen that lands while a palm rests on the screen takes over. A shape, area redaction or text box gives one-finger scrolling back once it has made something.
159
+
152
160
  ## Forms
153
161
 
154
- `InkViewport` fills the PDF's form fields and runs the form's scripts. `useForm()` returns the fields, their values, and `set` and `reset`. Use `bind:fields` to hold the values in your own state. The form never submits, opens a link, sends mail or prints: `onformaction` hands each request to you. `formHighlight={false}` turns off the field tint, and a change applies to the open document in place.
162
+ `InkViewport` fills the PDF's form fields and runs the form's scripts. `useForm()` returns the fields, their values, and `set` and `reset`. Use `bind:fields` to hold the values in your own state. The form never submits, opens a link, sends mail or prints: `onaction` hands each request to you; so does a link to a URL. `formHighlight={false}` turns off the field tint, and a change applies to the open document in place.
155
163
 
156
164
  The [forms guide](https://inkbar.dev/docs/guides/forms/) covers controlled fields, form actions, scripts, signature fields and saving values as Gloss.
157
165
 
@@ -163,9 +171,26 @@ A root note with no text and no replies is removed when its popover closes, or w
163
171
 
164
172
  The highlight tool leaves `contents` free for the comment. `doc.text(page)` returns the page's text items; match the markup's `quads` against them to get the marked text. `InkHighlightMenu` is a split button for the tool: it picks the markup kind and its colour.
165
173
 
174
+ ## Style menus
175
+
176
+ `InkColorMenu` (`property="border"`, `"fill"` or `"text"`), `InkLineStyleMenu` (weight, dashes, arrowheads) and `InkTextStyleMenu` (font, size, colour, bold, italic, underline, alignment) edit the selection, or the active tool's style when nothing is selected. A menu disables when nothing supports its properties. `InkShapeMenu` is a split button for the `shape` tool and renders nothing unless `shapeTool` is in `tools`. `fonts` on `InkRoot` sets the families the text style menu offers.
177
+
166
178
  ## Signatures
167
179
 
168
- `InkSignatureMenu` lists saved signatures, picks one for the `signature` tool, removes them, and opens `InkSignatureDialog` to draw, type or upload a new one. The menu needs `signatureTool()` in `tools`. The dialog and signature form fields work without it; the dialog then only saves the signature. These are marks on the page, not cryptographic signatures. Pass `signatures` to `InkRoot` to keep them somewhere: `createLocalSignatureStore(key)` from `@inkbar/core` uses `localStorage`, and without it they last until reload. `signatureFonts` lists the handwriting fonts the Type tab offers; load them with `@font-face`. A placed signature keeps its aspect ratio when resized.
180
+ `InkSignatureMenu` lists saved signatures, picks one for the `signature` tool, removes them, and opens `InkSignatureDialog` to draw, type or upload a new one. The menu needs `signatureTool()` in `tools`. The dialog and signature form fields work without it; the dialog then only saves the signature. These are marks on the page, not cryptographic signatures. `InkRoot` keeps them in its `storage` under the key `signatures`, so without a store they last until reload. `signatureFonts` lists the handwriting fonts the Type tab offers; load them with `@font-face`. A placed signature keeps its aspect ratio when resized.
181
+
182
+ ## Storage
183
+
184
+ `InkRoot` keeps a few small things between visits: saved signatures, sidebar widths and plugin settings. Pass `storage` to choose where. `createLocalStorage()` from `@inkbar/core` keeps them in `localStorage`, and any `InkStorage` works, including an async one that talks to your server. The default is `createMemoryStorage()`, which forgets everything on reload. Inkbar never touches `localStorage`, cookies or the network unless the store you pass does. The root reads `storage` once, when it is created. See the [`@inkbar/core` README](https://github.com/inkbar/inkbar/tree/main/packages/core#storage) for the keys.
185
+
186
+ ```svelte
187
+ <script lang="ts">
188
+ import { createLocalStorage } from '@inkbar/core'
189
+ const storage = createLocalStorage()
190
+ </script>
191
+
192
+ <InkRoot {src} {assets} {storage}>
193
+ ```
169
194
 
170
195
  ## Plugins
171
196
 
@@ -187,7 +212,7 @@ Plugin stores undo with annotations. In controlled mode with `history`, each und
187
212
 
188
213
  ## Search
189
214
 
190
- `InkFindBar` is the find bar and `InkSearchButton` opens it. Place the bar anywhere inside `InkRoot`, once `InkViewport` is there; Ctrl/Cmd+F opens it while it is mounted. `useSearch()` returns the search `state` and its actions (`open`, `setQuery`, `setMatchCase`, `next`, `previous`, `close`) for your own control. See the [`@inkbar/core` README](https://github.com/inkbar/inkbar/tree/main/packages/core#search) for the API.
215
+ `InkFindBar` is the find bar and `InkSearchButton` opens it. Place the bar anywhere inside `InkRoot`, once `InkViewport` is there; Ctrl/Cmd+F opens it while it is mounted. `useSearch()` returns the search `state` and its actions (`open(query?)`, `setQuery`, `setMatchCase`, `next`, `previous`, `select`, `close`) for your own control. See the [`@inkbar/core` README](https://github.com/inkbar/inkbar/tree/main/packages/core#search) for the API.
191
216
 
192
217
  The bar handles Escape itself and stops it there, so an `onkeydown` you pass to `InkFindBar` never sees Escape.
193
218
 
@@ -196,6 +221,10 @@ The bar handles Escape itself and stops it there, so an `onkeydown` you pass to
196
221
  `InkSidebar` holds `InkPanel`s and places nothing itself: put it beside `InkViewport` with your own flex or grid layout. Each panel has an `id`, a `label`, an optional `icon` (an `IconNode` from `@inkbar/icons`) and an optional `badge`, a number or short string hidden when empty or 0. Its children are the panel's content, your own component or one of Inkbar's.
197
222
 
198
223
  ```svelte
224
+ <script lang="ts">
225
+ import { Square, MessageSquare } from '@inkbar/icons'
226
+ </script>
227
+
199
228
  <InkRoot {src} {assets}>
200
229
  <div class="app">
201
230
  <InkSidebar side="left" layout="rail" bind:open>
@@ -211,9 +240,23 @@ The bar handles Escape itself and stops it there, so an `onkeydown` you pass to
211
240
  </InkRoot>
212
241
  ```
213
242
 
214
- `layout` is `rail` (default: icon buttons beside the document, and activating the open panel's button closes it), `tabs` (labelled tabs, one panel open) or `stack` (a header per panel, any number expanded). `side` (`left` by default) decides which edge the rail and border sit on. `bind:open` is the open panel's id, or `null`, for rail and tabs, and the expanded ids for stack. Left out, the first panel starts open. When the open panel goes (an `{#if}`), rail and tabs open the first one left and stack drops it, and the bound `open` receives the new value. In the rail, the open panel shows its label as a title above its content. `visible` (default `true`) shows or hides the whole sidebar; it keeps the open panel, its content and its scroll for when it shows again. Your code decides when: `visible={hits > 0}` keeps a results sidebar out of the way until a search finds something.
243
+ `layout` is `rail` (default: icon buttons beside the document, and activating the open panel's button closes it), `tabs` (labelled tabs, one panel open) or `stack` (a header per panel, any number expanded). `side` (`left` by default) decides which edge the rail and border sit on. `bind:open` is the open panel's id, or `null`, for rail and tabs, and the expanded ids for stack. Left out, the first panel starts open, unless the sidebar has no room (see below). When the open panel goes (an `{#if}`), rail and tabs open the first one left and stack drops it, and the bound `open` receives the new value. In the rail, the open panel shows its label as a title above its content. `visible` (default `true`) shows or hides the whole sidebar; it keeps the open panel, its content and its scroll for when it shows again. Your code decides when: `visible={hits > 0}` keeps a results sidebar out of the way until a search finds something.
215
244
 
216
- Panels take their place in the order they appear in the markup, including one added later with `{#if}`. A closed panel stays mounted and hidden, so its content keeps its state and scroll position, across layout changes too. The keys and ARIA are core's: see the [`@inkbar/core` README](https://github.com/inkbar/inkbar/tree/main/packages/core#sidebars). The sidebar needs no document and works outside `InkRoot`. On the server it renders its frame with the open panel showing, and the stack headers; rail and tab buttons follow once it has mounted.
245
+ Panels take their place in the order they appear in the markup, including one added later with `{#if}`. A closed panel stays mounted and hidden, so its content keeps its state and scroll position, across layout changes too. The keys and ARIA are core's: see the [`@inkbar/core` README](https://github.com/inkbar/inkbar/tree/main/packages/core#sidebars). The sidebar needs no document and works outside `InkRoot`. On the server it renders its frame at its width with the open panel showing, the stack headers and the resize handle; rail and tab buttons follow once it has mounted.
246
+
247
+ Each sidebar has a resize handle on its inner edge. Drag it, or focus it and use the arrow keys (16px a step), Home and End. Enter or a double-click resets the width. The width starts at `defaultWidth` (320) and stays between `minWidth` (240) and `maxWidth` (480). The handle is labelled "Resize left sidebar" or "Resize right sidebar"; pass `handleLabel` to name it yourself. The sidebar sets `--ink-sidebar-width` inline, so a CSS override of it no longer applies. Pass `defaultWidth` instead. Inside `InkRoot` the sidebar saves its width in the root's `storage` under `sidebar.<name>.width`, where `name` defaults to the side; give two sidebars on one side different names. Pass `storage` to the sidebar to use another store, or to save its width outside `InkRoot`. The sidebar reads `storage`, `name`, `minDocumentWidth` and `handleLabel` once, when it is created. To control the width, bind `width` to a number: the handle then only updates the binding, and the sidebar neither reads nor writes storage. Bind it to a value that starts `undefined` and you only receive the width; the sidebar keeps saving it.
248
+
249
+ ```svelte
250
+ <InkSidebar name="tools" side="right" defaultWidth={360} bind:width={toolsWidth}>
251
+ ```
252
+
253
+ Sidebars that share a parent element make room for the document together. While the document beside them would be narrower than `minDocumentWidth` (480 by default), a rail sidebar's open panel floats over the pages like a drawer, and the rail stays in place to close and reopen it. When the parent grows again, the panel goes back beside the document. Tabs and stack sidebars never float: they narrow toward `minWidth` instead. Either way, the saved width and the bound `width` stay the width the reader chose. Set `minDocumentWidth` on `InkRoot` for every sidebar inside it, or on one `InkSidebar`, whose own wins.
254
+
255
+ A floating panel closes on a tap anywhere else in the parent (the pages, say), on `Escape`, or when the find bar opens. The closing tap does nothing else: no tool draws, no link is followed and no field takes focus. An unbound sidebar with no room when it mounts starts with its panel closed. A bound `open` is never changed for you: a close goes through `bind:open`, and a host that keeps it open keeps the panel floating. On the server the sidebar renders beside the document as usual; floating and starting closed are decided in the browser once it has mounted.
256
+
257
+ ```svelte
258
+ <InkRoot {src} {assets} minDocumentWidth={600}>
259
+ ```
217
260
 
218
261
  ## Thumbnails
219
262
 
@@ -231,6 +274,20 @@ Panels take their place in the order they appear in the markup, including one ad
231
274
 
232
275
  An item's height is worked out from its page alone, so position what you add absolutely. The `item` snippet renders inside the item's `<button>`: keep it non-interactive, with no links, buttons or inputs. Both need `InkRoot` and render empty on the server.
233
276
 
277
+ ## Outline and Back
278
+
279
+ `InkOutline` shows the document's outline as a tree. Clicking an item, or Enter on it, follows it: a destination scrolls there (without changing the zoom), a web address goes to the host as an `open-url` action. The chevron expands and collapses an item without following it. The item the reader has reached is marked `aria-current="location"` and kept in view. It fills its parent's height and scrolls, so put it in a panel:
280
+
281
+ ```svelte
282
+ <InkPanel id="outline" label="Outline" icon={List}>
283
+ <InkOutline emptyText="No outline" />
284
+ </InkPanel>
285
+ ```
286
+
287
+ `emptyText` is shown when the document has no outline. The `item` snippet, given the item and `{ current, expanded }`, replaces an item's title. The keys and ARIA are core's, as in the thumbnails. Needs `InkRoot`; the tree renders empty on the server.
288
+
289
+ `InkBack` and `InkForward` return to where the view was before a jump (a link, an outline item) and undo that. Each is disabled until there is somewhere to go, and takes a `child` snippet. Put them in an `InkToolbar`.
290
+
234
291
  ## Record lists
235
292
 
236
293
  `InkRecordList` lists a plugin's records as cards, the same cards their marks open, with the same actions. Name the records `<plugin>.<name>`:
@@ -243,7 +300,7 @@ An item's height is worked out from its page alone, so position what you add abs
243
300
  </InkPanel>
244
301
  ```
245
302
 
246
- The list and the marks share one selection: choosing a card selects its mark and scrolls the viewer there, and activating a mark selects its card. Each action runs in one undo step. `card`, `where` and `sort` replace the marks' card, filter and reading order. A new function rebuilds the list, so define them once in the script, never inline in the markup. `bind:count` receives the number listed whenever it changes, ready for a panel badge. The `empty` snippet replaces "Nothing here yet.". To list something of your own, pass a `source` (a `RecordListSource`, as core's `recordsSource` and `searchSource` build) in place of `records`: it gets the same cards, keys and selection. With both, `source` wins.
303
+ The list and the marks share one selection: choosing a card selects its mark and scrolls the viewer there, and activating a mark selects its card. Each action runs in one undo step. `card`, `where` and `sort` replace the marks' card, filter and reading order. A new function rebuilds the list, so define them once in the script, never inline in the markup. They do not apply to a `source`, which carries its own. `bind:count` receives the number listed whenever it changes, ready for a panel badge. The `empty` snippet replaces "Nothing here yet.". To list something of your own, pass a `source` (a `RecordListSource`, as core's `recordsSource` and `searchSource` build) in place of `records`: it gets the same cards, keys and selection. With both, `source` wins.
247
304
 
248
305
  `InkSearchResults` is the same list over the document search: one card per hit, titled with its page ("Page 2"), with its place on that page ("Match 3") and the text around it. Choosing a card makes its hit current, as the find bar's next and previous do. It has its own field, labelled "Find in document", above the cards and the find bar's match count in a footer below them; `field={false}` leaves the field out when a find bar is on the page. Field and find bar share the search state, so they never disagree.
249
306
 
@@ -251,11 +308,11 @@ To build your own, `useRecords<T>(name)` returns the live `records` and the `han
251
308
 
252
309
  ## Custom rendering
253
310
 
254
- Slots are snippets. `InkViewport` takes `loading`, `empty`, `error`, `annotation` and `pageError`. `InkThreadPopover` takes `children` as a snippet that receives the popover's props. `InkToolButton` takes `children` as a snippet of `{ active, label }`, and `InkCommand` one of `{ label, busy }`. `InkThumbnails` takes `item`, and `InkRecordList` takes `empty`. The props each receives are typed as `AnnotationSlotProps` and `ThreadPopoverSlotProps`, the same types the Vue and React packages export.
311
+ Slots are snippets. `InkViewport` takes `loading`, `empty`, `error`, `annotation` and `pageError`. `InkThreadPopover` takes `children` as a snippet that receives the popover's props. `InkToolButton` takes `children` as a snippet of `{ active, label }`, and `InkCommand` one of `{ label, busy }`. `InkThumbnails` and `InkOutline` take `item`, and `InkRecordList` takes `empty`. The props each receives are typed as `AnnotationSlotProps` and `ThreadPopoverSlotProps`, the same types the Vue and React packages export.
255
312
 
256
313
  `InkDownloadButton` and `InkPrintButton` download and print the open PDF; `filename` names the download (the opened `File`'s name, else the URL's last segment, else `document.pdf`). Printing loads the file into a hidden frame and opens the browser's print dialog for it; on iOS the PDF opens in a new tab instead. Until saving into the PDF ships, both give the file as it was opened, without this session's annotations.
257
314
 
258
- `InkRoot`, `InkToolbar`, `InkToolButton`, `InkCommand`, `InkUndo`, `InkRedo`, `InkDownloadButton`, `InkPrintButton`, `InkPrevPage`, `InkNextPage`, `InkZoomIn` and `InkZoomOut` take a `child` snippet to render your own element. Spread the `props` it gives you on that element. The snippet type is exported as `ChildSnippet`.
315
+ `InkRoot`, `InkToolbar`, `InkToolButton`, `InkToolbarButton`, `InkCommand`, `InkUndo`, `InkRedo`, `InkDownloadButton`, `InkPrintButton`, `InkSearchButton`, `InkPrevPage`, `InkNextPage`, `InkBack`, `InkForward`, `InkZoomIn` and `InkZoomOut` take a `child` snippet to render your own element. Spread the `props` it gives you on that element. The snippet type is exported as `ChildSnippet`.
259
316
 
260
317
  ```svelte
261
318
  <InkToolbar>
@@ -277,11 +334,12 @@ The scroll area takes focus. From there:
277
334
 
278
335
  On a focused annotation:
279
336
 
280
- - `Enter` or `Space` selects and activates it. A note or text markup opens its thread; other types are only selected.
337
+ - `Enter` or `Space` selects and activates it. A note or text markup opens its thread; other types are only selected. `Enter` on an editable text box opens its editor instead.
281
338
  - `ArrowUp` and `ArrowDown` move to the previous or next annotation on the page.
282
339
  - `Shift` + arrow moves it by 1 pt, or by 10 pt with `Alt` as well.
283
340
  - `Ctrl` or `Cmd` + `Shift` + arrow resizes an area redaction, text box or shape.
284
341
  - `Delete` or `Backspace` removes it.
342
+ - `Escape` clears the selection.
285
343
 
286
344
  The full table, with the zoom and page keys, is in the [`@inkbar/core` README](https://github.com/inkbar/inkbar/tree/main/packages/core#tools-and-keyboard).
287
345
 
@@ -291,7 +349,7 @@ Components carry state on data attributes, for example `[data-annotation][data-s
291
349
 
292
350
  ## Hooks
293
351
 
294
- `useDocument`, `useAnnotations`, `useTool`, `useSelection`, `useZoom`, `usePage`, `useHistory`, `useEmbedded`, `useCommand`, `useRecords` and `useRecordSelection` read the state of the nearest `InkRoot`. Call them during component initialisation, as you would `getContext`. Each returns an object whose reactive members are getters: read `useZoom().zoom` in your template or an effect and it tracks; destructure it (`const { zoom } = useZoom()`) and you copy the value once. Keep the object and read through it. Tool options, such as the shape kind, last as long as `InkRoot`. The tool style that `useToolStyle` reads and sets (colours, line style, text style) belongs to the document: opening another one starts again from the theme's defaults.
352
+ `useDocument`, `useAnnotations`, `useTool`, `useSelection`, `useZoom`, `usePage`, `useHistory`, `useEmbedded`, `useCommand`, `useForm`, `useSearch`, `useToolStyle`, `useToolOptions`, `useRecords` and `useRecordSelection` read the state of the nearest `InkRoot`. Call them during component initialisation, as you would `getContext`. Each returns an object whose reactive members are getters: read `useZoom().zoom` in your template or an effect and it tracks; destructure it (`const { zoom } = useZoom()`) and you copy the value once. Keep the object and read through it. `useToolOptions('shape')` reads and sets a tool's options, such as the shape kind, which last as long as `InkRoot`. The tool style that `useToolStyle` reads and sets (colours, line style, text style) belongs to the document: opening another one starts again from the theme's defaults.
295
353
 
296
354
  ## Licence
297
355
 
@@ -0,0 +1,40 @@
1
+ <script lang="ts">
2
+ import { ArrowLeft } from '@inkbar/icons'
3
+ import { Toolbar } from 'bits-ui'
4
+
5
+ import { useInkContext } from '../context.js'
6
+ import { useReadable } from '../use-readable.svelte.js'
7
+
8
+ import { asBitsProps } from './child-snippet.js'
9
+ import InkIcon from './InkIcon.svelte'
10
+
11
+ import type { InkPageButtonProps } from './page-button.js'
12
+
13
+ let {
14
+ class: className,
15
+ children,
16
+ child,
17
+ disabled,
18
+ onclick,
19
+ ...rest
20
+ }: InkPageButtonProps = $props()
21
+
22
+ const ctx = useInkContext('InkBack')
23
+ const can = useReadable(() => ctx.navigation?.canGoBack, false)
24
+ </script>
25
+
26
+ <Toolbar.Button
27
+ class={['ink-back', className]}
28
+ data-ink-back=""
29
+ aria-label="Back"
30
+ title="Back"
31
+ disabled={!can.current || !!disabled}
32
+ {...child ? { child } : {}}
33
+ {...asBitsProps(rest)}
34
+ onclick={(e) => {
35
+ onclick?.(e)
36
+ if (!e.defaultPrevented) ctx.navigation?.back()
37
+ }}
38
+ >
39
+ {#if children}{@render children()}{:else}<InkIcon icon={ArrowLeft} />{/if}
40
+ </Toolbar.Button>
@@ -0,0 +1,5 @@
1
+ import type { InkPageButtonProps } from './page-button.js';
2
+ declare const InkBack: import("svelte").Component<InkPageButtonProps, {}, "">;
3
+ type InkBack = ReturnType<typeof InkBack>;
4
+ export default InkBack;
5
+ //# sourceMappingURL=InkBack.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkBack.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkBack.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAoC3D,QAAA,MAAM,OAAO,wDAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
@@ -0,0 +1,40 @@
1
+ <script lang="ts">
2
+ import { ArrowRight } from '@inkbar/icons'
3
+ import { Toolbar } from 'bits-ui'
4
+
5
+ import { useInkContext } from '../context.js'
6
+ import { useReadable } from '../use-readable.svelte.js'
7
+
8
+ import { asBitsProps } from './child-snippet.js'
9
+ import InkIcon from './InkIcon.svelte'
10
+
11
+ import type { InkPageButtonProps } from './page-button.js'
12
+
13
+ let {
14
+ class: className,
15
+ children,
16
+ child,
17
+ disabled,
18
+ onclick,
19
+ ...rest
20
+ }: InkPageButtonProps = $props()
21
+
22
+ const ctx = useInkContext('InkForward')
23
+ const can = useReadable(() => ctx.navigation?.canGoForward, false)
24
+ </script>
25
+
26
+ <Toolbar.Button
27
+ class={['ink-forward', className]}
28
+ data-ink-forward=""
29
+ aria-label="Forward"
30
+ title="Forward"
31
+ disabled={!can.current || !!disabled}
32
+ {...child ? { child } : {}}
33
+ {...asBitsProps(rest)}
34
+ onclick={(e) => {
35
+ onclick?.(e)
36
+ if (!e.defaultPrevented) ctx.navigation?.forward()
37
+ }}
38
+ >
39
+ {#if children}{@render children()}{:else}<InkIcon icon={ArrowRight} />{/if}
40
+ </Toolbar.Button>
@@ -0,0 +1,5 @@
1
+ import type { InkPageButtonProps } from './page-button.js';
2
+ declare const InkForward: import("svelte").Component<InkPageButtonProps, {}, "">;
3
+ type InkForward = ReturnType<typeof InkForward>;
4
+ export default InkForward;
5
+ //# sourceMappingURL=InkForward.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkForward.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkForward.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAoC3D,QAAA,MAAM,UAAU,wDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -0,0 +1,170 @@
1
+ <script module lang="ts">
2
+ import type { OutlineItem } from '@inkbar/core'
3
+ import type { Snippet } from 'svelte'
4
+ import type { HTMLAttributes } from 'svelte/elements'
5
+
6
+ export interface InkOutlineProps extends Omit<
7
+ HTMLAttributes<HTMLDivElement>,
8
+ 'children'
9
+ > {
10
+ /** Shown when the document has no outline. Default: "This document has no outline". */
11
+ emptyText?: string | undefined
12
+ /**
13
+ * Replaces an item's title, given the item and whether it is the current one and whether it
14
+ * is expanded. Keep what it renders non-interactive.
15
+ */
16
+ item?: Snippet<[OutlineItem, { current: boolean; expanded: boolean }]> | undefined
17
+ }
18
+ </script>
19
+
20
+ <script lang="ts">
21
+ /*
22
+ * The open document's outline as a tree: `createOutline`'s markup on core's outline controller,
23
+ * which holds what is expanded, the Tab stop, the keys, the current item and Back's history.
24
+ * Clicking an item, or Enter on it, follows it; its chevron expands and collapses it. It fills
25
+ * its parent's height and scrolls, and keeps the item the reader has reached in view. The
26
+ * `item` snippet replaces an item's title. Inside `InkRoot`; the tree is empty on the server.
27
+ */
28
+ import {
29
+ createOutlineController,
30
+ outlineTreeAttrs,
31
+ type OutlineController,
32
+ } from '@inkbar/core/dom'
33
+ import { ChevronRight } from '@inkbar/icons'
34
+ import { untrack } from 'svelte'
35
+
36
+ import { useInkContext } from '../context.js'
37
+ import { toReadable } from '../to-readable.svelte.js'
38
+
39
+ import InkIcon from './InkIcon.svelte'
40
+
41
+ let {
42
+ emptyText = 'This document has no outline',
43
+ item: renderItem,
44
+ class: className,
45
+ ...rest
46
+ }: InkOutlineProps = $props()
47
+
48
+ const ctx = useInkContext('InkOutline')
49
+ const deps = {
50
+ document: toReadable(() => ctx.document),
51
+ viewport: toReadable(() => ctx.viewport),
52
+ navigation: toReadable(() => ctx.navigation),
53
+ }
54
+
55
+ let root = $state<HTMLDivElement | null>(null)
56
+ let controller = $state.raw<OutlineController | null>(null)
57
+ // Until the controller is built after mount, and on the server: nothing listed.
58
+ let items = $state.raw<readonly OutlineItem[]>([])
59
+ let loading = $state.raw(false)
60
+ let expanded = $state.raw<ReadonlySet<string>>(new Set())
61
+ let current = $state.raw<string | null>(null)
62
+ let focused = $state.raw<string | null>(null)
63
+
64
+ // Built once the element exists, as the other controller-backed components do: it subscribes
65
+ // to the document, so nothing is created while rendering on the server.
66
+ $effect(() => {
67
+ const el = root
68
+ if (!el) return
69
+ return untrack(() => {
70
+ const c = createOutlineController(deps)
71
+ controller = c
72
+ items = c.items.get()
73
+ loading = c.loading.get()
74
+ expanded = c.expanded.get()
75
+ current = c.current.get()
76
+ focused = c.focused.get()
77
+ const stops = [
78
+ c.items.subscribe((v) => (items = v)),
79
+ c.loading.subscribe((v) => (loading = v)),
80
+ c.expanded.subscribe((v) => (expanded = v)),
81
+ c.current.subscribe((v) => (current = v)),
82
+ c.focused.subscribe((v) => (focused = v)),
83
+ c.bindScroll(el),
84
+ ]
85
+ return () => {
86
+ for (const stop of stops) stop()
87
+ c.destroy()
88
+ controller = null
89
+ }
90
+ })
91
+ })
92
+
93
+ /** The item's attributes. Reading the stores here makes a render follow them. */
94
+ function attrs(id: string): Record<string, string | undefined> {
95
+ void [expanded, current, focused]
96
+ return controller?.itemAttrs(id) ?? {}
97
+ }
98
+
99
+ const level = (id: string): number => id.split('.').length - 1
100
+ </script>
101
+
102
+ {#snippet nodes(list: readonly OutlineItem[])}
103
+ {#each list as entry (entry.id)}
104
+ {@const c = controller!}
105
+ {@const open = expanded.has(entry.id)}
106
+ <li
107
+ class="ink-outline-item"
108
+ data-ink-outline-item={entry.id}
109
+ data-bold={entry.bold ? '' : undefined}
110
+ data-italic={entry.italic ? '' : undefined}
111
+ style:--ink-outline-level={level(entry.id)}
112
+ {...attrs(entry.id)}
113
+ >
114
+ <!-- The tree's keys come from the controller, so the row itself is not focusable. -->
115
+ <div
116
+ class="ink-outline-row"
117
+ {...c.rowAttrs(entry.id)}
118
+ onclick={() => c.activate(entry.id)}
119
+ >
120
+ {#if entry.children.length > 0}
121
+ <span
122
+ class="ink-outline-toggle"
123
+ aria-hidden="true"
124
+ onclick={(e) => {
125
+ // Expanding is not following: the row's own click is not reached.
126
+ e.stopPropagation()
127
+ c.toggle(entry.id)
128
+ }}
129
+ >
130
+ <InkIcon icon={ChevronRight} />
131
+ </span>
132
+ {:else}
133
+ <span class="ink-outline-spacer" aria-hidden="true"></span>
134
+ {/if}
135
+ <span class="ink-outline-title" {...c.titleAttrs(entry.id)}>
136
+ {#if renderItem}
137
+ {@render renderItem(entry, { current: current === entry.id, expanded: open })}
138
+ {:else}
139
+ {entry.title}
140
+ {/if}
141
+ </span>
142
+ </div>
143
+ {#if entry.children.length > 0}
144
+ <ul class="ink-outline-group" role="group" hidden={!open}>
145
+ {@render nodes(entry.children)}
146
+ </ul>
147
+ {/if}
148
+ </li>
149
+ {/each}
150
+ {/snippet}
151
+
152
+ <div
153
+ {...rest}
154
+ bind:this={root}
155
+ class={['ink-outline', className]}
156
+ data-ink-outline=""
157
+ aria-busy={loading ? 'true' : undefined}
158
+ >
159
+ <ul
160
+ class="ink-outline-tree"
161
+ {...outlineTreeAttrs()}
162
+ hidden={items.length === 0}
163
+ onkeydown={(e) => controller?.onKeydown(e)}
164
+ >
165
+ {#if controller}{@render nodes(items)}{/if}
166
+ </ul>
167
+ {#if controller && !loading && items.length === 0}
168
+ <p class="ink-outline-empty">{emptyText}</p>
169
+ {/if}
170
+ </div>
@@ -0,0 +1,19 @@
1
+ import type { OutlineItem } from '@inkbar/core';
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ export interface InkOutlineProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
5
+ /** Shown when the document has no outline. Default: "This document has no outline". */
6
+ emptyText?: string | undefined;
7
+ /**
8
+ * Replaces an item's title, given the item and whether it is the current one and whether it
9
+ * is expanded. Keep what it renders non-interactive.
10
+ */
11
+ item?: Snippet<[OutlineItem, {
12
+ current: boolean;
13
+ expanded: boolean;
14
+ }]> | undefined;
15
+ }
16
+ declare const InkOutline: import("svelte").Component<InkOutlineProps, {}, "">;
17
+ type InkOutline = ReturnType<typeof InkOutline>;
18
+ export default InkOutline;
19
+ //# sourceMappingURL=InkOutline.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkOutline.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkOutline.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;CACnF;AA+IH,QAAA,MAAM,UAAU,qDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -7,12 +7,11 @@
7
7
  DocumentSource,
8
8
  FieldsChange,
9
9
  FieldValues,
10
- FormAction,
10
+ ViewerAction,
11
11
  InkDocument,
12
12
  InkError,
13
13
  InkStatus,
14
14
  PdfAssets,
15
- SignatureStore,
16
15
  } from '@inkbar/core'
17
16
  import type {
18
17
  DecorateAnnotation,
@@ -52,8 +51,11 @@
52
51
  * are controlled, after the bound value is written.
53
52
  */
54
53
  onFieldsChange?: ((next: FieldValues, change: FieldsChange) => void) | undefined
55
- /** The form asked to submit, open a link, send mail, print or prompt. Inkbar does none. */
56
- onformaction?: ((action: FormAction) => void) | undefined
54
+ /**
55
+ * The viewer asked the host to submit a form, open a link, send mail, print or prompt.
56
+ * Inkbar does none of these.
57
+ */
58
+ onaction?: ((action: ViewerAction) => void) | undefined
57
59
  /** Tints fillable form fields. Default true. A change applies to the open document in place. */
58
60
  formHighlight?: boolean | undefined
59
61
  tool?: ToolId | undefined
@@ -87,11 +89,18 @@
87
89
  */
88
90
  fonts?: string[] | undefined
89
91
  /**
90
- * Where saved signatures live. Default: memory, gone on reload.
91
- * `createLocalSignatureStore` keeps them in the browser; a host can keep them anywhere.
92
- * A new store takes effect at once, for the menus and the `signature` tool alike.
92
+ * Where the viewer keeps what lasts between visits: saved signatures, each `InkSidebar`'s
93
+ * width and the plugins' settings. Default: memory, gone on reload. `createLocalStorage`
94
+ * keeps them in the browser; a host can keep them anywhere. Read once, when the root is
95
+ * created.
93
96
  */
94
- signatures?: SignatureStore | undefined
97
+ storage?: InkStorage | undefined
98
+ /**
99
+ * The narrowest the document may get beside the sidebars, in CSS px, before a rail
100
+ * sidebar's panel floats over the pages instead. Default 480 (`MIN_DOCUMENT_WIDTH`). Every
101
+ * `InkSidebar` inside takes it unless it has its own. Read once, when the root is created.
102
+ */
103
+ minDocumentWidth?: number | undefined
95
104
  /** The handwriting fonts a typed signature offers; the host loads them. */
96
105
  signatureFonts?: string[] | undefined
97
106
  page?: number | undefined
@@ -121,9 +130,10 @@
121
130
 
122
131
  <script lang="ts">
123
132
  import {
124
- createMemorySignatureStore,
133
+ createMemoryStorage,
125
134
  createSignatureLibrary,
126
135
  createSnapshotHistory,
136
+ createStorageSignatureStore,
127
137
  InkError as InkErrorClass,
128
138
  openDocument,
129
139
  readonly,
@@ -139,6 +149,7 @@
139
149
  FONT_FAMILIES,
140
150
  handleFindKey,
141
151
  keepHistoryFocus,
152
+ MIN_DOCUMENT_WIDTH,
142
153
  pageSelectionText,
143
154
  SIGNATURE_FONTS,
144
155
  trackToolStyle,
@@ -153,8 +164,9 @@
153
164
  import { registeredToolIds } from '../hooks/useRegisteredTool.svelte.js'
154
165
  import { useReadable } from '../use-readable.svelte.js'
155
166
 
156
- import type { PluginHistory } from '@inkbar/core'
167
+ import type { InkStorage, PluginHistory } from '@inkbar/core'
157
168
  import type {
169
+ Navigation,
158
170
  PluginHost,
159
171
  SearchController,
160
172
  ToolController,
@@ -171,7 +183,7 @@
171
183
  onChange,
172
184
  fields = $bindable(),
173
185
  onFieldsChange,
174
- onformaction,
186
+ onaction,
175
187
  formHighlight,
176
188
  tool = $bindable(),
177
189
  onToolChange,
@@ -179,7 +191,8 @@
179
191
  plugins,
180
192
  decorateAnnotation,
181
193
  fonts,
182
- signatures: signatureStore,
194
+ storage: storageProp,
195
+ minDocumentWidth: minDocumentWidthProp,
183
196
  signatureFonts,
184
197
  page = $bindable(),
185
198
  onPageChange,
@@ -197,9 +210,12 @@
197
210
 
198
211
  type TestHookElement = HTMLElement & { __inkDocument?: InkDocument | undefined }
199
212
 
200
- const signatures = $derived(
201
- createSignatureLibrary(signatureStore ?? createMemorySignatureStore())
202
- )
213
+ // Read once, like `plugins`: the sidebars and the plugins load from it as they are created.
214
+ const storage = untrack(() => storageProp ?? createMemoryStorage())
215
+ const storageSignatures = createStorageSignatureStore(storage)
216
+ // Read once, like `storage`: each sidebar reads it as it is created.
217
+ const minDocumentWidth = untrack(() => minDocumentWidthProp ?? MIN_DOCUMENT_WIDTH)
218
+ const signatures = createSignatureLibrary(storageSignatures)
203
219
  $effect(() => {
204
220
  void signatures.refresh()
205
221
  })
@@ -233,6 +249,7 @@
233
249
  let activatedNow: string | null = null
234
250
  let viewport = $state.raw<Viewport | null>(null)
235
251
  let tools = $state.raw<ToolController | null>(null)
252
+ let navigation = $state.raw<Navigation | null>(null)
236
253
 
237
254
  const documentStatus = useReadable<InkStatus>(() => document?.status, IDLE)
238
255
  const status = $derived(override ?? documentStatus.current)
@@ -428,7 +445,16 @@
428
445
  zoom = z
429
446
  onZoomChange?.(z)
430
447
  }
448
+ /**
449
+ * Whether the host has given `page` a value of its own, as React's `page` prop. Until then the
450
+ * page written back below is only a report, so the next document opens at its first page
451
+ * instead of the last one's. Not reactive: it flips only with a change to `page`, which
452
+ * `pageModel`'s readers already track.
453
+ */
454
+ let hostPage = untrack(() => page) !== undefined
455
+ let reportedPage: number | undefined
431
456
  function reportPage(p: number): void {
457
+ reportedPage = p
432
458
  page = p
433
459
  onPageChange?.(p)
434
460
  }
@@ -529,6 +555,7 @@
529
555
  decorate: () => decorateAnnotation,
530
556
  viewport: () => viewport,
531
557
  search: viewerSearchOf(controller),
558
+ storage,
532
559
  })
533
560
  )
534
561
  search = controller
@@ -628,6 +655,12 @@
628
655
  get viewport() {
629
656
  return viewport
630
657
  },
658
+ get navigation() {
659
+ return navigation
660
+ },
661
+ setNavigation(n) {
662
+ navigation = n
663
+ },
631
664
  get tools() {
632
665
  return tools
633
666
  },
@@ -651,6 +684,8 @@
651
684
  return fonts ?? FONT_FAMILIES
652
685
  },
653
686
  toolOptions,
687
+ storage,
688
+ minDocumentWidth,
654
689
  get signatures() {
655
690
  return signatures
656
691
  },
@@ -664,7 +699,8 @@
664
699
  return zoom
665
700
  },
666
701
  get pageModel() {
667
- return page
702
+ if (page !== undefined && page !== reportedPage) hostPage = true
703
+ return hostPage ? page : undefined
668
704
  },
669
705
  reportZoom,
670
706
  reportPage,
@@ -683,7 +719,7 @@
683
719
  get formHighlight() {
684
720
  return formHighlight
685
721
  },
686
- reportFormAction: (a) => onformaction?.(a),
722
+ reportAction: (a) => onaction?.(a),
687
723
  reportError: (e) => onError?.(e),
688
724
  }
689
725
  setInkContext(context, () => activatedNow)
@@ -1,5 +1,5 @@
1
1
  import type { ChildSnippet } from './child-snippet.js';
2
- import type { Annotation, AnnotationChange, AnnotationDefaults, DocumentSource, FieldsChange, FieldValues, FormAction, InkDocument, InkError, InkStatus, PdfAssets, SignatureStore } from '@inkbar/core';
2
+ import type { Annotation, AnnotationChange, AnnotationDefaults, DocumentSource, FieldsChange, FieldValues, ViewerAction, InkDocument, InkError, InkStatus, PdfAssets } from '@inkbar/core';
3
3
  import type { DecorateAnnotation, InkPlugin, Tool, ToolId, ZoomValue } from '@inkbar/core/dom';
4
4
  import type { Snippet } from 'svelte';
5
5
  import type { HTMLAttributes } from 'svelte/elements';
@@ -28,8 +28,11 @@ export interface InkRootProps extends Omit<HTMLAttributes<HTMLDivElement>, 'chil
28
28
  * are controlled, after the bound value is written.
29
29
  */
30
30
  onFieldsChange?: ((next: FieldValues, change: FieldsChange) => void) | undefined;
31
- /** The form asked to submit, open a link, send mail, print or prompt. Inkbar does none. */
32
- onformaction?: ((action: FormAction) => void) | undefined;
31
+ /**
32
+ * The viewer asked the host to submit a form, open a link, send mail, print or prompt.
33
+ * Inkbar does none of these.
34
+ */
35
+ onaction?: ((action: ViewerAction) => void) | undefined;
33
36
  /** Tints fillable form fields. Default true. A change applies to the open document in place. */
34
37
  formHighlight?: boolean | undefined;
35
38
  tool?: ToolId | undefined;
@@ -63,11 +66,18 @@ export interface InkRootProps extends Omit<HTMLAttributes<HTMLDivElement>, 'chil
63
66
  */
64
67
  fonts?: string[] | undefined;
65
68
  /**
66
- * Where saved signatures live. Default: memory, gone on reload.
67
- * `createLocalSignatureStore` keeps them in the browser; a host can keep them anywhere.
68
- * A new store takes effect at once, for the menus and the `signature` tool alike.
69
+ * Where the viewer keeps what lasts between visits: saved signatures, each `InkSidebar`'s
70
+ * width and the plugins' settings. Default: memory, gone on reload. `createLocalStorage`
71
+ * keeps them in the browser; a host can keep them anywhere. Read once, when the root is
72
+ * created.
73
+ */
74
+ storage?: InkStorage | undefined;
75
+ /**
76
+ * The narrowest the document may get beside the sidebars, in CSS px, before a rail
77
+ * sidebar's panel floats over the pages instead. Default 480 (`MIN_DOCUMENT_WIDTH`). Every
78
+ * `InkSidebar` inside takes it unless it has its own. Read once, when the root is created.
69
79
  */
70
- signatures?: SignatureStore | undefined;
80
+ minDocumentWidth?: number | undefined;
71
81
  /** The handwriting fonts a typed signature offers; the host loads them. */
72
82
  signatureFonts?: string[] | undefined;
73
83
  page?: number | undefined;
@@ -97,6 +107,7 @@ export interface InkRootProps extends Omit<HTMLAttributes<HTMLDivElement>, 'chil
97
107
  child?: ChildSnippet;
98
108
  }
99
109
  import { type InkHistory } from '../context.js';
110
+ import type { InkStorage } from '@inkbar/core';
100
111
  declare const InkRoot: import("svelte").Component<InkRootProps, {
101
112
  history: InkHistory;
102
113
  getDocument: () => InkDocument | null;
@@ -1 +1 @@
1
- {"version":3,"file":"InkRoot.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkRoot.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,WAAW,EACX,UAAU,EACV,WAAW,EACX,QAAQ,EACR,SAAS,EACT,SAAS,EACT,cAAc,EACf,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,IAAI,EACJ,MAAM,EACN,SAAS,EACV,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,GAAG,UAAU,GAAG,SAAS,CACpC;IACC,GAAG,EAAE,cAAc,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,SAAS,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,wFAAwF;IACxF,QAAQ,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAA;IACzC;;;;OAIG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,GAAG,SAAS,CAAA;IACtC,mBAAmB,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAChE,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC3D;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAChF,2FAA2F;IAC3F,YAAY,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACzD,gGAAgG;IAChG,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACnC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACnD;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,SAAS,CAAA;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,SAAS,CAAA;IACjC;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAA;IACnD;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,GAAG,SAAS,CAAA;IACvC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IACrC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACnD,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;IAC5B,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACtD,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAClD;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACjD,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC/C,gDAAgD;IAChD,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC,CAAA;IACzE;;;OAGG;IACH,KAAK,CAAC,EAAE,YAAY,CAAA;CACrB;AAgCH,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,eAAe,CAAA;AA4kB/E,QAAA,MAAM,OAAO;;uBAhCc,WAAW,GAAG,IAAI;qBAGpB,SAAS;+DA6BmB,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"InkRoot.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkRoot.svelte.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  <script module lang="ts">
2
+ import type { InkStorage } from '@inkbar/core'
2
3
  import type { SidebarLayout, SidebarOpen, SidebarSide } from '@inkbar/core/dom'
3
4
  import type { Snippet } from 'svelte'
4
5
  import type { HTMLAttributes } from 'svelte/elements'
@@ -18,6 +19,40 @@
18
19
  * Left out, the first panel starts open.
19
20
  */
20
21
  open?: SidebarOpen | undefined
22
+ /**
23
+ * Where the width is saved. Default: InkRoot's `storage` inside InkRoot, else none, and the
24
+ * width lasts until unmount. Read once, when the sidebar is created.
25
+ */
26
+ storage?: InkStorage | undefined
27
+ /**
28
+ * The middle of the saved key, `sidebar.<name>.width`. Default: the side. Give two sidebars
29
+ * on one side different names. Read once, when the sidebar is created.
30
+ */
31
+ name?: string | undefined
32
+ /** In CSS px. Default 320; Enter or a double-click on the handle goes back to it. */
33
+ defaultWidth?: number | undefined
34
+ /** Default 240. */
35
+ minWidth?: number | undefined
36
+ /** Default 480. */
37
+ maxWidth?: number | undefined
38
+ /**
39
+ * Bindable, in CSS px. Bind it to a number to control the width: the handle then only
40
+ * updates the binding, and storage is neither read nor written. Bound to a value that
41
+ * starts undefined, it receives the width but the sidebar stays uncontrolled.
42
+ */
43
+ width?: number | undefined
44
+ /**
45
+ * The narrowest the document may get beside the sidebars sharing this one's parent, in CSS
46
+ * px, before a rail's open panel floats over the pages. Tabs and stack narrow toward
47
+ * `minWidth` instead. Default: InkRoot's `minDocumentWidth` inside InkRoot, else 480. Read
48
+ * once, when the sidebar is created.
49
+ */
50
+ minDocumentWidth?: number | undefined
51
+ /**
52
+ * The resize handle's accessible name. Default `Resize left sidebar` or `Resize right
53
+ * sidebar`. Read once, when the sidebar is created.
54
+ */
55
+ handleLabel?: string | undefined
21
56
  /** The `InkPanel`s. */
22
57
  children?: Snippet | undefined
23
58
  }
@@ -37,10 +72,21 @@
37
72
  * `InkRoot`. The server renders the root, the panels (the open one shown) and the stack
38
73
  * headers; rail and tab buttons follow once mounted, as the panels register after the root
39
74
  * has rendered.
75
+ *
76
+ * The handle on the inner edge resizes the sidebar. Its width is saved in `storage`, under
77
+ * `sidebar.<name>.width`; inside `InkRoot` the root's storage is the default. `bind:width`
78
+ * to a number makes the width the host's: drags and keys then only update the binding, and
79
+ * storage is not read or written. The server renders the handle too.
80
+ *
81
+ * Once mounted, a rail's open panel floats over the pages while the document beside it would
82
+ * be narrower than `minDocumentWidth` (InkRoot's inside it), and a tap on the pages or Escape
83
+ * closes it, through `bind:open` too. The server renders it beside the document, open as
84
+ * usual; once mounted, an unbound sidebar with no room closes its panel.
40
85
  */
41
86
  import { createSidebarController } from '@inkbar/core/dom'
42
87
  import { untrack } from 'svelte'
43
88
 
89
+ import { useOptionalInkContext } from '../context.js'
44
90
  import { useReadable } from '../use-readable.svelte.js'
45
91
 
46
92
  import { setSidebarContext, type SidebarPanelEntry } from './sidebar-context.js'
@@ -51,6 +97,14 @@
51
97
  layout = 'rail',
52
98
  visible = true,
53
99
  open = $bindable(),
100
+ storage,
101
+ name,
102
+ defaultWidth,
103
+ minWidth,
104
+ maxWidth,
105
+ width = $bindable(),
106
+ minDocumentWidth,
107
+ handleLabel,
54
108
  class: className,
55
109
  children,
56
110
  ...rest
@@ -62,6 +116,32 @@
62
116
  let entries = $state.raw<SidebarPanelEntry[]>([])
63
117
  const infos = () => entries.map((e) => e.info())
64
118
 
119
+ // Read once: the controller loads the saved width as it is created.
120
+ const ink = useOptionalInkContext()
121
+ const minDocument = untrack(() => minDocumentWidth ?? ink?.minDocumentWidth)
122
+
123
+ /*
124
+ * `width` is the host's only while it holds a number the sidebar did not write itself. The
125
+ * sidebar writes every change back to the binding; on an unbound prop that sets the local
126
+ * value, which would otherwise read as a controlling number and stop the saving. `written` is
127
+ * the last width we wrote. `controlled` turns on once the host gives a number that is not
128
+ * ours, or starts with one, and then stays on, as in core.
129
+ */
130
+ let written: number | undefined
131
+ let controlled = untrack(() => width !== undefined)
132
+ /** The width props the host gave; an undefined one keeps the controller's. */
133
+ function widthOptions(): Partial<
134
+ Record<'defaultWidth' | 'minWidth' | 'maxWidth' | 'width', number>
135
+ > {
136
+ if (width !== undefined && width !== written) controlled = true
137
+ return {
138
+ ...(defaultWidth !== undefined && { defaultWidth }),
139
+ ...(minWidth !== undefined && { minWidth }),
140
+ ...(maxWidth !== undefined && { maxWidth }),
141
+ ...(controlled && width !== undefined && { width }),
142
+ }
143
+ }
144
+
65
145
  // Pending until mounted: the panels register one by one as they initialise, and an open id
66
146
  // not registered yet is not a removed panel.
67
147
  const controller = untrack(() =>
@@ -72,6 +152,15 @@
72
152
  panels: [],
73
153
  ...(open !== undefined && { open }),
74
154
  pending: true,
155
+ ...((storage ?? ink?.storage) && { storage: (storage ?? ink?.storage)! }),
156
+ ...(name !== undefined && { name }),
157
+ ...(minDocument !== undefined && { minDocumentWidth: minDocument }),
158
+ ...(handleLabel !== undefined && { handleLabel }),
159
+ ...widthOptions(),
160
+ onWidthChange: (value) => {
161
+ written = value
162
+ width = value
163
+ },
75
164
  onOpenChange: (value) => {
76
165
  open = value
77
166
  },
@@ -86,13 +175,14 @@
86
175
 
87
176
  // Before the DOM updates, so the panels render the attributes these give.
88
177
  $effect.pre(() => {
89
- const next = { layout, side, visible, open }
178
+ const next = { layout, side, visible, open, widths: widthOptions() }
90
179
  untrack(() =>
91
180
  controller.update({
92
181
  layout: next.layout,
93
182
  side: next.side,
94
183
  visible: next.visible,
95
184
  ...(next.open !== undefined && { open: next.open }),
185
+ ...next.widths,
96
186
  })
97
187
  )
98
188
  })
@@ -134,11 +224,20 @@
134
224
 
135
225
  setSidebarContext({ controller, state: current, register, arrange })
136
226
 
227
+ // The panels register after the root rendered, so the server's and the first render's handle
228
+ // is shown (as the root is: `data-state` is open while pending); the real `hidden` follows
229
+ // once mounted.
230
+ let mounted = $state(false)
137
231
  const view = $derived.by(() => {
138
232
  const s = current.current
233
+ const handleAttrs = controller.handleAttrs()
234
+ if (!mounted) delete handleAttrs.hidden
139
235
  return {
140
236
  layout: s.layout,
141
237
  root: controller.rootAttrs(),
238
+ style: controller.rootStyle(),
239
+ panels: controller.panelsAttrs(),
240
+ handle: handleAttrs,
142
241
  tablist: controller.tablistAttrs(),
143
242
  triggers: s.panels.map((panel) => ({
144
243
  panel,
@@ -148,6 +247,7 @@
148
247
  })
149
248
 
150
249
  let root = $state<HTMLDivElement | null>(null)
250
+ let handle = $state<HTMLDivElement | null>(null)
151
251
  // The controller handles the triggers' clicks and keys, stack headers included. The panels
152
252
  // have registered by now.
153
253
  $effect(() => {
@@ -157,9 +257,31 @@
157
257
  untrack(() => controller.update({ pending: false }))
158
258
  return unbind
159
259
  })
260
+ // The controller handles the handle's drags, keys and double-click.
261
+ $effect(() => {
262
+ const el = handle
263
+ if (!el || !root) return
264
+ const host = root
265
+ const unbind = untrack(() => controller.bindHandle(el))
266
+ untrack(() => {
267
+ mounted = true
268
+ // Hydration keeps the server's markup: a width the client's storage gave applies here.
269
+ for (const [prop, value] of Object.entries(controller.rootStyle()))
270
+ host.style.setProperty(prop, value)
271
+ for (const [attr, value] of Object.entries(controller.handleAttrs()))
272
+ if (attr.startsWith('aria-value')) el.setAttribute(attr, value)
273
+ })
274
+ return unbind
275
+ })
160
276
  </script>
161
277
 
162
- <div {...rest} bind:this={root} class={['ink-sidebar', className]} {...view.root}>
278
+ <div
279
+ {...rest}
280
+ bind:this={root}
281
+ class={['ink-sidebar', className]}
282
+ {...view.root}
283
+ style:--ink-sidebar-width={view.style['--ink-sidebar-width']}
284
+ >
163
285
  {#if view.layout !== 'stack'}
164
286
  <div
165
287
  class={view.layout === 'rail' ? 'ink-sidebar-rail' : 'ink-sidebar-tabs'}
@@ -173,7 +295,13 @@
173
295
  </div>
174
296
  {/if}
175
297
  <!-- One element in every layout, so the panels are never remounted. -->
176
- <div class={{ 'ink-sidebar-panels': view.layout !== 'stack' }}>
298
+ <!-- The stack has no panels element: its id and class apply in rail and tabs only. -->
299
+ <div
300
+ class={{ 'ink-sidebar-panels': view.layout !== 'stack' }}
301
+ {...view.layout !== 'stack' ? view.panels : {}}
302
+ >
177
303
  {@render children?.()}
178
304
  </div>
305
+ <!-- The last child, on the inner edge. -->
306
+ <div bind:this={handle} class="ink-sidebar-handle" {...view.handle}></div>
179
307
  </div>
@@ -1,3 +1,4 @@
1
+ import type { InkStorage } from '@inkbar/core';
1
2
  import type { SidebarLayout, SidebarOpen, SidebarSide } from '@inkbar/core/dom';
2
3
  import type { Snippet } from 'svelte';
3
4
  import type { HTMLAttributes } from 'svelte/elements';
@@ -13,10 +14,44 @@ export interface InkSidebarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'c
13
14
  * Left out, the first panel starts open.
14
15
  */
15
16
  open?: SidebarOpen | undefined;
17
+ /**
18
+ * Where the width is saved. Default: InkRoot's `storage` inside InkRoot, else none, and the
19
+ * width lasts until unmount. Read once, when the sidebar is created.
20
+ */
21
+ storage?: InkStorage | undefined;
22
+ /**
23
+ * The middle of the saved key, `sidebar.<name>.width`. Default: the side. Give two sidebars
24
+ * on one side different names. Read once, when the sidebar is created.
25
+ */
26
+ name?: string | undefined;
27
+ /** In CSS px. Default 320; Enter or a double-click on the handle goes back to it. */
28
+ defaultWidth?: number | undefined;
29
+ /** Default 240. */
30
+ minWidth?: number | undefined;
31
+ /** Default 480. */
32
+ maxWidth?: number | undefined;
33
+ /**
34
+ * Bindable, in CSS px. Bind it to a number to control the width: the handle then only
35
+ * updates the binding, and storage is neither read nor written. Bound to a value that
36
+ * starts undefined, it receives the width but the sidebar stays uncontrolled.
37
+ */
38
+ width?: number | undefined;
39
+ /**
40
+ * The narrowest the document may get beside the sidebars sharing this one's parent, in CSS
41
+ * px, before a rail's open panel floats over the pages. Tabs and stack narrow toward
42
+ * `minWidth` instead. Default: InkRoot's `minDocumentWidth` inside InkRoot, else 480. Read
43
+ * once, when the sidebar is created.
44
+ */
45
+ minDocumentWidth?: number | undefined;
46
+ /**
47
+ * The resize handle's accessible name. Default `Resize left sidebar` or `Resize right
48
+ * sidebar`. Read once, when the sidebar is created.
49
+ */
50
+ handleLabel?: string | undefined;
16
51
  /** The `InkPanel`s. */
17
52
  children?: Snippet | undefined;
18
53
  }
19
- declare const InkSidebar: import("svelte").Component<InkSidebarProps, {}, "open">;
54
+ declare const InkSidebar: import("svelte").Component<InkSidebarProps, {}, "width" | "open">;
20
55
  type InkSidebar = ReturnType<typeof InkSidebar>;
21
56
  export default InkSidebar;
22
57
  //# sourceMappingURL=InkSidebar.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InkSidebar.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkSidebar.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;IAC9B,iDAAiD;IACjD,MAAM,CAAC,EAAE,aAAa,GAAG,SAAS,CAAA;IAClC,wHAAwH;IACxH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;IAC9B,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC/B;AAwKH,QAAA,MAAM,UAAU,yDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"InkSidebar.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkSidebar.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;IAC9B,iDAAiD;IACjD,MAAM,CAAC,EAAE,aAAa,GAAG,SAAS,CAAA;IAClC,wHAAwH;IACxH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;IAChC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC/B;AA6PH,QAAA,MAAM,UAAU,mEAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -126,6 +126,7 @@
126
126
  builtWith = null
127
127
  ctx.setOpenedToolIds(null)
128
128
  ctx.setViewport(null, null)
129
+ ctx.setNavigation(null)
129
130
  if (pages.length > 0) pages = []
130
131
  // Their fields and the document they came from are gone.
131
132
  signRequest = null
@@ -169,7 +170,6 @@
169
170
  toolHistory: { batch: (fn) => ctx.history.batch(fn) },
170
171
  toolOptions: ctx.toolOptions,
171
172
  fonts: [...ctx.fonts],
172
- // Read through, so a new `signatures` store reaches the tool as well as the menus.
173
173
  signatureLibrary: () => ctx.signatures,
174
174
  customAnnotations: custom,
175
175
  ...(ctx.formHighlight === undefined ? {} : { formHighlight: ctx.formHighlight }),
@@ -177,7 +177,7 @@
177
177
  onSignField: (req) => {
178
178
  signRequest = signRequest?.widget === req.widget ? null : req
179
179
  },
180
- onFormAction: (a) => ctx.reportFormAction(a),
180
+ onAction: (a) => ctx.reportAction(a),
181
181
  onFormAlert: (message) => {
182
182
  alert = { message, shown: (alert?.shown ?? 0) + 1 }
183
183
  },
@@ -235,6 +235,8 @@
235
235
  pages = pages.map((p) => (p.page === page ? { ...p, error: err } : p))
236
236
  },
237
237
  })
238
+ // The engine exists from here; its navigation lasts for its life, across rebuilds.
239
+ ctx.setNavigation(engine.navigation)
238
240
  }
239
241
 
240
242
  // The plugins' `root`. Before the build below, so it is set when the engine mounts.
@@ -1 +1 @@
1
- {"version":3,"file":"InkViewport.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkViewport.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kFAAkF;IAClF,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,KAAK,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC,mBAAmB,CAAC,CAAC,GAAG,SAAS,CAAA;IACvD,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,KAAK,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;CACrE;AA0XH,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"InkViewport.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkViewport.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,cAAc,CAAC,cAAc,CAAC,EAC9B,UAAU,CACX;IACC,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kFAAkF;IAClF,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,KAAK,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC,mBAAmB,CAAC,CAAC,GAAG,SAAS,CAAA;IACvD,wFAAwF;IACxF,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,KAAK,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GAAG,SAAS,CAAA;CACrE;AA4XH,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
package/dist/context.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { Annotation, FormAction, InkDocument, InkError, InkStatus, PdfAssets, PluginHistory, SignatureLibrary, Writable } from '@inkbar/core';
2
- import type { DecorateAnnotation, PluginHost, SearchController, Tool, ToolController, ToolId, ToolOptions, ToolStyle, Viewport, ZoomValue } from '@inkbar/core/dom';
1
+ import type { Annotation, ViewerAction, InkDocument, InkError, InkStatus, InkStorage, PdfAssets, PluginHistory, SignatureLibrary, Writable } from '@inkbar/core';
2
+ import type { DecorateAnnotation, Navigation, PluginHost, SearchController, Tool, ToolController, ToolId, ToolOptions, ToolStyle, Viewport, ZoomValue } from '@inkbar/core/dom';
3
3
  export type { InkStatus };
4
4
  /**
5
5
  * Undo and redo for the current document, whichever mode its annotations are in. `track` and
@@ -47,6 +47,12 @@ export interface InkContext {
47
47
  /** Set by InkViewport once it has built its viewport and tool controller. */
48
48
  readonly viewport: Viewport | null;
49
49
  readonly tools: ToolController | null;
50
+ /**
51
+ * The engine's navigation (jumps with Back and Forward), set by InkViewport when it builds
52
+ * the engine and cleared when it is torn down; `null` before that, and on the server.
53
+ */
54
+ readonly navigation: Navigation | null;
55
+ setNavigation(navigation: Navigation | null): void;
50
56
  /** Desired tool; InkViewport applies it to the controller. */
51
57
  readonly tool: ToolId;
52
58
  setTool(id: ToolId): void;
@@ -64,7 +70,17 @@ export interface InkContext {
64
70
  readonly fonts: readonly string[];
65
71
  /** The tools' options for InkRoot's life, so they persist across documents. */
66
72
  readonly toolOptions: ToolOptions;
67
- /** The saved signatures, from InkRoot's `signatures` store (memory by default). */
73
+ /**
74
+ * What InkRoot's `storage` holds between visits (memory by default): the signatures, each
75
+ * `InkSidebar`'s width and the plugins' settings. Read once, when the root is created.
76
+ */
77
+ readonly storage: InkStorage;
78
+ /**
79
+ * InkRoot's `minDocumentWidth` (`MIN_DOCUMENT_WIDTH` by default), fixed for the root's life.
80
+ * Each `InkSidebar` without its own takes it.
81
+ */
82
+ readonly minDocumentWidth: number;
83
+ /** The saved signatures: kept in InkRoot's `storage` under `signatures`. */
68
84
  readonly signatures: SignatureLibrary;
69
85
  /** The fonts a typed signature offers: InkRoot's `signatureFonts`, else `SIGNATURE_FONTS`. */
70
86
  readonly signatureFonts: readonly string[];
@@ -88,8 +104,8 @@ export interface InkContext {
88
104
  setViewport(viewport: Viewport | null, tools: ToolController | null): void;
89
105
  /** InkRoot's `formHighlight`; InkViewport reads it when it builds the viewer. */
90
106
  readonly formHighlight: boolean | undefined;
91
- /** Calls InkRoot's `onformaction`. */
92
- reportFormAction(action: FormAction): void;
107
+ /** Calls InkRoot's `onaction`. */
108
+ reportAction(action: ViewerAction): void;
93
109
  /** Calls InkRoot's `onError`, for failures after the document opened (a refused signing). */
94
110
  reportError(error: InkError): void;
95
111
  }
@@ -102,4 +118,9 @@ export declare function peekActivated(ctx: InkContext): string | null;
102
118
  * rendered inside `InkRoot`, including when called outside any component at all.
103
119
  */
104
120
  export declare function useInkContext(consumer: string): InkContext;
121
+ /**
122
+ * The context when there is one, else undefined: for components that also work outside
123
+ * `InkRoot`. Internal to the package.
124
+ */
125
+ export declare function useOptionalInkContext(): InkContext | undefined;
105
126
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/lib/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/lib/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,SAAS,EACT,UAAU,EACV,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACT,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EACV,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,IAAI,EACJ,cAAc,EACd,MAAM,EACN,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACV,MAAM,kBAAkB,CAAA;AAEzB,YAAY,EAAE,SAAS,EAAE,CAAA;AAEzB;;;GAGG;AACH,MAAM,WAAW,UAAW,SAAQ,aAAa;IAC/C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,IAAI,IAAI,IAAI,CAAA;IACZ,IAAI,IAAI,IAAI,CAAA;IACZ,KAAK,IAAI,IAAI,CAAA;IACb;;;;;OAKG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAA;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;IACrC,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAA;IAC3C,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IACrC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAA;IACtC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACxC,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IACjD,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAA;IACrC;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAA;IACtC,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAAA;IAClD,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,GAAG,SAAS,CAAA;IACtC;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;IAChD,gBAAgB,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;IACrD,+FAA+F;IAC/F,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,SAAS,CAAA;IAC3D,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;IAC5B;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAA;IACrC,8FAA8F;IAC9F,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1C,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;IACpC,yFAAyF;IACzF,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAAA;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,UAAU,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IAC9B,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,gGAAgG;IAChG,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC;;;;OAIG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IACrC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;IACnC,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAAA;IAC1E,iFAAiF;IACjF,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3C,kCAAkC;IAClC,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;IACxC,6FAA6F;IAC7F,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAA;CACnC;AAWD,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,CAGvF;AAED,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAG5D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAY1D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,UAAU,GAAG,SAAS,CAM9D"}
package/dist/context.js CHANGED
@@ -32,3 +32,15 @@ export function useInkContext(consumer) {
32
32
  throw new Error(`[inkbar] ${consumer} must be called in a component inside <InkRoot>.`);
33
33
  return ctx;
34
34
  }
35
+ /**
36
+ * The context when there is one, else undefined: for components that also work outside
37
+ * `InkRoot`. Internal to the package.
38
+ */
39
+ export function useOptionalInkContext() {
40
+ try {
41
+ return getContext(KEY);
42
+ }
43
+ catch {
44
+ return undefined;
45
+ }
46
+ }
package/dist/index.d.ts CHANGED
@@ -79,6 +79,10 @@ export type { InkPageCountProps } from './components/InkPageCount.svelte';
79
79
  export { default as InkPrevPage } from './components/InkPrevPage.svelte';
80
80
  export { default as InkNextPage } from './components/InkNextPage.svelte';
81
81
  export type { InkPageButtonProps } from './components/page-button.js';
82
+ export { default as InkBack } from './components/InkBack.svelte';
83
+ export { default as InkForward } from './components/InkForward.svelte';
84
+ export { default as InkOutline } from './components/InkOutline.svelte';
85
+ export type { InkOutlineProps } from './components/InkOutline.svelte';
82
86
  export type { ChildSnippet } from './components/child-snippet.js';
83
87
  export { default as InkThreadPopover } from './components/InkThreadPopover.svelte';
84
88
  export type { InkThreadPopoverProps } from './components/InkThreadPopover.svelte';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -45,6 +45,9 @@ export { default as InkPageInput } from './components/InkPageInput.svelte';
45
45
  export { default as InkPageCount } from './components/InkPageCount.svelte';
46
46
  export { default as InkPrevPage } from './components/InkPrevPage.svelte';
47
47
  export { default as InkNextPage } from './components/InkNextPage.svelte';
48
+ export { default as InkBack } from './components/InkBack.svelte';
49
+ export { default as InkForward } from './components/InkForward.svelte';
50
+ export { default as InkOutline } from './components/InkOutline.svelte';
48
51
  export { default as InkThreadPopover } from './components/InkThreadPopover.svelte';
49
52
  export { default as InkSidebar } from './components/InkSidebar.svelte';
50
53
  export { default as InkPanel } from './components/InkPanel.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkbar/svelte",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "Svelte 5 components and hooks for Inkbar, the browser PDF viewer and editor.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://inkbar.dev",
@@ -26,19 +26,19 @@
26
26
  "./package.json": "./package.json"
27
27
  },
28
28
  "dependencies": {
29
- "@inkbar/icons": "^0.11.0",
29
+ "@inkbar/icons": "^0.13.0",
30
30
  "@internationalized/date": "^3.12.4",
31
31
  "bits-ui": "^2.19.5",
32
32
  "esm-env": "^1.2.0"
33
33
  },
34
34
  "peerDependencies": {
35
- "@inkbar/core": "^0.11.0",
35
+ "@inkbar/core": "^0.13.0",
36
36
  "svelte": "^5.46.4"
37
37
  },
38
38
  "devDependencies": {
39
- "@inkbar/core": "0.11.0",
39
+ "@inkbar/core": "0.13.0",
40
40
  "@inkbar/fixtures": "0.0.0",
41
- "@inkbar/theme": "0.11.0",
41
+ "@inkbar/theme": "0.13.0",
42
42
  "@sveltejs/package": "^3.0.0",
43
43
  "@sveltejs/vite-plugin-svelte": "^7.3.1",
44
44
  "@vitest/browser-playwright": "^5.0.4",