@pdfme/ui 5.4.6 → 5.4.7

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.
@@ -12,280 +12,63 @@ export declare abstract class BaseUIClass {
12
12
  constructor(props: UIProps);
13
13
  protected getLang(): "en" | "zh" | "ja" | "ko" | "ar" | "th" | "pl" | "it" | "de" | "es" | "fr";
14
14
  protected getFont(): Record<string, {
15
- data: string | ArrayBuffer | Uint8Array<ArrayBufferLike>;
15
+ data: string | ArrayBuffer | Uint8Array<ArrayBuffer>;
16
16
  fallback?: boolean | undefined;
17
17
  subset?: boolean | undefined;
18
18
  }>;
19
19
  protected getPluginsRegistry(): PluginRegistry;
20
20
  getOptions(): UIOptions;
21
- getTemplate(): import("zod").objectOutputType<{
22
- schemas: import("zod").ZodArray<import("zod").ZodArray<import("zod").ZodObject<{
23
- name: import("zod").ZodString;
24
- type: import("zod").ZodString;
25
- content: import("zod").ZodOptional<import("zod").ZodString>;
26
- position: import("zod").ZodObject<{
27
- x: import("zod").ZodNumber;
28
- y: import("zod").ZodNumber;
29
- }, "strip", import("zod").ZodTypeAny, {
21
+ getTemplate(): {
22
+ [x: string]: unknown;
23
+ schemas: {
24
+ [x: string]: unknown;
25
+ name: string;
26
+ type: string;
27
+ position: {
30
28
  x: number;
31
29
  y: number;
32
- }, {
33
- x: number;
34
- y: number;
35
- }>;
36
- width: import("zod").ZodNumber;
37
- height: import("zod").ZodNumber;
38
- rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
39
- opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
40
- readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
41
- required: import("zod").ZodOptional<import("zod").ZodBoolean>;
42
- __bodyRange: import("zod").ZodOptional<import("zod").ZodObject<{
43
- start: import("zod").ZodNumber;
44
- end: import("zod").ZodOptional<import("zod").ZodNumber>;
45
- }, "strip", import("zod").ZodTypeAny, {
46
- start: number;
47
- end?: number | undefined;
48
- }, {
49
- start: number;
50
- end?: number | undefined;
51
- }>>;
52
- __isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
53
- }, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
54
- name: import("zod").ZodString;
55
- type: import("zod").ZodString;
56
- content: import("zod").ZodOptional<import("zod").ZodString>;
57
- position: import("zod").ZodObject<{
58
- x: import("zod").ZodNumber;
59
- y: import("zod").ZodNumber;
60
- }, "strip", import("zod").ZodTypeAny, {
61
- x: number;
62
- y: number;
63
- }, {
64
- x: number;
65
- y: number;
66
- }>;
67
- width: import("zod").ZodNumber;
68
- height: import("zod").ZodNumber;
69
- rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
70
- opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
71
- readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
72
- required: import("zod").ZodOptional<import("zod").ZodBoolean>;
73
- __bodyRange: import("zod").ZodOptional<import("zod").ZodObject<{
74
- start: import("zod").ZodNumber;
75
- end: import("zod").ZodOptional<import("zod").ZodNumber>;
76
- }, "strip", import("zod").ZodTypeAny, {
77
- start: number;
78
- end?: number | undefined;
79
- }, {
80
- start: number;
81
- end?: number | undefined;
82
- }>>;
83
- __isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
84
- }, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
85
- name: import("zod").ZodString;
86
- type: import("zod").ZodString;
87
- content: import("zod").ZodOptional<import("zod").ZodString>;
88
- position: import("zod").ZodObject<{
89
- x: import("zod").ZodNumber;
90
- y: import("zod").ZodNumber;
91
- }, "strip", import("zod").ZodTypeAny, {
92
- x: number;
93
- y: number;
94
- }, {
95
- x: number;
96
- y: number;
97
- }>;
98
- width: import("zod").ZodNumber;
99
- height: import("zod").ZodNumber;
100
- rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
101
- opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
102
- readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
103
- required: import("zod").ZodOptional<import("zod").ZodBoolean>;
104
- __bodyRange: import("zod").ZodOptional<import("zod").ZodObject<{
105
- start: import("zod").ZodNumber;
106
- end: import("zod").ZodOptional<import("zod").ZodNumber>;
107
- }, "strip", import("zod").ZodTypeAny, {
108
- start: number;
109
- end?: number | undefined;
110
- }, {
111
- start: number;
112
- end?: number | undefined;
113
- }>>;
114
- __isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
115
- }, import("zod").ZodTypeAny, "passthrough">>, "many">, "many">;
116
- basePdf: import("zod").ZodUnion<[import("zod").ZodUnion<[import("zod").ZodString, import("zod").ZodType<ArrayBuffer, import("zod").ZodTypeDef, ArrayBuffer>, import("zod").ZodType<Uint8Array<ArrayBufferLike>, import("zod").ZodTypeDef, Uint8Array<ArrayBufferLike>>]>, import("zod").ZodObject<{
117
- width: import("zod").ZodNumber;
118
- height: import("zod").ZodNumber;
119
- padding: import("zod").ZodTuple<[import("zod").ZodNumber, import("zod").ZodNumber, import("zod").ZodNumber, import("zod").ZodNumber], null>;
120
- staticSchema: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
121
- name: import("zod").ZodString;
122
- type: import("zod").ZodString;
123
- content: import("zod").ZodOptional<import("zod").ZodString>;
124
- position: import("zod").ZodObject<{
125
- x: import("zod").ZodNumber;
126
- y: import("zod").ZodNumber;
127
- }, "strip", import("zod").ZodTypeAny, {
128
- x: number;
129
- y: number;
130
- }, {
131
- x: number;
132
- y: number;
133
- }>;
134
- width: import("zod").ZodNumber;
135
- height: import("zod").ZodNumber;
136
- rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
137
- opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
138
- readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
139
- required: import("zod").ZodOptional<import("zod").ZodBoolean>;
140
- __bodyRange: import("zod").ZodOptional<import("zod").ZodObject<{
141
- start: import("zod").ZodNumber;
142
- end: import("zod").ZodOptional<import("zod").ZodNumber>;
143
- }, "strip", import("zod").ZodTypeAny, {
144
- start: number;
145
- end?: number | undefined;
146
- }, {
147
- start: number;
148
- end?: number | undefined;
149
- }>>;
150
- __isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
151
- }, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
152
- name: import("zod").ZodString;
153
- type: import("zod").ZodString;
154
- content: import("zod").ZodOptional<import("zod").ZodString>;
155
- position: import("zod").ZodObject<{
156
- x: import("zod").ZodNumber;
157
- y: import("zod").ZodNumber;
158
- }, "strip", import("zod").ZodTypeAny, {
159
- x: number;
160
- y: number;
161
- }, {
162
- x: number;
163
- y: number;
164
- }>;
165
- width: import("zod").ZodNumber;
166
- height: import("zod").ZodNumber;
167
- rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
168
- opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
169
- readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
170
- required: import("zod").ZodOptional<import("zod").ZodBoolean>;
171
- __bodyRange: import("zod").ZodOptional<import("zod").ZodObject<{
172
- start: import("zod").ZodNumber;
173
- end: import("zod").ZodOptional<import("zod").ZodNumber>;
174
- }, "strip", import("zod").ZodTypeAny, {
175
- start: number;
176
- end?: number | undefined;
177
- }, {
178
- start: number;
179
- end?: number | undefined;
180
- }>>;
181
- __isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
182
- }, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
183
- name: import("zod").ZodString;
184
- type: import("zod").ZodString;
185
- content: import("zod").ZodOptional<import("zod").ZodString>;
186
- position: import("zod").ZodObject<{
187
- x: import("zod").ZodNumber;
188
- y: import("zod").ZodNumber;
189
- }, "strip", import("zod").ZodTypeAny, {
190
- x: number;
191
- y: number;
192
- }, {
193
- x: number;
194
- y: number;
195
- }>;
196
- width: import("zod").ZodNumber;
197
- height: import("zod").ZodNumber;
198
- rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
199
- opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
200
- readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
201
- required: import("zod").ZodOptional<import("zod").ZodBoolean>;
202
- __bodyRange: import("zod").ZodOptional<import("zod").ZodObject<{
203
- start: import("zod").ZodNumber;
204
- end: import("zod").ZodOptional<import("zod").ZodNumber>;
205
- }, "strip", import("zod").ZodTypeAny, {
206
- start: number;
207
- end?: number | undefined;
208
- }, {
209
- start: number;
210
- end?: number | undefined;
211
- }>>;
212
- __isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
213
- }, import("zod").ZodTypeAny, "passthrough">>, "many">>;
214
- }, "strip", import("zod").ZodTypeAny, {
30
+ };
215
31
  width: number;
216
32
  height: number;
217
- padding: [number, number, number, number];
218
- staticSchema?: import("zod").objectOutputType<{
219
- name: import("zod").ZodString;
220
- type: import("zod").ZodString;
221
- content: import("zod").ZodOptional<import("zod").ZodString>;
222
- position: import("zod").ZodObject<{
223
- x: import("zod").ZodNumber;
224
- y: import("zod").ZodNumber;
225
- }, "strip", import("zod").ZodTypeAny, {
226
- x: number;
227
- y: number;
228
- }, {
229
- x: number;
230
- y: number;
231
- }>;
232
- width: import("zod").ZodNumber;
233
- height: import("zod").ZodNumber;
234
- rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
235
- opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
236
- readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
237
- required: import("zod").ZodOptional<import("zod").ZodBoolean>;
238
- __bodyRange: import("zod").ZodOptional<import("zod").ZodObject<{
239
- start: import("zod").ZodNumber;
240
- end: import("zod").ZodOptional<import("zod").ZodNumber>;
241
- }, "strip", import("zod").ZodTypeAny, {
242
- start: number;
243
- end?: number | undefined;
244
- }, {
245
- start: number;
246
- end?: number | undefined;
247
- }>>;
248
- __isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
249
- }, import("zod").ZodTypeAny, "passthrough">[] | undefined;
250
- }, {
33
+ content?: string | undefined;
34
+ rotate?: number | undefined;
35
+ opacity?: number | undefined;
36
+ readOnly?: boolean | undefined;
37
+ required?: boolean | undefined;
38
+ __bodyRange?: {
39
+ start: number;
40
+ end?: number | undefined;
41
+ } | undefined;
42
+ __isSplit?: boolean | undefined;
43
+ }[][];
44
+ basePdf: string | ArrayBuffer | Uint8Array<ArrayBuffer> | {
251
45
  width: number;
252
46
  height: number;
253
47
  padding: [number, number, number, number];
254
- staticSchema?: import("zod").objectInputType<{
255
- name: import("zod").ZodString;
256
- type: import("zod").ZodString;
257
- content: import("zod").ZodOptional<import("zod").ZodString>;
258
- position: import("zod").ZodObject<{
259
- x: import("zod").ZodNumber;
260
- y: import("zod").ZodNumber;
261
- }, "strip", import("zod").ZodTypeAny, {
48
+ staticSchema?: {
49
+ [x: string]: unknown;
50
+ name: string;
51
+ type: string;
52
+ position: {
262
53
  x: number;
263
54
  y: number;
264
- }, {
265
- x: number;
266
- y: number;
267
- }>;
268
- width: import("zod").ZodNumber;
269
- height: import("zod").ZodNumber;
270
- rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
271
- opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
272
- readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
273
- required: import("zod").ZodOptional<import("zod").ZodBoolean>;
274
- __bodyRange: import("zod").ZodOptional<import("zod").ZodObject<{
275
- start: import("zod").ZodNumber;
276
- end: import("zod").ZodOptional<import("zod").ZodNumber>;
277
- }, "strip", import("zod").ZodTypeAny, {
278
- start: number;
279
- end?: number | undefined;
280
- }, {
55
+ };
56
+ width: number;
57
+ height: number;
58
+ content?: string | undefined;
59
+ rotate?: number | undefined;
60
+ opacity?: number | undefined;
61
+ readOnly?: boolean | undefined;
62
+ required?: boolean | undefined;
63
+ __bodyRange?: {
281
64
  start: number;
282
65
  end?: number | undefined;
283
- }>>;
284
- __isSplit: import("zod").ZodOptional<import("zod").ZodBoolean>;
285
- }, import("zod").ZodTypeAny, "passthrough">[] | undefined;
286
- }>]>;
287
- pdfmeVersion: import("zod").ZodOptional<import("zod").ZodString>;
288
- }, import("zod").ZodTypeAny, "passthrough">;
66
+ } | undefined;
67
+ __isSplit?: boolean | undefined;
68
+ }[] | undefined;
69
+ };
70
+ pdfmeVersion?: string | undefined;
71
+ };
289
72
  updateTemplate(template: Template): void;
