kviewer 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/module.d.mts +8 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +25 -3
- package/dist/runtime/annotation/engine/canvas-resolution.d.ts +7 -0
- package/dist/runtime/annotation/engine/canvas-resolution.js +21 -0
- package/dist/runtime/annotation/engine/editor/editor.d.ts +5 -0
- package/dist/runtime/annotation/engine/editor/editor.js +14 -0
- package/dist/runtime/annotation/engine/editor/selector.d.ts +13 -1
- package/dist/runtime/annotation/engine/editor/selector.js +60 -8
- package/dist/runtime/annotation/engine/painter.d.ts +31 -0
- package/dist/runtime/annotation/engine/painter.js +88 -2
- package/dist/runtime/annotation/engine/store.js +3 -0
- package/dist/runtime/annotation/engine/tools/arrow.js +0 -1
- package/dist/runtime/annotation/engine/tools/circle.js +0 -2
- package/dist/runtime/annotation/engine/tools/free-highlight.js +0 -2
- package/dist/runtime/annotation/engine/tools/freehand.js +0 -2
- package/dist/runtime/annotation/engine/tools/rectangle.js +0 -2
- package/dist/runtime/annotation/engine/types.d.ts +5 -0
- package/dist/runtime/annotation/font-style.d.ts +15 -0
- package/dist/runtime/annotation/font-style.js +19 -0
- package/dist/runtime/annotation/parsers/extractCheckboxStyles.d.ts +8 -0
- package/dist/runtime/annotation/parsers/extractCheckboxStyles.js +24 -1
- package/dist/runtime/annotation/pdf-export/annotation-flags.d.ts +8 -0
- package/dist/runtime/annotation/pdf-export/annotation-flags.js +5 -0
- package/dist/runtime/annotation/pdf-export/export-form-fields.js +3 -1
- package/dist/runtime/annotation/pdf-export/export.js +13 -1
- package/dist/runtime/annotation/pdf-export/parse_circle.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_freetext.js +31 -19
- package/dist/runtime/annotation/pdf-export/parse_highlight.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_ink.js +5 -1
- package/dist/runtime/annotation/pdf-export/parse_line.js +5 -1
- package/dist/runtime/annotation/pdf-export/parse_polyline.js +5 -1
- package/dist/runtime/annotation/pdf-export/parse_square.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_stamp.js +4 -2
- package/dist/runtime/annotation/pdf-export/parse_strikeout.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_text.js +3 -0
- package/dist/runtime/annotation/pdf-export/parse_underline.js +3 -0
- package/dist/runtime/annotation/pdf-export/unicode-font.d.ts +5 -0
- package/dist/runtime/annotation/pdf-export/unicode-font.js +31 -0
- package/dist/runtime/annotation/pdf-export/winansi.d.ts +17 -0
- package/dist/runtime/annotation/pdf-export/winansi.js +77 -0
- package/dist/runtime/annotation/pdf-import/decode_circle.js +0 -1
- package/dist/runtime/annotation/pdf-import/decode_ink.js +0 -1
- package/dist/runtime/annotation/pdf-import/decode_line.js +0 -1
- package/dist/runtime/annotation/pdf-import/decode_square.js +0 -1
- package/dist/runtime/annotation/pdf-import/extract_stamp_appearance.d.ts +12 -0
- package/dist/runtime/annotation/pdf-import/extract_stamp_appearance.js +17 -4
- package/dist/runtime/annotation/pdf-import/types.d.ts +2 -0
- package/dist/runtime/assets/fonts/LICENSE-LiberationSans +102 -0
- package/dist/runtime/assets/fonts/LiberationSans-Regular.ttf +0 -0
- package/dist/runtime/assets/kviewer.css +1 -1
- package/dist/runtime/components/AnnotationToolbar.vue +6 -4
- package/dist/runtime/components/PdfPage.d.vue.ts +16 -0
- package/dist/runtime/components/PdfPage.vue +170 -9
- package/dist/runtime/components/PdfPage.vue.d.ts +16 -0
- package/dist/runtime/components/PerfHud.d.vue.ts +3 -0
- package/dist/runtime/components/PerfHud.vue +97 -0
- package/dist/runtime/components/PerfHud.vue.d.ts +3 -0
- package/dist/runtime/components/ToolButton.vue +4 -1
- package/dist/runtime/components/Viewer.d.vue.ts +25 -2
- package/dist/runtime/components/Viewer.vue +173 -11
- package/dist/runtime/components/Viewer.vue.d.ts +25 -2
- package/dist/runtime/components/ViewerBar.d.vue.ts +21 -1
- package/dist/runtime/components/ViewerBar.vue +183 -101
- package/dist/runtime/components/ViewerBar.vue.d.ts +21 -1
- package/dist/runtime/components/ViewerTabs.d.vue.ts +10 -2
- package/dist/runtime/components/ViewerTabs.vue +13 -2
- package/dist/runtime/components/ViewerTabs.vue.d.ts +10 -2
- package/dist/runtime/components/form-fields/FormDropdown.vue +50 -19
- package/dist/runtime/components/form-fields/FormSignatureField.vue +4 -2
- package/dist/runtime/components/form-fields/FormTextField.vue +7 -18
- package/dist/runtime/components/modals/FreeTextModal.vue +6 -4
- package/dist/runtime/components/modals/SignatureDrawModal.vue +6 -4
- package/dist/runtime/components/panels/PlacedFieldSidebar.vue +67 -50
- package/dist/runtime/components/panels/SignaturePicker.vue +6 -4
- package/dist/runtime/components/panels/StampPicker.vue +3 -1
- package/dist/runtime/components/tools/AnnotationToolButton.d.vue.ts +10 -0
- package/dist/runtime/components/tools/AnnotationToolButton.vue +33 -0
- package/dist/runtime/components/tools/AnnotationToolButton.vue.d.ts +10 -0
- package/dist/runtime/components/tools/MarqueeTool.vue +3 -1
- package/dist/runtime/components/tools/PageSettings.vue +13 -11
- package/dist/runtime/components/tools/SearchTool.vue +12 -10
- package/dist/runtime/components/tools/ToolProperties.vue +7 -5
- package/dist/runtime/components/tools/ToolbarMenu.d.vue.ts +9 -0
- package/dist/runtime/components/tools/ToolbarMenu.vue +79 -0
- package/dist/runtime/components/tools/ToolbarMenu.vue.d.ts +9 -0
- package/dist/runtime/components/tools/ZoomControls.vue +17 -9
- package/dist/runtime/composables/canvas-limits.d.ts +22 -0
- package/dist/runtime/composables/canvas-limits.js +10 -0
- package/dist/runtime/composables/useFormFields.d.ts +6 -0
- package/dist/runtime/composables/useFormFields.js +28 -0
- package/dist/runtime/composables/useInertiaPanzoom.d.ts +10 -0
- package/dist/runtime/composables/useInertiaPanzoom.js +57 -10
- package/dist/runtime/composables/useKviewerI18n.d.ts +18 -0
- package/dist/runtime/composables/useKviewerI18n.js +29 -0
- package/dist/runtime/composables/useScriptingManager.d.ts +8 -4
- package/dist/runtime/composables/useScriptingManager.js +2 -0
- package/dist/runtime/composables/useViewerState.d.ts +4 -0
- package/dist/runtime/composables/useViewerState.js +8 -0
- package/dist/runtime/i18n/messages.d.ts +252 -0
- package/dist/runtime/i18n/messages.js +249 -0
- package/dist/runtime/public-types.d.ts +2 -0
- package/dist/runtime/toolbar-tools.d.ts +54 -0
- package/dist/runtime/toolbar-tools.js +79 -0
- package/dist/types.d.mts +1 -1
- package/package.json +14 -31
|
@@ -6,9 +6,25 @@ type __VLS_Props = {
|
|
|
6
6
|
/** Canvas internal resolution multiplier (CSS size unchanged).
|
|
7
7
|
* Used by panzoom to sharpen the PDF when visually zoomed in. */
|
|
8
8
|
renderQuality?: number;
|
|
9
|
+
/** Visible region of this page in page-CSS coordinates (already
|
|
10
|
+
* includes margin), supplied by the viewer's panzoom. Drives the
|
|
11
|
+
* viewport-window raster at high zoom. Null = unknown/inapplicable
|
|
12
|
+
* (e.g. rotated pages), full-page rendering only. */
|
|
13
|
+
viewWindow?: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
} | null;
|
|
9
19
|
};
|
|
10
20
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
11
21
|
renderQuality: number;
|
|
22
|
+
viewWindow: {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
width: number;
|
|
26
|
+
height: number;
|
|
27
|
+
} | null;
|
|
12
28
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
29
|
declare const _default: typeof __VLS_export;
|
|
14
30
|
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div v-if="enabled" class="perf-hud">
|
|
3
|
+
<div>fps {{ fps }} | p95 {{ p95 }}ms | max {{ maxGap }}ms</div>
|
|
4
|
+
<div>evt/s {{ evtRate }} | konva {{ drawPerSec }}ms/s | long {{ longSupported ? longMs + "ms/s" : "n/a" }}</div>
|
|
5
|
+
<div>{{ canvasInfo }}</div>
|
|
6
|
+
<button class="perf-hud-btn" @pointerdown.stop @click="noDraw = !noDraw">
|
|
7
|
+
konva draw: {{ noDraw ? "OFF" : "on" }}
|
|
8
|
+
</button>
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script setup>
|
|
13
|
+
import { ref, onMounted, onBeforeUnmount } from "vue";
|
|
14
|
+
import Konva from "konva";
|
|
15
|
+
const enabled = ref(false);
|
|
16
|
+
const fps = ref(0);
|
|
17
|
+
const p95 = ref(0);
|
|
18
|
+
const maxGap = ref(0);
|
|
19
|
+
const evtRate = ref(0);
|
|
20
|
+
const drawPerSec = ref(0);
|
|
21
|
+
const longMs = ref(0);
|
|
22
|
+
const longSupported = ref(false);
|
|
23
|
+
const canvasInfo = ref("");
|
|
24
|
+
const noDraw = ref(false);
|
|
25
|
+
let raf = 0;
|
|
26
|
+
let interval = 0;
|
|
27
|
+
let last = 0;
|
|
28
|
+
let gaps = [];
|
|
29
|
+
let evtCount = 0;
|
|
30
|
+
let drawMs = 0;
|
|
31
|
+
let longTaskMs = 0;
|
|
32
|
+
let po = null;
|
|
33
|
+
let origDraw = null;
|
|
34
|
+
function onAnyMove() {
|
|
35
|
+
evtCount++;
|
|
36
|
+
}
|
|
37
|
+
onMounted(() => {
|
|
38
|
+
enabled.value = new URLSearchParams(window.location.search).has("perf");
|
|
39
|
+
if (!enabled.value) return;
|
|
40
|
+
origDraw = Konva.Layer.prototype.drawScene;
|
|
41
|
+
Konva.Layer.prototype.drawScene = function(...args) {
|
|
42
|
+
if (noDraw.value) return this;
|
|
43
|
+
const t0 = performance.now();
|
|
44
|
+
const r = origDraw.apply(this, args);
|
|
45
|
+
drawMs += performance.now() - t0;
|
|
46
|
+
return r;
|
|
47
|
+
};
|
|
48
|
+
window.addEventListener("pointermove", onAnyMove, { capture: true, passive: true });
|
|
49
|
+
window.addEventListener("touchmove", onAnyMove, { capture: true, passive: true });
|
|
50
|
+
try {
|
|
51
|
+
po = new PerformanceObserver((list) => {
|
|
52
|
+
for (const e of list.getEntries()) longTaskMs += e.duration;
|
|
53
|
+
});
|
|
54
|
+
po.observe({ type: "longtask" });
|
|
55
|
+
longSupported.value = true;
|
|
56
|
+
} catch {
|
|
57
|
+
longSupported.value = false;
|
|
58
|
+
}
|
|
59
|
+
const tick = (t) => {
|
|
60
|
+
if (last) gaps.push(t - last);
|
|
61
|
+
last = t;
|
|
62
|
+
raf = requestAnimationFrame(tick);
|
|
63
|
+
};
|
|
64
|
+
raf = requestAnimationFrame(tick);
|
|
65
|
+
interval = window.setInterval(() => {
|
|
66
|
+
const sorted = [...gaps].sort((a, b) => a - b);
|
|
67
|
+
const total = gaps.reduce((s, g) => s + g, 0);
|
|
68
|
+
fps.value = total > 0 ? Math.round(gaps.length / total * 1e3) : 0;
|
|
69
|
+
p95.value = Math.round(sorted[Math.floor(sorted.length * 0.95)] ?? 0);
|
|
70
|
+
maxGap.value = Math.round(sorted[sorted.length - 1] ?? 0);
|
|
71
|
+
evtRate.value = evtCount;
|
|
72
|
+
drawPerSec.value = Math.round(drawMs);
|
|
73
|
+
longMs.value = Math.round(longTaskMs);
|
|
74
|
+
gaps = [];
|
|
75
|
+
evtCount = 0;
|
|
76
|
+
drawMs = 0;
|
|
77
|
+
longTaskMs = 0;
|
|
78
|
+
const pageEl = document.querySelector(".kviewer-page");
|
|
79
|
+
if (pageEl) {
|
|
80
|
+
canvasInfo.value = [...pageEl.querySelectorAll(":scope > canvas, .konvajs-content canvas")].map((c) => `${c.width}x${c.height}`).join(" | ");
|
|
81
|
+
}
|
|
82
|
+
}, 1e3);
|
|
83
|
+
});
|
|
84
|
+
onBeforeUnmount(() => {
|
|
85
|
+
if (!enabled.value) return;
|
|
86
|
+
cancelAnimationFrame(raf);
|
|
87
|
+
clearInterval(interval);
|
|
88
|
+
window.removeEventListener("pointermove", onAnyMove, { capture: true });
|
|
89
|
+
window.removeEventListener("touchmove", onAnyMove, { capture: true });
|
|
90
|
+
po?.disconnect();
|
|
91
|
+
if (origDraw) Konva.Layer.prototype.drawScene = origDraw;
|
|
92
|
+
});
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<style scoped>
|
|
96
|
+
.perf-hud{background:rgba(0,0,0,.8);border-radius:6px;color:#4ade80;font:11px/1.4 ui-monospace,monospace;left:50%;padding:4px 8px;pointer-events:none;position:fixed;text-align:center;top:4px;transform:translateX(-50%);white-space:nowrap;z-index:99999}.perf-hud-btn{background:#333;border:1px solid #666;border-radius:4px;color:#fff;font:inherit;margin-top:2px;padding:2px 8px;pointer-events:auto}
|
|
97
|
+
</style>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
v-if="tool"
|
|
4
4
|
class="relative flex items-center justify-center w-8 h-8 rounded-md transition-colors cursor-pointer"
|
|
5
5
|
:class="active ? 'bg-default text-highlighted' : 'text-muted hover:bg-default/50 hover:text-highlighted'"
|
|
6
|
-
:title="tool.name"
|
|
6
|
+
:title="toolLabel(tool.name)"
|
|
7
|
+
:data-testid="`tool-${tool.name}`"
|
|
7
8
|
@click="$emit('click')"
|
|
8
9
|
>
|
|
9
10
|
<UIcon :name="tool.icon" class="text-lg" />
|
|
@@ -17,6 +18,8 @@
|
|
|
17
18
|
</template>
|
|
18
19
|
|
|
19
20
|
<script setup>
|
|
21
|
+
import { useKviewerI18n } from "../composables/useKviewerI18n";
|
|
22
|
+
const { toolLabel } = useKviewerI18n();
|
|
20
23
|
defineProps({
|
|
21
24
|
tool: { type: null, required: true },
|
|
22
25
|
active: { type: Boolean, required: true },
|
|
@@ -2,6 +2,9 @@ import { type ViewMode } from '../composables/useViewerState.js';
|
|
|
2
2
|
import type { AddFormFieldPayload, FormFieldDefinition, IAnnotationStore, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
3
3
|
import { type ExportPdfOptions } from '../annotation/pdf-export/export.js';
|
|
4
4
|
import type { ViewerMenuItem } from '../menu-items.js';
|
|
5
|
+
import type { ViewerToolEntry } from '../toolbar-tools.js';
|
|
6
|
+
import { type KviewerMessageOverrides } from '../composables/useKviewerI18n.js';
|
|
7
|
+
import { type KviewerLocale } from '../i18n/messages.js';
|
|
5
8
|
type __VLS_Props = {
|
|
6
9
|
source: string | Uint8Array | object;
|
|
7
10
|
textLayer?: boolean;
|
|
@@ -45,6 +48,19 @@ type __VLS_Props = {
|
|
|
45
48
|
* toggles or actions without replacing the entire header. Ignored
|
|
46
49
|
* when the host supplies a custom `#header` slot. */
|
|
47
50
|
menuItems?: ViewerMenuItem[];
|
|
51
|
+
/** Configures which toolbar tools render and in what order. Entries are
|
|
52
|
+
* built-in tool IDs (strings) or `{ type: 'slot', ... }` objects that
|
|
53
|
+
* inject a custom button via a `#tool-<name>` slot. When omitted, the
|
|
54
|
+
* default toolbar is rendered unchanged. Ignored when the host supplies
|
|
55
|
+
* a custom `#header` slot. See {@link ViewerToolEntry}. */
|
|
56
|
+
tools?: ViewerToolEntry[];
|
|
57
|
+
/** UI language for built-in viewer strings (toolbar, search, modals,
|
|
58
|
+
* form sidebar). Defaults to the `kviewer.locale` module option, then
|
|
59
|
+
* 'en'. Hosts with their own i18n just bind their active locale. */
|
|
60
|
+
locale?: KviewerLocale;
|
|
61
|
+
/** Per-string overrides for built-in messages — wins over the locale
|
|
62
|
+
* catalog. Useful for app-specific wording without forking locales. */
|
|
63
|
+
messages?: KviewerMessageOverrides;
|
|
48
64
|
};
|
|
49
65
|
declare function exportPdf(options?: ExportPdfOptions): Promise<Uint8Array>;
|
|
50
66
|
type ImportMode = 'replace' | 'merge';
|
|
@@ -55,11 +71,15 @@ declare function importAnnotations(annotations: IAnnotationStore[], options?: {
|
|
|
55
71
|
skipped: number;
|
|
56
72
|
}>;
|
|
57
73
|
declare function getKonvaCanvasState(): Record<number, string>;
|
|
58
|
-
declare var __VLS_1: {},
|
|
74
|
+
declare var __VLS_1: {}, __VLS_11: string, __VLS_12: {
|
|
75
|
+
state: import("../composables/useViewerState.js").ViewerState;
|
|
76
|
+
}, __VLS_62: {};
|
|
59
77
|
type __VLS_Slots = {} & {
|
|
78
|
+
[K in NonNullable<typeof __VLS_11>]?: (props: typeof __VLS_12) => any;
|
|
79
|
+
} & {
|
|
60
80
|
header?: (props: typeof __VLS_1) => any;
|
|
61
81
|
} & {
|
|
62
|
-
footer?: (props: typeof
|
|
82
|
+
footer?: (props: typeof __VLS_62) => any;
|
|
63
83
|
};
|
|
64
84
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
65
85
|
getAnnotations: () => IAnnotationStore[];
|
|
@@ -109,6 +129,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
109
129
|
readonly: boolean;
|
|
110
130
|
active: boolean;
|
|
111
131
|
menuItems: ViewerMenuItem[];
|
|
132
|
+
tools: ViewerToolEntry[];
|
|
112
133
|
scripting: boolean;
|
|
113
134
|
stamps: StampDefinition[];
|
|
114
135
|
signatureHandlers: SignatureHandlers;
|
|
@@ -117,6 +138,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
117
138
|
formEditMode: boolean;
|
|
118
139
|
roleColors: Record<string, string>;
|
|
119
140
|
activeRoleId: string | null;
|
|
141
|
+
locale: KviewerLocale;
|
|
142
|
+
messages: KviewerMessageOverrides;
|
|
120
143
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
121
144
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
122
145
|
declare const _default: typeof __VLS_export;
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
<div ref="viewerRoot" class="flex flex-col h-full">
|
|
3
3
|
<!-- Header slot: defaults to ViewerBar -->
|
|
4
4
|
<slot name="header">
|
|
5
|
-
<ViewerBar :menu-items="props.menuItems"
|
|
5
|
+
<ViewerBar :menu-items="props.menuItems" :tools="props.tools">
|
|
6
|
+
<template v-for="name in toolSlotNames" :key="name" #[name]="scope">
|
|
7
|
+
<slot :name="name" v-bind="scope" />
|
|
8
|
+
</template>
|
|
9
|
+
</ViewerBar>
|
|
6
10
|
</slot>
|
|
7
11
|
|
|
8
12
|
<div class="flex flex-1 min-h-0">
|
|
@@ -61,6 +65,7 @@
|
|
|
61
65
|
:page-number="singlePageMeta.pageNumber"
|
|
62
66
|
:page-meta="singlePageMeta"
|
|
63
67
|
:scale="pageScale"
|
|
68
|
+
:view-window="pageViewWindow(singlePageMeta.pageNumber)"
|
|
64
69
|
/>
|
|
65
70
|
</div>
|
|
66
71
|
</div>
|
|
@@ -89,6 +94,7 @@
|
|
|
89
94
|
:page-number="meta.pageNumber"
|
|
90
95
|
:page-meta="meta"
|
|
91
96
|
:scale="pageScale"
|
|
97
|
+
:view-window="pageViewWindow(meta.pageNumber)"
|
|
92
98
|
/>
|
|
93
99
|
</div>
|
|
94
100
|
</div>
|
|
@@ -122,6 +128,7 @@
|
|
|
122
128
|
:page-number="meta.pageNumber"
|
|
123
129
|
:page-meta="meta"
|
|
124
130
|
:scale="pageScale"
|
|
131
|
+
:view-window="pageViewWindow(meta.pageNumber)"
|
|
125
132
|
/>
|
|
126
133
|
</div>
|
|
127
134
|
</div>
|
|
@@ -133,6 +140,10 @@
|
|
|
133
140
|
|
|
134
141
|
<ClientOnly>
|
|
135
142
|
<FloatingPageIndicator :scroll-container="scrollContainer" />
|
|
143
|
+
<!-- Debug overlay for on-device profiling; renders only with
|
|
144
|
+
?perf in the URL. Gated on `active` so tabbed hosts show a
|
|
145
|
+
single instance. -->
|
|
146
|
+
<PerfHud v-if="props.active" />
|
|
136
147
|
</ClientOnly>
|
|
137
148
|
</div>
|
|
138
149
|
|
|
@@ -181,14 +192,17 @@ import {
|
|
|
181
192
|
nextTick,
|
|
182
193
|
triggerRef,
|
|
183
194
|
onMounted,
|
|
184
|
-
onBeforeUnmount
|
|
195
|
+
onBeforeUnmount,
|
|
196
|
+
useSlots
|
|
185
197
|
} from "vue";
|
|
198
|
+
import { useRuntimeConfig } from "#imports";
|
|
186
199
|
import ViewerBar from "./ViewerBar.vue";
|
|
187
200
|
import PdfPage from "./PdfPage.vue";
|
|
188
201
|
import FreeTextModal from "./modals/FreeTextModal.vue";
|
|
189
202
|
import PlacedFieldSidebar from "./panels/PlacedFieldSidebar.vue";
|
|
190
203
|
import AnnotationToolbar from "./AnnotationToolbar.vue";
|
|
191
204
|
import FloatingPageIndicator from "./FloatingPageIndicator.vue";
|
|
205
|
+
import PerfHud from "./PerfHud.vue";
|
|
192
206
|
import { providePageSettings } from "../composables/usePageSettings";
|
|
193
207
|
import { mapViewModeToFitMode, normalizeZoom, provideViewerState } from "../composables/useViewerState";
|
|
194
208
|
import { provideViewerSearch } from "../composables/useViewerSearch";
|
|
@@ -206,11 +220,13 @@ import { createPageProxyCache } from "../composables/usePageProxyCache";
|
|
|
206
220
|
import { createSearchIndex } from "../composables/useSearchIndex";
|
|
207
221
|
import { createShapeDetection } from "../composables/useShapeDetection";
|
|
208
222
|
import { provideFormFields } from "../composables/useFormFields";
|
|
209
|
-
import { extractCheckboxStyles, extractButtonCaptions } from "../annotation/parsers/extractCheckboxStyles";
|
|
223
|
+
import { extractCheckboxStyles, extractButtonCaptions, extractSignedSignatureNames } from "../annotation/parsers/extractCheckboxStyles";
|
|
210
224
|
import { isIPad } from "../annotation/engine/input-device";
|
|
211
225
|
import { useInertiaPanzoom } from "../composables/useInertiaPanzoom";
|
|
212
226
|
import { createScriptingManager } from "../composables/useScriptingManager";
|
|
213
227
|
import { createScriptingBridge } from "../composables/useScriptingBridge";
|
|
228
|
+
import { provideKviewerI18n } from "../composables/useKviewerI18n";
|
|
229
|
+
import { KVIEWER_LOCALES } from "../i18n/messages";
|
|
214
230
|
const props = defineProps({
|
|
215
231
|
source: { type: null, required: true },
|
|
216
232
|
textLayer: { type: Boolean, required: false },
|
|
@@ -227,12 +243,19 @@ const props = defineProps({
|
|
|
227
243
|
roleColors: { type: Object, required: false, default: void 0 },
|
|
228
244
|
activeRoleId: { type: [String, null], required: false, default: void 0 },
|
|
229
245
|
scripting: { type: Boolean, required: false, default: false },
|
|
230
|
-
menuItems: { type: Array, required: false, default: void 0 }
|
|
246
|
+
menuItems: { type: Array, required: false, default: void 0 },
|
|
247
|
+
tools: { type: Array, required: false, default: void 0 },
|
|
248
|
+
locale: { type: null, required: false, default: void 0 },
|
|
249
|
+
messages: { type: Object, required: false, default: void 0 }
|
|
231
250
|
});
|
|
251
|
+
const slots = useSlots();
|
|
252
|
+
const toolSlotNames = computed(
|
|
253
|
+
() => Object.keys(slots).filter((name) => name.startsWith("tool-"))
|
|
254
|
+
);
|
|
232
255
|
const emit = defineEmits(["update:formEditMode", "update:activeRoleId", "update:viewedPages", "all-pages-read"]);
|
|
233
256
|
const viewerRoot = ref(null);
|
|
234
257
|
const scrollContainer = ref(null);
|
|
235
|
-
const { state: viewerState, setScrollToPageFn, setDownloadPdfFn } = provideViewerState();
|
|
258
|
+
const { state: viewerState, setScrollToPageFn, setDownloadPdfFn, setApplyScaleFn } = provideViewerState();
|
|
236
259
|
watchEffect(() => {
|
|
237
260
|
viewerState.readonly.value = props.readonly ?? false;
|
|
238
261
|
});
|
|
@@ -255,6 +278,14 @@ watch(
|
|
|
255
278
|
);
|
|
256
279
|
const viewerSearch = provideViewerSearch();
|
|
257
280
|
const formFieldsState = provideFormFields();
|
|
281
|
+
const kviewerPublicConfig = useRuntimeConfig().public.kviewer;
|
|
282
|
+
provideKviewerI18n(
|
|
283
|
+
computed(() => {
|
|
284
|
+
const candidate = props.locale ?? kviewerPublicConfig?.locale ?? "en";
|
|
285
|
+
return KVIEWER_LOCALES.includes(candidate) ? candidate : "en";
|
|
286
|
+
}),
|
|
287
|
+
computed(() => props.messages ?? {})
|
|
288
|
+
);
|
|
258
289
|
watch(
|
|
259
290
|
() => props.roleColors,
|
|
260
291
|
(v) => {
|
|
@@ -295,6 +326,7 @@ const proxyCache = createPageProxyCache();
|
|
|
295
326
|
const searchIndex = createSearchIndex();
|
|
296
327
|
const shapeDetectionCache = createShapeDetection();
|
|
297
328
|
const doc = shallowRef(null);
|
|
329
|
+
let destroyActiveDoc = null;
|
|
298
330
|
let painter = null;
|
|
299
331
|
let scriptingManager = null;
|
|
300
332
|
let scriptingBridge = null;
|
|
@@ -353,6 +385,116 @@ const isRotatedSideways = computed(() => {
|
|
|
353
385
|
});
|
|
354
386
|
const zoomWrapper = ref(null);
|
|
355
387
|
const inertiaPanzoom = useInertiaPanzoom({ minScale: 0.5, maxScale: 4 });
|
|
388
|
+
const MIN_ZOOM = 0.25;
|
|
389
|
+
const MAX_ZOOM = 4;
|
|
390
|
+
let suppressScaleReset = false;
|
|
391
|
+
async function commitZoom(target) {
|
|
392
|
+
const s0 = viewerState.scale.value;
|
|
393
|
+
target = Math.min(Math.max(MAX_ZOOM, s0), Math.max(Math.min(MIN_ZOOM, s0), target));
|
|
394
|
+
const viewportEl = zoomWrapper.value?.parentElement ?? null;
|
|
395
|
+
const anchor = virtualization.getPageElement(viewerState.currentPage.value);
|
|
396
|
+
const visual = inertiaPanzoom.getScale();
|
|
397
|
+
if (target === viewerState.scale.value && Math.abs(visual - 1) < 5e-3) return;
|
|
398
|
+
if (!viewportEl || !anchor || !anchor.isConnected) {
|
|
399
|
+
viewerState.fitMode.value = "custom";
|
|
400
|
+
viewerState.scale.value = target;
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
const vpRect = viewportEl.getBoundingClientRect();
|
|
404
|
+
const fx = vpRect.width / 2;
|
|
405
|
+
const fy = vpRect.height / 2;
|
|
406
|
+
const aRect = anchor.getBoundingClientRect();
|
|
407
|
+
const qx = (vpRect.left + fx - aRect.left) / aRect.width;
|
|
408
|
+
const qy = (vpRect.top + fy - aRect.top) / aRect.height;
|
|
409
|
+
suppressScaleReset = target !== viewerState.scale.value;
|
|
410
|
+
viewerState.fitMode.value = "custom";
|
|
411
|
+
viewerState.scale.value = target;
|
|
412
|
+
await nextTick();
|
|
413
|
+
const t = inertiaPanzoom.getTransform();
|
|
414
|
+
const vp2 = viewportEl.getBoundingClientRect();
|
|
415
|
+
const a2 = anchor.getBoundingClientRect();
|
|
416
|
+
const layoutLeft = (a2.left - vp2.left - t.tx) / t.scale;
|
|
417
|
+
const layoutTop = (a2.top - vp2.top - t.ty) / t.scale;
|
|
418
|
+
const layoutW = a2.width / t.scale;
|
|
419
|
+
const layoutH = a2.height / t.scale;
|
|
420
|
+
inertiaPanzoom.setTransform({
|
|
421
|
+
scale: 1,
|
|
422
|
+
tx: fx - (layoutLeft + qx * layoutW),
|
|
423
|
+
ty: fy - (layoutTop + qy * layoutH)
|
|
424
|
+
});
|
|
425
|
+
viewWindows.value = {};
|
|
426
|
+
computeViewWindows();
|
|
427
|
+
}
|
|
428
|
+
setApplyScaleFn((value) => {
|
|
429
|
+
void commitZoom(value);
|
|
430
|
+
});
|
|
431
|
+
watch(
|
|
432
|
+
() => viewerState.scale.value,
|
|
433
|
+
(s) => inertiaPanzoom.setScaleLimits(
|
|
434
|
+
Math.min(1, MIN_ZOOM / s),
|
|
435
|
+
Math.max(1, MAX_ZOOM / s)
|
|
436
|
+
),
|
|
437
|
+
{ immediate: true }
|
|
438
|
+
);
|
|
439
|
+
inertiaPanzoom.onZoomEnd((visual) => {
|
|
440
|
+
if (Math.abs(visual - 1) < 5e-3) return;
|
|
441
|
+
void commitZoom(viewerState.scale.value * visual);
|
|
442
|
+
});
|
|
443
|
+
const viewWindows = shallowRef({});
|
|
444
|
+
const VIEW_WINDOW_MARGIN = 0.25;
|
|
445
|
+
function computeViewWindows() {
|
|
446
|
+
const viewportEl = zoomWrapper.value?.parentElement;
|
|
447
|
+
if (!viewportEl) return;
|
|
448
|
+
const vpRect = viewportEl.getBoundingClientRect();
|
|
449
|
+
if (vpRect.width === 0 || vpRect.height === 0) return;
|
|
450
|
+
const prev = viewWindows.value;
|
|
451
|
+
const next = {};
|
|
452
|
+
let changed = false;
|
|
453
|
+
for (const meta of pageMetas.value) {
|
|
454
|
+
const el = virtualization.getPageElement(meta.pageNumber);
|
|
455
|
+
if (!el) continue;
|
|
456
|
+
const r = el.getBoundingClientRect();
|
|
457
|
+
if (r.width === 0 || el.offsetWidth === 0) continue;
|
|
458
|
+
const k = r.width / el.offsetWidth;
|
|
459
|
+
const vx = (Math.max(vpRect.left, r.left) - r.left) / k;
|
|
460
|
+
const vy = (Math.max(vpRect.top, r.top) - r.top) / k;
|
|
461
|
+
const vr = (Math.min(vpRect.right, r.right) - r.left) / k;
|
|
462
|
+
const vb = (Math.min(vpRect.bottom, r.bottom) - r.top) / k;
|
|
463
|
+
if (vr <= vx || vb <= vy) continue;
|
|
464
|
+
const old = prev[meta.pageNumber];
|
|
465
|
+
if (old && vx >= old.x && vy >= old.y && vr <= old.x + old.width && vb <= old.y + old.height) {
|
|
466
|
+
next[meta.pageNumber] = old;
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
const mx = vpRect.width / k * VIEW_WINDOW_MARGIN;
|
|
470
|
+
const my = vpRect.height / k * VIEW_WINDOW_MARGIN;
|
|
471
|
+
next[meta.pageNumber] = {
|
|
472
|
+
x: vx - mx,
|
|
473
|
+
y: vy - my,
|
|
474
|
+
width: vr - vx + 2 * mx,
|
|
475
|
+
height: vb - vy + 2 * my
|
|
476
|
+
};
|
|
477
|
+
changed = true;
|
|
478
|
+
}
|
|
479
|
+
if (changed || Object.keys(next).length !== Object.keys(prev).length) {
|
|
480
|
+
viewWindows.value = next;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
let viewWindowTimer = 0;
|
|
484
|
+
let lastViewWindowUpdate = 0;
|
|
485
|
+
inertiaPanzoom.onChange(() => {
|
|
486
|
+
const now = performance.now();
|
|
487
|
+
const wait = Math.max(0, 250 - (now - lastViewWindowUpdate));
|
|
488
|
+
clearTimeout(viewWindowTimer);
|
|
489
|
+
viewWindowTimer = window.setTimeout(() => {
|
|
490
|
+
lastViewWindowUpdate = performance.now();
|
|
491
|
+
computeViewWindows();
|
|
492
|
+
}, wait);
|
|
493
|
+
});
|
|
494
|
+
function pageViewWindow(pageNumber) {
|
|
495
|
+
if (pageSettings.rotation.value !== 0) return null;
|
|
496
|
+
return viewWindows.value[pageNumber] ?? null;
|
|
497
|
+
}
|
|
356
498
|
function pageSlotStyle(meta) {
|
|
357
499
|
const s = pageScale.value;
|
|
358
500
|
if (isRotatedSideways.value) {
|
|
@@ -449,26 +591,36 @@ async function loadDocument() {
|
|
|
449
591
|
}
|
|
450
592
|
const source = props.source;
|
|
451
593
|
const baseParams = source instanceof Uint8Array || typeof source === "string" ? { url: typeof source === "string" ? source : void 0, data: source instanceof Uint8Array ? source : void 0 } : { ...source };
|
|
594
|
+
if (baseParams.data instanceof Uint8Array) {
|
|
595
|
+
baseParams.data = baseParams.data.slice();
|
|
596
|
+
} else if (baseParams.data instanceof ArrayBuffer) {
|
|
597
|
+
baseParams.data = baseParams.data.slice(0);
|
|
598
|
+
}
|
|
452
599
|
const docParams = {
|
|
453
600
|
...baseParams,
|
|
454
601
|
standardFontDataUrl: "/_kviewer/standard_fonts/",
|
|
455
602
|
cMapUrl: "/_kviewer/cmaps/",
|
|
456
603
|
cMapPacked: true,
|
|
457
|
-
useSystemFonts: true
|
|
604
|
+
useSystemFonts: true,
|
|
605
|
+
wasmUrl: "/_kviewer/wasm/",
|
|
606
|
+
iccUrl: "/_kviewer/iccs/"
|
|
458
607
|
};
|
|
459
608
|
const loadingTask = pdfjs.getDocument(docParams);
|
|
609
|
+
destroyActiveDoc = () => loadingTask.destroy();
|
|
460
610
|
const pdfDoc = await loadingTask.promise;
|
|
461
611
|
doc.value = pdfDoc;
|
|
462
612
|
viewerState.doc.value = pdfDoc;
|
|
463
613
|
viewerState.totalPages.value = pdfDoc.numPages;
|
|
464
614
|
proxyCache.setDocument(pdfDoc);
|
|
465
615
|
pdfDoc.getData().then(async (bytes) => {
|
|
466
|
-
const [styles, captions] = await Promise.all([
|
|
616
|
+
const [styles, captions, signedSigs] = await Promise.all([
|
|
467
617
|
extractCheckboxStyles(bytes),
|
|
468
|
-
extractButtonCaptions(bytes)
|
|
618
|
+
extractButtonCaptions(bytes),
|
|
619
|
+
extractSignedSignatureNames(bytes)
|
|
469
620
|
]);
|
|
470
621
|
if (styles.size > 0) formFieldsState.applyCheckboxStyles(styles);
|
|
471
622
|
if (captions.size > 0) formFieldsState.applyButtonCaptions(captions);
|
|
623
|
+
if (signedSigs.size > 0) formFieldsState.applySignedSignatures(signedSigs);
|
|
472
624
|
}).catch((err) => console.warn("[KViewer] Failed to read MK data from source PDF:", err));
|
|
473
625
|
if (!scrollContainer.value) {
|
|
474
626
|
await nextTick();
|
|
@@ -819,10 +971,18 @@ onMounted(() => {
|
|
|
819
971
|
{ immediate: true }
|
|
820
972
|
);
|
|
821
973
|
watch(() => viewerState.scale.value, async () => {
|
|
974
|
+
if (suppressScaleReset) {
|
|
975
|
+
suppressScaleReset = false;
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
822
978
|
await nextTick();
|
|
823
979
|
inertiaPanzoom.reset();
|
|
980
|
+
viewWindows.value = {};
|
|
981
|
+
computeViewWindows();
|
|
982
|
+
});
|
|
983
|
+
watch(() => viewerState.currentPage.value, () => {
|
|
984
|
+
if (isSinglePageMode.value) inertiaPanzoom.reset();
|
|
824
985
|
});
|
|
825
|
-
watch(() => viewerState.currentPage.value, () => inertiaPanzoom.reset());
|
|
826
986
|
}
|
|
827
987
|
if (isIPad()) {
|
|
828
988
|
viewerState.setStylusMode(true);
|
|
@@ -843,7 +1003,7 @@ watch(
|
|
|
843
1003
|
searchIndex.destroy();
|
|
844
1004
|
virtualization.destroy();
|
|
845
1005
|
proxyCache.clear();
|
|
846
|
-
|
|
1006
|
+
void destroyActiveDoc?.();
|
|
847
1007
|
loadDocument();
|
|
848
1008
|
}
|
|
849
1009
|
);
|
|
@@ -875,6 +1035,7 @@ watch(
|
|
|
875
1035
|
);
|
|
876
1036
|
onBeforeUnmount(() => {
|
|
877
1037
|
window.removeEventListener("keydown", onGlobalKeydown);
|
|
1038
|
+
clearTimeout(viewWindowTimer);
|
|
878
1039
|
scrollContainer.value?.removeEventListener("wheel", onWheel);
|
|
879
1040
|
inertiaPanzoom.detach();
|
|
880
1041
|
resizeObserver?.disconnect();
|
|
@@ -889,7 +1050,8 @@ onBeforeUnmount(() => {
|
|
|
889
1050
|
virtualization.destroy();
|
|
890
1051
|
proxyCache.clear();
|
|
891
1052
|
painter?.destroy();
|
|
892
|
-
|
|
1053
|
+
void destroyActiveDoc?.();
|
|
1054
|
+
destroyActiveDoc = null;
|
|
893
1055
|
});
|
|
894
1056
|
defineExpose({
|
|
895
1057
|
getAnnotations: () => painter?.getData() ?? [],
|
|
@@ -2,6 +2,9 @@ import { type ViewMode } from '../composables/useViewerState.js';
|
|
|
2
2
|
import type { AddFormFieldPayload, FormFieldDefinition, IAnnotationStore, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
3
3
|
import { type ExportPdfOptions } from '../annotation/pdf-export/export.js';
|
|
4
4
|
import type { ViewerMenuItem } from '../menu-items.js';
|
|
5
|
+
import type { ViewerToolEntry } from '../toolbar-tools.js';
|
|
6
|
+
import { type KviewerMessageOverrides } from '../composables/useKviewerI18n.js';
|
|
7
|
+
import { type KviewerLocale } from '../i18n/messages.js';
|
|
5
8
|
type __VLS_Props = {
|
|
6
9
|
source: string | Uint8Array | object;
|
|
7
10
|
textLayer?: boolean;
|
|
@@ -45,6 +48,19 @@ type __VLS_Props = {
|
|
|
45
48
|
* toggles or actions without replacing the entire header. Ignored
|
|
46
49
|
* when the host supplies a custom `#header` slot. */
|
|
47
50
|
menuItems?: ViewerMenuItem[];
|
|
51
|
+
/** Configures which toolbar tools render and in what order. Entries are
|
|
52
|
+
* built-in tool IDs (strings) or `{ type: 'slot', ... }` objects that
|
|
53
|
+
* inject a custom button via a `#tool-<name>` slot. When omitted, the
|
|
54
|
+
* default toolbar is rendered unchanged. Ignored when the host supplies
|
|
55
|
+
* a custom `#header` slot. See {@link ViewerToolEntry}. */
|
|
56
|
+
tools?: ViewerToolEntry[];
|
|
57
|
+
/** UI language for built-in viewer strings (toolbar, search, modals,
|
|
58
|
+
* form sidebar). Defaults to the `kviewer.locale` module option, then
|
|
59
|
+
* 'en'. Hosts with their own i18n just bind their active locale. */
|
|
60
|
+
locale?: KviewerLocale;
|
|
61
|
+
/** Per-string overrides for built-in messages — wins over the locale
|
|
62
|
+
* catalog. Useful for app-specific wording without forking locales. */
|
|
63
|
+
messages?: KviewerMessageOverrides;
|
|
48
64
|
};
|
|
49
65
|
declare function exportPdf(options?: ExportPdfOptions): Promise<Uint8Array>;
|
|
50
66
|
type ImportMode = 'replace' | 'merge';
|
|
@@ -55,11 +71,15 @@ declare function importAnnotations(annotations: IAnnotationStore[], options?: {
|
|
|
55
71
|
skipped: number;
|
|
56
72
|
}>;
|
|
57
73
|
declare function getKonvaCanvasState(): Record<number, string>;
|
|
58
|
-
declare var __VLS_1: {},
|
|
74
|
+
declare var __VLS_1: {}, __VLS_11: string, __VLS_12: {
|
|
75
|
+
state: import("../composables/useViewerState.js").ViewerState;
|
|
76
|
+
}, __VLS_62: {};
|
|
59
77
|
type __VLS_Slots = {} & {
|
|
78
|
+
[K in NonNullable<typeof __VLS_11>]?: (props: typeof __VLS_12) => any;
|
|
79
|
+
} & {
|
|
60
80
|
header?: (props: typeof __VLS_1) => any;
|
|
61
81
|
} & {
|
|
62
|
-
footer?: (props: typeof
|
|
82
|
+
footer?: (props: typeof __VLS_62) => any;
|
|
63
83
|
};
|
|
64
84
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
65
85
|
getAnnotations: () => IAnnotationStore[];
|
|
@@ -109,6 +129,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
109
129
|
readonly: boolean;
|
|
110
130
|
active: boolean;
|
|
111
131
|
menuItems: ViewerMenuItem[];
|
|
132
|
+
tools: ViewerToolEntry[];
|
|
112
133
|
scripting: boolean;
|
|
113
134
|
stamps: StampDefinition[];
|
|
114
135
|
signatureHandlers: SignatureHandlers;
|
|
@@ -117,6 +138,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
117
138
|
formEditMode: boolean;
|
|
118
139
|
roleColors: Record<string, string>;
|
|
119
140
|
activeRoleId: string | null;
|
|
141
|
+
locale: KviewerLocale;
|
|
142
|
+
messages: KviewerMessageOverrides;
|
|
120
143
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
121
144
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
122
145
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
import type { ViewerMenuItem } from '../menu-items.js';
|
|
2
|
+
import { type ViewerToolEntry } from '../toolbar-tools.js';
|
|
2
3
|
type __VLS_Props = {
|
|
3
4
|
/** Extra items appended to the burger menu after the built-ins.
|
|
4
5
|
* See {@link ViewerMenuItem}. Pure forwarding from `<KViewer>`. */
|
|
5
6
|
menuItems?: ViewerMenuItem[];
|
|
7
|
+
/** Configures which toolbar tools render and in what order. When
|
|
8
|
+
* omitted, the default toolbar is rendered. See {@link ViewerToolEntry}. */
|
|
9
|
+
tools?: ViewerToolEntry[];
|
|
6
10
|
};
|
|
7
|
-
declare
|
|
11
|
+
declare var __VLS_109: string, __VLS_110: {
|
|
12
|
+
state: import("../composables/useViewerState.js").ViewerState;
|
|
13
|
+
}, __VLS_154: string, __VLS_155: {
|
|
14
|
+
state: import("../composables/useViewerState.js").ViewerState;
|
|
15
|
+
};
|
|
16
|
+
type __VLS_Slots = {} & {
|
|
17
|
+
[K in NonNullable<typeof __VLS_109>]?: (props: typeof __VLS_110) => any;
|
|
18
|
+
} & {
|
|
19
|
+
[K in NonNullable<typeof __VLS_154>]?: (props: typeof __VLS_155) => any;
|
|
20
|
+
};
|
|
21
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
8
23
|
declare const _default: typeof __VLS_export;
|
|
9
24
|
export default _default;
|
|
25
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
26
|
+
new (): {
|
|
27
|
+
$slots: S;
|
|
28
|
+
};
|
|
29
|
+
};
|