@inkbar/svelte 0.11.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/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)). `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. `onformaction` still works until 0.13.0. `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. A `signatures` store of your own still works and wins over `storage` until 0.13.0, which removes it. `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>
@@ -213,7 +242,13 @@ The bar handles Escape itself and stops it there, so an `onkeydown` you pass to
213
242
 
214
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. 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), and never past half of the sidebar's container. 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` and `name` 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
+ ```
217
252
 
218
253
  ## Thumbnails
219
254
 
@@ -231,6 +266,20 @@ Panels take their place in the order they appear in the markup, including one ad
231
266
 
232
267
  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
268
 
269
+ ## Outline and Back
270
+
271
+ `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:
272
+
273
+ ```svelte
274
+ <InkPanel id="outline" label="Outline" icon={List}>
275
+ <InkOutline emptyText="No outline" />
276
+ </InkPanel>
277
+ ```
278
+
279
+ `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.
280
+
281
+ `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`.
282
+
234
283
  ## Record lists
235
284
 
236
285
  `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 +292,7 @@ An item's height is worked out from its page alone, so position what you add abs
243
292
  </InkPanel>
244
293
  ```
245
294
 
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.
295
+ 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
296
 
248
297
  `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
298
 
@@ -251,11 +300,11 @@ To build your own, `useRecords<T>(name)` returns the live `records` and the `han
251
300
 
252
301
  ## Custom rendering
253
302
 
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.
303
+ 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
304
 
256
305
  `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
306
 
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`.
307
+ `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
308
 
260
309
  ```svelte
261
310
  <InkToolbar>
@@ -277,11 +326,12 @@ The scroll area takes focus. From there:
277
326
 
278
327
  On a focused annotation:
279
328
 
280
- - `Enter` or `Space` selects and activates it. A note or text markup opens its thread; other types are only selected.
329
+ - `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
330
  - `ArrowUp` and `ArrowDown` move to the previous or next annotation on the page.
282
331
  - `Shift` + arrow moves it by 1 pt, or by 10 pt with `Alt` as well.
283
332
  - `Ctrl` or `Cmd` + `Shift` + arrow resizes an area redaction, text box or shape.
284
333
  - `Delete` or `Backspace` removes it.
334
+ - `Escape` clears the selection.
285
335
 
286
336
  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
337
 
@@ -291,7 +341,7 @@ Components carry state on data attributes, for example `[data-annotation][data-s
291
341
 
292
342
  ## Hooks
293
343
 
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.
344
+ `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
345
 
296
346
  ## Licence
297
347
 
@@ -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,7 +7,7 @@
7
7
  DocumentSource,
8
8
  FieldsChange,
9
9
  FieldValues,
10
- FormAction,
10
+ ViewerAction,
11
11
  InkDocument,
12
12
  InkError,
13
13
  InkStatus,
@@ -52,8 +52,13 @@
52
52
  * are controlled, after the bound value is written.
53
53
  */
54
54
  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
55
+ /**
56
+ * The viewer asked the host to submit a form, open a link, send mail, print or prompt.
57
+ * Inkbar does none of these.
58
+ */
59
+ onaction?: ((action: ViewerAction) => void) | undefined
60
+ /** @deprecated Use `onaction`. Removed in 0.13.0. Ignored when `onaction` is given. */
61
+ onformaction?: ((action: ViewerAction) => void) | undefined
57
62
  /** Tints fillable form fields. Default true. A change applies to the open document in place. */
58
63
  formHighlight?: boolean | undefined
59
64
  tool?: ToolId | undefined
@@ -87,9 +92,16 @@
87
92
  */
88
93
  fonts?: string[] | undefined
89
94
  /**
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.
95
+ * Where the viewer keeps what lasts between visits: saved signatures, each `InkSidebar`'s
96
+ * width and the plugins' settings. Default: memory, gone on reload. `createLocalStorage`
97
+ * keeps them in the browser; a host can keep them anywhere. Read once, when the root is
98
+ * created.
99
+ */
100
+ storage?: InkStorage | undefined
101
+ /**
102
+ * Where saved signatures live, in place of `storage`. A new store takes effect at once, for
103
+ * the menus and the `signature` tool alike.
104
+ * @deprecated Pass `storage`; signatures are kept in it under `signatures`. Removed in 0.13.0.
93
105
  */
94
106
  signatures?: SignatureStore | undefined
95
107
  /** The handwriting fonts a typed signature offers; the host loads them. */
@@ -121,9 +133,10 @@
121
133
 
122
134
  <script lang="ts">
