@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.
- package/README.md +7 -3
- package/dist/index.js +1 -1
- package/dist/index.js.LICENSE.txt +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/builtInRenderer.d.ts +3 -0
- package/dist/types/class.d.ts +10 -1
- package/dist/types/components/CtlBar/Pager.d.ts +3 -2
- package/dist/types/components/CtlBar/Zoom.d.ts +3 -2
- package/dist/types/components/CtlBar/index.d.ts +3 -2
- package/dist/types/components/Designer/Main/Guides.d.ts +2 -2
- package/dist/types/components/Designer/Main/Mask.d.ts +2 -1
- package/dist/types/components/Designer/Main/Moveable.d.ts +1 -1
- package/dist/types/components/Designer/Main/Selecto.d.ts +2 -1
- package/dist/types/components/Designer/Sidebar/DetailView/BarCodePropEditor.d.ts +7 -0
- package/dist/types/components/Designer/Sidebar/DetailView/ExampleInputEditor.d.ts +2 -1
- package/dist/types/components/Designer/Sidebar/DetailView/FormComponents/ColorInputSet.d.ts +9 -0
- package/dist/types/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.d.ts +2 -1
- package/dist/types/components/Designer/Sidebar/DetailView/TextPropEditor.d.ts +2 -1
- package/dist/types/components/Designer/Sidebar/DetailView/TypeAndKeyEditor.d.ts +2 -1
- package/dist/types/components/Designer/Sidebar/DetailView/index.d.ts +3 -2
- package/dist/types/components/Designer/Sidebar/ListView/SelectableSortableContainer.d.ts +2 -1
- package/dist/types/components/Designer/Sidebar/ListView/SelectableSortableItem.d.ts +1 -1
- package/dist/types/components/Designer/Sidebar/ListView/index.d.ts +2 -1
- package/dist/types/components/Designer/Sidebar/index.d.ts +4 -2
- package/dist/types/components/Designer/index.d.ts +11 -2
- package/dist/types/components/Divider.d.ts +2 -1
- package/dist/types/components/Error.d.ts +2 -1
- package/dist/types/components/Paper.d.ts +2 -2
- package/dist/types/components/Preview.d.ts +2 -1
- package/dist/types/components/Renderer.d.ts +4 -0
- package/dist/types/components/Root.d.ts +1 -1
- package/dist/types/components/Spinner.d.ts +2 -1
- package/dist/types/components/UnitPager.d.ts +3 -2
- package/dist/types/contexts.d.ts +3 -1
- package/dist/types/helper.d.ts +5 -0
- package/dist/types/hooks.d.ts +2 -2
- package/dist/types/i18n.d.ts +4 -1
- package/dist/types/renders/barcodes.d.ts +2 -0
- package/dist/types/renders/image.d.ts +2 -0
- package/dist/types/renders/text.d.ts +2 -0
- package/dist/types/types.d.ts +25 -0
- package/package.json +2 -1
- package/src/Designer.tsx +21 -17
- package/src/Form.tsx +18 -14
- package/src/Viewer.tsx +6 -2
- package/src/builtInRenderer.ts +14 -0
- package/src/class.ts +22 -2
- package/src/components/Designer/Main/index.tsx +4 -15
- package/src/components/Designer/Sidebar/DetailView/BarCodePropEditor.tsx +81 -0
- package/src/components/Designer/Sidebar/DetailView/ExampleInputEditor.tsx +1 -2
- package/src/components/Designer/Sidebar/DetailView/FormComponents/ColorInputSet.tsx +50 -0
- package/src/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.tsx +1 -3
- package/src/components/Designer/Sidebar/DetailView/TextPropEditor.tsx +189 -209
- package/src/components/Designer/Sidebar/DetailView/index.tsx +16 -8
- package/src/components/Designer/Sidebar/index.tsx +3 -2
- package/src/components/Designer/index.tsx +1 -0
- package/src/components/Preview.tsx +6 -6
- package/src/components/Renderer.tsx +80 -0
- package/src/contexts.ts +5 -0
- package/src/helper.ts +8 -0
- package/src/i18n.ts +44 -1
- package/src/renders/barcodes.ts +117 -0
- package/src/renders/image.ts +101 -0
- package/src/renders/text.ts +138 -0
- package/src/types.ts +28 -0
- package/dist/types/components/Schemas/BarcodeSchema.d.ts +0 -15
- package/dist/types/components/Schemas/ImageSchema.d.ts +0 -15
- package/dist/types/components/Schemas/SchemaUI.d.ts +0 -15
- package/dist/types/components/Schemas/TextSchema.d.ts +0 -27
- package/src/components/Schemas/BarcodeSchema.tsx +0 -124
- package/src/components/Schemas/ImageSchema.tsx +0 -87
- package/src/components/Schemas/SchemaUI.tsx +0 -62
- 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
|
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
|
-
<
|
312
|
+
<Renderer
|
323
313
|
key={schema.id}
|
324
314
|
schema={schema}
|
325
315
|
onChangeHoveringSchemaId={onChangeHoveringSchemaId}
|
326
|
-
|
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
|
-
|
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 {
|
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
|
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') => {
|