@inkbar/vue 0.4.0 → 0.6.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 (73) hide show
  1. package/README.md +23 -7
  2. package/dist/components/InkAnnotation.js.map +1 -1
  3. package/dist/components/InkAnnotation.vue.d.ts.map +1 -1
  4. package/dist/components/InkAnnotation.vue_vue_type_script_setup_true_lang.js +16 -24
  5. package/dist/components/InkAnnotation.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/components/InkColorMenu.js.map +1 -1
  7. package/dist/components/InkColorMenu.vue.d.ts +2 -0
  8. package/dist/components/InkColorMenu.vue.d.ts.map +1 -1
  9. package/dist/components/InkColorMenu.vue_vue_type_script_setup_true_lang.js +3 -2
  10. package/dist/components/InkColorMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/components/InkCommand.js +7 -0
  12. package/dist/components/InkCommand.js.map +1 -0
  13. package/dist/components/InkCommand.vue.d.ts +23 -0
  14. package/dist/components/InkCommand.vue.d.ts.map +1 -0
  15. package/dist/components/InkCommand.vue_vue_type_script_setup_true_lang.js +51 -0
  16. package/dist/components/InkCommand.vue_vue_type_script_setup_true_lang.js.map +1 -0
  17. package/dist/components/InkHighlightMenu.js.map +1 -1
  18. package/dist/components/InkHighlightMenu.vue.d.ts +2 -2
  19. package/dist/components/InkHighlightMenu.vue.d.ts.map +1 -1
  20. package/dist/components/InkHighlightMenu.vue_vue_type_script_setup_true_lang.js +118 -108
  21. package/dist/components/InkHighlightMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/InkPageInput.js.map +1 -1
  23. package/dist/components/InkPageInput.vue.d.ts.map +1 -1
  24. package/dist/components/InkPageInput.vue_vue_type_script_setup_true_lang.js +1 -1
  25. package/dist/components/InkPageInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/InkRoot.js.map +1 -1
  27. package/dist/components/InkRoot.vue.d.ts +415 -424
  28. package/dist/components/InkRoot.vue.d.ts.map +1 -1
  29. package/dist/components/InkRoot.vue_vue_type_script_setup_true_lang.js +145 -102
  30. package/dist/components/InkRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  31. package/dist/components/InkShapeMenu.js.map +1 -1
  32. package/dist/components/InkShapeMenu.vue.d.ts +2 -2
  33. package/dist/components/InkShapeMenu.vue.d.ts.map +1 -1
  34. package/dist/components/InkShapeMenu.vue_vue_type_script_setup_true_lang.js +99 -91
  35. package/dist/components/InkShapeMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  36. package/dist/components/InkSignatureMenu.js.map +1 -1
  37. package/dist/components/InkSignatureMenu.vue.d.ts +2 -2
  38. package/dist/components/InkSignatureMenu.vue.d.ts.map +1 -1
  39. package/dist/components/InkSignatureMenu.vue_vue_type_script_setup_true_lang.js +156 -151
  40. package/dist/components/InkSignatureMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/InkToolButton.js.map +1 -1
  42. package/dist/components/InkToolButton.vue.d.ts.map +1 -1
  43. package/dist/components/InkToolButton.vue_vue_type_script_setup_true_lang.js +36 -35
  44. package/dist/components/InkToolButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/InkViewport.js.map +1 -1
  46. package/dist/components/InkViewport.vue.d.ts.map +1 -1
  47. package/dist/components/InkViewport.vue_vue_type_script_setup_true_lang.js +14 -4
  48. package/dist/components/InkViewport.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/composables/useAnnotations.d.ts +915 -1386
  50. package/dist/composables/useAnnotations.d.ts.map +1 -1
  51. package/dist/composables/useAnnotations.js +13 -18
  52. package/dist/composables/useAnnotations.js.map +1 -1
  53. package/dist/composables/useCommand.d.ts +23 -0
  54. package/dist/composables/useCommand.d.ts.map +1 -0
  55. package/dist/composables/useCommand.js +22 -0
  56. package/dist/composables/useCommand.js.map +1 -0
  57. package/dist/context.d.ts +22 -4
  58. package/dist/context.d.ts.map +1 -1
  59. package/dist/context.js.map +1 -1
  60. package/dist/index.d.ts +4 -2
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +27 -26
  63. package/dist/ref-history.d.ts +12 -3
  64. package/dist/ref-history.d.ts.map +1 -1
  65. package/dist/ref-history.js +27 -16
  66. package/dist/ref-history.js.map +1 -1
  67. package/package.json +5 -5
  68. package/dist/components/InkSuggestionCard.js +0 -7
  69. package/dist/components/InkSuggestionCard.js.map +0 -1
  70. package/dist/components/InkSuggestionCard.vue.d.ts +0 -16
  71. package/dist/components/InkSuggestionCard.vue.d.ts.map +0 -1
  72. package/dist/components/InkSuggestionCard.vue_vue_type_script_setup_true_lang.js +0 -85
  73. package/dist/components/InkSuggestionCard.vue_vue_type_script_setup_true_lang.js.map +0 -1
@@ -1,118 +1,126 @@
1
1
  import { useTool as e } from "../composables/useTool.js";
2
2
  import { useToolOptions as t } from "../composables/useToolOptions.js";
3
3
  import n from "./InkIcon.js";
