@pdfme/ui 5.3.11-dev.9 → 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.
@@ -7,4 +7,4 @@ export declare const FontContext: import("react").Context<Record<string, {
7
7
  }>>;
8
8
  export declare const PluginsRegistry: import("react").Context<Plugins>;
9
9
  export declare const OptionsContext: import("react").Context<UIOptions>;
10
- export declare const CacheContext: import("react").Context<Map<unknown, unknown>>;
10
+ export declare const CacheContext: import("react").Context<Map<string | number, unknown>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdfme/ui",
3
- "version": "5.3.11-dev.9",
3
+ "version": "5.3.12-dev.1",
4
4
  "sideEffects": false,
5
5
  "author": "hand-dot",
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "devBuildType:watch": "tsc --emitDeclarationOnly --watch",
31
31
  "build": "vite build && tsc --emitDeclarationOnly",
32
32
  "clean": "rimraf dist",
33
- "lint": "eslint --ext .ts,.tsx src --config eslint.config.mjs --no-error-on-unmatched-pattern",
33
+ "lint": "eslint --ext .ts,.tsx src --config eslint.config.mjs",
34
34
  "test": "jest",
35
35
  "prune": "ts-prune src",
36
36
  "prettier": "prettier --write 'src/**/*.{ts,tsx}'"
