@pdfme/ui 3.0.1-dev.9 → 3.1.0-dev.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/__mocks__/pdfjs-dist.js +15 -0
- package/dist/__vite-browser-external-jWVCDlBL.js +4 -0
- package/dist/index.js +1115 -2
- package/dist/path2d-polyfill.esm-yIGK7UQJ.js +214 -0
- package/dist/style.css +1 -0
- package/dist/types/class.d.ts +3 -3
- package/dist/types/components/AppContextProvider.d.ts +11 -0
- package/dist/types/components/{CtlBar/index.d.ts → CtlBar.d.ts} +2 -2
- package/dist/types/components/Designer/Canvas/Selecto.d.ts +3 -2
- package/dist/types/components/Designer/Sidebar/DetailView/AlignWidget.d.ts +1 -1
- package/dist/types/components/Designer/Sidebar/ListView/SelectableSortableContainer.d.ts +1 -1
- package/dist/types/components/Renderer.d.ts +1 -1
- package/dist/types/components/UnitPager.d.ts +1 -1
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/contexts.d.ts +46 -4
- package/dist/types/helper.d.ts +2 -1
- package/dist/types/hooks.d.ts +19 -2
- package/dist/types/i18n.d.ts +3 -27
- package/dist/types/theme.d.ts +2 -0
- package/package.json +17 -13
- package/src/Designer.tsx +27 -53
- package/src/Form.tsx +22 -23
- package/src/Viewer.tsx +10 -11
- package/src/class.ts +5 -5
- package/src/components/AppContextProvider.tsx +63 -0
- package/src/components/CtlBar.tsx +125 -0
- package/src/components/Designer/Canvas/Guides.tsx +18 -23
- package/src/components/Designer/Canvas/Mask.tsx +2 -1
- package/src/components/Designer/Canvas/Moveable.tsx +60 -60
- package/src/components/Designer/Canvas/Selecto.tsx +33 -20
- package/src/components/Designer/Canvas/index.tsx +21 -15
- package/src/components/Designer/Sidebar/DetailView/AlignWidget.tsx +53 -89
- package/src/components/Designer/Sidebar/DetailView/index.tsx +41 -30
- package/src/components/Designer/Sidebar/ListView/Item.tsx +30 -19
- package/src/components/Designer/Sidebar/ListView/SelectableSortableContainer.tsx +9 -6
- package/src/components/Designer/Sidebar/ListView/SelectableSortableItem.tsx +4 -1
- package/src/components/Designer/Sidebar/ListView/index.tsx +76 -71
- package/src/components/Designer/Sidebar/index.tsx +25 -49
- package/src/components/Designer/index.tsx +24 -82
- package/src/components/ErrorScreen.tsx +13 -11
- package/src/components/Preview.tsx +5 -2
- package/src/components/Renderer.tsx +10 -6
- package/src/components/Root.tsx +2 -8
- package/src/components/Spinner.tsx +12 -31
- package/src/components/UnitPager.tsx +72 -55
- package/src/constants.ts +2 -0
- package/src/contexts.ts +4 -5
- package/src/helper.ts +8 -5
- package/src/hooks.ts +136 -3
- package/src/i18n.ts +168 -59
- package/src/theme.ts +20 -0
- package/tsconfig.json +35 -13
- package/vite.config.ts +27 -0
- package/dist/index.js.LICENSE.txt +0 -142
- package/dist/types/components/CtlBar/Pager.d.ts +0 -8
- package/dist/types/components/CtlBar/Zoom.d.ts +0 -7
- package/dist/types/components/Divider.d.ts +0 -3
- package/src/components/CtlBar/Pager.tsx +0 -53
- package/src/components/CtlBar/Zoom.tsx +0 -56
- package/src/components/CtlBar/index.tsx +0 -46
- package/src/components/Divider.tsx +0 -7
- package/webpack.config.js +0 -51
- /package/{assetsTransformer.js → __mocks__/assetsTransformer.js} +0 -0
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import React, { useContext, useState } from 'react';
|
|
2
2
|
import type { SidebarProps } from '../../../../types';
|
|
3
|
-
import {
|
|
3
|
+
import { SIDEBAR_WIDTH } from '../../../../constants';
|
|
4
4
|
import { I18nContext } from '../../../../contexts';
|
|
5
|
-
import
|
|
5
|
+
import { getSidebarContentHeight } from '../../../../helper';
|
|
6
|
+
import { theme, Input, Typography, Divider, Button } from 'antd';
|
|
6
7
|
import SelectableSortableContainer from './SelectableSortableContainer';
|
|
7
8
|
|
|
9
|
+
const { Text } = Typography;
|
|
10
|
+
const { TextArea } = Input;
|
|
11
|
+
|
|
12
|
+
const headHeight = 40;
|
|
13
|
+
|
|
8
14
|
const ListView = (
|
|
9
15
|
props: Pick<
|
|
10
16
|
SidebarProps,
|
|
@@ -26,89 +32,88 @@ const ListView = (
|
|
|
26
32
|
onChangeHoveringSchemaId,
|
|
27
33
|
changeSchemas,
|
|
28
34
|
} = props;
|
|
35
|
+
const { token } = theme.useToken();
|
|
29
36
|
const i18n = useContext(I18nContext);
|
|
30
37
|
const [isBulkUpdateFieldNamesMode, setIsBulkUpdateFieldNamesMode] = useState(false);
|
|
31
38
|
const [fieldNamesValue, setFieldNamesValue] = useState('');
|
|
32
|
-
const height = size.height
|
|
39
|
+
const height = getSidebarContentHeight(size.height);
|
|
40
|
+
|
|
41
|
+
const commitBulk = () => {
|
|
42
|
+
const names = fieldNamesValue.split('\n');
|
|
43
|
+
if (names.length !== schemas.length) {
|
|
44
|
+
alert(i18n('errorBulkUpdateFieldName'));
|
|
45
|
+
} else {
|
|
46
|
+
changeSchemas(
|
|
47
|
+
names.map((value, index) => ({
|
|
48
|
+
key: 'key',
|
|
49
|
+
value,
|
|
50
|
+
schemaId: schemas[index].id,
|
|
51
|
+
}))
|
|
52
|
+
);
|
|
53
|
+
setIsBulkUpdateFieldNamesMode(false);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const startBulk = () => {
|
|
58
|
+
setFieldNamesValue(schemas.map((s) => s.key).join('\n'));
|
|
59
|
+
setIsBulkUpdateFieldNamesMode(true);
|
|
60
|
+
};
|
|
61
|
+
|
|
33
62
|
return (
|
|
34
63
|
<div>
|
|
35
|
-
<div style={{ height:
|
|
36
|
-
<
|
|
64
|
+
<div style={{ height: headHeight, display: 'flex', alignItems: 'center' }}>
|
|
65
|
+
<Text strong style={{ textAlign: 'center', width: '100%' }}>
|
|
37
66
|
{i18n('fieldsList')}
|
|
38
|
-
</
|
|
67
|
+
</Text>
|
|
39
68
|
</div>
|
|
40
|
-
<Divider />
|
|
41
|
-
{
|
|
42
|
-
|
|
43
|
-
<
|
|
69
|
+
<Divider style={{ marginTop: token.marginXS, marginBottom: token.marginXS }} />
|
|
70
|
+
<div style={{ height: height - headHeight }}>
|
|
71
|
+
{isBulkUpdateFieldNamesMode ? (
|
|
72
|
+
<TextArea
|
|
44
73
|
wrap="off"
|
|
45
74
|
value={fieldNamesValue}
|
|
46
75
|
onChange={(e) => setFieldNamesValue(e.target.value)}
|
|
47
76
|
style={{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
lineHeight: '2.
|
|
52
|
-
background: 'transparent',
|
|
53
|
-
margin: 0,
|
|
54
|
-
padding: '1rem',
|
|
55
|
-
boxSizing: 'border-box',
|
|
56
|
-
fontFamily: 'inherit',
|
|
77
|
+
paddingLeft: 30,
|
|
78
|
+
height: height - headHeight,
|
|
79
|
+
width: SIDEBAR_WIDTH - 35,
|
|
80
|
+
lineHeight: '2.75rem',
|
|
57
81
|
}}
|
|
58
|
-
|
|
59
|
-
</div>
|
|
60
|
-
) : (
|
|
61
|
-
<SelectableSortableContainer
|
|
62
|
-
height={height}
|
|
63
|
-
schemas={schemas}
|
|
64
|
-
hoveringSchemaId={hoveringSchemaId}
|
|
65
|
-
onChangeHoveringSchemaId={onChangeHoveringSchemaId}
|
|
66
|
-
onSortEnd={onSortEnd}
|
|
67
|
-
onEdit={onEdit}
|
|
68
|
-
/>
|
|
69
|
-
)}
|
|
70
|
-
<div
|
|
71
|
-
style={{
|
|
72
|
-
display: 'flex',
|
|
73
|
-
justifyContent: 'flex-end',
|
|
74
|
-
cursor: 'pointer',
|
|
75
|
-
fontSize: '0.75rem',
|
|
76
|
-
}}
|
|
77
|
-
>
|
|
78
|
-
{isBulkUpdateFieldNamesMode ? (
|
|
79
|
-
<>
|
|
80
|
-
<u
|
|
81
|
-
onClick={() => {
|
|
82
|
-
const names = fieldNamesValue.split('\n');
|
|
83
|
-
if (names.length !== schemas.length) {
|
|
84
|
-
alert(i18n('errorBulkUpdateFieldName'));
|
|
85
|
-
} else {
|
|
86
|
-
changeSchemas(
|
|
87
|
-
names.map((value, index) => ({
|
|
88
|
-
key: 'key',
|
|
89
|
-
value,
|
|
90
|
-
schemaId: schemas[index].id,
|
|
91
|
-
}))
|
|
92
|
-
);
|
|
93
|
-
setIsBulkUpdateFieldNamesMode(false);
|
|
94
|
-
}
|
|
95
|
-
}}
|
|
96
|
-
>
|
|
97
|
-
{i18n('commitBulkUpdateFieldName')}
|
|
98
|
-
</u>
|
|
99
|
-
<span style={{ margin: '0 1rem' }}>/</span>
|
|
100
|
-
<u onClick={() => setIsBulkUpdateFieldNamesMode(false)}>{i18n('cancel')}</u>
|
|
101
|
-
</>
|
|
82
|
+
/>
|
|
102
83
|
) : (
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
</u>
|
|
84
|
+
<SelectableSortableContainer
|
|
85
|
+
schemas={schemas}
|
|
86
|
+
hoveringSchemaId={hoveringSchemaId}
|
|
87
|
+
onChangeHoveringSchemaId={onChangeHoveringSchemaId}
|
|
88
|
+
onSortEnd={onSortEnd}
|
|
89
|
+
onEdit={onEdit}
|
|
90
|
+
/>
|
|
111
91
|
)}
|
|
92
|
+
<div
|
|
93
|
+
style={{
|
|
94
|
+
display: 'flex',
|
|
95
|
+
alignItems: 'center',
|
|
96
|
+
justifyContent: 'flex-end',
|
|
97
|
+
height: headHeight,
|
|
98
|
+
borderBottom: `1px solid ${token.colorSplit}`,
|
|
99
|
+
}}
|
|
100
|
+
>
|
|
101
|
+
{isBulkUpdateFieldNamesMode ? (
|
|
102
|
+
<>
|
|
103
|
+
<Button size="small" type="text" onClick={commitBulk}>
|
|
104
|
+
<u> {i18n('commitBulkUpdateFieldName')}</u>
|
|
105
|
+
</Button>
|
|
106
|
+
<span style={{ margin: '0 1rem' }}>/</span>
|
|
107
|
+
<Button size="small" type="text" onClick={() => setIsBulkUpdateFieldNamesMode(false)}>
|
|
108
|
+
<u> {i18n('cancel')}</u>
|
|
109
|
+
</Button>
|
|
110
|
+
</>
|
|
111
|
+
) : (
|
|
112
|
+
<Button size="small" type="text" onClick={startBulk}>
|
|
113
|
+
<u> {i18n('bulkUpdateFieldName')}</u>
|
|
114
|
+
</Button>
|
|
115
|
+
)}
|
|
116
|
+
</div>
|
|
112
117
|
</div>
|
|
113
118
|
</div>
|
|
114
119
|
);
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
|
+
import { theme, Button } from 'antd';
|
|
2
3
|
import type { SidebarProps } from '../../../types';
|
|
3
4
|
import { SIDEBAR_WIDTH } from '../../../constants';
|
|
4
5
|
import { I18nContext } from '../../../contexts';
|
|
5
|
-
import {
|
|
6
|
+
import { ArrowLeftOutlined, ArrowRightOutlined } from '@ant-design/icons';
|
|
6
7
|
import ListView from './ListView/index';
|
|
7
8
|
import DetailView from './DetailView/index';
|
|
8
9
|
|
|
9
10
|
const Sidebar = (props: SidebarProps) => {
|
|
10
11
|
const { sidebarOpen, setSidebarOpen, activeElements, schemas, addSchema } = props;
|
|
11
12
|
|
|
13
|
+
const { token } = theme.useToken();
|
|
12
14
|
const i18n = useContext(I18nContext);
|
|
13
15
|
const getActiveSchemas = () =>
|
|
14
16
|
schemas.filter((s) => activeElements.map((ae) => ae.id).includes(s.id));
|
|
@@ -25,33 +27,22 @@ const Sidebar = (props: SidebarProps) => {
|
|
|
25
27
|
zIndex: 1,
|
|
26
28
|
height: '100%',
|
|
27
29
|
width: sidebarOpen ? SIDEBAR_WIDTH : 0,
|
|
28
|
-
fontSize: '1rem',
|
|
29
30
|
}}
|
|
30
31
|
>
|
|
31
32
|
<div>
|
|
32
|
-
<
|
|
33
|
-
type="button"
|
|
33
|
+
<Button
|
|
34
34
|
style={{
|
|
35
35
|
position: 'absolute',
|
|
36
|
-
|
|
36
|
+
display: 'flex',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
justifyContent: 'center',
|
|
39
|
+
top: '1rem',
|
|
37
40
|
right: '1rem',
|
|
38
41
|
zIndex: 100,
|
|
39
|
-
border: 'none',
|
|
40
|
-
borderRadius: 2,
|
|
41
|
-
padding: '0.5rem',
|
|
42
|
-
cursor: 'pointer',
|
|
43
|
-
background: '#eee',
|
|
44
|
-
width: 30,
|
|
45
|
-
height: 30,
|
|
46
42
|
}}
|
|
43
|
+
icon={sidebarOpen ? <ArrowRightOutlined /> : <ArrowLeftOutlined />}
|
|
47
44
|
onClick={() => setSidebarOpen(!sidebarOpen)}
|
|
48
|
-
|
|
49
|
-
{sidebarOpen ? (
|
|
50
|
-
<ArrowRightIcon width={15} height={15} />
|
|
51
|
-
) : (
|
|
52
|
-
<ArrowLeftIcon width={15} height={15} />
|
|
53
|
-
)}
|
|
54
|
-
</button>
|
|
45
|
+
/>
|
|
55
46
|
<div
|
|
56
47
|
style={{
|
|
57
48
|
width: SIDEBAR_WIDTH,
|
|
@@ -60,47 +51,32 @@ const Sidebar = (props: SidebarProps) => {
|
|
|
60
51
|
top: 0,
|
|
61
52
|
right: 0,
|
|
62
53
|
position: 'absolute',
|
|
63
|
-
background: '#fffffffa',
|
|
64
|
-
color: '#333',
|
|
65
|
-
border: '1px solid #eee',
|
|
66
54
|
padding: '0.7rem 1rem',
|
|
67
55
|
overflowY: 'auto',
|
|
68
56
|
fontFamily: "'Open Sans', sans-serif",
|
|
69
|
-
fontWeight: 400,
|
|
70
|
-
textAlign: 'left',
|
|
71
57
|
boxSizing: 'border-box',
|
|
58
|
+
background: token.colorBgLayout,
|
|
72
59
|
}}
|
|
73
60
|
>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
61
|
+
<div>
|
|
62
|
+
{getActiveSchemas().length === 0 ? (
|
|
63
|
+
<ListView {...props} />
|
|
64
|
+
) : (
|
|
65
|
+
<DetailView {...props} activeSchema={getLastActiveSchema()} />
|
|
66
|
+
)}
|
|
67
|
+
</div>
|
|
79
68
|
<div
|
|
80
69
|
style={{
|
|
81
70
|
position: 'absolute',
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
71
|
+
bottom: '1.5rem',
|
|
72
|
+
marginTop: '1rem',
|
|
73
|
+
left: '50%',
|
|
74
|
+
transform: 'translateX(-50%)',
|
|
86
75
|
}}
|
|
87
76
|
>
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
style={{
|
|
92
|
-
padding: '0.5rem',
|
|
93
|
-
background: '#18a0fb',
|
|
94
|
-
border: 'none',
|
|
95
|
-
borderRadius: 2,
|
|
96
|
-
cursor: 'pointer',
|
|
97
|
-
margin: '0 auto',
|
|
98
|
-
display: 'block',
|
|
99
|
-
}}
|
|
100
|
-
onClick={addSchema}
|
|
101
|
-
>
|
|
102
|
-
<strong style={{ color: '#fff' }}>{i18n('addNewField')}</strong>
|
|
103
|
-
</button>
|
|
77
|
+
<Button type="primary" style={{ fontWeight: 600 }} onClick={addSchema}>
|
|
78
|
+
{i18n('addNewField')}
|
|
79
|
+
</Button>
|
|
104
80
|
</div>
|
|
105
81
|
</div>
|
|
106
82
|
</div>
|
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
import React, { useRef, useState, useEffect, useContext, useCallback } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ZOOM,
|
|
4
|
+
Template,
|
|
5
|
+
Schema,
|
|
6
|
+
SchemaForUI,
|
|
7
|
+
ChangeSchemas,
|
|
8
|
+
DesignerProps,
|
|
9
|
+
Size,
|
|
10
|
+
Plugin,
|
|
11
|
+
} from '@pdfme/common';
|
|
3
12
|
import Sidebar from './Sidebar/index';
|
|
4
13
|
import Canvas from './Canvas/index';
|
|
5
14
|
import { RULER_HEIGHT, SIDEBAR_WIDTH } from '../../constants';
|
|
6
15
|
import { I18nContext, PluginsRegistry } from '../../contexts';
|
|
7
16
|
import {
|
|
17
|
+
fmtTemplate,
|
|
8
18
|
uuid,
|
|
9
19
|
set,
|
|
10
20
|
cloneDeep,
|
|
11
|
-
initShortCuts,
|
|
12
|
-
destroyShortCuts,
|
|
13
21
|
templateSchemas2SchemasList,
|
|
14
|
-
fmtTemplate,
|
|
15
|
-
getUniqSchemaKey,
|
|
16
|
-
moveCommandToChangeSchemasArg,
|
|
17
22
|
getPagesScrollTopByIndex,
|
|
18
23
|
} from '../../helper';
|
|
19
|
-
import { useUIPreProcessor, useScrollPageCursor } from '../../hooks';
|
|
24
|
+
import { useUIPreProcessor, useScrollPageCursor, useInitEvents } from '../../hooks';
|
|
20
25
|
import Root from '../Root';
|
|
21
26
|
import ErrorScreen from '../ErrorScreen';
|
|
22
|
-
import CtlBar from '../CtlBar
|
|
27
|
+
import CtlBar from '../CtlBar';
|
|
23
28
|
|
|
24
29
|
const TemplateEditor = ({
|
|
25
30
|
template,
|
|
@@ -30,7 +35,6 @@ const TemplateEditor = ({
|
|
|
30
35
|
onSaveTemplate: (t: Template) => void;
|
|
31
36
|
size: Size;
|
|
32
37
|
} & { onChangeTemplate: (t: Template) => void }) => {
|
|
33
|
-
const copiedSchemas = useRef<SchemaForUI[] | null>(null);
|
|
34
38
|
const past = useRef<SchemaForUI[][]>([]);
|
|
35
39
|
const future = useRef<SchemaForUI[][]>([]);
|
|
36
40
|
const mainRef = useRef<HTMLDivElement>(null);
|
|
@@ -69,8 +73,6 @@ const TemplateEditor = ({
|
|
|
69
73
|
},
|
|
70
74
|
});
|
|
71
75
|
|
|
72
|
-
const modifiedTemplate = fmtTemplate(template, schemasList);
|
|
73
|
-
|
|
74
76
|
const commitSchemas = useCallback(
|
|
75
77
|
(newSchemas: SchemaForUI[]) => {
|
|
76
78
|
future.current = [];
|
|
@@ -119,76 +121,22 @@ const TemplateEditor = ({
|
|
|
119
121
|
[commitSchemas, pageCursor, schemasList]
|
|
120
122
|
);
|
|
121
123
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return schemasList[pageCursor].filter((s) => ids.includes(s.id));
|
|
127
|
-
};
|
|
128
|
-
const timeTravel = (mode: 'undo' | 'redo') => {
|
|
129
|
-
const isUndo = mode === 'undo';
|
|
130
|
-
const stack = isUndo ? past : future;
|
|
131
|
-
if (stack.current.length <= 0) return;
|
|
132
|
-
(isUndo ? future : past).current.push(cloneDeep(schemasList[pageCursor]));
|
|
133
|
-
const s = cloneDeep(schemasList);
|
|
134
|
-
s[pageCursor] = stack.current.pop()!;
|
|
135
|
-
setSchemasList(s);
|
|
136
|
-
};
|
|
137
|
-
initShortCuts({
|
|
138
|
-
move: (command, isShift) => {
|
|
139
|
-
const pageSize = pageSizes[pageCursor];
|
|
140
|
-
const activeSchemas = getActiveSchemas();
|
|
141
|
-
const arg = moveCommandToChangeSchemasArg({ command, activeSchemas, pageSize, isShift });
|
|
142
|
-
changeSchemas(arg);
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
copy: () => {
|
|
146
|
-
const activeSchemas = getActiveSchemas();
|
|
147
|
-
if (activeSchemas.length === 0) return;
|
|
148
|
-
copiedSchemas.current = activeSchemas;
|
|
149
|
-
},
|
|
150
|
-
paste: () => {
|
|
151
|
-
if (!copiedSchemas.current || copiedSchemas.current.length === 0) return;
|
|
152
|
-
const schema = schemasList[pageCursor];
|
|
153
|
-
const stackUniqSchemaKeys: string[] = [];
|
|
154
|
-
const pasteSchemas = copiedSchemas.current.map((cs) => {
|
|
155
|
-
const id = uuid();
|
|
156
|
-
const key = getUniqSchemaKey({ copiedSchemaKey: cs.key, schema, stackUniqSchemaKeys });
|
|
157
|
-
const { height, width, position: p } = cs;
|
|
158
|
-
const ps = pageSizes[pageCursor];
|
|
159
|
-
const position = {
|
|
160
|
-
x: p.x + 10 > ps.width - width ? ps.width - width : p.x + 10,
|
|
161
|
-
y: p.y + 10 > ps.height - height ? ps.height - height : p.y + 10,
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
return Object.assign(cloneDeep(cs), { id, key, position });
|
|
165
|
-
});
|
|
166
|
-
commitSchemas(schemasList[pageCursor].concat(pasteSchemas));
|
|
167
|
-
onEdit(pasteSchemas.map((s) => document.getElementById(s.id)!));
|
|
168
|
-
copiedSchemas.current = pasteSchemas;
|
|
169
|
-
},
|
|
170
|
-
redo: () => timeTravel('redo'),
|
|
171
|
-
undo: () => timeTravel('undo'),
|
|
172
|
-
save: () => onSaveTemplate && onSaveTemplate(modifiedTemplate),
|
|
173
|
-
remove: () => removeSchemas(getActiveSchemas().map((s) => s.id)),
|
|
174
|
-
esc: onEditEnd,
|
|
175
|
-
selectAll: () => onEdit(schemasList[pageCursor].map((s) => document.getElementById(s.id)!)),
|
|
176
|
-
});
|
|
177
|
-
}, [
|
|
124
|
+
useInitEvents({
|
|
125
|
+
pageCursor,
|
|
126
|
+
pageSizes,
|
|
178
127
|
activeElements,
|
|
128
|
+
template,
|
|
129
|
+
schemasList,
|
|
179
130
|
changeSchemas,
|
|
180
131
|
commitSchemas,
|
|
181
|
-
modifiedTemplate,
|
|
182
|
-
pageCursor,
|
|
183
|
-
pageSizes,
|
|
184
132
|
removeSchemas,
|
|
185
133
|
onSaveTemplate,
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
134
|
+
past,
|
|
135
|
+
future,
|
|
136
|
+
setSchemasList,
|
|
137
|
+
onEdit,
|
|
138
|
+
onEditEnd,
|
|
139
|
+
});
|
|
192
140
|
|
|
193
141
|
const updateTemplate = useCallback(async (newTemplate: Template) => {
|
|
194
142
|
const sl = await templateSchemas2SchemasList(newTemplate);
|
|
@@ -204,12 +152,6 @@ const TemplateEditor = ({
|
|
|
204
152
|
updateTemplate(template);
|
|
205
153
|
}, [template, updateTemplate]);
|
|
206
154
|
|
|
207
|
-
useEffect(() => {
|
|
208
|
-
initEvents();
|
|
209
|
-
|
|
210
|
-
return destroyEvents;
|
|
211
|
-
}, [initEvents, destroyEvents]);
|
|
212
|
-
|
|
213
155
|
const addSchema = () => {
|
|
214
156
|
const propPanel = (Object.values(pluginsRegistry)[0] as Plugin<Schema>)?.propPanel;
|
|
215
157
|
|
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
2
|
import { Size } from '@pdfme/common';
|
|
3
3
|
import { I18nContext } from '../contexts';
|
|
4
|
+
import { BACKGROUND_COLOR } from '../constants';
|
|
5
|
+
import { theme, Result } from 'antd';
|
|
4
6
|
|
|
5
7
|
const ErrorScreen = ({ size, error }: { size: Size; error: Error }) => {
|
|
6
8
|
const i18n = useContext(I18nContext);
|
|
9
|
+
const { token } = theme.useToken();
|
|
7
10
|
|
|
8
11
|
return (
|
|
9
12
|
<div
|
|
10
13
|
style={{
|
|
11
|
-
position: 'relative',
|
|
12
|
-
background: 'rgb(74, 74, 74)',
|
|
13
|
-
overflow: 'auto',
|
|
14
14
|
display: 'flex',
|
|
15
|
-
|
|
15
|
+
flexDirection: 'column',
|
|
16
16
|
justifyContent: 'center',
|
|
17
|
+
background: BACKGROUND_COLOR,
|
|
17
18
|
...size,
|
|
18
19
|
}}
|
|
19
20
|
>
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
<div style={{ width: 300, margin: '0 auto', background: token.colorBgLayout }}>
|
|
22
|
+
<Result
|
|
23
|
+
icon={null}
|
|
24
|
+
title="ERROR"
|
|
25
|
+
subTitle={i18n('errorOccurred')}
|
|
26
|
+
extra={<span>{error.message}</span>}
|
|
27
|
+
/>
|
|
28
|
+
</div>
|
|
27
29
|
</div>
|
|
28
30
|
);
|
|
29
31
|
};
|
|
@@ -3,11 +3,12 @@ import type { SchemaForUI, PreviewProps, Size } from '@pdfme/common';
|
|
|
3
3
|
import UnitPager from './UnitPager';
|
|
4
4
|
import Root from './Root';
|
|
5
5
|
import ErrorScreen from './ErrorScreen';
|
|
6
|
-
import CtlBar from './CtlBar
|
|
6
|
+
import CtlBar from './CtlBar';
|
|
7
7
|
import Paper from './Paper';
|
|
8
8
|
import Renderer from './Renderer';
|
|
9
9
|
import { useUIPreProcessor, useScrollPageCursor } from '../hooks';
|
|
10
10
|
import { templateSchemas2SchemasList, getPagesScrollTopByIndex } from '../helper';
|
|
11
|
+
import { theme } from 'antd';
|
|
11
12
|
|
|
12
13
|
const Preview = ({
|
|
13
14
|
template,
|
|
@@ -18,6 +19,8 @@ const Preview = ({
|
|
|
18
19
|
onChangeInput?: (args: { index: number; value: string; key: string }) => void;
|
|
19
20
|
size: Size;
|
|
20
21
|
}) => {
|
|
22
|
+
const { token } = theme.useToken();
|
|
23
|
+
|
|
21
24
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
22
25
|
const paperRefs = useRef<HTMLDivElement[]>([]);
|
|
23
26
|
|
|
@@ -101,7 +104,7 @@ const Preview = ({
|
|
|
101
104
|
placeholder={template.sampledata?.[0]?.[key] ?? ''}
|
|
102
105
|
tabIndex={index + 100}
|
|
103
106
|
onChange={(value) => handleChangeInput({ key, value })}
|
|
104
|
-
outline={isForm ?
|
|
107
|
+
outline={isForm ? `1px dashed ${token.colorPrimary}` : 'transparent'}
|
|
105
108
|
scale={scale}
|
|
106
109
|
/>
|
|
107
110
|
);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React, { useEffect, useContext, ReactNode, useRef } from 'react';
|
|
2
|
-
import { ZOOM, UIRenderProps, SchemaForUI, Schema } from '@pdfme/common';
|
|
2
|
+
import { Dict, ZOOM, UIRenderProps, SchemaForUI, Schema } from '@pdfme/common';
|
|
3
|
+
import { theme as antdTheme } from 'antd';
|
|
3
4
|
import { SELECTABLE_CLASSNAME } from '../constants';
|
|
4
|
-
import { PluginsRegistry, OptionsContext } from '../contexts';
|
|
5
|
+
import { PluginsRegistry, OptionsContext, I18nContext } from '../contexts';
|
|
5
6
|
|
|
6
7
|
type RendererProps = Omit<
|
|
7
8
|
UIRenderProps<Schema>,
|
|
8
|
-
'value' | 'schema' | 'onChange' | 'rootElement' | 'options'
|
|
9
|
+
'value' | 'schema' | 'onChange' | 'rootElement' | 'options' | 'theme' | 'i18n'
|
|
9
10
|
> & {
|
|
10
11
|
schema: SchemaForUI;
|
|
11
12
|
onChange: (value: string) => void;
|
|
@@ -44,6 +45,8 @@ const Wrapper = ({
|
|
|
44
45
|
const Renderer = (props: RendererProps) => {
|
|
45
46
|
const pluginsRegistry = useContext(PluginsRegistry);
|
|
46
47
|
const options = useContext(OptionsContext);
|
|
48
|
+
const i18n = useContext(I18nContext) as (key: keyof Dict | string) => string;
|
|
49
|
+
const { token: theme } = antdTheme.useToken();
|
|
47
50
|
|
|
48
51
|
const { schema, mode, onChange, stopEditing, tabIndex, placeholder, scale } = props;
|
|
49
52
|
|
|
@@ -51,10 +54,9 @@ const Renderer = (props: RendererProps) => {
|
|
|
51
54
|
|
|
52
55
|
useEffect(() => {
|
|
53
56
|
if (ref.current && schema.type) {
|
|
54
|
-
|
|
55
57
|
const render = Object.values(pluginsRegistry).find(
|
|
56
58
|
(plugin) => plugin?.propPanel.defaultSchema.type === schema.type
|
|
57
|
-
)?.ui
|
|
59
|
+
)?.ui;
|
|
58
60
|
|
|
59
61
|
if (!render) {
|
|
60
62
|
console.error(`[@pdfme/ui] Renderer for type ${schema.type} not found.
|
|
@@ -76,6 +78,8 @@ Check this document: https://pdfme.com/docs/custom-schemas`);
|
|
|
76
78
|
tabIndex,
|
|
77
79
|
placeholder,
|
|
78
80
|
options,
|
|
81
|
+
theme,
|
|
82
|
+
i18n,
|
|
79
83
|
});
|
|
80
84
|
}
|
|
81
85
|
return () => {
|
|
@@ -83,7 +87,7 @@ Check this document: https://pdfme.com/docs/custom-schemas`);
|
|
|
83
87
|
ref.current.innerHTML = '';
|
|
84
88
|
}
|
|
85
89
|
};
|
|
86
|
-
}, [JSON.stringify(schema),
|
|
90
|
+
}, [JSON.stringify(schema), JSON.stringify(options), mode, scale]);
|
|
87
91
|
|
|
88
92
|
return (
|
|
89
93
|
<Wrapper {...props}>
|
package/src/components/Root.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useContext, forwardRef, ReactNode, Ref, useEffect } from 'react';
|
|
2
2
|
import { Size } from '@pdfme/common';
|
|
3
3
|
import { FontContext } from '../contexts';
|
|
4
|
+
import { BACKGROUND_COLOR } from '../constants';
|
|
4
5
|
import Spinner from './Spinner';
|
|
5
6
|
|
|
6
7
|
type Props = { size: Size; scale: number; children: ReactNode };
|
|
@@ -30,14 +31,7 @@ const Root = ({ size, scale, children }: Props, ref: Ref<HTMLDivElement>) => {
|
|
|
30
31
|
}, [font]);
|
|
31
32
|
|
|
32
33
|
return (
|
|
33
|
-
<div
|
|
34
|
-
ref={ref}
|
|
35
|
-
style={{
|
|
36
|
-
position: 'relative',
|
|
37
|
-
background: 'rgb(74, 74, 74)',
|
|
38
|
-
...size,
|
|
39
|
-
}}
|
|
40
|
-
>
|
|
34
|
+
<div ref={ref} style={{ position: 'relative', background: BACKGROUND_COLOR, ...size }}>
|
|
41
35
|
<div style={{ margin: '0 auto', ...size }}>{scale === 0 ? <Spinner /> : children}</div>
|
|
42
36
|
</div>
|
|
43
37
|
);
|
|
@@ -1,37 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { LoadingOutlined } from '@ant-design/icons';
|
|
3
|
+
import { Spin } from 'antd';
|
|
2
4
|
|
|
3
5
|
const Spinner = () => (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<div
|
|
15
|
-
style={{
|
|
16
|
-
width: '100%',
|
|
17
|
-
height: '100%',
|
|
18
|
-
display: 'flex',
|
|
19
|
-
alignItems: 'center',
|
|
20
|
-
justifyContent: 'center',
|
|
21
|
-
}}
|
|
22
|
-
>
|
|
23
|
-
<div
|
|
24
|
-
style={{
|
|
25
|
-
width: 65,
|
|
26
|
-
height: 65,
|
|
27
|
-
borderRadius: '50%',
|
|
28
|
-
border: '4px solid',
|
|
29
|
-
borderColor: '#4285f4 rgba(0,0,0,0.1) rgba(0,0,0,0.1)',
|
|
30
|
-
animation: 'spin 1s ease infinite',
|
|
31
|
-
}}
|
|
32
|
-
></div>
|
|
33
|
-
</div>
|
|
34
|
-
</>
|
|
6
|
+
<Spin
|
|
7
|
+
style={{
|
|
8
|
+
width: '100%',
|
|
9
|
+
height: '100%',
|
|
10
|
+
display: 'flex',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
justifyContent: 'center',
|
|
13
|
+
}}
|
|
14
|
+
indicator={<LoadingOutlined style={{ fontSize: 50 }} spin />}
|
|
15
|
+
/>
|
|
35
16
|
);
|
|
36
17
|
|
|
37
18
|
export default Spinner;
|