@pdfme/ui 4.2.2 → 4.2.3-dev.3
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/README.md +27 -13
- package/dist/index.es.js +103 -92
- package/dist/index.umd.js +6 -6
- package/dist/types/class.d.ts +0 -3
- package/dist/types/components/Designer/RightSidebar/DetailView/index.d.ts +4 -3
- package/dist/types/helper.d.ts +0 -1
- package/package.json +1 -1
- package/src/components/Designer/LeftSidebar.tsx +6 -3
- package/src/components/Designer/RightSidebar/DetailView/index.tsx +61 -56
- package/src/helper.ts +6 -1
package/dist/types/class.d.ts
CHANGED
@@ -21,7 +21,6 @@ export declare abstract class BaseUIClass {
|
|
21
21
|
getTemplate(): import("zod").objectOutputType<{
|
22
22
|
schemas: import("zod").ZodArray<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{
|
23
23
|
type: import("zod").ZodString;
|
24
|
-
icon: import("zod").ZodOptional<import("zod").ZodString>;
|
25
24
|
content: import("zod").ZodOptional<import("zod").ZodString>;
|
26
25
|
position: import("zod").ZodObject<{
|
27
26
|
x: import("zod").ZodNumber;
|
@@ -40,7 +39,6 @@ export declare abstract class BaseUIClass {
|
|
40
39
|
readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
41
40
|
}, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
|
42
41
|
type: import("zod").ZodString;
|
43
|
-
icon: import("zod").ZodOptional<import("zod").ZodString>;
|
44
42
|
content: import("zod").ZodOptional<import("zod").ZodString>;
|
45
43
|
position: import("zod").ZodObject<{
|
46
44
|
x: import("zod").ZodNumber;
|
@@ -59,7 +57,6 @@ export declare abstract class BaseUIClass {
|
|
59
57
|
readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
60
58
|
}, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
|
61
59
|
type: import("zod").ZodString;
|
62
|
-
icon: import("zod").ZodOptional<import("zod").ZodString>;
|
63
60
|
content: import("zod").ZodOptional<import("zod").ZodString>;
|
64
61
|
position: import("zod").ZodObject<{
|
65
62
|
x: import("zod").ZodNumber;
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import type { SchemaForUI } from '@pdfme/common';
|
3
3
|
import type { SidebarProps } from '../../../../types';
|
4
|
-
|
4
|
+
type DetailViewProps = Pick<SidebarProps, 'size' | 'schemas' | 'pageSize' | 'changeSchemas' | 'activeElements' | 'deselectSchema'> & {
|
5
5
|
activeSchema: SchemaForUI;
|
6
|
-
}
|
7
|
-
|
6
|
+
};
|
7
|
+
declare const _default: React.MemoExoticComponent<(props: DetailViewProps) => React.JSX.Element>;
|
8
|
+
export default _default;
|
package/dist/types/helper.d.ts
CHANGED
@@ -36,7 +36,6 @@ export declare const template2SchemasList: (_template: Template) => Promise<{
|
|
36
36
|
key: string;
|
37
37
|
opacity?: number | undefined;
|
38
38
|
rotate?: number | undefined;
|
39
|
-
icon?: string | undefined;
|
40
39
|
content?: string | undefined;
|
41
40
|
readOnly?: boolean | undefined;
|
42
41
|
}[][]>;
|
package/package.json
CHANGED
@@ -8,7 +8,7 @@ import { theme, Button } from 'antd';
|
|
8
8
|
import { useDraggable } from '@dnd-kit/core';
|
9
9
|
import { CSS } from "@dnd-kit/utilities";
|
10
10
|
import Renderer from '../Renderer';
|
11
|
-
import { PluginsRegistry } from '../../contexts';
|
11
|
+
import { PluginsRegistry, OptionsContext } from '../../contexts';
|
12
12
|
|
13
13
|
const Draggable = (props: { plugin: Plugin<any>, scale: number, basePdf: BasePdf, children: React.ReactNode }) => {
|
14
14
|
const { scale, basePdf, plugin } = props;
|
@@ -44,6 +44,7 @@ const Draggable = (props: { plugin: Plugin<any>, scale: number, basePdf: BasePdf
|
|
44
44
|
const LeftSidebar = ({ height, scale, basePdf }: { height: number, scale: number, basePdf: BasePdf }) => {
|
45
45
|
const { token } = theme.useToken();
|
46
46
|
const pluginsRegistry = useContext(PluginsRegistry);
|
47
|
+
const options = useContext(OptionsContext);
|
47
48
|
|
48
49
|
const [isDragging, setIsDragging] = useState(false);
|
49
50
|
|
@@ -76,6 +77,8 @@ const LeftSidebar = ({ height, scale, basePdf }: { height: number, scale: number
|
|
76
77
|
>
|
77
78
|
{Object.entries(pluginsRegistry).map(([label, plugin]) => {
|
78
79
|
if (!plugin?.propPanel.defaultSchema) return null;
|
80
|
+
const icon = options.icons?.[plugin.propPanel.defaultSchema.type] ?? plugin.icon;
|
81
|
+
|
79
82
|
return <Draggable
|
80
83
|
key={label}
|
81
84
|
scale={scale}
|
@@ -87,8 +90,8 @@ const LeftSidebar = ({ height, scale, basePdf }: { height: number, scale: number
|
|
87
90
|
setIsDragging(true);
|
88
91
|
}}
|
89
92
|
style={{ width: 35, height: 35, marginTop: '0.25rem', padding: '0.25rem' }}>
|
90
|
-
{
|
91
|
-
<div dangerouslySetInnerHTML={{ __html:
|
93
|
+
{icon ?
|
94
|
+
<div dangerouslySetInnerHTML={{ __html: icon }} />
|
92
95
|
:
|
93
96
|
<div style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>{label}</div>
|
94
97
|
}
|
@@ -13,14 +13,13 @@ import { InternalNamePath, ValidateErrorEntity } from "rc-field-form/es/interfac
|
|
13
13
|
|
14
14
|
const { Text } = Typography;
|
15
15
|
|
16
|
-
|
17
|
-
props: Pick<
|
18
|
-
SidebarProps,
|
16
|
+
type DetailViewProps = Pick<SidebarProps,
|
19
17
|
'size' | 'schemas' | 'pageSize' | 'changeSchemas' | 'activeElements' | 'deselectSchema'
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
> & {
|
19
|
+
activeSchema: SchemaForUI;
|
20
|
+
};
|
21
|
+
|
22
|
+
const DetailView = (props: DetailViewProps) => {
|
24
23
|
const { token } = theme.useToken();
|
25
24
|
|
26
25
|
const { size, changeSchemas, deselectSchema, activeSchema, activeElements } = props;
|
@@ -34,62 +33,41 @@ const DetailView = (
|
|
34
33
|
[key: string]: (props: PropPanelWidgetProps) => React.JSX.Element;
|
35
34
|
}>({});
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
{...p}
|
51
|
-
{...props}
|
52
|
-
options={options}
|
53
|
-
theme={token}
|
54
|
-
i18n={i18n as (key: keyof Dict | string) => string}
|
55
|
-
widget={widgetValue}
|
56
|
-
/>
|
57
|
-
);
|
58
|
-
});
|
59
|
-
}
|
60
|
-
setWidgets(newWidgets);
|
61
|
-
}, [activeSchema, activeElements, pluginsRegistry, JSON.stringify(options)]);
|
62
|
-
|
63
|
-
useEffect(() => {
|
64
|
-
const values: any = { ...activeSchema };
|
65
|
-
|
66
|
-
// [position] Change the nested position object into a flat, as a three-column layout is difficult to implement
|
67
|
-
values.x = values.position.x;
|
68
|
-
values.y = values.position.y;
|
69
|
-
delete values.position;
|
70
|
-
|
71
|
-
if (values.key !== (form.getValues() || {}).key) {
|
72
|
-
form.resetFields();
|
36
|
+
const values: any = { ...activeSchema };
|
37
|
+
// [position] Change the nested position object into a flat, as a three-column layout is difficult to implement
|
38
|
+
values.x = values.position.x;
|
39
|
+
values.y = values.position.y;
|
40
|
+
delete values.position;
|
41
|
+
form.setValues(values);
|
42
|
+
|
43
|
+
const handleWatch = (formSchema: any) => {
|
44
|
+
const formAndSchemaValuesDiffer = (formValue: any, schemaValue: any): boolean => {
|
45
|
+
if (typeof formValue === 'object') {
|
46
|
+
return JSON.stringify(formValue) !== JSON.stringify(schemaValue);
|
47
|
+
}
|
48
|
+
return formValue !== schemaValue;
|
73
49
|
}
|
74
50
|
|
75
|
-
form.setValues(values);
|
76
|
-
}, [form, activeSchema]);
|
77
|
-
|
78
|
-
const handleWatch = (newSchema: any) => {
|
79
51
|
let changes: ChangeSchemaItem[] = [];
|
80
|
-
for (let key in
|
52
|
+
for (let key in formSchema) {
|
81
53
|
if (['id', 'content'].includes(key)) continue;
|
82
54
|
|
83
|
-
|
84
|
-
|
85
|
-
|
55
|
+
let value = formSchema[key];
|
56
|
+
let changed = false;
|
57
|
+
|
58
|
+
if (['x', 'y'].includes(key)) {
|
59
|
+
// [position] Return the flattened position to its original form.
|
60
|
+
changed = value !== (activeSchema as any)['position'][key];
|
61
|
+
key = 'position.' + key;
|
62
|
+
} else {
|
63
|
+
changed = formAndSchemaValuesDiffer(value, (activeSchema as any)[key]);
|
64
|
+
}
|
86
65
|
|
87
|
-
if (
|
88
|
-
let value = newSchema[key];
|
66
|
+
if (changed) {
|
89
67
|
// FIXME memo: https://github.com/pdfme/pdfme/pull/367#issuecomment-1857468274
|
90
68
|
if (value === null && ['rotate', 'opacity'].includes(key)) value = undefined;
|
91
69
|
|
92
|
-
changes.push({
|
70
|
+
changes.push({key, value, schemaId: activeSchema.id});
|
93
71
|
}
|
94
72
|
}
|
95
73
|
|
@@ -203,6 +181,29 @@ Check this document: https://pdfme.com/docs/custom-schemas`);
|
|
203
181
|
};
|
204
182
|
}
|
205
183
|
|
184
|
+
const allWidgets: typeof widgets = {
|
185
|
+
AlignWidget: (p) => <AlignWidget {...p} {...props} options={options} />,
|
186
|
+
Divider: () => (
|
187
|
+
<Divider style={{ marginTop: token.marginXS, marginBottom: token.marginXS }} />
|
188
|
+
),
|
189
|
+
ButtonGroup: (p) => <ButtonGroupWidget {...p} {...props} options={options} />,
|
190
|
+
};
|
191
|
+
for (const plugin of Object.values(pluginsRegistry)) {
|
192
|
+
const widgets = plugin?.propPanel.widgets || {};
|
193
|
+
Object.entries(widgets).forEach(([widgetKey, widgetValue]) => {
|
194
|
+
allWidgets[widgetKey] = (p) => (
|
195
|
+
<WidgetRenderer
|
196
|
+
{...p}
|
197
|
+
{...props}
|
198
|
+
options={options}
|
199
|
+
theme={token}
|
200
|
+
i18n={i18n as (key: keyof Dict | string) => string}
|
201
|
+
widget={widgetValue}
|
202
|
+
/>
|
203
|
+
);
|
204
|
+
});
|
205
|
+
}
|
206
|
+
|
206
207
|
return (
|
207
208
|
<div>
|
208
209
|
<div style={{ height: 40, display: 'flex', alignItems: 'center' }}>
|
@@ -232,7 +233,7 @@ Check this document: https://pdfme.com/docs/custom-schemas`);
|
|
232
233
|
<FormRender
|
233
234
|
form={form}
|
234
235
|
schema={propPanelSchema}
|
235
|
-
widgets={
|
236
|
+
widgets={allWidgets}
|
236
237
|
watch={{ '#': handleWatch }}
|
237
238
|
locale="en-US"
|
238
239
|
/>
|
@@ -241,4 +242,8 @@ Check this document: https://pdfme.com/docs/custom-schemas`);
|
|
241
242
|
);
|
242
243
|
};
|
243
244
|
|
244
|
-
|
245
|
+
const propsAreUnchanged = (prevProps: DetailViewProps, nextProps: DetailViewProps) => {
|
246
|
+
return JSON.stringify(prevProps.activeSchema) == JSON.stringify(nextProps.activeSchema)
|
247
|
+
};
|
248
|
+
|
249
|
+
export default React.memo(DetailView, propsAreUnchanged);
|
package/src/helper.ts
CHANGED
@@ -454,10 +454,15 @@ const handleTypeChange = (
|
|
454
454
|
delete schema[key as keyof typeof schema];
|
455
455
|
}
|
456
456
|
});
|
457
|
+
// Apply attributes from new defaultSchema
|
457
458
|
const propPanel = Object.values(pluginsRegistry).find(
|
458
459
|
(plugin) => plugin?.propPanel.defaultSchema.type === value
|
459
460
|
)?.propPanel;
|
460
|
-
Object.
|
461
|
+
Object.keys(propPanel?.defaultSchema || {}).forEach((key) => {
|
462
|
+
if (!schema.hasOwnProperty(key)) {
|
463
|
+
(schema as any)[key] = propPanel?.defaultSchema[key];
|
464
|
+
}
|
465
|
+
});
|
461
466
|
};
|
462
467
|
|
463
468
|
export const changeSchemas = (args: {
|