@inkbar/vue 0.9.0 → 0.10.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.
Files changed (99) hide show
  1. package/README.md +63 -2
  2. package/dist/components/InkDownloadButton.js +7 -0
  3. package/dist/components/InkDownloadButton.js.map +1 -0
  4. package/dist/components/InkDownloadButton.vue.d.ts +21 -0
  5. package/dist/components/InkDownloadButton.vue.d.ts.map +1 -0
  6. package/dist/components/InkDownloadButton.vue_vue_type_script_setup_true_lang.js +42 -0
  7. package/dist/components/InkDownloadButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  8. package/dist/components/InkFindBar.js.map +1 -1
  9. package/dist/components/InkFindBar.vue.d.ts.map +1 -1
  10. package/dist/components/InkFindBar.vue_vue_type_script_setup_true_lang.js +48 -48
  11. package/dist/components/InkFindBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  12. package/dist/components/InkPanel.js +7 -0
  13. package/dist/components/InkPanel.js.map +1 -0
  14. package/dist/components/InkPanel.vue.d.ts +21 -0
  15. package/dist/components/InkPanel.vue.d.ts.map +1 -0
  16. package/dist/components/InkPanel.vue_vue_type_script_setup_true_lang.js +48 -0
  17. package/dist/components/InkPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  18. package/dist/components/InkPrintButton.js +7 -0
  19. package/dist/components/InkPrintButton.js.map +1 -0
  20. package/dist/components/InkPrintButton.vue.d.ts +19 -0
  21. package/dist/components/InkPrintButton.vue.d.ts.map +1 -0
  22. package/dist/components/InkPrintButton.vue_vue_type_script_setup_true_lang.js +39 -0
  23. package/dist/components/InkPrintButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  24. package/dist/components/InkRecordList.js +7 -0
  25. package/dist/components/InkRecordList.js.map +1 -0
  26. package/dist/components/InkRecordList.vue.d.ts +35 -0
  27. package/dist/components/InkRecordList.vue.d.ts.map +1 -0
  28. package/dist/components/InkRecordList.vue_vue_type_script_setup_true_lang.js +41 -0
  29. package/dist/components/InkRecordList.vue_vue_type_script_setup_true_lang.js.map +1 -0
  30. package/dist/components/InkRoot.js.map +1 -1
  31. package/dist/components/InkRoot.vue.d.ts +39 -0
  32. package/dist/components/InkRoot.vue.d.ts.map +1 -1
  33. package/dist/components/InkRoot.vue_vue_type_script_setup_true_lang.js +45 -45
  34. package/dist/components/InkRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  35. package/dist/components/InkSearchResults.js +7 -0
  36. package/dist/components/InkSearchResults.js.map +1 -0
  37. package/dist/components/InkSearchResults.vue.d.ts +9 -0
  38. package/dist/components/InkSearchResults.vue.d.ts.map +1 -0
  39. package/dist/components/InkSearchResults.vue_vue_type_script_setup_true_lang.js +52 -0
  40. package/dist/components/InkSearchResults.vue_vue_type_script_setup_true_lang.js.map +1 -0
  41. package/dist/components/InkSidebar.js +7 -0
  42. package/dist/components/InkSidebar.js.map +1 -0
  43. package/dist/components/InkSidebar.vue.d.ts +34 -0
  44. package/dist/components/InkSidebar.vue.d.ts.map +1 -0
  45. package/dist/components/InkSidebar.vue_vue_type_script_setup_true_lang.js +95 -0
  46. package/dist/components/InkSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  47. package/dist/components/InkThumbnail.js +7 -0
  48. package/dist/components/InkThumbnail.js.map +1 -0
  49. package/dist/components/InkThumbnail.vue.d.ts +18 -0
  50. package/dist/components/InkThumbnail.vue.d.ts.map +1 -0
  51. package/dist/components/InkThumbnail.vue_vue_type_script_setup_true_lang.js +49 -0
  52. package/dist/components/InkThumbnail.vue_vue_type_script_setup_true_lang.js.map +1 -0
  53. package/dist/components/InkThumbnails.js +7 -0
  54. package/dist/components/InkThumbnails.js.map +1 -0
  55. package/dist/components/InkThumbnails.vue.d.ts +27 -0
  56. package/dist/components/InkThumbnails.vue.d.ts.map +1 -0
  57. package/dist/components/InkThumbnails.vue_vue_type_script_setup_true_lang.js +107 -0
  58. package/dist/components/InkThumbnails.vue_vue_type_script_setup_true_lang.js.map +1 -0
  59. package/dist/components/InkZoomSelect.js.map +1 -1
  60. package/dist/components/InkZoomSelect.vue.d.ts.map +1 -1
  61. package/dist/components/InkZoomSelect.vue_vue_type_script_setup_true_lang.js +1 -1
  62. package/dist/components/InkZoomSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  63. package/dist/components/RecordCards.js +7 -0
  64. package/dist/components/RecordCards.js.map +1 -0
  65. package/dist/components/RecordCards.vue.d.ts +25 -0
  66. package/dist/components/RecordCards.vue.d.ts.map +1 -0
  67. package/dist/components/RecordCards.vue_vue_type_script_setup_true_lang.js +120 -0
  68. package/dist/components/RecordCards.vue_vue_type_script_setup_true_lang.js.map +1 -0
  69. package/dist/components/SidebarTrigger.js +7 -0
  70. package/dist/components/SidebarTrigger.js.map +1 -0
  71. package/dist/components/SidebarTrigger.vue.d.ts +9 -0
  72. package/dist/components/SidebarTrigger.vue.d.ts.map +1 -0
  73. package/dist/components/SidebarTrigger.vue_vue_type_script_setup_true_lang.js +33 -0
  74. package/dist/components/SidebarTrigger.vue_vue_type_script_setup_true_lang.js.map +1 -0
  75. package/dist/components/sidebar-context.d.ts +21 -0
  76. package/dist/components/sidebar-context.d.ts.map +1 -0
  77. package/dist/components/sidebar-context.js +7 -0
  78. package/dist/components/sidebar-context.js.map +1 -0
  79. package/dist/composables/useAnnotations.d.ts +91 -0
  80. package/dist/composables/useAnnotations.d.ts.map +1 -1
  81. package/dist/composables/useRecordSelection.d.ts +12 -0
  82. package/dist/composables/useRecordSelection.d.ts.map +1 -0
  83. package/dist/composables/useRecordSelection.js +15 -0
  84. package/dist/composables/useRecordSelection.js.map +1 -0
  85. package/dist/composables/useRecords.d.ts +14 -0
  86. package/dist/composables/useRecords.d.ts.map +1 -0
  87. package/dist/composables/useRecords.js +16 -0
  88. package/dist/composables/useRecords.js.map +1 -0
  89. package/dist/composables/useSearch.d.ts.map +1 -1
  90. package/dist/composables/useSearch.js +1 -0
  91. package/dist/composables/useSearch.js.map +1 -1
  92. package/dist/index.d.ts +11 -0
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +40 -30
  95. package/dist/to-readable.d.ts +7 -0
  96. package/dist/to-readable.d.ts.map +1 -0
  97. package/dist/to-readable.js +11 -0
  98. package/dist/to-readable.js.map +1 -0
  99. package/package.json +5 -5
package/README.md CHANGED
@@ -159,11 +159,71 @@ Plugin stores undo with annotations. In controlled mode with `:history="true"`,
159
159
 