123
135
  import {
124
- createMemorySignatureStore,
136
+ createMemoryStorage,
125
137
  createSignatureLibrary,
126
138
  createSnapshotHistory,
139
+ createStorageSignatureStore,
127
140
  InkError as InkErrorClass,
128
141
  openDocument,
129
142
  readonly,
@@ -153,8 +166,9 @@
153
166
  import { registeredToolIds } from '../hooks/useRegisteredTool.svelte.js'
154
167
  import { useReadable } from '../use-readable.svelte.js'
155
168
 
156
- import type { PluginHistory } from '@inkbar/core'
169
+ import type { InkStorage, PluginHistory } from '@inkbar/core'
157
170
  import type {
171
+ Navigation,
158
172
  PluginHost,
159
173
  SearchController,
160
174
  ToolController,
@@ -171,6 +185,7 @@
171
185
  onChange,
172
186
  fields = $bindable(),
173
187
  onFieldsChange,
188
+ onaction,
174
189
  onformaction,
175
190
  formHighlight,
176
191
  tool = $bindable(),
@@ -179,6 +194,7 @@
179
194
  plugins,
180
195
  decorateAnnotation,
181
196
  fonts,
197
+ storage: storageProp,
182
198
  signatures: signatureStore,
183
199
  signatureFonts,
184
200
  page = $bindable(),
@@ -197,9 +213,11 @@
197
213
 
198
214
  type TestHookElement = HTMLElement & { __inkDocument?: InkDocument | undefined }
199
215
 
200
- const signatures = $derived(
201
- createSignatureLibrary(signatureStore ?? createMemorySignatureStore())
202
- )
216
+ // Read once, like `plugins`: the sidebars and the plugins load from it as they are created.
217
+ const storage = untrack(() => storageProp ?? createMemoryStorage())
218
+ const storageSignatures = createStorageSignatureStore(storage)
219
+ // The deprecated `signatures` wins when both are given.
220
+ const signatures = $derived(createSignatureLibrary(signatureStore ?? storageSignatures))
203
221
  $effect(() => {
204
222
  void signatures.refresh()
205
223
  })
@@ -233,6 +251,7 @@
233
251
  let activatedNow: string | null = null
234
252
  let viewport = $state.raw<Viewport | null>(null)
235
253
  let tools = $state.raw<ToolController | null>(null)
254
+ let navigation = $state.raw<Navigation | null>(null)
236
255
 
237
256
  const documentStatus = useReadable<InkStatus>(() => document?.status, IDLE)
238
257
  const status = $derived(override ?? documentStatus.current)
@@ -428,7 +447,16 @@
428
447
  zoom = z
429
448
  onZoomChange?.(z)
430
449
  }
450
+ /**
451
+ * Whether the host has given `page` a value of its own, as React's `page` prop. Until then the
452
+ * page written back below is only a report, so the next document opens at its first page
453
+ * instead of the last one's. Not reactive: it flips only with a change to `page`, which
454
+ * `pageModel`'s readers already track.
455
+ */
456
+ let hostPage = untrack(() => page) !== undefined
457
+ let reportedPage: number | undefined
431
458
  function reportPage(p: number): void {
459
+ reportedPage = p
432
460
  page = p
433
461
  onPageChange?.(p)
434
462
  }
@@ -529,6 +557,7 @@
529
557
  decorate: () => decorateAnnotation,
530
558
  viewport: () => viewport,
531
559
  search: viewerSearchOf(controller),
560
+ storage,
532
561
  })
533
562
  )
534
563
  search = controller
@@ -628,6 +657,12 @@
628
657
  get viewport() {
629
658
  return viewport
630
659
  },
660
+ get navigation() {
661
+ return navigation
662
+ },
663
+ setNavigation(n) {
664
+ navigation = n
665
+ },
631
666
  get tools() {
632
667
  return tools
633
668
  },
@@ -651,6 +686,7 @@
651
686
  return fonts ?? FONT_FAMILIES
652
687
  },
653
688
  toolOptions,
689
+ storage,
654
690
  get signatures() {
655
691
  return signatures
656
692
  },
@@ -664,7 +700,8 @@
664
700
  return zoom
665
701
  },
666
702
  get pageModel() {
667
- return page
703
+ if (page !== undefined && page !== reportedPage) hostPage = true
704
+ return hostPage ? page : undefined
668
705
  },
669
706
  reportZoom,
670
707
  reportPage,
@@ -683,7 +720,7 @@
683
720
  get formHighlight() {
684
721
  return formHighlight
685
722
  },