290
73
  updateOptions(options: UIOptions): void;
291
74
  destroy(): void;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { SchemaForUI } from '@pdfme/common';
3
3
  import type { SidebarProps } from '../../../../types.js';
4
- type DetailViewProps = Pick<SidebarProps, 'size' | 'schemas' | 'schemasList' | 'pageSize' | 'changeSchemas' | 'activeElements' | 'deselectSchema'> & {
4
+ type DetailViewProps = Pick<SidebarProps, 'size' | 'schemas' | 'schemasList' | 'pageSize' | 'basePdf' | 'changeSchemas' | 'activeElements' | 'deselectSchema'> & {
5
5
  activeSchema: SchemaForUI;
6
6
  };
7
7
  declare const _default: React.MemoExoticComponent<(props: DetailViewProps) => React.JSX.Element>;
@@ -1,7 +1,7 @@
1
1
  import { PluginRegistry, UIOptions } from '@pdfme/common';
2
2
  export declare const I18nContext: import("react").Context<(key: keyof import("@pdfme/common").Dict, dict?: import("@pdfme/common").Dict) => string>;
3
3
  export declare const FontContext: import("react").Context<Record<string, {
4
- data: string | ArrayBuffer | Uint8Array<ArrayBufferLike>;
4
+ data: string | ArrayBuffer | Uint8Array<ArrayBuffer>;
5
5
  fallback?: boolean | undefined;
6
6
  subset?: boolean | undefined;
7
7
  }>>;
@@ -17,20 +17,20 @@ export declare const initShortCuts: (arg: {
17
17
  export declare const destroyShortCuts: () => void;
18
18
  export declare const arrayBufferToBase64: (arrayBuffer: ArrayBuffer) => string;
19
19
  export declare const template2SchemasList: (_template: Template) => Promise<{
20
- width: number;
21
- height: number;
22
- type: string;
23
20
  name: string;
21
+ type: string;
24
22
  position: {
25
23
  x: number;
26
24
  y: number;
27
25
  };
26
+ width: number;
27
+ height: number;
28
28
  id: string;
29
- opacity?: number | undefined;
30
- rotate?: number | undefined;
31
- required?: boolean | undefined;
32
29
  content?: string | undefined;
30
+ rotate?: number | undefined;
31
+ opacity?: number | undefined;
33
32
  readOnly?: boolean | undefined;
33
+ required?: boolean | undefined;
34
34
  __bodyRange?: {
35
35
  start: number;
36
36
  end?: number | undefined;
@@ -10,8 +10,8 @@ type UIPreProcessorProps = {
10
10
  export declare const useUIPreProcessor: ({ template, size, zoomLevel, maxZoom }: UIPreProcessorProps) => {
11
11
  backgrounds: string[];
12
12
  pageSizes: {
13
- width: number;
14
13
  height: number;
14
+ width: number;
15
15
  }[];
16
16
  scale: number;
17
17
  error: Error | null;
@@ -1,10 +1,11 @@
1
- import type { SchemaForUI, Size, ChangeSchemas } from '@pdfme/common';
1
+ import type { SchemaForUI, Size, ChangeSchemas, BasePdf } from '@pdfme/common';
2
2
  export type SidebarProps = {
3
3
  height: number;
4
4
  hoveringSchemaId: string | null;
5
5
  onChangeHoveringSchemaId: (id: string | null) => void;
6
6
  size: Size;
7
7
  pageSize: Size;
8
+ basePdf: BasePdf;
8
9
  activeElements: HTMLElement[];
9
10
  schemas: SchemaForUI[];
10
11
  schemasList: SchemaForUI[][];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdfme/ui",
3
- "version": "5.4.6",
3
+ "version": "5.4.7",
4
4
  "sideEffects": false,
5
5
  "author": "hand-dot",
6
6
  "license": "MIT",
@@ -40,12 +40,12 @@
40
40
  "@dnd-kit/sortable": "^10.0.0",
41
41
  "@pdfme/converter": "*",
42
42
  "@scena/react-guides": "^0.28.2",
43
- "antd": "^5.26.3",
44
- "dompurify": "^3.2.6",
43
+ "antd": "^5.27.4",
44
+ "dompurify": "^3.2.7",
45
45
  "form-render": "^2.5.5",
46
46
  "globrex": "^0.1.2",
47
- "hotkeys-js": "^3.13.14",
48
- "lucide-react": "^0.542.0",
47
+ "hotkeys-js": "^3.13.15",
48
+ "lucide-react": "^0.552.0",
49
49
  "react": "^16.14.0",
50
50
  "react-dom": "^16.14.0",
51
51
  "react-moveable": "^0.56.0",
@@ -57,14 +57,14 @@
57
57
  "@pdfme/schemas": "*",
58
58
  "@testing-library/jest-dom": "^6.8.0",
59
59
  "@testing-library/react": "^12.1.2",
60
- "@types/dompurify": "^3.0.5",
60
+ "@types/dompurify": "^3.2.0",
61
61
  "@types/jest": "^30.0.0",
62
62
  "@types/react": "^17.0.52",
63
63
  "@types/react-dom": "^17.0.18",
64
64
  "@ungap/structured-clone": "^1.3.0",
65
- "@vitejs/plugin-react": "^4.6.0",
65
+ "@vitejs/plugin-react": "^5.0.4",
66
66
  "csstype": "^3.1.2",
67
- "esbuild": "^0.25.9",
67
+ "esbuild": "^0.25.10",
68
68
  "eslint-plugin-react": "^7.37.5",
69
69
  "eslint-plugin-react-hooks": "^5.2.0",
70
70
  "is-path-inside": "^4.0.0",
@@ -73,7 +73,7 @@
73
73
  "postcss": "^8.5.6",
74
74
  "process": "^0.11.10",
75
75
  "rollup": "^4.44.1",
76
- "vite": "^7.1.4",
76
+ "vite": "^7.1.7",
77
77
  "vite-plugin-css-injected-by-js": "^3.3.0",
78
78
  "vite-tsconfig-paths": "^5.1.4"
79
79
  },
@@ -8,6 +8,7 @@ import type {
8
8
  PropPanelSchema,
9
9
  Schema,
10
10
  } from '@pdfme/common';
11
+ import { isBlankPdf } from '@pdfme/common';
11
12
  import type { SidebarProps } from '../../../../types.js';
12
13
  import { Menu } from 'lucide-react';
13
14
  import { I18nContext, PluginsRegistry, OptionsContext } from '../../../../contexts.js';
@@ -29,6 +30,7 @@ type DetailViewProps = Pick<
29
30
  | 'schemas'
30
31
  | 'schemasList'
31
32
  | 'pageSize'
33
+ | 'basePdf'
32
34
  | 'changeSchemas'
33
35
  | 'activeElements'
34
36
  | 'deselectSchema'
@@ -39,7 +41,8 @@ type DetailViewProps = Pick<
39
41
  const DetailView = (props: DetailViewProps) => {
40
42
  const { token } = theme.useToken();
41
43
 
42
- const { size, schemasList, changeSchemas, deselectSchema, activeSchema } = props;
44
+ const { size, schemasList, changeSchemas, deselectSchema, activeSchema, pageSize, basePdf } =
45
+ props;
43
46
  const form = useForm();
44
47
 
45
48
  const i18n = useContext(I18nContext);
@@ -116,6 +119,37 @@ const DetailView = (props: DetailViewProps) => {
116
119
  const validateUniqueSchemaName = (_: unknown, value: string): boolean =>
117
120
  uniqueSchemaName.current(value);
118
121
 
122
+ // Calculate padding values once
123
+ const [paddingTop, paddingRight, paddingBottom, paddingLeft] = isBlankPdf(basePdf)
124
+ ? basePdf.padding
125
+ : [0, 0, 0, 0];
126
+
127
+ // Cross-field validation: only checks when both fields are individually valid
128
+ const validatePosition = (_: unknown, value: number, fieldName: string): boolean => {
129
+ const formValues = form.getValues() as Record<string, unknown>;
130
+ const position = formValues.position as { x: number; y: number } | undefined;
131
+ const width = formValues.width as number | undefined;
132
+ const height = formValues.height as number | undefined;
133
+
134
+ if (!position || width === undefined || height === undefined) return true;
135
+
136
+ if (fieldName === 'x') {
137
+ if (value < paddingLeft || value > pageSize.width - paddingRight) return true;
138
+ if (width > 0 && value + width > pageSize.width - paddingRight) return false;
139
+ } else if (fieldName === 'y') {
140
+ if (value < paddingTop || value > pageSize.height - paddingBottom) return true;
141
+ if (height > 0 && value + height > pageSize.height - paddingBottom) return false;
142
+ } else if (fieldName === 'width') {
143
+ if (position.x < paddingLeft || position.x > pageSize.width - paddingRight) return true;
144
+ if (value > 0 && position.x + value > pageSize.width - paddingRight) return false;
145
+ } else if (fieldName === 'height') {
146
+ if (position.y < paddingTop || position.y > pageSize.height - paddingBottom) return true;
147
+ if (value > 0 && position.y + value > pageSize.height - paddingBottom) return false;
148
+ }
149
+
150
+ return true;
151
+ };
152
+
119
153
  // Use explicit type for debounce function that matches the expected signature
120
154
  const handleWatch = debounce(function (...args: unknown[]) {
121
155
  const formSchema = args[0] as Record<string, unknown>;
@@ -203,6 +237,10 @@ const DetailView = (props: DetailViewProps) => {
203
237
  })()
204
238
  : emptySchema;
205
239
 
240
+ // Calculate max values considering padding
241
+ const maxWidth = pageSize.width - paddingLeft - paddingRight;
242
+ const maxHeight = pageSize.height - paddingTop - paddingBottom;
243
+
206
244
  // Create a type-safe schema object
207
245
  const propPanelSchema: PropPanelSchema = {
208
246
  type: 'object',
@@ -247,8 +285,36 @@ const DetailView = (props: DetailViewProps) => {
247
285
  type: 'object',
248
286
  widget: 'card',
249
287
  properties: {
250
- x: { title: 'X', type: 'number', widget: 'inputNumber', required: true, span: 8, min: 0 },
251
- y: { title: 'Y', type: 'number', widget: 'inputNumber', required: true, span: 8, min: 0 },
288
+ x: {
289
+ title: 'X',
290
+ type: 'number',
291
+ widget: 'inputNumber',
292
+ required: true,
293
+ span: 8,
294
+ min: paddingLeft,
295
+ max: pageSize.width - paddingRight,
296
+ rules: [
297
+ {
298
+ validator: (_: unknown, value: number) => validatePosition(_, value, 'x'),
299
+ message: typedI18n('validation.outOfBounds'),
300
+ },
301
+ ],
302
+ },
303
+ y: {
304
+ title: 'Y',
305
+ type: 'number',
306
+ widget: 'inputNumber',
307
+ required: true,
308
+ span: 8,
309
+ min: paddingTop,
310
+ max: pageSize.height - paddingBottom,
311
+ rules: [
312
+ {
313
+ validator: (_: unknown, value: number) => validatePosition(_, value, 'y'),
314
+ message: typedI18n('validation.outOfBounds'),
315
+ },
316
+ ],
317
+ },
252
318
  },
253
319
  },
254
320
  width: {
@@ -257,7 +323,13 @@ const DetailView = (props: DetailViewProps) => {
257
323
  widget: 'inputNumber',
258
324
  required: true,
259
325
  span: 6,
260
- props: { min: 0 },
326
+ props: { min: 0, max: maxWidth },
327
+ rules: [
328
+ {
329
+ validator: (_: unknown, value: number) => validatePosition(_, value, 'width'),
330
+ message: typedI18n('validation.outOfBounds'),
331
+ },
332
+ ],
261
333
  },
262
334
  height: {
263
335
  title: typedI18n('height'),
@@ -265,7 +337,13 @@ const DetailView = (props: DetailViewProps) => {
265
337
  widget: 'inputNumber',
266
338
  required: true,
267
339
  span: 6,
268
- props: { min: 0 },
340
+ props: { min: 0, max: maxHeight },
341
+ rules: [
342
+ {
343
+ validator: (_: unknown, value: number) => validatePosition(_, value, 'height'),
344
+ message: typedI18n('validation.outOfBounds'),
345
+ },
346
+ ],
269
347
  },
270
348
  rotate: {
271
349
  title: typedI18n('rotate'),
@@ -339,6 +339,7 @@ const TemplateEditor = ({
339
339
  height={canvasRef.current ? canvasRef.current.clientHeight : 0}
340
340
  size={size}
341
341
  pageSize={pageSizes[pageCursor] ?? []}
342
+ basePdf={template.basePdf}
342
343
  activeElements={activeElements}
343
344
  schemasList={schemasList}
344
345
  schemas={schemasList[pageCursor] ?? []}
@@ -13,7 +13,7 @@ const Root = ({ size, scale, children }: Props, ref: Ref<HTMLDivElement>) => {
13
13
  if (!document || !document.fonts) return;
14
14
  const fontFaces = Object.entries(font).map(
15
15
  ([key, { data }]) =>
16
- new FontFace(key, typeof data === 'string' ? `url(${data})` : data, {
16
+ new FontFace(key, typeof data === 'string' ? `url(${data})` : (data as BufferSource), {
17
17
  display: 'swap',
18
18
  }),
19
19
  );
package/src/helper.ts CHANGED
@@ -308,13 +308,11 @@ export const template2SchemasList = async (_template: Template) => {
308
308
  const { width, height } = pageSizes[i];
309
309
  const xEdge = value.position.x + value.width;
310
310
  const yEdge = value.position.y + value.height;
311
- if (width < xEdge) {
312
- const diff = xEdge - width;
313
- value.position.x += diff;
311
+ if (xEdge > width) {
312
+ value.position.x = Math.max(0, width - value.width);
314
313
  }
315
- if (height < yEdge) {
316
- const diff = yEdge - height;
317
- value.position.y += diff;
314
+ if (yEdge > height) {
315
+ value.position.y = Math.max(0, height - value.height);
318
316
  }
319
317
  });
320
318