@inkbar/vue 0.7.0 → 0.9.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 (79) hide show
  1. package/README.md +14 -2
  2. package/dist/components/InkFormAlert.js +7 -0
  3. package/dist/components/InkFormAlert.js.map +1 -0
  4. package/dist/components/InkFormAlert.vue.d.ts +16 -0
  5. package/dist/components/InkFormAlert.vue.d.ts.map +1 -0
  6. package/dist/components/InkFormAlert.vue_vue_type_script_setup_true_lang.js +90 -0
  7. package/dist/components/InkFormAlert.vue_vue_type_script_setup_true_lang.js.map +1 -0
  8. package/dist/components/InkHighlightMenu.js.map +1 -1
  9. package/dist/components/InkHighlightMenu.vue.d.ts.map +1 -1
  10. package/dist/components/InkHighlightMenu.vue_vue_type_script_setup_true_lang.js +67 -65
  11. package/dist/components/InkHighlightMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  12. package/dist/components/InkRoot.js.map +1 -1
  13. package/dist/components/InkRoot.vue.d.ts +24 -5
  14. package/dist/components/InkRoot.vue.d.ts.map +1 -1
  15. package/dist/components/InkRoot.vue_vue_type_script_setup_true_lang.js +197 -148
  16. package/dist/components/InkRoot.vue_vue_type_script_setup_true_lang.js.map +1 -1
  17. package/dist/components/InkShapeMenu.js.map +1 -1
  18. package/dist/components/InkShapeMenu.vue.d.ts.map +1 -1
  19. package/dist/components/InkShapeMenu.vue_vue_type_script_setup_true_lang.js +58 -56
  20. package/dist/components/InkShapeMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/components/InkSignFieldPopover.js +7 -0
  22. package/dist/components/InkSignFieldPopover.js.map +1 -0
  23. package/dist/components/InkSignFieldPopover.vue.d.ts +13 -0
  24. package/dist/components/InkSignFieldPopover.vue.d.ts.map +1 -0
  25. package/dist/components/InkSignFieldPopover.vue_vue_type_script_setup_true_lang.js +116 -0
  26. package/dist/components/InkSignFieldPopover.vue_vue_type_script_setup_true_lang.js.map +1 -0
  27. package/dist/components/InkSignatureDialog.js.map +1 -1
  28. package/dist/components/InkSignatureDialog.vue.d.ts +10 -1
  29. package/dist/components/InkSignatureDialog.vue.d.ts.map +1 -1
  30. package/dist/components/InkSignatureDialog.vue_vue_type_script_setup_true_lang.js +9 -2
  31. package/dist/components/InkSignatureDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  32. package/dist/components/InkSignatureMenu.js.map +1 -1
  33. package/dist/components/InkSignatureMenu.vue.d.ts.map +1 -1
  34. package/dist/components/InkSignatureMenu.vue_vue_type_script_setup_true_lang.js +69 -154
  35. package/dist/components/InkSignatureMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  36. package/dist/components/InkToolButton.js.map +1 -1
  37. package/dist/components/InkToolButton.vue.d.ts.map +1 -1
  38. package/dist/components/InkToolButton.vue_vue_type_script_setup_true_lang.js +39 -36
  39. package/dist/components/InkToolButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  40. package/dist/components/InkToolbarButton.js +7 -0
  41. package/dist/components/InkToolbarButton.js.map +1 -0
  42. package/dist/components/InkToolbarButton.vue.d.ts +22 -0
  43. package/dist/components/InkToolbarButton.vue.d.ts.map +1 -0
  44. package/dist/components/InkToolbarButton.vue_vue_type_script_setup_true_lang.js +32 -0
  45. package/dist/components/InkToolbarButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  46. package/dist/components/InkViewport.js.map +1 -1
  47. package/dist/components/InkViewport.vue.d.ts.map +1 -1
  48. package/dist/components/InkViewport.vue_vue_type_script_setup_true_lang.js +123 -91
  49. package/dist/components/InkViewport.vue_vue_type_script_setup_true_lang.js.map +1 -1
  50. package/dist/components/SignatureForm.js.map +1 -1
  51. package/dist/components/SignatureForm.vue.d.ts +5 -1
  52. package/dist/components/SignatureForm.vue.d.ts.map +1 -1
  53. package/dist/components/SignatureForm.vue_vue_type_script_setup_true_lang.js +64 -57
  54. package/dist/components/SignatureForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  55. package/dist/components/SignatureMenuPanel.js +7 -0
  56. package/dist/components/SignatureMenuPanel.js.map +1 -0
  57. package/dist/components/SignatureMenuPanel.vue.d.ts +15 -0
  58. package/dist/components/SignatureMenuPanel.vue.d.ts.map +1 -0
  59. package/dist/components/SignatureMenuPanel.vue_vue_type_script_setup_true_lang.js +116 -0
  60. package/dist/components/SignatureMenuPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  61. package/dist/composables/useForm.d.ts +18 -0
  62. package/dist/composables/useForm.d.ts.map +1 -0
  63. package/dist/composables/useForm.js +17 -0
  64. package/dist/composables/useForm.js.map +1 -0
  65. package/dist/composables/useRegisteredTool.d.ts +21 -0
  66. package/dist/composables/useRegisteredTool.d.ts.map +1 -0
  67. package/dist/composables/useRegisteredTool.js +25 -0
  68. package/dist/composables/useRegisteredTool.js.map +1 -0
  69. package/dist/composables/useToolOptions.d.ts +8 -0
  70. package/dist/composables/useToolOptions.d.ts.map +1 -1
  71. package/dist/composables/useToolOptions.js +10 -5
  72. package/dist/composables/useToolOptions.js.map +1 -1
  73. package/dist/context.d.ts +12 -1
  74. package/dist/context.d.ts.map +1 -1
  75. package/dist/context.js.map +1 -1
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +29 -27
  79. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"InkRoot.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_unref","_mergeProps","_withCtx","_renderSlot","InkRoot_vue_vue_type_script_setup_true_lang_default","__expose","__emit","props","__props","emit","primitive","useTemplateRef","rootEl","shallowRef","syncRootEl","el","document","override","documentStatus","useReadable","status","computed","annotationList","selection","viewport","toolController","internalTool","ref","activated","controlled","setActivated","id","noop","identity","src","generation","release","doc","open","gen","refHistory","openDocument","cssVariableDefaults","next","change","cause","error","InkError","s","createRefHistory","list","coreCanUndo","coreCanRedo","inkHistory","fn","store","hostDocument","writable","viewportEl","hostRoot","hostActivated","pluginHost","search","setUpPlugins","controller","createSearchController","readonly","createPluginHost","viewerSearchOf","rootListeners","onKeydown","root","handleFindKey","pageSelectionText","toolStyle","setStyleTool","watch","tracker","trackToolStyle","onMounted","onUpdated","t","setTool","tc","onBeforeUnmount","onUnmounted","signatures","createSignatureLibrary","createMemorySignatureStore","lib","toolOptions","createToolOptions","provideInkContext","FONT_FAMILIES","SIGNATURE_FONTS","z","p","openBlock","createBlock","unref","Primitive","mergeProps","withCtx","renderSlot","_ctx"],"sources":["../../src/components/InkRoot.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n createMemorySignatureStore,\n createSignatureLibrary,\n InkError,\n openDocument,\n readonly,\n writable,\n} from '@inkbar/core'\nimport {\n createPluginHost,\n createSearchController,\n createToolOptions,\n handleFindKey,\n pageSelectionText,\n viewerSearchOf,\n cssVariableDefaults,\n FONT_FAMILIES,\n SIGNATURE_FONTS,\n trackToolStyle,\n} from '@inkbar/core/dom'\nimport { Primitive } from 'reka-ui'\nimport {\n computed,\n onBeforeUnmount,\n onUnmounted,\n onMounted,\n onUpdated,\n ref,\n shallowRef,\n useTemplateRef,\n watch,\n} from 'vue'\n\nimport { provideInkContext, type InkHistory, type InkStatus } from '../context'\nimport { createRefHistory } from '../ref-history'\nimport { useReadable } from '../use-readable'\n\nimport type {\n Annotation,\n AnnotationChange,\n AnnotationDefaults,\n DocumentSource,\n InkDocument,\n PdfAssets,\n SignatureStore,\n} from '@inkbar/core'\nimport type {\n DecorateAnnotation,\n InkPlugin,\n PluginHost,\n SearchController,\n Tool,\n ToolController,\n ToolId,\n ToolStyle,\n Viewport,\n ZoomValue,\n} from '@inkbar/core/dom'\n\nconst props = withDefaults(\n defineProps<{\n src: DocumentSource | null\n assets: PdfAssets\n password?: string | undefined\n /** Colour defaults. Without it, the theme's CSS variables on the root element apply. */\n defaults?: AnnotationDefaults | undefined\n /**\n * Pass (with v-model) to put annotations under the host's control. The mode is fixed when a\n * document opens: passing or dropping this prop later takes effect on the next open.\n */\n annotations?: Annotation[] | undefined\n tool?: ToolId | undefined\n /**\n * Host tools, added to the built-ins; one with a built-in's id replaces it. Read when a\n * document opens.\n */\n tools?: Tool[] | undefined\n /**\n * Plugins, set up once when the root is created; a later change to this prop is not\n * applied. Their tools join `tools`, their decoration and page layers apply to every\n * document, and their commands are placed with `InkCommand` or `useCommand`.\n */\n plugins?: InkPlugin[] | undefined\n /**\n * Adds `data-*` attributes, classes and a screen-reader description to each annotation's\n * element (see `DecorateAnnotation`). Decorations re-apply whenever the annotations change\n * and when this prop changes, without rebuilding the viewer. Pass a new function when its\n * output would change for any other reason.\n */\n decorateAnnotation?: DecorateAnnotation | undefined\n /**\n * The font families text boxes offer, replacing the PDF standard families\n * (`FONT_FAMILIES`). Fonts beyond those are the PDF writer's to embed.\n */\n fonts?: string[] | undefined\n /**\n * Where saved signatures live. Default: memory, gone on reload.\n * `createLocalSignatureStore` keeps them in the browser; a host can keep them anywhere.\n * A new store takes effect at once, for the menus and the `signature` tool alike.\n */\n signatures?: SignatureStore | undefined\n /** The handwriting fonts a typed signature offers; the host loads them. */\n signatureFonts?: string[] | undefined\n page?: number | undefined\n zoom?: ZoomValue | undefined\n /** Undo history. Defaults to on for uncontrolled, off for controlled. */\n history?: boolean | undefined\n asChild?: boolean\n }>(),\n {\n password: undefined,\n defaults: undefined,\n annotations: undefined,\n tool: undefined,\n tools: undefined,\n plugins: undefined,\n decorateAnnotation: undefined,\n fonts: undefined,\n signatures: undefined,\n signatureFonts: undefined,\n page: undefined,\n zoom: undefined,\n history: undefined,\n asChild: false,\n }\n)\n\nconst emit = defineEmits<{\n 'update:annotations': [next: Annotation[]]\n change: [change: AnnotationChange]\n 'update:tool': [tool: ToolId]\n 'update:page': [page: number]\n 'update:zoom': [zoom: ZoomValue]\n ready: [doc: InkDocument]\n error: [error: InkError]\n activate: [id: string]\n}>()\n\ntype TestHookElement = HTMLElement & { __inkDocument?: InkDocument | undefined }\n\n// A template ref on Primitive is a component instance; the context needs its element.\nconst primitive = useTemplateRef<{ $el: unknown }>('primitive')\nconst rootEl = shallowRef<HTMLElement | null>(null)\nfunction syncRootEl(): void {\n const el = primitive.value?.$el\n rootEl.value = el instanceof HTMLElement ? el : null\n}\n\nconst document = shallowRef<InkDocument | null>(null)\n/** Overrides the document's status while opening, and when opening itself failed. */\nconst override = shallowRef<InkStatus | null>(null)\nconst idle: InkStatus = { state: 'idle' }\nconst documentStatus = useReadable<InkStatus>(() => document.value?.status ?? null, idle)\nconst status = computed<InkStatus>(() => override.value ?? documentStatus.value)\nconst annotationList = useReadable<readonly Annotation[]>(\n () => document.value?.annotations.list ?? null,\n []\n)\nconst selection = useReadable<readonly string[]>(\n () => document.value?.annotations.selection ?? null,\n []\n)\nconst viewport = shallowRef<Viewport | null>(null)\nconst toolController = shallowRef<ToolController | null>(null)\nconst internalTool = ref<ToolId>(props.tool ?? 'select-text')\nconst activated = ref<string | null>(null)\n\nconst controlled = computed(() => props.annotations !== undefined)\n\nfunction setActivated(id: string | null): void {\n activated.value = id\n if (id) emit('activate', id)\n}\n\nconst noop = () => {}\n\n/** Signed URLs change; the key does not. Bytes and Blobs are their own identity. */\nfunction identity(src: DocumentSource | null): unknown {\n if (src === null) return null\n if (typeof src === 'string') return src\n if ('key' in src) return src.key\n return src\n}\n\nfunction setTestHook(doc: InkDocument | undefined): void {\n if (import.meta.env.DEV && rootEl.value)\n (rootEl.value as TestHookElement).__inkDocument = doc\n}\n\nlet generation = 0\nfunction release(): void {\n // Cleared first, so the plugins close their stores while the document is still alive.\n const doc = document.value\n document.value = null\n doc?.destroy()\n setTestHook(undefined)\n}\n\nasync function open(): Promise<void> {\n const gen = ++generation\n const src = props.src\n release()\n refHistory.clear()\n if (src === null) {\n override.value = null\n return\n }\n override.value = { state: 'loading' }\n syncRootEl()\n let doc: InkDocument\n try {\n doc = await openDocument(src, {\n assets: props.assets,\n password: props.password,\n defaults:\n props.defaults ?? (rootEl.value ? cssVariableDefaults(rootEl.value) : undefined),\n // Controlled hosts get the ref history below; core's own stack stays off.\n history: controlled.value ? false : (props.history ?? true),\n annotations: controlled.value\n ? {\n mode: 'controlled',\n initial: props.annotations ?? [],\n onChange: (next, change) => {\n emit('update:annotations', next)\n emit('change', change)\n },\n }\n : { mode: 'uncontrolled' },\n })\n } catch (cause) {\n if (gen !== generation) return\n const error =\n cause instanceof InkError\n ? cause\n : new InkError(\n 'InvalidPdf',\n cause instanceof Error ? cause.message : String(cause),\n {},\n cause\n )\n override.value = { state: 'error', error }\n emit('error', error)\n return\n }\n if (gen !== generation) {\n doc.destroy()\n return\n }\n // The prop may have changed while the file loaded, when there was no store to apply it to.\n if (doc.annotations.mode === 'controlled' && props.annotations !== undefined)\n doc.annotations.setControlledValue(props.annotations)\n document.value = doc\n override.value = null\n setTestHook(doc)\n const s = doc.status.get()\n if (s.state === 'ready') emit('ready', doc)\n else if (s.state === 'error') emit('error', s.error)\n}\n\nconst refHistory = createRefHistory({\n source: () => props.annotations,\n apply: (list) => document.value?.annotations.replaceAll(list, 'history'),\n enabled: computed(() => controlled.value && props.history === true),\n store: () =>\n document.value?.annotations.mode === 'controlled' ? document.value.annotations : null,\n})\nconst coreCanUndo = useReadable(() => document.value?.history.canUndo ?? null, false)\nconst coreCanRedo = useReadable(() => document.value?.history.canRedo ?? null, false)\nconst inkHistory: InkHistory = {\n canUndo: computed(() =>\n controlled.value ? refHistory.canUndo.value : coreCanUndo.value\n ),\n canRedo: computed(() =>\n controlled.value ? refHistory.canRedo.value : coreCanRedo.value\n ),\n undo: () => (controlled.value ? refHistory.undo() : document.value?.history.undo()),\n redo: () => (controlled.value ? refHistory.redo() : document.value?.history.redo()),\n clear: () => (controlled.value ? refHistory.clear() : document.value?.history.clear()),\n batch: (fn) => {\n if (controlled.value) refHistory.batch(fn)\n else if (document.value) document.value.history.batch(fn)\n else fn()\n },\n track: (store) =>\n controlled.value\n ? refHistory.track(store)\n : (document.value?.history.track(store) ?? noop),\n react: (fn) =>\n controlled.value ? refHistory.react(fn) : (document.value?.history.react(fn) ?? noop),\n}\n\n/*\n * One plugin host for the root's life, built once mounted so that no `setup` runs on the\n * server, where nothing would clean it up. Until then `pluginHost` is null, and InkCommand\n * renders its command disabled. The host follows `hostDocument`, which is set after `document`\n * (a sync watch): when the host reads `inkHistory` for a new document, it is that document's\n * history.\n */\nconst hostDocument = writable<InkDocument | null>(null)\nwatch(document, (doc) => hostDocument.set(doc), { flush: 'sync' })\nconst viewportEl = shallowRef<HTMLElement | null>(null)\nconst hostRoot = writable<HTMLElement | null>(null)\nwatch(viewportEl, (el) => hostRoot.set(el), { flush: 'sync' })\nconst hostActivated = writable<string | null>(null)\nwatch(activated, (id) => hostActivated.set(id), { flush: 'sync' })\nconst pluginHost = shallowRef<PluginHost | null>(null)\n/** One search controller for the root's life, built with the plugin host that shares it. */\nconst search = shallowRef<SearchController | null>(null)\nfunction setUpPlugins(): void {\n const controller = createSearchController({\n document: readonly(hostDocument),\n viewport: () => viewport.value,\n })\n search.value = controller\n pluginHost.value = createPluginHost({\n plugins: props.plugins ?? [],\n document: readonly(hostDocument),\n history: () => inkHistory,\n activated: readonly(hostActivated),\n // As in `createViewer`: an id not in the open document is ignored.\n setActivated: (id) => {\n if (id === null || document.value?.annotations.get(id)) setActivated(id)\n },\n root: readonly(hostRoot),\n decorate: () => props.decorateAnnotation,\n viewport: () => viewport.value,\n search: viewerSearchOf(controller),\n })\n}\n\n// Reka's typed props stop at its own; listeners go through a bound object.\nconst rootListeners = { onKeydown }\n\n/** Ctrl/Cmd+F while focus is in the root and a find bar is mounted; else the browser's. */\nfunction onKeydown(e: KeyboardEvent): void {\n const controller = search.value\n const root = e.currentTarget\n if (controller && root instanceof HTMLElement)\n handleFindKey(e, controller, () => pageSelectionText(root))\n}\n\n/** The document's tool style; it batches through `inkHistory`, whichever mode is on. */\nconst toolStyle = shallowRef<ToolStyle | null>(null)\nlet setStyleTool: ((id: ToolId) => void) | undefined\nwatch(\n document,\n (doc) => {\n if (!doc) {\n toolStyle.value = null\n setStyleTool = undefined\n return\n }\n const tracker = trackToolStyle({\n store: doc.annotations,\n history: { batch: (fn) => inkHistory.batch(fn) },\n // The plugins' tools too, so a plugin tool's style group applies (the host is set by now:\n // it is built on mount, before the first document opens).\n tools: [...(props.tools ?? []), ...(pluginHost.value?.tools ?? [])],\n tool: internalTool.value,\n })\n setStyleTool = (id) => tracker.setTool(id)\n toolStyle.value = tracker.toolStyle\n },\n // Sync: the style is in place before InkViewport's watcher mounts the engine with it.\n { immediate: true, flush: 'sync' }\n)\nwatch(internalTool, (id) => setStyleTool?.(id))\n\n// Plugins and the document on the client only: on the server InkRoot renders its empty slot.\n// The plugins first, so the first document opens with their stores and reactions.\nonMounted(() => {\n syncRootEl()\n // A plugin whose setup throws still leaves the document to open; the error then goes to\n // Vue's error handling (`onErrorCaptured`, `app.config.errorHandler`).\n try {\n setUpPlugins()\n } finally {\n void open()\n }\n})\nonUpdated(syncRootEl)\n\n// Separate sources, so a new `{ url, key }` object with the same key compares equal.\nwatch([() => identity(props.src), () => props.password], () => void open())\n\nwatch(\n () => props.annotations,\n (next) => {\n if (next && document.value?.annotations.mode === 'controlled')\n document.value.annotations.setControlledValue(next)\n }\n)\n\nwatch(\n () => props.tool,\n (t) => {\n if (t) internalTool.value = t\n }\n)\n\nfunction setTool(id: ToolId): void {\n // Picking the active tool again starts it afresh, as after a one-shot tool's use.\n const tc = toolController.value\n if (internalTool.value === id && tc?.active.get() === id) tc.set(id)\n internalTool.value = id\n emit('update:tool', id)\n}\n\nonBeforeUnmount(() => {\n generation++\n release()\n})\n\n// After the children: InkViewport's engine, and the plugin layers with it, are gone by now, as\n// in `createViewer`, so no layer `destroy` runs after the plugins' cleanups.\nonUnmounted(() => {\n pluginHost.value?.destroy()\n pluginHost.value = null\n search.value?.destroy()\n search.value = null\n})\n\nconst signatures = computed(() =>\n createSignatureLibrary(props.signatures ?? createMemorySignatureStore())\n)\nwatch(signatures, (lib) => void lib.refresh(), { immediate: true })\n/** Tool options last as long as the root; the tool style is per document. */\nconst toolOptions = createToolOptions()\n\nprovideInkContext({\n assets: computed(() => props.assets),\n document,\n status,\n annotations: annotationList,\n selection,\n viewport,\n tools: toolController,\n tool: internalTool,\n setTool,\n hostTools: computed(() => props.tools),\n decorateAnnotation: computed(() => props.decorateAnnotation),\n fonts: computed(() => props.fonts ?? FONT_FAMILIES),\n toolOptions,\n signatures,\n signatureFonts: computed(() => props.signatureFonts ?? SIGNATURE_FONTS),\n toolStyle,\n zoomModel: computed(() => props.zoom),\n pageModel: computed(() => props.page),\n reportZoom: (z) => emit('update:zoom', z),\n reportPage: (p) => emit('update:page', p),\n activated,\n setActivated,\n pluginHost,\n search,\n viewportEl,\n history: inkHistory,\n rootEl,\n})\n\n// `history` is what `useHistory()` returns inside the root, for hosts that hold a template ref:\n// a controlled host calls `history.clear()` after loading its saved list.\ndefineExpose({ document, status, rootEl, history: inkHistory })\n</script>\n\n<template>\n <Primitive\n ref=\"primitive\"\n :as-child=\"props.asChild\"\n as=\"div\"\n data-ink-root\n :data-state=\"status.state\"\n v-bind=\"rootListeners\"\n >\n <slot :status=\"status\" :document=\"document\" />\n </Primitive>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"InkRoot.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_unref","_withCtx","_renderSlot","InkRoot_vue_vue_type_script_setup_true_lang_default","__expose","__emit","props","__props","emit","primitive","useTemplateRef","rootEl","shallowRef","syncRootEl","el","document","override","documentStatus","useReadable","status","computed","annotationList","selection","viewport","toolController","internalTool","ref","activated","controlled","fieldsControlled","setActivated","id","noop","identity","src","generation","stopFormErrors","release","doc","open","gen","refHistory","openDocument","cssVariableDefaults","next","change","cause","error","InkError","held","s","early","createRefHistory","list","coreCanUndo","coreCanRedo","inkHistory","fn","store","stopKeys","attachHistoryKeys","stopFocus","keepHistoryFocus","onKeydown","onCleanup","hostDocument","writable","viewportEl","hostRoot","hostActivated","pluginHost","search","setUpPlugins","controller","createSearchController","readonly","createPluginHost","viewerSearchOf","root","handleFindKey","pageSelectionText","toolStyle","setStyleTool","watch","tracker","trackToolStyle","onMounted","onUpdated","mounted","openedToolIds","toolIds","registeredToolIds","isRegistered","logUnknownTool","unknownTool","fallBack","t","setTool","tc","onBeforeUnmount","onUnmounted","signatures","createSignatureLibrary","createMemorySignatureStore","lib","toolOptions","createToolOptions","provideInkContext","FONT_FAMILIES","SIGNATURE_FONTS","z","p","a","openBlock","createBlock","unref","Primitive","withCtx","renderSlot","_ctx"],"sources":["../../src/components/InkRoot.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n createMemorySignatureStore,\n createSignatureLibrary,\n InkError,\n openDocument,\n readonly,\n writable,\n} from '@inkbar/core'\nimport {\n attachHistoryKeys,\n createPluginHost,\n createSearchController,\n createToolOptions,\n handleFindKey,\n pageSelectionText,\n viewerSearchOf,\n cssVariableDefaults,\n FONT_FAMILIES,\n keepHistoryFocus,\n SIGNATURE_FONTS,\n trackToolStyle,\n unknownTool,\n} from '@inkbar/core/dom'\nimport { Primitive } from 'reka-ui'\nimport {\n computed,\n onBeforeUnmount,\n onUnmounted,\n onMounted,\n onUpdated,\n ref,\n shallowRef,\n useTemplateRef,\n watch,\n} from 'vue'\n\nimport { registeredToolIds } from '../composables/useRegisteredTool'\nimport { provideInkContext, type InkHistory, type InkStatus } from '../context'\nimport { createRefHistory } from '../ref-history'\nimport { useReadable } from '../use-readable'\n\nimport type {\n Annotation,\n AnnotationChange,\n AnnotationDefaults,\n DocumentSource,\n FieldsChange,\n FieldValues,\n FormAction,\n InkDocument,\n PdfAssets,\n SignatureStore,\n} from '@inkbar/core'\nimport type {\n DecorateAnnotation,\n InkPlugin,\n PluginHost,\n SearchController,\n Tool,\n ToolController,\n ToolId,\n ToolStyle,\n Viewport,\n ZoomValue,\n} from '@inkbar/core/dom'\n\nconst props = withDefaults(\n defineProps<{\n src: DocumentSource | null\n assets: PdfAssets\n password?: string | undefined\n /** Colour defaults. Without it, the theme's CSS variables on the root element apply. */\n defaults?: AnnotationDefaults | undefined\n /**\n * Pass (with v-model) to put annotations under the host's control. The mode is fixed when a\n * document opens: passing or dropping this prop later takes effect on the next open.\n */\n annotations?: Annotation[] | undefined\n /**\n * Pass (with `v-model:fields`) to put the form's field values under the host's control. A\n * commit shows at once and is reported after; the host's push wins. The mode is fixed when\n * a document opens, as for `annotations`.\n */\n fields?: FieldValues | undefined\n /** Tints fillable form fields. Default true. A change applies to the open document in place. */\n formHighlight?: boolean | undefined\n tool?: ToolId | undefined\n /**\n * The creation tools, such as `allTools()` or a pick of the tool factories. `select-text`\n * and `select` are always present; a tool with either id replaces it. They are read when a\n * document opens: a tool added later is usable from the next open, one removed stops at\n * once. When the active tool goes, the viewer switches to `select-text` and emits\n * `update:tool`. A controlled `tool` naming a missing tool is reported back as\n * `select-text` and is not applied again when the tool appears later. Each mounted control\n * for a missing tool logs its own `UnknownTool`.\n */\n tools?: Tool[] | undefined\n /**\n * Plugins, set up once when the root is created; a later change to this prop is not\n * applied. Their tools join `tools`, their decoration and page layers apply to every\n * document, and their commands are placed with `InkCommand` or `useCommand`.\n */\n plugins?: InkPlugin[] | undefined\n /**\n * Adds `data-*` attributes, classes and a screen-reader description to each annotation's\n * element (see `DecorateAnnotation`). Decorations re-apply whenever the annotations change\n * and when this prop changes, without rebuilding the viewer. Pass a new function when its\n * output would change for any other reason.\n */\n decorateAnnotation?: DecorateAnnotation | undefined\n /**\n * The font families text boxes offer, replacing the PDF standard families\n * (`FONT_FAMILIES`). Fonts beyond those are the PDF writer's to embed.\n */\n fonts?: string[] | undefined\n /**\n * Where saved signatures live. Default: memory, gone on reload.\n * `createLocalSignatureStore` keeps them in the browser; a host can keep them anywhere.\n * A new store takes effect at once, for the menus and the `signature` tool alike.\n */\n signatures?: SignatureStore | undefined\n /** The handwriting fonts a typed signature offers; the host loads them. */\n signatureFonts?: string[] | undefined\n page?: number | undefined\n zoom?: ZoomValue | undefined\n /** Undo history. Defaults to on for uncontrolled, off for controlled. */\n history?: boolean | undefined\n asChild?: boolean\n }>(),\n {\n password: undefined,\n defaults: undefined,\n annotations: undefined,\n fields: undefined,\n formHighlight: undefined,\n tool: undefined,\n tools: undefined,\n plugins: undefined,\n decorateAnnotation: undefined,\n fonts: undefined,\n signatures: undefined,\n signatureFonts: undefined,\n page: undefined,\n zoom: undefined,\n history: undefined,\n asChild: false,\n }\n)\n\nconst emit = defineEmits<{\n 'update:annotations': [next: Annotation[]]\n change: [change: AnnotationChange]\n /** Committed field values, in full, with what changed them. */\n 'update:fields': [next: FieldValues, change: FieldsChange]\n /** The form asked to submit, open a link, send mail, print or prompt. Inkbar does none. */\n 'form-action': [action: FormAction]\n 'update:tool': [tool: ToolId]\n 'update:page': [page: number]\n 'update:zoom': [zoom: ZoomValue]\n ready: [doc: InkDocument]\n /**\n * Opening failed, or later a form script failed or a signature field refused its signing.\n * An error from while the document opened comes after `ready`.\n */\n error: [error: InkError]\n activate: [id: string]\n}>()\n\ntype TestHookElement = HTMLElement & { __inkDocument?: InkDocument | undefined }\n\n// A template ref on Primitive is a component instance; the context needs its element.\nconst primitive = useTemplateRef<{ $el: unknown }>('primitive')\nconst rootEl = shallowRef<HTMLElement | null>(null)\nfunction syncRootEl(): void {\n const el = primitive.value?.$el\n rootEl.value = el instanceof HTMLElement ? el : null\n}\n\nconst document = shallowRef<InkDocument | null>(null)\n/** Overrides the document's status while opening, and when opening itself failed. */\nconst override = shallowRef<InkStatus | null>(null)\nconst idle: InkStatus = { state: 'idle' }\nconst documentStatus = useReadable<InkStatus>(() => document.value?.status ?? null, idle)\nconst status = computed<InkStatus>(() => override.value ?? documentStatus.value)\nconst annotationList = useReadable<readonly Annotation[]>(\n () => document.value?.annotations.list ?? null,\n []\n)\nconst selection = useReadable<readonly string[]>(\n () => document.value?.annotations.selection ?? null,\n []\n)\nconst viewport = shallowRef<Viewport | null>(null)\nconst toolController = shallowRef<ToolController | null>(null)\nconst internalTool = ref<ToolId>(props.tool ?? 'select-text')\nconst activated = ref<string | null>(null)\n\nconst controlled = computed(() => props.annotations !== undefined)\nconst fieldsControlled = computed(() => props.fields !== undefined)\n\nfunction setActivated(id: string | null): void {\n activated.value = id\n if (id) emit('activate', id)\n}\n\nconst noop = () => {}\n\n/** Signed URLs change; the key does not. Bytes and Blobs are their own identity. */\nfunction identity(src: DocumentSource | null): unknown {\n if (src === null) return null\n if (typeof src === 'string') return src\n if ('key' in src) return src.key\n return src\n}\n\nfunction setTestHook(doc: InkDocument | undefined): void {\n if (import.meta.env.DEV && rootEl.value)\n (rootEl.value as TestHookElement).__inkDocument = doc\n}\n\nlet generation = 0\nlet stopFormErrors: () => void = noop\nfunction release(): void {\n stopFormErrors()\n stopFormErrors = noop\n // Cleared first, so the plugins close their stores while the document is still alive.\n const doc = document.value\n document.value = null\n doc?.destroy()\n setTestHook(undefined)\n}\n\nasync function open(): Promise<void> {\n const gen = ++generation\n const src = props.src\n release()\n refHistory.clear()\n if (src === null) {\n override.value = null\n return\n }\n override.value = { state: 'loading' }\n syncRootEl()\n let doc: InkDocument\n try {\n doc = await openDocument(src, {\n assets: props.assets,\n password: props.password,\n defaults:\n props.defaults ?? (rootEl.value ? cssVariableDefaults(rootEl.value) : undefined),\n // Controlled hosts get the ref history below; core's own stack stays off.\n history: controlled.value ? false : (props.history ?? true),\n annotations: controlled.value\n ? {\n mode: 'controlled',\n initial: props.annotations ?? [],\n onChange: (next, change) => {\n emit('update:annotations', next)\n emit('change', change)\n },\n }\n : { mode: 'uncontrolled' },\n fields: fieldsControlled.value\n ? {\n mode: 'controlled',\n initial: props.fields ?? {},\n onChange: (next, change) => emit('update:fields', next, change),\n }\n : { mode: 'uncontrolled' },\n })\n } catch (cause) {\n if (gen !== generation) return\n const error =\n cause instanceof InkError\n ? cause\n : new InkError(\n 'InvalidPdf',\n cause instanceof Error ? cause.message : String(cause),\n {},\n cause\n )\n override.value = { state: 'error', error }\n emit('error', error)\n return\n }\n if (gen !== generation) {\n doc.destroy()\n return\n }\n // The prop may have changed while the file loaded, when there was no store to apply it to.\n if (doc.annotations.mode === 'controlled' && props.annotations !== undefined)\n doc.annotations.setControlledValue(props.annotations)\n // The same for the fields; a document whose fields opened uncontrolled ignores the push.\n if (props.fields !== undefined) doc.form.setControlledValue(props.fields)\n // A form script that fails leaves the form fillable; the failure goes to `error`. Subscribed\n // before anyone hears of the document, so the form replays the errors from while it opened\n // here, not to a listener added in `ready`; they are held until `ready` has gone out.\n let held: InkError[] | undefined = []\n stopFormErrors = doc.form.on('error', (e) => {\n if (held) held.push(e)\n else emit('error', e)\n })\n document.value = doc\n override.value = null\n setTestHook(doc)\n const s = doc.status.get()\n if (s.state === 'ready') emit('ready', doc)\n else if (s.state === 'error') emit('error', s.error)\n const early = held\n held = undefined\n if (gen === generation) for (const e of early) emit('error', e)\n}\n\nconst refHistory = createRefHistory({\n source: () => props.annotations,\n apply: (list) => document.value?.annotations.replaceAll(list, 'history'),\n enabled: computed(() => controlled.value && props.history === true),\n store: () =>\n document.value?.annotations.mode === 'controlled' ? document.value.annotations : null,\n})\nconst coreCanUndo = useReadable(() => document.value?.history.canUndo ?? null, false)\nconst coreCanRedo = useReadable(() => document.value?.history.canRedo ?? null, false)\nconst inkHistory: InkHistory = {\n canUndo: computed(() =>\n controlled.value ? refHistory.canUndo.value : coreCanUndo.value\n ),\n canRedo: computed(() =>\n controlled.value ? refHistory.canRedo.value : coreCanRedo.value\n ),\n undo: () => (controlled.value ? refHistory.undo() : document.value?.history.undo()),\n redo: () => (controlled.value ? refHistory.redo() : document.value?.history.redo()),\n clear: () => (controlled.value ? refHistory.clear() : document.value?.history.clear()),\n batch: (fn) => {\n if (controlled.value) refHistory.batch(fn)\n else if (document.value) document.value.history.batch(fn)\n else fn()\n },\n track: (store) =>\n controlled.value\n ? refHistory.track(store)\n : (document.value?.history.track(store) ?? noop),\n react: (fn) =>\n controlled.value ? refHistory.react(fn) : (document.value?.history.react(fn) ?? noop),\n}\n\n// The undo and redo keys anywhere in the root do what InkUndo and InkRedo do. When either\n// button undoes or redoes the last step and disables itself, focus goes back to the document.\n// The find key listens here too.\nwatch(\n rootEl,\n (el, _prev, onCleanup) => {\n if (!el) return\n const stopKeys = attachHistoryKeys(el, () => ({\n canUndo: inkHistory.canUndo.value,\n canRedo: inkHistory.canRedo.value,\n undo: inkHistory.undo,\n redo: inkHistory.redo,\n }))\n const stopFocus = keepHistoryFocus(el, () =>\n el.querySelector<HTMLElement>('[data-ink-scroll]')\n )\n // Not a template listener: Vue leaves those on the element when it unmounts.\n el.addEventListener('keydown', onKeydown)\n onCleanup(() => {\n stopKeys()\n stopFocus()\n el.removeEventListener('keydown', onKeydown)\n })\n },\n { immediate: true }\n)\n\n/*\n * One plugin host for the root's life, built once mounted so that no `setup` runs on the\n * server, where nothing would clean it up. Until then `pluginHost` is null, and InkCommand\n * renders its command disabled. The host follows `hostDocument`, which is set after `document`\n * (a sync watch): when the host reads `inkHistory` for a new document, it is that document's\n * history.\n */\nconst hostDocument = writable<InkDocument | null>(null)\nwatch(document, (doc) => hostDocument.set(doc), { flush: 'sync' })\nconst viewportEl = shallowRef<HTMLElement | null>(null)\nconst hostRoot = writable<HTMLElement | null>(null)\nwatch(viewportEl, (el) => hostRoot.set(el), { flush: 'sync' })\nconst hostActivated = writable<string | null>(null)\nwatch(activated, (id) => hostActivated.set(id), { flush: 'sync' })\nconst pluginHost = shallowRef<PluginHost | null>(null)\n/** One search controller for the root's life, built with the plugin host that shares it. */\nconst search = shallowRef<SearchController | null>(null)\nfunction setUpPlugins(): void {\n const controller = createSearchController({\n document: readonly(hostDocument),\n viewport: () => viewport.value,\n })\n search.value = controller\n pluginHost.value = createPluginHost({\n plugins: props.plugins ?? [],\n document: readonly(hostDocument),\n history: () => inkHistory,\n activated: readonly(hostActivated),\n // As in `createViewer`: an id not in the open document is ignored.\n setActivated: (id) => {\n if (id === null || document.value?.annotations.get(id)) setActivated(id)\n },\n root: readonly(hostRoot),\n decorate: () => props.decorateAnnotation,\n viewport: () => viewport.value,\n search: viewerSearchOf(controller),\n })\n}\n\n/** Ctrl/Cmd+F while focus is in the root and a find bar is mounted; else the browser's. */\nfunction onKeydown(e: KeyboardEvent): void {\n const controller = search.value\n const root = e.currentTarget\n if (controller && root instanceof HTMLElement)\n handleFindKey(e, controller, () => pageSelectionText(root))\n}\n\n/** The document's tool style; it batches through `inkHistory`, whichever mode is on. */\nconst toolStyle = shallowRef<ToolStyle | null>(null)\nlet setStyleTool: ((id: ToolId) => void) | undefined\nwatch(\n document,\n (doc) => {\n if (!doc) {\n toolStyle.value = null\n setStyleTool = undefined\n return\n }\n const tracker = trackToolStyle({\n store: doc.annotations,\n history: { batch: (fn) => inkHistory.batch(fn) },\n // The plugins' tools too, so a plugin tool's style group applies (the host is set by now:\n // it is built on mount, before the first document opens).\n tools: [...(props.tools ?? []), ...(pluginHost.value?.tools ?? [])],\n tool: internalTool.value,\n })\n setStyleTool = (id) => tracker.setTool(id)\n toolStyle.value = tracker.toolStyle\n },\n // Sync: the style is in place before InkViewport's watcher mounts the engine with it.\n { immediate: true, flush: 'sync' }\n)\nwatch(internalTool, (id) => setStyleTool?.(id))\n\n// Plugins and the document on the client only: on the server InkRoot renders its empty slot.\n// The plugins first, so the first document opens with their stores and reactions.\nonMounted(() => {\n syncRootEl()\n // A plugin whose setup throws still leaves the document to open; the error then goes to\n // Vue's error handling (`onErrorCaptured`, `app.config.errorHandler`).\n try {\n setUpPlugins()\n } finally {\n mounted.value = true\n void open()\n }\n})\nonUpdated(syncRootEl)\n\n// Separate sources, so a new `{ url, key }` object with the same key compares equal.\nwatch([() => identity(props.src), () => props.password], () => void open())\n\nwatch(\n () => props.annotations,\n (next) => {\n if (next && document.value?.annotations.mode === 'controlled')\n document.value.annotations.setControlledValue(next)\n }\n)\n\nwatch(\n () => props.fields,\n (next) => {\n if (next) document.value?.form.setControlledValue(next)\n }\n)\n\n/*\n * The tools are known once the plugins are set up on mount. A tool id nobody registered is\n * logged as `UnknownTool`; as the active tool, from a `tool` prop or because it left `tools`,\n * it falls back to `select-text`, reported through `update:tool`. A controlled `tool` that\n * stays on the missing id is not applied again.\n */\nconst mounted = ref(false)\n/** The ids of the tools the current viewer was built with; InkViewport sets them. */\nconst openedToolIds = shallowRef<readonly ToolId[] | null>(null)\nconst toolIds = computed(() =>\n registeredToolIds(props.tools, pluginHost.value, openedToolIds.value)\n)\nconst isRegistered = (id: ToolId): boolean => !mounted.value || toolIds.value.includes(id)\nconst logUnknownTool = (id: ToolId): void => console.error(unknownTool(id, toolIds.value))\n\nfunction fallBack(id: ToolId): void {\n logUnknownTool(id)\n internalTool.value = 'select-text'\n emit('update:tool', 'select-text')\n}\n\nwatch(\n () => props.tool,\n (t) => {\n if (!t) return\n if (isRegistered(t)) internalTool.value = t\n else fallBack(t)\n }\n)\nwatch([mounted, toolIds], () => {\n if (!isRegistered(internalTool.value)) fallBack(internalTool.value)\n})\n\nfunction setTool(id: ToolId): void {\n // As the tool controller does: a missing tool is logged and nothing changes.\n if (!isRegistered(id)) {\n logUnknownTool(id)\n return\n }\n // Picking the active tool again starts it afresh, as after a one-shot tool's use.\n const tc = toolController.value\n if (internalTool.value === id && tc?.active.get() === id) tc.set(id)\n internalTool.value = id\n emit('update:tool', id)\n}\n\nonBeforeUnmount(() => {\n generation++\n release()\n})\n\n// After the children: InkViewport's engine, and the plugin layers with it, are gone by now, as\n// in `createViewer`, so no layer `destroy` runs after the plugins' cleanups.\nonUnmounted(() => {\n pluginHost.value?.destroy()\n pluginHost.value = null\n search.value?.destroy()\n search.value = null\n})\n\nconst signatures = computed(() =>\n createSignatureLibrary(props.signatures ?? createMemorySignatureStore())\n)\nwatch(signatures, (lib) => void lib.refresh(), { immediate: true })\n/** Tool options last as long as the root; the tool style is per document. */\nconst toolOptions = createToolOptions()\n\nprovideInkContext({\n assets: computed(() => props.assets),\n document,\n status,\n annotations: annotationList,\n selection,\n viewport,\n tools: toolController,\n tool: internalTool,\n setTool,\n hostTools: computed(() => props.tools),\n openedToolIds,\n decorateAnnotation: computed(() => props.decorateAnnotation),\n fonts: computed(() => props.fonts ?? FONT_FAMILIES),\n toolOptions,\n signatures,\n signatureFonts: computed(() => props.signatureFonts ?? SIGNATURE_FONTS),\n toolStyle,\n zoomModel: computed(() => props.zoom),\n pageModel: computed(() => props.page),\n reportZoom: (z) => emit('update:zoom', z),\n reportPage: (p) => emit('update:page', p),\n activated,\n setActivated,\n pluginHost,\n search,\n viewportEl,\n history: inkHistory,\n rootEl,\n formHighlight: computed(() => props.formHighlight),\n reportFormAction: (a) => emit('form-action', a),\n reportError: (e) => emit('error', e),\n})\n\n// `history` is what `useHistory()` returns inside the root, for hosts that hold a template ref:\n// a controlled host calls `history.clear()` after loading its saved list.\ndefineExpose({ document, status, rootEl, history: inkHistory })\n</script>\n\n<template>\n <Primitive\n ref=\"primitive\"\n :as-child=\"props.asChild\"\n as=\"div\"\n data-ink-root\n :data-state=\"status.state\"\n >\n <slot :status=\"status\" :document=\"document\" />\n </Primitive>\n</template>\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"InkShapeMenu.js","names":["_sfc_main","InkShapeMenu_vue_vue_type_script_setup_true_lang_default","InkShapeMenu_default"],"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":""}