686
- reportFormAction: (a) => onformaction?.(a),
723
+ reportAction: (a) => (onaction ?? onformaction)?.(a),
687
724
  reportError: (e) => onError?.(e),
688
725
  }
689
726
  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, SignatureStore } 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,13 @@ 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;
36
+ /** @deprecated Use `onaction`. Removed in 0.13.0. Ignored when `onaction` is given. */
37
+ onformaction?: ((action: ViewerAction) => void) | undefined;
33
38
  /** Tints fillable form fields. Default true. A change applies to the open document in place. */
34
39
  formHighlight?: boolean | undefined;
35
40
  tool?: ToolId | undefined;
@@ -63,9 +68,16 @@ export interface InkRootProps extends Omit<HTMLAttributes<HTMLDivElement>, 'chil
63
68
  */
64
69
  fonts?: string[] | undefined;
65
70
  /**
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.
71
+ * Where the viewer keeps what lasts between visits: saved signatures, each `InkSidebar`'s
72
+ * width and the plugins' settings. Default: memory, gone on reload. `createLocalStorage`
73
+ * keeps them in the browser; a host can keep them anywhere. Read once, when the root is
74
+ * created.
75
+ */
76
+ storage?: InkStorage | undefined;
77
+ /**
78
+ * Where saved signatures live, in place of `storage`. A new store takes effect at once, for
79
+ * the menus and the `signature` tool alike.
80
+ * @deprecated Pass `storage`; signatures are kept in it under `signatures`. Removed in 0.13.0.
69
81
  */
70
82
  signatures?: SignatureStore | undefined;
71
83
  /** The handwriting fonts a typed signature offers; the host loads them. */
@@ -97,6 +109,7 @@ export interface InkRootProps extends Omit<HTMLAttributes<HTMLDivElement>, 'chil
97
109
  child?: ChildSnippet;
98
110
  }
99
111
  import { type InkHistory } from '../context.js';
112
+ import type { InkStorage } from '@inkbar/core';
100
113
  declare const InkRoot: import("svelte").Component<InkRootProps, {
101
114
  history: InkHistory;
102
115
  getDocument: () => InkDocument | null;
@@ -1 +1 @@
1
- {"version":3,"file":"InkRoot.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/components/InkRoot.svelte.ts"],"names":[],"mappings":"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"}
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,28 @@
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. The shown width also stays within half the sidebar's container. */
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
21
44
  /** The `InkPanel`s. */
22
45
  children?: Snippet | undefined
23
46
  }
@@ -37,10 +60,16 @@
37
60
  * `InkRoot`. The server renders the root, the panels (the open one shown) and the stack
38
61
  * headers; rail and tab buttons follow once mounted, as the panels register after the root
39
62
  * has rendered.
63
+ *
64
+ * The handle on the inner edge resizes the sidebar. Its width is saved in `storage`, under
65
+ * `sidebar.<name>.width`; inside `InkRoot` the root's storage is the default. `bind:width`
66
+ * to a number makes the width the host's: drags and keys then only update the binding, and
67
+ * storage is not read or written. The server renders the handle too.
40
68
  */
41
69
  import { createSidebarController } from '@inkbar/core/dom'
42
70
  import { untrack } from 'svelte'
43
71
 
72
+ import { useOptionalInkContext } from '../context.js'
44
73
  import { useReadable } from '../use-readable.svelte.js'
45
74
 
46
75
  import { setSidebarContext, type SidebarPanelEntry } from './sidebar-context.js'
@@ -51,6 +80,12 @@
51
80
  layout = 'rail',
52
81
  visible = true,
53
82
  open = $bindable(),
83
+ storage,
84
+ name,
85
+ defaultWidth,
86
+ minWidth,
87
+ maxWidth,
88
+ width = $bindable(),
54
89
  class: className,
55
90
  children,
56
91
  ...rest
@@ -62,6 +97,31 @@
62
97
  let entries = $state.raw<SidebarPanelEntry[]>([])
63
98
  const infos = () => entries.map((e) => e.info())
64
99
 
