kviewer 0.0.1

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 (197) hide show
  1. package/README.md +134 -0
  2. package/dist/module.d.mts +15 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +26 -0
  5. package/dist/runtime/annotation/engine/config.d.ts +52 -0
  6. package/dist/runtime/annotation/engine/config.js +283 -0
  7. package/dist/runtime/annotation/engine/const.d.ts +6 -0
  8. package/dist/runtime/annotation/engine/const.js +7 -0
  9. package/dist/runtime/annotation/engine/cursor-preview.d.ts +2 -0
  10. package/dist/runtime/annotation/engine/cursor-preview.js +88 -0
  11. package/dist/runtime/annotation/engine/editor/editor.d.ts +69 -0
  12. package/dist/runtime/annotation/engine/editor/editor.js +233 -0
  13. package/dist/runtime/annotation/engine/editor/selector.d.ts +74 -0
  14. package/dist/runtime/annotation/engine/editor/selector.js +594 -0
  15. package/dist/runtime/annotation/engine/import-normalize.d.ts +5 -0
  16. package/dist/runtime/annotation/engine/import-normalize.js +99 -0
  17. package/dist/runtime/annotation/engine/input-device.d.ts +53 -0
  18. package/dist/runtime/annotation/engine/input-device.js +64 -0
  19. package/dist/runtime/annotation/engine/painter.d.ts +97 -0
  20. package/dist/runtime/annotation/engine/painter.js +591 -0
  21. package/dist/runtime/annotation/engine/store.d.ts +11 -0
  22. package/dist/runtime/annotation/engine/store.js +47 -0
  23. package/dist/runtime/annotation/engine/tools/arrow.d.ts +22 -0
  24. package/dist/runtime/annotation/engine/tools/arrow.js +126 -0
  25. package/dist/runtime/annotation/engine/tools/circle.d.ts +45 -0
  26. package/dist/runtime/annotation/engine/tools/circle.js +148 -0
  27. package/dist/runtime/annotation/engine/tools/cloud.d.ts +50 -0
  28. package/dist/runtime/annotation/engine/tools/cloud.js +244 -0
  29. package/dist/runtime/annotation/engine/tools/free-highlight.d.ts +43 -0
  30. package/dist/runtime/annotation/engine/tools/free-highlight.js +165 -0
  31. package/dist/runtime/annotation/engine/tools/free-text.d.ts +27 -0
  32. package/dist/runtime/annotation/engine/tools/free-text.js +114 -0
  33. package/dist/runtime/annotation/engine/tools/freehand.d.ts +44 -0
  34. package/dist/runtime/annotation/engine/tools/freehand.js +151 -0
  35. package/dist/runtime/annotation/engine/tools/highlight.d.ts +87 -0
  36. package/dist/runtime/annotation/engine/tools/highlight.js +215 -0
  37. package/dist/runtime/annotation/engine/tools/note.d.ts +9 -0
  38. package/dist/runtime/annotation/engine/tools/note.js +34 -0
  39. package/dist/runtime/annotation/engine/tools/rectangle.d.ts +45 -0
  40. package/dist/runtime/annotation/engine/tools/rectangle.js +142 -0
  41. package/dist/runtime/annotation/engine/tools/signature.d.ts +16 -0
  42. package/dist/runtime/annotation/engine/tools/signature.js +74 -0
  43. package/dist/runtime/annotation/engine/tools/stamp.d.ts +18 -0
  44. package/dist/runtime/annotation/engine/tools/stamp.js +94 -0
  45. package/dist/runtime/annotation/engine/types.d.ts +170 -0
  46. package/dist/runtime/annotation/engine/types.js +67 -0
  47. package/dist/runtime/annotation/engine/utils.d.ts +40 -0
  48. package/dist/runtime/annotation/engine/utils.js +257 -0
  49. package/dist/runtime/annotation/parsers/parseFormFields.d.ts +9 -0
  50. package/dist/runtime/annotation/parsers/parseFormFields.js +101 -0
  51. package/dist/runtime/annotation/pdf-export/download.d.ts +1 -0
  52. package/dist/runtime/annotation/pdf-export/download.js +10 -0
  53. package/dist/runtime/annotation/pdf-export/export-form-fields.d.ts +9 -0
  54. package/dist/runtime/annotation/pdf-export/export-form-fields.js +90 -0
  55. package/dist/runtime/annotation/pdf-export/export.d.ts +15 -0
  56. package/dist/runtime/annotation/pdf-export/export.js +145 -0
  57. package/dist/runtime/annotation/pdf-export/parse.d.ts +10 -0
  58. package/dist/runtime/annotation/pdf-export/parse.js +19 -0
  59. package/dist/runtime/annotation/pdf-export/parse_circle.d.ts +4 -0
  60. package/dist/runtime/annotation/pdf-export/parse_circle.js +41 -0
  61. package/dist/runtime/annotation/pdf-export/parse_freetext.d.ts +4 -0
  62. package/dist/runtime/annotation/pdf-export/parse_freetext.js +54 -0
  63. package/dist/runtime/annotation/pdf-export/parse_highlight.d.ts +4 -0
  64. package/dist/runtime/annotation/pdf-export/parse_highlight.js +134 -0
  65. package/dist/runtime/annotation/pdf-export/parse_ink.d.ts +4 -0
  66. package/dist/runtime/annotation/pdf-export/parse_ink.js +124 -0
  67. package/dist/runtime/annotation/pdf-export/parse_line.d.ts +4 -0
  68. package/dist/runtime/annotation/pdf-export/parse_line.js +71 -0
  69. package/dist/runtime/annotation/pdf-export/parse_polyline.d.ts +4 -0
  70. package/dist/runtime/annotation/pdf-export/parse_polyline.js +93 -0
  71. package/dist/runtime/annotation/pdf-export/parse_square.d.ts +4 -0
  72. package/dist/runtime/annotation/pdf-export/parse_square.js +41 -0
  73. package/dist/runtime/annotation/pdf-export/parse_stamp.d.ts +4 -0
  74. package/dist/runtime/annotation/pdf-export/parse_stamp.js +195 -0
  75. package/dist/runtime/annotation/pdf-export/parse_strikeout.d.ts +4 -0
  76. package/dist/runtime/annotation/pdf-export/parse_strikeout.js +59 -0
  77. package/dist/runtime/annotation/pdf-export/parse_text.d.ts +4 -0
  78. package/dist/runtime/annotation/pdf-export/parse_text.js +42 -0
  79. package/dist/runtime/annotation/pdf-export/parse_underline.d.ts +4 -0
  80. package/dist/runtime/annotation/pdf-export/parse_underline.js +59 -0
  81. package/dist/runtime/assets/kviewer.css +1 -0
  82. package/dist/runtime/components/AnnotationToolbar.d.vue.ts +3 -0
  83. package/dist/runtime/components/AnnotationToolbar.vue +125 -0
  84. package/dist/runtime/components/AnnotationToolbar.vue.d.ts +3 -0
  85. package/dist/runtime/components/FloatingPageIndicator.d.vue.ts +6 -0
  86. package/dist/runtime/components/FloatingPageIndicator.vue +93 -0
  87. package/dist/runtime/components/FloatingPageIndicator.vue.d.ts +6 -0
  88. package/dist/runtime/components/FormFieldLayer.d.vue.ts +11 -0
  89. package/dist/runtime/components/FormFieldLayer.vue +40 -0
  90. package/dist/runtime/components/FormFieldLayer.vue.d.ts +11 -0
  91. package/dist/runtime/components/PdfPage.d.vue.ts +9 -0
  92. package/dist/runtime/components/PdfPage.vue +199 -0
  93. package/dist/runtime/components/PdfPage.vue.d.ts +9 -0
  94. package/dist/runtime/components/ToolButton.d.vue.ts +13 -0
  95. package/dist/runtime/components/ToolButton.vue +26 -0
  96. package/dist/runtime/components/ToolButton.vue.d.ts +13 -0
  97. package/dist/runtime/components/Toolbar.d.vue.ts +3 -0
  98. package/dist/runtime/components/Toolbar.vue +11 -0
  99. package/dist/runtime/components/Toolbar.vue.d.ts +3 -0
  100. package/dist/runtime/components/Viewer.d.vue.ts +45 -0
  101. package/dist/runtime/components/Viewer.vue +617 -0
  102. package/dist/runtime/components/Viewer.vue.d.ts +45 -0
  103. package/dist/runtime/components/ViewerBar.d.vue.ts +3 -0
  104. package/dist/runtime/components/ViewerBar.vue +91 -0
  105. package/dist/runtime/components/ViewerBar.vue.d.ts +3 -0
  106. package/dist/runtime/components/ViewerTabs.d.vue.ts +381 -0
  107. package/dist/runtime/components/ViewerTabs.vue +171 -0
  108. package/dist/runtime/components/ViewerTabs.vue.d.ts +381 -0
  109. package/dist/runtime/components/form-fields/FormButton.d.vue.ts +7 -0
  110. package/dist/runtime/components/form-fields/FormButton.vue +39 -0
  111. package/dist/runtime/components/form-fields/FormButton.vue.d.ts +7 -0
  112. package/dist/runtime/components/form-fields/FormCheckbox.d.vue.ts +7 -0
  113. package/dist/runtime/components/form-fields/FormCheckbox.vue +28 -0
  114. package/dist/runtime/components/form-fields/FormCheckbox.vue.d.ts +7 -0
  115. package/dist/runtime/components/form-fields/FormDropdown.d.vue.ts +7 -0
  116. package/dist/runtime/components/form-fields/FormDropdown.vue +112 -0
  117. package/dist/runtime/components/form-fields/FormDropdown.vue.d.ts +7 -0
  118. package/dist/runtime/components/form-fields/FormFieldWrapper.d.vue.ts +8 -0
  119. package/dist/runtime/components/form-fields/FormFieldWrapper.vue +41 -0
  120. package/dist/runtime/components/form-fields/FormFieldWrapper.vue.d.ts +8 -0
  121. package/dist/runtime/components/form-fields/FormRadioButton.d.vue.ts +7 -0
  122. package/dist/runtime/components/form-fields/FormRadioButton.vue +30 -0
  123. package/dist/runtime/components/form-fields/FormRadioButton.vue.d.ts +7 -0
  124. package/dist/runtime/components/form-fields/FormSignatureField.d.vue.ts +7 -0
  125. package/dist/runtime/components/form-fields/FormSignatureField.vue +54 -0
  126. package/dist/runtime/components/form-fields/FormSignatureField.vue.d.ts +7 -0
  127. package/dist/runtime/components/form-fields/FormTextField.d.vue.ts +7 -0
  128. package/dist/runtime/components/form-fields/FormTextField.vue +66 -0
  129. package/dist/runtime/components/form-fields/FormTextField.vue.d.ts +7 -0
  130. package/dist/runtime/components/modals/FreeTextModal.d.vue.ts +25 -0
  131. package/dist/runtime/components/modals/FreeTextModal.vue +89 -0
  132. package/dist/runtime/components/modals/FreeTextModal.vue.d.ts +25 -0
  133. package/dist/runtime/components/modals/SignatureDrawModal.d.vue.ts +14 -0
  134. package/dist/runtime/components/modals/SignatureDrawModal.vue +120 -0
  135. package/dist/runtime/components/modals/SignatureDrawModal.vue.d.ts +14 -0
  136. package/dist/runtime/components/panels/SignaturePicker.d.vue.ts +3 -0
  137. package/dist/runtime/components/panels/SignaturePicker.vue +85 -0
  138. package/dist/runtime/components/panels/SignaturePicker.vue.d.ts +3 -0
  139. package/dist/runtime/components/panels/StampPicker.d.vue.ts +3 -0
  140. package/dist/runtime/components/panels/StampPicker.vue +46 -0
  141. package/dist/runtime/components/panels/StampPicker.vue.d.ts +3 -0
  142. package/dist/runtime/components/tools/ActionTools.d.vue.ts +3 -0
  143. package/dist/runtime/components/tools/ActionTools.vue +32 -0
  144. package/dist/runtime/components/tools/ActionTools.vue.d.ts +3 -0
  145. package/dist/runtime/components/tools/DrawingTools.d.vue.ts +6 -0
  146. package/dist/runtime/components/tools/DrawingTools.vue +57 -0
  147. package/dist/runtime/components/tools/DrawingTools.vue.d.ts +6 -0
  148. package/dist/runtime/components/tools/HandTool.d.vue.ts +3 -0
  149. package/dist/runtime/components/tools/HandTool.vue +14 -0
  150. package/dist/runtime/components/tools/HandTool.vue.d.ts +3 -0
  151. package/dist/runtime/components/tools/MarqueeTool.d.vue.ts +3 -0
  152. package/dist/runtime/components/tools/MarqueeTool.vue +15 -0
  153. package/dist/runtime/components/tools/MarqueeTool.vue.d.ts +3 -0
  154. package/dist/runtime/components/tools/PageInfo.d.vue.ts +3 -0
  155. package/dist/runtime/components/tools/PageInfo.vue +10 -0
  156. package/dist/runtime/components/tools/PageInfo.vue.d.ts +3 -0
  157. package/dist/runtime/components/tools/PageSettings.d.vue.ts +3 -0
  158. package/dist/runtime/components/tools/PageSettings.vue +92 -0
  159. package/dist/runtime/components/tools/PageSettings.vue.d.ts +3 -0
  160. package/dist/runtime/components/tools/SearchTool.d.vue.ts +3 -0
  161. package/dist/runtime/components/tools/SearchTool.vue +149 -0
  162. package/dist/runtime/components/tools/SearchTool.vue.d.ts +3 -0
  163. package/dist/runtime/components/tools/ToolProperties.d.vue.ts +7 -0
  164. package/dist/runtime/components/tools/ToolProperties.vue +174 -0
  165. package/dist/runtime/components/tools/ToolProperties.vue.d.ts +7 -0
  166. package/dist/runtime/components/tools/ZoomControls.d.vue.ts +3 -0
  167. package/dist/runtime/components/tools/ZoomControls.vue +59 -0
  168. package/dist/runtime/components/tools/ZoomControls.vue.d.ts +3 -0
  169. package/dist/runtime/composables/search-utils.d.ts +20 -0
  170. package/dist/runtime/composables/search-utils.js +55 -0
  171. package/dist/runtime/composables/useAnnotationEngine.d.ts +7 -0
  172. package/dist/runtime/composables/useAnnotationEngine.js +70 -0
  173. package/dist/runtime/composables/useAnnotationHistory.d.ts +12 -0
  174. package/dist/runtime/composables/useAnnotationHistory.js +69 -0
  175. package/dist/runtime/composables/useFormFields.d.ts +26 -0
  176. package/dist/runtime/composables/useFormFields.js +112 -0
  177. package/dist/runtime/composables/usePageProxyCache.d.ts +8 -0
  178. package/dist/runtime/composables/usePageProxyCache.js +73 -0
  179. package/dist/runtime/composables/usePageSettings.d.ts +16 -0
  180. package/dist/runtime/composables/usePageSettings.js +66 -0
  181. package/dist/runtime/composables/usePageVirtualization.d.ts +19 -0
  182. package/dist/runtime/composables/usePageVirtualization.js +203 -0
  183. package/dist/runtime/composables/useSearchIndex.d.ts +11 -0
  184. package/dist/runtime/composables/useSearchIndex.js +71 -0
  185. package/dist/runtime/composables/useViewerSearch.d.ts +32 -0
  186. package/dist/runtime/composables/useViewerSearch.js +418 -0
  187. package/dist/runtime/composables/useViewerState.d.ts +62 -0
  188. package/dist/runtime/composables/useViewerState.js +189 -0
  189. package/dist/runtime/composables/viewMode.d.ts +11 -0
  190. package/dist/runtime/composables/viewMode.js +19 -0
  191. package/dist/runtime/plugin.d.ts +2 -0
  192. package/dist/runtime/plugin.js +3 -0
  193. package/dist/runtime/public-types.d.ts +2 -0
  194. package/dist/runtime/public-types.js +0 -0
  195. package/dist/runtime/server/tsconfig.json +3 -0
  196. package/dist/types.d.mts +5 -0
  197. package/package.json +64 -0