4
- import { Fragment as r, computed as i, createElementBlock as a, createElementVNode as o, createTextVNode as s, createVNode as c, defineComponent as l, guardReactiveProps as u, mergeProps as d, normalizeProps as f, openBlock as p, ref as m, renderList as h, renderSlot as g, toDisplayString as _, unref as v, withCtx as y } from "vue";
5
- import { SHAPE_COLUMNS as b, SHAPE_ICONS as x, SHAPE_KINDS as S, focusInitialMenuItem as C, handleMenuKeys as w, menuItems as T, shapeMenuModel as E } from "@inkbar/core/dom";
6
- import { PopoverContent as D, PopoverPortal as O, PopoverRoot as k, PopoverTrigger as A, ToolbarButton as j } from "reka-ui";
7
- import { ChevronDown as M } from "@inkbar/icons";
4
+ import { Fragment as r, computed as i, createBlock as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, guardReactiveProps as d, mergeProps as f, normalizeProps as p, openBlock as m, ref as h, renderList as g, renderSlot as _, toDisplayString as v, unref as y, withCtx as b } from "vue";
5
+ import { SHAPE_COLUMNS as x, SHAPE_ICONS as S, SHAPE_KINDS as C, focusInitialMenuItem as w, handleMenuKeys as T, menuItems as E, shapeMenuModel as D } from "@inkbar/core/dom";
6
+ import { PopoverAnchor as O, PopoverContent as k, PopoverPortal as A, PopoverRoot as j, PopoverTrigger as M, ToolbarButton as N } from "reka-ui";
7
+ import { ChevronDown as P } from "@inkbar/icons";
8
8
  //#region src/components/InkShapeMenu.vue?vue&type=script&setup=true&lang.ts