100
+ // Read once: the controller loads the saved width as it is created.
101
+ const inheritedStorage = useOptionalInkContext()?.storage
102
+
103
+ /*
104
+ * `width` is the host's only while it holds a number the sidebar did not write itself. The
105
+ * sidebar writes every change back to the binding; on an unbound prop that sets the local
106
+ * value, which would otherwise read as a controlling number and stop the saving. `written` is
107
+ * the last width we wrote. `controlled` turns on once the host gives a number that is not
108
+ * ours, or starts with one, and then stays on, as in core.
109
+ */
110
+ let written: number | undefined
111
+ let controlled = untrack(() => width !== undefined)
112
+ /** The width props the host gave; an undefined one keeps the controller's. */
113
+ function widthOptions(): Partial<
114
+ Record<'defaultWidth' | 'minWidth' | 'maxWidth' | 'width', number>
115
+ > {
116
+ if (width !== undefined && width !== written) controlled = true
117
+ return {
118
+ ...(defaultWidth !== undefined && { defaultWidth }),
119
+ ...(minWidth !== undefined && { minWidth }),
120
+ ...(maxWidth !== undefined && { maxWidth }),
121
+ ...(controlled && width !== undefined && { width }),
122
+ }
123
+ }
124
+
65
125
  // Pending until mounted: the panels register one by one as they initialise, and an open id
66
126
  // not registered yet is not a removed panel.
