@pdfme/ui 5.3.11 → 5.3.12-dev.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/dist/index.es.js +40494 -42705
- package/dist/index.umd.js +231 -231
- package/dist/types/src/components/Designer/Canvas/Guides.d.ts +3 -9
- package/dist/types/src/components/Designer/Canvas/Moveable.d.ts +2 -49
- package/dist/types/src/components/Designer/Canvas/Selecto.d.ts +5 -16
- package/dist/types/src/components/Designer/PluginIcon.d.ts +2 -2
- package/dist/types/src/components/Designer/RightSidebar/ListView/Item.d.ts +17 -0
- package/dist/types/src/components/Renderer.d.ts +1 -10
- package/dist/types/src/constants.d.ts +1 -1
- package/dist/types/src/contexts.d.ts +1 -1
- package/dist/types/src/helper.d.ts +3 -4
- package/package.json +3 -3
- package/src/components/AppContextProvider.tsx +23 -10
- package/src/components/CtlBar.tsx +2 -2
- package/src/components/Designer/Canvas/Guides.tsx +4 -13
- package/src/components/Designer/Canvas/Moveable.tsx +21 -76
- package/src/components/Designer/Canvas/Selecto.tsx +12 -24
- package/src/components/Designer/Canvas/index.tsx +51 -72
- package/src/components/Designer/LeftSidebar.tsx +2 -2
- package/src/components/Designer/PluginIcon.tsx +15 -3
- package/src/components/Designer/RightSidebar/DetailView/AlignWidget.tsx +105 -19
- package/src/components/Designer/RightSidebar/DetailView/ButtonGroupWidget.tsx +14 -11
- package/src/components/Designer/RightSidebar/DetailView/index.tsx +170 -48
- package/src/components/Designer/RightSidebar/ListView/Item.tsx +114 -88
- package/src/components/Designer/RightSidebar/ListView/SelectableSortableContainer.tsx +23 -3
- package/src/components/Designer/RightSidebar/ListView/SelectableSortableItem.tsx +21 -4
- package/src/components/Designer/index.tsx +14 -9
- package/src/components/Preview.tsx +5 -5
- package/src/components/Renderer.tsx +43 -37
- package/src/components/Root.tsx +1 -1
- package/src/constants.ts +1 -1
- package/src/contexts.ts +1 -1
- package/src/helper.ts +136 -38
- package/src/types/react-guides.d.ts +0 -22
- package/src/types/react-selecto.d.ts +0 -35
@@ -24,7 +24,7 @@ import {
|
|
24
24
|
template2SchemasList,
|
25
25
|
getPagesScrollTopByIndex,
|
26
26
|
changeSchemas as _changeSchemas,
|
27
|
-
|
27
|
+
useMaxZoom,
|
28
28
|
} from '../../helper.js';
|
29
29
|
import { useUIPreProcessor, useScrollPageCursor, useInitEvents } from '../../hooks.js';
|
30
30
|
import Root from '../Root.js';
|
@@ -64,7 +64,7 @@ const TemplateEditor = ({
|
|
64
64
|
const i18n = useContext(I18nContext);
|
65
65
|
const pluginsRegistry = useContext(PluginsRegistry);
|
66
66
|
const options = useContext(OptionsContext);
|
67
|
-
const maxZoom =
|
67
|
+
const maxZoom = useMaxZoom();
|
68
68
|
|
69
69
|
const [hoveringSchemaId, setHoveringSchemaId] = useState<string | null>(null);
|
70
70
|
const [activeElements, setActiveElements] = useState<HTMLElement[]>([]);
|
@@ -227,12 +227,13 @@ const TemplateEditor = ({
|
|
227
227
|
onChangeTemplate(newTemplate);
|
228
228
|
await updateTemplate(newTemplate);
|
229
229
|
void refresh(newTemplate);
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
230
|
+
|
231
|
+
// Use setTimeout to update scroll position after render
|
232
|
+
setTimeout(() => {
|
233
|
+
if (canvasRef.current) {
|
234
|
+
canvasRef.current.scrollTop = getPagesScrollTopByIndex(pageSizes, newPageCursor, scale);
|
235
|
+
}
|
236
|
+
}, 0);
|
236
237
|
};
|
237
238
|
|
238
239
|
const handleRemovePage = () => {
|
@@ -262,6 +263,7 @@ const TemplateEditor = ({
|
|
262
263
|
};
|
263
264
|
|
264
265
|
if (error) {
|
266
|
+
// Pass the error directly to ErrorScreen
|
265
267
|
return <ErrorScreen size={size} error={error} />;
|
266
268
|
}
|
267
269
|
const pageManipulation = isBlankPdf(template.basePdf)
|
@@ -309,6 +311,7 @@ const TemplateEditor = ({
|
|
309
311
|
pageNum={schemasList.length}
|
310
312
|
setPageCursor={(p) => {
|
311
313
|
if (!canvasRef.current) return;
|
314
|
+
// Update scroll position and state
|
312
315
|
canvasRef.current.scrollTop = getPagesScrollTopByIndex(pageSizes, p, scale);
|
313
316
|
setPageCursor(p);
|
314
317
|
onEditEnd();
|
@@ -331,7 +334,9 @@ const TemplateEditor = ({
|
|
331
334
|
onSortEnd={onSortEnd}
|
332
335
|
onEdit={(id) => {
|
333
336
|
const editingElem = document.getElementById(id);
|
334
|
-
|
337
|
+
if (editingElem) {
|
338
|
+
onEdit([editingElem]);
|
339
|
+
}
|
335
340
|
}}
|
336
341
|
onEditEnd={onEditEnd}
|
337
342
|
deselectSchema={onEditEnd}
|
@@ -17,10 +17,10 @@ import Paper from './Paper.js';
|
|
17
17
|
import Renderer from './Renderer.js';
|
18
18
|
import { useUIPreProcessor, useScrollPageCursor } from '../hooks.js';
|
19
19
|
import { FontContext } from '../contexts.js';
|
20
|
-
import { template2SchemasList, getPagesScrollTopByIndex,
|
20
|
+
import { template2SchemasList, getPagesScrollTopByIndex, useMaxZoom } from '../helper.js';
|
21
21
|
import { theme } from 'antd';
|
22
22
|
|
23
|
-
const _cache = new Map();
|
23
|
+
const _cache = new Map<string | number, unknown>();
|
24
24
|
|
25
25
|
const Preview = ({
|
26
26
|
template,
|
@@ -34,7 +34,7 @@ const Preview = ({
|
|
34
34
|
const { token } = theme.useToken();
|
35
35
|
|
36
36
|
const font = useContext(FontContext);
|
37
|
-
const maxZoom =
|
37
|
+
const maxZoom = useMaxZoom();
|
38
38
|
|
39
39
|
const containerRef = useRef<HTMLDivElement>(null);
|
40
40
|
const paperRefs = useRef<HTMLDivElement[]>([]);
|
@@ -98,7 +98,7 @@ const Preview = ({
|
|
98
98
|
const handleChangeInput = ({ name, value }: { name: string; value: string }) =>
|
99
99
|
onChangeInput && onChangeInput({ index: unitCursor, name, value });
|
100
100
|
|
101
|
-
const handleOnChangeRenderer = (args: { key: string; value:
|
101
|
+
const handleOnChangeRenderer = (args: { key: string; value: unknown }[], schema: SchemaForUI) => {
|
102
102
|
let isNeedInit = false;
|
103
103
|
args.forEach(({ key: _key, value }) => {
|
104
104
|
if (_key === 'content') {
|
@@ -112,7 +112,7 @@ const Preview = ({
|
|
112
112
|
const targetSchema = schemasList[pageCursor].find((s) => s.id === schema.id) as SchemaForUI;
|
113
113
|
if (!targetSchema) return;
|
114
114
|
|
115
|
-
// @ts-
|
115
|
+
// @ts-expect-error Dynamic property assignment
|
116
116
|
targetSchema[_key] = value as string;
|
117
117
|
}
|
118
118
|
});
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import React, { useEffect, useContext, ReactNode, useRef, useMemo } from 'react';
|
2
2
|
import {
|
3
|
-
Dict,
|
4
3
|
Mode,
|
5
4
|
ZOOM,
|
6
5
|
UIRenderProps,
|
@@ -29,7 +28,7 @@ type RendererProps = Omit<
|
|
29
28
|
};
|
30
29
|
|
31
30
|
type ReRenderCheckProps = {
|
32
|
-
plugin
|
31
|
+
plugin?: Plugin<Schema>;
|
33
32
|
value: string;
|
34
33
|
mode: Mode;
|
35
34
|
scale: number;
|
@@ -37,7 +36,7 @@ type ReRenderCheckProps = {
|
|
37
36
|
options: UIOptions;
|
38
37
|
};
|
39
38
|
|
40
|
-
|
39
|
+
const useRerenderDependencies = (arg: ReRenderCheckProps) => {
|
41
40
|
const { plugin, value, mode, scale, schema, options } = arg;
|
42
41
|
const _options = cloneDeep(options);
|
43
42
|
if (_options.font) {
|
@@ -48,12 +47,12 @@ export const useRerenderDependencies = (arg: ReRenderCheckProps) => {
|
|
48
47
|
const optionStr = JSON.stringify(_options);
|
49
48
|
|
50
49
|
return useMemo(() => {
|
51
|
-
if (plugin
|
50
|
+
if (plugin?.uninterruptedEditMode && mode === 'designer') {
|
52
51
|
return [mode];
|
53
52
|
} else {
|
54
53
|
return [value, mode, scale, JSON.stringify(schema), optionStr];
|
55
54
|
}
|
56
|
-
}, [plugin
|
55
|
+
}, [plugin?.uninterruptedEditMode, value, mode, scale, schema, optionStr, plugin]);
|
57
56
|
};
|
58
57
|
|
59
58
|
const Wrapper = ({
|
@@ -105,56 +104,63 @@ const Renderer = (props: RendererProps) => {
|
|
105
104
|
|
106
105
|
const pluginsRegistry = useContext(PluginsRegistry);
|
107
106
|
const options = useContext(OptionsContext);
|
108
|
-
const i18n = useContext(I18nContext) as (key:
|
107
|
+
const i18n = useContext(I18nContext) as (key: string) => string;
|
109
108
|
const { token: theme } = antdTheme.useToken();
|
110
109
|
|
111
110
|
const ref = useRef<HTMLDivElement>(null);
|
112
111
|
const _cache = useContext(CacheContext);
|
113
|
-
|
114
|
-
|
115
|
-
|
112
|
+
// Safely extract schema type
|
113
|
+
const schemaType = typeof schema.type === 'string' ? schema.type : '';
|
114
|
+
|
115
|
+
// Find plugin with matching schema type using a type-safe approach
|
116
|
+
const plugin = Object.values(pluginsRegistry || {}).find((plugin) => {
|
117
|
+
const defaultSchema = plugin?.propPanel?.defaultSchema as Record<string, unknown> | undefined;
|
118
|
+
return defaultSchema?.type === schemaType;
|
119
|
+
});
|
116
120
|
|
117
|
-
if (!plugin || !plugin.ui) {
|
118
|
-
console.error(`[@pdfme/ui] Renderer for type ${schema.type} not found.
|
119
|
-
Check this document: https://pdfme.com/docs/custom-schemas`);
|
120
|
-
return <></>;
|
121
|
-
}
|
122
121
|
const reRenderDependencies = useRerenderDependencies({
|
123
|
-
plugin,
|
122
|
+
plugin: plugin || ({} as Plugin<Schema>),
|
124
123
|
value,
|
125
124
|
mode,
|
126
125
|
scale,
|
127
126
|
schema,
|
128
|
-
options
|
127
|
+
options,
|
129
128
|
});
|
130
129
|
|
131
130
|
useEffect(() => {
|
132
|
-
if (ref.current
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
}
|
131
|
+
if (!plugin?.ui || !ref.current || !schema.type) return;
|
132
|
+
|
133
|
+
ref.current.innerHTML = '';
|
134
|
+
const render = plugin.ui;
|
135
|
+
|
136
|
+
void render({
|
137
|
+
value,
|
138
|
+
schema,
|
139
|
+
basePdf,
|
140
|
+
rootElement: ref.current,
|
141
|
+
mode,
|
142
|
+
onChange,
|
143
|
+
stopEditing,
|
144
|
+
tabIndex,
|
145
|
+
placeholder,
|
146
|
+
options,
|
147
|
+
theme,
|
148
|
+
i18n,
|
149
|
+
_cache,
|
150
|
+
});
|
151
|
+
|
152
152
|
return () => {
|
153
153
|
if (ref.current) {
|
154
154
|
ref.current.innerHTML = '';
|
155
155
|
}
|
156
156
|
};
|
157
|
-
}, reRenderDependencies);
|
157
|
+
}, [plugin?.ui, schema.type, reRenderDependencies]);
|
158
|
+
|
159
|
+
if (!plugin || !plugin.ui) {
|
160
|
+
console.error(`[@pdfme/ui] Renderer for type ${schema.type} not found.
|
161
|
+
Check this document: https://pdfme.com/docs/custom-schemas`);
|
162
|
+
return <></>;
|
163
|
+
}
|
158
164
|
|
159
165
|
return (
|
160
166
|
<Wrapper {...props}>
|
package/src/components/Root.tsx
CHANGED
@@ -19,7 +19,7 @@ const Root = ({ size, scale, children }: Props, ref: Ref<HTMLDivElement>) => {
|
|
19
19
|
);
|
20
20
|
const newFontFaces = fontFaces.filter((fontFace) => !document.fonts.has(fontFace));
|
21
21
|
|
22
|
-
Promise.allSettled(newFontFaces.map((f) => f.load())).then((loadedFontFaces) => {
|
22
|
+
void Promise.allSettled(newFontFaces.map((f) => f.load())).then((loadedFontFaces) => {
|
23
23
|
loadedFontFaces.forEach((loadedFontFace) => {
|
24
24
|
if (loadedFontFace.status === 'fulfilled') {
|
25
25
|
document.fonts.add(loadedFontFace.value);
|
package/src/constants.ts
CHANGED
package/src/contexts.ts
CHANGED
@@ -11,4 +11,4 @@ export const PluginsRegistry = createContext<Plugins>(builtInPlugins);
|
|
11
11
|
|
12
12
|
export const OptionsContext = createContext<UIOptions>({});
|
13
13
|
|
14
|
-
export const CacheContext = createContext<Map<
|
14
|
+
export const CacheContext = createContext<Map<string | number, unknown>>(new Map());
|
package/src/helper.ts
CHANGED
@@ -16,20 +16,28 @@ import { pdf2size } from '@pdfme/converter';
|
|
16
16
|
import { DEFAULT_MAX_ZOOM, RULER_HEIGHT } from './constants.js';
|
17
17
|
import { OptionsContext } from './contexts.js';
|
18
18
|
|
19
|
+
// Define a type for the hotkeys function with additional properties
|
20
|
+
type HotkeysFunction = {
|
21
|
+
(keys: string, callback: (e: KeyboardEvent, handler: { shortcut: string }) => void): unknown;
|
22
|
+
shift: boolean;
|
23
|
+
unbind: (keys: string) => void;
|
24
|
+
};
|
25
|
+
|
19
26
|
// Create a simple mock for hotkeys to avoid TypeScript errors
|
20
27
|
const hotkeys = function (
|
21
28
|
keys: string,
|
22
29
|
callback: (e: KeyboardEvent, handler: { shortcut: string }) => void,
|
23
30
|
) {
|
24
|
-
return
|
25
|
-
};
|
31
|
+
return hotkeysJs(keys, callback);
|
32
|
+
} as HotkeysFunction;
|
26
33
|
|
27
34
|
// Add properties to the hotkeys function
|
28
|
-
|
29
|
-
|
35
|
+
hotkeys.shift = false;
|
36
|
+
hotkeys.unbind = function (keys: string) {
|
30
37
|
// Do nothing if hotkeysJs doesn't have unbind
|
31
|
-
|
32
|
-
|
38
|
+
const hotkeysFn = hotkeysJs as unknown as { unbind?: (keys: string) => void };
|
39
|
+
if (typeof hotkeysFn.unbind === 'function') {
|
40
|
+
hotkeysFn.unbind(keys);
|
33
41
|
}
|
34
42
|
};
|
35
43
|
|
@@ -40,29 +48,29 @@ export const uuid = () =>
|
|
40
48
|
return v.toString(16);
|
41
49
|
});
|
42
50
|
|
43
|
-
|
51
|
+
const set = <T extends object>(obj: T, path: string | string[], value: unknown) => {
|
44
52
|
path = Array.isArray(path) ? path : path.replace('[', '.').replace(']', '').split('.');
|
45
|
-
let src:
|
53
|
+
let src: Record<string, unknown> = obj as Record<string, unknown>;
|
46
54
|
path.forEach((key, index, array) => {
|
47
55
|
if (index == path.length - 1) {
|
48
56
|
src[key] = value;
|
49
57
|
} else {
|
50
|
-
if (!
|
58
|
+
if (!Object.prototype.hasOwnProperty.call(src, key)) {
|
51
59
|
const next = array[index + 1];
|
52
60
|
src[key] = String(Number(next)) === next ? [] : {};
|
53
61
|
}
|
54
|
-
src = src[key]
|
62
|
+
src = src[key] as Record<string, unknown>;
|
55
63
|
}
|
56
64
|
});
|
57
65
|
};
|
58
66
|
|
59
|
-
export const debounce = <T extends
|
67
|
+
export const debounce = <T extends (...args: unknown[]) => unknown>(cb: T, wait = 20) => {
|
60
68
|
let h: null | ReturnType<typeof setTimeout> = null;
|
61
|
-
const callable = (...args:
|
69
|
+
const callable = (...args: Parameters<T>) => {
|
62
70
|
if (h) clearTimeout(h);
|
63
71
|
h = setTimeout(() => cb(...args), wait);
|
64
72
|
};
|
65
|
-
return
|
73
|
+
return callable as T;
|
66
74
|
};
|
67
75
|
|
68
76
|
const shift = (number: number, precision: number, reverseShift: boolean) => {
|
@@ -147,22 +155,22 @@ export const initShortCuts = (arg: {
|
|
147
155
|
case up:
|
148
156
|
case shiftUp:
|
149
157
|
e.preventDefault();
|
150
|
-
arg.move('up',
|
158
|
+
arg.move('up', hotkeys.shift);
|
151
159
|
break;
|
152
160
|
case down:
|
153
161
|
case shiftDown:
|
154
162
|
e.preventDefault();
|
155
|
-
arg.move('down',
|
163
|
+
arg.move('down', hotkeys.shift);
|
156
164
|
break;
|
157
165
|
case left:
|
158
166
|
case shiftLeft:
|
159
167
|
e.preventDefault();
|
160
|
-
arg.move('left',
|
168
|
+
arg.move('left', hotkeys.shift);
|
161
169
|
break;
|
162
170
|
case right:
|
163
171
|
case shiftRight:
|
164
172
|
e.preventDefault();
|
165
|
-
arg.move('right',
|
173
|
+
arg.move('right', hotkeys.shift);
|
166
174
|
break;
|
167
175
|
case rmWin:
|
168
176
|
case rmMac:
|
@@ -204,7 +212,7 @@ export const initShortCuts = (arg: {
|
|
204
212
|
};
|
205
213
|
|
206
214
|
export const destroyShortCuts = () => {
|
207
|
-
|
215
|
+
hotkeys.unbind(keys.join());
|
208
216
|
};
|
209
217
|
|
210
218
|
/**
|
@@ -259,10 +267,10 @@ export const arrayBufferToBase64 = (arrayBuffer: ArrayBuffer): string => {
|
|
259
267
|
};
|
260
268
|
|
261
269
|
const convertSchemasForUI = (template: Template): SchemaForUI[][] => {
|
262
|
-
template.schemas.forEach((page
|
263
|
-
page.forEach((schema
|
264
|
-
schema.id = uuid();
|
265
|
-
schema.content = schema.content || '';
|
270
|
+
template.schemas.forEach((page) => {
|
271
|
+
page.forEach((schema) => {
|
272
|
+
(schema as SchemaForUI).id = uuid();
|
273
|
+
(schema as SchemaForUI).content = schema.content || '';
|
266
274
|
});
|
267
275
|
});
|
268
276
|
|
@@ -282,8 +290,8 @@ export const template2SchemasList = async (_template: Template) => {
|
|
282
290
|
}));
|
283
291
|
} else {
|
284
292
|
const b64BasePdf = await getB64BasePdf(basePdf);
|
285
|
-
//
|
286
|
-
const pdfArrayBuffer = b64toUint8Array(b64BasePdf)
|
293
|
+
// pdf2size accepts both ArrayBuffer and Uint8Array
|
294
|
+
const pdfArrayBuffer = b64toUint8Array(b64BasePdf);
|
287
295
|
|
288
296
|
pageSizes = await pdf2size(pdfArrayBuffer);
|
289
297
|
}
|
@@ -317,7 +325,7 @@ export const template2SchemasList = async (_template: Template) => {
|
|
317
325
|
export const schemasList2template = (schemasList: SchemaForUI[][], basePdf: BasePdf): Template => ({
|
318
326
|
schemas: cloneDeep(schemasList).map((page) =>
|
319
327
|
page.map((schema) => {
|
320
|
-
// @ts-
|
328
|
+
// @ts-expect-error Property 'id' is used only in UI
|
321
329
|
delete schema.id;
|
322
330
|
return schema;
|
323
331
|
}),
|
@@ -420,14 +428,15 @@ export const getSidebarContentHeight = (sidebarHeight: number) =>
|
|
420
428
|
const handlePositionSizeChange = (
|
421
429
|
schema: SchemaForUI,
|
422
430
|
key: string,
|
423
|
-
value:
|
431
|
+
value: unknown,
|
424
432
|
basePdf: BasePdf,
|
425
433
|
pageSize: Size,
|
426
434
|
) => {
|
427
435
|
const padding = isBlankPdf(basePdf) ? basePdf.padding : [0, 0, 0, 0];
|
428
436
|
const [pt, pr, pb, pl] = padding;
|
429
437
|
const { width: pw, height: ph } = pageSize;
|
430
|
-
const calcBounds = (v:
|
438
|
+
const calcBounds = (v: unknown, min: number, max: number) =>
|
439
|
+
Math.min(Math.max(Number(v), min), max);
|
431
440
|
if (key === 'position.x') {
|
432
441
|
schema.position.x = calcBounds(value, pl, pw - schema.width - pr);
|
433
442
|
} else if (key === 'position.y') {
|
@@ -442,7 +451,7 @@ const handlePositionSizeChange = (
|
|
442
451
|
const handleTypeChange = (
|
443
452
|
schema: SchemaForUI,
|
444
453
|
key: string,
|
445
|
-
value:
|
454
|
+
value: unknown,
|
446
455
|
pluginsRegistry: Plugins,
|
447
456
|
) => {
|
448
457
|
if (key !== 'type') return;
|
@@ -453,21 +462,110 @@ const handleTypeChange = (
|
|
453
462
|
}
|
454
463
|
});
|
455
464
|
// Apply attributes from new defaultSchema
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
465
|
+
// Find the plugin with matching type
|
466
|
+
const pluginValue = value as string;
|
467
|
+
|
468
|
+
// Define a type-safe approach to find the matching plugin
|
469
|
+
interface PluginSchema {
|
470
|
+
type: string;
|
471
|
+
[key: string]: unknown;
|
472
|
+
}
|
473
|
+
|
474
|
+
interface PluginType {
|
475
|
+
propPanel: {
|
476
|
+
defaultSchema: PluginSchema;
|
477
|
+
};
|
478
|
+
}
|
479
|
+
|
480
|
+
// Initialize plugin as undefined
|
481
|
+
let plugin: PluginType | undefined;
|
482
|
+
|
483
|
+
// Safely iterate through plugins to find one with matching type
|
484
|
+
const pluginEntries = Object.entries(pluginsRegistry);
|
485
|
+
for (let i = 0; i < pluginEntries.length; i++) {
|
486
|
+
const [, pluginObj] = pluginEntries[i];
|
487
|
+
|
488
|
+
// Skip invalid plugins
|
489
|
+
if (!pluginObj || typeof pluginObj !== 'object') continue;
|
490
|
+
|
491
|
+
// Check if propPanel exists and is an object
|
492
|
+
if (
|
493
|
+
!('propPanel' in pluginObj) ||
|
494
|
+
!pluginObj.propPanel ||
|
495
|
+
typeof pluginObj.propPanel !== 'object'
|
496
|
+
)
|
497
|
+
continue;
|
498
|
+
|
499
|
+
// Check if defaultSchema exists and is an object
|
500
|
+
const propPanel = pluginObj.propPanel as { defaultSchema?: unknown };
|
501
|
+
if (
|
502
|
+
!('defaultSchema' in propPanel) ||
|
503
|
+
!propPanel.defaultSchema ||
|
504
|
+
typeof propPanel.defaultSchema !== 'object'
|
505
|
+
)
|
506
|
+
continue;
|
507
|
+
|
508
|
+
// Safely check if type property exists and matches
|
509
|
+
const defaultSchema = propPanel.defaultSchema as Record<string, unknown>;
|
510
|
+
if (!('type' in defaultSchema) || typeof defaultSchema.type !== 'string') continue;
|
511
|
+
|
512
|
+
// Check if the type matches
|
513
|
+
const schemaType = defaultSchema.type;
|
514
|
+
if (schemaType === pluginValue) {
|
515
|
+
// Create a type-safe copy of the plugin
|
516
|
+
const safeSchema: PluginSchema = {
|
517
|
+
type: schemaType,
|
518
|
+
};
|
519
|
+
|
520
|
+
// Copy other properties safely
|
521
|
+
Object.keys(defaultSchema).forEach((key) => {
|
522
|
+
if (key !== 'type' && Object.prototype.hasOwnProperty.call(defaultSchema, key)) {
|
523
|
+
safeSchema[key] = defaultSchema[key];
|
524
|
+
}
|
525
|
+
});
|
526
|
+
|
527
|
+
// Found matching plugin with proper typing
|
528
|
+
plugin = {
|
529
|
+
propPanel: {
|
530
|
+
defaultSchema: safeSchema,
|
531
|
+
},
|
532
|
+
};
|
533
|
+
break;
|
462
534
|
}
|
463
|
-
}
|
535
|
+
}
|
536
|
+
|
537
|
+
const propPanel = plugin?.propPanel;
|
538
|
+
|
539
|
+
// Apply default schema properties if available
|
540
|
+
if (propPanel?.defaultSchema) {
|
541
|
+
// Create a type-safe copy of the default schema
|
542
|
+
const defaultSchema = propPanel.defaultSchema;
|
543
|
+
const schemaRecord = schema as Record<string, unknown>;
|
544
|
+
|
545
|
+
// Use a type-safe approach to copy properties
|
546
|
+
for (const key of Object.keys(defaultSchema)) {
|
547
|
+
// Only add properties that don't already exist in the schema
|
548
|
+
if (!Object.prototype.hasOwnProperty.call(schema, key)) {
|
549
|
+
// Create a safe copy of the property
|
550
|
+
if (Object.prototype.hasOwnProperty.call(defaultSchema, key)) {
|
551
|
+
// Get the property value safely
|
552
|
+
const propertyValue = defaultSchema[key];
|
553
|
+
|
554
|
+
// Only assign if the value is defined
|
555
|
+
if (propertyValue !== undefined) {
|
556
|
+
schemaRecord[key] = propertyValue;
|
557
|
+
}
|
558
|
+
}
|
559
|
+
}
|
560
|
+
}
|
561
|
+
}
|
464
562
|
if (schema.readOnly) {
|
465
563
|
schema.required = false;
|
466
564
|
}
|
467
565
|
};
|
468
566
|
|
469
567
|
export const changeSchemas = (args: {
|
470
|
-
objs: { key: string; value:
|
568
|
+
objs: { key: string; value: unknown; schemaId: string }[];
|
471
569
|
schemas: SchemaForUI[];
|
472
570
|
basePdf: BasePdf;
|
473
571
|
pluginsRegistry: Plugins;
|
@@ -492,8 +590,8 @@ export const changeSchemas = (args: {
|
|
492
590
|
commitSchemas(newSchemas);
|
493
591
|
};
|
494
592
|
|
495
|
-
export const
|
593
|
+
export const useMaxZoom = () => {
|
496
594
|
const options = useContext(OptionsContext);
|
497
595
|
|
498
|
-
return options.maxZoom ?
|
596
|
+
return options.maxZoom ? options.maxZoom / 100 : DEFAULT_MAX_ZOOM;
|
499
597
|
};
|
@@ -1,22 +0,0 @@
|
|
1
|
-
declare module '@scena/react-guides' {
|
2
|
-
import { Component, ForwardRefExoticComponent, RefAttributes } from 'react';
|
3
|
-
|
4
|
-
interface GuidesInterface {
|
5
|
-
getGuides(): number[];
|
6
|
-
scroll(pos: number): void;
|
7
|
-
scrollGuides(pos: number): void;
|
8
|
-
loadGuides(guides: number[]): void;
|
9
|
-
resize(): void;
|
10
|
-
}
|
11
|
-
|
12
|
-
interface GuidesProps {
|
13
|
-
zoom?: number;
|
14
|
-
style?: React.CSSProperties;
|
15
|
-
type?: 'horizontal' | 'vertical';
|
16
|
-
}
|
17
|
-
|
18
|
-
// Define the component as a ForwardRefExoticComponent to support refs
|
19
|
-
const GuidesComponent: ForwardRefExoticComponent<GuidesProps & RefAttributes<GuidesInterface>>;
|
20
|
-
|
21
|
-
export default GuidesComponent;
|
22
|
-
}
|
@@ -1,35 +0,0 @@
|
|
1
|
-
declare module 'react-selecto' {
|
2
|
-
import { ForwardRefExoticComponent, RefAttributes } from 'react';
|
3
|
-
|
4
|
-
interface OnDragStart {
|
5
|
-
inputEvent: MouseEvent;
|
6
|
-
stop: () => void;
|
7
|
-
isTrusted: boolean;
|
8
|
-
}
|
9
|
-
|
10
|
-
interface OnSelect {
|
11
|
-
selected: Element[];
|
12
|
-
added: Element[];
|
13
|
-
removed: Element[];
|
14
|
-
inputEvent: MouseEvent;
|
15
|
-
rect: DOMRect;
|
16
|
-
}
|
17
|
-
|
18
|
-
interface SelectoProps {
|
19
|
-
className?: string;
|
20
|
-
selectFromInside?: boolean;
|
21
|
-
selectByClick?: boolean;
|
22
|
-
preventDefault?: boolean;
|
23
|
-
hitRate?: number;
|
24
|
-
selectableTargets?: string[];
|
25
|
-
container?: HTMLElement | null;
|
26
|
-
continueSelect?: boolean;
|
27
|
-
onDragStart?: (e: OnDragStart) => void;
|
28
|
-
onSelect?: (e: OnSelect) => void;
|
29
|
-
}
|
30
|
-
|
31
|
-
// Define the component as a ForwardRefExoticComponent
|
32
|
-
const SelectoComponent: ForwardRefExoticComponent<SelectoProps & RefAttributes<any>>;
|
33
|
-
|
34
|
-
export default SelectoComponent;
|
35
|
-
}
|