9
- var N = {
10
- role: "group",
11
- "aria-label": "Shape",
12
- class: "ink-split-button ink-shape-menu",
13
- "data-ink-shape-menu": ""
14
- }, P = ["data-state"], F = ["data-ink-menu-columns"], I = [
9
+ var F = ["data-state"], I = ["data-ink-menu-columns"], L = [
15
10
  "data-key",
16
11
  "aria-checked",
17
12
  "data-state",
18
13
  "onClick"
19
- ], L = /*@__PURE__*/ l({
14
+ ], R = /*@__PURE__*/ u({
15
+ inheritAttrs: !1,
20
16
  __name: "InkShapeMenu",
21
- setup(l) {
22
- let { tool: L, setTool: R } = e(), { options: z, setOptions: B } = t("shape"), V = m(!1), H = i(() => E(z.value, S)), U = i(() => L.value === "shape"), W = i(() => x[H.value.kind]), G = !1;
23
- function K(e) {
24
- e.key !== "ArrowDown" || e.defaultPrevented || V.value || (e.preventDefault(), G = !0, V.value = !0);
25
- }
17
+ setup(u) {
18
+ let { tool: R, setTool: z } = e(), { options: B, setOptions: V } = t("shape"), H = h(!1), U = i(() => D(B.value, C)), W = i(() => R.value === "shape"), G = i(() => S[U.value.kind]), K = !1;
26
19
  function q(e) {
20
+ e.key !== "ArrowDown" || e.defaultPrevented || H.value || (e.preventDefault(), K = !0, H.value = !0);
21
+ }
22
+ function J(e) {
27
23
  e.preventDefault();
28
24
  let t = document.querySelector("[data-ink-menu=\"shape\"] [role=\"menu\"]");
29
- t && (G ? T(t)[0]?.focus({ preventScroll: !0 }) : C(t)), G = !1;
25
+ t && (K ? E(t)[0]?.focus({ preventScroll: !0 }) : w(t)), K = !1;
30
26
  }
31
- function J(e) {
32
- B({ kind: e }), R("shape"), V.value = !1;
27
+ function Y(e) {
28
+ V({ kind: e }), z("shape"), H.value = !1;
33
29
  }
34
- let Y = i(() => ({
35
- "aria-pressed": String(U.value),
36
- "aria-label": H.value.label,
37
- title: H.value.label,
38
- onClick: () => R("shape")
39
- })), X = {
30
+ let X = i(() => ({
31
+ "aria-pressed": String(W.value),
32
+ "aria-label": U.value.label,
33
+ title: U.value.label,
34
+ onClick: () => z("shape")
35
+ })), Z = {
40
36
  "aria-label": "Choose shape",
41
37
  title: "Choose shape",
42
38
  "aria-haspopup": "menu",
43
- onKeydown: K
44
- }, Z = { "aria-label": "Shapes" }, Q = {
39
+ onKeydown: q
40
+ }, Q = { "aria-label": "Shapes" }, $ = {
45
41
  role: "menu",
46
42
  "aria-label": "Shapes",
47
- onKeydown: (e) => w(e, e.currentTarget)
43
+ onKeydown: (e) => T(e, e.currentTarget)
48
44
  };
49
- return (e, t) => (p(), a("div", N, [c(v(j), d({
50
- class: "ink-tool-button ink-shape-button",
51
- "data-ink-tool-button": "",
52
- "data-ink-shape-button": "",
53
- "data-tool": "shape",
54
- "data-kind": H.value.kind,
55
- "data-state": U.value ? "on" : "off"
56
- }, Y.value), {
57
- default: y(() => [g(e.$slots, "default", {
58
- active: U.value,
59
- kind: H.value.kind
60
- }, () => [c(n, { icon: W.value }, null, 8, ["icon"])])]),
61
- _: 3
62
- }, 16, ["data-kind", "data-state"]), c(v(k), {
63
- open: V.value,
64
- "onUpdate:open": t[0] ||= (e) => V.value = e
45
+ return (e, t) => (m(), a(y(j), {
46
+ open: H.value,
47
+ "onUpdate:open": t[0] ||= (e) => H.value = e
65
48
  }, {
66
- default: y(() => [c(v(j), { "as-child": "" }, {
67
- default: y(() => [c(v(A), { "as-child": "" }, {
68
- default: y(() => [o("button", d({
69
- type: "button",
70
- class: "ink-menu-trigger ink-shape-menu-trigger",
71
- "data-ink-shape-menu-trigger": "",
72
- "data-state": V.value ? "open" : "closed"
73
- }, X), [c(n, { icon: v(M) }, null, 8, ["icon"])], 16, P)]),
74
- _: 1
75
- })]),
76
- _: 1
77
- }), c(v(O), null, {
78
- default: y(() => [c(v(D), d({
79
- class: "ink-select-content ink-menu-content",
80
- "data-ink-select-content": "",
81
- "data-ink-menu": "shape",
82
- side: "bottom",
83
- align: "start",
84
- "side-offset": 4,
85
- "collision-padding": 8
86
- }, Z, { onOpenAutoFocus: q }), {
87
- default: y(() => [o("div", f(u(Q)), [o("div", {
88
- role: "group",
89
- "aria-label": "Shapes",
90
- class: "ink-shape-grid",
91
- "data-ink-menu-columns": v(b)
92
- }, [(p(!0), a(r, null, h(H.value.items, (e) => (p(), a("button", {
93
- key: e.kind,
94
- type: "button",
95
- role: "menuitemradio",
96
- class: "ink-select-item ink-menu-item ink-shape-item",
97
- "data-ink-select-item": "",
98
- tabindex: "-1",
99
- "data-key": e.kind,
100
- "aria-checked": e.checked,
101
- "data-state": e.checked ? "checked" : "unchecked",
102
- onClick: (t) => J(e.kind)
103
- }, [c(n, {
104
- icon: v(x)[e.kind],
105
- size: 16
106
- }, null, 8, ["icon"]), s(" " + _(e.label), 1)], 8, I))), 128))], 8, F)], 16)]),
107
- _: 1
108
- }, 16)]),
109
- _: 1
49
+ default: b(() => [l(y(O), { "as-child": "" }, {
50
+ default: b(() => [s("div", f({
51
+ role: "group",
52
+ "aria-label": "Shape",
53
+ class: "ink-split-button ink-shape-menu",
54
+ "data-ink-shape-menu": ""
55
+ }, e.$attrs), [
56
+ l(y(N), f({
57
+ class: "ink-tool-button ink-shape-button",
58
+ "data-ink-tool-button": "",
59
+ "data-ink-shape-button": "",
60
+ "data-tool": "shape",
61
+ "data-kind": U.value.kind,
62
+ "data-state": W.value ? "on" : "off"
63
+ }, X.value), {
64
+ default: b(() => [_(e.$slots, "default", {
65
+ active: W.value,
66
+ kind: U.value.kind
67
+ }, () => [l(n, { icon: G.value }, null, 8, ["icon"])])]),
68
+ _: 3
69
+ }, 16, ["data-kind", "data-state"]),
70
+ l(y(N), { "as-child": "" }, {
71
+ default: b(() => [l(y(M), { "as-child": "" }, {
72
+ default: b(() => [s("button", f({
73
+ type: "button",
74
+ class: "ink-menu-trigger ink-shape-menu-trigger",
75
+ "data-ink-shape-menu-trigger": "",
76
+ "data-state": H.value ? "open" : "closed"
77
+ }, Z), [l(n, { icon: y(P) }, null, 8, ["icon"])], 16, F)]),
78
+ _: 1
79
+ })]),
80
+ _: 1
81
+ }),
82
+ l(y(A), null, {
83
+ default: b(() => [l(y(k), f({
84
+ class: "ink-select-content ink-menu-content",
85
+ "data-ink-select-content": "",
86
+ "data-ink-menu": "shape",
87
+ side: "bottom",
88
+ align: "start",
89
+ "side-offset": 4,
90
+ "collision-padding": 8
91
+ }, Q, { onOpenAutoFocus: J }), {
92
+ default: b(() => [s("div", p(d($)), [s("div", {
93
+ role: "group",
94
+ "aria-label": "Shapes",
95
+ class: "ink-shape-grid",
96
+ "data-ink-menu-columns": y(x)
97
+ }, [(m(!0), o(r, null, g(U.value.items, (e) => (m(), o("button", {
98
+ key: e.kind,
99
+ type: "button",
100
+ role: "menuitemradio",
101
+ class: "ink-select-item ink-menu-item ink-shape-item",
102
+ "data-ink-select-item": "",
103
+ tabindex: "-1",
104
+ "data-key": e.kind,
105
+ "aria-checked": e.checked,
106
+ "data-state": e.checked ? "checked" : "unchecked",
107
+ onClick: (t) => Y(e.kind)
108
+ }, [l(n, {
109
+ icon: y(S)[e.kind],
110
+ size: 16
111
+ }, null, 8, ["icon"]), c(" " + v(e.label), 1)], 8, L))), 128))], 8, I)], 16)]),
112
+ _: 1
113
+ }, 16)]),
114
+ _: 1
115
+ })
116
+ ], 16)]),
117
+ _: 3
110
118
  })]),
111
- _: 1
112
- }, 8, ["open"])]));
119
+ _: 3
120
+ }, 8, ["open"]));
113
121
  }
114
122
  });
115
123
  //#endregion
116
- export { L as default };
124
+ export { R as default };
117
125
 
118
126
  //# sourceMappingURL=InkShapeMenu.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InkShapeMenu.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_createVNode","_unref","_mergeProps","_withCtx","_renderSlot","InkIcon","_createElementVNode","_normalizeProps","_guardReactiveProps","_Fragment","_renderList","_createTextVNode","_toDisplayString","InkIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","InkShapeMenu_vue_vue_type_script_setup_true_lang_default","useTool","useToolOptions","open","ref","model","computed","shapeMenuModel","options","SHAPE_KINDS","active","tool","icon","SHAPE_ICONS","focusFirst","onTriggerKeydown","onOpenAutoFocus","menu","menuItems","focusInitialMenuItem","choose","setOptions","setTool","mainAttrs","triggerAttrs","menuAttrs","innerAttrs","handleMenuKeys","openBlock","createElementBlock","createVNode","unref","ToolbarButton","mergeProps","withCtx","renderSlot","_ctx","PopoverRoot","_cache","$event","PopoverTrigger","createElementVNode","ChevronDown","PopoverPortal","PopoverContent","normalizeProps","guardReactiveProps","SHAPE_COLUMNS","Fragment","renderList","item","createTextVNode","toDisplayString"],"sources":["../../src/components/InkShapeMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A split button for the shape tool. The main part activates the tool with the current\n * kind and draws that kind's icon; the chevron opens a two-column grid of kinds. Choosing a\n * kind switches to the tool with it.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n SHAPE_COLUMNS,\n SHAPE_ICONS,\n SHAPE_KINDS,\n shapeMenuModel,\n type ShapeKind,\n type ShapeOptions,\n} from '@inkbar/core/dom'\nimport { ChevronDown } from '@inkbar/icons'\nimport {\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n ToolbarButton,\n} from 'reka-ui'\nimport { computed, ref } from 'vue'\n\nimport { useTool } from '../composables/useTool'\nimport { useToolOptions } from '../composables/useToolOptions'\n\nimport InkIcon from './InkIcon.vue'\n\nconst { tool, setTool } = useTool()\nconst { options, setOptions } = useToolOptions<ShapeOptions>('shape')\nconst open = ref(false)\n\nconst model = computed(() => shapeMenuModel(options.value, SHAPE_KINDS))\nconst active = computed(() => tool.value === 'shape')\nconst icon = computed(() => SHAPE_ICONS[model.value.kind])\n\n/** ArrowDown opens on the first item; a click opens on the checked one. */\nlet focusFirst = false\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open.value) return\n e.preventDefault()\n focusFirst = true\n open.value = true\n}\n\nfunction onOpenAutoFocus(e: Event): void {\n e.preventDefault()\n // One menu is open at a time.\n const menu = document.querySelector('[data-ink-menu=\"shape\"] [role=\"menu\"]')\n if (menu) {\n if (focusFirst) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n }\n focusFirst = false\n}\n\nfunction choose(kind: ShapeKind): void {\n setOptions({ kind })\n setTool('shape')\n open.value = false\n}\n\n// Reka's typed props stop at its own; ARIA and listeners go through bound objects.\nconst mainAttrs = computed(() => ({\n 'aria-pressed': String(active.value),\n 'aria-label': model.value.label,\n title: model.value.label,\n onClick: () => setTool('shape'),\n}))\nconst triggerAttrs = {\n 'aria-label': 'Choose shape',\n title: 'Choose shape',\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n}\nconst menuAttrs = { 'aria-label': 'Shapes' }\nconst innerAttrs = {\n role: 'menu',\n 'aria-label': 'Shapes',\n onKeydown: (e: KeyboardEvent) => handleMenuKeys(e, e.currentTarget as HTMLElement),\n}\n</script>\n\n<template>\n <div\n role=\"group\"\n aria-label=\"Shape\"\n class=\"ink-split-button ink-shape-menu\"\n data-ink-shape-menu\n >\n <ToolbarButton\n class=\"ink-tool-button ink-shape-button\"\n data-ink-tool-button\n data-ink-shape-button\n data-tool=\"shape\"\n :data-kind=\"model.kind\"\n :data-state=\"active ? 'on' : 'off'\"\n v-bind=\"mainAttrs\"\n >\n <slot :active=\"active\" :kind=\"model.kind\"><InkIcon :icon=\"icon\" /></slot>\n </ToolbarButton>\n <PopoverRoot v-model:open=\"open\">\n <ToolbarButton as-child>\n <PopoverTrigger as-child>\n <button\n type=\"button\"\n class=\"ink-menu-trigger ink-shape-menu-trigger\"\n data-ink-shape-menu-trigger\n :data-state=\"open ? 'open' : 'closed'\"\n v-bind=\"triggerAttrs\"\n >\n <InkIcon :icon=\"ChevronDown\" />\n </button>\n </PopoverTrigger>\n </ToolbarButton>\n <PopoverPortal>\n <PopoverContent\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n data-ink-menu=\"shape\"\n side=\"bottom\"\n align=\"start\"\n :side-offset=\"4\"\n :collision-padding=\"8\"\n v-bind=\"menuAttrs\"\n @open-auto-focus=\"onOpenAutoFocus\"\n >\n <div v-bind=\"innerAttrs\">\n <div\n role=\"group\"\n aria-label=\"Shapes\"\n class=\"ink-shape-grid\"\n :data-ink-menu-columns=\"SHAPE_COLUMNS\"\n >\n <button\n v-for=\"item in model.items\"\n :key=\"item.kind\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-select-item ink-menu-item ink-shape-item\"\n data-ink-select-item\n tabindex=\"-1\"\n :data-key=\"item.kind\"\n :aria-checked=\"item.checked\"\n :data-state=\"item.checked ? 'checked' : 'unchecked'\"\n @click=\"choose(item.kind)\"\n >\n <InkIcon :icon=\"SHAPE_ICONS[item.kind]\" :size=\"16\" />\n {{ item.label }}\n </button>\n </div>\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"InkShapeMenu.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_createElementVNode","_mergeProps","_renderSlot","InkIcon","_normalizeProps","_guardReactiveProps","_createElementBlock","_Fragment","_renderList","_createTextVNode","_toDisplayString","InkIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","InkShapeMenu_vue_vue_type_script_setup_true_lang_default","useTool","useToolOptions","open","ref","model","computed","shapeMenuModel","options","SHAPE_KINDS","active","tool","icon","SHAPE_ICONS","focusFirst","onTriggerKeydown","onOpenAutoFocus","menu","menuItems","focusInitialMenuItem","choose","setOptions","setTool","mainAttrs","triggerAttrs","menuAttrs","innerAttrs","handleMenuKeys","openBlock","createBlock","unref","PopoverRoot","_cache","$event","withCtx","createVNode","PopoverAnchor","createElementVNode","mergeProps","_ctx","ToolbarButton","renderSlot","PopoverTrigger","ChevronDown","PopoverPortal","PopoverContent","normalizeProps","guardReactiveProps","SHAPE_COLUMNS","createElementBlock","Fragment","renderList","item","createTextVNode","toDisplayString"],"sources":["../../src/components/InkShapeMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A split button for the shape tool. The main part activates the tool with the current\n * kind and draws that kind's icon; the chevron opens a two-column grid of kinds. Choosing a\n * kind switches to the tool with it.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n SHAPE_COLUMNS,\n SHAPE_ICONS,\n SHAPE_KINDS,\n shapeMenuModel,\n type ShapeKind,\n type ShapeOptions,\n} from '@inkbar/core/dom'\nimport { ChevronDown } from '@inkbar/icons'\nimport {\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n ToolbarButton,\n} from 'reka-ui'\nimport { computed, ref } from 'vue'\n\nimport { useTool } from '../composables/useTool'\nimport { useToolOptions } from '../composables/useToolOptions'\n\nimport InkIcon from './InkIcon.vue'\n\ndefineOptions({ inheritAttrs: false })\nconst { tool, setTool } = useTool()\nconst { options, setOptions } = useToolOptions<ShapeOptions>('shape')\nconst open = ref(false)\n\nconst model = computed(() => shapeMenuModel(options.value, SHAPE_KINDS))\nconst active = computed(() => tool.value === 'shape')\nconst icon = computed(() => SHAPE_ICONS[model.value.kind])\n\n/** ArrowDown opens on the first item; a click opens on the checked one. */\nlet focusFirst = false\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open.value) return\n e.preventDefault()\n focusFirst = true\n open.value = true\n}\n\nfunction onOpenAutoFocus(e: Event): void {\n e.preventDefault()\n // One menu is open at a time.\n const menu = document.querySelector('[data-ink-menu=\"shape\"] [role=\"menu\"]')\n if (menu) {\n if (focusFirst) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n }\n focusFirst = false\n}\n\nfunction choose(kind: ShapeKind): void {\n setOptions({ kind })\n setTool('shape')\n open.value = false\n}\n\n// Reka's typed props stop at its own; ARIA and listeners go through bound objects.\nconst mainAttrs = computed(() => ({\n 'aria-pressed': String(active.value),\n 'aria-label': model.value.label,\n title: model.value.label,\n onClick: () => setTool('shape'),\n}))\nconst triggerAttrs = {\n 'aria-label': 'Choose shape',\n title: 'Choose shape',\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n}\nconst menuAttrs = { 'aria-label': 'Shapes' }\nconst innerAttrs = {\n role: 'menu',\n 'aria-label': 'Shapes',\n onKeydown: (e: KeyboardEvent) => handleMenuKeys(e, e.currentTarget as HTMLElement),\n}\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <PopoverAnchor as-child>\n <div\n role=\"group\"\n aria-label=\"Shape\"\n class=\"ink-split-button ink-shape-menu\"\n data-ink-shape-menu\n v-bind=\"$attrs\"\n >\n <ToolbarButton\n class=\"ink-tool-button ink-shape-button\"\n data-ink-tool-button\n data-ink-shape-button\n data-tool=\"shape\"\n :data-kind=\"model.kind\"\n :data-state=\"active ? 'on' : 'off'\"\n v-bind=\"mainAttrs\"\n >\n <slot :active=\"active\" :kind=\"model.kind\"><InkIcon :icon=\"icon\" /></slot>\n </ToolbarButton>\n <ToolbarButton as-child>\n <PopoverTrigger as-child>\n <button\n type=\"button\"\n class=\"ink-menu-trigger ink-shape-menu-trigger\"\n data-ink-shape-menu-trigger\n :data-state=\"open ? 'open' : 'closed'\"\n v-bind=\"triggerAttrs\"\n >\n <InkIcon :icon=\"ChevronDown\" />\n </button>\n </PopoverTrigger>\n </ToolbarButton>\n <PopoverPortal>\n <PopoverContent\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n data-ink-menu=\"shape\"\n side=\"bottom\"\n align=\"start\"\n :side-offset=\"4\"\n :collision-padding=\"8\"\n v-bind=\"menuAttrs\"\n @open-auto-focus=\"onOpenAutoFocus\"\n >\n <div v-bind=\"innerAttrs\">\n <div\n role=\"group\"\n aria-label=\"Shapes\"\n class=\"ink-shape-grid\"\n :data-ink-menu-columns=\"SHAPE_COLUMNS\"\n >\n <button\n v-for=\"item in model.items\"\n :key=\"item.kind\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-select-item ink-menu-item ink-shape-item\"\n data-ink-select-item\n tabindex=\"-1\"\n :data-key=\"item.kind\"\n :aria-checked=\"item.checked\"\n :data-state=\"item.checked ? 'checked' : 'unchecked'\"\n @click=\"choose(item.kind)\"\n >\n <InkIcon :icon=\"SHAPE_ICONS[item.kind]\" :size=\"16\" />\n {{ item.label }}\n </button>\n </div>\n </div>\n </PopoverContent>\n </PopoverPortal>\n </div>\n </PopoverAnchor>\n </PopoverRoot>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"InkSignatureMenu.js","names":["_sfc_main","InkSignatureMenu_vue_vue_type_script_setup_true_lang_default","InkSignatureMenu_default"],"sources":["../../src/components/InkSignatureMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A split button for the signature tool. The main part activates the tool with the chosen\n * signature, or opens the menu when none is chosen; the chevron opens the saved signatures as\n * previews, each with a remove button, and \"Create signature\", which opens\n * `InkSignatureDialog`. Choosing a signature switches to the tool with it.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n SIGNATURE_LABELS,\n signatureMenuModel,\n signaturePreview,\n} from '@inkbar/core/dom'\nimport { ChevronDown, Plus, Signature, Trash2 } from '@inkbar/icons'\nimport {\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n ToolbarButton,\n} from 'reka-ui'\nimport { computed, nextTick, ref, useTemplateRef, watch } from 'vue'\n\nimport { useTool } from '../composables/useTool'\nimport { useToolOptions } from '../composables/useToolOptions'\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport InkIcon from './InkIcon.vue'\nimport InkSignatureDialog from './InkSignatureDialog.vue'\n\nimport type { SignatureOptions, SignatureTemplate } from '@inkbar/core'\n\nconst props = defineProps<{\n /** The fonts the dialog's Type tab offers. Default: InkRoot's `signatureFonts`. */\n fonts?: readonly string[] | undefined\n}>()\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\nconst { tool, setTool } = useTool()\nconst { options, setOptions } = useToolOptions<SignatureOptions>('signature')\nconst ctx = useInkContext('InkSignatureMenu')\nconst templates = useReadable(() => ctx.signatures.value.templates, NO_TEMPLATES)\nconst removeError = useReadable(() => ctx.signatures.value.removeError, undefined)\nconst model = computed(() => signatureMenuModel(templates.value, options.value))\nconst active = computed(() => tool.value === 'signature')\nconst open = ref(false)\nconst creating = ref(false)\n// An old removal error is not news when the menu opens again.\nwatch(open, (isOpen) => {\n if (isOpen) ctx.signatures.value.clearRemoveError()\n})\nconst main = useTemplateRef<{ $el: HTMLElement }>('main')\n\n/** A saved signature drawn small: ink as filled outlines. */\nconst previews = computed(() =>\n model.value.items.map((item) =>\n item.template.kind === 'ink' ? signaturePreview(item.template) : null\n )\n)\n\n/** ArrowDown opens on the first item; a click opens on the checked one. */\nlet focusFirst = false\n/** Set while the menu closes for the dialog, which takes focus instead of the trigger. */\nlet toDialog = false\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open.value) return\n e.preventDefault()\n focusFirst = true\n open.value = true\n}\n\nconst panel = (): HTMLElement | null =>\n document.querySelector<HTMLElement>('[data-ink-menu=\"signature\"] [role=\"menu\"]')\n\nfunction onOpenAutoFocus(e: Event): void {\n e.preventDefault()\n const menu = panel()\n if (menu) {\n if (focusFirst) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n }\n focusFirst = false\n}\n\nfunction onCloseAutoFocus(e: Event): void {\n if (toDialog) e.preventDefault()\n toDialog = false\n}\n\nfunction onMain(): void {\n if (model.value.selected) setTool('signature')\n else open.value = true\n}\n\nfunction choose(id: string): void {\n setOptions({ templateId: id })\n setTool('signature')\n open.value = false\n}\n\n/** Removes a template; focus moves to the signature now in its row, else \"Create signature\". */\nfunction remove(id: string, row: number): void {\n ctx.signatures.value.remove(id).then(\n async () => {\n await nextTick()\n const menu = panel()\n if (!menu) return\n const rows = menu.querySelectorAll<HTMLElement>('.ink-signature-item')\n const next =\n rows[Math.min(row, rows.length - 1)] ??\n menu.querySelector<HTMLElement>('[data-ink-signature-create]')\n next?.focus({ preventScroll: true })\n },\n () => {\n // The host's store refused: the signature stays.\n }\n )\n}\n\nfunction create(): void {\n toDialog = true\n open.value = false\n creating.value = true\n}\n\nfunction onDialogCloseAutoFocus(e: Event): void {\n e.preventDefault()\n main.value?.$el.focus({ preventScroll: true })\n}\n\n// Reka's typed props stop at its own; ARIA and listeners go through bound objects.\nconst mainAttrs = computed(() => ({\n 'aria-pressed': String(active.value),\n 'aria-label': SIGNATURE_LABELS.sign,\n title: SIGNATURE_LABELS.sign,\n onClick: onMain,\n}))\nconst triggerAttrs = {\n 'aria-label': SIGNATURE_LABELS.trigger,\n title: SIGNATURE_LABELS.trigger,\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n}\nconst menuAttrs = { 'aria-label': SIGNATURE_LABELS.menu }\nconst innerAttrs = {\n role: 'menu',\n 'aria-label': SIGNATURE_LABELS.menu,\n onKeydown: (e: KeyboardEvent) => handleMenuKeys(e, e.currentTarget as HTMLElement),\n}\n</script>\n\n<template>\n <div\n role=\"group\"\n :aria-label=\"SIGNATURE_LABELS.sign\"\n class=\"ink-split-button ink-signature-menu\"\n data-ink-signature-menu\n >\n <ToolbarButton\n ref=\"main\"\n class=\"ink-tool-button ink-signature-button\"\n data-ink-tool-button\n data-ink-signature-button\n data-tool=\"signature\"\n :data-state=\"active ? 'on' : 'off'\"\n v-bind=\"mainAttrs\"\n >\n <slot :active=\"active\"><InkIcon :icon=\"Signature\" /></slot>\n </ToolbarButton>\n <PopoverRoot v-model:open=\"open\">\n <ToolbarButton as-child>\n <PopoverTrigger as-child>\n <button\n type=\"button\"\n class=\"ink-menu-trigger ink-signature-menu-trigger\"\n data-ink-signature-menu-trigger\n :data-state=\"open ? 'open' : 'closed'\"\n v-bind=\"triggerAttrs\"\n >\n <InkIcon :icon=\"ChevronDown\" />\n </button>\n </PopoverTrigger>\n </ToolbarButton>\n <PopoverPortal>\n <PopoverContent\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n data-ink-menu=\"signature\"\n side=\"bottom\"\n align=\"start\"\n :side-offset=\"4\"\n :collision-padding=\"8\"\n v-bind=\"menuAttrs\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @close-auto-focus=\"onCloseAutoFocus\"\n >\n <div v-bind=\"innerAttrs\">\n <template v-if=\"model.items.length > 0\">\n <div\n role=\"group\"\n :aria-label=\"SIGNATURE_LABELS.saved\"\n class=\"ink-signature-list\"\n data-ink-menu-columns=\"2\"\n >\n <template v-for=\"(item, row) in model.items\" :key=\"item.id\">\n <button\n type=\"button\"\n role=\"menuitemradio\"\n :aria-checked=\"item.checked\"\n :aria-label=\"item.label\"\n tabindex=\"-1\"\n class=\"ink-select-item ink-menu-item ink-signature-item\"\n data-ink-select-item\n :data-key=\"item.id\"\n :data-state=\"item.checked ? 'checked' : 'unchecked'\"\n @click=\"choose(item.id)\"\n >\n <span class=\"ink-signature-preview\" :data-kind=\"item.template.kind\">\n <img\n v-if=\"item.template.kind === 'image'\"\n :src=\"item.template.imagedata\"\n alt=\"\"\n draggable=\"false\"\n />\n <svg v-else :viewBox=\"previews[row]?.viewBox\" aria-hidden=\"true\">\n <path\n v-for=\"(d, i) in previews[row]?.paths ?? []\"\n :key=\"i\"\n :d=\"d\"\n fill=\"currentColor\"\n />\n </svg>\n </span>\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n :aria-label=\"item.removeLabel\"\n :title=\"item.removeLabel\"\n tabindex=\"-1\"\n class=\"ink-menu-item ink-signature-remove\"\n data-ink-signature-remove\n :data-key=\"item.id\"\n @click=\"remove(item.id, row)\"\n >\n <InkIcon :icon=\"Trash2\" :size=\"16\" />\n </button>\n </template>\n </div>\n <div role=\"separator\" class=\"ink-select-separator\" />\n </template>\n <button\n type=\"button\"\n role=\"menuitem\"\n tabindex=\"-1\"\n class=\"ink-select-item ink-menu-item ink-signature-create\"\n data-ink-select-item\n data-ink-signature-create\n @click=\"create\"\n >\n <InkIcon :icon=\"Plus\" :size=\"16\" />\n {{ SIGNATURE_LABELS.create }}\n </button>\n <p\n v-if=\"removeError\"\n class=\"ink-field-error ink-signature-remove-error\"\n role=\"alert\"\n data-ink-signature-remove-error\n >\n {{ removeError }}\n </p>\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <InkSignatureDialog\n v-model:open=\"creating\"\n :fonts=\"props.fonts\"\n @close-auto-focus=\"onDialogCloseAutoFocus\"\n />\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"InkSignatureMenu.js","names":["_sfc_main","InkSignatureMenu_vue_vue_type_script_setup_true_lang_default","InkSignatureMenu_default"],"sources":["../../src/components/InkSignatureMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A split button for the signature tool. The main part activates the tool with the chosen\n * signature, or opens the menu when none is chosen; the chevron opens the saved signatures as\n * previews, each with a remove button, and \"Create signature\", which opens\n * `InkSignatureDialog`. Choosing a signature switches to the tool with it.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n SIGNATURE_LABELS,\n signatureMenuModel,\n signaturePreview,\n} from '@inkbar/core/dom'\nimport { ChevronDown, Plus, Signature, Trash2 } from '@inkbar/icons'\nimport {\n PopoverAnchor,\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n ToolbarButton,\n} from 'reka-ui'\nimport { computed, nextTick, ref, useTemplateRef, watch } from 'vue'\n\nimport { useTool } from '../composables/useTool'\nimport { useToolOptions } from '../composables/useToolOptions'\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport InkIcon from './InkIcon.vue'\nimport InkSignatureDialog from './InkSignatureDialog.vue'\n\nimport type { SignatureOptions, SignatureTemplate } from '@inkbar/core'\n\ndefineOptions({ inheritAttrs: false })\nconst props = defineProps<{\n /** The fonts the dialog's Type tab offers. Default: InkRoot's `signatureFonts`. */\n fonts?: readonly string[] | undefined\n}>()\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\nconst { tool, setTool } = useTool()\nconst { options, setOptions } = useToolOptions<SignatureOptions>('signature')\nconst ctx = useInkContext('InkSignatureMenu')\nconst templates = useReadable(() => ctx.signatures.value.templates, NO_TEMPLATES)\nconst removeError = useReadable(() => ctx.signatures.value.removeError, undefined)\nconst model = computed(() => signatureMenuModel(templates.value, options.value))\nconst active = computed(() => tool.value === 'signature')\nconst open = ref(false)\nconst creating = ref(false)\n// An old removal error is not news when the menu opens again.\nwatch(open, (isOpen) => {\n if (isOpen) ctx.signatures.value.clearRemoveError()\n})\nconst main = useTemplateRef<{ $el: HTMLElement }>('main')\n\n/** A saved signature drawn small: ink as filled outlines. */\nconst previews = computed(() =>\n model.value.items.map((item) =>\n item.template.kind === 'ink' ? signaturePreview(item.template) : null\n )\n)\n\n/** ArrowDown opens on the first item; a click opens on the checked one. */\nlet focusFirst = false\n/** Set while the menu closes for the dialog, which takes focus instead of the trigger. */\nlet toDialog = false\n\nfunction onTriggerKeydown(e: KeyboardEvent): void {\n if (e.key !== 'ArrowDown' || e.defaultPrevented || open.value) return\n e.preventDefault()\n focusFirst = true\n open.value = true\n}\n\nconst panel = (): HTMLElement | null =>\n document.querySelector<HTMLElement>('[data-ink-menu=\"signature\"] [role=\"menu\"]')\n\nfunction onOpenAutoFocus(e: Event): void {\n e.preventDefault()\n const menu = panel()\n if (menu) {\n if (focusFirst) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n }\n focusFirst = false\n}\n\nfunction onCloseAutoFocus(e: Event): void {\n if (toDialog) e.preventDefault()\n toDialog = false\n}\n\nfunction onMain(): void {\n if (model.value.selected) setTool('signature')\n else open.value = true\n}\n\nfunction choose(id: string): void {\n setOptions({ templateId: id })\n setTool('signature')\n open.value = false\n}\n\n/** Removes a template; focus moves to the signature now in its row, else \"Create signature\". */\nfunction remove(id: string, row: number): void {\n ctx.signatures.value.remove(id).then(\n async () => {\n await nextTick()\n const menu = panel()\n if (!menu) return\n const rows = menu.querySelectorAll<HTMLElement>('.ink-signature-item')\n const next =\n rows[Math.min(row, rows.length - 1)] ??\n menu.querySelector<HTMLElement>('[data-ink-signature-create]')\n next?.focus({ preventScroll: true })\n },\n () => {\n // The host's store refused: the signature stays.\n }\n )\n}\n\nfunction create(): void {\n toDialog = true\n open.value = false\n creating.value = true\n}\n\nfunction onDialogCloseAutoFocus(e: Event): void {\n e.preventDefault()\n main.value?.$el.focus({ preventScroll: true })\n}\n\n// Reka's typed props stop at its own; ARIA and listeners go through bound objects.\nconst mainAttrs = computed(() => ({\n 'aria-pressed': String(active.value),\n 'aria-label': SIGNATURE_LABELS.sign,\n title: SIGNATURE_LABELS.sign,\n onClick: onMain,\n}))\nconst triggerAttrs = {\n 'aria-label': SIGNATURE_LABELS.trigger,\n title: SIGNATURE_LABELS.trigger,\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n}\nconst menuAttrs = { 'aria-label': SIGNATURE_LABELS.menu }\nconst innerAttrs = {\n role: 'menu',\n 'aria-label': SIGNATURE_LABELS.menu,\n onKeydown: (e: KeyboardEvent) => handleMenuKeys(e, e.currentTarget as HTMLElement),\n}\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <PopoverAnchor as-child>\n <div\n role=\"group\"\n :aria-label=\"SIGNATURE_LABELS.sign\"\n class=\"ink-split-button ink-signature-menu\"\n data-ink-signature-menu\n v-bind=\"$attrs\"\n >\n <ToolbarButton\n ref=\"main\"\n class=\"ink-tool-button ink-signature-button\"\n data-ink-tool-button\n data-ink-signature-button\n data-tool=\"signature\"\n :data-state=\"active ? 'on' : 'off'\"\n v-bind=\"mainAttrs\"\n >\n <slot :active=\"active\"><InkIcon :icon=\"Signature\" /></slot>\n </ToolbarButton>\n <ToolbarButton as-child>\n <PopoverTrigger as-child>\n <button\n type=\"button\"\n class=\"ink-menu-trigger ink-signature-menu-trigger\"\n data-ink-signature-menu-trigger\n :data-state=\"open ? 'open' : 'closed'\"\n v-bind=\"triggerAttrs\"\n >\n <InkIcon :icon=\"ChevronDown\" />\n </button>\n </PopoverTrigger>\n </ToolbarButton>\n <PopoverPortal>\n <PopoverContent\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n data-ink-menu=\"signature\"\n side=\"bottom\"\n align=\"start\"\n :side-offset=\"4\"\n :collision-padding=\"8\"\n v-bind=\"menuAttrs\"\n @open-auto-focus=\"onOpenAutoFocus\"\n @close-auto-focus=\"onCloseAutoFocus\"\n >\n <div v-bind=\"innerAttrs\">\n <template v-if=\"model.items.length > 0\">\n <div\n role=\"group\"\n :aria-label=\"SIGNATURE_LABELS.saved\"\n class=\"ink-signature-list\"\n data-ink-menu-columns=\"2\"\n >\n <template v-for=\"(item, row) in model.items\" :key=\"item.id\">\n <button\n type=\"button\"\n role=\"menuitemradio\"\n :aria-checked=\"item.checked\"\n :aria-label=\"item.label\"\n tabindex=\"-1\"\n class=\"ink-select-item ink-menu-item ink-signature-item\"\n data-ink-select-item\n :data-key=\"item.id\"\n :data-state=\"item.checked ? 'checked' : 'unchecked'\"\n @click=\"choose(item.id)\"\n >\n <span class=\"ink-signature-preview\" :data-kind=\"item.template.kind\">\n <img\n v-if=\"item.template.kind === 'image'\"\n :src=\"item.template.imagedata\"\n alt=\"\"\n draggable=\"false\"\n />\n <svg v-else :viewBox=\"previews[row]?.viewBox\" aria-hidden=\"true\">\n <path\n v-for=\"(d, i) in previews[row]?.paths ?? []\"\n :key=\"i\"\n :d=\"d\"\n fill=\"currentColor\"\n />\n </svg>\n </span>\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n :aria-label=\"item.removeLabel\"\n :title=\"item.removeLabel\"\n tabindex=\"-1\"\n class=\"ink-menu-item ink-signature-remove\"\n data-ink-signature-remove\n :data-key=\"item.id\"\n @click=\"remove(item.id, row)\"\n >\n <InkIcon :icon=\"Trash2\" :size=\"16\" />\n </button>\n </template>\n </div>\n <div role=\"separator\" class=\"ink-select-separator\" />\n </template>\n <button\n type=\"button\"\n role=\"menuitem\"\n tabindex=\"-1\"\n class=\"ink-select-item ink-menu-item ink-signature-create\"\n data-ink-select-item\n data-ink-signature-create\n @click=\"create\"\n >\n <InkIcon :icon=\"Plus\" :size=\"16\" />\n {{ SIGNATURE_LABELS.create }}\n </button>\n <p\n v-if=\"removeError\"\n class=\"ink-field-error ink-signature-remove-error\"\n role=\"alert\"\n data-ink-signature-remove-error\n >\n {{ removeError }}\n </p>\n </div>\n </PopoverContent>\n </PopoverPortal>\n <InkSignatureDialog\n v-model:open=\"creating\"\n :fonts=\"props.fonts\"\n @close-auto-focus=\"onDialogCloseAutoFocus\"\n />\n </div>\n </PopoverAnchor>\n </PopoverRoot>\n</template>\n"],"mappings":""}
@@ -2,11 +2,11 @@ type __VLS_Props = {
2
2
  /** The fonts the dialog's Type tab offers. Default: InkRoot's `signatureFonts`. */
3
3
  fonts?: readonly string[] | undefined;
4
4
  };
5
- declare var __VLS_7: {
5
+ declare var __VLS_21: {
6
6
  active: boolean;
7
7
  };
8
8
  type __VLS_Slots = {} & {
9
- default?: (props: typeof __VLS_7) => any;
9
+ default?: (props: typeof __VLS_21) => any;
10
10
  };
11
11
  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>;
12
12
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -1 +1 @@
1
- {"version":3,"file":"InkSignatureMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkSignatureMenu.vue"],"names":[],"mappings":"AAoUA,KAAK,WAAW,GAAG;IACjB,mFAAmF;IACnF,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;CACtC,CAAC;AA2cF,QAAA,IAAI,OAAO;;CAAW,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"}
1
+ {"version":3,"file":"InkSignatureMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkSignatureMenu.vue"],"names":[],"mappings":"AA2UA,KAAK,WAAW,GAAG;IACjB,mFAAmF;IACnF,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;CACtC,CAAC;AA2dF,QAAA,IAAI,QAAQ;;CAAY,CAAC;AACzB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAGhD,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"}