@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.
@@ -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
- declare const DetailView: (props: Pick<SidebarProps, 'size' | 'schemas' | 'pageSize' | 'changeSchemas' | 'activeElements' | 'deselectSchema'> & {
4
+ type DetailViewProps = Pick<SidebarProps, 'size' | 'schemas' | 'pageSize' | 'changeSchemas' | 'activeElements' | 'deselectSchema'> & {
5
5
  activeSchema: SchemaForUI;
6
- }) => React.JSX.Element;
7
- export default DetailView;
6
+ };
7
+ declare const _default: React.MemoExoticComponent<(props: DetailViewProps) => React.JSX.Element>;
8
+ export default _default;
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdfme/ui",
3
- "version": "4.2.2",
3
+ "version": "4.2.3-dev.3",
4
4
  "sideEffects": false,
5
5
  "author": "hand-dot",
6
6
  "license": "MIT",
@@ -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
- {plugin.propPanel.defaultSchema.icon ?
91
- <div dangerouslySetInnerHTML={{ __html: plugin.propPanel.defaultSchema.icon }} />
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
- const DetailView = (
17
- props: Pick<
18
- SidebarProps,
16
+ type DetailViewProps = Pick<SidebarProps,
19
17
  'size' | 'schemas' | 'pageSize' | 'changeSchemas' | 'activeElements' | 'deselectSchema'
20
- > & {
21
- activeSchema: SchemaForUI;
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
- useEffect(() => {
38
- const newWidgets: typeof widgets = {
39
- AlignWidget: (p) => <AlignWidget {...p} {...props} options={options} />,
40
- Divider: () => (
41
- <Divider style={{ marginTop: token.marginXS, marginBottom: token.marginXS }} />
42
- ),
43
- ButtonGroup: (p) => <ButtonGroupWidget {...p} {...props} options={options} />,
44
- };
45
- for (const plugin of Object.values(pluginsRegistry)) {
46
- const widgets = plugin?.propPanel.widgets || {};
47
- Object.entries(widgets).forEach(([widgetKey, widgetValue]) => {
48
- newWidgets[widgetKey] = (p) => (
49
- <WidgetRenderer
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 newSchema) {
52
+ for (let key in formSchema) {
81
53
  if (['id', 'content'].includes(key)) continue;
82
54
 
83
- // [position] Return the flattened position to its original form.
84
- if (key === 'x') key = 'position.x';
85
- if (key === 'y') key = 'position.y';
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 (newSchema[key] !== (activeSchema as any)[key]) {
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({ key, value, schemaId: activeSchema.id });
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={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
- export default DetailView;
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.assign(schema, propPanel?.defaultSchema || {});
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: {