@pdfme/ui 2.0.1 → 2.1.0

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.
@@ -34,6 +34,7 @@ export declare abstract class BaseUIClass {
34
34
  dynamicFontSize?: {
35
35
  max: number;
36
36
  min: number;
37
+ fit?: string | undefined;
37
38
  } | undefined;
38
39
  } | {
39
40
  type: "image";
@@ -20,6 +20,7 @@ declare const TemplateEditor: ({ template, size, onSaveTemplate, onChangeTemplat
20
20
  dynamicFontSize?: {
21
21
  max: number;
22
22
  min: number;
23
+ fit?: string | undefined;
23
24
  } | undefined;
24
25
  } | {
25
26
  type: "image";
@@ -68,6 +69,7 @@ declare const TemplateEditor: ({ template, size, onSaveTemplate, onChangeTemplat
68
69
  dynamicFontSize?: {
69
70
  max: number;
70
71
  min: number;
72
+ fit?: string | undefined;
71
73
  } | undefined;
72
74
  } | {
73
75
  type: "image";
@@ -98,7 +100,7 @@ declare const TemplateEditor: ({ template, size, onSaveTemplate, onChangeTemplat
98
100
  fallback?: boolean | undefined;
99
101
  subset?: boolean | undefined;
100
102
  }> | undefined;
101
- lang?: "th" | "en" | "ja" | "ar" | undefined;
103
+ lang?: "th" | "en" | "ja" | "ar" | "pl" | undefined;
102
104
  } | undefined;
103
105
  } & {
104
106
  onChangeTemplate: (t: Template) => void;
@@ -1,6 +1,6 @@
1
1
  import { MutableRefObject, ReactNode } from 'react';
2
2
  import { SchemaForUI, Size } from '@pdfme/common';
3
- declare const Paper: (porps: {
3
+ declare const Paper: (props: {
4
4
  paperRefs: MutableRefObject<HTMLDivElement[]>;
5
5
  scale: number;
6
6
  size: Size;
@@ -4,6 +4,7 @@ export interface SchemaUIProps {
4
4
  schema: SchemaForUI;
5
5
  editable: boolean;
6
6
  onChange: (value: string) => void;
7
+ onStopEditing: () => void;
7
8
  tabIndex?: number;
8
9
  placeholder?: string;
9
10
  }
@@ -20,6 +20,7 @@ declare const _default: React.ForwardRefExoticComponent<SchemaUIProps & {
20
20
  dynamicFontSize?: {
21
21
  max: number;
22
22
  min: number;
23
+ fit?: string | undefined;
23
24
  } | undefined;
24
25
  };
25
26
  } & React.RefAttributes<HTMLTextAreaElement>>;
@@ -48,6 +48,7 @@ export declare const templateSchemas2SchemasList: (_template: Template) => Promi
48
48
  dynamicFontSize?: {
49
49
  max: number;
50
50
  min: number;
51
+ fit?: string | undefined;
51
52
  } | undefined;
52
53
  } | {
53
54
  type: "image";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdfme/ui",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "sideEffects": false,
5
5
  "author": "hand-dot",
6
6
  "license": "MIT",
@@ -41,7 +41,6 @@
41
41
  "@dnd-kit/core": "^5.0.1",
42
42
  "@dnd-kit/sortable": "^6.0.0",
43
43
  "@heroicons/react": "^2.0.13",
44
- "@pdfme/common": "file:../common",
45
44
  "@scena/react-guides": "^0.16.0",
46
45
  "hotkeys-js": "^3.8.7",
47
46
  "pdfjs-dist": "2.12.313",
@@ -51,6 +50,7 @@
51
50
  "react-selecto": "^1.12.0"
52
51
  },
53
52
  "devDependencies": {
53
+ "@pdfme/common": "file:../common",
54
54
  "@testing-library/jest-dom": "^5.16.1",
55
55
  "@testing-library/react": "^12.1.2",
56
56
  "@types/pdfjs-dist": "^2.10.378",
@@ -63,6 +63,9 @@
63
63
  "webpack": "^5.75.0",
64
64
  "webpack-cli": "^5.0.1"
65
65
  },
66
+ "peerDependencies": {
67
+ "@pdfme/common": "^2.1.0"
68
+ },
66
69
  "jest": {
67
70
  "setupFiles": [
68
71
  "jest-canvas-mock"
@@ -39,6 +39,7 @@ const DeleteButton = ({ activeElements: aes }: { activeElements: HTMLElement[] }
39
39
  zIndex: 1,
40
40
  top,
41
41
  left,
42
+ padding: 2,
42
43
  height: 24,
43
44
  width: 24,
44
45
  cursor: 'pointer',
@@ -52,7 +53,7 @@ const DeleteButton = ({ activeElements: aes }: { activeElements: HTMLElement[] }
52
53
  justifyContent: 'center',
53
54
  }}
54
55
  >
55
- <XMarkIcon width={10} height={10} />
56
+ <XMarkIcon style={{ pointerEvents: 'none' }} width={24} height={24} />
56
57
  </button>
57
58
  );
58
59
  };
@@ -110,7 +111,7 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
110
111
  if (e.shiftKey) setIsPressShiftKey(true);
111
112
  };
112
113
  const onKeyup = (e: KeyboardEvent) => {
113
- if (e.key === 'Shift') setIsPressShiftKey(false);
114
+ if (e.key === 'Shift' || !e.shiftKey) setIsPressShiftKey(false);
114
115
  if (e.key === 'Escape' || e.key === 'Esc') setEditing(false);
115
116
  };
116
117
 
@@ -195,14 +196,6 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
195
196
  changeSchemas(flatten(arg));
196
197
  };
197
198
 
198
- const currentlyEditingThisTextSchema = (target: EventTarget | null) => {
199
- if (!target) return false;
200
- if (target instanceof HTMLTextAreaElement) {
201
- return activeElements.map((ae) => ae.id).includes(target.parentElement?.id || '');
202
- }
203
- return false;
204
- }
205
-
206
199
  const onResize = ({ target, width, height, direction }: OnResize) => {
207
200
  if (!target) return;
208
201
  const s = target.style;
@@ -239,16 +232,7 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
239
232
  };
240
233
 
241
234
  return (
242
- <div
243
- ref={ref}
244
- onClick={(e) => {
245
- e.stopPropagation();
246
- if (!currentlyEditingThisTextSchema(e.target)) {
247
- setEditing(false);
248
- }
249
- }}
250
- style={{ overflow: 'overlay' }}
251
- >
235
+ <div ref={ref} style={{ overflow: 'overlay' }}>
252
236
  <Selecto
253
237
  container={paperRefs.current[pageCursor]}
254
238
  continueSelect={isPressShiftKey}
@@ -262,8 +246,7 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
262
246
  if (paperRefs.current[pageCursor] === inputEvent.target) {
263
247
  onEdit([]);
264
248
  }
265
-
266
- if (inputEvent.target.id === DELETE_BTN_ID) {
249
+ if (inputEvent.target?.id === DELETE_BTN_ID) {
267
250
  removeSchemas(activeElements.map((ae) => ae.id));
268
251
  }
269
252
  }}
@@ -276,8 +259,15 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
276
259
  if (!isClick && removed.length > 0) {
277
260
  newActiveElements = activeElements.filter((ae) => !removed.includes(ae));
278
261
  }
279
-
280
262
  onEdit(newActiveElements);
263
+
264
+ if (newActiveElements != activeElements) {
265
+ setEditing(false);
266
+ }
267
+ // For MacOS CMD+SHIFT+3/4 screenshots where the keydown event is never received, check mouse too
268
+ if (!inputEvent.shiftKey) {
269
+ setIsPressShiftKey(false);
270
+ }
281
271
  }}
282
272
  />
283
273
  <Paper
@@ -334,9 +324,10 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
334
324
  schema={schema}
335
325
  onChangeHoveringSchemaId={onChangeHoveringSchemaId}
336
326
  editable={editing && activeElements.map((ae) => ae.id).includes(schema.id)}
337
- onChange={async (value) => {
327
+ onChange={(value) => {
338
328
  changeSchemas([{ key: 'data', value, schemaId: schema.id }]);
339
329
  }}
330
+ onStopEditing={() => setEditing(false)}
340
331
  outline={hoveringSchemaId === schema.id ? '1px solid #18a0fb' : '1px dashed #4af'}
341
332
  ref={inputRef}
342
333
  />
@@ -6,6 +6,9 @@ import {
6
6
  DEFAULT_LINE_HEIGHT,
7
7
  DEFAULT_CHARACTER_SPACING,
8
8
  DEFAULT_FONT_COLOR,
9
+ DYNAMIC_FIT_VERTICAL,
10
+ DYNAMIC_FIT_HORIZONTAL,
11
+ DEFAULT_DYNAMIC_FIT,
9
12
  } from '@pdfme/common';
10
13
  import { FontContext } from '../../../../contexts';
11
14
  import { SidebarProps } from '..';
@@ -24,11 +27,14 @@ const NumberInputSet = (props: {
24
27
  width: string;
25
28
  label: string;
26
29
  value: number;
30
+ step?: number;
27
31
  minNumber?: number;
28
32
  maxNumber?: number;
33
+ disabled?: boolean;
34
+ style?: object;
29
35
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
30
36
  }) => {
31
- const { label, value, width, minNumber, maxNumber, onChange } = props;
37
+ const { label, step, value, width, minNumber, maxNumber, disabled, style, onChange } = props;
32
38
  const formattedLabel = label.replace(/\s/g, '');
33
39
 
34
40
  return (
@@ -37,10 +43,12 @@ const NumberInputSet = (props: {
37
43
  <input
38
44
  id={`input-${formattedLabel}`}
39
45
  name={`input-${formattedLabel}`}
40
- style={inputStyle}
46
+ style={{ ...inputStyle, ...style }}
41
47
  onChange={onChange}
42
- value={value}
48
+ value={isNaN(value) ? '' : value}
43
49
  type="number"
50
+ step={step ?? 1}
51
+ disabled={disabled}
44
52
  {...(minNumber && { min: minNumber })}
45
53
  {...(maxNumber && { max: maxNumber })}
46
54
  />
@@ -92,13 +100,14 @@ const SelectSet = (props: {
92
100
  label: string;
93
101
  value: string;
94
102
  options: string[];
103
+ width?: string;
95
104
  onChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;
96
105
  }) => {
97
- const { label, value, options, onChange } = props;
106
+ const { label, value, options, width, onChange } = props;
98
107
  const formattedLabel = label.replace(/\s/g, '');
99
108
 
100
109
  return (
101
- <div style={{ width: '45%' }}>
110
+ <div style={{ width: width ?? '45%' }}>
102
111
  <label htmlFor={`select-${formattedLabel}`}>{label}:</label>
103
112
  <select
104
113
  id={`select-${formattedLabel}`}
@@ -145,6 +154,7 @@ const TextPropEditor = (
145
154
  ) => {
146
155
  const { changeSchemas, activeSchema } = props;
147
156
  const alignments = ['left', 'center', 'right'];
157
+ const dynamicFits = [DYNAMIC_FIT_HORIZONTAL, DYNAMIC_FIT_VERTICAL];
148
158
  const font = useContext(FontContext);
149
159
  const fallbackFontName = getFallbackFontName(font);
150
160
 
@@ -189,26 +199,17 @@ const TextPropEditor = (
189
199
  <NumberInputSet
190
200
  width="30%"
191
201
  label={'FontSize(pt)'}
192
- value={activeSchema.fontSize ?? DEFAULT_FONT_SIZE}
202
+ value={activeSchema.dynamicFontSize ? NaN : (activeSchema.fontSize ?? DEFAULT_FONT_SIZE)}
203
+ style={activeSchema.dynamicFontSize ? { background: '#ccc', cursor: 'not-allowed' } : {}}
204
+ disabled={!!activeSchema.dynamicFontSize}
193
205
  onChange={(e) => {
194
- const currentFontSize = Number(e.target.value);
195
- const dynamincFontSizeMinAdjust = activeSchema.dynamicFontSize && activeSchema.dynamicFontSize.min > currentFontSize;
196
-
197
- changeSchemas([
198
- { key: 'fontSize', value: currentFontSize, schemaId: activeSchema.id },
199
- ...(dynamincFontSizeMinAdjust
200
- ? [{
201
- key: 'dynamicFontSize.min',
202
- value: currentFontSize,
203
- schemaId: activeSchema.id,
204
- }]
205
- : []),
206
- ]);
206
+ changeSchemas([{ key: 'fontSize', value: Number(e.target.value), schemaId: activeSchema.id }])
207
207
  }}
208
208
  />
209
209
  <NumberInputSet
210
210
  width="30%"
211
211
  label={'LineHeight(em)'}
212
+ step={0.1}
212
213
  value={activeSchema.lineHeight ?? DEFAULT_LINE_HEIGHT}
213
214
  onChange={(e) =>
214
215
  changeSchemas([
@@ -220,6 +221,7 @@ const TextPropEditor = (
220
221
  <NumberInputSet
221
222
  width="40%"
222
223
  label={'CharacterSpacing(pt)'}
224
+ step={0.1}
223
225
  value={activeSchema.characterSpacing ?? DEFAULT_CHARACTER_SPACING}
224
226
  onChange={async (e) => {
225
227
  const currentCharacterSpacing = Number(e.target.value);
@@ -257,26 +259,46 @@ const TextPropEditor = (
257
259
  {activeSchema.dynamicFontSize && (
258
260
  <>
259
261
  <NumberInputSet
260
- width="45%"
262
+ width="30%"
261
263
  label={'FontSize Min(pt)'}
262
264
  value={activeSchema.dynamicFontSize.min ?? Number(activeSchema.fontSize)}
263
265
  minNumber={0}
264
- maxNumber={activeSchema.fontSize}
266
+ style={
267
+ activeSchema.dynamicFontSize &&
268
+ activeSchema.dynamicFontSize.max < activeSchema.dynamicFontSize.min
269
+ ? { background: 'rgb(200 0 0 / 30%)' }
270
+ : {}
271
+ }
265
272
  onChange={(e) => {
266
273
  changeSchemas([{ key: 'dynamicFontSize.min', value: Number(e.target.value), schemaId: activeSchema.id }])
267
-
268
274
  }}
269
275
  />
270
276
 
271
277
  <NumberInputSet
272
- width="45%"
278
+ width="30%"
273
279
  label={'FontSize Max(pt)'}
274
280
  value={activeSchema.dynamicFontSize.max ?? Number(activeSchema.fontSize)}
275
- minNumber={activeSchema.fontSize}
281
+ minNumber={0}
282
+ style={
283
+ activeSchema.dynamicFontSize &&
284
+ activeSchema.dynamicFontSize.max < activeSchema.dynamicFontSize.min
285
+ ? { background: 'rgb(200 0 0 / 30%)' }
286
+ : {}
287
+ }
276
288
  onChange={(e) => {
277
289
  changeSchemas([{ key: 'dynamicFontSize.max', value: Number(e.target.value), schemaId: activeSchema.id }])
278
290
  }}
279
291
  />
292
+
293
+ <SelectSet
294
+ width="40%"
295
+ label={'Fit'}
296
+ value={activeSchema.dynamicFontSize.fit ?? DEFAULT_DYNAMIC_FIT}
297
+ options={dynamicFits}
298
+ onChange={(e) => {
299
+ changeSchemas([{ key: 'dynamicFontSize.fit', value: e.target.value, schemaId: activeSchema.id }])
300
+ }}
301
+ />
280
302
  </>
281
303
  )}
282
304
  </div>
@@ -3,7 +3,7 @@ import { SchemaForUI, Size, getFallbackFontName } from '@pdfme/common';
3
3
  import { FontContext } from '../contexts';
4
4
  import { ZOOM, RULER_HEIGHT } from '../constants';
5
5
 
6
- const Paper = (porps: {
6
+ const Paper = (props: {
7
7
  paperRefs: MutableRefObject<HTMLDivElement[]>;
8
8
  scale: number;
9
9
  size: Size;
@@ -14,7 +14,7 @@ const Paper = (porps: {
14
14
  renderSchema: (arg: { index: number; schema: SchemaForUI }) => ReactNode;
15
15
  }) => {
16
16
  const { paperRefs, scale, size, schemasList, pageSizes, backgrounds, renderPaper, renderSchema } =
17
- porps;
17
+ props;
18
18
  const font = useContext(FontContext);
19
19
 
20
20
  if (pageSizes.length !== backgrounds.length || pageSizes.length !== schemasList.length) {
@@ -100,8 +100,9 @@ const Preview = ({ template, inputs, size, onChangeInput }: PreviewReactProps) =
100
100
  key={schema.id}
101
101
  schema={Object.assign(schema, { data })}
102
102
  editable={editable}
103
- placeholder={template.sampledata ? template.sampledata[0][key] : ''}
103
+ placeholder={template.sampledata?.[0]?.[key] ?? ''}
104
104
  tabIndex={index + 100}
105
+ onStopEditing={() => { }}
105
106
  onChange={(value) => handleChangeInput({ key, value })}
106
107
  outline={editable ? '1px dashed #4af' : 'transparent'}
107
108
  />
@@ -69,7 +69,7 @@ const BarcodePreview = (props: { schema: BarcodeSchema; value: string }) => {
69
69
  type Props = SchemaUIProps & { schema: BarcodeSchema };
70
70
 
71
71
  const BarcodeSchemaUI = (
72
- { schema, editable, placeholder, tabIndex, onChange }: Props,
72
+ { schema, editable, placeholder, tabIndex, onChange, onStopEditing }: Props,
73
73
  ref: Ref<HTMLInputElement>
74
74
  ) => {
75
75
  const value = schema.data;
@@ -109,6 +109,7 @@ const BarcodeSchemaUI = (
109
109
  style={style}
110
110
  value={value}
111
111
  onChange={(e) => onChange(e.target.value)}
112
+ onBlur={onStopEditing}
112
113
  />
113
114
  ) : (
114
115
  <div style={style}>
@@ -8,7 +8,7 @@ import { XMarkIcon } from '@heroicons/react/24/outline';
8
8
  type Props = SchemaUIProps & { schema: ImageSchema };
9
9
 
10
10
  const ImageSchemaUI = (props: Props, ref: Ref<HTMLInputElement>) => {
11
- const { editable, placeholder, tabIndex, schema, onChange } = props;
11
+ const { editable, placeholder, tabIndex, schema, onChange, onStopEditing } = props;
12
12
  const [fileName, setFileName] = useState<string>('');
13
13
  const hasData = Boolean(schema.data);
14
14
 
@@ -75,6 +75,7 @@ const ImageSchemaUI = (props: Props, ref: Ref<HTMLInputElement>) => {
75
75
  onChange={(event: ChangeEvent<HTMLInputElement>) =>
76
76
  readFiles(event.target.files, 'dataURL').then((result) => onChange(result as string))
77
77
  }
78
+ onBlur={onStopEditing}
78
79
  type="file"
79
80
  accept="image/jpeg, image/png"
80
81
  />
@@ -9,6 +9,7 @@ export interface SchemaUIProps {
9
9
  schema: SchemaForUI;
10
10
  editable: boolean;
11
11
  onChange: (value: string) => void;
12
+ onStopEditing: () => void;
12
13
  tabIndex?: number;
13
14
  placeholder?: string;
14
15
  }
@@ -17,7 +17,7 @@ import { FontContext } from '../../contexts';
17
17
  type Props = SchemaUIProps & { schema: TextSchema };
18
18
 
19
19
  const TextSchemaUI = (
20
- { schema, editable, placeholder, tabIndex, onChange }: Props,
20
+ { schema, editable, placeholder, tabIndex, onChange, onStopEditing }: Props,
21
21
  ref: Ref<HTMLTextAreaElement>
22
22
  ) => {
23
23
  const font = useContext(FontContext);
@@ -27,15 +27,45 @@ const TextSchemaUI = (
27
27
 
28
28
  useEffect(() => {
29
29
  if (schema.dynamicFontSize && schema.data) {
30
- calculateDynamicFontSize({ textSchema: schema, font, input: schema.data }).then(setDynamicFontSize)
30
+ calculateDynamicFontSize({
31
+ textSchema: schema,
32
+ font,
33
+ input: schema.data,
34
+ startingFontSize: dynamicFontSize,
35
+ }).then(setDynamicFontSize);
31
36
  } else {
32
37
  setDynamicFontSize(undefined);
33
38
  }
39
+ }, [
40
+ schema.data,
41
+ schema.width,
42
+ schema.height,
43
+ schema.dynamicFontSize?.min,
44
+ schema.dynamicFontSize?.max,
45
+ schema.dynamicFontSize?.fit,
46
+ schema.characterSpacing,
47
+ schema.lineHeight,
48
+ font
49
+ ]);
50
+
51
+ useEffect(() => {
34
52
  getFontKitFont(schema, font).then(fontKitFont => {
35
53
  const fav = getFontAlignmentValue(fontKitFont, dynamicFontSize ?? schema.fontSize ?? DEFAULT_FONT_SIZE);
36
54
  setFontAlignmentValue(fav);
37
55
  });
38
- }, [schema.data, schema.width, schema.fontName, schema.fontSize, schema.dynamicFontSize, schema.dynamicFontSize?.max, schema.dynamicFontSize?.min, schema.characterSpacing, font]);
56
+ }, [
57
+ schema.width,
58
+ schema.height,
59
+ schema.fontName,
60
+ schema.fontSize,
61
+ schema.dynamicFontSize?.max,
62
+ schema.dynamicFontSize?.min,
63
+ schema.dynamicFontSize?.fit,
64
+ schema.characterSpacing,
65
+ schema.lineHeight,
66
+ font,
67
+ dynamicFontSize
68
+ ]);
39
69
 
40
70
 
41
71
  const style: React.CSSProperties = {
@@ -53,7 +83,7 @@ const TextSchemaUI = (
53
83
  letterSpacing: `${schema.characterSpacing ?? DEFAULT_CHARACTER_SPACING}pt`,
54
84
  lineHeight: `${schema.lineHeight ?? DEFAULT_LINE_HEIGHT}em`,
55
85
  textAlign: schema.alignment ?? DEFAULT_ALIGNMENT,
56
- whiteSpace: 'pre-line',
86
+ whiteSpace: 'pre-wrap',
57
87
  wordBreak: 'break-word',
58
88
  backgroundColor:
59
89
  schema.data && schema.backgroundColor ? schema.backgroundColor : 'rgb(242 244 255 / 75%)',
@@ -67,6 +97,7 @@ const TextSchemaUI = (
67
97
  tabIndex={tabIndex}
68
98
  style={style}
69
99
  onChange={(e) => onChange(e.target.value)}
100
+ onBlur={onStopEditing}
70
101
  value={schema.data}
71
102
  ></textarea>
72
103
  ) : (
package/src/helper.ts CHANGED
@@ -314,7 +314,7 @@ const sortSchemasList = (template: Template, pageNum: number): SchemaForUI[][] =
314
314
  })
315
315
  .map((e) => {
316
316
  const [key, value] = e;
317
- const data = template.sampledata ? template.sampledata[0][key] : '';
317
+ const data = template.sampledata?.[0]?.[key] ?? '';
318
318
 
319
319
  return Object.assign(value, {
320
320
  key,
package/src/i18n.ts CHANGED
@@ -91,8 +91,33 @@ const dictTh: { [key in keyof DictEn]: string } = {
91
91
  bulkUpdateFieldName: 'แก้ไขชื่อฟิลด์เป็นชุด',
92
92
  };
93
93
 
94
+ const dictPl: {[key in keyof DictEn]: string} = {
95
+ cancel: 'Anuluj',
96
+ field: 'pole',
97
+ fieldName: 'Klucz pola',
98
+ require: 'wymagany',
99
+ uniq: 'unikalny',
100
+ inputExample: 'Przykład',
101
+ edit: 'Edytuj',
102
+ plsInputName: 'Wymagane wprowadzenie klucza pola',
103
+ fieldMustUniq: 'Klucz pola nie jest unikalny',
104
+ notUniq: '(Klucz pola nie jest unikalny)',
105
+ noKeyName: 'Brak nazwy klucza pola',
106
+ fieldsList: 'Lista pól',
107
+ addNewField: 'Dodaj nowe pole',
108
+ editField: 'Edytuj pole',
109
+ type: 'Typ pola',
110
+ errorOccurred: 'Wystąpił błąd',
111
+ errorBulkUpdateFieldName:
112
+ 'Nie można wprowadzić zmian ponieważ liczba elementów uległa zmianie.',
113
+ commitBulkUpdateFieldName: 'Zaakceptuj zmiany',
114
+ bulkUpdateFieldName: 'Masowo aktualizuj klucze pól',
115
+ }
116
+
94
117
  const i18n = (lang: Lang, key: keyof DictEn) => {
95
118
  switch (lang) {
119
+ case 'pl':
120
+ return dictPl[key];
96
121
  case 'th':
97
122
  return dictTh[key];
98
123