@pdfme/ui 1.0.0-beta.1 → 1.0.0-beta.10
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 +8 -7
- package/coverage/clover.xml +6 -0
- package/coverage/coverage-final.json +1 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +101 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +0 -0
- package/dist/index.js +3 -0
- package/dist/{@pdfme/ui.js.LICENSE.txt → index.js.LICENSE.txt} +3 -1
- package/dist/index.js.map +1 -0
- package/dist/types/{ui/src/Designer.d.ts → Designer.d.ts} +0 -0
- package/dist/types/{ui/src/Form.d.ts → Form.d.ts} +0 -0
- package/dist/types/{ui/src/Viewer.d.ts → Viewer.d.ts} +0 -0
- package/dist/types/{ui/src/class.d.ts → class.d.ts} +5 -4
- package/dist/types/{ui/src/components → components}/Designer/Main/Guides.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Designer/Main/Mask.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Designer/Main/Moveable.d.ts +1 -1
- package/dist/types/{ui/src/components → components}/Designer/Main/Selecto.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Designer/Main/index.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Designer/Sidebar/DetailView/ExampleInputEditor.d.ts +4 -1
- package/dist/types/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.d.ts +6 -0
- package/dist/types/{ui/src/components → components}/Designer/Sidebar/DetailView/TextPropEditor.d.ts +4 -1
- package/dist/types/{ui/src/components → components}/Designer/Sidebar/DetailView/TypeAndKeyEditor.d.ts +4 -1
- package/dist/types/components/Designer/Sidebar/DetailView/index.d.ts +6 -0
- package/dist/types/components/Designer/Sidebar/ListView/Item.d.ts +25 -0
- package/dist/types/components/Designer/Sidebar/ListView/SelectableSortableContainer.d.ts +3 -0
- package/dist/types/components/Designer/Sidebar/ListView/SelectableSortableItem.d.ts +14 -0
- package/dist/types/{ui/src/components/Designer/Sidebar/ListView.d.ts → components/Designer/Sidebar/ListView/index.d.ts} +2 -2
- package/dist/types/{ui/src/components → components}/Designer/Sidebar/index.d.ts +2 -7
- package/dist/types/{ui/src/components → components}/Designer/index.d.ts +0 -1
- package/dist/types/{ui/src/components → components}/Divider.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Error.d.ts +0 -1
- package/dist/types/{ui/src/components → components}/Paper.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Preview/Pager/Page.d.ts +0 -1
- package/dist/types/{ui/src/components → components}/Preview/Pager/Unit.d.ts +0 -1
- package/dist/types/{ui/src/components → components}/Preview/index.d.ts +0 -1
- package/dist/types/{ui/src/components → components}/Root.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Schemas/BarcodeSchema.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Schemas/ImageSchema.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Schemas/SchemaUI.d.ts +1 -1
- package/dist/types/{ui/src/components → components}/Schemas/TextSchema.d.ts +0 -0
- package/dist/types/{ui/src/components → components}/Spinner.d.ts +0 -0
- package/dist/types/{ui/src/constants.d.ts → constants.d.ts} +1 -0
- package/dist/types/{ui/src/contexts.d.ts → contexts.d.ts} +1 -1
- package/dist/types/{ui/src/helper.d.ts → helper.d.ts} +1 -1
- package/dist/types/{ui/src/hooks.d.ts → hooks.d.ts} +1 -0
- package/dist/types/{ui/src/i18n.d.ts → i18n.d.ts} +4 -2
- package/dist/types/index.d.ts +6 -0
- package/package.json +14 -8
- package/src/Designer.tsx +2 -1
- package/src/Form.tsx +1 -0
- package/src/Viewer.tsx +1 -0
- package/src/assets/icons/align-horizontal-center.svg +1 -0
- package/src/assets/icons/align-horizontal-left.svg +1 -0
- package/src/assets/icons/align-horizontal-right.svg +1 -0
- package/src/assets/icons/align-vertical-bottom.svg +1 -0
- package/src/assets/icons/align-vertical-middle.svg +1 -0
- package/src/assets/icons/align-vertical-top.svg +1 -0
- package/src/assets/icons/close.svg +4 -0
- package/src/assets/icons/horizontal-distribute.svg +1 -0
- package/src/assets/icons/vertical-distribute.svg +1 -0
- package/src/assets/imageExample.png +0 -0
- package/src/class.ts +20 -8
- package/src/components/Designer/Main/Moveable.tsx +1 -1
- package/src/components/Designer/Main/index.tsx +22 -16
- package/src/components/Designer/Sidebar/DetailView/ExampleInputEditor.tsx +28 -6
- package/src/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.tsx +115 -24
- package/src/components/Designer/Sidebar/DetailView/TextPropEditor.tsx +36 -6
- package/src/components/Designer/Sidebar/DetailView/TypeAndKeyEditor.tsx +14 -6
- package/src/components/Designer/Sidebar/DetailView/index.tsx +21 -16
- package/src/components/Designer/Sidebar/ListView/Item.tsx +113 -0
- package/src/components/Designer/Sidebar/ListView/SelectableSortableContainer.tsx +162 -0
- package/src/components/Designer/Sidebar/ListView/SelectableSortableItem.tsx +78 -0
- package/src/components/Designer/Sidebar/ListView/index.tsx +119 -0
- package/src/components/Designer/Sidebar/index.tsx +30 -14
- package/src/components/Designer/index.tsx +12 -24
- package/src/components/Error.tsx +2 -2
- package/src/components/Paper.tsx +10 -3
- package/src/components/Preview/Pager/Page.tsx +1 -1
- package/src/components/Preview/Pager/Unit.tsx +1 -1
- package/src/components/Preview/index.tsx +3 -4
- package/src/components/Root.tsx +2 -7
- package/src/components/Schemas/BarcodeSchema.tsx +40 -24
- package/src/components/Schemas/ImageSchema.tsx +71 -66
- package/src/components/Schemas/TextSchema.tsx +1 -2
- package/src/constants.ts +2 -0
- package/src/helper.ts +44 -38
- package/src/hooks.ts +11 -0
- package/src/i18n.ts +10 -7
- package/src/index.ts +5 -41
- package/tsconfig.json +2 -1
- package/webpack.config.js +1 -20
- package/dist/@pdfme/ui.js +0 -3
- package/dist/@pdfme/ui.js.map +0 -1
- package/dist/types/common/src/barcode.d.ts +0 -2
- package/dist/types/common/src/constants.d.ts +0 -6
- package/dist/types/common/src/helper.d.ts +0 -15
- package/dist/types/common/src/index.d.ts +0 -4
- package/dist/types/common/src/schema.d.ts +0 -3613
- package/dist/types/common/src/type.d.ts +0 -64
- package/dist/types/common/src/utils.d.ts +0 -12
- package/dist/types/ui/src/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.d.ts +0 -3
- package/dist/types/ui/src/components/Designer/Sidebar/DetailView/index.d.ts +0 -3
- package/dist/types/ui/src/index.d.ts +0 -5
- package/dist/types/ui/src/libs/class.d.ts +0 -84
- package/dist/types/ui/src/libs/contexts.d.ts +0 -7
- package/dist/types/ui/src/libs/helper.d.ts +0 -64
- package/dist/types/ui/src/libs/hooks.d.ts +0 -26
- package/dist/types/ui/src/libs/i18n.d.ts +0 -30
- package/dist/types/ui/src/libs/ui.d.ts +0 -64
- package/public/Designer.html +0 -90
- package/public/Form.html +0 -74
- package/public/SauceHanSansJP.ttf +0 -0
- package/public/SauceHanSerifJP.ttf +0 -0
- package/public/Viewer.html +0 -73
- package/public/helper.js +0 -51
- package/public/index.html +0 -54
- package/src/components/Designer/Sidebar/ListView.tsx +0 -180
@@ -1,33 +1,52 @@
|
|
1
1
|
import React, { useContext } from 'react';
|
2
|
+
import { SchemaForUI } from '@pdfme/common';
|
2
3
|
import { readFiles } from '../../../../helper';
|
3
4
|
import { I18nContext } from '../../../../contexts';
|
4
5
|
import { SidebarProps } from '..';
|
6
|
+
import closeIcon from '../../../../assets/icons/close.svg';
|
5
7
|
|
6
|
-
const ExampleInputEditor = (
|
8
|
+
const ExampleInputEditor = (
|
9
|
+
props: Pick<SidebarProps, 'changeSchemas'> & { activeSchema: SchemaForUI }
|
10
|
+
) => {
|
7
11
|
const { changeSchemas, activeSchema } = props;
|
8
12
|
const i18n = useContext(I18nContext);
|
9
13
|
|
10
14
|
return (
|
11
15
|
<div>
|
12
|
-
<label
|
16
|
+
<label>{i18n('inputExample')}</label>
|
13
17
|
{activeSchema.type === 'image' ? (
|
14
|
-
<div style={{ position: 'relative'
|
18
|
+
<div style={{ position: 'relative' }}>
|
15
19
|
{activeSchema.data ? (
|
16
20
|
<div style={{ margin: '0 auto' }}>
|
17
21
|
<button
|
18
|
-
style={{
|
22
|
+
style={{
|
23
|
+
position: 'absolute',
|
24
|
+
top: 0,
|
25
|
+
left: 0,
|
26
|
+
display: 'flex',
|
27
|
+
justifyContent: 'center',
|
28
|
+
alignItems: 'center',
|
29
|
+
color: '#333',
|
30
|
+
background: '#f2f2f2',
|
31
|
+
cursor: 'pointer',
|
32
|
+
borderRadius: 2,
|
33
|
+
border: '1px solid #767676',
|
34
|
+
height: 20,
|
35
|
+
width: 20,
|
36
|
+
}}
|
19
37
|
aria-label="close"
|
20
38
|
onClick={() =>
|
21
39
|
changeSchemas([{ key: 'data', value: '', schemaId: activeSchema.id }])
|
22
40
|
}
|
23
41
|
>
|
24
|
-
|
42
|
+
<img src={closeIcon} alt="Close icon" width={10} />
|
25
43
|
</button>
|
26
44
|
<img style={{ maxHeight: 180 }} src={activeSchema.data} alt="Input Example" />
|
27
45
|
</div>
|
28
46
|
) : (
|
29
47
|
<label>
|
30
48
|
<input
|
49
|
+
style={{ color: '#333', background: 'none' }}
|
31
50
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
32
51
|
const { files } = e.target;
|
33
52
|
readFiles(files, 'dataURL').then((result) => {
|
@@ -50,7 +69,10 @@ const ExampleInputEditor = (props: Pick<SidebarProps, 'changeSchemas' | 'activeS
|
|
50
69
|
}
|
51
70
|
style={{
|
52
71
|
width: '100%',
|
53
|
-
|
72
|
+
border: '1px solid #767676',
|
73
|
+
borderRadius: 2,
|
74
|
+
color: '#333',
|
75
|
+
background: activeSchema.data ? 'none' : '#ffa19b',
|
54
76
|
}}
|
55
77
|
value={activeSchema.data}
|
56
78
|
/>
|
@@ -1,30 +1,128 @@
|
|
1
|
-
import React from 'react';
|
1
|
+
import React, { CSSProperties } from 'react';
|
2
|
+
import { SchemaForUI } from '@pdfme/common';
|
3
|
+
import { round } from '../../../../helper';
|
2
4
|
import { SidebarProps } from '..';
|
5
|
+
import alignVerticalTop from '../../../../assets/icons/align-vertical-top.svg';
|
6
|
+
import alignVerticalMiddle from '../../../../assets/icons/align-vertical-middle.svg';
|
7
|
+
import alignVerticalBottom from '../../../../assets/icons/align-vertical-bottom.svg';
|
8
|
+
import alignHorizontalRight from '../../../../assets/icons/align-horizontal-right.svg';
|
9
|
+
import alignHorizontalLeft from '../../../../assets/icons/align-horizontal-left.svg';
|
10
|
+
import alignHorizontalCenter from '../../../../assets/icons/align-horizontal-center.svg';
|
11
|
+
import verticalDistribute from '../../../../assets/icons/vertical-distribute.svg';
|
12
|
+
import horizontalDistribute from '../../../../assets/icons/horizontal-distribute.svg';
|
3
13
|
|
4
|
-
const inputSetStyle:
|
5
|
-
|
14
|
+
const inputSetStyle: CSSProperties = { marginRight: '1rem', display: 'flex', alignItems: 'center' };
|
15
|
+
|
16
|
+
const inputStyle: CSSProperties = {
|
17
|
+
width: 70,
|
18
|
+
border: '1px solid #767676',
|
19
|
+
borderRadius: 2,
|
20
|
+
color: '#333',
|
21
|
+
background: 'none',
|
22
|
+
};
|
23
|
+
|
24
|
+
const buttonStyle: CSSProperties = {
|
6
25
|
display: 'flex',
|
26
|
+
background: 'none',
|
7
27
|
alignItems: 'center',
|
28
|
+
borderRadius: 2,
|
29
|
+
border: '1px solid rgb(118, 118, 118)',
|
30
|
+
cursor: 'pointer',
|
8
31
|
};
|
9
32
|
|
10
33
|
const PositionAndSizeEditor = (
|
11
|
-
props: Pick<SidebarProps, 'pageSize' | 'changeSchemas' | '
|
34
|
+
props: Pick<SidebarProps, 'pageSize' | 'schemas' | 'changeSchemas' | 'activeElements'> & {
|
35
|
+
activeSchema: SchemaForUI;
|
36
|
+
}
|
12
37
|
) => {
|
13
|
-
const { changeSchemas, activeSchema, pageSize } = props;
|
38
|
+
const { changeSchemas, schemas, activeSchema, activeElements, pageSize } = props;
|
39
|
+
|
40
|
+
const align = (type: 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom') => {
|
41
|
+
const ids = activeElements.map((ae) => ae.id);
|
42
|
+
const ass = schemas.filter((s) => ids.includes(s.id));
|
43
|
+
|
44
|
+
const isVertical = ['left', 'center', 'right'].includes(type);
|
45
|
+
const tgtPos = isVertical ? 'x' : 'y';
|
46
|
+
const tgtSize = isVertical ? 'width' : 'height';
|
47
|
+
const isSingle = ass.length === 1;
|
48
|
+
const root = pageSize[tgtSize];
|
49
|
+
|
50
|
+
const min = isSingle ? 0 : Math.min(...ass.map((as) => as.position[tgtPos]));
|
51
|
+
const max = isSingle ? root : Math.max(...ass.map((as) => as.position[tgtPos] + as[tgtSize]));
|
52
|
+
|
53
|
+
let basePos = min;
|
54
|
+
let adjust = (_: number) => 0;
|
55
|
+
|
56
|
+
if (['center', 'middle'].includes(type)) {
|
57
|
+
basePos = (min + max) / 2;
|
58
|
+
adjust = (num: number) => num / 2;
|
59
|
+
} else if (['right', 'bottom'].includes(type)) {
|
60
|
+
basePos = max;
|
61
|
+
adjust = (num: number) => num;
|
62
|
+
}
|
63
|
+
|
64
|
+
changeSchemas(
|
65
|
+
ass.map((as) => ({
|
66
|
+
key: `position.${tgtPos}`,
|
67
|
+
value: round(basePos - adjust(as[tgtSize]), 2),
|
68
|
+
schemaId: as.id,
|
69
|
+
}))
|
70
|
+
);
|
71
|
+
};
|
72
|
+
|
73
|
+
const distribute = (type: 'vertical' | 'horizontal') => {
|
74
|
+
const ids = activeElements.map((ae) => ae.id);
|
75
|
+
const ass = schemas.filter((s) => ids.includes(s.id));
|
76
|
+
|
77
|
+
const isVertical = type === 'vertical';
|
78
|
+
const tgtPos = isVertical ? 'y' : 'x';
|
79
|
+
const tgtSize = isVertical ? 'height' : 'width';
|
80
|
+
const min = Math.min(...ass.map((as) => as.position[tgtPos]));
|
81
|
+
const max = Math.max(...ass.map((as) => as.position[tgtPos] + as[tgtSize]));
|
82
|
+
|
83
|
+
if (ass.length < 3) return;
|
84
|
+
|
85
|
+
const boxPos = min;
|
86
|
+
const boxSize = max - min;
|
87
|
+
const sum = ass.reduce((acc, cur) => acc + cur[tgtSize], 0);
|
88
|
+
const remain = boxSize - sum;
|
89
|
+
const unit = remain / (ass.length - 1);
|
90
|
+
|
91
|
+
let prev = 0;
|
92
|
+
changeSchemas(
|
93
|
+
ass.map((as, index) => {
|
94
|
+
prev += index === 0 ? 0 : ass[index - 1][tgtSize] + unit;
|
95
|
+
const value = round(boxPos + prev, 2);
|
96
|
+
return { key: `position.${tgtPos}`, value, schemaId: as.id };
|
97
|
+
})
|
98
|
+
);
|
99
|
+
};
|
100
|
+
|
101
|
+
const layoutBtns: { id: string; icon: any; action: () => void }[] = [
|
102
|
+
{ id: 'left', icon: alignHorizontalLeft, action: () => align('left') },
|
103
|
+
{ id: 'center', icon: alignHorizontalCenter, action: () => align('center') },
|
104
|
+
{ id: 'right', icon: alignHorizontalRight, action: () => align('right') },
|
105
|
+
{ id: 'top', icon: alignVerticalTop, action: () => align('top') },
|
106
|
+
{ id: 'middle', icon: alignVerticalMiddle, action: () => align('middle') },
|
107
|
+
{ id: 'bottom', icon: alignVerticalBottom, action: () => align('bottom') },
|
108
|
+
{ id: 'vertical', icon: verticalDistribute, action: () => distribute('vertical') },
|
109
|
+
{ id: 'horizontal', icon: horizontalDistribute, action: () => distribute('horizontal') },
|
110
|
+
];
|
14
111
|
|
15
112
|
return (
|
16
113
|
<div>
|
17
|
-
<div
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
}
|
23
|
-
>
|
114
|
+
<div style={{ display: 'flex', alignItems: 'center', marginBottom: '0.5rem' }}>
|
115
|
+
{layoutBtns.map((b) => (
|
116
|
+
<button key={b.id} title={b.id} onClick={b.action} style={buttonStyle}>
|
117
|
+
<img width={15} src={b.icon} />
|
118
|
+
</button>
|
119
|
+
))}
|
120
|
+
</div>
|
121
|
+
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
24
122
|
<div style={inputSetStyle}>
|
25
123
|
<label style={{ width: 17 }}>X</label>
|
26
124
|
<input
|
27
|
-
style={
|
125
|
+
style={inputStyle}
|
28
126
|
type="number"
|
29
127
|
onChange={(e) => {
|
30
128
|
const value = Number(e.target.value);
|
@@ -39,7 +137,7 @@ const PositionAndSizeEditor = (
|
|
39
137
|
<div style={inputSetStyle}>
|
40
138
|
<label style={{ width: 17 }}>Y</label>
|
41
139
|
<input
|
42
|
-
style={
|
140
|
+
style={inputStyle}
|
43
141
|
type="number"
|
44
142
|
onChange={(e) => {
|
45
143
|
const value = Number(e.target.value);
|
@@ -52,18 +150,11 @@ const PositionAndSizeEditor = (
|
|
52
150
|
<span style={{ fontSize: '0.6rem' }}>mm</span>
|
53
151
|
</div>
|
54
152
|
</div>
|
55
|
-
<div
|
56
|
-
style={{
|
57
|
-
display: 'flex',
|
58
|
-
alignItems: 'center',
|
59
|
-
justifyContent: 'space-between',
|
60
|
-
marginTop: '0.25rem',
|
61
|
-
}}
|
62
|
-
>
|
153
|
+
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
63
154
|
<div style={inputSetStyle}>
|
64
155
|
<label style={{ width: 17 }}>W</label>
|
65
156
|
<input
|
66
|
-
style={
|
157
|
+
style={inputStyle}
|
67
158
|
type="number"
|
68
159
|
onChange={(e) => {
|
69
160
|
const value = Number(e.target.value);
|
@@ -78,7 +169,7 @@ const PositionAndSizeEditor = (
|
|
78
169
|
<div style={inputSetStyle}>
|
79
170
|
<label style={{ width: 17 }}>H</label>
|
80
171
|
<input
|
81
|
-
style={
|
172
|
+
style={inputStyle}
|
82
173
|
type="number"
|
83
174
|
onChange={(e) => {
|
84
175
|
const value = Number(e.target.value);
|
@@ -1,12 +1,24 @@
|
|
1
1
|
import React, { useContext } from 'react';
|
2
2
|
import {
|
3
|
+
SchemaForUI,
|
3
4
|
getFallbackFontName,
|
4
5
|
DEFAULT_FONT_SIZE,
|
5
6
|
DEFAULT_LINE_HEIGHT,
|
6
7
|
DEFAULT_CHARACTER_SPACING,
|
8
|
+
DEFAULT_FONT_COLOR,
|
7
9
|
} from '@pdfme/common';
|
8
10
|
import { FontContext } from '../../../../contexts';
|
9
11
|
import { SidebarProps } from '..';
|
12
|
+
import closeIcon from '../../../../assets/icons/close.svg';
|
13
|
+
|
14
|
+
const inputStyle = {
|
15
|
+
width: '90%',
|
16
|
+
color: '#333',
|
17
|
+
background: 'none',
|
18
|
+
borderRadius: 2,
|
19
|
+
border: '1px solid #767676',
|
20
|
+
};
|
21
|
+
const selectStyle = inputStyle;
|
10
22
|
|
11
23
|
const NumberInputSet = (props: {
|
12
24
|
width: string;
|
@@ -19,7 +31,7 @@ const NumberInputSet = (props: {
|
|
19
31
|
return (
|
20
32
|
<div style={{ width }}>
|
21
33
|
<label>{label}</label>
|
22
|
-
<input style={
|
34
|
+
<input style={inputStyle} onChange={onChange} value={value} type="number" />
|
23
35
|
</div>
|
24
36
|
);
|
25
37
|
};
|
@@ -36,8 +48,20 @@ const ColorInputSet = (props: {
|
|
36
48
|
<div style={{ width: '45%' }}>
|
37
49
|
<label>{label}</label>
|
38
50
|
<div style={{ display: 'flex' }}>
|
39
|
-
<input onChange={onChange} value={value} type="color" style={
|
40
|
-
<button
|
51
|
+
<input onChange={onChange} value={value || '#ffffff'} type="color" style={inputStyle} />
|
52
|
+
<button
|
53
|
+
onClick={onClear}
|
54
|
+
style={{
|
55
|
+
display: 'flex',
|
56
|
+
background: 'none',
|
57
|
+
alignItems: 'center',
|
58
|
+
borderRadius: 2,
|
59
|
+
border: '1px solid #767676',
|
60
|
+
cursor: 'pointer',
|
61
|
+
}}
|
62
|
+
>
|
63
|
+
<img src={closeIcon} width={10} alt="Close icon" />
|
64
|
+
</button>
|
41
65
|
</div>
|
42
66
|
</div>
|
43
67
|
);
|
@@ -54,7 +78,7 @@ const SelectSet = (props: {
|
|
54
78
|
return (
|
55
79
|
<div style={{ width: '45%' }}>
|
56
80
|
<label>{label}:</label>
|
57
|
-
<select style={
|
81
|
+
<select style={selectStyle} onChange={onChange} value={value}>
|
58
82
|
{options.map((o) => (
|
59
83
|
<option key={o} value={o}>
|
60
84
|
{o}
|
@@ -65,7 +89,9 @@ const SelectSet = (props: {
|
|
65
89
|
);
|
66
90
|
};
|
67
91
|
|
68
|
-
const TextPropEditor = (
|
92
|
+
const TextPropEditor = (
|
93
|
+
props: Pick<SidebarProps, 'changeSchemas'> & { activeSchema: SchemaForUI }
|
94
|
+
) => {
|
69
95
|
const { changeSchemas, activeSchema } = props;
|
70
96
|
const alignments = ['left', 'center', 'right'];
|
71
97
|
const font = useContext(FontContext);
|
@@ -80,6 +106,7 @@ const TextPropEditor = (props: Pick<SidebarProps, 'changeSchemas' | 'activeSchem
|
|
80
106
|
display: 'flex',
|
81
107
|
alignItems: 'center',
|
82
108
|
justifyContent: 'space-between',
|
109
|
+
marginBottom: '0.25rem',
|
83
110
|
}}
|
84
111
|
>
|
85
112
|
<SelectSet
|
@@ -105,6 +132,7 @@ const TextPropEditor = (props: Pick<SidebarProps, 'changeSchemas' | 'activeSchem
|
|
105
132
|
display: 'flex',
|
106
133
|
alignItems: 'center',
|
107
134
|
justifyContent: 'space-between',
|
135
|
+
marginBottom: '0.25rem',
|
108
136
|
}}
|
109
137
|
>
|
110
138
|
<NumberInputSet
|
@@ -154,7 +182,9 @@ const TextPropEditor = (props: Pick<SidebarProps, 'changeSchemas' | 'activeSchem
|
|
154
182
|
changeSchemas([{ key: 'fontColor', value: e.target.value, schemaId: activeSchema.id }])
|
155
183
|
}
|
156
184
|
onClear={() =>
|
157
|
-
changeSchemas([
|
185
|
+
changeSchemas([
|
186
|
+
{ key: 'fontColor', value: DEFAULT_FONT_COLOR, schemaId: activeSchema.id },
|
187
|
+
])
|
158
188
|
}
|
159
189
|
/>
|
160
190
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React, { useContext, useRef, useCallback } from 'react';
|
2
|
-
import { schemaTypes } from '@pdfme/common';
|
2
|
+
import { schemaTypes, SchemaForUI } from '@pdfme/common';
|
3
3
|
import { SidebarProps } from '..';
|
4
4
|
import { I18nContext } from '../../../../contexts';
|
5
5
|
|
@@ -12,7 +12,7 @@ const ErrorLabel = ({ isError, msg }: { isError: boolean; msg: string }) => (
|
|
12
12
|
);
|
13
13
|
|
14
14
|
const TypeAndKeyEditor = (
|
15
|
-
props: Pick<SidebarProps, 'schemas' | 'changeSchemas'
|
15
|
+
props: Pick<SidebarProps, 'schemas' | 'changeSchemas'> & { activeSchema: SchemaForUI }
|
16
16
|
) => {
|
17
17
|
const { changeSchemas, activeSchema, schemas } = props;
|
18
18
|
const i18n = useContext(I18nContext);
|
@@ -37,7 +37,13 @@ const TypeAndKeyEditor = (
|
|
37
37
|
<div>
|
38
38
|
<label style={{ marginBottom: 0 }}>{i18n('type')}</label>
|
39
39
|
<select
|
40
|
-
style={{
|
40
|
+
style={{
|
41
|
+
width: '100%',
|
42
|
+
border: '1px solid #767676',
|
43
|
+
borderRadius: 2,
|
44
|
+
color: '#333',
|
45
|
+
background: 'none',
|
46
|
+
}}
|
41
47
|
onChange={(e) =>
|
42
48
|
changeSchemas([{ key: 'type', value: e.target.value, schemaId: activeSchema.id }])
|
43
49
|
}
|
@@ -50,7 +56,7 @@ const TypeAndKeyEditor = (
|
|
50
56
|
))}
|
51
57
|
</select>
|
52
58
|
</div>
|
53
|
-
<div
|
59
|
+
<div>
|
54
60
|
<label style={{ marginBottom: 0 }}>
|
55
61
|
{i18n('fieldName')}
|
56
62
|
<u style={{ fontSize: '0.7rem' }}>
|
@@ -65,9 +71,11 @@ const TypeAndKeyEditor = (
|
|
65
71
|
changeSchemas([{ key: 'key', value: e.target.value, schemaId: activeSchema.id }])
|
66
72
|
}
|
67
73
|
style={{
|
68
|
-
|
74
|
+
width: '100%',
|
69
75
|
border: '1px solid #767676',
|
70
|
-
|
76
|
+
borderRadius: 2,
|
77
|
+
color: '#333',
|
78
|
+
background: hasSameKey || blankKey ? '#ffa19b' : 'none',
|
71
79
|
}}
|
72
80
|
value={activeSchema.key}
|
73
81
|
/>
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import React, { useContext } from 'react';
|
2
|
+
import { SchemaForUI } from '@pdfme/common';
|
2
3
|
import { I18nContext } from '../../../../contexts';
|
3
4
|
import Divider from '../../../Divider';
|
4
5
|
import { SidebarProps } from '..';
|
@@ -8,31 +9,35 @@ import PositionAndSizeEditor from './PositionAndSizeEditor';
|
|
8
9
|
import TypeAndKeyEditor from './TypeAndKeyEditor';
|
9
10
|
|
10
11
|
const DetailView = (
|
11
|
-
props: Pick<SidebarProps, 'schemas' | 'pageSize' | 'changeSchemas' | '
|
12
|
+
props: Pick<SidebarProps, 'schemas' | 'pageSize' | 'changeSchemas' | 'activeElements'> & {
|
13
|
+
activeSchema: SchemaForUI;
|
14
|
+
}
|
12
15
|
) => {
|
13
16
|
const { activeSchema } = props;
|
14
17
|
const i18n = useContext(I18nContext);
|
15
18
|
|
16
19
|
return (
|
17
|
-
<
|
20
|
+
<div>
|
18
21
|
<div style={{ height: 40, display: 'flex', alignItems: 'center' }}>
|
19
|
-
<
|
22
|
+
<span style={{ textAlign: 'center', width: '100%', fontWeight: 'bold' }}>
|
20
23
|
{i18n('editField')}
|
21
|
-
</
|
24
|
+
</span>
|
22
25
|
</div>
|
23
26
|
<Divider />
|
24
|
-
<
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
<div style={{ fontSize: '0.9rem' }}>
|
28
|
+
<TypeAndKeyEditor {...props} />
|
29
|
+
<Divider />
|
30
|
+
<PositionAndSizeEditor {...props} />
|
31
|
+
<Divider />
|
32
|
+
{activeSchema.type === 'text' && (
|
33
|
+
<>
|
34
|
+
<TextPropEditor {...props} />
|
35
|
+
<Divider />
|
36
|
+
</>
|
37
|
+
)}
|
38
|
+
<ExampleInputEditor {...props} />
|
39
|
+
</div>
|
40
|
+
</div>
|
36
41
|
);
|
37
42
|
};
|
38
43
|
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import React, { useEffect, useContext } from 'react';
|
2
|
+
import { DraggableSyntheticListeners } from '@dnd-kit/core';
|
3
|
+
import { I18nContext } from '../../../../contexts';
|
4
|
+
import dragIcon from '../../../../assets/icons/drag.svg';
|
5
|
+
import warningIcon from '../../../../assets/icons/warning.svg';
|
6
|
+
|
7
|
+
interface Props {
|
8
|
+
value: React.ReactNode;
|
9
|
+
style?: React.CSSProperties;
|
10
|
+
status?: 'is-warning' | 'is-danger';
|
11
|
+
title?: string;
|
12
|
+
dragOverlay?: boolean;
|
13
|
+
onClick?: () => void;
|
14
|
+
onMouseEnter?: () => void;
|
15
|
+
onMouseLeave?: () => void;
|
16
|
+
dragging?: boolean;
|
17
|
+
sorting?: boolean;
|
18
|
+
transition?: string;
|
19
|
+
transform?: { x: number; y: number; scaleX: number; scaleY: number } | null;
|
20
|
+
fadeIn?: boolean;
|
21
|
+
listeners?: DraggableSyntheticListeners;
|
22
|
+
}
|
23
|
+
const Item = React.memo(
|
24
|
+
React.forwardRef<HTMLLIElement, Props>(
|
25
|
+
(
|
26
|
+
{
|
27
|
+
value,
|
28
|
+
status,
|
29
|
+
title,
|
30
|
+
style,
|
31
|
+
dragOverlay,
|
32
|
+
onClick,
|
33
|
+
onMouseEnter,
|
34
|
+
onMouseLeave,
|
35
|
+
dragging,
|
36
|
+
fadeIn,
|
37
|
+
listeners,
|
38
|
+
sorting,
|
39
|
+
transition,
|
40
|
+
transform,
|
41
|
+
...props
|
42
|
+
},
|
43
|
+
ref
|
44
|
+
) => {
|
45
|
+
const i18n = useContext(I18nContext);
|
46
|
+
|
47
|
+
useEffect(() => {
|
48
|
+
if (!dragOverlay) {
|
49
|
+
return;
|
50
|
+
}
|
51
|
+
|
52
|
+
document.body.style.cursor = 'grabbing';
|
53
|
+
|
54
|
+
return () => {
|
55
|
+
document.body.style.cursor = '';
|
56
|
+
};
|
57
|
+
}, [dragOverlay]);
|
58
|
+
|
59
|
+
const { x, y, scaleX, scaleY } = transform || { x: 0, y: 0, scaleX: 1, scaleY: 1 };
|
60
|
+
|
61
|
+
return (
|
62
|
+
<li
|
63
|
+
style={{
|
64
|
+
transition,
|
65
|
+
transform: `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`,
|
66
|
+
}}
|
67
|
+
onMouseEnter={onMouseEnter}
|
68
|
+
onMouseLeave={onMouseLeave}
|
69
|
+
ref={ref}
|
70
|
+
>
|
71
|
+
<div style={{ display: 'flex', alignItems: 'center', ...style }} {...props}>
|
72
|
+
<button
|
73
|
+
{...listeners}
|
74
|
+
style={{ padding: '0.5rem', background: 'none', border: 'none', display: 'flex' }}
|
75
|
+
>
|
76
|
+
<img style={{ cursor: 'grab' }} src={dragIcon} width={15} alt="Drag icon" />
|
77
|
+
</button>
|
78
|
+
<div
|
79
|
+
style={{
|
80
|
+
width: '100%',
|
81
|
+
padding: '0.5rem',
|
82
|
+
paddingLeft: 0,
|
83
|
+
cursor: 'pointer',
|
84
|
+
overflow: 'hidden',
|
85
|
+
whiteSpace: 'nowrap',
|
86
|
+
textOverflow: 'ellipsis',
|
87
|
+
}}
|
88
|
+
title={title || ''}
|
89
|
+
onClick={() => onClick && onClick()}
|
90
|
+
>
|
91
|
+
{status === undefined ? (
|
92
|
+
value
|
93
|
+
) : (
|
94
|
+
<span style={{ display: 'flex', alignItems: 'center' }}>
|
95
|
+
<img
|
96
|
+
alt="Warning icon"
|
97
|
+
src={warningIcon}
|
98
|
+
width={15}
|
99
|
+
style={{ marginRight: '0.5rem' }}
|
100
|
+
/>
|
101
|
+
{status === 'is-warning' ? i18n('noKeyName') : value}
|
102
|
+
{status === 'is-danger' ? i18n('notUniq') : ''}
|
103
|
+
</span>
|
104
|
+
)}
|
105
|
+
</div>
|
106
|
+
</div>
|
107
|
+
</li>
|
108
|
+
);
|
109
|
+
}
|
110
|
+
)
|
111
|
+
);
|
112
|
+
|
113
|
+
export default Item;
|