@pdfme/ui 5.3.11-dev.9 → 5.3.12
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 +8357 -8308
- package/dist/index.umd.js +114 -114
- package/dist/types/src/contexts.d.ts +1 -1
- package/package.json +3 -3
- package/src/components/AppContextProvider.tsx +8 -2
- package/src/components/Designer/Canvas/Moveable.tsx +8 -4
- package/src/components/Designer/Canvas/Selecto.tsx +4 -1
- package/src/components/Designer/Canvas/index.tsx +50 -18
- package/src/components/Designer/PluginIcon.tsx +10 -9
- package/src/components/Designer/RightSidebar/DetailView/AlignWidget.tsx +74 -63
- package/src/components/Designer/RightSidebar/DetailView/ButtonGroupWidget.tsx +2 -3
- package/src/components/Designer/RightSidebar/DetailView/index.tsx +147 -68
- package/src/components/Designer/RightSidebar/ListView/Item.tsx +89 -91
- package/src/components/Designer/RightSidebar/ListView/SelectableSortableContainer.tsx +18 -17
- package/src/components/Designer/RightSidebar/ListView/SelectableSortableItem.tsx +16 -15
- package/src/components/Designer/index.tsx +1 -1
- package/src/components/Preview.tsx +1 -1
- package/src/components/Renderer.tsx +2 -2
- package/src/contexts.ts +1 -1
- package/src/helper.ts +34 -29
@@ -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<
|
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.
|
3
|
+
"version": "5.3.12",
|
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
|
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(
|
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(
|
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, {
|
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, {
|
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,
|
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 = (
|
324
|
-
|
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
|
-
|
339
|
-
|
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
|
-
|
358
|
-
const
|
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] ===
|
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 =
|
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={(
|
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 ?
|
401
|
+
let newActiveElements: HTMLElement[] = isClick ? selected : [];
|
402
|
+
|
375
403
|
if (!isClick && added.length > 0) {
|
376
|
-
newActiveElements = activeElements.concat(added
|
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
|
-
|
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
|
-
|
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 =
|
44
|
-
|
45
|
-
plugin.propPanel
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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,
|
@@ -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 =
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
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(
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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(
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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 =
|
138
|
-
|
139
|
-
|
140
|
-
(
|
141
|
-
|
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 };
|
@@ -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 =
|
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
|
};
|