@inkbar/vue 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -5
- package/dist/components/InkAnnotation.js.map +1 -1
- package/dist/components/InkAnnotation.vue.d.ts.map +1 -1
- package/dist/components/InkAnnotation.vue_vue_type_script_setup_true_lang.js +16 -24
- package/dist/components/InkAnnotation.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/InkColorMenu.js.map +1 -1
- package/dist/components/InkColorMenu.vue.d.ts +2 -0
- package/dist/components/InkColorMenu.vue.d.ts.map +1 -1
- package/dist/components/InkColorMenu.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/components/InkColorMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/InkHighlightMenu.js.map +1 -1
- package/dist/components/InkHighlightMenu.vue.d.ts +2 -2
- package/dist/components/InkHighlightMenu.vue.d.ts.map +1 -1
- package/dist/components/InkHighlightMenu.vue_vue_type_script_setup_true_lang.js +118 -108
- package/dist/components/InkHighlightMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/InkRoot.js.map +1 -1
- package/dist/components/InkRoot.vue.d.ts +408 -424
- package/dist/components/InkRoot.vue.d.ts.map +1 -1
- package/dist/components/InkRoot.vue_vue_type_script_setup_true_lang.js +33 -27
- package/dist/components/InkRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/InkShapeMenu.js.map +1 -1
- package/dist/components/InkShapeMenu.vue.d.ts +2 -2
- package/dist/components/InkShapeMenu.vue.d.ts.map +1 -1
- package/dist/components/InkShapeMenu.vue_vue_type_script_setup_true_lang.js +99 -91
- package/dist/components/InkShapeMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/InkSignatureMenu.js.map +1 -1
- package/dist/components/InkSignatureMenu.vue.d.ts +2 -2
- package/dist/components/InkSignatureMenu.vue.d.ts.map +1 -1
- package/dist/components/InkSignatureMenu.vue_vue_type_script_setup_true_lang.js +156 -151
- package/dist/components/InkSignatureMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/InkViewport.js.map +1 -1
- package/dist/components/InkViewport.vue.d.ts.map +1 -1
- package/dist/components/InkViewport.vue_vue_type_script_setup_true_lang.js +9 -2
- package/dist/components/InkViewport.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/composables/useAnnotations.d.ts +915 -1386
- package/dist/composables/useAnnotations.d.ts.map +1 -1
- package/dist/composables/useAnnotations.js +13 -18
- package/dist/composables/useAnnotations.js.map +1 -1
- package/dist/context.d.ts +8 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/package.json +5 -5
- package/dist/components/InkSuggestionCard.js +0 -7
- package/dist/components/InkSuggestionCard.js.map +0 -1
- package/dist/components/InkSuggestionCard.vue.d.ts +0 -16
- package/dist/components/InkSuggestionCard.vue.d.ts.map +0 -1
- package/dist/components/InkSuggestionCard.vue_vue_type_script_setup_true_lang.js +0 -85
- package/dist/components/InkSuggestionCard.vue_vue_type_script_setup_true_lang.js.map +0 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-
Drop a PDF viewer into your Vue app and let people highlight text, leave notes with replies and
|
|
23
|
+
Drop a PDF viewer into your Vue app and let people highlight text, leave notes with replies and redact. `@inkbar/vue` gives you components and composables to build your own toolbars, plus a popover for comment threads, all styled by `@inkbar/theme`.
|
|
24
24
|
|
|
25
25
|
Annotations are plain typed objects. Bind them with `v-model` to keep them in your own state, or let Inkbar hold them with undo and redo.
|
|
26
26
|
|
|
@@ -51,7 +51,6 @@ import {
|
|
|
51
51
|
InkNextPage,
|
|
52
52
|
InkZoomSelect,
|
|
53
53
|
InkThreadPopover,
|
|
54
|
-
InkSuggestionCard,
|
|
55
54
|
} from '@inkbar/vue'
|
|
56
55
|
import type { Annotation } from '@inkbar/core'
|
|
57
56
|
import { assets } from 'virtual:inkbar-assets'
|
|
@@ -87,7 +86,6 @@ const annotations = ref<Annotation[]>([])
|
|
|
87
86
|
<InkZoomSelect />
|
|
88
87
|
</InkToolbar>
|
|
89
88
|
<InkThreadPopover />
|
|
90
|
-
<InkSuggestionCard />
|
|
91
89
|
</InkRoot>
|
|
92
90
|
</template>
|
|
93
91
|
```
|
|
@@ -130,7 +128,7 @@ The highlight tool leaves `contents` free for the comment. `doc.text(page)` retu
|
|
|
130
128
|
|
|
131
129
|
## Custom rendering
|
|
132
130
|
|
|
133
|
-
Slots let you render parts yourself. `InkViewport` has `loading`, `empty`, `error`, `annotation` and `page-error` slots. `InkThreadPopover`
|
|
131
|
+
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.
|
|
134
132
|
|
|
135
133
|
`InkRoot`, `InkToolbar`, `InkToolButton`, `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.
|
|
136
134
|
|
|
@@ -144,7 +142,7 @@ The scroll area takes focus. From there:
|
|
|
144
142
|
|
|
145
143
|
On a focused annotation:
|
|
146
144
|
|
|
147
|
-
- `Enter` or `Space` selects and activates it. A note
|
|
145
|
+
- `Enter` or `Space` selects and activates it. A note or text markup opens its thread; other types are only selected.
|
|
148
146
|
- `ArrowUp` and `ArrowDown` move to the previous or next annotation on the page.
|
|
149
147
|
- `Shift` + arrow moves it by 1 pt, or by 10 pt with `Alt` as well.
|
|
150
148
|
- `Ctrl` or `Cmd` + `Shift` + arrow resizes an area redaction, text box or shape.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkAnnotation.js","names":["_sfc_main","InkAnnotation_vue_vue_type_script_setup_true_lang_default","InkAnnotation_default"],"sources":["../../src/components/InkAnnotation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * Slot props for one annotation. It renders only its default slot: the overlay already draws\n * the default visual for every annotation that is not custom, so this never draws a second\n * one. InkPage teleports it into the annotation's overlay element.\n */\nimport {
|
|
1
|
+
{"version":3,"file":"InkAnnotation.js","names":["_sfc_main","InkAnnotation_vue_vue_type_script_setup_true_lang_default","InkAnnotation_default"],"sources":["../../src/components/InkAnnotation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * Slot props for one annotation. It renders only its default slot: the overlay already draws\n * the default visual for every annotation that is not custom, so this never draws a second\n * one. InkPage teleports it into the annotation's overlay element.\n */\nimport { computed, onBeforeUnmount, shallowRef, watch } from 'vue'\n\nimport { injectInkContext } from '../context'\n\nimport type { AnnotationSlotProps, AnnotationState } from './annotation-slot'\nimport type { Annotation } from '@inkbar/core'\n\nconst props = withDefaults(\n defineProps<{\n annotation: Annotation\n /** The overlay element; its `data-state` (which includes hover) drives `state`. */\n element?: HTMLElement | undefined\n }>(),\n { element: undefined }\n)\n\ndefineSlots<{ default?(props: AnnotationSlotProps): unknown }>()\n\nconst ctx = injectInkContext()\n\nconst observed = shallowRef<AnnotationState | null>(null)\nlet observer: MutationObserver | undefined\nfunction readState(el: HTMLElement): AnnotationState | null {\n const s = el.dataset.state\n return s === 'idle' || s === 'hover' || s === 'selected' ? s : null\n}\nwatch(\n () => props.element,\n (el) => {\n observer?.disconnect()\n observer = undefined\n observed.value = el ? readState(el) : null\n if (!el) return\n observer = new MutationObserver(() => {\n observed.value = readState(el)\n })\n observer.observe(el, { attributes: true, attributeFilter: ['data-state'] })\n },\n { immediate: true }\n)\nonBeforeUnmount(() => observer?.disconnect())\n\nconst slotProps = computed<AnnotationSlotProps>(() => {\n const { id } = props.annotation\n const store = () => ctx.document.value?.annotations\n return {\n annotation: props.annotation,\n state: observed.value ?? (ctx.selection.value.includes(id) ? 'selected' : 'idle'),\n locked: props.annotation.locked === true,\n select: () => store()?.select([id]),\n remove: () => void store()?.remove(id),\n }\n})\n</script>\n\n<template>\n <slot v-bind=\"slotProps\" />\n</template>\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkAnnotation.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkAnnotation.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"InkAnnotation.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkAnnotation.vue"],"names":[],"mappings":"AA2EA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,mBAAmB,CAAA;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAG9C,KAAK,WAAW,GAAG;IACf,UAAU,EAAE,UAAU,CAAA;IACtB,mFAAmF;IACnF,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CAClC,CAAC;AAMJ,KAAK,WAAW,GAAG;IAAE,OAAO,CAAC,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAA;CAAE,CAAC;AA4DrE,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"}
|
|
@@ -1,48 +1,40 @@
|
|
|
1
1
|
import { injectInkContext as e } from "../context.js";
|
|
2
2
|
import { computed as t, defineComponent as n, guardReactiveProps as r, normalizeProps as i, onBeforeUnmount as a, renderSlot as o, shallowRef as s, watch as c } from "vue";
|
|
3
|
-
import { acceptSuggestion as l } from "@inkbar/core";
|
|
4
3
|
//#region src/components/InkAnnotation.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var
|
|
4
|
+
var l = /*@__PURE__*/ n({
|
|
6
5
|
__name: "InkAnnotation",
|
|
7
6
|
props: {
|
|
8
7
|
annotation: {},
|
|
9
8
|
element: { default: void 0 }
|
|
10
9
|
},
|
|
11
10
|
setup(n) {
|
|
12
|
-
let
|
|
13
|
-
function
|
|
11
|
+
let l = n, u = e(), d = s(null), f;
|
|
12
|
+
function p(e) {
|
|
14
13
|
let t = e.dataset.state;
|
|
15
14
|
return t === "idle" || t === "hover" || t === "selected" ? t : null;
|
|
16
15
|
}
|
|
17
|
-
c(() =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}),
|
|
16
|
+
c(() => l.element, (e) => {
|
|
17
|
+
f?.disconnect(), f = void 0, d.value = e ? p(e) : null, e && (f = new MutationObserver(() => {
|
|
18
|
+
d.value = p(e);
|
|
19
|
+
}), f.observe(e, {
|
|
21
20
|
attributes: !0,
|
|
22
21
|
attributeFilter: ["data-state"]
|
|
23
22
|
}));
|
|
24
|
-
}, { immediate: !0 }), a(() =>
|
|
25
|
-
let
|
|
26
|
-
let { id: e } =
|
|
23
|
+
}, { immediate: !0 }), a(() => f?.disconnect());
|
|
24
|
+
let m = t(() => {
|
|
25
|
+
let { id: e } = l.annotation, t = () => u.document.value?.annotations;
|
|
27
26
|
return {
|
|
28
|
-
annotation:
|
|
29
|
-
state:
|
|
30
|
-
locked:
|
|
27
|
+
annotation: l.annotation,
|
|
28
|
+
state: d.value ?? (u.selection.value.includes(e) ? "selected" : "idle"),
|
|
29
|
+
locked: l.annotation.locked === !0,
|
|
31
30
|
select: () => t()?.select([e]),
|
|
32
|
-
remove: () => void t()?.remove(e)
|
|
33
|
-
accept: () => {
|
|
34
|
-
let n = t();
|
|
35
|
-
n && h.value && l(n, e);
|
|
36
|
-
},
|
|
37
|
-
dismiss: () => {
|
|
38
|
-
h.value && t()?.remove(e);
|
|
39
|
-
}
|
|
31
|
+
remove: () => void t()?.remove(e)
|
|
40
32
|
};
|
|
41
33
|
});
|
|
42
|
-
return (e, t) => o(e.$slots, "default", i(r(
|
|
34
|
+
return (e, t) => o(e.$slots, "default", i(r(m.value)));
|
|
43
35
|
}
|
|
44
36
|
});
|
|
45
37
|
//#endregion
|
|
46
|
-
export {
|
|
38
|
+
export { l as default };
|
|
47
39
|
|
|
48
40
|
//# sourceMappingURL=InkAnnotation.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkAnnotation.vue_vue_type_script_setup_true_lang.js","names":["_renderSlot","_normalizeProps","_guardReactiveProps","InkAnnotation_vue_vue_type_script_setup_true_lang_default","props","__props","ctx","injectInkContext","observed","shallowRef","observer","readState","s","el","watch","onBeforeUnmount","
|
|
1
|
+
{"version":3,"file":"InkAnnotation.vue_vue_type_script_setup_true_lang.js","names":["_renderSlot","_normalizeProps","_guardReactiveProps","InkAnnotation_vue_vue_type_script_setup_true_lang_default","props","__props","ctx","injectInkContext","observed","shallowRef","observer","readState","s","el","watch","onBeforeUnmount","slotProps","computed","store","id","renderSlot","_ctx","normalizeProps","guardReactiveProps"],"sources":["../../src/components/InkAnnotation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * Slot props for one annotation. It renders only its default slot: the overlay already draws\n * the default visual for every annotation that is not custom, so this never draws a second\n * one. InkPage teleports it into the annotation's overlay element.\n */\nimport { computed, onBeforeUnmount, shallowRef, watch } from 'vue'\n\nimport { injectInkContext } from '../context'\n\nimport type { AnnotationSlotProps, AnnotationState } from './annotation-slot'\nimport type { Annotation } from '@inkbar/core'\n\nconst props = withDefaults(\n defineProps<{\n annotation: Annotation\n /** The overlay element; its `data-state` (which includes hover) drives `state`. */\n element?: HTMLElement | undefined\n }>(),\n { element: undefined }\n)\n\ndefineSlots<{ default?(props: AnnotationSlotProps): unknown }>()\n\nconst ctx = injectInkContext()\n\nconst observed = shallowRef<AnnotationState | null>(null)\nlet observer: MutationObserver | undefined\nfunction readState(el: HTMLElement): AnnotationState | null {\n const s = el.dataset.state\n return s === 'idle' || s === 'hover' || s === 'selected' ? s : null\n}\nwatch(\n () => props.element,\n (el) => {\n observer?.disconnect()\n observer = undefined\n observed.value = el ? readState(el) : null\n if (!el) return\n observer = new MutationObserver(() => {\n observed.value = readState(el)\n })\n observer.observe(el, { attributes: true, attributeFilter: ['data-state'] })\n },\n { immediate: true }\n)\nonBeforeUnmount(() => observer?.disconnect())\n\nconst slotProps = computed<AnnotationSlotProps>(() => {\n const { id } = props.annotation\n const store = () => ctx.document.value?.annotations\n return {\n annotation: props.annotation,\n state: observed.value ?? (ctx.selection.value.includes(id) ? 'selected' : 'idle'),\n locked: props.annotation.locked === true,\n select: () => store()?.select([id]),\n remove: () => void store()?.remove(id),\n }\n})\n</script>\n\n<template>\n <slot v-bind=\"slotProps\" />\n</template>\n"],"mappings":";;;;;;;;;;EAaA,IAAMI,IAAQC,GAWRC,IAAMC,EAAiB,GAEvBC,IAAWC,EAAmC,IAAI,GACpDC;EACJ,SAASC,EAAU,GAAyC;GAC1D,IAAMC,IAAIC,EAAG,QAAQ;GACrB,OAAOD,MAAM,UAAUA,MAAM,WAAWA,MAAM,aAAaA,IAAI;EACjE;EAeA,AAdAE,QACQV,EAAM,UACX,MAAO;GAIN,AAHAM,GAAU,WAAW,GACrB,IAAW,KAAA,GACX,EAAS,QAAQG,IAAKF,EAAUE,CAAE,IAAI,MACjCA,MACL,IAAW,IAAI,uBAAuB;IACpC,EAAS,QAAQF,EAAUE,CAAE;GAC/B,CAAC,GACDH,EAAS,QAAQG,GAAI;IAAE,YAAY;IAAM,iBAAiB,CAAC,YAAY;GAAE,CAAC;EAC5E,GACA,EAAE,WAAW,GAAK,CACpB,GACAE,QAAsBL,GAAU,WAAW,CAAC;EAE5C,IAAMM,IAAYC,QAAoC;GACpD,IAAM,EAAE,UAAOb,EAAM,YACfc,UAAcZ,EAAI,SAAS,OAAO;GACxC,OAAO;IACL,YAAYF,EAAM;IAClB,OAAOI,EAAS,UAAUF,EAAI,UAAU,MAAM,SAASa,CAAE,IAAI,aAAa;IAC1E,QAAQf,EAAM,WAAW,WAAW;IACpC,cAAcc,EAAM,CAAC,EAAE,OAAO,CAACC,CAAE,CAAC;IAClC,cAAc,KAAKD,EAAM,CAAC,EAAE,OAAOC,CAAE;GACvC;EACF,CAAC;mBAICnB,EAA2BqB,EAAA,QAAA,WAAApB,EAAAC,EAAbc,EAAA,KAAS,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkColorMenu.js","names":["_sfc_main","InkColorMenu_vue_vue_type_script_setup_true_lang_default","InkColorMenu_default"],"sources":["../../src/components/InkColorMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A colour menu for one colour property (border, fill or text) of the selection or the active\n * tool. The trigger shows the current colour as a swatch: split when the selection disagrees,\n * slashed for no fill. The panel is a palette grid, plus \"No fill\" for `fill` and \"Custom…\",\n * which opens a native colour input. The menu disables when nothing supports the property.\n */\nimport {\n COLOR_COLUMNS,\n colorMenuModel,\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n type ColorProperty,\n} from '@inkbar/core/dom'\nimport { Check } from '@inkbar/icons'\nimport {\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n ToolbarButton,\n} from 'reka-ui'\nimport { computed, defineComponent, mergeProps, ref, useAttrs, watch } from 'vue'\n\nimport { useToolStyle } from '../composables/useToolStyle'\n\nimport InkIcon from './InkIcon.vue'\n\nimport type { StyleGroup } from '@inkbar/core'\n\ndefineOptions({ inheritAttrs: false })\nconst attrs = useAttrs()\n\n/** Stands in for the toolbar item when the menu is nested in another panel. */\nconst PassThrough = defineComponent({\n inheritAttrs: false,\n setup:\n (_, { slots }) =>\n () =>\n slots.default?.(),\n})\n\nconst props = defineProps<{\n /** The colour this menu sets. */\n property: ColorProperty\n /** Accessible name; defaults to \"Border colour\", \"Fill colour\" or \"Text colour\". */\n label?: string\n /**\n * Renders the trigger outside the toolbar's roving focus, for a menu nested in another\n * panel (the text style menu's text colour).\n */\n standalone?: boolean\n /**\n * Scopes the menu to one style group: it shows and sets that group's colour whatever tool\n * is active, and recolours the selection only when it is all in the group.\n */\n group?: StyleGroup | undefined\n}>()\n\nconst { current, supported, set } = useToolStyle(() => props.group)\nconst open = ref(false)\nconst customInput = ref<HTMLInputElement | null>(null)\n\nconst model = computed(() =>\n colorMenuModel(props.property, current.value, supported.value)\n)\nconst name = computed(() => props.label ?? model.value.label)\nconst trigger = computed(() => model.value.trigger)\n\n// The menu closes when the control disables (the selection cleared while it was open).\nwatch(\n () => model.value.enabled,\n (enabled) => {\n if (!enabled) open.value = false\n }\n)\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 || !model.value.enabled)\n 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(\n `[data-ink-menu=\"color-${props.property}\"] [role=\"menu\"]`\n )\n if (menu) {\n if (focusFirst) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n }\n focusFirst = false\n}\n\n// Reka's typed props stop at its own; ARIA goes through bound objects.\nconst triggerAttrs = computed(() => ({\n 'aria-label': name.value,\n title: name.value,\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n 'data-mixed': model.value.mixed ? '' : undefined,\n}))\n/**\n * The trigger's bindings over the host's: both keydown listeners run, the host's first, and a\n * host `disabled` can disable the trigger but not enable it.\n */\nconst triggerBindings = computed(() =>\n mergeProps(attrs, triggerAttrs.value, {\n disabled: (attrs.disabled ?? false) !== false || !model.value.enabled,\n })\n)\nconst menuAttrs = computed(() => ({ 'aria-label': name.value }))\nconst innerAttrs = computed(() => ({\n role: 'menu',\n 'aria-label': name.value,\n onKeydown: (e: KeyboardEvent) => handleMenuKeys(e, e.currentTarget as HTMLElement),\n}))\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <component :is=\"standalone ? PassThrough : ToolbarButton\" as-child>\n <PopoverTrigger as-child>\n <button\n type=\"button\"\n class=\"ink-menu-trigger ink-color-menu\"\n :data-ink-color-menu=\"property\"\n :data-state=\"open ? 'open' : 'closed'\"\n v-bind=\"triggerBindings\"\n >\n <slot>\n <span\n class=\"ink-swatch\"\n data-ink-swatch\n aria-hidden=\"true\"\n :data-property=\"property\"\n :data-kind=\"trigger.kind\"\n :data-color=\"trigger.kind === 'color' ? trigger.color : undefined\"\n :style=\"\n trigger.kind === 'color' ? { '--ink-swatch': trigger.color } : undefined\n \"\n />\n </slot>\n </button>\n </PopoverTrigger>\n </component>\n <PopoverPortal>\n <PopoverContent\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n :data-ink-menu=\"`color-${property}`\"\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 <button\n v-if=\"model.noFill\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-select-item ink-menu-item\"\n data-ink-select-item\n tabindex=\"-1\"\n :aria-checked=\"model.noFill.checked\"\n :data-state=\"model.noFill.checked ? 'checked' : 'unchecked'\"\n @click=\"set(model.noFill.patch)\"\n >\n No fill\n <span v-if=\"model.noFill.checked\" class=\"ink-select-indicator\">\n <InkIcon :icon=\"Check\" :size=\"16\" />\n </span>\n </button>\n <div\n role=\"group\"\n aria-label=\"Colours\"\n class=\"ink-color-grid\"\n :data-ink-menu-columns=\"COLOR_COLUMNS\"\n >\n <button\n v-for=\"sw in model.swatches\"\n :key=\"sw.key\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-swatch-item\"\n tabindex=\"-1\"\n :aria-label=\"sw.label\"\n :aria-checked=\"sw.checked\"\n :data-state=\"sw.checked ? 'checked' : 'unchecked'\"\n :style=\"{ '--ink-swatch': sw.color }\"\n @click=\"set(sw.patch)\"\n />\n </div>\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"ink-select-item ink-menu-item\"\n data-ink-select-item\n tabindex=\"-1\"\n @click=\"customInput?.click()\"\n >\n Custom…\n </button>\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <input\n ref=\"customInput\"\n type=\"color\"\n class=\"ink-color-input\"\n aria-label=\"Custom colour\"\n :data-ink-color-input=\"property\"\n tabindex=\"-1\"\n :value=\"model.customValue.toLowerCase()\"\n @change=\"set(model.custom(($event.target as HTMLInputElement).value))\"\n />\n</template>\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"InkColorMenu.js","names":["_sfc_main","InkColorMenu_vue_vue_type_script_setup_true_lang_default","InkColorMenu_default"],"sources":["../../src/components/InkColorMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A colour menu for one colour property (border, fill or text) of the selection or the active\n * tool. The trigger shows the current colour as a swatch: split when the selection disagrees,\n * slashed for no fill. The panel is a palette grid, plus \"No fill\" for `fill` and \"Custom…\",\n * which opens a native colour input. The menu disables when nothing supports the property.\n */\nimport {\n COLOR_COLUMNS,\n colorMenuModel,\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n type ColorProperty,\n} from '@inkbar/core/dom'\nimport { Check } from '@inkbar/icons'\nimport {\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n ToolbarButton,\n} from 'reka-ui'\nimport { computed, defineComponent, mergeProps, ref, useAttrs, watch } from 'vue'\n\nimport { useToolStyle } from '../composables/useToolStyle'\n\nimport InkIcon from './InkIcon.vue'\n\nimport type { StyleGroup } from '@inkbar/core'\n\ndefineOptions({ inheritAttrs: false })\nconst attrs = useAttrs()\n\n/** Stands in for the toolbar item when the menu is nested in another panel. */\nconst PassThrough = defineComponent({\n inheritAttrs: false,\n setup:\n (_, { slots }) =>\n () =>\n slots.default?.(),\n})\n\nconst props = defineProps<{\n /** The colour this menu sets. */\n property: ColorProperty\n /** Accessible name; defaults to \"Border colour\", \"Fill colour\" or \"Text colour\". */\n label?: string\n /**\n * Renders the trigger outside the toolbar's roving focus, for a menu nested in another\n * panel (the text style menu's text colour).\n */\n standalone?: boolean\n /**\n * Scopes the menu to one style group: it shows and sets that group's colour whatever tool\n * is active, and recolours the selection only when it is all in the group.\n */\n group?: StyleGroup | undefined\n /** The colour new annotations get while the style leaves it unset; the swatch shows it. */\n fallback?: string | undefined\n}>()\n\nconst { current, supported, set } = useToolStyle(() => props.group)\nconst open = ref(false)\nconst customInput = ref<HTMLInputElement | null>(null)\n\nconst model = computed(() =>\n colorMenuModel(props.property, current.value, supported.value, props.fallback)\n)\nconst name = computed(() => props.label ?? model.value.label)\nconst trigger = computed(() => model.value.trigger)\n\n// The menu closes when the control disables (the selection cleared while it was open).\nwatch(\n () => model.value.enabled,\n (enabled) => {\n if (!enabled) open.value = false\n }\n)\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 || !model.value.enabled)\n 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(\n `[data-ink-menu=\"color-${props.property}\"] [role=\"menu\"]`\n )\n if (menu) {\n if (focusFirst) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n }\n focusFirst = false\n}\n\n// Reka's typed props stop at its own; ARIA goes through bound objects.\nconst triggerAttrs = computed(() => ({\n 'aria-label': name.value,\n title: name.value,\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n 'data-mixed': model.value.mixed ? '' : undefined,\n}))\n/**\n * The trigger's bindings over the host's: both keydown listeners run, the host's first, and a\n * host `disabled` can disable the trigger but not enable it.\n */\nconst triggerBindings = computed(() =>\n mergeProps(attrs, triggerAttrs.value, {\n disabled: (attrs.disabled ?? false) !== false || !model.value.enabled,\n })\n)\nconst menuAttrs = computed(() => ({ 'aria-label': name.value }))\nconst innerAttrs = computed(() => ({\n role: 'menu',\n 'aria-label': name.value,\n onKeydown: (e: KeyboardEvent) => handleMenuKeys(e, e.currentTarget as HTMLElement),\n}))\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <component :is=\"standalone ? PassThrough : ToolbarButton\" as-child>\n <PopoverTrigger as-child>\n <button\n type=\"button\"\n class=\"ink-menu-trigger ink-color-menu\"\n :data-ink-color-menu=\"property\"\n :data-state=\"open ? 'open' : 'closed'\"\n v-bind=\"triggerBindings\"\n >\n <slot>\n <span\n class=\"ink-swatch\"\n data-ink-swatch\n aria-hidden=\"true\"\n :data-property=\"property\"\n :data-kind=\"trigger.kind\"\n :data-color=\"trigger.kind === 'color' ? trigger.color : undefined\"\n :style=\"\n trigger.kind === 'color' ? { '--ink-swatch': trigger.color } : undefined\n \"\n />\n </slot>\n </button>\n </PopoverTrigger>\n </component>\n <PopoverPortal>\n <PopoverContent\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n :data-ink-menu=\"`color-${property}`\"\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 <button\n v-if=\"model.noFill\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-select-item ink-menu-item\"\n data-ink-select-item\n tabindex=\"-1\"\n :aria-checked=\"model.noFill.checked\"\n :data-state=\"model.noFill.checked ? 'checked' : 'unchecked'\"\n @click=\"set(model.noFill.patch)\"\n >\n No fill\n <span v-if=\"model.noFill.checked\" class=\"ink-select-indicator\">\n <InkIcon :icon=\"Check\" :size=\"16\" />\n </span>\n </button>\n <div\n role=\"group\"\n aria-label=\"Colours\"\n class=\"ink-color-grid\"\n :data-ink-menu-columns=\"COLOR_COLUMNS\"\n >\n <button\n v-for=\"sw in model.swatches\"\n :key=\"sw.key\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-swatch-item\"\n tabindex=\"-1\"\n :aria-label=\"sw.label\"\n :aria-checked=\"sw.checked\"\n :data-state=\"sw.checked ? 'checked' : 'unchecked'\"\n :style=\"{ '--ink-swatch': sw.color }\"\n @click=\"set(sw.patch)\"\n />\n </div>\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"ink-select-item ink-menu-item\"\n data-ink-select-item\n tabindex=\"-1\"\n @click=\"customInput?.click()\"\n >\n Custom…\n </button>\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <input\n ref=\"customInput\"\n type=\"color\"\n class=\"ink-color-input\"\n aria-label=\"Custom colour\"\n :data-ink-color-input=\"property\"\n tabindex=\"-1\"\n :value=\"model.customValue.toLowerCase()\"\n @change=\"set(model.custom(($event.target as HTMLInputElement).value))\"\n />\n</template>\n"],"mappings":""}
|
|
@@ -15,6 +15,8 @@ type __VLS_Props = {
|
|
|
15
15
|
* is active, and recolours the selection only when it is all in the group.
|
|
16
16
|
*/
|
|
17
17
|
group?: StyleGroup | undefined;
|
|
18
|
+
/** The colour new annotations get while the style leaves it unset; the swatch shows it. */
|
|
19
|
+
fallback?: string | undefined;
|
|
18
20
|
};
|
|
19
21
|
declare var __VLS_21: {};
|
|
20
22
|
type __VLS_Slots = {} & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkColorMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkColorMenu.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"InkColorMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkColorMenu.vue"],"names":[],"mappings":"AA6OA,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAA;AAezB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAe9C,KAAK,WAAW,GAAG;IACjB,iCAAiC;IACjC,QAAQ,EAAE,aAAa,CAAA;IACvB,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAA;IAC9B,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC9B,CAAC;AAqTF,QAAA,IAAI,QAAQ,IAAY,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"}
|
|
@@ -24,13 +24,14 @@ var P = ["data-ink-color-menu", "data-state"], F = [
|
|
|
24
24
|
property: {},
|
|
25
25
|
label: {},
|
|
26
26
|
standalone: { type: Boolean },
|
|
27
|
-
group: {}
|
|
27
|
+
group: {},
|
|
28
|
+
fallback: {}
|
|
28
29
|
},
|
|
29
30
|
setup(V) {
|
|
30
31
|
let H = b(), U = l({
|
|
31
32
|
inheritAttrs: !1,
|
|
32
33
|
setup: (e, { slots: t }) => () => t.default?.()
|
|
33
|
-
}), W = V, { current: G, supported: K, set: q } = e(() => W.group), J = h(!1), Y = h(null), X = r(() => w(W.property, G.value, K.value)), Z = r(() => W.label ?? X.value.label), Q = r(() => X.value.trigger);
|
|
34
|
+
}), W = V, { current: G, supported: K, set: q } = e(() => W.group), J = h(!1), Y = h(null), X = r(() => w(W.property, G.value, K.value, W.fallback)), Z = r(() => W.label ?? X.value.label), Q = r(() => X.value.trigger);
|
|
34
35
|
x(() => X.value.enabled, (e) => {
|
|
35
36
|
e || (J.value = !1);
|
|
36
37
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkColorMenu.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_Fragment","_createVNode","_unref","_withCtx","_createBlock","_resolveDynamicComponent","_createElementVNode","_mergeProps","_renderSlot","_normalizeStyle","_normalizeProps","_guardReactiveProps","_createTextVNode","InkIcon","_createCommentVNode","_renderList","InkIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","InkColorMenu_vue_vue_type_script_setup_true_lang_default","attrs","useAttrs","PassThrough","defineComponent","slots","props","__props","useToolStyle","open","ref","customInput","model","computed","colorMenuModel","current","supported","name","trigger","enabled","focusFirst","onTriggerKeydown","onOpenAutoFocus","menu","menuItems","focusInitialMenuItem","triggerAttrs","triggerBindings","mergeProps","menuAttrs","innerAttrs","handleMenuKeys","openBlock","createElementBlock","Fragment","createVNode","unref","PopoverRoot","_cache","$event","withCtx","createBlock","resolveDynamicComponent","ToolbarButton","PopoverTrigger","createElementVNode","renderSlot","_ctx","normalizeStyle","PopoverPortal","PopoverContent","normalizeProps","guardReactiveProps","set","createTextVNode","Check","createCommentVNode","COLOR_COLUMNS","renderList","sw"],"sources":["../../src/components/InkColorMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A colour menu for one colour property (border, fill or text) of the selection or the active\n * tool. The trigger shows the current colour as a swatch: split when the selection disagrees,\n * slashed for no fill. The panel is a palette grid, plus \"No fill\" for `fill` and \"Custom…\",\n * which opens a native colour input. The menu disables when nothing supports the property.\n */\nimport {\n COLOR_COLUMNS,\n colorMenuModel,\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n type ColorProperty,\n} from '@inkbar/core/dom'\nimport { Check } from '@inkbar/icons'\nimport {\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n ToolbarButton,\n} from 'reka-ui'\nimport { computed, defineComponent, mergeProps, ref, useAttrs, watch } from 'vue'\n\nimport { useToolStyle } from '../composables/useToolStyle'\n\nimport InkIcon from './InkIcon.vue'\n\nimport type { StyleGroup } from '@inkbar/core'\n\ndefineOptions({ inheritAttrs: false })\nconst attrs = useAttrs()\n\n/** Stands in for the toolbar item when the menu is nested in another panel. */\nconst PassThrough = defineComponent({\n inheritAttrs: false,\n setup:\n (_, { slots }) =>\n () =>\n slots.default?.(),\n})\n\nconst props = defineProps<{\n /** The colour this menu sets. */\n property: ColorProperty\n /** Accessible name; defaults to \"Border colour\", \"Fill colour\" or \"Text colour\". */\n label?: string\n /**\n * Renders the trigger outside the toolbar's roving focus, for a menu nested in another\n * panel (the text style menu's text colour).\n */\n standalone?: boolean\n /**\n * Scopes the menu to one style group: it shows and sets that group's colour whatever tool\n * is active, and recolours the selection only when it is all in the group.\n */\n group?: StyleGroup | undefined\n}>()\n\nconst { current, supported, set } = useToolStyle(() => props.group)\nconst open = ref(false)\nconst customInput = ref<HTMLInputElement | null>(null)\n\nconst model = computed(() =>\n colorMenuModel(props.property, current.value, supported.value)\n)\nconst name = computed(() => props.label ?? model.value.label)\nconst trigger = computed(() => model.value.trigger)\n\n// The menu closes when the control disables (the selection cleared while it was open).\nwatch(\n () => model.value.enabled,\n (enabled) => {\n if (!enabled) open.value = false\n }\n)\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 || !model.value.enabled)\n 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(\n `[data-ink-menu=\"color-${props.property}\"] [role=\"menu\"]`\n )\n if (menu) {\n if (focusFirst) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n }\n focusFirst = false\n}\n\n// Reka's typed props stop at its own; ARIA goes through bound objects.\nconst triggerAttrs = computed(() => ({\n 'aria-label': name.value,\n title: name.value,\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n 'data-mixed': model.value.mixed ? '' : undefined,\n}))\n/**\n * The trigger's bindings over the host's: both keydown listeners run, the host's first, and a\n * host `disabled` can disable the trigger but not enable it.\n */\nconst triggerBindings = computed(() =>\n mergeProps(attrs, triggerAttrs.value, {\n disabled: (attrs.disabled ?? false) !== false || !model.value.enabled,\n })\n)\nconst menuAttrs = computed(() => ({ 'aria-label': name.value }))\nconst innerAttrs = computed(() => ({\n role: 'menu',\n 'aria-label': name.value,\n onKeydown: (e: KeyboardEvent) => handleMenuKeys(e, e.currentTarget as HTMLElement),\n}))\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <component :is=\"standalone ? PassThrough : ToolbarButton\" as-child>\n <PopoverTrigger as-child>\n <button\n type=\"button\"\n class=\"ink-menu-trigger ink-color-menu\"\n :data-ink-color-menu=\"property\"\n :data-state=\"open ? 'open' : 'closed'\"\n v-bind=\"triggerBindings\"\n >\n <slot>\n <span\n class=\"ink-swatch\"\n data-ink-swatch\n aria-hidden=\"true\"\n :data-property=\"property\"\n :data-kind=\"trigger.kind\"\n :data-color=\"trigger.kind === 'color' ? trigger.color : undefined\"\n :style=\"\n trigger.kind === 'color' ? { '--ink-swatch': trigger.color } : undefined\n \"\n />\n </slot>\n </button>\n </PopoverTrigger>\n </component>\n <PopoverPortal>\n <PopoverContent\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n :data-ink-menu=\"`color-${property}`\"\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 <button\n v-if=\"model.noFill\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-select-item ink-menu-item\"\n data-ink-select-item\n tabindex=\"-1\"\n :aria-checked=\"model.noFill.checked\"\n :data-state=\"model.noFill.checked ? 'checked' : 'unchecked'\"\n @click=\"set(model.noFill.patch)\"\n >\n No fill\n <span v-if=\"model.noFill.checked\" class=\"ink-select-indicator\">\n <InkIcon :icon=\"Check\" :size=\"16\" />\n </span>\n </button>\n <div\n role=\"group\"\n aria-label=\"Colours\"\n class=\"ink-color-grid\"\n :data-ink-menu-columns=\"COLOR_COLUMNS\"\n >\n <button\n v-for=\"sw in model.swatches\"\n :key=\"sw.key\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-swatch-item\"\n tabindex=\"-1\"\n :aria-label=\"sw.label\"\n :aria-checked=\"sw.checked\"\n :data-state=\"sw.checked ? 'checked' : 'unchecked'\"\n :style=\"{ '--ink-swatch': sw.color }\"\n @click=\"set(sw.patch)\"\n />\n </div>\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"ink-select-item ink-menu-item\"\n data-ink-select-item\n tabindex=\"-1\"\n @click=\"customInput?.click()\"\n >\n Custom…\n </button>\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <input\n ref=\"customInput\"\n type=\"color\"\n class=\"ink-color-input\"\n aria-label=\"Custom colour\"\n :data-ink-color-input=\"property\"\n tabindex=\"-1\"\n :value=\"model.customValue.toLowerCase()\"\n @change=\"set(model.custom(($event.target as HTMLInputElement).value))\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCA,IAAM2B,IAAQC,EAAS,GAGjBC,IAAcC,EAAgB;GAClC,cAAc;GACd,QACG,GAAG,EAAE,qBAEJC,EAAM,UAAU;EACtB,CAAC,GAEKC,IAAQC,GAiBR,EAAE,YAAS,cAAW,WAAQC,QAAmBF,EAAM,KAAK,GAC5DG,IAAOC,EAAI,EAAK,GAChBC,IAAcD,EAA6B,IAAI,GAE/CE,IAAQC,QACZC,EAAeR,EAAM,UAAUS,EAAQ,OAAOC,EAAU,KAAK,CAC/D,GACMC,IAAOJ,QAAeP,EAAM,SAASM,EAAM,MAAM,KAAK,GACtDM,IAAUL,QAAeD,EAAM,MAAM,OAAO;EAGlD,QACQA,EAAM,MAAM,UACjB,MAAY;GACX,AAAKO,MAAS,EAAK,QAAQ;EAC7B,CACF;EAGA,IAAIC,IAAa;EACjB,SAASC,GAAiB,GAAwB;GAChD,AAAI,EAAE,QAAQ,eAAe,EAAE,oBAAoBZ,EAAK,SAAS,CAACG,EAAM,MAAM,YAE9E,EAAE,eAAe,GACjB,IAAa,IACb,EAAK,QAAQ;EACf;EAEA,SAASU,GAAgB,GAAgB;GACvC,EAAE,eAAe;GAEjB,IAAMC,IAAO,SAAS,cACpB,yBAAyBjB,EAAM,SAAS,iBAC1C;GAKA,AAJIiB,MACEH,IAAYI,EAAUD,CAAI,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,GAAK,CAAC,IAC5DE,EAAqBF,CAAI,IAEhC,IAAa;EACf;EAGA,IAAMG,KAAeb,SAAgB;GACnC,cAAcI,EAAK;GACnB,OAAOA,EAAK;GACZ,iBAAiB;GACjB,WAAWI;GACX,cAAcT,EAAM,MAAM,QAAQ,KAAK,KAAA;EACzC,EAAE,GAKIe,KAAkBd,QACtBe,EAAW3B,GAAOyB,GAAa,OAAO,EACpC,WAAWzB,EAAM,YAAY,QAAW,MAAS,CAACW,EAAM,MAAM,QAChE,CAAC,CACH,GACMiB,KAAYhB,SAAgB,EAAE,cAAcI,EAAK,MAAM,EAAE,GACzDa,KAAajB,SAAgB;GACjC,MAAM;GACN,cAAcI,EAAK;GACnB,YAAY,MAAqBc,EAAe,GAAG,EAAE,aAA4B;EACnF,EAAE;oBAIAtD,EAAAA,GAAAA,EAAAA,GAAAA,MAAAA,CAAAA,EAwFcC,EAAA2D,CAAA,GAAA;GAxFO,MAAM5B,EAAA;GAAA,iBAAA,AAAA6B,EAAA,QAAA,MAAA,EAAI,QAAAC;;GAC7B,SAAA5D,QAwBY,EAxBZL,EAAA,GAAAM,GAwBYC,EAxBI0B,EAAA,aAAa7B,EAAAyB,CAAA,IAAczB,EAAAiE,CAAA,CAAa,GAAA,EAAE,YAAA,GAAQ,GAAA;IAChE,SAAAhE,QAsBiB,CAtBjBF,EAsBiBC,EAAAkE,CAAA,GAAA,EAtBD,YAAA,GAAQ,GAAA;KACtB,SAAAjE,QAoBS,CApBTG,EAoBS,UApBTC,EAoBS;MAnBP,MAAK;MACL,OAAM;MACL,uBAAqBwB,EAAA;MACrB,cAAYE,EAAA,QAAI,SAAA;KACT,GAAAkB,GAAA,KAAe,GAAA,CAEvB3C,EAYO+D,EAAA,QAAA,WAAA,CAAA,SAAA,CAXLjE,EAUE,QAAA;MATA,OAAM;MACN,mBAAA;MACA,eAAY;MACX,iBAAeyB,EAAA;MACf,aAAWW,EAAA,MAAQ;MACnB,cAAYA,EAAA,MAAQ,SAAI,UAAeA,EAAA,MAAQ,QAAQ,KAAA;MACvD,OAAKjC,EAAmBiC,EAAA,MAAQ,SAAI,UAAA,EAAA,gBAAiCA,EAAA,MAAQ,MAAK,IAAK,KAAA,CAAA;;;;;GAQlGzC,CAAAA,IAAAA,EA6DgBC,EAAAuE,CAAA,GAAA,MAAA;IA5Dd,SAAAtE,QA2DiB,CA3DjBF,EA2DiBC,EAAAwE,CAAA,GA3DjBnE,EA2DiB;KA1Df,OAAM;KACN,2BAAA;KACC,iBAAa,SAAWwB,EAAA;KACzB,MAAK;KACL,OAAM;KACL,eAAa;KACb,qBAAmB;IACZ,GAAAsB,GAAA,OAAS,EACC,oBAAe,CAAA,GAAA;KAEjC,SAAAlD,QA+CM,CA/CNG,EA+CM,OAAAI,EAAAC,EA/CO2C,GAAA,KAAU,CAAA,GAAA;MAEblB,EAAA,MAAM,UADdtC,EAAA,GAAAC,EAeS,UAAA;;OAbP,MAAK;OACL,MAAK;OACL,OAAM;OACN,wBAAA;OACA,UAAS;OACR,gBAAcqC,EAAA,MAAM,OAAO;OAC3B,cAAYA,EAAA,MAAM,OAAO,UAAO,YAAA;OAChC,SAAK,AAAA0B,EAAA,QAAA,MAAE5D,EAAA2E,CAAA,CAAG,CAACzC,EAAA,MAAM,OAAO,KAAK;MAC/B,GAAA,CAAA,AAAA0B,EAAA,OAAAlD,EAAA,aAEC,EAAA,GAAYwB,EAAA,MAAM,OAAO,WAAzBtC,EAAA,GAAAC,EAEO,QAFPqB,GAEO,CADLnB,EAAoCY,GAAA;OAA1B,MAAMX,EAAA6E,CAAA;OAAQ,MAAM;;MAGlCzE,EAmBM,OAAA;OAlBJ,MAAK;OACL,cAAW;OACX,OAAM;OACL,yBAAuBJ,EAAA+E,CAAA;MAExBnF,GAAAA,EAAAA,EAAA,EAAA,GAAAC,EAYEC,GAAA,MAAAe,EAXaqB,EAAA,MAAM,WAAZ,OADTtC,EAAA,GAAAC,EAYE,UAAA;OAVC,KAAKoF,EAAG;OACT,MAAK;OACL,MAAK;OACL,OAAM;OACN,UAAS;OACR,cAAYA,EAAG;OACf,gBAAcA,EAAG;OACjB,cAAYA,EAAG,UAAO,YAAA;OACtB,OAAK1E,EAAA,EAAA,gBAAoB0E,EAAG,MAAK,CAAA;OACjC,UAAK,MAAEjF,EAAA2E,CAAA,CAAG,CAACM,EAAG,KAAK;;MAGxB7E,EASS,UAAA;OARP,MAAK;OACL,MAAK;OACL,OAAM;OACN,wBAAA;OACA,UAAS;OACR,SAAK,AAAAwD,EAAA,QAAA,MAAE3B,EAAA,OAAa,MAAK;MAC3B,GAAA,WAED;;;;;;;EAKR7B,GAAAA,GAAAA,CAAAA,MAAAA,CAAAA,GAAAA,EASE,SAAA;GARI,SAAA;GAAJ,KAAI6B;GACJ,MAAK;GACL,OAAM;GACN,cAAW;GACV,wBAAsBJ,EAAA;GACvB,UAAS;GACR,OAAOK,EAAA,MAAM,YAAY,YAAW;GACpC,UAAM,AAAA0B,EAAA,QAAA,MAAE5D,EAAA2E,CAAA,CAAG,CAACzC,EAAA,MAAM,OAAQ2B,EAAO,OAA4B,KAAK,CAAA"}
|
|
1
|
+
{"version":3,"file":"InkColorMenu.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_Fragment","_createVNode","_unref","_withCtx","_createBlock","_resolveDynamicComponent","_createElementVNode","_mergeProps","_renderSlot","_normalizeStyle","_normalizeProps","_guardReactiveProps","_createTextVNode","InkIcon","_createCommentVNode","_renderList","InkIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","InkColorMenu_vue_vue_type_script_setup_true_lang_default","attrs","useAttrs","PassThrough","defineComponent","slots","props","__props","useToolStyle","open","ref","customInput","model","computed","colorMenuModel","current","supported","name","trigger","enabled","focusFirst","onTriggerKeydown","onOpenAutoFocus","menu","menuItems","focusInitialMenuItem","triggerAttrs","triggerBindings","mergeProps","menuAttrs","innerAttrs","handleMenuKeys","openBlock","createElementBlock","Fragment","createVNode","unref","PopoverRoot","_cache","$event","withCtx","createBlock","resolveDynamicComponent","ToolbarButton","PopoverTrigger","createElementVNode","renderSlot","_ctx","normalizeStyle","PopoverPortal","PopoverContent","normalizeProps","guardReactiveProps","set","createTextVNode","Check","createCommentVNode","COLOR_COLUMNS","renderList","sw"],"sources":["../../src/components/InkColorMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A colour menu for one colour property (border, fill or text) of the selection or the active\n * tool. The trigger shows the current colour as a swatch: split when the selection disagrees,\n * slashed for no fill. The panel is a palette grid, plus \"No fill\" for `fill` and \"Custom…\",\n * which opens a native colour input. The menu disables when nothing supports the property.\n */\nimport {\n COLOR_COLUMNS,\n colorMenuModel,\n focusInitialMenuItem,\n handleMenuKeys,\n menuItems,\n type ColorProperty,\n} from '@inkbar/core/dom'\nimport { Check } from '@inkbar/icons'\nimport {\n PopoverContent,\n PopoverPortal,\n PopoverRoot,\n PopoverTrigger,\n ToolbarButton,\n} from 'reka-ui'\nimport { computed, defineComponent, mergeProps, ref, useAttrs, watch } from 'vue'\n\nimport { useToolStyle } from '../composables/useToolStyle'\n\nimport InkIcon from './InkIcon.vue'\n\nimport type { StyleGroup } from '@inkbar/core'\n\ndefineOptions({ inheritAttrs: false })\nconst attrs = useAttrs()\n\n/** Stands in for the toolbar item when the menu is nested in another panel. */\nconst PassThrough = defineComponent({\n inheritAttrs: false,\n setup:\n (_, { slots }) =>\n () =>\n slots.default?.(),\n})\n\nconst props = defineProps<{\n /** The colour this menu sets. */\n property: ColorProperty\n /** Accessible name; defaults to \"Border colour\", \"Fill colour\" or \"Text colour\". */\n label?: string\n /**\n * Renders the trigger outside the toolbar's roving focus, for a menu nested in another\n * panel (the text style menu's text colour).\n */\n standalone?: boolean\n /**\n * Scopes the menu to one style group: it shows and sets that group's colour whatever tool\n * is active, and recolours the selection only when it is all in the group.\n */\n group?: StyleGroup | undefined\n /** The colour new annotations get while the style leaves it unset; the swatch shows it. */\n fallback?: string | undefined\n}>()\n\nconst { current, supported, set } = useToolStyle(() => props.group)\nconst open = ref(false)\nconst customInput = ref<HTMLInputElement | null>(null)\n\nconst model = computed(() =>\n colorMenuModel(props.property, current.value, supported.value, props.fallback)\n)\nconst name = computed(() => props.label ?? model.value.label)\nconst trigger = computed(() => model.value.trigger)\n\n// The menu closes when the control disables (the selection cleared while it was open).\nwatch(\n () => model.value.enabled,\n (enabled) => {\n if (!enabled) open.value = false\n }\n)\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 || !model.value.enabled)\n 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(\n `[data-ink-menu=\"color-${props.property}\"] [role=\"menu\"]`\n )\n if (menu) {\n if (focusFirst) menuItems(menu)[0]?.focus({ preventScroll: true })\n else focusInitialMenuItem(menu)\n }\n focusFirst = false\n}\n\n// Reka's typed props stop at its own; ARIA goes through bound objects.\nconst triggerAttrs = computed(() => ({\n 'aria-label': name.value,\n title: name.value,\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n 'data-mixed': model.value.mixed ? '' : undefined,\n}))\n/**\n * The trigger's bindings over the host's: both keydown listeners run, the host's first, and a\n * host `disabled` can disable the trigger but not enable it.\n */\nconst triggerBindings = computed(() =>\n mergeProps(attrs, triggerAttrs.value, {\n disabled: (attrs.disabled ?? false) !== false || !model.value.enabled,\n })\n)\nconst menuAttrs = computed(() => ({ 'aria-label': name.value }))\nconst innerAttrs = computed(() => ({\n role: 'menu',\n 'aria-label': name.value,\n onKeydown: (e: KeyboardEvent) => handleMenuKeys(e, e.currentTarget as HTMLElement),\n}))\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <component :is=\"standalone ? PassThrough : ToolbarButton\" as-child>\n <PopoverTrigger as-child>\n <button\n type=\"button\"\n class=\"ink-menu-trigger ink-color-menu\"\n :data-ink-color-menu=\"property\"\n :data-state=\"open ? 'open' : 'closed'\"\n v-bind=\"triggerBindings\"\n >\n <slot>\n <span\n class=\"ink-swatch\"\n data-ink-swatch\n aria-hidden=\"true\"\n :data-property=\"property\"\n :data-kind=\"trigger.kind\"\n :data-color=\"trigger.kind === 'color' ? trigger.color : undefined\"\n :style=\"\n trigger.kind === 'color' ? { '--ink-swatch': trigger.color } : undefined\n \"\n />\n </slot>\n </button>\n </PopoverTrigger>\n </component>\n <PopoverPortal>\n <PopoverContent\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n :data-ink-menu=\"`color-${property}`\"\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 <button\n v-if=\"model.noFill\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-select-item ink-menu-item\"\n data-ink-select-item\n tabindex=\"-1\"\n :aria-checked=\"model.noFill.checked\"\n :data-state=\"model.noFill.checked ? 'checked' : 'unchecked'\"\n @click=\"set(model.noFill.patch)\"\n >\n No fill\n <span v-if=\"model.noFill.checked\" class=\"ink-select-indicator\">\n <InkIcon :icon=\"Check\" :size=\"16\" />\n </span>\n </button>\n <div\n role=\"group\"\n aria-label=\"Colours\"\n class=\"ink-color-grid\"\n :data-ink-menu-columns=\"COLOR_COLUMNS\"\n >\n <button\n v-for=\"sw in model.swatches\"\n :key=\"sw.key\"\n type=\"button\"\n role=\"menuitemradio\"\n class=\"ink-swatch-item\"\n tabindex=\"-1\"\n :aria-label=\"sw.label\"\n :aria-checked=\"sw.checked\"\n :data-state=\"sw.checked ? 'checked' : 'unchecked'\"\n :style=\"{ '--ink-swatch': sw.color }\"\n @click=\"set(sw.patch)\"\n />\n </div>\n <button\n type=\"button\"\n role=\"menuitem\"\n class=\"ink-select-item ink-menu-item\"\n data-ink-select-item\n tabindex=\"-1\"\n @click=\"customInput?.click()\"\n >\n Custom…\n </button>\n </div>\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <input\n ref=\"customInput\"\n type=\"color\"\n class=\"ink-color-input\"\n aria-label=\"Custom colour\"\n :data-ink-color-input=\"property\"\n tabindex=\"-1\"\n :value=\"model.customValue.toLowerCase()\"\n @change=\"set(model.custom(($event.target as HTMLInputElement).value))\"\n />\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkHighlightMenu.js","names":["_sfc_main","InkHighlightMenu_vue_vue_type_script_setup_true_lang_default","InkHighlightMenu_default"],"sources":["../../src/components/InkHighlightMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A split button for the highlight tool. The main part activates the tool with the current\n * markup kind and draws that kind's icon; the chevron opens a menu of the four kinds plus\n * the markup colour. Choosing a kind switches to the tool with it. The colour is a nested\n * `InkColorMenu` scoped to the `markup` style group, so it works whatever tool is active.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n highlightMenuModel,\n MARKUP_ICONS,\n MARKUP_KINDS,\n menuItems,\n type HighlightOptions,\n type MarkupKind,\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 InkColorMenu from './InkColorMenu.vue'\nimport InkIcon from './InkIcon.vue'\n\nconst { tool, setTool } = useTool()\nconst { options, setOptions } = useToolOptions<HighlightOptions>('highlight')\nconst open = ref(false)\n\nconst model = computed(() => highlightMenuModel(options.value, MARKUP_KINDS))\nconst active = computed(() => tool.value === 'highlight')\nconst icon = computed(() => MARKUP_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 highlight menu is open at a time.\n const menu = document.querySelector('[data-ink-menu=\"highlight\"] [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: MarkupKind): void {\n setOptions({ kind })\n setTool('highlight')\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('highlight'),\n}))\nconst triggerAttrs = {\n 'aria-label': 'Choose highlight',\n title: 'Choose highlight',\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n}\nconst menuAttrs = { 'aria-label': 'Highlights' }\n/** The colour trigger is an item of this menu, reached with the arrow keys. */\nconst colourAttrs = { role: 'menuitem', tabindex: -1 }\nconst innerAttrs = {\n role: 'menu',\n 'aria-label': 'Highlights',\n // Capture, so the arrow keys move on from the colour item before its own ArrowDown\n // opens the nested menu.\n onKeydownCapture: (e: KeyboardEvent) =>\n handleMenuKeys(e, e.currentTarget as HTMLElement),\n}\n</script>\n\n<template>\n <div\n
|
|
1
|
+
{"version":3,"file":"InkHighlightMenu.js","names":["_sfc_main","InkHighlightMenu_vue_vue_type_script_setup_true_lang_default","InkHighlightMenu_default"],"sources":["../../src/components/InkHighlightMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * A split button for the highlight tool. The main part activates the tool with the current\n * markup kind and draws that kind's icon; the chevron opens a menu of the four kinds plus\n * the markup colour. Choosing a kind switches to the tool with it. The colour is a nested\n * `InkColorMenu` scoped to the `markup` style group, so it works whatever tool is active.\n */\nimport {\n focusInitialMenuItem,\n handleMenuKeys,\n highlightMenuModel,\n MARKUP_ICONS,\n MARKUP_KINDS,\n menuItems,\n type HighlightOptions,\n type MarkupKind,\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 { useDocument } from '../composables/useDocument'\nimport { useTool } from '../composables/useTool'\nimport { useToolOptions } from '../composables/useToolOptions'\n\nimport InkColorMenu from './InkColorMenu.vue'\nimport InkIcon from './InkIcon.vue'\n\ndefineOptions({ inheritAttrs: false })\nconst { tool, setTool } = useTool()\nconst { options, setOptions } = useToolOptions<HighlightOptions>('highlight')\nconst { document: doc } = useDocument()\nconst open = ref(false)\n\nconst model = computed(() => highlightMenuModel(options.value, MARKUP_KINDS))\nconst active = computed(() => tool.value === 'highlight')\n/** The colour the chosen kind gets while the markup style leaves it unset. */\nconst fallback = computed(() => doc.value?.annotations.defaults.color(model.value.kind))\nconst icon = computed(() => MARKUP_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 highlight menu is open at a time.\n const menu = document.querySelector('[data-ink-menu=\"highlight\"] [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: MarkupKind): void {\n setOptions({ kind })\n setTool('highlight')\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('highlight'),\n}))\nconst triggerAttrs = {\n 'aria-label': 'Choose highlight',\n title: 'Choose highlight',\n 'aria-haspopup': 'menu' as const,\n onKeydown: onTriggerKeydown,\n}\nconst menuAttrs = { 'aria-label': 'Highlights' }\n/** The colour trigger is an item of this menu, reached with the arrow keys. */\nconst colourAttrs = { role: 'menuitem', tabindex: -1 }\nconst innerAttrs = {\n role: 'menu',\n 'aria-label': 'Highlights',\n // Capture, so the arrow keys move on from the colour item before its own ArrowDown\n // opens the nested menu.\n onKeydownCapture: (e: KeyboardEvent) =>\n 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=\"Highlight\"\n class=\"ink-split-button ink-highlight-menu\"\n data-ink-highlight-menu\n v-bind=\"$attrs\"\n >\n <ToolbarButton\n class=\"ink-tool-button ink-highlight-button\"\n data-ink-tool-button\n data-ink-highlight-button\n data-tool=\"highlight\"\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-highlight-menu-trigger\"\n data-ink-highlight-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=\"highlight\"\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 role=\"group\" aria-label=\"Kinds\" class=\"ink-highlight-kinds\">\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-highlight-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=\"MARKUP_ICONS[item.kind]\" :size=\"16\" />\n {{ item.label }}\n </button>\n </div>\n <div role=\"separator\" class=\"ink-select-separator\" />\n <div role=\"group\" aria-label=\"Colour\" class=\"ink-highlight-colour\">\n <span class=\"ink-highlight-colour-label\" aria-hidden=\"true\">Colour</span>\n <InkColorMenu\n property=\"border\"\n group=\"markup\"\n label=\"Highlight colour\"\n standalone\n :fallback=\"fallback\"\n v-bind=\"colourAttrs\"\n />\n </div>\n </div>\n </PopoverContent>\n </PopoverPortal>\n </div>\n </PopoverAnchor>\n </PopoverRoot>\n</template>\n"],"mappings":""}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
declare var
|
|
1
|
+
declare var __VLS_21: {
|
|
2
2
|
active: boolean;
|
|
3
3
|
kind: "highlight" | "underline" | "strikeout" | "squiggly";
|
|
4
4
|
};
|
|
5
5
|
type __VLS_Slots = {} & {
|
|
6
|
-
default?: (props: typeof
|
|
6
|
+
default?: (props: typeof __VLS_21) => any;
|
|
7
7
|
};
|
|
8
8
|
declare const __VLS_base: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
|
|
9
9
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InkHighlightMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkHighlightMenu.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"InkHighlightMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkHighlightMenu.vue"],"names":[],"mappings":"AA8hBA,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,+QACd,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"}
|