@pdfme/ui 2.1.0 → 2.2.1

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.
Files changed (73) hide show
  1. package/README.md +7 -3
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.LICENSE.txt +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/types/builtInRenderer.d.ts +3 -0
  6. package/dist/types/class.d.ts +10 -1
  7. package/dist/types/components/CtlBar/Pager.d.ts +3 -2
  8. package/dist/types/components/CtlBar/Zoom.d.ts +3 -2
  9. package/dist/types/components/CtlBar/index.d.ts +3 -2
  10. package/dist/types/components/Designer/Main/Guides.d.ts +2 -2
  11. package/dist/types/components/Designer/Main/Mask.d.ts +2 -1
  12. package/dist/types/components/Designer/Main/Moveable.d.ts +1 -1
  13. package/dist/types/components/Designer/Main/Selecto.d.ts +2 -1
  14. package/dist/types/components/Designer/Sidebar/DetailView/BarCodePropEditor.d.ts +7 -0
  15. package/dist/types/components/Designer/Sidebar/DetailView/ExampleInputEditor.d.ts +2 -1
  16. package/dist/types/components/Designer/Sidebar/DetailView/FormComponents/ColorInputSet.d.ts +9 -0
  17. package/dist/types/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.d.ts +2 -1
  18. package/dist/types/components/Designer/Sidebar/DetailView/TextPropEditor.d.ts +2 -1
  19. package/dist/types/components/Designer/Sidebar/DetailView/TypeAndKeyEditor.d.ts +2 -1
  20. package/dist/types/components/Designer/Sidebar/DetailView/index.d.ts +3 -2
  21. package/dist/types/components/Designer/Sidebar/ListView/SelectableSortableContainer.d.ts +2 -1
  22. package/dist/types/components/Designer/Sidebar/ListView/SelectableSortableItem.d.ts +1 -1
  23. package/dist/types/components/Designer/Sidebar/ListView/index.d.ts +2 -1
  24. package/dist/types/components/Designer/Sidebar/index.d.ts +4 -2
  25. package/dist/types/components/Designer/index.d.ts +11 -2
  26. package/dist/types/components/Divider.d.ts +2 -1
  27. package/dist/types/components/Error.d.ts +2 -1
  28. package/dist/types/components/Paper.d.ts +2 -2
  29. package/dist/types/components/Preview.d.ts +2 -1
  30. package/dist/types/components/Renderer.d.ts +4 -0
  31. package/dist/types/components/Root.d.ts +1 -1
  32. package/dist/types/components/Spinner.d.ts +2 -1
  33. package/dist/types/components/UnitPager.d.ts +3 -2
  34. package/dist/types/contexts.d.ts +3 -1
  35. package/dist/types/helper.d.ts +5 -0
  36. package/dist/types/hooks.d.ts +2 -2
  37. package/dist/types/i18n.d.ts +4 -1
  38. package/dist/types/renders/barcodes.d.ts +2 -0
  39. package/dist/types/renders/image.d.ts +2 -0
  40. package/dist/types/renders/text.d.ts +2 -0
  41. package/dist/types/types.d.ts +25 -0
  42. package/package.json +2 -1
  43. package/src/Designer.tsx +21 -17
  44. package/src/Form.tsx +18 -14
  45. package/src/Viewer.tsx +6 -2
  46. package/src/builtInRenderer.ts +14 -0
  47. package/src/class.ts +22 -2
  48. package/src/components/Designer/Main/index.tsx +4 -15
  49. package/src/components/Designer/Sidebar/DetailView/BarCodePropEditor.tsx +81 -0
  50. package/src/components/Designer/Sidebar/DetailView/ExampleInputEditor.tsx +1 -2
  51. package/src/components/Designer/Sidebar/DetailView/FormComponents/ColorInputSet.tsx +50 -0
  52. package/src/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.tsx +1 -3
  53. package/src/components/Designer/Sidebar/DetailView/TextPropEditor.tsx +189 -209
  54. package/src/components/Designer/Sidebar/DetailView/index.tsx +16 -8
  55. package/src/components/Designer/Sidebar/index.tsx +3 -2
  56. package/src/components/Designer/index.tsx +1 -0
  57. package/src/components/Preview.tsx +6 -6
  58. package/src/components/Renderer.tsx +80 -0
  59. package/src/contexts.ts +5 -0
  60. package/src/helper.ts +8 -0
  61. package/src/i18n.ts +44 -1
  62. package/src/renders/barcodes.ts +117 -0
  63. package/src/renders/image.ts +101 -0
  64. package/src/renders/text.ts +138 -0
  65. package/src/types.ts +28 -0
  66. package/dist/types/components/Schemas/BarcodeSchema.d.ts +0 -15
  67. package/dist/types/components/Schemas/ImageSchema.d.ts +0 -15
  68. package/dist/types/components/Schemas/SchemaUI.d.ts +0 -15
  69. package/dist/types/components/Schemas/TextSchema.d.ts +0 -27
  70. package/src/components/Schemas/BarcodeSchema.tsx +0 -124
  71. package/src/components/Schemas/ImageSchema.tsx +0 -87
  72. package/src/components/Schemas/SchemaUI.tsx +0 -62
  73. package/src/components/Schemas/TextSchema.tsx +0 -117
