@pdfme/ui 1.0.0-beta.9 → 1.0.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.
@@ -1,10 +1,10 @@
1
- import { Template, Size, UIProps, PreviewProps } from '@pdfme/common';
1
+ import { Template, Size, UIProps, UIOptions, PreviewProps } from '@pdfme/common';
2
2
  export declare abstract class BaseUIClass {
3
3
  protected domContainer: HTMLElement | null;
4
4
  protected template: Template;
5
5
  protected size: Size;
6
- private readonly lang;
7
- private readonly font;
6
+ private lang;
7
+ private font;
8
8
  private readonly setSize;
9
9
  constructor(props: UIProps);
10
10
  protected getI18n(): (key: "type" | "field" | "cancel" | "fieldName" | "require" | "uniq" | "inputExample" | "edit" | "plsSelect" | "plsInputName" | "plsAddNewField" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "goToFirst" | "goToPrevious" | "goToNext" | "goToEnd" | "select" | "errorOccurred" | "errorBulkUpdateFieldName" | "commitBulkUpdateFieldName" | "bulkUpdateFieldName") => string;
@@ -54,6 +54,7 @@ export declare abstract class BaseUIClass {
54
54
  basePdf: string | ArrayBuffer | Uint8Array;
55
55
  };
56
56
  updateTemplate(template: Template): void;
57
+ updateOptions(options: UIOptions): void;
57
58
  destroy(): void;
58
59
  protected abstract render(): void;
59
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdfme/ui",
3
- "version": "1.0.0-beta.9",
3
+ "version": "1.0.0",
4
4
  "author": "hand-dot",
5
5
  "license": "MIT",
6
6
  "description": "TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!",
@@ -31,7 +31,7 @@
31
31
  "dependencies": {
32
32
  "@dnd-kit/core": "^5.0.1",
33
33
  "@dnd-kit/sortable": "^6.0.0",
34
- "@pdfme/common": "^1.0.0-beta.7",
34
+ "@pdfme/common": "^1.0.0-beta.11",
35
35
  "@scena/react-guides": "^0.16.0",
36
36
  "hotkeys-js": "^3.8.7",
37
37
  "pdfjs-dist": "^2.12.313",
package/src/Designer.tsx CHANGED
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import ReactDOM from 'react-dom';
3
- import { Template, DesignerProps, checkDesignerProps } from '@pdfme/common';
3
+ import { Template, DesignerProps, checkDesignerProps, checkTemplate } from '@pdfme/common';
4
4
  import { BaseUIClass } from './class';
5
5
  import { DESTROYED_ERR_MSG } from './constants';
6
6
  import { I18nContext, FontContext } from './contexts';
@@ -26,6 +26,7 @@ class Designer extends BaseUIClass {
26
26
  }
27
27
 
28
28
  public updateTemplate(template: Template) {
29
+ checkTemplate(template);
29
30
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
30
31
  this.template = cloneDeep(template);
31
32
  if (this.onChangeTemplateCallback) {
package/src/class.ts CHANGED
@@ -8,9 +8,13 @@ import {
8
8
  Lang,
9
9
  Font,
10
10
  UIProps,
11
+ UIOptions,
11
12
  PreviewProps,
12
13
  getDefaultFont,
13
14
  checkUIProps,
15
+ checkTemplate,
16
+ checkInputs,
17
+ checkUIOptions,
14
18
  checkPreviewProps,
15
19
  } from '@pdfme/common';
16
20
 
@@ -57,9 +61,9 @@ export abstract class BaseUIClass {
57
61
 
58
62
  protected size!: Size;
59
63
 
60
- private readonly lang: Lang = DEFAULT_LANG;
64
+ private lang: Lang = DEFAULT_LANG;
61
65
 
62
- private readonly font: Font = getDefaultFont();
66
+ private font: Font = getDefaultFont();
63
67
 
64
68
  private readonly setSize = debounce(() => {
65
69
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
@@ -106,11 +110,26 @@ export abstract class BaseUIClass {
106
110
  }
107
111
 
108
112
  public updateTemplate(template: Template) {
113
+ checkTemplate(template);
109
114
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
115
+
110
116
  this.template = cloneDeep(template);
111
117
  this.render();
112
118
  }
113
119
 
120
+ public updateOptions(options: UIOptions) {
121
+ checkUIOptions(options);
122
+ const { lang, font } = options || {};
123
+
124
+ if (lang) {
125
+ this.lang = lang;
126
+ }
127
+ if (font) {
128
+ this.font = font;
129
+ }
130
+ this.render();
131
+ }
132
+
114
133
  public destroy() {
115
134
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
116
135
  ReactDOM.unmountComponentAtNode(this.domContainer);
@@ -138,6 +157,7 @@ export abstract class PreviewUI extends BaseUIClass {
138
157
 
139
158
  public setInputs(inputs: { [key: string]: string }[]) {
140
159
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
160
+ checkInputs(inputs);
141
161
  this.inputs = cloneDeep(inputs);
142
162
  this.render();
143
163
  }
@@ -309,7 +309,7 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
309
309
  onChangeHoveringSchemaId={onChangeHoveringSchemaId}
310
310
  editable={editing && activeElements.map((ae) => ae.id).includes(schema.id)}
311
311
  onChange={(value) => changeSchemas([{ key: 'data', value, schemaId: schema.id }])}
312
- border={hoveringSchemaId === schema.id ? '2px solid #18a0fb' : '1px dashed #4af'}
312
+ border={hoveringSchemaId === schema.id ? '1px solid #18a0fb' : '1px dashed #4af'}
313
313
  ref={inputRef}
314
314
  />
315
315
  )}
@@ -19,9 +19,9 @@ const DetailView = (
19
19
  return (
20
20
  <div>
21
21
  <div style={{ height: 40, display: 'flex', alignItems: 'center' }}>
22
- <p style={{ textAlign: 'center', width: '100%', fontWeight: 'bold' }}>
22
+ <span style={{ textAlign: 'center', width: '100%', fontWeight: 'bold' }}>
23
23
  {i18n('editField')}
24
- </p>
24
+ </span>
25
25
  </div>
26
26
  <Divider />
27
27
  <div style={{ fontSize: '0.9rem' }}>
@@ -33,9 +33,9 @@ const ListView = (
33
33
  return (
34
34
  <div>
35
35
  <div style={{ height: 40, display: 'flex', alignItems: 'center' }}>
36
- <p style={{ textAlign: 'center', width: '100%', fontWeight: 'bold' }}>
36
+ <span style={{ textAlign: 'center', width: '100%', fontWeight: 'bold' }}>
37
37
  {i18n('fieldsList')}
38
- </p>
38
+ </span>
39
39
  </div>
40
40
  <Divider />
41
41
  {isBulkUpdateFieldNamesMode ? (
@@ -48,10 +48,11 @@ const ListView = (
48
48
  height: height - 5,
49
49
  width: SIDEBAR_WIDTH,
50
50
  fontSize: '1rem',
51
- lineHeight: '2.25rem',
51
+ lineHeight: '2.5rem',
52
52
  background: 'transparent',
53
53
  margin: 0,
54
- padding: 0,
54
+ padding: '1rem',
55
+ boxSizing: 'border-box',
55
56
  fontFamily: 'inherit',
56
57
  }}
57
58
  ></textarea>
@@ -55,6 +55,7 @@ const Sidebar = (props: SidebarProps) => {
55
55
  padding: '0.5rem',
56
56
  cursor: 'pointer',
57
57
  background: '#eee',
58
+ width: 30,
58
59
  }}
59
60
  onClick={() => setOpen(!open)}
60
61
  >
@@ -75,6 +76,8 @@ const Sidebar = (props: SidebarProps) => {
75
76
  overflowY: 'auto',
76
77
  fontFamily: "'Open Sans', sans-serif",
77
78
  fontWeight: 400,
79
+ textAlign: 'left',
80
+ boxSizing: 'content-box',
78
81
  }}
79
82
  >
80
83
  {getActiveSchemas().length === 0 ? (
@@ -96,7 +99,6 @@ const Sidebar = (props: SidebarProps) => {
96
99
  <button
97
100
  style={{
98
101
  padding: '0.5rem',
99
- color: '#fff',
100
102
  background: '#18a0fb',
101
103
  border: 'none',
102
104
  borderRadius: 2,
@@ -104,7 +106,7 @@ const Sidebar = (props: SidebarProps) => {
104
106
  }}
105
107
  onClick={addSchema}
106
108
  >
107
- <strong>{i18n('addNewField')}</strong>
109
+ <strong style={{ color: '#fff' }}>{i18n('addNewField')}</strong>
108
110
  </button>
109
111
  </div>
110
112
  </div>
@@ -17,13 +17,13 @@ const Error = ({ size, error }: { size: Size; error: Error }) => {
17
17
  ...size,
18
18
  }}
19
19
  >
20
- <p style={{ color: '#fff', textAlign: 'center' }}>
20
+ <span style={{ color: '#fff', textAlign: 'center' }}>
21
21
  <span style={{ fontSize: 'large', fontWeight: 'bold', borderBottom: '1px solid #fff' }}>
22
22
  ERROR: {i18n('errorOccurred')}
23
23
  </span>
24
24
  <br />
25
25
  <span style={{ fontSize: 'small' }}>*{error.message}</span>
26
- </p>
26
+ </span>
27
27
  </div>
28
28
  );
29
29
  };
@@ -42,6 +42,16 @@ const Paper = (porps: {
42
42
  paperRefs.current[paperIndex] = e;
43
43
  }
44
44
  }}
45
+ onClick={(e) => {
46
+ if (
47
+ e.currentTarget === e.target &&
48
+ document &&
49
+ document.hasFocus() &&
50
+ document.activeElement instanceof HTMLElement
51
+ ) {
52
+ document.activeElement.blur();
53
+ }
54
+ }}
45
55
  style={{
46
56
  fontFamily: `'${getFallbackFontName(font)}'`,
47
57
  margin: `${RULER_HEIGHT * scale}px auto`,
@@ -80,7 +80,7 @@ const Preview = ({ template, inputs, size, onChangeInput }: PreviewReactProps) =
80
80
  backgrounds={backgrounds}
81
81
  renderSchema={({ schema, index }) => {
82
82
  const { key } = schema;
83
- const data = input[key] || '';
83
+ const data = (input && input[key]) || '';
84
84
  return (
85
85
  <SchemaUI
86
86
  key={schema.id}
@@ -41,7 +41,7 @@ const SampleBarcode = ({ schema }: { schema: BarcodeSchema }) => (
41
41
 
42
42
  const ErrorBarcode = () => (
43
43
  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
44
- <p
44
+ <span
45
45
  style={{
46
46
  color: 'white',
47
47
  background: 'red',
@@ -52,17 +52,23 @@ const ErrorBarcode = () => (
52
52
  }}
53
53
  >
54
54
  ERROR
55
- </p>
55
+ </span>
56
56
  </div>
57
57
  );
58
58
 
59
- const ErrorOrSampleBarcode = ({ schema, value }: { schema: BarcodeSchema; value: string }) =>
60
- validateBarcodeInput(schema.type as BarCodeType, value) ? (
59
+ const BarcodePreview = (props: { schema: BarcodeSchema; value: string }) => {
60
+ const { schema, value } = props;
61
+
62
+ if (value.length === 0) {
63
+ return null;
64
+ }
65
+
66
+ return validateBarcodeInput(schema.type as BarCodeType, value) ? (
61
67
  <SampleBarcode schema={schema} />
62
68
  ) : (
63
69
  <ErrorBarcode />
64
70
  );
65
-
71
+ };
66
72
  type Props = SchemaUIProps & { schema: BarcodeSchema };
67
73
 
68
74
  const BarcodeSchemaUI = (
@@ -95,6 +101,7 @@ const BarcodeSchemaUI = (
95
101
  display: 'flex',
96
102
  alignItems: 'center',
97
103
  justifyContent: 'center',
104
+ fontFamily: "'Open Sans', sans-serif",
98
105
  }}
99
106
  >
100
107
  {editable ? (
@@ -111,14 +118,7 @@ const BarcodeSchemaUI = (
111
118
  <span>{value}</span>
112
119
  </div>
113
120
  )}
114
-
115
- {value ? (
116
- <ErrorOrSampleBarcode value={value} schema={schema} />
117
- ) : editable ? (
118
- <SampleBarcode schema={schema} />
119
- ) : (
120
- <ErrorBarcode />
121
- )}
121
+ <BarcodePreview value={value} schema={schema} />
122
122
  </div>
123
123
  );
124
124
  };
@@ -17,19 +17,22 @@ const TextSchemaUI = (
17
17
  ref: Ref<HTMLTextAreaElement>
18
18
  ) => {
19
19
  const style: React.CSSProperties = {
20
+ padding: 0,
20
21
  resize: 'none',
22
+ position: 'absolute',
21
23
  fontFamily: schema.fontName ?? 'inherit',
22
24
  height: schema.height * ZOOM,
23
- width: schema.width * ZOOM,
25
+ // Increase the width by 1 point. (0.75 pixels)
26
+ width: (schema.width + (schema.characterSpacing ?? DEFAULT_CHARACTER_SPACING) * 0.75) * ZOOM,
24
27
  textAlign: schema.alignment ?? DEFAULT_ALIGNMENT,
25
28
  fontSize: `${schema.fontSize ?? DEFAULT_FONT_SIZE}pt`,
26
29
  letterSpacing: `${schema.characterSpacing ?? DEFAULT_CHARACTER_SPACING}pt`,
27
- fontFeatureSettings: `"palt"`,
28
30
  lineHeight: `${schema.lineHeight ?? DEFAULT_LINE_HEIGHT}em`,
29
31
  whiteSpace: 'pre-line',
30
32
  wordBreak: 'break-all',
31
33
  background: 'transparent',
32
34
  border: 'none',
35
+ outline: 'none',
33
36
  color: schema.fontColor ? schema.fontColor : DEFAULT_FONT_COLOR,
34
37
  };
35
38
 
package/src/helper.ts CHANGED
@@ -352,6 +352,7 @@ export const templateSchemas2SchemasList = async (_template: Template) => {
352
352
 
353
353
  export const fmtTemplate = (template: Template, schemasList: SchemaForUI[][]): Template => {
354
354
  const schemaAddedTemplate: Template = {
355
+ ...template,
355
356
  schemas: cloneDeep(schemasList).map((schema) =>
356
357
  schema.reduce((acc, cur) => {
357
358
  const k = cur.key;