@@ -0,0 +1,125 @@
1
+ <template>
2
+ <div
3
+ v-if="hasSelection && state.selectionRect.value"
4
+ class="fixed z-50 pointer-events-auto"
5
+ :style="toolbarStyle"
6
+ >
7
+ <div class="flex items-center gap-0.5 bg-elevated rounded-lg shadow-lg border border-default p-1">
8
+ <!-- Color picker (single selection only) -->
9
+ <UPopover v-if="hasColorEdit && !isMultiSelect">
10
+ <button
11
+ class="flex items-center justify-center w-7 h-7 rounded-md hover:bg-default cursor-pointer"
12
+ title="Color"
13
+ >
14
+ <UIcon name="i-lucide-palette" class="text-sm text-muted" />
15
+ </button>
16
+ <template #content>
17
+ <div class="p-3">
18
+ <div class="grid grid-cols-5 gap-1.5">
19
+ <button
20
+ v-for="color in colors"
21
+ :key="color"
22
+ class="w-6 h-6 rounded-full border-2 cursor-pointer transition-transform hover:scale-110"
23
+ :class="color === currentColor ? 'border-white ring-2 ring-primary' : 'border-transparent'"
24
+ :style="{ backgroundColor: color }"
25
+ @click="onColorChange(color)"
26
+ />
27
+ </div>
28
+ </div>
29
+ </template>
30
+ </UPopover>
31
+
32
+ <!-- Font size picker (free text only) -->
33
+ <USelect
34
+ v-if="isFreeText"
35
+ :model-value="currentFontSize"
36
+ :items="fontSizeItems"
37
+ class="w-20"
38
+ size="sm"
39
+ @update:model-value="onFontSizeChange"
40
+ />
41
+
42
+ <!-- Selection count badge for multi-select -->
43
+ <span v-if="isMultiSelect" class="text-xs text-muted px-1.5">
44
+ {{ state.selectedAnnotations.value.length }} selected
45
+ </span>
46
+
47
+ <!-- Delete -->
48
+ <button
49
+ class="flex items-center justify-center w-7 h-7 rounded-md hover:bg-default cursor-pointer"
50
+ title="Delete"
51
+ @click="onDelete"
52
+ >
53
+ <UIcon name="i-lucide-trash-2" class="text-sm text-error" />
54
+ </button>
55
+ </div>
56
+ </div>
57
+ </template>
58
+
59
+ <script setup>
60
+ import { computed } from "vue";
61
+ import { useViewerState } from "../composables/useViewerState";
62
+ import { defaultOptions, annotationDefinitions } from "../annotation/engine/config";
63
+ import { AnnotationType } from "../annotation/engine/types";
64
+ const state = useViewerState();
65
+ const colors = defaultOptions.colors;
66
+ const isMultiSelect = computed(() => state.selectedAnnotations.value.length > 1);
67
+ const hasSelection = computed(
68
+ () => state.selectedAnnotation.value !== null || state.selectedAnnotations.value.length > 0
69
+ );
70
+ const selectedDef = computed(() => {
71
+ const ann = state.selectedAnnotation.value;
72
+ if (!ann) return null;
73
+ return annotationDefinitions.find((d) => d.type === ann.type);
74
+ });
75
+ const hasColorEdit = computed(() => {
76
+ return selectedDef.value?.styleEditable?.color ?? false;
77
+ });
78
+ const currentColor = computed(() => {
79
+ return state.selectedAnnotation.value?.color ?? selectedDef.value?.style?.color ?? null;
80
+ });
81
+ const isFreeText = computed(
82
+ () => !isMultiSelect.value && state.selectedAnnotation.value?.type === AnnotationType.FREETEXT
83
+ );
84
+ const currentFontSize = computed(() => {
85
+ const ann = state.selectedAnnotation.value;
86
+ return ann?.fontSize ? String(ann.fontSize) : String(defaultOptions.setting.FONT_SIZE);
87
+ });
88
+ const fontSizeItems = defaultOptions.fontSize.map((s) => ({
89
+ label: `${s}px`,
90
+ value: String(s)
91
+ }));
92
+ const toolbarStyle = computed(() => {
93
+ const rect = state.selectionRect.value;
94
+ if (!rect) return { display: "none" };
95
+ return {
96
+ left: `${rect.x + rect.width / 2}px`,
97
+ top: `${rect.y + rect.height + 8}px`,
98
+ transform: "translateX(-50%)"
99
+ };
100
+ });
101
+ function onColorChange(color) {
102
+ const ann = state.selectedAnnotation.value;
103
+ if (!ann || !state.painter.value) return;
104
+ state.painter.value.updateAnnotationStyle(ann, { color });
105
+ ann.color = color;
106
+ state.selectedAnnotation.value = { ...ann };
107
+ }
108
+ function onFontSizeChange(value) {
109
+ const ann = state.selectedAnnotation.value;
110
+ if (!ann || !state.painter.value) return;
111
+ const fontSize = Number(value);
112
+ state.painter.value.updateAnnotationStyle(ann, { fontSize });
113
+ ann.fontSize = fontSize;
114
+ state.selectedAnnotation.value = { ...ann };
115
+ }
116
+ function onDelete() {
117
+ if (isMultiSelect.value) {
118
+ const ids = state.selectedAnnotations.value.map((a) => a.id);
119
+ ids.forEach((id) => state.deleteAnnotation(id));
120
+ } else {
121
+ const ann = state.selectedAnnotation.value;
122
+ if (ann) state.deleteAnnotation(ann.id);
123
+ }
124
+ }
125
+ </script>
@@ -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,6 @@
1
+ type __VLS_Props = {
2
+ scrollContainer: HTMLElement | null;
3
+ };
4
+ declare const __VLS_export: 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>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,93 @@
1
+ <template>
2
+ <div
3
+ class="absolute bottom-0 left-0 right-0 z-10 flex justify-center pb-4"
4
+ @mouseenter="onMouseEnter"
5
+ @mouseleave="onMouseLeave"
6
+ >
7
+ <!-- Invisible hover zone at the bottom of the viewer -->
8
+ <div class="absolute inset-x-0 bottom-0 h-16" />
9
+
10
+ <div
11
+ class="relative z-10 flex items-center gap-1 bg-elevated rounded-full px-1 py-0.5 shadow-md
12
+ transition-opacity duration-300"
13
+ :class="visible ? 'opacity-100' : 'opacity-0 pointer-events-none'"
14
+ >
15
+ <UButton
16
+ icon="i-lucide-chevron-left"
17
+ variant="ghost"
18
+ color="neutral"
19
+ size="xs"
20
+ :disabled="state.currentPage.value <= 1"
21
+ @click="goToPreviousPage"
22
+ />
23
+ <span class="text-sm text-muted tabular-nums px-1 select-none">
24
+ {{ state.currentPage.value }} / {{ state.totalPages.value }}
25
+ </span>
26
+ <UButton
27
+ icon="i-lucide-chevron-right"
28
+ variant="ghost"
29
+ color="neutral"
30
+ size="xs"
31
+ :disabled="state.currentPage.value >= state.totalPages.value"
32
+ @click="goToNextPage"
33
+ />
34
+ </div>
35
+ </div>
36
+ </template>
37
+
38
+ <script setup>
39
+ import { ref, onMounted, onBeforeUnmount } from "vue";
40
+ import { useViewerState } from "../composables/useViewerState";
41
+ const props = defineProps({
42
+ scrollContainer: { type: null, required: true }
43
+ });
44
+ const state = useViewerState();
45
+ const visible = ref(true);
46
+ const hovered = ref(false);
47
+ let hideTimer = null;
48
+ function scheduleHide() {
49
+ if (hideTimer) clearTimeout(hideTimer);
50
+ hideTimer = setTimeout(() => {
51
+ if (!hovered.value) {
52
+ visible.value = false;
53
+ }
54
+ }, 3e3);
55
+ }
56
+ function onScroll() {
57
+ visible.value = true;
58
+ scheduleHide();
59
+ }
60
+ function onMouseEnter() {
61
+ hovered.value = true;
62
+ visible.value = true;
63
+ if (hideTimer) clearTimeout(hideTimer);
64
+ }
65
+ function onMouseLeave() {
66
+ hovered.value = false;
67
+ scheduleHide();
68
+ }
69
+ function goToPreviousPage() {
70
+ const prev = state.currentPage.value - 1;
71
+ if (prev >= 1) {
72
+ state.scrollToPage(prev);
73
+ }
74
+ }
75
+ function goToNextPage() {
76
+ const next = state.currentPage.value + 1;
77
+ if (next <= state.totalPages.value) {
78
+ state.scrollToPage(next);
79
+ }
80
+ }
81
+ onMounted(() => {
82
+ scheduleHide();
83
+ if (props.scrollContainer) {
84
+ props.scrollContainer.addEventListener("scroll", onScroll, { passive: true });
85
+ }
86
+ });
87
+ onBeforeUnmount(() => {
88
+ if (hideTimer) clearTimeout(hideTimer);
89
+ if (props.scrollContainer) {
90
+ props.scrollContainer.removeEventListener("scroll", onScroll);
91
+ }
92
+ });
93
+ </script>
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ scrollContainer: HTMLElement | null;
3
+ };
4
+ declare const __VLS_export: 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>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
@@ -0,0 +1,11 @@
1
+ type __VLS_Props = {
2
+ pageNumber: number;
3
+ scale: number;
4
+ pageWidth: number;
5
+ pageHeight: number;
6
+ pointerEvents: string;
7
+ zIndex: number;
8
+ };
9
+ declare const __VLS_export: 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>;
10
+ declare const _default: typeof __VLS_export;
11
+ export default _default;
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <div
3
+ v-if="fields.length > 0"
4
+ class="kviewer-form-layer"
5
+ :style="{
6
+ position: 'absolute',
7
+ top: 0,
8
+ left: 0,
9
+ width: props.pageWidth + 'px',
10
+ height: props.pageHeight + 'px',
11
+ transform: `scale(${props.scale})`,
12
+ transformOrigin: '0 0',
13
+ zIndex: props.zIndex,
14
+ pointerEvents: props.pointerEvents
15
+ }"
16
+ >
17
+ <FormFieldWrapper
18
+ v-for="field in fields"
19
+ :key="field.id"
20
+ :field="field"
21
+ :page-height="props.pageHeight"
22
+ />
23
+ </div>
24
+ </template>
25
+
26
+ <script setup>
27
+ import { computed } from "vue";
28
+ import { useFormFields } from "../composables/useFormFields";
29
+ import FormFieldWrapper from "./form-fields/FormFieldWrapper.vue";
30
+ const props = defineProps({
31
+ pageNumber: { type: Number, required: true },
32
+ scale: { type: Number, required: true },
33
+ pageWidth: { type: Number, required: true },
34
+ pageHeight: { type: Number, required: true },
35
+ pointerEvents: { type: String, required: true },
36
+ zIndex: { type: Number, required: true }
37
+ });
38
+ const formFields = useFormFields();
39
+ const fields = computed(() => formFields.getFieldsForPage(props.pageNumber));
40
+ </script>
@@ -0,0 +1,11 @@
1
+ type __VLS_Props = {
2
+ pageNumber: number;
3
+ scale: number;
4
+ pageWidth: number;
5
+ pageHeight: number;
6
+ pointerEvents: string;
7
+ zIndex: number;
8
+ };
9
+ declare const __VLS_export: 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>;
10
+ declare const _default: typeof __VLS_export;
11
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import type { PageMeta } from '../composables/usePageVirtualization.js';
2
+ type __VLS_Props = {
3
+ pageNumber: number;
4
+ pageMeta: PageMeta;
5
+ scale: number;
6
+ };
7
+ declare const __VLS_export: 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>;
8
+ declare const _default: typeof __VLS_export;
9
+ export default _default;
@@ -0,0 +1,199 @@
1
+ <template>
2
+ <div
3
+ class="kviewer-page"
4
+ :style="{
5
+ position: 'relative',
6
+ width: cssWidth + 'px',
7
+ height: cssHeight + 'px',
8
+ '--scale-factor': String(props.scale),
9
+ '--user-unit': String(pageProxy?.userUnit || 1),
10
+ '--total-scale-factor': String(props.scale * (pageProxy?.userUnit || 1)),
11
+ '--scale-round-x': '1px',
12
+ '--scale-round-y': '1px'
13
+ }"
14
+ >
15
+ <canvas
16
+ ref="canvasRef"
17
+ :style="{ display: 'block', width: cssWidth + 'px', height: cssHeight + 'px' }"
18
+ />
19
+ <div
20
+ ref="textLayerRef"
21
+ class="kviewer-text-layer textLayer"
22
+ :class="{ 'kviewer-text-layer--interactive': isSearchTextInteractive }"
23
+ :style="{
24
+ width: cssWidth + 'px',
25
+ height: cssHeight + 'px',
26
+ pointerEvents: isSearchTextInteractive ? 'auto' : 'none'
27
+ }"
28
+ />
29
+ <FormFieldLayer
30
+ :page-number="props.pageNumber"
31
+ :scale="props.scale"
32
+ :page-width="baseWidth"
33
+ :page-height="baseHeight"
34
+ :pointer-events="formFieldPointerEvents"
35
+ :z-index="formFieldZIndex"
36
+ />
37
+ <div
38
+ ref="annotationRef"
39
+ class="kviewer-annotation-layer"
40
+ :style="{
41
+ position: 'absolute',
42
+ top: 0,
43
+ left: 0,
44
+ width: cssWidth + 'px',
45
+ height: cssHeight + 'px',
46
+ zIndex: 3,
47
+ pointerEvents: annotationPointerEvents
48
+ }"
49
+ />
50
+ </div>
51
+ </template>
52
+
53
+ <script setup>
54
+ import { ref, shallowRef, computed, onMounted, onBeforeUnmount, watch } from "vue";
55
+ import { useViewerState } from "../composables/useViewerState";
56
+ import { useViewerSearch } from "../composables/useViewerSearch";
57
+ import { usePageProxyCache } from "../composables/usePageProxyCache";
58
+ import { useFormFields } from "../composables/useFormFields";
59
+ import { AnnotationType } from "../annotation/engine/types";
60
+ import FormFieldLayer from "./FormFieldLayer.vue";
61
+ const props = defineProps({
62
+ pageNumber: { type: Number, required: true },
63
+ pageMeta: { type: Object, required: true },
64
+ scale: { type: Number, required: true }
65
+ });
66
+ const canvasRef = ref(null);
67
+ const textLayerRef = ref(null);
68
+ const annotationRef = ref(null);
69
+ const state = useViewerState();
70
+ const search = useViewerSearch();
71
+ const proxyCache = usePageProxyCache();
72
+ const formFields = useFormFields();
73
+ const pageProxy = shallowRef(null);
74
+ let currentRenderTask = null;
75
+ let textLayer = null;
76
+ const baseWidth = props.pageMeta.width;
77
+ const baseHeight = props.pageMeta.height;
78
+ const cssWidth = computed(() => baseWidth * props.scale);
79
+ const cssHeight = computed(() => baseHeight * props.scale);
80
+ const isAnnotating = computed(() => {
81
+ const tool = state.activeTool.value;
82
+ return tool === "hand" || tool === "marquee" || tool === "eraser" || typeof tool === "number" && tool !== AnnotationType.NONE;
83
+ });
84
+ const isSearchTextInteractive = computed(() => search.isOpen.value && state.activeTool.value === "hand");
85
+ const annotationPointerEvents = computed(() => isSearchTextInteractive.value ? "none" : isAnnotating.value ? "auto" : "none");
86
+ const isUsingAnnotationTool = computed(() => {
87
+ const tool = state.activeTool.value;
88
+ return tool === "marquee" || tool === "eraser" || typeof tool === "number" && tool !== AnnotationType.NONE;
89
+ });
90
+ const formFieldPointerEvents = computed(() => isUsingAnnotationTool.value ? "none" : "auto");
91
+ const formFieldZIndex = computed(() => isUsingAnnotationTool.value ? 2 : 4);
92
+ onMounted(async () => {
93
+ pageProxy.value = await proxyCache.getPage(props.pageNumber);
94
+ await renderCanvas();
95
+ await renderTextLayer();
96
+ initKonva();
97
+ if (pageProxy.value) {
98
+ const rawAnnotations = await pageProxy.value.getAnnotations();
99
+ formFields.parsePageFields(props.pageNumber, rawAnnotations);
100
+ }
101
+ });
102
+ watch(
103
+ () => props.scale,
104
+ async () => {
105
+ if (!pageProxy.value) return;
106
+ await renderCanvas();
107
+ updateTextLayer();
108
+ if (state.painter.value) {
109
+ state.painter.value.destroyCanvasForPage(props.pageNumber);
110
+ initKonva();
111
+ }
112
+ }
113
+ );
114
+ async function renderCanvas() {
115
+ const canvas = canvasRef.value;
116
+ const proxy = pageProxy.value;
117
+ if (!canvas || !proxy) return;
118
+ if (currentRenderTask) {
119
+ currentRenderTask.cancel();
120
+ currentRenderTask = null;
121
+ }
122
+ const dpr = window.devicePixelRatio || 1;
123
+ const viewport = proxy.getViewport({
124
+ scale: props.scale * dpr
125
+ });
126
+ canvas.width = viewport.width;
127
+ canvas.height = viewport.height;
128
+ try {
129
+ currentRenderTask = proxy.render({
130
+ canvasContext: canvas.getContext("2d"),
131
+ viewport
132
+ });
133
+ await currentRenderTask.promise;
134
+ } catch (e) {
135
+ if (e instanceof Error && e.message?.includes("Rendering cancelled")) return;
136
+ throw e;
137
+ } finally {
138
+ currentRenderTask = null;
139
+ }
140
+ }
141
+ function initKonva() {
142
+ if (!annotationRef.value || !state.painter.value) return;
143
+ state.painter.value.initCanvasForPage(
144
+ props.pageNumber,
145
+ annotationRef.value,
146
+ baseWidth,
147
+ baseHeight,
148
+ props.scale
149
+ );
150
+ }
151
+ async function renderTextLayer() {
152
+ const container = textLayerRef.value;
153
+ const proxy = pageProxy.value;
154
+ if (!container || !proxy) return;
155
+ const viewport = proxy.getViewport({ scale: props.scale });
156
+ if (!textLayer) {
157
+ const pdfjs = await import("pdfjs-dist/legacy/build/pdf.mjs");
158
+ textLayer = new pdfjs.TextLayer({
159
+ textContentSource: proxy.streamTextContent({
160
+ includeMarkedContent: true,
161
+ disableNormalization: true
162
+ }),
163
+ container,
164
+ viewport
165
+ });
166
+ await textLayer.render();
167
+ search.registerPageLayer(
168
+ props.pageNumber,
169
+ textLayer.textDivs,
170
+ textLayer.textContentItemsStr
171
+ );
172
+ return;
173
+ }
174
+ textLayer.update({ viewport });
175
+ search.updatePageLayer(
176
+ props.pageNumber,
177
+ textLayer.textDivs,
178
+ textLayer.textContentItemsStr
179
+ );
180
+ }
181
+ function updateTextLayer() {
182
+ const proxy = pageProxy.value;
183
+ if (!textLayer || !proxy) return;
184
+ const viewport = proxy.getViewport({ scale: props.scale });
185
+ textLayer.update({ viewport });
186
+ search.updatePageLayer(
187
+ props.pageNumber,
188
+ textLayer.textDivs,
189
+ textLayer.textContentItemsStr
190
+ );
191
+ }
192
+ onBeforeUnmount(() => {
193
+ currentRenderTask?.cancel();
194
+ textLayer?.cancel();
195
+ textLayer = null;
196
+ search.unregisterPageLayer(props.pageNumber);
197
+ state.painter.value?.destroyCanvasForPage(props.pageNumber);
198
+ });
199
+ </script>
@@ -0,0 +1,9 @@
1
+ import type { PageMeta } from '../composables/usePageVirtualization.js';
2
+ type __VLS_Props = {
3
+ pageNumber: number;
4
+ pageMeta: PageMeta;
5
+ scale: number;
6
+ };
7
+ declare const __VLS_export: 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>;
8
+ declare const _default: typeof __VLS_export;
9
+ export default _default;
@@ -0,0 +1,13 @@
1
+ import type { IAnnotationType } from '../annotation/engine/types.js';
2
+ type __VLS_Props = {
3
+ tool: IAnnotationType | undefined;
4
+ active: boolean;
5
+ indicatorColor?: string;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
+ click: () => any;
9
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ onClick?: (() => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <button
3
+ v-if="tool"
4
+ class="relative flex items-center justify-center w-8 h-8 rounded-md transition-colors cursor-pointer"
5
+ :class="active ? 'bg-default text-highlighted' : 'text-muted hover:bg-default/50 hover:text-highlighted'"
6
+ :title="tool.name"
7
+ @click="$emit('click')"
8
+ >
9
+ <UIcon :name="tool.icon" class="text-lg" />
10
+ <!-- Color indicator line under icon -->
11
+ <span
12
+ v-if="indicatorColor"
13
+ class="absolute bottom-0.5 left-1.5 right-1.5 h-0.5 rounded-full"
14
+ :style="{ backgroundColor: indicatorColor }"
15
+ />
16
+ </button>
17
+ </template>
18
+
19
+ <script setup>
20
+ defineProps({
21
+ tool: { type: null, required: true },
22
+ active: { type: Boolean, required: true },
23
+ indicatorColor: { type: String, required: false }
24
+ });
25
+ defineEmits(["click"]);
26
+ </script>
@@ -0,0 +1,13 @@
1
+ import type { IAnnotationType } from '../annotation/engine/types.js';
2
+ type __VLS_Props = {
3
+ tool: IAnnotationType | undefined;
4
+ active: boolean;
5
+ indicatorColor?: string;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
+ click: () => any;
9
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ onClick?: (() => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ 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,11 @@
1
+ <template>
2
+ <div/>
3
+ </template>
4
+
5
+ <script lang="ts" setup>
6
+
7
+ </script>
8
+
9
+ <style>
10
+
11
+ </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;
@@ -0,0 +1,45 @@
1
+ import { type ViewMode } from '../composables/useViewerState.js';
2
+ import type { IAnnotationStore, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
3
+ import { type ExportPdfOptions } from '../annotation/pdf-export/export.js';
4
+ type __VLS_Props = {
5
+ source: string | Uint8Array | object;
6
+ textLayer?: boolean;
7
+ userName?: string;
8
+ stamps?: StampDefinition[];
9
+ signatureHandlers?: SignatureHandlers;
10
+ viewMode?: ViewMode;
11
+ zoom?: number;
12
+ /** When false, global keyboard shortcuts (e.g. Cmd+F) are suppressed. Used by ViewerTabs to prevent hidden viewers from capturing input. */
13
+ active?: boolean;
14
+ };
15
+ declare function exportPdf(options?: ExportPdfOptions): Promise<Uint8Array>;
16
+ type ImportMode = 'replace' | 'merge';
17
+ declare function importAnnotations(annotations: IAnnotationStore[], options?: {
18
+ mode?: ImportMode;
19
+ }): Promise<{
20
+ loaded: number;
21
+ skipped: number;
22
+ }>;
23
+ declare function getKonvaCanvasState(): Record<number, string>;
24
+ declare var __VLS_1: {}, __VLS_40: {};
25
+ type __VLS_Slots = {} & {
26
+ header?: (props: typeof __VLS_1) => any;
27
+ } & {
28
+ footer?: (props: typeof __VLS_40) => any;
29
+ };
30
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
31
+ getAnnotations: () => IAnnotationStore[];
32
+ importAnnotations: typeof importAnnotations;
33
+ exportPdf: typeof exportPdf;
34
+ getKonvaCanvasState: typeof getKonvaCanvasState;
35
+ getFormFieldValues: () => import("../annotation/engine/types.js").FormFieldValue[];
36
+ setFormFieldValue: (fieldName: string, value: string | boolean | string[]) => void;
37
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
38
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
39
+ declare const _default: typeof __VLS_export;
40
+ export default _default;
41
+ type __VLS_WithSlots<T, S> = T & {
42
+ new (): {
43
+ $slots: S;
44
+ };
45
+ };