@pdfme/ui 5.4.6-dev.31 → 5.4.6-dev.33
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 +17775 -17705
- package/dist/index.umd.js +115 -115
- package/dist/types/src/components/Designer/RightSidebar/DetailView/index.d.ts +1 -1
- package/dist/types/src/types.d.ts +2 -1
- package/package.json +1 -1
- package/src/components/Designer/RightSidebar/DetailView/index.tsx +83 -5
- package/src/components/Designer/index.tsx +1 -0
- package/src/i18n.ts +11 -0
- package/src/types.ts +2 -1
|
@@ -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,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
|
@@ -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 } =
|
|
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: {
|
|
251
|
-
|
|
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] ?? []}
|
package/src/i18n.ts
CHANGED
|
@@ -34,6 +34,7 @@ const dictEn: { [key in keyof Dict]: string } = {
|
|
|
34
34
|
'validation.hexColor': 'Please enter a valid hex color code.',
|
|
35
35
|
'validation.uniqueName': 'Please enter a unique name.',
|
|
36
36
|
'validation.dateTimeFormat': 'Invalid date time format.',
|
|
37
|
+
'validation.outOfBounds': 'Exceeds page boundaries.',
|
|
37
38
|
'schemas.color': 'Color',
|
|
38
39
|
'schemas.borderWidth': 'Border Width',
|
|
39
40
|
'schemas.borderColor': 'Border Color',
|
|
@@ -112,6 +113,7 @@ const dictZh: { [key in keyof Dict]: string } = {
|
|
|
112
113
|
'validation.hexColor': '请输入有效的十六进制颜色代码。',
|
|
113
114
|
'validation.uniqueName': '请输入一个唯一的名称。',
|
|
114
115
|
'validation.dateTimeFormat': '日期时间格式无效。',
|
|
116
|
+
'validation.outOfBounds': '超出页面边界。',
|
|
115
117
|
'schemas.color': '颜色',
|
|
116
118
|
'schemas.borderWidth': '边框宽度',
|
|
117
119
|
'schemas.borderColor': '边框颜色',
|
|
@@ -189,6 +191,7 @@ const dictJa: { [key in keyof Dict]: string } = {
|
|
|
189
191
|
'validation.hexColor': '有効な16進数のカラーコードを入力してください。',
|
|
190
192
|
'validation.uniqueName': '一意の名前を入力してください。',
|
|
191
193
|
'validation.dateTimeFormat': '日付と時刻のフォーマットが無効です。',
|
|
194
|
+
'validation.outOfBounds': 'ページ境界を超えています。',
|
|
192
195
|
'schemas.color': '色',
|
|
193
196
|
'schemas.borderWidth': '枠線の太さ',
|
|
194
197
|
'schemas.borderColor': '枠線の色',
|
|
@@ -266,6 +269,7 @@ const dictKo: { [key in keyof Dict]: string } = {
|
|
|
266
269
|
'validation.hexColor': '유효한 16진수 색상 코드를 입력하세요.',
|
|
267
270
|
'validation.uniqueName': '고유한 이름을 입력하세요.',
|
|
268
271
|
'validation.dateTimeFormat': '날짜/시간 형식이 잘못되었습니다.',
|
|
272
|
+
'validation.outOfBounds': '페이지 경계를 초과합니다.',
|
|
269
273
|
'schemas.color': '색상',
|
|
270
274
|
'schemas.borderWidth': '테두리 너비',
|
|
271
275
|
'schemas.borderColor': '테두리 색상',
|
|
@@ -343,6 +347,7 @@ const dictAr: { [key in keyof Dict]: string } = {
|
|
|
343
347
|
'validation.hexColor': 'الرجاء إدخال رمز لون سداسي عشري صالح.',
|
|
344
348
|
'validation.uniqueName': 'الرجاء إدخال اسم فريد.',
|
|
345
349
|
'validation.dateTimeFormat': 'تنسيق التاريخ والوقت غير صالح.',
|
|
350
|
+
'validation.outOfBounds': 'يتجاوز حدود الصفحة.',
|
|
346
351
|
'schemas.color': 'اللون',
|
|
347
352
|
'schemas.borderWidth': 'عرض الحدود',
|
|
348
353
|
'schemas.borderColor': 'لون الحدود',
|
|
@@ -421,6 +426,7 @@ const dictTh: { [key in keyof Dict]: string } = {
|
|
|
421
426
|
'validation.hexColor': 'กรุณาใส่รหัสสีแบบฐานสิบหกที่ถูกต้อง',
|
|
422
427
|
'validation.uniqueName': 'กรุณาระบุชื่อที่ไม่ซ้ำ',
|
|
423
428
|
'validation.dateTimeFormat': 'รูปแบบวันที่และเวลาไม่ถูกต้อง',
|
|
429
|
+
'validation.outOfBounds': 'เกินขอบเขตหน้า',
|
|
424
430
|
'schemas.color': 'สี',
|
|
425
431
|
'schemas.borderWidth': 'ความกว้างของเส้นขอบ',
|
|
426
432
|
'schemas.borderColor': 'สีขอบ',
|
|
@@ -500,6 +506,7 @@ const dictIt: { [key in keyof Dict]: string } = {
|
|
|
500
506
|
'validation.hexColor': 'Inserisci un codice colore esadecimale valido.',
|
|
501
507
|
'validation.uniqueName': 'Inserisci un nome univoco.',
|
|
502
508
|
'validation.dateTimeFormat': 'Formato data-ora non valido.',
|
|
509
|
+
'validation.outOfBounds': 'Supera i limiti della pagina.',
|
|
503
510
|
'schemas.color': 'Colore',
|
|
504
511
|
'schemas.borderWidth': 'Spessore bordo',
|
|
505
512
|
'schemas.borderColor': 'Colore bordo',
|
|
@@ -578,6 +585,7 @@ const dictPl: { [key in keyof Dict]: string } = {
|
|
|
578
585
|
'validation.hexColor': 'Wprowadź poprawny kod koloru szesnastkowego.',
|
|
579
586
|
'validation.uniqueName': 'Proszę wpisać unikalną nazwę.',
|
|
580
587
|
'validation.dateTimeFormat': 'Nieprawidłowy format daty i godziny.',
|
|
588
|
+
'validation.outOfBounds': 'Przekracza granice strony.',
|
|
581
589
|
'schemas.color': 'Kolor',
|
|
582
590
|
'schemas.borderWidth': 'Szerokość obramowania',
|
|
583
591
|
'schemas.borderColor': 'Kolor obramowania',
|
|
@@ -657,6 +665,7 @@ const dictDe: { [key in keyof Dict]: string } = {
|
|
|
657
665
|
'validation.hexColor': 'Bitte geben Sie einen gültigen Hex-Farbcode ein.',
|
|
658
666
|
'validation.uniqueName': 'Bitte geben Sie einen eindeutigen Namen ein.',
|
|
659
667
|
'validation.dateTimeFormat': 'Ungültiges Datums- und Zeitformat.',
|
|
668
|
+
'validation.outOfBounds': 'Überschreitet die Seitengrenzen.',
|
|
660
669
|
'schemas.color': 'Farbe',
|
|
661
670
|
'schemas.borderWidth': 'Rahmenbreite',
|
|
662
671
|
'schemas.borderColor': 'Rahmenfarbe',
|
|
@@ -737,6 +746,7 @@ const dictEs: { [key in keyof Dict]: string } = {
|
|
|
737
746
|
'validation.hexColor': 'Introduce un código de color hexadecimal válido.',
|
|
738
747
|
'validation.uniqueName': 'Por favor, introduzca un nombre único.',
|
|
739
748
|
'validation.dateTimeFormat': 'Formato de fecha y hora no válido.',
|
|
749
|
+
'validation.outOfBounds': 'Excede los límites de la página.',
|
|
740
750
|
'schemas.color': 'Color',
|
|
741
751
|
'schemas.borderWidth': 'Ancho del borde',
|
|
742
752
|
'schemas.borderColor': 'Color del borde',
|
|
@@ -816,6 +826,7 @@ const dictFr: { [key in keyof Dict]: string } = {
|
|
|
816
826
|
'validation.hexColor': 'Veuillez entrer un code couleur hexadécimal valide.',
|
|
817
827
|
'validation.uniqueName': 'Veuillez saisir un nom unique.',
|
|
818
828
|
'validation.dateTimeFormat': "Format de date et d'heure non valide.",
|
|
829
|
+
'validation.outOfBounds': 'Dépasse les limites de la page.',
|
|
819
830
|
'schemas.color': 'Couleur',
|
|
820
831
|
'schemas.borderWidth': 'Largeur de la bordure',
|
|
821
832
|
'schemas.borderColor': 'Couleur de la bordure',
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SchemaForUI, Size, ChangeSchemas } from '@pdfme/common';
|
|
1
|
+
import type { SchemaForUI, Size, ChangeSchemas, BasePdf } from '@pdfme/common';
|
|
2
2
|
|
|
3
3
|
export type SidebarProps = {
|
|
4
4
|
height: number;
|
|
@@ -6,6 +6,7 @@ export type SidebarProps = {
|
|
|
6
6
|
onChangeHoveringSchemaId: (id: string | null) => void;
|
|
7
7
|
size: Size;
|
|
8
8
|
pageSize: Size;
|
|
9
|
+
basePdf: BasePdf;
|
|
9
10
|
activeElements: HTMLElement[];
|
|
10
11
|
schemas: SchemaForUI[];
|
|
11
12
|
schemasList: SchemaForUI[][];
|