@@ -38,7 +38,7 @@
38
38
  "dependencies": {
39
39
  "@dnd-kit/core": "^6.0.8",
40
40
  "@dnd-kit/sortable": "^10.0.0",
41
- "@pdfme/converter": "*",
41
+ "@pdfme/converter": "file:../converter",
42
42
  "@scena/react-guides": "^0.28.2",
43
43
  "antd": "^5.24.2",
44
44
  "form-render": "^2.2.16",
@@ -48,12 +48,18 @@ const deepMerge = <T extends Record<string, unknown>, U extends Record<string, u
48
48
  const AppContextProvider = ({ children, lang, font, plugins, options }: Props) => {
49
49
  let theme = defaultTheme;
50
50
  if (options.theme) {
51
- theme = deepMerge(theme as unknown as Record<string, unknown>, options.theme as unknown as Record<string, unknown>) as typeof theme;
51
+ theme = deepMerge(
52
+ theme as unknown as Record<string, unknown>,
53
+ options.theme as unknown as Record<string, unknown>,
54
+ ) as typeof theme;
52
55
  }
53
56
 
54
57
  let dict = getDict(lang);
55
58
  if (options.labels) {
56
- dict = deepMerge(dict as unknown as Record<string, unknown>, options.labels as unknown as Record<string, unknown>) as typeof dict;
59
+ dict = deepMerge(
60
+ dict as unknown as Record<string, unknown>,
61
+ options.labels as unknown as Record<string, unknown>,
62
+ ) as typeof dict;
57
63
  }
58
64
 
59
65
  return (
@@ -1,5 +1,11 @@
1
1
  import React, { useEffect, forwardRef, Ref } from 'react';
2
- import MoveableComponent, { OnDrag, OnRotate, OnRotateEnd, OnClick, OnResize } from 'react-moveable';
2
+ import MoveableComponent, {
3
+ OnDrag,
4
+ OnRotate,
5
+ OnRotateEnd,
6
+ OnClick,
7
+ OnResize,
8
+ } from 'react-moveable';
3
9
  import { theme } from 'antd';
4
10
 
5
11
  type Props = {
@@ -27,9 +33,7 @@ const Moveable = (props: Props, ref: Ref<MoveableComponent>) => {
27
33
  const { token } = theme.useToken();
28
34
  useEffect(() => {
29
35
  const containerElement = document.querySelector(`.${className}`);
30
- const containerElement2 = document.querySelectorAll(
31
- `.${className} .moveable-line`,
32
- );
36
+ const containerElement2 = document.querySelectorAll(`.${className} .moveable-line`);
33
37
  if (containerElement instanceof HTMLElement) {
34
38
  containerElement.style.setProperty('--moveable-color', token.colorPrimary);
35
39
  Array.from(containerElement2).forEach((e) => {
@@ -1,5 +1,8 @@
1
1
  import React, { useEffect } from 'react';
2
- import SelectoComponent, { OnSelect as SelectoOnSelect, OnDragStart as SelectoOnDragStart } from 'react-selecto';
2
+ import SelectoComponent, {
3
+ OnSelect as SelectoOnSelect,
4
+ OnDragStart as SelectoOnDragStart,
5
+ } from 'react-selecto';
3
6
  import { SELECTABLE_CLASSNAME } from '../../../constants.js';
4
7
  import { theme } from 'antd';
5
8
 
@@ -10,7 +10,7 @@ import React, {
10
10
  useCallback,
11
11
  } from 'react';
12
12
  import { theme, Button } from 'antd';
13
- import MoveableComponent, { OnDrag, OnRotate, OnRotateEnd, OnClick, OnResize } from 'react-moveable';
13
+ import MoveableComponent, { OnDrag, OnRotate, OnResize } from 'react-moveable';
14
14
  import {
15
15
  ZOOM,
16
16
  SchemaForUI,
@@ -320,8 +320,8 @@ const Canvas = (props: Props, ref: Ref<HTMLDivElement>) => {
320
320
  const getGuideLines = (guides: GuidesInterface[], index: number) =>
321
321
  guides[index] && guides[index].getGuides().map((g) => g * ZOOM);
322
322
 
323
- const onClickMoveable = (e: OnClick) => {
324
- e.inputEvent.stopPropagation();
323
+ const onClickMoveable = () => {
324
+ // Just set editing to true without trying to access event properties
325
325
  setEditing(true);
326
326
  };
327
327
 
@@ -331,13 +331,30 @@ const Canvas = (props: Props, ref: Ref<HTMLDivElement>) => {
331
331
  );
332
332
  const schemaTypes = selectedSchemas.map((s) => s.type);
333
333
  const uniqueSchemaTypes = [...new Set(schemaTypes)];
334
- const defaultSchemas = Object.values(pluginsRegistry).map(
335
- (plugin) => plugin?.propPanel.defaultSchema,
336
- );
337
334
 
338
- return uniqueSchemaTypes.every(
339
- (type) => defaultSchemas.find((ds) => ds.type === type)?.rotate !== undefined,
340
- );
335
+ // Create a type-safe array of default schemas
336
+ const defaultSchemas: Record<string, unknown>[] = [];
337
+
338
+ // Safely iterate through plugins registry
339
+ Object.values(pluginsRegistry).forEach((plugin) => {
340
+ if (
341
+ plugin &&
342
+ typeof plugin === 'object' &&
343
+ 'propPanel' in plugin &&
344
+ plugin.propPanel &&
345
+ typeof plugin.propPanel === 'object' &&
346
+ 'defaultSchema' in plugin.propPanel &&
347
+ plugin.propPanel.defaultSchema
348
+ ) {
349
+ defaultSchemas.push(plugin.propPanel.defaultSchema as Record<string, unknown>);
350
+ }
351
+ });
352
+
353
+ // Check if all schema types have rotate property
354
+ return uniqueSchemaTypes.every((type) => {
355
+ const matchingSchema = defaultSchemas.find((ds) => ds && 'type' in ds && ds.type === type);
356
+ return matchingSchema && 'rotate' in matchingSchema;
357
+ });
341
358
  }, [activeElements, pageCursor, schemasList, pluginsRegistry]);
342
359
 
343
360
  return (
@@ -354,26 +371,37 @@ const Canvas = (props: Props, ref: Ref<HTMLDivElement>) => {
354
371
  container={paperRefs.current[pageCursor]}
355
372
  continueSelect={isPressShiftKey}
356
373
  onDragStart={(e) => {
357
- const { inputEvent } = e;
358
- const isMoveableElement = moveable.current?.isMoveableElement(inputEvent.target as Element);
374
+ // Use type assertion to safely access inputEvent properties
375
+ const inputEvent = e.inputEvent as MouseEvent | TouchEvent;
376
+ const target = inputEvent.target as Element | null;
377
+ const isMoveableElement = moveable.current?.isMoveableElement(target as Element);
378
+
359
379
  if ((inputEvent.type === 'touchstart' && e.isTrusted) || isMoveableElement) {
360
380
  e.stop();
361
381
  }
362
382
 
363
- if (paperRefs.current[pageCursor] === inputEvent.target) {
383
+ if (paperRefs.current[pageCursor] === target) {
364
384
  onEdit([]);
365
385
  }
386
+
366
387
  // Check if the target is an HTMLElement and has an id property
367
- const targetElement = inputEvent.target as HTMLElement;
388
+ const targetElement = target as HTMLElement | null;
368
389
  if (targetElement && targetElement.id === DELETE_BTN_ID) {
369
390
  removeSchemas(activeElements.map((ae) => ae.id));
370
391
  }
371
392
  }}
372
- onSelect={({ added, removed, selected, inputEvent }) => {
393
+ onSelect={(e) => {
394
+ // Use type assertions to safely access properties
395
+ const inputEvent = e.inputEvent as MouseEvent | TouchEvent;
396
+ const added = e.added as HTMLElement[];
397
+ const removed = e.removed as HTMLElement[];
398
+ const selected = e.selected as HTMLElement[];
399
+
373
400
  const isClick = inputEvent.type === 'mousedown';
374
- let newActiveElements: HTMLElement[] = isClick ? (selected as HTMLElement[]) : [];
401
+ let newActiveElements: HTMLElement[] = isClick ? selected : [];
402
+
375
403
  if (!isClick && added.length > 0) {
376
- newActiveElements = activeElements.concat(added as HTMLElement[]);
404
+ newActiveElements = activeElements.concat(added);
377
405
  }
378
406
  if (!isClick && removed.length > 0) {
379
407
  newActiveElements = activeElements.filter((ae) => !removed.includes(ae));
@@ -383,8 +411,10 @@ const Canvas = (props: Props, ref: Ref<HTMLDivElement>) => {
383
411
  if (newActiveElements != activeElements) {
384
412
  setEditing(false);
385
413
  }
414
+
386
415
  // For MacOS CMD+SHIFT+3/4 screenshots where the keydown event is never received, check mouse too
387
- if (!inputEvent.shiftKey) {
416
+ const mouseEvent = inputEvent as MouseEvent;
417
+ if (mouseEvent && typeof mouseEvent.shiftKey === 'boolean' && !mouseEvent.shiftKey) {
388
418
  setIsPressShiftKey(false);
389
419
  }
390
420
  }}
@@ -485,7 +515,9 @@ const Canvas = (props: Props, ref: Ref<HTMLDivElement>) => {
485
515
  onChangeHoveringSchemaId={onChangeHoveringSchemaId}
486
516
  mode={mode}
487
517
  onChange={(arg) => {
488
- const args = Array.isArray(arg) ? arg : [arg];
518
+ // Use type assertion to safely handle the argument
519
+ type ChangeArg = { key: string; value: unknown };
520
+ const args = Array.isArray(arg) ? (arg as ChangeArg[]) : [arg as ChangeArg];
489
521
  changeSchemas(args.map(({ key, value }) => ({ key, value, schemaId: schema.id })));
490
522
  }}
491
523
  stopEditing={() => setEditing(false)}
@@ -38,17 +38,18 @@ const PluginIcon = (props: PluginIconProps) => {
38
38
  const { plugin, label, size, styles } = props;
39
39
  const { token } = theme.useToken();
40
40
  const options = useContext(OptionsContext);
41
-
41
+
42
42
  // Safely access plugin properties with proper type checking
43
- const defaultSchemaType = plugin.propPanel &&
44
- typeof plugin.propPanel === 'object' &&
45
- plugin.propPanel.defaultSchema &&
46
- typeof plugin.propPanel.defaultSchema === 'object' &&
47
- 'type' in plugin.propPanel.defaultSchema &&
48
- typeof plugin.propPanel.defaultSchema.type === 'string'
49
- ? plugin.propPanel.defaultSchema.type
43
+ const defaultSchemaType =
44
+ plugin.propPanel &&
45
+ typeof plugin.propPanel === 'object' &&
46
+ plugin.propPanel.defaultSchema &&
47
+ typeof plugin.propPanel.defaultSchema === 'object' &&
48
+ 'type' in plugin.propPanel.defaultSchema &&
49
+ typeof plugin.propPanel.defaultSchema.type === 'string'
50
+ ? plugin.propPanel.defaultSchema.type
50
51
  : '';
51
-
52
+
52
53
  const icon = options.icons?.[defaultSchemaType] ?? plugin.icon;
53
54
  const iconStyles = {
54
55
  ...styles,
@@ -1,4 +1,4 @@
1
- import { Button, Form } from 'antd';
1
+ import { Space, Button, Form } from 'antd';
2
2
  import React from 'react';
3
3
  import type { PropPanelWidgetProps } from '@pdfme/common';
4
4
  import {
@@ -24,34 +24,44 @@ const AlignWidget = (props: PropPanelWidgetProps) => {
24
24
  const tgtSize = isVertical ? 'width' : 'height';
25
25
  const isSingle = ass.length === 1;
26
26
  // Access pageSize property safely with proper type assertion
27
- const root = pageSize && typeof pageSize === 'object' ?
28
- (tgtSize === 'width' ?
29
- (pageSize as unknown as { width: number }).width :
30
- (pageSize as unknown as { height: number }).height) : 0;
27
+ const root =
28
+ pageSize && typeof pageSize === 'object'
29
+ ? tgtSize === 'width'
30
+ ? (pageSize as unknown as { width: number }).width
31
+ : (pageSize as unknown as { height: number }).height
32
+ : 0;
31
33
 
32
34
  // Access position properties safely with proper type assertion
33
- const min = isSingle ? 0 : Math.min(...ass.map((as) => {
34
- // Safely access position property with proper type assertion
35
- const position = as.position && typeof as.position === 'object' ?
36
- (as.position as unknown as { x: number; y: number }) :
37
- { x: 0, y: 0 };
38
- return tgtPos === 'x' ? position.x : position.y;
39
- }));
40
- const max = isSingle ? root : Math.max(...ass.map((as) => {
41
- // Safely access position and size properties with proper type assertion
42
- const position = as.position && typeof as.position === 'object' ?
43
- (as.position as unknown as { x: number; y: number }) :
44
- { x: 0, y: 0 };
45
- const posValue = tgtPos === 'x' ? position.x : position.y;
46
-
47
- // Safely access width/height with proper type assertion
48
- const asWithSize = as as unknown as { width?: number; height?: number };
49
- const sizeValue = tgtSize === 'width' ?
50
- (asWithSize.width || 0) :
51
- (asWithSize.height || 0);
52
-
53
- return posValue + sizeValue;
54
- }));
35
+ const min = isSingle
36
+ ? 0
37
+ : Math.min(
38
+ ...ass.map((as) => {
39
+ // Safely access position property with proper type assertion
40
+ const position =
41
+ as.position && typeof as.position === 'object'
42
+ ? (as.position as unknown as { x: number; y: number })
43
+ : { x: 0, y: 0 };
44
+ return tgtPos === 'x' ? position.x : position.y;
45
+ }),
46
+ );
47
+ const max = isSingle
48
+ ? root
49
+ : Math.max(
50
+ ...ass.map((as) => {
51
+ // Safely access position and size properties with proper type assertion
52
+ const position =
53
+ as.position && typeof as.position === 'object'
54
+ ? (as.position as unknown as { x: number; y: number })
55
+ : { x: 0, y: 0 };
56
+ const posValue = tgtPos === 'x' ? position.x : position.y;
57
+
58
+ // Safely access width/height with proper type assertion
59
+ const asWithSize = as as unknown as { width?: number; height?: number };
60
+ const sizeValue = tgtSize === 'width' ? asWithSize.width || 0 : asWithSize.height || 0;
61
+
62
+ return posValue + sizeValue;
63
+ }),
64
+ );
55
65
 
56
66
  let basePos = min;
57
67
  // Define adjust function with consistent parameter usage
@@ -70,10 +80,8 @@ const AlignWidget = (props: PropPanelWidgetProps) => {
70
80
  ass.map((as) => {
71
81
  // Safely access size property with proper type assertion
72
82
  const asWithSize = as as unknown as { width?: number; height?: number; id: string };
73
- const sizeValue = tgtSize === 'width' ?
74
- (asWithSize.width || 0) :
75
- (asWithSize.height || 0);
76
-
83
+ const sizeValue = tgtSize === 'width' ? asWithSize.width || 0 : asWithSize.height || 0;
84
+
77
85
  return {
78
86
  key: `position.${tgtPos}`,
79
87
  value: round(basePos - adjust(sizeValue), 2),
@@ -90,30 +98,34 @@ const AlignWidget = (props: PropPanelWidgetProps) => {
90
98
  const isVertical = type === 'vertical';
91
99
  const tgtPos = isVertical ? 'y' : 'x';
92
100
  const tgtSize = isVertical ? 'height' : 'width';
93
-
101
+
94
102
  // Safely access position property with proper type assertion
95
- const min = Math.min(...ass.map((as) => {
96
- const position = as.position && typeof as.position === 'object' ?
97
- (as.position as unknown as { x: number; y: number }) :
98
- { x: 0, y: 0 };
99
- return tgtPos === 'x' ? position.x : position.y;
100
- }));
101
-
103
+ const min = Math.min(
104
+ ...ass.map((as) => {
105
+ const position =
106
+ as.position && typeof as.position === 'object'
107
+ ? (as.position as unknown as { x: number; y: number })
108
+ : { x: 0, y: 0 };
109
+ return tgtPos === 'x' ? position.x : position.y;
110
+ }),
111
+ );
112
+
102
113
  // Safely access position and size properties with proper type assertion
103
- const max = Math.max(...ass.map((as) => {
104
- const position = as.position && typeof as.position === 'object' ?
105
- (as.position as unknown as { x: number; y: number }) :
106
- { x: 0, y: 0 };
107
- const posValue = tgtPos === 'x' ? position.x : position.y;
108
-
109
- // Safely access width/height with proper type assertion
110
- const asWithSize = as as unknown as { width?: number; height?: number };
111
- const sizeValue = tgtSize === 'width' ?
112
- (asWithSize.width || 0) :
113
- (asWithSize.height || 0);
114
-
115
- return posValue + sizeValue;
116
- }));
114
+ const max = Math.max(
115
+ ...ass.map((as) => {
116
+ const position =
117
+ as.position && typeof as.position === 'object'
118
+ ? (as.position as unknown as { x: number; y: number })
119
+ : { x: 0, y: 0 };
120
+ const posValue = tgtPos === 'x' ? position.x : position.y;
121
+
122
+ // Safely access width/height with proper type assertion
123
+ const asWithSize = as as unknown as { width?: number; height?: number };
124
+ const sizeValue = tgtSize === 'width' ? asWithSize.width || 0 : asWithSize.height || 0;
125
+
126
+ return posValue + sizeValue;
127
+ }),
128
+ );
117
129
 
118
130
  if (ass.length < 3) return;
119
131
 
@@ -122,9 +134,7 @@ const AlignWidget = (props: PropPanelWidgetProps) => {
122
134
  // Safely access size property with proper type assertion
123
135
  const sum = ass.reduce((acc, cur) => {
124
136
  const curWithSize = cur as unknown as { width?: number; height?: number };
125
- const sizeValue = tgtSize === 'width' ?
126
- (curWithSize.width || 0) :
127
- (curWithSize.height || 0);
137
+ const sizeValue = tgtSize === 'width' ? curWithSize.width || 0 : curWithSize.height || 0;
128
138
  return acc + sizeValue;
129
139
  }, 0);
130
140
  const remain = boxSize - sum;
@@ -134,16 +144,17 @@ const AlignWidget = (props: PropPanelWidgetProps) => {
134
144
  changeSchemas(
135
145
  ass.map((as, index) => {
136
146
  // Safely access size property of previous element with proper type assertion
137
- const prevSize = index === 0 ? 0 : (() => {
138
- const prevAs = ass[index - 1] as unknown as { width?: number; height?: number };
139
- return tgtSize === 'width' ?
140
- (prevAs.width || 0) :
141
- (prevAs.height || 0);
142
- })();
143
-
147
+ const prevSize =
148
+ index === 0
149
+ ? 0
150
+ : (() => {
151
+ const prevAs = ass[index - 1] as unknown as { width?: number; height?: number };
152
+ return tgtSize === 'width' ? prevAs.width || 0 : prevAs.height || 0;
153
+ })();
154
+
144
155
  prev += index === 0 ? 0 : prevSize + unit;
145
156
  const value = round(boxPos + prev, 2);
146
-
157
+
147
158
  // Safely access id with proper type assertion
148
159
  const asWithId = as as unknown as { id: string };
149
160
  return { key: `position.${tgtPos}`, value, schemaId: asWithId.id };
@@ -199,7 +210,7 @@ const AlignWidget = (props: PropPanelWidgetProps) => {
199
210
 
200
211
  return (
201
212
  <Form.Item label={schema.title}>
202
- <Button.Group>
213
+ <Space.Compact>
203
214
  {layoutBtns.map((btn) => (
204
215
  <Button
205
216
  key={btn.id}
@@ -208,7 +219,7 @@ const AlignWidget = (props: PropPanelWidgetProps) => {
208
219
  {...btn}
209
220
  />
210
221
  ))}
211
- </Button.Group>
222
+ </Space.Compact>
212
223
  </Form.Item>
213
224
  );
214
225
  };
@@ -1,4 +1,4 @@
1
- import { Button, Form, theme } from 'antd';
1
+ import { Space, Button, Form, theme } from 'antd';
2
2
  import React from 'react';
3
3
  import type { PropPanelWidgetProps, SchemaForUI } from '@pdfme/common';
4
4
  interface ButtonConfig {
@@ -35,9 +35,8 @@ const ButtonGroupWidget = (props: PropPanelWidgetProps) => {
35
35
  ass.forEach((s: SchemaForUI) => {
36
36
  // Cast schema to Record to safely access dynamic properties
37
37
  const schemaRecord = s as Record<string, unknown>;
38
- active = type === 'boolean'
39
- ? Boolean(schemaRecord[key] ?? false)
40
- : schemaRecord[key] === btn.value;
38
+ active =
39
+ type === 'boolean' ? Boolean(schemaRecord[key] ?? false) : schemaRecord[key] === btn.value;
41
40
  });
42
41
  return active;
43
42
  };
@@ -54,7 +53,7 @@ const ButtonGroupWidget = (props: PropPanelWidgetProps) => {
54
53
 
55
54
  return (
56
55
  <Form.Item>
57
- <Button.Group>
56
+ <Space.Compact>
58
57
  {(schema.buttons as ButtonConfig[]).map((btn: ButtonConfig, index: number) => {
59
58
  const active = isActive(btn);
60
59
  return (
@@ -71,7 +70,7 @@ const ButtonGroupWidget = (props: PropPanelWidgetProps) => {
71
70
  />
72
71
  );
73
72
  })}
74
- </Button.Group>
73
+ </Space.Compact>
75
74
  </Form.Item>
76
75
  );
77
76
  };