1
+ {"version":3,"file":"InkShapeMenu.js","names":["_sfc_main","InkShapeMenu_vue_vue_type_script_setup_true_lang_default","InkShapeMenu_default"],"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 { useRegisteredTool } from '../composables/useRegisteredTool'\nimport { useTool } from '../composables/useTool'\nimport { useToolOptionsWhile } from '../composables/useToolOptions'\n\nimport InkIcon from './InkIcon.vue'\n\ndefineOptions({ inheritAttrs: false })\nconst { tool, setTool } = useTool()\n// Nothing renders while no `shape` tool is registered.\nconst registered = useRegisteredTool('shape')\nconst { options, setOptions } = useToolOptionsWhile<ShapeOptions>('shape', registered)\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-if=\"registered\" 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":""}
@@ -1 +1 @@
1
- {"version":3,"file":"InkShapeMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkShapeMenu.vue"],"names":[],"mappings":"AA6KA,OAAO,EAQL,KAAK,SAAS,EAEf,MAAM,kBAAkB,CAAA;AA+SzB,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"}
1
+ {"version":3,"file":"InkShapeMenu.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkShapeMenu.vue"],"names":[],"mappings":"AAgLA,OAAO,EAQL,KAAK,SAAS,EAEf,MAAM,kBAAkB,CAAA;AAwTzB,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"}
@@ -1,86 +1,88 @@
1
- import { useTool as e } from "../composables/useTool.js";
2
- import { useToolOptions as t } from "../composables/useToolOptions.js";
3
- import n from "./InkIcon.js";
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";
1
+ import { useRegisteredTool as e } from "../composables/useRegisteredTool.js";
2
+ import { useTool as t } from "../composables/useTool.js";
3
+ import { useToolOptionsWhile as n } from "../composables/useToolOptions.js";
4
+ import r from "./InkIcon.js";
5
+ import { Fragment as i, computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, createVNode as d, defineComponent as f, guardReactiveProps as p, mergeProps as m, normalizeProps as h, openBlock as g, ref as _, renderList as v, renderSlot as y, toDisplayString as b, unref as x, withCtx as S } from "vue";
6
+ import { SHAPE_COLUMNS as C, SHAPE_ICONS as w, SHAPE_KINDS as T, focusInitialMenuItem as E, handleMenuKeys as D, menuItems as O, shapeMenuModel as k } from "@inkbar/core/dom";
7
+ import { PopoverAnchor as A, PopoverContent as j, PopoverPortal as M, PopoverRoot as N, PopoverTrigger as P, ToolbarButton as F } from "reka-ui";
8
+ import { ChevronDown as I } from "@inkbar/icons";
8
9
  //#region src/components/InkShapeMenu.vue?vue&type=script&setup=true&lang.ts