package/src/class.ts CHANGED
@@ -1,7 +1,9 @@
1
+ import type { Renderer } from './types';
1
2
  import ReactDOM from 'react-dom';
2
3
  import { curriedI18n } from './i18n';
3
4
  import { DESTROYED_ERR_MSG, DEFAULT_LANG } from './constants';
4
5
  import { debounce, flatten, cloneDeep } from './helper';
6
+ import builtInRenderer from './builtInRenderer';
5
7
  import {
6
8
  Template,
7
9
  Size,
@@ -65,6 +67,10 @@ export abstract class BaseUIClass {
65
67
 
66
68
  private font: Font = getDefaultFont();
67
69
 
70
+ private rendererRegistry: Renderer = builtInRenderer;
71
+
72
+ private options = {};
73
+
68
74
  private readonly setSize = debounce(() => {
69
75
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
70
76
  this.size = {
@@ -79,22 +85,28 @@ export abstract class BaseUIClass {
79
85
  constructor(props: UIProps) {
80
86
  checkUIProps(props);
81
87
 
82
- const { domContainer, template, options } = props;
83
- const { lang, font } = options || {};
88
+ const { domContainer, template, options = {} } = props;
84
89
  this.domContainer = domContainer;
85
90
  this.template = generateColumnsAndSampledataIfNeeded(cloneDeep(template));
91
+ this.options = options;
86
92
  this.size = {
87
93
  height: this.domContainer!.clientHeight || window.innerHeight,
88
94
  width: this.domContainer!.clientWidth || window.innerWidth,
89
95
  };
90
96
  this.resizeObserver.observe(this.domContainer!);
91
97
 
98
+ const { lang, font } = options;
92
99
  if (lang) {
93
100
  this.lang = lang;
94
101
  }
95
102
  if (font) {
96
103
  this.font = font;
97
104
  }
105
+ // TODO: In the future, when we support custom schemas, we will create the registry using options.renderer instead of {}.
106
+ // if(renderer){
107
+ // this.renderer = Object.assign(this.renderer, renderer);;
108
+ // }
109
+
98
110
  }
99
111
 
100
112
  protected getI18n() {
@@ -105,6 +117,14 @@ export abstract class BaseUIClass {
105
117
  return this.font;
106
118
  }
107
119
 
120
+ protected getRendererRegistry() {
121
+ return this.rendererRegistry;
122
+ }
123
+
124
+ protected getOptions() {
125
+ return this.options;
126
+ }
127
+
108
128
  public getTemplate() {
109
129
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
110
130
 
@@ -6,7 +6,6 @@ import React, {
6
6
  useEffect,
7
7
  forwardRef,
8
8
  useCallback,
9
- useContext,
10
9
  } from 'react';
11
10
  import { OnDrag, OnResize, OnClick } from 'react-moveable';
12
11
  import { SchemaForUI, Size } from '@pdfme/common';
@@ -15,12 +14,11 @@ import { ZOOM, RULER_HEIGHT } from '../../../constants';
15
14
  import { usePrevious } from '../../../hooks';
16
15
  import { uuid, round, flatten } from '../../../helper';
17
16
  import Paper from '../../Paper';
18
- import SchemaUI from '../../Schemas/SchemaUI';
17
+ import Renderer from '../../Renderer';
19
18
  import Selecto from './Selecto';
20
19
  import Moveable from './Moveable';
21
20
  import Guides from './Guides';
22
21
  import Mask from './Mask';
23
- import { FontContext } from '../../../contexts';
24
22
 
25
23
  const DELETE_BTN_ID = uuid();
26
24
  const fmt4Num = (prop: string) => Number(prop.replace('px', ''));
@@ -96,11 +94,9 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
96
94
  } = props;
97
95
  const { onEdit, changeSchemas, removeSchemas, onChangeHoveringSchemaId, paperRefs } = props;
98
96
 
99
- const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);
100
97
  const verticalGuides = useRef<GuidesInterface[]>([]);
101
98
  const horizontalGuides = useRef<GuidesInterface[]>([]);
102
99
  const moveable = useRef<any>(null);
103
- const font = useContext(FontContext);
104
100
 
105
101
  const [isPressShiftKey, setIsPressShiftKey] = useState(false);
106
102
  const [editing, setEditing] = useState(false);
@@ -223,12 +219,6 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
223
219
  const onClickMoveable = (e: OnClick) => {
224
220
  e.inputEvent.stopPropagation();
225
221
  setEditing(true);
226
- const ic = inputRef.current;
227
- if (!ic) return;
228
- ic.focus();
229
- if (ic.type !== 'file') {
230
- ic.setSelectionRange(ic.value.length, ic.value.length);
231
- }
232
222
  };
233
223
 
234
224
  return (
@@ -319,17 +309,16 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
319
309
  </>
320
310
  )}
321
311
  renderSchema={({ schema }) => (
322
- <SchemaUI
312
+ <Renderer
323
313
  key={schema.id}
324
314
  schema={schema}
325
315
  onChangeHoveringSchemaId={onChangeHoveringSchemaId}
326
- editable={editing && activeElements.map((ae) => ae.id).includes(schema.id)}
316
+ mode={editing && activeElements.map((ae) => ae.id).includes(schema.id) ? 'form' : 'viewer'}
327
317
  onChange={(value) => {
328
318
  changeSchemas([{ key: 'data', value, schemaId: schema.id }]);
329
319
  }}
330
- onStopEditing={() => setEditing(false)}
320
+ stopEditing={() => setEditing(false)}
331
321
  outline={hoveringSchemaId === schema.id ? '1px solid #18a0fb' : '1px dashed #4af'}
332
- ref={inputRef}
333
322
  />
334
323
  )}
335
324
  />
@@ -0,0 +1,81 @@
1
+ import React, { CSSProperties, useContext } from 'react';
2
+ import {
3
+ SchemaForUI,
4
+ DEFAULT_FONT_COLOR,
5
+ DEFAULT_BARCODE_BG_COLOR,
6
+ DEFAULT_BARCODE_COLOR,
7
+ } from '@pdfme/common';
8
+ import { I18nContext } from '../../../../contexts';
9
+ import { SidebarProps } from '..';
10
+ import ColorInputSet from './FormComponents/ColorInputSet';
11
+
12
+ const BarcodePropEditor = (
13
+ props: Pick<SidebarProps, 'changeSchemas'> & { activeSchema: SchemaForUI }
14
+ ) => {
15
+ const i18n = useContext(I18nContext);
16
+ const { changeSchemas, activeSchema } = props;
17
+
18
+ if (activeSchema.type === 'text' || activeSchema.type === 'image') return <></>;
19
+
20
+ const barcodeHasText = activeSchema.type !== 'qrcode' && activeSchema.type !== 'gs1datamatrix';
21
+ const colorInputStyles: CSSProperties = {
22
+ width: barcodeHasText ? '30%' : '45%',
23
+ marginBottom: '10px',
24
+ };
25
+
26
+ return (
27
+ <section style={{ fontSize: '0.7rem' }}>
28
+ <div
29
+ style={{
30
+ marginBottom: '1rem',
31
+ display: 'flex',
32
+ alignItems: 'center',
33
+ justifyContent: 'space-between',
34
+ flexWrap: 'wrap',
35
+ }}
36
+ >
37
+ <ColorInputSet
38
+ label={i18n('barColor')}
39
+ value={activeSchema.barcolor ?? DEFAULT_BARCODE_COLOR}
40
+ onChange={(e) => {
41
+ changeSchemas([{ key: 'barcolor', value: e.target.value, schemaId: activeSchema.id }]);
42
+ }}
43
+ onClear={() =>
44
+ changeSchemas([
45
+ { key: 'barcolor', value: DEFAULT_FONT_COLOR, schemaId: activeSchema.id },
46
+ ])
47
+ }
48
+ extraStyle={colorInputStyles}
49
+ />
50
+
51
+ <ColorInputSet
52
+ label={i18n('bgColor')}
53
+ value={activeSchema.backgroundcolor ?? DEFAULT_BARCODE_BG_COLOR}
54
+ onChange={(e) => {
55
+ changeSchemas([{ key: 'backgroundcolor', value: e.target.value, schemaId: activeSchema.id }])
56
+ }}
57
+ onClear={() => {
58
+ changeSchemas([{ key: 'backgroundcolor', value: '', schemaId: activeSchema.id }])
59
+ }}
60
+ extraStyle={colorInputStyles}
61
+ />
62
+
63
+ {barcodeHasText && (
64
+ <ColorInputSet
65
+ label={i18n('textColor')}
66
+ value={activeSchema.textcolor ?? DEFAULT_FONT_COLOR}
67
+ onChange={(e) => {
68
+ changeSchemas([{ key: 'textcolor', value: e.target.value, schemaId: activeSchema.id }])
69
+ }}
70
+ onClear={() => {
71
+ changeSchemas([{ key: 'textcolor', value: '', schemaId: activeSchema.id }])
72
+ }}
73
+ extraStyle={colorInputStyles}
74
+ />
75
+ )}
76
+ </div>
77
+ </section>
78
+ );
79
+ };
80
+
81
+ export default BarcodePropEditor;
@@ -1,7 +1,7 @@
1
1
  import React, { useContext } from 'react';
2
2
  import { SchemaForUI } from '@pdfme/common';
3
3
  import { readFiles } from '../../../../helper';
4
- import { FontContext, I18nContext } from '../../../../contexts';
4
+ import { I18nContext } from '../../../../contexts';
5
5
  import { SidebarProps } from '..';
6
6
  import { XMarkIcon } from '@heroicons/react/24/outline';
7
7
 
@@ -10,7 +10,6 @@ const ExampleInputEditor = (
10
10
  ) => {
11
11
  const { changeSchemas, activeSchema } = props;
12
12
  const i18n = useContext(I18nContext);
13
- const fontData = useContext(FontContext);
14
13
 
15
14
  return (
16
15
  <div>
@@ -0,0 +1,50 @@
1
+ import React, { ChangeEvent, CSSProperties } from 'react';
2
+ import { XMarkIcon } from '@heroicons/react/24/outline';
3
+
4
+ const baseInputStyle: CSSProperties = {
5
+ color: '#333',
6
+ background: 'none',
7
+ borderRadius: 2,
8
+ border: '1px solid #767676',
9
+ };
10
+
11
+ const ColorInputSet = (props: {
12
+ label: string;
13
+ value: string;
14
+ onChange: (e: ChangeEvent<HTMLInputElement>) => void;
15
+ onClear: () => void;
16
+ extraStyle?: CSSProperties;
17
+ }) => {
18
+ const { label, value, onChange, onClear, extraStyle } = props;
19
+ const fieldId = 'input-' + label.replace(/\s/g, '');
20
+
21
+ return (
22
+ <div style={{ width: '45%', ...extraStyle }}>
23
+ <label htmlFor={fieldId}>{label}</label>
24
+ <div style={{ display: 'flex' }}>
25
+ <input
26
+ id={fieldId}
27
+ name={fieldId}
28
+ onChange={onChange}
29
+ value={value}
30
+ type="color"
31
+ style={{ ...baseInputStyle, width: '90%' }}
32
+ />
33
+ <button
34
+ onClick={onClear}
35
+ style={{
36
+ ...baseInputStyle,
37
+ display: 'flex',
38
+ alignItems: 'center',
39
+ justifyContent: 'center',
40
+ cursor: 'pointer',
41
+ }}
42
+ >
43
+ <XMarkIcon width={10} height={10} />
44
+ </button>
45
+ </div>
46
+ </div>
47
+ );
48
+ };
49
+
50
+ export default ColorInputSet;
@@ -1,8 +1,7 @@
1
- import React, { CSSProperties, useContext } from 'react';
1
+ import React, { CSSProperties } from 'react';
2
2
  import { SchemaForUI } from '@pdfme/common';
3
3
  import { round } from '../../../../helper';
4
4
  import { SidebarProps } from '../index';
5
- import { FontContext } from '../../../../contexts';
6
5
 
7
6
  const inputSetStyle: CSSProperties = { marginRight: '1rem', display: 'flex', alignItems: 'center' };
8
7
 
@@ -38,7 +37,6 @@ const PositionAndSizeEditor = (
38
37
  activeSchema: SchemaForUI;
39
38
  }
40
39
  ) => {
41
- const font = useContext(FontContext);
42
40
  const { changeSchemas, schemas, activeSchema, activeElements, pageSize } = props;
43
41
 
44
42
  const align = (type: 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom') => {