@pdfme/ui 5.3.11 → 5.3.12-dev.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 (35) hide show
  1. package/dist/index.es.js +9116 -8977
  2. package/dist/index.umd.js +125 -125
  3. package/dist/types/src/components/Designer/Canvas/Guides.d.ts +3 -9
  4. package/dist/types/src/components/Designer/Canvas/Moveable.d.ts +2 -49
  5. package/dist/types/src/components/Designer/Canvas/Selecto.d.ts +5 -16
  6. package/dist/types/src/components/Designer/PluginIcon.d.ts +2 -2
  7. package/dist/types/src/components/Designer/RightSidebar/ListView/Item.d.ts +17 -0
  8. package/dist/types/src/components/Renderer.d.ts +1 -10
  9. package/dist/types/src/constants.d.ts +1 -1
  10. package/dist/types/src/contexts.d.ts +1 -1
  11. package/dist/types/src/helper.d.ts +3 -4
  12. package/package.json +3 -3
  13. package/src/components/AppContextProvider.tsx +23 -10
  14. package/src/components/CtlBar.tsx +2 -2
  15. package/src/components/Designer/Canvas/Guides.tsx +4 -13
  16. package/src/components/Designer/Canvas/Moveable.tsx +21 -76
  17. package/src/components/Designer/Canvas/Selecto.tsx +12 -24
  18. package/src/components/Designer/Canvas/index.tsx +51 -72
  19. package/src/components/Designer/LeftSidebar.tsx +2 -2
  20. package/src/components/Designer/PluginIcon.tsx +15 -3
  21. package/src/components/Designer/RightSidebar/DetailView/AlignWidget.tsx +105 -19
  22. package/src/components/Designer/RightSidebar/DetailView/ButtonGroupWidget.tsx +14 -11
  23. package/src/components/Designer/RightSidebar/DetailView/index.tsx +170 -48
  24. package/src/components/Designer/RightSidebar/ListView/Item.tsx +114 -88
  25. package/src/components/Designer/RightSidebar/ListView/SelectableSortableContainer.tsx +23 -3
  26. package/src/components/Designer/RightSidebar/ListView/SelectableSortableItem.tsx +21 -4
  27. package/src/components/Designer/index.tsx +14 -9
  28. package/src/components/Preview.tsx +5 -5
  29. package/src/components/Renderer.tsx +43 -37
  30. package/src/components/Root.tsx +1 -1
  31. package/src/constants.ts +1 -1
  32. package/src/contexts.ts +1 -1
  33. package/src/helper.ts +136 -38
  34. package/src/types/react-guides.d.ts +0 -22
  35. 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
- getMaxZoom,
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 = getMaxZoom();
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
- setTimeout(
231
- () =>
232
- canvasRef.current &&
233
- ((canvasRef.current.scrollTop = getPagesScrollTopByIndex(pageSizes, newPageCursor, scale)),
234
- 0),
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
- editingElem && onEdit([editingElem]);
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, getMaxZoom } from '../helper.js';
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 = getMaxZoom();
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: any }[], schema: SchemaForUI) => {
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-ignore
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: Plugin<any>;
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
- export const useRerenderDependencies = (arg: ReRenderCheckProps) => {
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.uninterruptedEditMode && mode === 'designer') {
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.uninterruptedEditMode, value, mode, scale, schema, optionStr]);
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: keyof Dict | string) => string;
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
- const plugin = Object.values(pluginsRegistry || {}).find(
114
- (plugin) => plugin?.propPanel.defaultSchema.type === schema.type,
115
- ) as Plugin<any> | undefined;
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: options as UIOptions,
127
+ options,
129
128
  });
130
129
 
131
130
  useEffect(() => {
132
- if (ref.current && schema.type) {
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: options as UIOptions,
147
- theme,
148
- i18n,
149
- _cache: _cache as Map<any, any>,
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}>
@@ -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
@@ -1,4 +1,4 @@
1
- export const DEFAULT_LANG = 'en' as const;
1
+ export const DEFAULT_LANG = 'en';
2
2
 
3
3
  export const DESTROYED_ERR_MSG = '[@pdfme/ui] this instance is already destroyed';
4
4
 
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<any, any>>(new 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 (hotkeysJs as any)(keys, callback);
25
- };
31
+ return hotkeysJs(keys, callback);
32
+ } as HotkeysFunction;
26
33
 
27
34
  // Add properties to the hotkeys function
28
- (hotkeys as any).shift = false;
29
- (hotkeys as any).unbind = function (keys: string) {
35
+ hotkeys.shift = false;
36
+ hotkeys.unbind = function (keys: string) {
30
37
  // Do nothing if hotkeysJs doesn't have unbind
31
- if (typeof (hotkeysJs as any).unbind === 'function') {
32
- (hotkeysJs as any).unbind(keys);
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
- export const set = <T extends object>(obj: T, path: string | string[], value: any) => {
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: any = obj;
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 (!src.hasOwnProperty(key)) {
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 Function>(cb: T, wait = 20) => {
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: any) => {
69
+ const callable = (...args: Parameters<T>) => {
62
70
  if (h) clearTimeout(h);
63
71
  h = setTimeout(() => cb(...args), wait);
64
72
  };
65
- return <T>(<any>callable);
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', (hotkeys as any).shift);
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', (hotkeys as any).shift);
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', (hotkeys as any).shift);
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', (hotkeys as any).shift);
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
- (hotkeys as any).unbind(keys.join());
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: any[]) => {
263
- page.forEach((schema: any) => {
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
- // @ts-expect-error
286
- const pdfArrayBuffer = b64toUint8Array(b64BasePdf) as ArrayBuffer;
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-ignore
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: any,
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: any, min: number, max: number) => Math.min(Math.max(Number(v), min), max);
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: any,
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
- const propPanel = Object.values(pluginsRegistry).find(
457
- (plugin) => plugin?.propPanel.defaultSchema.type === value,
458
- )?.propPanel;
459
- Object.keys(propPanel?.defaultSchema || {}).forEach((key) => {
460
- if (!schema.hasOwnProperty(key)) {
461
- (schema as any)[key] = propPanel?.defaultSchema[key];
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: any; schemaId: string }[];
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 getMaxZoom = () => {
593
+ export const useMaxZoom = () => {
496
594
  const options = useContext(OptionsContext);
497
595
 
498
- return options.maxZoom ? (options.maxZoom as number) / 100 : DEFAULT_MAX_ZOOM;
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
- }