9
- var F = ["data-state"], I = ["data-ink-menu-columns"], L = [
10
+ var ee = ["data-state"], L = ["data-ink-menu-columns"], R = [
10
11
  "data-key",
11
12
  "aria-checked",
12
13
  "data-state",
13
14
  "onClick"
14
- ], R = /*@__PURE__*/ u({
15
+ ], z = /*@__PURE__*/ f({
15
16
  inheritAttrs: !1,
16
17
  __name: "InkShapeMenu",
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;
19
- function q(e) {
20
- e.key !== "ArrowDown" || e.defaultPrevented || H.value || (e.preventDefault(), K = !0, H.value = !0);
18
+ setup(f) {
19
+ let { tool: z, setTool: B } = t(), V = e("shape"), { options: H, setOptions: U } = n("shape", V), W = _(!1), G = a(() => k(H.value, T)), K = a(() => z.value === "shape"), q = a(() => w[G.value.kind]), J = !1;
20
+ function Y(e) {
21
+ e.key !== "ArrowDown" || e.defaultPrevented || W.value || (e.preventDefault(), J = !0, W.value = !0);
21
22
  }
22
- function J(e) {
23
+ function X(e) {
23
24
  e.preventDefault();
24
25
  let t = document.querySelector("[data-ink-menu=\"shape\"] [role=\"menu\"]");
25
- t && (K ? E(t)[0]?.focus({ preventScroll: !0 }) : w(t)), K = !1;
26
+ t && (J ? O(t)[0]?.focus({ preventScroll: !0 }) : E(t)), J = !1;
26
27
  }
27
- function Y(e) {
28
- V({ kind: e }), z("shape"), H.value = !1;
28
+ function Z(e) {
29
+ U({ kind: e }), B("shape"), W.value = !1;
29
30
  }
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 = {
31
+ let Q = a(() => ({
32
+ "aria-pressed": String(K.value),
33
+ "aria-label": G.value.label,
34
+ title: G.value.label,
35
+ onClick: () => B("shape")
36
+ })), $ = {
36
37
  "aria-label": "Choose shape",
37
38
  title: "Choose shape",
38
39
  "aria-haspopup": "menu",
39
- onKeydown: q
40
- }, Q = { "aria-label": "Shapes" }, $ = {
40
+ onKeydown: Y
41
+ }, te = { "aria-label": "Shapes" }, ne = {
41
42
  role: "menu",
42
43
  "aria-label": "Shapes",
43
- onKeydown: (e) => T(e, e.currentTarget)
44
+ onKeydown: (e) => D(e, e.currentTarget)
44
45
  };
45
- return (e, t) => (m(), a(y(j), {
46
- open: H.value,
47
- "onUpdate:open": t[0] ||= (e) => H.value = e
46
+ return (e, t) => x(V) ? (g(), o(x(N), {
47
+ key: 0,
48
+ open: W.value,
49
+ "onUpdate:open": t[0] ||= (e) => W.value = e
48
50
  }, {
49
- default: b(() => [l(y(O), { "as-child": "" }, {
50
- default: b(() => [s("div", f({
51
+ default: S(() => [d(x(A), { "as-child": "" }, {
52
+ default: S(() => [l("div", m({
51
53
  role: "group",
52
54
  "aria-label": "Shape",
53
55
  class: "ink-split-button ink-shape-menu",
54
56
  "data-ink-shape-menu": ""
55
57
  }, e.$attrs), [
56
- l(y(N), f({
58
+ d(x(F), m({
57
59
  class: "ink-tool-button ink-shape-button",
58
60
  "data-ink-tool-button": "",
59
61
  "data-ink-shape-button": "",
60
62
  "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"])])]),
63
+ "data-kind": G.value.kind,
64
+ "data-state": K.value ? "on" : "off"
65
+ }, Q.value), {
66
+ default: S(() => [y(e.$slots, "default", {
67
+ active: K.value,
68
+ kind: G.value.kind
69
+ }, () => [d(r, { icon: q.value }, null, 8, ["icon"])])]),
68
70
  _: 3
69
71
  }, 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({
72
+ d(x(F), { "as-child": "" }, {
73
+ default: S(() => [d(x(P), { "as-child": "" }, {
74
+ default: S(() => [l("button", m({
73
75
  type: "button",
74
76
  class: "ink-menu-trigger ink-shape-menu-trigger",
75
77
  "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
+ "data-state": W.value ? "open" : "closed"
79
+ }, $), [d(r, { icon: x(I) }, null, 8, ["icon"])], 16, ee)]),
78
80
  _: 1
79
81
  })]),
80
82
  _: 1
81
83
  }),
82
- l(y(A), null, {
83
- default: b(() => [l(y(k), f({
84
+ d(x(M), null, {
85
+ default: S(() => [d(x(j), m({
84
86
  class: "ink-select-content ink-menu-content",
85
87
  "data-ink-select-content": "",
86
88
  "data-ink-menu": "shape",
@@ -88,13 +90,13 @@ var F = ["data-state"], I = ["data-ink-menu-columns"], L = [
88
90
  align: "start",
89
91
  "side-offset": 4,
90
92
  "collision-padding": 8
91
- }, Q, { onOpenAutoFocus: J }), {
92
- default: b(() => [s("div", p(d($)), [s("div", {
93
+ }, te, { onOpenAutoFocus: X }), {
94
+ default: S(() => [l("div", h(p(ne)), [l("div", {
93
95
  role: "group",
94
96
  "aria-label": "Shapes",
95
97
  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
+ "data-ink-menu-columns": x(C)
99
+ }, [(g(!0), c(i, null, v(G.value.items, (e) => (g(), c("button", {
98
100
  key: e.kind,
99
101
  type: "button",
100
102
  role: "menuitemradio",
@@ -104,11 +106,11 @@ var F = ["data-state"], I = ["data-ink-menu-columns"], L = [
104
106
  "data-key": e.kind,
105
107
  "aria-checked": e.checked,
106
108
  "data-state": e.checked ? "checked" : "unchecked",
107
- onClick: (t) => Y(e.kind)
108
- }, [l(n, {
109
- icon: y(S)[e.kind],
109
+ onClick: (t) => Z(e.kind)
110
+ }, [d(r, {
111
+ icon: x(w)[e.kind],
110
112
  size: 16
111
- }, null, 8, ["icon"]), c(" " + v(e.label), 1)], 8, L))), 128))], 8, I)], 16)]),
113
+ }, null, 8, ["icon"]), u(" " + b(e.label), 1)], 8, R))), 128))], 8, L)], 16)]),
112
114
  _: 1
113
115
  }, 16)]),
114
116
  _: 1
@@ -117,10 +119,10 @@ var F = ["data-state"], I = ["data-ink-menu-columns"], L = [
117
119
  _: 3
118
120
  })]),
119
121
  _: 3
120
- }, 8, ["open"]));
122
+ }, 8, ["open"])) : s("", !0);
121
123
  }
122
124
  });
123
125
  //#endregion
124
- export { R as default };
126
+ export { z as default };
125
127
 
126
128
  //# 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":["$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
+ {"version":3,"file":"InkShapeMenu.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_unref","_openBlock","_createBlock","_withCtx","_createVNode","_createElementVNode","_mergeProps","_renderSlot","InkIcon","_normalizeProps","_guardReactiveProps","_createElementBlock","_Fragment","_renderList","_createTextVNode","_toDisplayString","_createCommentVNode","InkIcon_default","_hoisted_1","_hoisted_2","_hoisted_3","InkShapeMenu_vue_vue_type_script_setup_true_lang_default","useTool","registered","useRegisteredTool","useToolOptionsWhile","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","unref","openBlock","createBlock","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","createCommentVNode"],"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 { useRegisteredTool } from '../composables/useRegisteredTool'\nimport { useTool } from '../composables/useTool'\nimport { useToolOptionsWhile } from '../composables/useToolOptions'\n\nimport InkIcon from './InkIcon.vue'\n\ndefineOptions({ inheritAttrs: false })\nconst { tool, setTool } = useTool()\n// Nothing renders while no `shape` tool is registered.\nconst registered = useRegisteredTool('shape')\nconst { options, setOptions } = useToolOptionsWhile<ShapeOptions>('shape', registered)\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-if=\"registered\" 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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"}
@@ -0,0 +1,7 @@
1
+ import e from "./InkSignFieldPopover.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/components/InkSignFieldPopover.vue
3
+ var t = e;
4
+ //#endregion
5
+ export { t as default };
6
+
7
+ //# sourceMappingURL=InkSignFieldPopover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkSignFieldPopover.js","names":["_sfc_main","InkSignFieldPopover_vue_vue_type_script_setup_true_lang_default","InkSignFieldPopover_default"],"sources":["../../src/components/InkSignFieldPopover.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * The signature menu for a signature field, opened from the field's \"Sign\" button and anchored\n * to its box. It lists the saved signatures and \"Create signature\", as `InkSignatureMenu`\n * does. Picking one signs the field with it (`signField`); a signature made in\n * `InkSignatureDialog` signs the field once saved, without picking the signature tool. Focus\n * returns to the field. InkViewport mounts it, one per document; hosts compose nothing.\n */\nimport { InkError, signField, type SignatureTemplate } from '@inkbar/core'\nimport {\n focusInitialMenuItem,\n SIGNATURE_LABELS,\n signatureMenuModel,\n watchDetached,\n} from '@inkbar/core/dom'\nimport { PopoverContent, PopoverPortal, PopoverRoot } from 'reka-ui'\nimport { computed, onBeforeUnmount, shallowRef, watch } from 'vue'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport InkSignatureDialog from './InkSignatureDialog.vue'\nimport SignatureMenuPanel from './SignatureMenuPanel.vue'\n\nimport type { InkDocument } from '@inkbar/core'\nimport type { SignFieldRequest } from '@inkbar/core/dom'\n\nconst props = defineProps<{\n /** The field to sign; `null` while the menu is closed. */\n request: SignFieldRequest | null\n}>()\nconst emit = defineEmits<{ close: [] }>()\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\nconst ctx = useInkContext('InkSignFieldPopover')\nconst templates = useReadable(() => ctx.signatures.value.templates, NO_TEMPLATES)\n// No signature is \"chosen\" here: each signing picks its own.\nconst model = computed(() => signatureMenuModel(templates.value, {}))\nconst open = computed(() => props.request !== null)\n/** The field the dialog signs once its signature is saved, and the document it is in. */\nconst creatingFor = shallowRef<{ req: SignFieldRequest; doc: InkDocument } | null>(null)\nconst creating = computed({\n get: () => creatingFor.value !== null,\n set: (next) => {\n if (!next) creatingFor.value = null\n },\n})\n/**\n * The request the menu was last open for, kept to return focus once it closes. A request that\n * replaces the open one takes over, so focus returns to the field asked for last.\n */\nlet last: SignFieldRequest | null = null\n/** Set while the menu closes for the dialog, which takes focus instead of the field. */\nlet toDialog = false\n/** Cleared on unmount, so a dialog save that settles after the document went signs nothing. */\nlet alive = true\nonBeforeUnmount(() => {\n alive = false\n})\n\n// The field's box went (its page unmounted, its layer rebuilt): the menu has nothing to stand\n// by.\nwatch(\n () => props.request,\n (req, _, onCleanup) => {\n if (!req) return\n last = req\n onCleanup(watchDetached(req.anchor, () => emit('close')))\n },\n { immediate: true }\n)\n\nconst control = (req: SignFieldRequest | null): HTMLElement | null =>\n req?.anchor.querySelector<HTMLElement>('button.ink-form-control') ?? null\n\n/** Focus goes back to the field's button, or to the scroll element once the field's box has gone. */\nfunction returnFocus(req: SignFieldRequest | null): void {\n const c = control(req)\n ;(c?.isConnected ? c : ctx.viewportEl.value)?.focus({ preventScroll: true })\n}\n\n/** Signs the request's field with `t`; a refusal (signed, read-only by now) goes to `error`. */\nfunction sign(req: SignFieldRequest, doc: InkDocument, t: SignatureTemplate): void {\n // The document the request came from is still the open one.\n if (!alive || ctx.document.value !== doc) return\n try {\n signField(doc, req.field, req.widget, t)\n } catch (e) {\n if (!(e instanceof InkError)) throw e\n ctx.reportError(e)\n }\n}\n\nfunction choose(t: SignatureTemplate): void {\n const req = props.request\n const doc = ctx.document.value\n emit('close')\n if (req && doc) sign(req, doc, t)\n}\n\nfunction create(): void {\n const req = props.request\n const doc = ctx.document.value\n if (!req || !doc) return\n toDialog = true\n creatingFor.value = { req, doc }\n emit('close')\n}\n\nfunction onSaved(t: SignatureTemplate): void {\n const c = creatingFor.value\n if (c) sign(c.req, c.doc, t)\n}\n\n/**\n * A press on this field's own button toggles the menu through the engine; it must not also\n * close it here first, or the click would open it again.\n */\nfunction onInteractOutside(e: CustomEvent<{ originalEvent: Event }>): void {\n const target = e.detail.originalEvent.target\n if (target instanceof Node && props.request?.anchor.contains(target)) e.preventDefault()\n}\n\nfunction onOpenAutoFocus(e: Event): void {\n e.preventDefault()\n // An old removal error is not news when the menu opens again.\n ctx.signatures.value.clearRemoveError()\n const menu = (e.target as HTMLElement | null)?.querySelector<HTMLElement>(\n '[role=\"menu\"]'\n )\n if (menu) focusInitialMenuItem(menu)\n}\n\nfunction onCloseAutoFocus(e: Event): void {\n e.preventDefault()\n if (!toDialog) returnFocus(last)\n toDialog = false\n}\n\nfunction onDialogCloseAutoFocus(e: Event): void {\n e.preventDefault()\n returnFocus(last)\n}\n\nfunction onOpenChange(next: boolean): void {\n if (!next) emit('close')\n}\n\n// Reka's typed props stop at its own; ARIA goes through a bound object.\nconst menuAttrs = { 'aria-label': SIGNATURE_LABELS.menu }\n</script>\n\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"onOpenChange\">\n <PopoverPortal>\n <PopoverContent\n v-if=\"props.request\"\n :reference=\"props.request.anchor\"\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n data-ink-menu=\"signature\"\n :data-ink-sign-field-menu=\"props.request.field\"\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 @interact-outside=\"onInteractOutside\"\n >\n <SignatureMenuPanel :items=\"model.items\" @choose=\"choose\" @create=\"create\" />\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <InkSignatureDialog\n v-model:open=\"creating\"\n :select=\"false\"\n @save=\"onSaved\"\n @close-auto-focus=\"onDialogCloseAutoFocus\"\n />\n</template>\n"],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { SignFieldRequest } from '@inkbar/core/dom';
2
+ type __VLS_Props = {
3
+ /** The field to sign; `null` while the menu is closed. */
4
+ request: SignFieldRequest | null;
5
+ };
6
+ declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
7
+ close: () => any;
8
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
9
+ onClose?: () => any;
10
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
13
+ //# sourceMappingURL=InkSignFieldPopover.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkSignFieldPopover.vue.d.ts","sourceRoot":"","sources":["../../src/components/InkSignFieldPopover.vue"],"names":[],"mappings":"AAiNA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAGxD,KAAK,WAAW,GAAG;IACjB,0DAA0D;IAC1D,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAA;CACjC,CAAC;AA4RF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -0,0 +1,116 @@
1
+ import { useInkContext as e } from "../context.js";
2
+ import { useReadable as t } from "../use-readable.js";
3
+ import n from "./InkSignatureDialog.js";
4
+ import r from "./SignatureMenuPanel.js";
5
+ import { Fragment as i, computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createVNode as l, defineComponent as u, mergeProps as d, onBeforeUnmount as f, openBlock as p, shallowRef as m, unref as h, watch as g, withCtx as _ } from "vue";
6
+ import { InkError as v, signField as y } from "@inkbar/core";
7
+ import { SIGNATURE_LABELS as b, focusInitialMenuItem as x, signatureMenuModel as S, watchDetached as C } from "@inkbar/core/dom";
8
+ import { PopoverContent as w, PopoverPortal as T, PopoverRoot as E } from "reka-ui";
9
+ //#region src/components/InkSignFieldPopover.vue?vue&type=script&setup=true&lang.ts
10
+ var D = /*@__PURE__*/ u({
11
+ __name: "InkSignFieldPopover",
12
+ props: { request: {} },
13
+ emits: ["close"],
14
+ setup(u, { emit: D }) {
15
+ let O = u, k = D, A = [], j = e("InkSignFieldPopover"), M = t(() => j.signatures.value.templates, A), N = a(() => S(M.value, {})), P = a(() => O.request !== null), F = m(null), I = a({
16
+ get: () => F.value !== null,
17
+ set: (e) => {
18
+ e || (F.value = null);
19
+ }
20
+ }), L = null, R = !1, z = !0;
21
+ f(() => {
22
+ z = !1;
23
+ }), g(() => O.request, (e, t, n) => {
24
+ e && (L = e, n(C(e.anchor, () => k("close"))));
25
+ }, { immediate: !0 });
26
+ let B = (e) => e?.anchor.querySelector("button.ink-form-control") ?? null;
27
+ function V(e) {
28
+ let t = B(e);
29
+ (t?.isConnected ? t : j.viewportEl.value)?.focus({ preventScroll: !0 });
30
+ }
31
+ function H(e, t, n) {
32
+ if (z && j.document.value === t) try {
33
+ y(t, e.field, e.widget, n);
34
+ } catch (e) {
35
+ if (!(e instanceof v)) throw e;
36
+ j.reportError(e);
37
+ }
38
+ }
39
+ function U(e) {
40
+ let t = O.request, n = j.document.value;
41
+ k("close"), t && n && H(t, n, e);
42
+ }
43
+ function W() {
44
+ let e = O.request, t = j.document.value;
45
+ e && t && (R = !0, F.value = {
46
+ req: e,
47
+ doc: t
48
+ }, k("close"));
49
+ }
50
+ function G(e) {
51
+ let t = F.value;
52
+ t && H(t.req, t.doc, e);
53
+ }
54
+ function K(e) {
55
+ let t = e.detail.originalEvent.target;
56
+ t instanceof Node && O.request?.anchor.contains(t) && e.preventDefault();
57
+ }
58
+ function q(e) {
59
+ e.preventDefault(), j.signatures.value.clearRemoveError();
60
+ let t = e.target?.querySelector("[role=\"menu\"]");
61
+ t && x(t);
62
+ }
63
+ function J(e) {
64
+ e.preventDefault(), R || V(L), R = !1;
65
+ }
66
+ function Y(e) {
67
+ e.preventDefault(), V(L);
68
+ }
69
+ function X(e) {
70
+ e || k("close");
71
+ }
72
+ let Z = { "aria-label": b.menu };
73
+ return (e, t) => (p(), c(i, null, [l(h(E), {
74
+ open: P.value,
75
+ "onUpdate:open": X
76
+ }, {
77
+ default: _(() => [l(h(T), null, {
78
+ default: _(() => [O.request ? (p(), o(h(w), d({
79
+ key: 0,
80
+ reference: O.request.anchor,
81
+ class: "ink-select-content ink-menu-content",
82
+ "data-ink-select-content": "",
83
+ "data-ink-menu": "signature",
84
+ "data-ink-sign-field-menu": O.request.field,
85
+ side: "bottom",
86
+ align: "start",
87
+ "side-offset": 4,
88
+ "collision-padding": 8
89
+ }, Z, {
90
+ onOpenAutoFocus: q,
91
+ onCloseAutoFocus: J,
92
+ onInteractOutside: K
93
+ }), {
94
+ default: _(() => [l(r, {
95
+ items: N.value.items,
96
+ onChoose: U,
97
+ onCreate: W
98
+ }, null, 8, ["items"])]),
99
+ _: 1
100
+ }, 16, ["reference", "data-ink-sign-field-menu"])) : s("", !0)]),
101
+ _: 1
102
+ })]),
103
+ _: 1
104
+ }, 8, ["open"]), l(n, {
105
+ open: I.value,
106
+ "onUpdate:open": t[0] ||= (e) => I.value = e,
107
+ select: !1,
108
+ onSave: G,
109
+ onCloseAutoFocus: Y
110
+ }, null, 8, ["open"])], 64));
111
+ }
112
+ });
113
+ //#endregion
114
+ export { D as default };
115
+
116
+ //# sourceMappingURL=InkSignFieldPopover.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InkSignFieldPopover.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_Fragment","_createVNode","_unref","_withCtx","_createBlock","_mergeProps","SignatureMenuPanel","_createCommentVNode","InkSignatureDialog","InkSignatureDialog_default","SignatureMenuPanel_default","InkSignFieldPopover_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","NO_TEMPLATES","ctx","useInkContext","templates","useReadable","model","computed","signatureMenuModel","open","creatingFor","shallowRef","creating","next","last","toDialog","alive","onBeforeUnmount","watch","req","onCleanup","watchDetached","control","returnFocus","c","sign","doc","t","InkError","choose","create","onSaved","onInteractOutside","target","onOpenAutoFocus","menu","focusInitialMenuItem","onCloseAutoFocus","onDialogCloseAutoFocus","onOpenChange","menuAttrs","SIGNATURE_LABELS","openBlock","createElementBlock","Fragment","createVNode","unref","PopoverRoot","withCtx","PopoverPortal","createBlock","PopoverContent","mergeProps","createCommentVNode","_cache","$event"],"sources":["../../src/components/InkSignFieldPopover.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/*\n * The signature menu for a signature field, opened from the field's \"Sign\" button and anchored\n * to its box. It lists the saved signatures and \"Create signature\", as `InkSignatureMenu`\n * does. Picking one signs the field with it (`signField`); a signature made in\n * `InkSignatureDialog` signs the field once saved, without picking the signature tool. Focus\n * returns to the field. InkViewport mounts it, one per document; hosts compose nothing.\n */\nimport { InkError, signField, type SignatureTemplate } from '@inkbar/core'\nimport {\n focusInitialMenuItem,\n SIGNATURE_LABELS,\n signatureMenuModel,\n watchDetached,\n} from '@inkbar/core/dom'\nimport { PopoverContent, PopoverPortal, PopoverRoot } from 'reka-ui'\nimport { computed, onBeforeUnmount, shallowRef, watch } from 'vue'\n\nimport { useInkContext } from '../context'\nimport { useReadable } from '../use-readable'\n\nimport InkSignatureDialog from './InkSignatureDialog.vue'\nimport SignatureMenuPanel from './SignatureMenuPanel.vue'\n\nimport type { InkDocument } from '@inkbar/core'\nimport type { SignFieldRequest } from '@inkbar/core/dom'\n\nconst props = defineProps<{\n /** The field to sign; `null` while the menu is closed. */\n request: SignFieldRequest | null\n}>()\nconst emit = defineEmits<{ close: [] }>()\n\nconst NO_TEMPLATES: readonly SignatureTemplate[] = []\n\nconst ctx = useInkContext('InkSignFieldPopover')\nconst templates = useReadable(() => ctx.signatures.value.templates, NO_TEMPLATES)\n// No signature is \"chosen\" here: each signing picks its own.\nconst model = computed(() => signatureMenuModel(templates.value, {}))\nconst open = computed(() => props.request !== null)\n/** The field the dialog signs once its signature is saved, and the document it is in. */\nconst creatingFor = shallowRef<{ req: SignFieldRequest; doc: InkDocument } | null>(null)\nconst creating = computed({\n get: () => creatingFor.value !== null,\n set: (next) => {\n if (!next) creatingFor.value = null\n },\n})\n/**\n * The request the menu was last open for, kept to return focus once it closes. A request that\n * replaces the open one takes over, so focus returns to the field asked for last.\n */\nlet last: SignFieldRequest | null = null\n/** Set while the menu closes for the dialog, which takes focus instead of the field. */\nlet toDialog = false\n/** Cleared on unmount, so a dialog save that settles after the document went signs nothing. */\nlet alive = true\nonBeforeUnmount(() => {\n alive = false\n})\n\n// The field's box went (its page unmounted, its layer rebuilt): the menu has nothing to stand\n// by.\nwatch(\n () => props.request,\n (req, _, onCleanup) => {\n if (!req) return\n last = req\n onCleanup(watchDetached(req.anchor, () => emit('close')))\n },\n { immediate: true }\n)\n\nconst control = (req: SignFieldRequest | null): HTMLElement | null =>\n req?.anchor.querySelector<HTMLElement>('button.ink-form-control') ?? null\n\n/** Focus goes back to the field's button, or to the scroll element once the field's box has gone. */\nfunction returnFocus(req: SignFieldRequest | null): void {\n const c = control(req)\n ;(c?.isConnected ? c : ctx.viewportEl.value)?.focus({ preventScroll: true })\n}\n\n/** Signs the request's field with `t`; a refusal (signed, read-only by now) goes to `error`. */\nfunction sign(req: SignFieldRequest, doc: InkDocument, t: SignatureTemplate): void {\n // The document the request came from is still the open one.\n if (!alive || ctx.document.value !== doc) return\n try {\n signField(doc, req.field, req.widget, t)\n } catch (e) {\n if (!(e instanceof InkError)) throw e\n ctx.reportError(e)\n }\n}\n\nfunction choose(t: SignatureTemplate): void {\n const req = props.request\n const doc = ctx.document.value\n emit('close')\n if (req && doc) sign(req, doc, t)\n}\n\nfunction create(): void {\n const req = props.request\n const doc = ctx.document.value\n if (!req || !doc) return\n toDialog = true\n creatingFor.value = { req, doc }\n emit('close')\n}\n\nfunction onSaved(t: SignatureTemplate): void {\n const c = creatingFor.value\n if (c) sign(c.req, c.doc, t)\n}\n\n/**\n * A press on this field's own button toggles the menu through the engine; it must not also\n * close it here first, or the click would open it again.\n */\nfunction onInteractOutside(e: CustomEvent<{ originalEvent: Event }>): void {\n const target = e.detail.originalEvent.target\n if (target instanceof Node && props.request?.anchor.contains(target)) e.preventDefault()\n}\n\nfunction onOpenAutoFocus(e: Event): void {\n e.preventDefault()\n // An old removal error is not news when the menu opens again.\n ctx.signatures.value.clearRemoveError()\n const menu = (e.target as HTMLElement | null)?.querySelector<HTMLElement>(\n '[role=\"menu\"]'\n )\n if (menu) focusInitialMenuItem(menu)\n}\n\nfunction onCloseAutoFocus(e: Event): void {\n e.preventDefault()\n if (!toDialog) returnFocus(last)\n toDialog = false\n}\n\nfunction onDialogCloseAutoFocus(e: Event): void {\n e.preventDefault()\n returnFocus(last)\n}\n\nfunction onOpenChange(next: boolean): void {\n if (!next) emit('close')\n}\n\n// Reka's typed props stop at its own; ARIA goes through a bound object.\nconst menuAttrs = { 'aria-label': SIGNATURE_LABELS.menu }\n</script>\n\n<template>\n <PopoverRoot :open=\"open\" @update:open=\"onOpenChange\">\n <PopoverPortal>\n <PopoverContent\n v-if=\"props.request\"\n :reference=\"props.request.anchor\"\n class=\"ink-select-content ink-menu-content\"\n data-ink-select-content\n data-ink-menu=\"signature\"\n :data-ink-sign-field-menu=\"props.request.field\"\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 @interact-outside=\"onInteractOutside\"\n >\n <SignatureMenuPanel :items=\"model.items\" @choose=\"choose\" @create=\"create\" />\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n <InkSignatureDialog\n v-model:open=\"creating\"\n :select=\"false\"\n @save=\"onSaved\"\n @close-auto-focus=\"onDialogCloseAutoFocus\"\n />\n</template>\n"],"mappings":"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"}