160
160
  `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.
161
161
 
162
+ ## Sidebars
163
+
164
+ `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 default slot is the panel's content, your own component or one of Inkbar's.
165
+
166
+ ```vue
167
+ <InkRoot :src="src" :assets="assets">
168
+ <div class="app">
169
+ <InkSidebar side="left" layout="rail" v-model:open="open">
170
+ <InkPanel id="pages" label="Pages" :icon="Square">
171
+ <InkThumbnails />
172
+ </InkPanel>
173
+ <InkPanel id="notes" label="Notes" :icon="MessageSquare" :badge="noteCount">
174
+ <MyNotes />
175
+ </InkPanel>
176
+ </InkSidebar>
177
+ <InkViewport />
178
+ </div>
179
+ </InkRoot>
180
+ ```
181
+
182
+ `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. `v-model:open` is the open panel's id, or `null`, for rail and tabs, and the expanded ids for stack. Left unbound, the first panel starts open. When the open panel goes (a `v-if`), rail and tabs open the first one left and stack drops it, and `v-model: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.
183
+
184
+ Panels take their place in the order they appear in the template, including one added later with `v-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.
185
+
186
+ ## Thumbnails
187
+
188
+ `InkThumbnail` draws one page (0-based `page`) as a small image, with its annotations and plugin marks. Give it a `width` or a `height` and the other follows the page; with neither it is 120px wide. `:annotations="false"` and `:marks="false"` leave those out, and `label` replaces its accessible name ("Page 4" for page 3). It is an image with no focus or click behaviour, so wrap it in the control you need, a checkbox label in a dialog for instance.
189
+
190
+ `InkThumbnails` lists the pages as thumbnails, each a button that scrolls the viewport to its page, with the current page marked `aria-current="page"`. It fills its parent's height and scrolls. `pages` lists the pages to show, in order. The thumbnails fill the list's width less a 16px gutter each side and follow it as it resizes; `width` fixes them at that many pixels instead. `annotations` and `marks` pass to each thumbnail. Only the items near the visible part are mounted. The `item` slot adds to each item after its page number:
191
+
192
+ ```vue
193
+ <InkThumbnails>
194
+ <template #item="{ page, current }">
195
+ <span class="page-count">{{ counts[page] }}</span>
196
+ </template>
197
+ </InkThumbnails>
198
+ ```
199
+
200
+ An item's height is worked out from its page alone, so position what you add absolutely. The `item` slot 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.
201
+
202
+ ## Record lists
203
+
204
+ `InkRecordList` lists a plugin's records as cards, the same cards their marks open, with the same actions. Name the records `<plugin>.<name>`:
205
+
206
+ ```vue
207
+ <InkPanel id="suggestions" label="Suggestions" :icon="MessageSquare" :badge="count">
208
+ <InkRecordList records="review.suggestions" @update:count="count = $event">
209
+ <template #empty>No suggestions left.</template>
210
+ </InkRecordList>
211
+ </InkPanel>
212
+ ```
213
+
214
+ 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. Changing one rebuilds the list, so define them once in your script, not inline in the template. `update:count` gives the number listed whenever it changes, ready for a panel badge. The `empty` slot 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.
215
+
216
+ `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.
217
+
218
+ To build your own, `useRecords<T>(name)` returns the live `records` and the `handle` to read and write them, each write one undo step, and `useRecordSelection(name)` returns `selected` and `select(id | null)`. Both need `InkRoot`. Plugins are set up once it has mounted, so until then `handle` is null, `records` is empty and nothing is selected. Both lists fill their parent's height and render empty on the server. The keys, focus and announcements are core's: see the [`@inkbar/core` README](https://github.com/inkbar/inkbar/tree/main/packages/core#record-lists).
219
+
162
220
  ## Custom rendering
163
221
 
164
222
  Slots let you render parts yourself. `InkViewport` has `loading`, `empty`, `error`, `annotation` and `page-error` slots. `InkThreadPopover` has a scoped default slot that receives the popover's props, and the default slot of `InkToolButton` receives `{ active, label }`. The props are typed as `AnnotationSlotProps` and `ThreadPopoverSlotProps`, the same types the React and Svelte packages export.
165
223
 
166
- `InkRoot`, `InkToolbar`, `InkToolButton`, `InkCommand`, `InkUndo`, `InkRedo`, `InkPrevPage`, `InkNextPage`, `InkZoomIn` and `InkZoomOut` take `as-child` to render your own element in place of theirs, such as a button from your design system. Put that element in the default slot. The control keeps its behaviour and accessible name.
224
+ `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.
225
+
226
+ `InkRoot`, `InkToolbar`, `InkToolButton`, `InkCommand`, `InkUndo`, `InkRedo`, `InkDownloadButton`, `InkPrintButton`, `InkPrevPage`, `InkNextPage`, `InkZoomIn` and `InkZoomOut` take `as-child` to render your own element in place of theirs, such as a button from your design system. Put that element in the default slot. The control keeps its behaviour and accessible name.
167
227
 
168
228
  ## Keyboard
169
229
 
@@ -173,6 +233,7 @@ The scroll area takes focus. From there:
173
233
  - With the `note` tool active, `Enter` places a note at the centre of the current page and opens it.
174
234
  - With the `signature` tool active, `Enter` places the chosen signature at the centre of the current page.
175
235
  - `Ctrl` or `Cmd` + `Z` undoes. `Ctrl` or `Cmd` + `Shift` + `Z`, or `Ctrl` + `Y`, redoes. `Ctrl` and `Cmd` both work on every platform. The keys do what `InkUndo` and `InkRedo` do, from anywhere in `InkRoot`, toolbars included, and act only while that button is enabled. In a text field or editable content the keys stay with the element, so a field keeps its own text undo. In a `<select>` they are left to the browser, which does nothing with them.
236
+ - `Ctrl` or `Cmd` + `P` prints the PDF and `Ctrl` or `Cmd` + `S` downloads it, as `InkPrintButton` and `InkDownloadButton` do, from anywhere in `InkRoot` once the document is ready. Outside `InkRoot` the browser keeps them.
176
237
 
177
238
  On a focused annotation:
178
239
 
@@ -190,7 +251,7 @@ Components carry state on data attributes, for example `[data-annotation][data-s
190
251
 
191
252
  ## Composables
192
253
 
193
- `useDocument`, `useAnnotations`, `useTool`, `useSelection`, `useZoom`, `usePage`, `useHistory`, `useEmbedded` and `useCommand` read the state of the nearest `InkRoot`. Build your own toolbar or side panel from them. 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.
254
+ `useDocument`, `useAnnotations`, `useTool`, `useSelection`, `useZoom`, `usePage`, `useHistory`, `useEmbedded`, `useCommand`, `useRecords` and `useRecordSelection` read the state of the nearest `InkRoot`. Build your own toolbar or side panel from them. 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.
194
255
 
195
256
  ## Licence
196
257
 
@@ -0,0 +1,7 @@
1
+ import e from "./InkDownloadButton.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/components/InkDownloadButton.vue
3
+ var t = e;
4
+ //#endregion
5
+ export { t as default };
6
+
7
+ //# sourceMappingURL=InkDownloadButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkDownloadButton.js","names":["_sfc_main","InkDownloadButton_vue_vue_type_script_setup_true_lang_default","InkDownloadButton_default"],"sources":["../../src/components/InkDownloadButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * Saves the open document's file through the browser's download, under its `fileName` or\n * `filename`. Disabled until the document is ready. Today that is the file as it was\n * opened, without this session's annotations.\n */\nimport { downloadDocument } from '@inkbar/core/dom'\nimport { Download } from '@inkbar/icons'\nimport { ToolbarButton } from 'reka-ui'\nimport { computed } from 'vue'\n\nimport { useInkContext } from '../context'\n\nimport InkIcon from './InkIcon.vue'\n\nconst props = withDefaults(\n defineProps<{ asChild?: boolean; filename?: string | undefined }>(),\n {\n asChild: false,\n filename: undefined,\n }\n)\nconst ctx = useInkContext('InkDownloadButton')\nconst ready = computed(\n () => ctx.document.value !== null && ctx.status.value.state === 'ready'\n)\n\nfunction run(): void {\n const doc = ctx.document.value\n if (doc)\n void downloadDocument(\n doc,\n props.filename === undefined ? {} : { filename: props.filename }\n ).catch(() => undefined)\n}\n// Reka's typed props stop at its own; ARIA and listeners go through a bound object.\nconst attrs = { 'aria-label': 'Download', title: 'Download', onClick: run }\n</script>\n\n<template>\n <ToolbarButton\n :as-child=\"asChild\"\n :disabled=\"!ready\"\n class=\"ink-download\"\n data-ink-download\n v-bind=\"attrs\"\n >\n <slot><InkIcon :icon=\"Download\" /></slot>\n </ToolbarButton>\n</template>\n"],"mappings":""}
@@ -0,0 +1,21 @@
1
+ type __VLS_Props = {
2
+ asChild?: boolean;
3
+ filename?: string | undefined;
4
+ };
5
+ declare var __VLS_7: {};
6
+ type __VLS_Slots = {} & {
7
+ default?: (props: typeof __VLS_7) => any;
8
+ };
9
+ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ asChild: boolean;
11
+ filename: string | undefined;
12
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ type __VLS_WithSlots<T, S> = T & {
17
+ new (): {
18
+ $slots: S;
19
+ };
20
+ };
21
+ //# sourceMappingURL=InkDownloadButton.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkDownloadButton.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkDownloadButton.vue"],"names":[],"mappings":"AAmEA,KAAK,WAAW,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AA0ExE,QAAA,IAAI,OAAO,IAAW,CAAC;AACvB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAG/C,QAAA,MAAM,UAAU;;;6EAGd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { useInkContext as e } from "../context.js";
2
+ import t from "./InkIcon.js";
3
+ import { computed as n, createBlock as r, createVNode as i, defineComponent as a, mergeProps as o, openBlock as s, renderSlot as c, unref as l, withCtx as u } from "vue";
4
+ import { downloadDocument as d } from "@inkbar/core/dom";
5
+ import { ToolbarButton as f } from "reka-ui";
6
+ import { Download as p } from "@inkbar/icons";
7
+ //#region src/components/InkDownloadButton.vue?vue&type=script&setup=true&lang.ts
8
+ var m = /*@__PURE__*/ a({
9
+ __name: "InkDownloadButton",
10
+ props: {
11
+ asChild: {
12
+ type: Boolean,
13
+ default: !1
14
+ },
15
+ filename: { default: void 0 }
16
+ },
17
+ setup(a) {
18
+ let m = a, h = e("InkDownloadButton"), g = n(() => h.document.value !== null && h.status.value.state === "ready");
19
+ function _() {
20
+ let e = h.document.value;
21
+ e && d(e, m.filename === void 0 ? {} : { filename: m.filename }).catch(() => void 0);
22
+ }
23
+ let v = {
24
+ "aria-label": "Download",
25
+ title: "Download",
26
+ onClick: _
27
+ };
28
+ return (e, n) => (s(), r(l(f), o({
29
+ "as-child": a.asChild,
30
+ disabled: !g.value,
31
+ class: "ink-download",
32
+ "data-ink-download": ""
33
+ }, v), {
34
+ default: u(() => [c(e.$slots, "default", {}, () => [i(t, { icon: l(p) }, null, 8, ["icon"])])]),
35
+ _: 3
36
+ }, 16, ["as-child", "disabled"]));
37
+ }
38
+ });
39
+ //#endregion
40
+ export { m as default };
41
+
42
+ //# sourceMappingURL=InkDownloadButton.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkDownloadButton.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_unref","_mergeProps","_withCtx","_renderSlot","_createVNode","InkIcon","InkIcon_default","InkDownloadButton_vue_vue_type_script_setup_true_lang_default","props","__props","ctx","useInkContext","ready","computed","run","doc","downloadDocument","attrs","openBlock","createBlock","unref","ToolbarButton","mergeProps","withCtx","renderSlot","_ctx","createVNode","Download"],"sources":["../../src/components/InkDownloadButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * Saves the open document's file through the browser's download, under its `fileName` or\n * `filename`. Disabled until the document is ready. Today that is the file as it was\n * opened, without this session's annotations.\n */\nimport { downloadDocument } from '@inkbar/core/dom'\nimport { Download } from '@inkbar/icons'\nimport { ToolbarButton } from 'reka-ui'\nimport { computed } from 'vue'\n\nimport { useInkContext } from '../context'\n\nimport InkIcon from './InkIcon.vue'\n\nconst props = withDefaults(\n defineProps<{ asChild?: boolean; filename?: string | undefined }>(),\n {\n asChild: false,\n filename: undefined,\n }\n)\nconst ctx = useInkContext('InkDownloadButton')\nconst ready = computed(\n () => ctx.document.value !== null && ctx.status.value.state === 'ready'\n)\n\nfunction run(): void {\n const doc = ctx.document.value\n if (doc)\n void downloadDocument(\n doc,\n props.filename === undefined ? {} : { filename: props.filename }\n ).catch(() => undefined)\n}\n// Reka's typed props stop at its own; ARIA and listeners go through a bound object.\nconst attrs = { 'aria-label': 'Download', title: 'Download', onClick: run }\n</script>\n\n<template>\n <ToolbarButton\n :as-child=\"asChild\"\n :disabled=\"!ready\"\n class=\"ink-download\"\n data-ink-download\n v-bind=\"attrs\"\n >\n <slot><InkIcon :icon=\"Download\" /></slot>\n </ToolbarButton>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;EAeA,IAAMU,IAAQC,GAORC,IAAMC,EAAc,mBAAmB,GACvCC,IAAQC,QACNH,EAAI,SAAS,UAAU,QAAQA,EAAI,OAAO,MAAM,UAAU,OAClE;EAEA,SAASI,IAAY;GACnB,IAAMC,IAAML,EAAI,SAAS;GACzB,AAAIK,KACFC,EACED,GACAP,EAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAUA,EAAM,SAAS,CACjE,CAAC,CAAC,YAAY,KAAA,CAAS;EAC3B;EAEA,IAAMS,IAAQ;GAAE,cAAc;GAAY,OAAO;GAAY,SAASH;EAAI;oBAIxEhB,EAAA,GAAAC,EAQgBC,EAAAqB,CAAA,GARhBpB,EAQgB;GAPb,YAAUQ,EAAA;GACV,UAAQ,CAAGG,EAAA;GACZ,OAAM;GACN,qBAAA;EACQ,GAAAK,CAAK,GAAA;GAEb,SAAAf,QAAyC,CAAzCC,EAAyCsB,EAAA,QAAA,WAAA,CAAA,SAAA,CAAnCrB,EAA4BC,GAAA,EAAlB,MAAML,EAAA2B,CAAA,EAAQ,GAAA,MAAA,GAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"InkFindBar.js","names":["_sfc_main","InkFindBar_vue_vue_type_script_setup_true_lang_default","InkFindBar_default"],"sources":["../../src/components/InkFindBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * The find bar: a field, the match count, previous and next, a match-case toggle and close,\n * a view of the root's search state. Place it anywhere inside `InkRoot`: it teleports itself\n * into `[data-ink-viewport-root]`, the positioned ancestor the theme floats it from over the\n * top-right of the pages (as `InkThreadPopover` anchors to the root's overlay rather than\n * where it is written). It is hidden while the search is closed. While it is mounted it\n * registers with the search controller, which is what lets Ctrl/Cmd+F open it.\n *\n * Enter in the field steps to the next match, Shift+Enter to the previous, Escape closes.\n * Closing returns focus to where it was before the bar opened, else to the document.\n */\nimport { findAnnouncer, findCountText } from '@inkbar/core/dom'\nimport { CaseSensitive, ChevronDown, ChevronUp, X } from '@inkbar/icons'\nimport { computed, onBeforeUnmount, useTemplateRef, watch } from 'vue'\n\nimport { useSearch } from '../composables/useSearch'\nimport { useInkContext } from '../context'\n\nimport InkIcon from './InkIcon.vue'\n\nimport type { SearchState } from '@inkbar/core/dom'\n\n// The root is a Teleport, so attributes such as `class` are bound to the bar itself.\ndefineOptions({ inheritAttrs: false })\n\nconst ctx = useInkContext('InkFindBar')\nconst { state, setQuery, setMatchCase, next, previous, close } = useSearch()\n\n/** The viewport root: the scroll element's parent, once InkViewport has mounted. */\nconst target = computed(() => ctx.viewportEl.value?.parentElement ?? null)\nconst bar = useTemplateRef<HTMLElement>('bar')\nconst field = useTemplateRef<HTMLInputElement>('field')\nconst live = useTemplateRef<HTMLElement>('live')\n\nconst count = computed(() => findCountText(state.value))\n\n// The live region follows the controller's state change by change, as the vanilla bar does,\n// and is written directly. A render shows only the last of the changes since the one before,\n// so two steps in one tick that end where they began would otherwise say nothing.\nwatch(\n [() => ctx.search.value, live],\n ([controller, el], _, onCleanup) => {\n if (!controller || !el) return\n const announce = findAnnouncer()\n const say = (s: SearchState): void => {\n const text = announce(s)\n if (el.textContent !== text) el.textContent = text\n }\n say(controller.state.get())\n onCleanup(controller.state.subscribe(say))\n },\n { flush: 'post', immediate: true }\n)\n\nfunction onFieldKeydown(e: KeyboardEvent): void {\n if (e.key !== 'Enter' || e.isComposing) return\n e.preventDefault()\n if (e.shiftKey) previous()\n else next()\n}\nfunction onBarKeydown(e: KeyboardEvent): void {\n if (e.key !== 'Escape' || e.defaultPrevented || e.isComposing) return\n e.preventDefault()\n e.stopPropagation()\n close()\n}\n\n/** Where focus was when the bar opened. */\nlet before: HTMLElement | null = null\nlet wasOpen = false\n\nfunction restoreFocus(): void {\n const el = bar.value\n const scroll = ctx.viewportEl.value\n const to = before?.isConnected && !el?.contains(before) ? before : scroll\n before = null\n to?.focus({ preventScroll: true })\n}\n\nfunction show(s: SearchState): void {\n const el = bar.value\n const input = field.value\n if (!el || !input) return\n if (s.open !== wasOpen) {\n wasOpen = s.open\n const doc = el.ownerDocument\n if (s.open) {\n const active = doc.activeElement\n before =\n active instanceof HTMLElement && active !== doc.body && !el.contains(active)\n ? active\n : null\n input.focus()\n input.select()\n } else {\n // Focus inside the bar is about to be lost with it; focus elsewhere is left alone.\n const hadFocus = el.contains(doc.activeElement) || doc.activeElement === doc.body\n if (hadFocus) restoreFocus()\n else before = null\n }\n }\n if (input.value !== s.query) {\n input.value = s.query\n // A query set from code arrives after the bar opened: keep the new text selected.\n if (el.ownerDocument.activeElement === input) input.select()\n }\n}\n\n// After the render, so the bar is shown (and can take focus) when it opens, and the field is\n// updated once it exists.\nwatch([state, bar, field], ([s]) => show(s), { flush: 'post', immediate: true })\n\n// Registered while mounted.\nlet detach: (() => void) | null = null\nwatch(\n [() => ctx.search.value, bar],\n ([controller, el]) => {\n detach?.()\n detach = controller && el ? controller.attachBar() : null\n },\n { flush: 'post', immediate: true }\n)\nonBeforeUnmount(() => {\n detach?.()\n detach = null\n})\n</script>\n\n<template>\n <Teleport v-if=\"target\" :to=\"target\">\n <div\n v-bind=\"$attrs\"\n ref=\"bar\"\n class=\"ink-find-bar\"\n data-ink-find-bar\n role=\"search\"\n :hidden=\"!state.open\"\n @keydown=\"onBarKeydown\"\n >\n <input\n ref=\"field\"\n type=\"text\"\n aria-label=\"Find in document\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n @input=\"setQuery(($event.target as HTMLInputElement).value)\"\n @keydown=\"onFieldKeydown\"\n />\n <span class=\"ink-find-count\" data-ink-find-count>{{ count }}</span>\n <button\n type=\"button\"\n data-ink-find-previous\n aria-label=\"Previous match\"\n title=\"Previous match\"\n @click=\"previous()\"\n >\n <InkIcon :icon=\"ChevronUp\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-next\n aria-label=\"Next match\"\n title=\"Next match\"\n @click=\"next()\"\n >\n <InkIcon :icon=\"ChevronDown\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-match-case\n aria-label=\"Match case\"\n title=\"Match case\"\n :aria-pressed=\"state.matchCase\"\n @click=\"setMatchCase(!state.matchCase)\"\n >\n <InkIcon :icon=\"CaseSensitive\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-close\n aria-label=\"Close find\"\n title=\"Close find\"\n @click=\"close()\"\n >\n <InkIcon :icon=\"X\" />\n </button>\n <div\n ref=\"live\"\n class=\"ink-visually-hidden\"\n data-ink-find-status\n aria-live=\"polite\"\n />\n </div>\n </Teleport>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"InkFindBar.js","names":["_sfc_main","InkFindBar_vue_vue_type_script_setup_true_lang_default","InkFindBar_default"],"sources":["../../src/components/InkFindBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * The find bar: a field, the match count, previous and next, a match-case toggle and close,\n * a view of the root's search state. Place it anywhere inside `InkRoot`: it teleports itself\n * into `[data-ink-viewport-root]`, the positioned ancestor the theme floats it from over the\n * top-right of the pages (as `InkThreadPopover` anchors to the root's overlay rather than\n * where it is written). It is hidden while the search is closed. While it is mounted it\n * registers with the search controller, which is what lets Ctrl/Cmd+F open it.\n *\n * Enter in the field steps to the next match, Shift+Enter to the previous, Escape closes.\n * Closing returns focus to where it was before the bar opened, else to the document.\n */\nimport { findAnnouncer, findCountText } from '@inkbar/core/dom'\nimport { CaseSensitive, ChevronDown, ChevronUp, Search, X } from '@inkbar/icons'\nimport { computed, onBeforeUnmount, useTemplateRef, watch } from 'vue'\n\nimport { useSearch } from '../composables/useSearch'\nimport { useInkContext } from '../context'\n\nimport InkIcon from './InkIcon.vue'\n\nimport type { SearchState } from '@inkbar/core/dom'\n\n// The root is a Teleport, so attributes such as `class` are bound to the bar itself.\ndefineOptions({ inheritAttrs: false })\n\nconst ctx = useInkContext('InkFindBar')\nconst { state, setQuery, setMatchCase, next, previous, close } = useSearch()\n\n/** The viewport root: the scroll element's parent, once InkViewport has mounted. */\nconst target = computed(() => ctx.viewportEl.value?.parentElement ?? null)\nconst bar = useTemplateRef<HTMLElement>('bar')\nconst field = useTemplateRef<HTMLInputElement>('field')\nconst live = useTemplateRef<HTMLElement>('live')\n\nconst count = computed(() => findCountText(state.value))\n\n// The live region follows the controller's state change by change, as the vanilla bar does,\n// and is written directly. A render shows only the last of the changes since the one before,\n// so two steps in one tick that end where they began would otherwise say nothing.\nwatch(\n [() => ctx.search.value, live],\n ([controller, el], _, onCleanup) => {\n if (!controller || !el) return\n const announce = findAnnouncer()\n const say = (s: SearchState): void => {\n const text = announce(s)\n if (el.textContent !== text) el.textContent = text\n }\n say(controller.state.get())\n onCleanup(controller.state.subscribe(say))\n },\n { flush: 'post', immediate: true }\n)\n\nfunction onFieldKeydown(e: KeyboardEvent): void {\n if (e.key !== 'Enter' || e.isComposing) return\n e.preventDefault()\n if (e.shiftKey) previous()\n else next()\n}\nfunction onBarKeydown(e: KeyboardEvent): void {\n if (e.key !== 'Escape' || e.defaultPrevented || e.isComposing) return\n e.preventDefault()\n e.stopPropagation()\n close()\n}\n\n/** Where focus was when the bar opened. */\nlet before: HTMLElement | null = null\nlet wasOpen = false\n\nfunction restoreFocus(): void {\n const el = bar.value\n const scroll = ctx.viewportEl.value\n const to = before?.isConnected && !el?.contains(before) ? before : scroll\n before = null\n to?.focus({ preventScroll: true })\n}\n\nfunction show(s: SearchState): void {\n const el = bar.value\n const input = field.value\n if (!el || !input) return\n if (s.open !== wasOpen) {\n wasOpen = s.open\n const doc = el.ownerDocument\n if (s.open) {\n const active = doc.activeElement\n before =\n active instanceof HTMLElement && active !== doc.body && !el.contains(active)\n ? active\n : null\n input.focus()\n input.select()\n } else {\n // Focus inside the bar is about to be lost with it; focus elsewhere is left alone.\n const hadFocus = el.contains(doc.activeElement) || doc.activeElement === doc.body\n if (hadFocus) restoreFocus()\n else before = null\n }\n }\n if (input.value !== s.query) {\n input.value = s.query\n // A query set from code arrives after the bar opened: keep the new text selected.\n if (el.ownerDocument.activeElement === input) input.select()\n }\n}\n\n// After the render, so the bar is shown (and can take focus) when it opens, and the field is\n// updated once it exists.\nwatch([state, bar, field], ([s]) => show(s), { flush: 'post', immediate: true })\n\n// Registered while mounted.\nlet detach: (() => void) | null = null\nwatch(\n [() => ctx.search.value, bar],\n ([controller, el]) => {\n detach?.()\n detach = controller && el ? controller.attachBar() : null\n },\n { flush: 'post', immediate: true }\n)\nonBeforeUnmount(() => {\n detach?.()\n detach = null\n})\n</script>\n\n<template>\n <Teleport v-if=\"target\" :to=\"target\">\n <div\n v-bind=\"$attrs\"\n ref=\"bar\"\n class=\"ink-find-bar\"\n data-ink-find-bar\n role=\"search\"\n :hidden=\"!state.open\"\n @keydown=\"onBarKeydown\"\n >\n <div class=\"ink-input-group\">\n <span class=\"ink-input-accessory\"><InkIcon :icon=\"Search\" /></span>\n <input\n ref=\"field\"\n type=\"text\"\n aria-label=\"Find in document\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n @input=\"setQuery(($event.target as HTMLInputElement).value)\"\n @keydown=\"onFieldKeydown\"\n />\n </div>\n <span class=\"ink-find-count\" data-ink-find-count>{{ count }}</span>\n <button\n type=\"button\"\n data-ink-find-previous\n aria-label=\"Previous match\"\n title=\"Previous match\"\n @click=\"previous()\"\n >\n <InkIcon :icon=\"ChevronUp\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-next\n aria-label=\"Next match\"\n title=\"Next match\"\n @click=\"next()\"\n >\n <InkIcon :icon=\"ChevronDown\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-match-case\n aria-label=\"Match case\"\n title=\"Match case\"\n :aria-pressed=\"state.matchCase\"\n @click=\"setMatchCase(!state.matchCase)\"\n >\n <InkIcon :icon=\"CaseSensitive\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-close\n aria-label=\"Close find\"\n title=\"Close find\"\n @click=\"close()\"\n >\n <InkIcon :icon=\"X\" />\n </button>\n <div\n ref=\"live\"\n class=\"ink-visually-hidden\"\n data-ink-find-status\n aria-live=\"polite\"\n />\n </div>\n </Teleport>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"InkFindBar.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkFindBar.vue"],"names":[],"mappings":"AA8dA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"InkFindBar.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkFindBar.vue"],"names":[],"mappings":"AAifA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -3,17 +3,17 @@ import { useSearch as t } from "../composables/useSearch.js";
3
3
  import n from "./InkIcon.js";
4
4
  import { Teleport as r, computed as i, createBlock as a, createCommentVNode as o, createElementVNode as s, createVNode as c, defineComponent as l, mergeProps as u, onBeforeUnmount as d, openBlock as f, toDisplayString as p, unref as m, useTemplateRef as h, watch as g } from "vue";
5
5
  import { findAnnouncer as _, findCountText as v } from "@inkbar/core/dom";
6
- import { CaseSensitive as y, ChevronDown as b, ChevronUp as x, X as S } from "@inkbar/icons";
6
+ import { CaseSensitive as y, ChevronDown as b, ChevronUp as x, Search as S, X as C } from "@inkbar/icons";
7
7
  //#region src/components/InkFindBar.vue?vue&type=script&setup=true&lang.ts
8
- var C = ["hidden"], w = {
8
+ var w = ["hidden"], T = { class: "ink-input-group" }, E = { class: "ink-input-accessory" }, D = {
9
9
  class: "ink-find-count",
10
10
  "data-ink-find-count": ""
11
- }, T = ["aria-pressed"], E = /*@__PURE__*/ l({
11
+ }, O = ["aria-pressed"], k = /*@__PURE__*/ l({
12
12
  inheritAttrs: !1,
13
13
  __name: "InkFindBar",
14
14
  setup(l) {
15
- let E = e("InkFindBar"), { state: D, setQuery: O, setMatchCase: k, next: A, previous: j, close: M } = t(), N = i(() => E.viewportEl.value?.parentElement ?? null), P = h("bar"), F = h("field"), I = h("live"), L = i(() => v(D.value));
16
- g([() => E.search.value, I], ([e, t], n, r) => {
15
+ let k = e("InkFindBar"), { state: A, setQuery: j, setMatchCase: M, next: N, previous: P, close: F } = t(), I = i(() => k.viewportEl.value?.parentElement ?? null), L = h("bar"), R = h("field"), z = h("live"), B = i(() => v(A.value));
16
+ g([() => k.search.value, z], ([e, t], n, r) => {
17
17
  if (!e || !t) return;
18
18
  let i = _(), a = (e) => {
19
19
  let n = i(e);
@@ -24,110 +24,110 @@ var C = ["hidden"], w = {
24
24
  flush: "post",
25
25
  immediate: !0
26
26
  });
27
- function R(e) {
28
- e.key !== "Enter" || e.isComposing || (e.preventDefault(), e.shiftKey ? j() : A());
27
+ function V(e) {
28
+ e.key !== "Enter" || e.isComposing || (e.preventDefault(), e.shiftKey ? P() : N());
29
29
  }
30
- function z(e) {
31
- e.key !== "Escape" || e.defaultPrevented || e.isComposing || (e.preventDefault(), e.stopPropagation(), M());
30
+ function H(e) {
31
+ e.key !== "Escape" || e.defaultPrevented || e.isComposing || (e.preventDefault(), e.stopPropagation(), F());
32
32
  }
33
- let B = null, V = !1;
34
- function H() {
35
- let e = P.value, t = E.viewportEl.value, n = B?.isConnected && !e?.contains(B) ? B : t;
36
- B = null, n?.focus({ preventScroll: !0 });
33
+ let U = null, W = !1;
34
+ function G() {
35
+ let e = L.value, t = k.viewportEl.value, n = U?.isConnected && !e?.contains(U) ? U : t;
36
+ U = null, n?.focus({ preventScroll: !0 });
37
37
  }
38
- function U(e) {
39
- let t = P.value, n = F.value;
38
+ function K(e) {
39
+ let t = L.value, n = R.value;
40
40
  if (t && n) {
41
- if (e.open !== V) {
42
- V = e.open;
41
+ if (e.open !== W) {
42
+ W = e.open;
43
43
  let r = t.ownerDocument;
44
44
  if (e.open) {
45
45
  let e = r.activeElement;
46
- B = e instanceof HTMLElement && e !== r.body && !t.contains(e) ? e : null, n.focus(), n.select();
47
- } else t.contains(r.activeElement) || r.activeElement === r.body ? H() : B = null;
46
+ U = e instanceof HTMLElement && e !== r.body && !t.contains(e) ? e : null, n.focus(), n.select();
47
+ } else t.contains(r.activeElement) || r.activeElement === r.body ? G() : U = null;
48
48
  }
49
49
  n.value !== e.query && (n.value = e.query, t.ownerDocument.activeElement === n && n.select());
50
50
  }
51
51
  }
52
52
  g([
53
- D,
54
- P,
55
- F
56
- ], ([e]) => U(e), {
53
+ A,
54
+ L,
55
+ R
56
+ ], ([e]) => K(e), {
57
57
  flush: "post",
58
58
  immediate: !0
59
59
  });
60
- let W = null;
61
- return g([() => E.search.value, P], ([e, t]) => {
62
- W?.(), W = e && t ? e.attachBar() : null;
60
+ let q = null;
61
+ return g([() => k.search.value, L], ([e, t]) => {
62
+ q?.(), q = e && t ? e.attachBar() : null;
63
63
  }, {
64
64
  flush: "post",
65
65
  immediate: !0
66
66
  }), d(() => {
67
- W?.(), W = null;
68
- }), (e, t) => N.value ? (f(), a(r, {
67
+ q?.(), q = null;
68
+ }), (e, t) => I.value ? (f(), a(r, {
69
69
  key: 0,
70
- to: N.value
70
+ to: I.value
71
71
  }, [s("div", u(e.$attrs, {
72
72
  ref_key: "bar",
73
- ref: P,
73
+ ref: L,
74
74
  class: "ink-find-bar",
75
75
  "data-ink-find-bar": "",
76
76
  role: "search",
77
- hidden: !m(D).open,
78
- onKeydown: z
77
+ hidden: !m(A).open,
78
+ onKeydown: H
79
79
  }), [
80
- s("input", {
80
+ s("div", T, [s("span", E, [c(n, { icon: m(S) }, null, 8, ["icon"])]), s("input", {
81
81
  ref_key: "field",
82
- ref: F,
82
+ ref: R,
83
83
  type: "text",
84
84
  "aria-label": "Find in document",
85
85
  autocomplete: "off",
86
86
  spellcheck: "false",
87
- onInput: t[0] ||= (e) => m(O)(e.target.value),
88
- onKeydown: R
89
- }, null, 544),
90
- s("span", w, p(L.value), 1),
87
+ onInput: t[0] ||= (e) => m(j)(e.target.value),
88
+ onKeydown: V
89
+ }, null, 544)]),
90
+ s("span", D, p(B.value), 1),
91
91
  s("button", {
92
92
  type: "button",
93
93
  "data-ink-find-previous": "",
94
94
  "aria-label": "Previous match",
95
95
  title: "Previous match",
96
- onClick: t[1] ||= (e) => m(j)()
96
+ onClick: t[1] ||= (e) => m(P)()
97
97
  }, [c(n, { icon: m(x) }, null, 8, ["icon"])]),
98
98
  s("button", {
99
99
  type: "button",
100
100
  "data-ink-find-next": "",
101
101
  "aria-label": "Next match",
102
102
  title: "Next match",
103
- onClick: t[2] ||= (e) => m(A)()
103
+ onClick: t[2] ||= (e) => m(N)()
104
104
  }, [c(n, { icon: m(b) }, null, 8, ["icon"])]),
105
105
  s("button", {
106
106
  type: "button",
107
107
  "data-ink-find-match-case": "",
108
108
  "aria-label": "Match case",
109
109
  title: "Match case",
110
- "aria-pressed": m(D).matchCase,
111
- onClick: t[3] ||= (e) => m(k)(!m(D).matchCase)
112
- }, [c(n, { icon: m(y) }, null, 8, ["icon"])], 8, T),
110
+ "aria-pressed": m(A).matchCase,
111
+ onClick: t[3] ||= (e) => m(M)(!m(A).matchCase)
112
+ }, [c(n, { icon: m(y) }, null, 8, ["icon"])], 8, O),
113
113
  s("button", {
114
114
  type: "button",
115
115
  "data-ink-find-close": "",
116
116
  "aria-label": "Close find",
117
117
  title: "Close find",
118
- onClick: t[4] ||= (e) => m(M)()
119
- }, [c(n, { icon: m(S) }, null, 8, ["icon"])]),
118
+ onClick: t[4] ||= (e) => m(F)()
119
+ }, [c(n, { icon: m(C) }, null, 8, ["icon"])]),
120
120
  s("div", {
121
121
  ref_key: "live",
122
- ref: I,
122
+ ref: z,
123
123
  class: "ink-visually-hidden",
124
124
  "data-ink-find-status": "",
125
125
  "aria-live": "polite"
126
126
  }, null, 512)
127
- ], 16, C)], 8, ["to"])) : o("", !0);
127
+ ], 16, w)], 8, ["to"])) : o("", !0);
128
128
  }
129
129
  });
130
130
  //#endregion
131
- export { E as default };
131
+ export { k as default };
132
132
 
133
133
  //# sourceMappingURL=InkFindBar.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InkFindBar.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_openBlock","_createBlock","_Teleport","_createElementVNode","_mergeProps","_unref","_toDisplayString","_createVNode","InkIcon","_createCommentVNode","InkIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","InkFindBar_vue_vue_type_script_setup_true_lang_default","ctx","useInkContext","useSearch","target","computed","bar","useTemplateRef","field","live","count","findCountText","state","controller","el","announce","findAnnouncer","say","text","s","onCleanup","onFieldKeydown","previous","next","onBarKeydown","close","before","wasOpen","restoreFocus","scroll","to","show","input","doc","active","detach","watch","onBeforeUnmount","openBlock","createBlock","Teleport","createElementVNode","mergeProps","_ctx","unref","_cache","setQuery","$event","toDisplayString","createVNode","ChevronUp","ChevronDown","setMatchCase","CaseSensitive","X","createCommentVNode"],"sources":["../../src/components/InkFindBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * The find bar: a field, the match count, previous and next, a match-case toggle and close,\n * a view of the root's search state. Place it anywhere inside `InkRoot`: it teleports itself\n * into `[data-ink-viewport-root]`, the positioned ancestor the theme floats it from over the\n * top-right of the pages (as `InkThreadPopover` anchors to the root's overlay rather than\n * where it is written). It is hidden while the search is closed. While it is mounted it\n * registers with the search controller, which is what lets Ctrl/Cmd+F open it.\n *\n * Enter in the field steps to the next match, Shift+Enter to the previous, Escape closes.\n * Closing returns focus to where it was before the bar opened, else to the document.\n */\nimport { findAnnouncer, findCountText } from '@inkbar/core/dom'\nimport { CaseSensitive, ChevronDown, ChevronUp, X } from '@inkbar/icons'\nimport { computed, onBeforeUnmount, useTemplateRef, watch } from 'vue'\n\nimport { useSearch } from '../composables/useSearch'\nimport { useInkContext } from '../context'\n\nimport InkIcon from './InkIcon.vue'\n\nimport type { SearchState } from '@inkbar/core/dom'\n\n// The root is a Teleport, so attributes such as `class` are bound to the bar itself.\ndefineOptions({ inheritAttrs: false })\n\nconst ctx = useInkContext('InkFindBar')\nconst { state, setQuery, setMatchCase, next, previous, close } = useSearch()\n\n/** The viewport root: the scroll element's parent, once InkViewport has mounted. */\nconst target = computed(() => ctx.viewportEl.value?.parentElement ?? null)\nconst bar = useTemplateRef<HTMLElement>('bar')\nconst field = useTemplateRef<HTMLInputElement>('field')\nconst live = useTemplateRef<HTMLElement>('live')\n\nconst count = computed(() => findCountText(state.value))\n\n// The live region follows the controller's state change by change, as the vanilla bar does,\n// and is written directly. A render shows only the last of the changes since the one before,\n// so two steps in one tick that end where they began would otherwise say nothing.\nwatch(\n [() => ctx.search.value, live],\n ([controller, el], _, onCleanup) => {\n if (!controller || !el) return\n const announce = findAnnouncer()\n const say = (s: SearchState): void => {\n const text = announce(s)\n if (el.textContent !== text) el.textContent = text\n }\n say(controller.state.get())\n onCleanup(controller.state.subscribe(say))\n },\n { flush: 'post', immediate: true }\n)\n\nfunction onFieldKeydown(e: KeyboardEvent): void {\n if (e.key !== 'Enter' || e.isComposing) return\n e.preventDefault()\n if (e.shiftKey) previous()\n else next()\n}\nfunction onBarKeydown(e: KeyboardEvent): void {\n if (e.key !== 'Escape' || e.defaultPrevented || e.isComposing) return\n e.preventDefault()\n e.stopPropagation()\n close()\n}\n\n/** Where focus was when the bar opened. */\nlet before: HTMLElement | null = null\nlet wasOpen = false\n\nfunction restoreFocus(): void {\n const el = bar.value\n const scroll = ctx.viewportEl.value\n const to = before?.isConnected && !el?.contains(before) ? before : scroll\n before = null\n to?.focus({ preventScroll: true })\n}\n\nfunction show(s: SearchState): void {\n const el = bar.value\n const input = field.value\n if (!el || !input) return\n if (s.open !== wasOpen) {\n wasOpen = s.open\n const doc = el.ownerDocument\n if (s.open) {\n const active = doc.activeElement\n before =\n active instanceof HTMLElement && active !== doc.body && !el.contains(active)\n ? active\n : null\n input.focus()\n input.select()\n } else {\n // Focus inside the bar is about to be lost with it; focus elsewhere is left alone.\n const hadFocus = el.contains(doc.activeElement) || doc.activeElement === doc.body\n if (hadFocus) restoreFocus()\n else before = null\n }\n }\n if (input.value !== s.query) {\n input.value = s.query\n // A query set from code arrives after the bar opened: keep the new text selected.\n if (el.ownerDocument.activeElement === input) input.select()\n }\n}\n\n// After the render, so the bar is shown (and can take focus) when it opens, and the field is\n// updated once it exists.\nwatch([state, bar, field], ([s]) => show(s), { flush: 'post', immediate: true })\n\n// Registered while mounted.\nlet detach: (() => void) | null = null\nwatch(\n [() => ctx.search.value, bar],\n ([controller, el]) => {\n detach?.()\n detach = controller && el ? controller.attachBar() : null\n },\n { flush: 'post', immediate: true }\n)\nonBeforeUnmount(() => {\n detach?.()\n detach = null\n})\n</script>\n\n<template>\n <Teleport v-if=\"target\" :to=\"target\">\n <div\n v-bind=\"$attrs\"\n ref=\"bar\"\n class=\"ink-find-bar\"\n data-ink-find-bar\n role=\"search\"\n :hidden=\"!state.open\"\n @keydown=\"onBarKeydown\"\n >\n <input\n ref=\"field\"\n type=\"text\"\n aria-label=\"Find in document\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n @input=\"setQuery(($event.target as HTMLInputElement).value)\"\n @keydown=\"onFieldKeydown\"\n />\n <span class=\"ink-find-count\" data-ink-find-count>{{ count }}</span>\n <button\n type=\"button\"\n data-ink-find-previous\n aria-label=\"Previous match\"\n title=\"Previous match\"\n @click=\"previous()\"\n >\n <InkIcon :icon=\"ChevronUp\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-next\n aria-label=\"Next match\"\n title=\"Next match\"\n @click=\"next()\"\n >\n <InkIcon :icon=\"ChevronDown\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-match-case\n aria-label=\"Match case\"\n title=\"Match case\"\n :aria-pressed=\"state.matchCase\"\n @click=\"setMatchCase(!state.matchCase)\"\n >\n <InkIcon :icon=\"CaseSensitive\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-close\n aria-label=\"Close find\"\n title=\"Close find\"\n @click=\"close()\"\n >\n <InkIcon :icon=\"X\" />\n </button>\n <div\n ref=\"live\"\n class=\"ink-visually-hidden\"\n data-ink-find-status\n aria-live=\"polite\"\n />\n </div>\n </Teleport>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"InkFindBar.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_openBlock","_createBlock","_Teleport","_createElementVNode","_mergeProps","_unref","_createVNode","InkIcon","_toDisplayString","_createCommentVNode","InkIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","InkFindBar_vue_vue_type_script_setup_true_lang_default","ctx","useInkContext","useSearch","target","computed","bar","useTemplateRef","field","live","count","findCountText","state","controller","el","announce","findAnnouncer","say","text","s","onCleanup","onFieldKeydown","previous","next","onBarKeydown","close","before","wasOpen","restoreFocus","scroll","to","show","input","doc","active","detach","watch","onBeforeUnmount","openBlock","createBlock","Teleport","createElementVNode","mergeProps","_ctx","unref","createVNode","Search","_cache","setQuery","$event","toDisplayString","ChevronUp","ChevronDown","setMatchCase","CaseSensitive","X","createCommentVNode"],"sources":["../../src/components/InkFindBar.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * The find bar: a field, the match count, previous and next, a match-case toggle and close,\n * a view of the root's search state. Place it anywhere inside `InkRoot`: it teleports itself\n * into `[data-ink-viewport-root]`, the positioned ancestor the theme floats it from over the\n * top-right of the pages (as `InkThreadPopover` anchors to the root's overlay rather than\n * where it is written). It is hidden while the search is closed. While it is mounted it\n * registers with the search controller, which is what lets Ctrl/Cmd+F open it.\n *\n * Enter in the field steps to the next match, Shift+Enter to the previous, Escape closes.\n * Closing returns focus to where it was before the bar opened, else to the document.\n */\nimport { findAnnouncer, findCountText } from '@inkbar/core/dom'\nimport { CaseSensitive, ChevronDown, ChevronUp, Search, X } from '@inkbar/icons'\nimport { computed, onBeforeUnmount, useTemplateRef, watch } from 'vue'\n\nimport { useSearch } from '../composables/useSearch'\nimport { useInkContext } from '../context'\n\nimport InkIcon from './InkIcon.vue'\n\nimport type { SearchState } from '@inkbar/core/dom'\n\n// The root is a Teleport, so attributes such as `class` are bound to the bar itself.\ndefineOptions({ inheritAttrs: false })\n\nconst ctx = useInkContext('InkFindBar')\nconst { state, setQuery, setMatchCase, next, previous, close } = useSearch()\n\n/** The viewport root: the scroll element's parent, once InkViewport has mounted. */\nconst target = computed(() => ctx.viewportEl.value?.parentElement ?? null)\nconst bar = useTemplateRef<HTMLElement>('bar')\nconst field = useTemplateRef<HTMLInputElement>('field')\nconst live = useTemplateRef<HTMLElement>('live')\n\nconst count = computed(() => findCountText(state.value))\n\n// The live region follows the controller's state change by change, as the vanilla bar does,\n// and is written directly. A render shows only the last of the changes since the one before,\n// so two steps in one tick that end where they began would otherwise say nothing.\nwatch(\n [() => ctx.search.value, live],\n ([controller, el], _, onCleanup) => {\n if (!controller || !el) return\n const announce = findAnnouncer()\n const say = (s: SearchState): void => {\n const text = announce(s)\n if (el.textContent !== text) el.textContent = text\n }\n say(controller.state.get())\n onCleanup(controller.state.subscribe(say))\n },\n { flush: 'post', immediate: true }\n)\n\nfunction onFieldKeydown(e: KeyboardEvent): void {\n if (e.key !== 'Enter' || e.isComposing) return\n e.preventDefault()\n if (e.shiftKey) previous()\n else next()\n}\nfunction onBarKeydown(e: KeyboardEvent): void {\n if (e.key !== 'Escape' || e.defaultPrevented || e.isComposing) return\n e.preventDefault()\n e.stopPropagation()\n close()\n}\n\n/** Where focus was when the bar opened. */\nlet before: HTMLElement | null = null\nlet wasOpen = false\n\nfunction restoreFocus(): void {\n const el = bar.value\n const scroll = ctx.viewportEl.value\n const to = before?.isConnected && !el?.contains(before) ? before : scroll\n before = null\n to?.focus({ preventScroll: true })\n}\n\nfunction show(s: SearchState): void {\n const el = bar.value\n const input = field.value\n if (!el || !input) return\n if (s.open !== wasOpen) {\n wasOpen = s.open\n const doc = el.ownerDocument\n if (s.open) {\n const active = doc.activeElement\n before =\n active instanceof HTMLElement && active !== doc.body && !el.contains(active)\n ? active\n : null\n input.focus()\n input.select()\n } else {\n // Focus inside the bar is about to be lost with it; focus elsewhere is left alone.\n const hadFocus = el.contains(doc.activeElement) || doc.activeElement === doc.body\n if (hadFocus) restoreFocus()\n else before = null\n }\n }\n if (input.value !== s.query) {\n input.value = s.query\n // A query set from code arrives after the bar opened: keep the new text selected.\n if (el.ownerDocument.activeElement === input) input.select()\n }\n}\n\n// After the render, so the bar is shown (and can take focus) when it opens, and the field is\n// updated once it exists.\nwatch([state, bar, field], ([s]) => show(s), { flush: 'post', immediate: true })\n\n// Registered while mounted.\nlet detach: (() => void) | null = null\nwatch(\n [() => ctx.search.value, bar],\n ([controller, el]) => {\n detach?.()\n detach = controller && el ? controller.attachBar() : null\n },\n { flush: 'post', immediate: true }\n)\nonBeforeUnmount(() => {\n detach?.()\n detach = null\n})\n</script>\n\n<template>\n <Teleport v-if=\"target\" :to=\"target\">\n <div\n v-bind=\"$attrs\"\n ref=\"bar\"\n class=\"ink-find-bar\"\n data-ink-find-bar\n role=\"search\"\n :hidden=\"!state.open\"\n @keydown=\"onBarKeydown\"\n >\n <div class=\"ink-input-group\">\n <span class=\"ink-input-accessory\"><InkIcon :icon=\"Search\" /></span>\n <input\n ref=\"field\"\n type=\"text\"\n aria-label=\"Find in document\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n @input=\"setQuery(($event.target as HTMLInputElement).value)\"\n @keydown=\"onFieldKeydown\"\n />\n </div>\n <span class=\"ink-find-count\" data-ink-find-count>{{ count }}</span>\n <button\n type=\"button\"\n data-ink-find-previous\n aria-label=\"Previous match\"\n title=\"Previous match\"\n @click=\"previous()\"\n >\n <InkIcon :icon=\"ChevronUp\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-next\n aria-label=\"Next match\"\n title=\"Next match\"\n @click=\"next()\"\n >\n <InkIcon :icon=\"ChevronDown\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-match-case\n aria-label=\"Match case\"\n title=\"Match case\"\n :aria-pressed=\"state.matchCase\"\n @click=\"setMatchCase(!state.matchCase)\"\n >\n <InkIcon :icon=\"CaseSensitive\" />\n </button>\n <button\n type=\"button\"\n data-ink-find-close\n aria-label=\"Close find\"\n title=\"Close find\"\n @click=\"close()\"\n >\n <InkIcon :icon=\"X\" />\n </button>\n <div\n ref=\"live\"\n class=\"ink-visually-hidden\"\n data-ink-find-status\n aria-live=\"polite\"\n />\n </div>\n </Teleport>\n</template>\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import e from "./InkPanel.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/components/InkPanel.vue
3
+ var t = e;
4
+ //#endregion
5
+ export { t as default };
6
+
7
+ //# sourceMappingURL=InkPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkPanel.js","names":["_sfc_main","InkPanel_vue_vue_type_script_setup_true_lang_default","InkPanel_default"],"sources":["../../src/components/InkPanel.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * One panel of an `InkSidebar`, holding your content in its default slot. `id` names it in\n * `v-model:open`, `label` names its trigger, `icon` (an `@inkbar/icons` node) shows on the rail,\n * and `badge` (a count or short text) shows beside it, hidden when empty or 0. Closed, the panel\n * stays mounted and hidden. In a stack it renders its own header above its content.\n */\nimport { computed, onBeforeUnmount, onMounted, useTemplateRef } from 'vue'\n\nimport { injectSidebarContext } from './sidebar-context'\nimport SidebarTrigger from './SidebarTrigger.vue'\n\nimport type { SidebarPanelInfo } from '@inkbar/core/dom'\nimport type { IconNode } from '@inkbar/icons'\n\nconst props = defineProps<{\n id: string\n label: string\n icon?: IconNode | undefined\n badge?: string | number | undefined\n}>()\n\nconst ctx = injectSidebarContext()\nconst wrapper = useTemplateRef<HTMLElement>('wrapper')\n\nconst info = (): SidebarPanelInfo => ({\n id: props.id,\n label: props.label,\n ...(props.icon !== undefined && { icon: props.icon }),\n ...(props.badge !== undefined && { badge: props.badge }),\n})\n// Registered now, so the server renders this panel's attributes; ordered once in the DOM.\nconst unregister = ctx.register({ info, element: () => wrapper.value })\nonMounted(() => ctx.arrange())\nonBeforeUnmount(unregister)\n\nconst view = computed(() => {\n const s = ctx.state.value\n return {\n stack: s.layout === 'stack',\n trigger: ctx.controller.triggerAttrs(props.id),\n panel: ctx.controller.panelAttrs(props.id),\n }\n})\n</script>\n\n<template>\n <!-- A section in a stack; in rail and tabs the theme leaves the layout to the panel. Kept in\n every layout, so the content is never remounted. -->\n <div ref=\"wrapper\" :class=\"['ink-sidebar-slot', { 'ink-sidebar-section': view.stack }]\">\n <button v-if=\"view.stack\" class=\"ink-sidebar-header\" v-bind=\"view.trigger\">\n <SidebarTrigger :panel=\"info()\" :rail=\"false\" />\n </button>\n <div class=\"ink-sidebar-panel\" v-bind=\"view.panel\">\n <!-- The rail button names the panel for assistive technology; this repeats it on screen. -->\n <div class=\"ink-sidebar-panel-title\" aria-hidden=\"true\">{{ label }}</div>\n <div class=\"ink-sidebar-panel-body\"><slot /></div>\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { IconNode } from '@inkbar/icons';
2
+ type __VLS_Props = {
3
+ id: string;
4
+ label: string;
5
+ icon?: IconNode | undefined;
6
+ badge?: string | number | undefined;
7
+ };
8
+ declare var __VLS_6: {};
9
+ type __VLS_Slots = {} & {
10
+ default?: (props: typeof __VLS_6) => any;
11
+ };
12
+ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
13
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ type __VLS_WithSlots<T, S> = T & {
17
+ new (): {
18
+ $slots: S;
19
+ };
20
+ };
21
+ //# sourceMappingURL=InkPanel.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkPanel.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkPanel.vue"],"names":[],"mappings":"AA0EA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAG7C,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CACpC,CAAC;AAiFF,QAAA,IAAI,OAAO,IAAW,CAAC;AACvB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAG/C,QAAA,MAAM,UAAU,kSAEd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AACzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { injectSidebarContext as e } from "./sidebar-context.js";
2
+ import t from "./SidebarTrigger.js";
3
+ import { computed as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createVNode as o, defineComponent as s, mergeProps as c, normalizeClass as l, onBeforeUnmount as u, onMounted as d, openBlock as f, renderSlot as p, toDisplayString as m, useTemplateRef as h } from "vue";
4
+ //#region src/components/InkPanel.vue?vue&type=script&setup=true&lang.ts
5
+ var g = {
6
+ class: "ink-sidebar-panel-title",
7
+ "aria-hidden": "true"
8
+ }, _ = { class: "ink-sidebar-panel-body" }, v = /*@__PURE__*/ s({
9
+ __name: "InkPanel",
10
+ props: {
11
+ id: {},
12
+ label: {},
13
+ icon: {},
14
+ badge: {}
15
+ },
16
+ setup(s) {
17
+ let v = s, y = e(), b = h("wrapper"), x = () => ({
18
+ id: v.id,
19
+ label: v.label,
20
+ ...v.icon !== void 0 && { icon: v.icon },
21
+ ...v.badge !== void 0 && { badge: v.badge }
22
+ }), S = y.register({
23
+ info: x,
24
+ element: () => b.value
25
+ });
26
+ d(() => y.arrange()), u(S);
27
+ let C = n(() => ({
28
+ stack: y.state.value.layout === "stack",
29
+ trigger: y.controller.triggerAttrs(v.id),
30
+ panel: y.controller.panelAttrs(v.id)
31
+ }));
32
+ return (e, n) => (f(), i("div", {
33
+ ref_key: "wrapper",
34
+ ref: b,
35
+ class: l(["ink-sidebar-slot", { "ink-sidebar-section": C.value.stack }])
36
+ }, [C.value.stack ? (f(), i("button", c({
37
+ key: 0,
38
+ class: "ink-sidebar-header"
39
+ }, C.value.trigger), [o(t, {
40
+ panel: x(),
41
+ rail: !1
42
+ }, null, 8, ["panel"])], 16)) : r("", !0), a("div", c({ class: "ink-sidebar-panel" }, C.value.panel), [a("div", g, m(s.label), 1), a("div", _, [p(e.$slots, "default")])], 16)], 2));
43
+ }
44
+ });
45
+ //#endregion
46
+ export { v as default };
47
+
48
+ //# sourceMappingURL=InkPanel.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkPanel.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_mergeProps","_createVNode","SidebarTrigger","_createCommentVNode","_createElementVNode","_toDisplayString","_renderSlot","SidebarTrigger_default","_hoisted_1","_hoisted_2","InkPanel_vue_vue_type_script_setup_true_lang_default","props","__props","ctx","injectSidebarContext","wrapper","useTemplateRef","info","unregister","onMounted","onBeforeUnmount","view","computed","openBlock","createElementBlock","normalizeClass","mergeProps","createVNode","createCommentVNode","createElementVNode","toDisplayString","renderSlot","_ctx"],"sources":["../../src/components/InkPanel.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * One panel of an `InkSidebar`, holding your content in its default slot. `id` names it in\n * `v-model:open`, `label` names its trigger, `icon` (an `@inkbar/icons` node) shows on the rail,\n * and `badge` (a count or short text) shows beside it, hidden when empty or 0. Closed, the panel\n * stays mounted and hidden. In a stack it renders its own header above its content.\n */\nimport { computed, onBeforeUnmount, onMounted, useTemplateRef } from 'vue'\n\nimport { injectSidebarContext } from './sidebar-context'\nimport SidebarTrigger from './SidebarTrigger.vue'\n\nimport type { SidebarPanelInfo } from '@inkbar/core/dom'\nimport type { IconNode } from '@inkbar/icons'\n\nconst props = defineProps<{\n id: string\n label: string\n icon?: IconNode | undefined\n badge?: string | number | undefined\n}>()\n\nconst ctx = injectSidebarContext()\nconst wrapper = useTemplateRef<HTMLElement>('wrapper')\n\nconst info = (): SidebarPanelInfo => ({\n id: props.id,\n label: props.label,\n ...(props.icon !== undefined && { icon: props.icon }),\n ...(props.badge !== undefined && { badge: props.badge }),\n})\n// Registered now, so the server renders this panel's attributes; ordered once in the DOM.\nconst unregister = ctx.register({ info, element: () => wrapper.value })\nonMounted(() => ctx.arrange())\nonBeforeUnmount(unregister)\n\nconst view = computed(() => {\n const s = ctx.state.value\n return {\n stack: s.layout === 'stack',\n trigger: ctx.controller.triggerAttrs(props.id),\n panel: ctx.controller.panelAttrs(props.id),\n }\n})\n</script>\n\n<template>\n <!-- A section in a stack; in rail and tabs the theme leaves the layout to the panel. Kept in\n every layout, so the content is never remounted. -->\n <div ref=\"wrapper\" :class=\"['ink-sidebar-slot', { 'ink-sidebar-section': view.stack }]\">\n <button v-if=\"view.stack\" class=\"ink-sidebar-header\" v-bind=\"view.trigger\">\n <SidebarTrigger :panel=\"info()\" :rail=\"false\" />\n </button>\n <div class=\"ink-sidebar-panel\" v-bind=\"view.panel\">\n <!-- The rail button names the panel for assistive technology; this repeats it on screen. -->\n <div class=\"ink-sidebar-panel-title\" aria-hidden=\"true\">{{ label }}</div>\n <div class=\"ink-sidebar-panel-body\"><slot /></div>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;EAeA,IAAMc,IAAQC,GAORC,IAAMC,EAAqB,GAC3BC,IAAUC,EAA4B,SAAS,GAE/CC,WAAgC;GACpC,IAAIN,EAAM;GACV,OAAOA,EAAM;GACb,GAAIA,EAAM,SAAS,KAAA,KAAa,EAAE,MAAMA,EAAM,KAAK;GACnD,GAAIA,EAAM,UAAU,KAAA,KAAa,EAAE,OAAOA,EAAM,MAAM;EACxD,IAEMO,IAAaL,EAAI,SAAS;GAAE;GAAM,eAAeE,EAAQ;EAAM,CAAC;EAEtE,AADAI,QAAgBN,EAAI,QAAQ,CAAC,GAC7BO,EAAgBF,CAAU;EAE1B,IAAMG,IAAOC,SAEJ;GACL,OAFQT,EAAI,MAAM,MAET,WAAW;GACpB,SAASA,EAAI,WAAW,aAAaF,EAAM,EAAE;GAC7C,OAAOE,EAAI,WAAW,WAAWF,EAAM,EAAE;EAC3C,EACD;oBAMCd,EAAA,GAAAC,EASM,OAAA;GATG,SAAA;GAAJ,KAAIiB;GAAW,OAAKhB,EAAA,CAAA,oBAAA,EAAA,uBAAgDsB,EAAA,MAAK,MAAK,CAAA,CAAA;EACnE,GAAA,CAAAA,EAAA,MAAK,SAAnBxB,EAAA,GAAAC,EAES,UAFTE,EAES;;GAFiB,OAAM;EAA6B,GAAAqB,EAAA,MAAK,OAAO,GAAA,CACvEpB,EAAgDC,GAAA;GAA/B,OAAOe,EAAI;GAAK,MAAM;EAEzCb,GAAAA,MAAAA,GAAAA,CAAAA,OAAAA,CAAAA,CAAAA,GAAAA,EAAAA,KAAAA,EAAAA,IAAAA,EAAAA,GAAAA,EAIM,OAJNJ,EAIM,EAJD,OAAM,oBAAmB,GAASqB,EAAA,MAAK,KAAK,GAAA,CAE/CjB,EAAyE,OAAzEI,GAAyEH,EAAdO,EAAA,KAAK,GAAA,CAAA,GAChER,EAAkD,OAAlDK,GAAkD,CAAdH,EAAQ0B,EAAA,QAAA,SAAA,CAAA,CAAA,CAAA,GAAA,EAAA,CAAA,GAAA,CAAA"}
@@ -0,0 +1,7 @@
1
+ import e from "./InkPrintButton.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/components/InkPrintButton.vue
3
+ var t = e;
4
+ //#endregion
5
+ export { t as default };
6
+
7
+ //# sourceMappingURL=InkPrintButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkPrintButton.js","names":["_sfc_main","InkPrintButton_vue_vue_type_script_setup_true_lang_default","InkPrintButton_default"],"sources":["../../src/components/InkPrintButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * Prints the open document's file with the browser's own PDF viewer (on iOS, in a new\n * tab). Disabled until the document is ready. Today that is the file as it was\n * opened, without this session's annotations.\n */\nimport { printDocument } from '@inkbar/core/dom'\nimport { Printer } from '@inkbar/icons'\nimport { ToolbarButton } from 'reka-ui'\nimport { computed } from 'vue'\n\nimport { useInkContext } from '../context'\n\nimport InkIcon from './InkIcon.vue'\n\nwithDefaults(defineProps<{ asChild?: boolean }>(), {\n asChild: false,\n})\nconst ctx = useInkContext('InkPrintButton')\nconst ready = computed(\n () => ctx.document.value !== null && ctx.status.value.state === 'ready'\n)\n\nfunction run(): void {\n const doc = ctx.document.value\n if (doc) void printDocument(doc).catch(() => undefined)\n}\n// Reka's typed props stop at its own; ARIA and listeners go through a bound object.\nconst attrs = { 'aria-label': 'Print', title: 'Print', onClick: run }\n</script>\n\n<template>\n <ToolbarButton\n :as-child=\"asChild\"\n :disabled=\"!ready\"\n class=\"ink-print\"\n data-ink-print\n v-bind=\"attrs\"\n >\n <slot><InkIcon :icon=\"Printer\" /></slot>\n </ToolbarButton>\n</template>\n"],"mappings":""}
@@ -0,0 +1,19 @@
1
+ type __VLS_Props = {
2
+ asChild?: boolean;
3
+ };
4
+ declare var __VLS_7: {};
5
+ type __VLS_Slots = {} & {
6
+ default?: (props: typeof __VLS_7) => any;
7
+ };
8
+ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
9
+ asChild: boolean;
10
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
11
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
14
+ type __VLS_WithSlots<T, S> = T & {
15
+ new (): {
16
+ $slots: S;
17
+ };
18
+ };
19
+ //# sourceMappingURL=InkPrintButton.vue.d.ts.map