67
127
  const controller = untrack(() =>
@@ -72,6 +132,13 @@
72
132
  panels: [],
73
133
  ...(open !== undefined && { open }),
74
134
  pending: true,
135
+ ...((storage ?? inheritedStorage) && { storage: (storage ?? inheritedStorage)! }),
136
+ ...(name !== undefined && { name }),
137
+ ...widthOptions(),
138
+ onWidthChange: (value) => {
139
+ written = value
140
+ width = value
141
+ },
75
142
  onOpenChange: (value) => {
76
143
  open = value
77
144
  },
@@ -86,13 +153,14 @@
86
153
 
87
154
  // Before the DOM updates, so the panels render the attributes these give.
88
155
  $effect.pre(() => {
89
- const next = { layout, side, visible, open }
156
+ const next = { layout, side, visible, open, widths: widthOptions() }
90
157
  untrack(() =>
91
158
  controller.update({
92
159
  layout: next.layout,
93
160
  side: next.side,
94
161
  visible: next.visible,
95
162
  ...(next.open !== undefined && { open: next.open }),
163
+ ...next.widths,
96
164
  })
97
165
  )
98
166
  })
@@ -134,11 +202,20 @@
134
202
 
135
203
  setSidebarContext({ controller, state: current, register, arrange })
136
204
 
205
+ // The panels register after the root rendered, so the server's and the first render's handle
206
+ // is shown (as the root is: `data-state` is open while pending); the real `hidden` follows
207
+ // once mounted.
208
+ let mounted = $state(false)
137
209
  const view = $derived.by(() => {
138
210
  const s = current.current
211
+ const handleAttrs = controller.handleAttrs()
212
+ if (!mounted) delete handleAttrs.hidden
139
213
  return {
140
214
  layout: s.layout,
141
215
  root: controller.rootAttrs(),
216
+ style: controller.rootStyle(),
217
+ panels: controller.panelsAttrs(),
218
+ handle: handleAttrs,
142
219
  tablist: controller.tablistAttrs(),
143
220
  triggers: s.panels.map((panel) => ({
144
221
  panel,
@@ -148,6 +225,7 @@
148
225
  })
149
226
 
150
227
  let root = $state<HTMLDivElement | null>(null)
228
+ let handle = $state<HTMLDivElement | null>(null)
151
229
  // The controller handles the triggers' clicks and keys, stack headers included. The panels
152
230
  // have registered by now.
153
231
  $effect(() => {
@@ -157,9 +235,31 @@
157
235
  untrack(() => controller.update({ pending: false }))
158
236
  return unbind
159
237
  })
238
+ // The controller handles the handle's drags, keys and double-click.
239
+ $effect(() => {
240
+ const el = handle
241
+ if (!el || !root) return
242
+ const host = root
243
+ const unbind = untrack(() => controller.bindHandle(el))
244
+ untrack(() => {
245
+ mounted = true
246
+ // Hydration keeps the server's markup: a width the client's storage gave applies here.
247
+ for (const [prop, value] of Object.entries(controller.rootStyle()))
248
+ host.style.setProperty(prop, value)
249
+ for (const [attr, value] of Object.entries(controller.handleAttrs()))
250
+ if (attr.startsWith('aria-value')) el.setAttribute(attr, value)
251
+ })
252
+ return unbind
253
+ })
160
254
  </script>
161
255
 
162
- <div {...rest} bind:this={root} class={['ink-sidebar', className]} {...view.root}>
256
+ <div
257
+ {...rest}
258
+ bind:this={root}
259
+ class={['ink-sidebar', className]}
260
+ {...view.root}
261
+ style:--ink-sidebar-width={view.style['--ink-sidebar-width']}
262
+ >
163
263
  {#if view.layout !== 'stack'}
164
264
  <div
165
265
  class={view.layout === 'rail' ? 'ink-sidebar-rail' : 'ink-sidebar-tabs'}
@@ -173,7 +273,13 @@
173
273
  </div>
174
274
  {/if}
175
275
  <!-- One element in every layout, so the panels are never remounted. -->
176
- <div class={{ 'ink-sidebar-panels': view.layout !== 'stack' }}>
276
+ <!-- The stack has no panels element: its id and class apply in rail and tabs only. -->
277
+ <div
278
+ class={{ 'ink-sidebar-panels': view.layout !== 'stack' }}
279
+ {...view.layout !== 'stack' ? view.panels : {}}
280
+ >
177
281
  {@render children?.()}
178
282
  </div>
283
+ <!-- The last child, on the inner edge. -->
284
+ <div bind:this={handle} class="ink-sidebar-handle" {...view.handle}></div>
179
285
  </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,32 @@ 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. The shown width also stays within half the sidebar's container. */
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;
16
39
  /** The `InkPanel`s. */
17
40
  children?: Snippet | undefined;
18
41
  }
19
- declare const InkSidebar: import("svelte").Component<InkSidebarProps, {}, "open">;
42
+ declare const InkSidebar: import("svelte").Component<InkSidebarProps, {}, "width" | "open">;
20
43
  type InkSidebar = ReturnType<typeof InkSidebar>;
21
44
  export default InkSidebar;
22
45
  //# 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,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC/B;AAmPH,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
@@ -177,7 +178,7 @@
177
178
  onSignField: (req) => {
178
179
  signRequest = signRequest?.widget === req.widget ? null : req
179
180
  },
180
- onFormAction: (a) => ctx.reportFormAction(a),
181
+ onAction: (a) => ctx.reportAction(a),
181
182
  onFormAlert: (message) => {
182
183
  alert = { message, shown: (alert?.shown ?? 0) + 1 }
183
184
  },
@@ -235,6 +236,8 @@
235
236
  pages = pages.map((p) => (p.page === page ? { ...p, error: err } : p))
236
237
  },
237
238
  })
239
+ // The engine exists from here; its navigation lasts for its life, across rebuilds.
240
+ ctx.setNavigation(engine.navigation)
238
241
  }
239
242
 
240
243
  // 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;AA6XH,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,12 @@ 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
+ /** The saved signatures: InkRoot's deprecated `signatures` store, else its `storage`. */
68
79
  readonly signatures: SignatureLibrary;
69
80
  /** The fonts a typed signature offers: InkRoot's `signatureFonts`, else `SIGNATURE_FONTS`. */
70
81
  readonly signatureFonts: readonly string[];
@@ -88,8 +99,8 @@ export interface InkContext {
88
99
  setViewport(viewport: Viewport | null, tools: ToolController | null): void;
89
100
  /** InkRoot's `formHighlight`; InkViewport reads it when it builds the viewer. */
90
101
  readonly formHighlight: boolean | undefined;
91
- /** Calls InkRoot's `onformaction`. */
92
- reportFormAction(action: FormAction): void;
102
+ /** Calls InkRoot's `onaction`, or the deprecated `onformaction`. */
103
+ reportAction(action: ViewerAction): void;
93
104
  /** Calls InkRoot's `onError`, for failures after the document opened (a refused signing). */
94
105
  reportError(error: InkError): void;
95
106
  }
@@ -102,4 +113,9 @@ export declare function peekActivated(ctx: InkContext): string | null;
102
113
  * rendered inside `InkRoot`, including when called outside any component at all.
103
114
  */
104
115
  export declare function useInkContext(consumer: string): InkContext;
116
+ /**
117
+ * The context when there is one, else undefined: for components that also work outside
118
+ * `InkRoot`. Internal to the package.
119
+ */
120
+ export declare function useOptionalInkContext(): InkContext | undefined;
105
121
  //# 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,yFAAyF;IACzF,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,oEAAoE;IACpE,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.12.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.12.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.12.0",
36
36
  "svelte": "^5.46.4"
37
37
  },
38
38
  "devDependencies": {
39
- "@inkbar/core": "0.11.0",
39
+ "@inkbar/core": "0.12.0",
40
40
  "@inkbar/fixtures": "0.0.0",
41
- "@inkbar/theme": "0.11.0",
41
+ "@inkbar/theme": "0.12.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",