@pdfme/ui 1.0.3 → 1.0.6
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 +30 -2
- package/dist/index.js +1 -1
- package/dist/index.js.LICENSE.txt +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/class.d.ts +1 -1
- package/dist/types/components/{Preview/Pager/Page.d.ts → CtlBar/Pager.d.ts} +0 -0
- package/dist/types/components/CtlBar/Zoom.d.ts +6 -0
- package/dist/types/components/CtlBar/index.d.ts +9 -0
- package/dist/types/components/Paper.d.ts +2 -2
- package/dist/types/components/{Preview/index.d.ts → Preview.d.ts} +0 -0
- package/dist/types/components/{Preview/Pager/Unit.d.ts → UnitPager.d.ts} +0 -0
- package/dist/types/contexts.d.ts +1 -1
- package/dist/types/helper.d.ts +5 -0
- package/dist/types/hooks.d.ts +4 -4
- package/dist/types/i18n.d.ts +2 -0
- package/package.json +9 -1
- package/src/assets/icons/add.svg +3 -0
- package/src/assets/icons/remove.svg +3 -0
- package/src/components/CtlBar/Pager.tsx +52 -0
- package/src/components/CtlBar/Zoom.tsx +57 -0
- package/src/components/CtlBar/index.tsx +46 -0
- package/src/components/Designer/Main/index.tsx +2 -2
- package/src/components/Designer/Sidebar/index.tsx +9 -4
- package/src/components/Designer/index.tsx +28 -12
- package/src/components/Error.tsx +1 -1
- package/src/components/Paper.tsx +4 -2
- package/src/components/{Preview/index.tsx → Preview.tsx} +32 -35
- package/src/components/Root.tsx +1 -2
- package/src/components/Schemas/SchemaUI.tsx +1 -0
- package/src/components/Schemas/TextSchema.tsx +0 -1
- package/src/components/{Preview/Pager/Unit.tsx → UnitPager.tsx} +20 -10
- package/src/helper.ts +21 -0
- package/src/hooks.ts +16 -18
- package/src/i18n.ts +4 -0
- package/src/components/Preview/Pager/Page.tsx +0 -85
@@ -1,9 +1,9 @@
|
|
1
1
|
import React, { useContext } from 'react';
|
2
|
-
import left from '
|
3
|
-
import right from '
|
4
|
-
import doubleLeft from '
|
5
|
-
import doubleRight from '
|
6
|
-
import { I18nContext } from '
|
2
|
+
import left from '../assets/icons/left.svg';
|
3
|
+
import right from '../assets/icons/right.svg';
|
4
|
+
import doubleLeft from '../assets/icons/double-left.svg';
|
5
|
+
import doubleRight from '../assets/icons/double-right.svg';
|
6
|
+
import { I18nContext } from '../contexts';
|
7
7
|
|
8
8
|
const buttonWrapStyle: React.CSSProperties = {
|
9
9
|
position: 'sticky',
|
@@ -14,7 +14,8 @@ const buttonWrapStyle: React.CSSProperties = {
|
|
14
14
|
padding: '0.5rem',
|
15
15
|
display: 'flex',
|
16
16
|
alignItems: 'center',
|
17
|
-
|
17
|
+
justifyContent: 'space-around',
|
18
|
+
width: 110,
|
18
19
|
};
|
19
20
|
|
20
21
|
const btnStyle: React.CSSProperties = {
|
@@ -37,7 +38,16 @@ const UnitPager = ({ unitCursor, unitNum, setUnitCursor }: Props) => {
|
|
37
38
|
if (unitNum <= 1) return <></>;
|
38
39
|
|
39
40
|
return (
|
40
|
-
|
41
|
+
<div
|
42
|
+
style={{
|
43
|
+
position: 'fixed',
|
44
|
+
width: '100%',
|
45
|
+
zIndex: 1,
|
46
|
+
top: '50%',
|
47
|
+
display: 'flex',
|
48
|
+
alignItems: 'center',
|
49
|
+
}}
|
50
|
+
>
|
41
51
|
{unitCursor > 0 && (
|
42
52
|
<div style={{ marginLeft: '1rem', ...buttonWrapStyle }}>
|
43
53
|
<button
|
@@ -54,14 +64,14 @@ const UnitPager = ({ unitCursor, unitNum, setUnitCursor }: Props) => {
|
|
54
64
|
>
|
55
65
|
<img src={left} alt={i18n('goToPrevious')} style={{ width: 20 }} />
|
56
66
|
</button>
|
57
|
-
<strong style={{ color: 'white' }}>
|
67
|
+
<strong style={{ color: 'white', fontSize: '0.9rem' }}>
|
58
68
|
{unitCursor + 1}/{unitNum}
|
59
69
|
</strong>
|
60
70
|
</div>
|
61
71
|
)}
|
62
72
|
{unitCursor + 1 < unitNum && (
|
63
73
|
<div style={{ marginLeft: 'auto', marginRight: '1rem', ...buttonWrapStyle }}>
|
64
|
-
<strong style={{ color: 'white' }}>
|
74
|
+
<strong style={{ color: 'white', fontSize: '0.9rem' }}>
|
65
75
|
{unitCursor + 1}/{unitNum}
|
66
76
|
</strong>
|
67
77
|
<button
|
@@ -80,7 +90,7 @@ const UnitPager = ({ unitCursor, unitNum, setUnitCursor }: Props) => {
|
|
80
90
|
</button>
|
81
91
|
</div>
|
82
92
|
)}
|
83
|
-
|
93
|
+
</div>
|
84
94
|
);
|
85
95
|
};
|
86
96
|
|
package/src/helper.ts
CHANGED
@@ -15,6 +15,7 @@ import {
|
|
15
15
|
DEFAULT_CHARACTER_SPACING,
|
16
16
|
DEFAULT_LINE_HEIGHT,
|
17
17
|
} from '@pdfme/common';
|
18
|
+
import { ZOOM, RULER_HEIGHT } from './constants';
|
18
19
|
|
19
20
|
export const uuid = () =>
|
20
21
|
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
@@ -233,6 +234,13 @@ const pt2mm = (pt: number) => {
|
|
233
234
|
return parseFloat(String(pt)) * mmRatio;
|
234
235
|
};
|
235
236
|
|
237
|
+
export const px2mm = (px: number) => {
|
238
|
+
// http://www.unitconversion.org/typography/millimeters-to-pixels-y-conversion.html
|
239
|
+
const mmRatio = 0.264583333;
|
240
|
+
|
241
|
+
return parseFloat(String(px)) * mmRatio;
|
242
|
+
};
|
243
|
+
|
236
244
|
export const getPdfPageSizes = async (pdfBlob: Blob) => {
|
237
245
|
const url = URL.createObjectURL(pdfBlob);
|
238
246
|
const pdfDoc = await getDocument({ url }).promise;
|
@@ -520,3 +528,16 @@ export const moveCommandToChangeSchemasArg = (props: {
|
|
520
528
|
return { key: `position.${key}`, value, schemaId: as.id };
|
521
529
|
});
|
522
530
|
};
|
531
|
+
|
532
|
+
export const getPagesScrollTopByIndex = (
|
533
|
+
pageSizes: {
|
534
|
+
width: number;
|
535
|
+
height: number;
|
536
|
+
}[],
|
537
|
+
index: number,
|
538
|
+
scale: number
|
539
|
+
) => {
|
540
|
+
return pageSizes
|
541
|
+
.slice(0, index)
|
542
|
+
.reduce((acc, cur) => acc + (cur.height * ZOOM + RULER_HEIGHT * scale) * scale, 0);
|
543
|
+
};
|
package/src/hooks.ts
CHANGED
@@ -14,9 +14,9 @@ export const usePrevious = <T>(value: T) => {
|
|
14
14
|
|
15
15
|
const getScale = (n: number, paper: number) => (n / paper > 1 ? 1 : n / paper);
|
16
16
|
|
17
|
-
type UIPreProcessorProps = { template: Template; size: Size;
|
17
|
+
type UIPreProcessorProps = { template: Template; size: Size; zoomLevel: number };
|
18
18
|
|
19
|
-
export const useUIPreProcessor = ({ template, size,
|
19
|
+
export const useUIPreProcessor = ({ template, size, zoomLevel }: UIPreProcessorProps) => {
|
20
20
|
const [backgrounds, setBackgrounds] = useState<string[]>([]);
|
21
21
|
const [pageSizes, setPageSizes] = useState<Size[]>([]);
|
22
22
|
const [scale, setScale] = useState(0);
|
@@ -32,18 +32,16 @@ export const useUIPreProcessor = ({ template, size, offset = 0 }: UIPreProcessor
|
|
32
32
|
|
33
33
|
const _scale = Math.min(
|
34
34
|
getScale(size.width, paperWidth),
|
35
|
-
getScale(size.height -
|
35
|
+
getScale(size.height - RULER_HEIGHT, paperHeight)
|
36
36
|
);
|
37
37
|
|
38
38
|
return { backgrounds: _backgrounds, pageSizes: _pageSizes, scale: _scale };
|
39
|
-
}, [template, size
|
39
|
+
}, [template, size]);
|
40
40
|
|
41
41
|
useEffect(() => {
|
42
42
|
init()
|
43
|
-
.then((
|
44
|
-
setPageSizes(
|
45
|
-
setScale(data.scale);
|
46
|
-
setBackgrounds(data.backgrounds);
|
43
|
+
.then(({ pageSizes, scale, backgrounds }) => {
|
44
|
+
setPageSizes(pageSizes), setScale(scale), setBackgrounds(backgrounds);
|
47
45
|
})
|
48
46
|
.catch((e: Error) => {
|
49
47
|
console.error(e);
|
@@ -51,11 +49,11 @@ export const useUIPreProcessor = ({ template, size, offset = 0 }: UIPreProcessor
|
|
51
49
|
});
|
52
50
|
}, [init]);
|
53
51
|
|
54
|
-
return { backgrounds, pageSizes, scale, error };
|
52
|
+
return { backgrounds, pageSizes, scale: scale * zoomLevel, error };
|
55
53
|
};
|
56
54
|
|
57
55
|
type ScrollPageCursorProps = {
|
58
|
-
|
56
|
+
ref: RefObject<HTMLDivElement>;
|
59
57
|
pageSizes: Size[];
|
60
58
|
scale: number;
|
61
59
|
pageCursor: number;
|
@@ -63,19 +61,19 @@ type ScrollPageCursorProps = {
|
|
63
61
|
};
|
64
62
|
|
65
63
|
export const useScrollPageCursor = ({
|
66
|
-
|
64
|
+
ref,
|
67
65
|
pageSizes,
|
68
66
|
scale,
|
69
67
|
pageCursor,
|
70
68
|
onChangePageCursor,
|
71
69
|
}: ScrollPageCursorProps) => {
|
72
70
|
const onScroll = useCallback(() => {
|
73
|
-
if (!pageSizes[0] || !
|
71
|
+
if (!pageSizes[0] || !ref.current) {
|
74
72
|
return;
|
75
73
|
}
|
76
74
|
|
77
|
-
const scroll =
|
78
|
-
const { top } =
|
75
|
+
const scroll = ref.current.scrollTop;
|
76
|
+
const { top } = ref.current.getBoundingClientRect();
|
79
77
|
const pageHeights = pageSizes.reduce((acc, cur, i) => {
|
80
78
|
let value = (cur.height * ZOOM + RULER_HEIGHT) * scale;
|
81
79
|
if (i === 0) {
|
@@ -95,15 +93,15 @@ export const useScrollPageCursor = ({
|
|
95
93
|
if (_pageCursor !== pageCursor) {
|
96
94
|
onChangePageCursor(_pageCursor);
|
97
95
|
}
|
98
|
-
}, [onChangePageCursor, pageCursor, pageSizes,
|
96
|
+
}, [onChangePageCursor, pageCursor, pageSizes, ref, scale]);
|
99
97
|
|
100
98
|
useEffect(() => {
|
101
|
-
|
99
|
+
ref.current?.addEventListener('scroll', onScroll);
|
102
100
|
|
103
101
|
return () => {
|
104
|
-
|
102
|
+
ref.current?.removeEventListener('scroll', onScroll);
|
105
103
|
};
|
106
|
-
}, [
|
104
|
+
}, [ref, onScroll]);
|
107
105
|
};
|
108
106
|
|
109
107
|
export const useMountStatus = () => {
|
package/src/i18n.ts
CHANGED
@@ -26,6 +26,8 @@ const dictEn = {
|
|
26
26
|
goToNext: 'Next',
|
27
27
|
goToEnd: 'Go to end',
|
28
28
|
select: 'Select',
|
29
|
+
zoomIn: 'Zoom in',
|
30
|
+
zoomOut: 'Zoom out',
|
29
31
|
errorOccurred: 'An error occurred',
|
30
32
|
errorBulkUpdateFieldName:
|
31
33
|
'Cannot commit the change because the number of items has been changed.',
|
@@ -56,6 +58,8 @@ const dictJa: { [key in keyof DictEn]: string } = {
|
|
56
58
|
goToNext: '1つ進む',
|
57
59
|
goToEnd: '最後に進む',
|
58
60
|
select: '選択',
|
61
|
+
zoomIn: '拡大',
|
62
|
+
zoomOut: '縮小',
|
59
63
|
errorOccurred: 'エラーが発生しました',
|
60
64
|
errorBulkUpdateFieldName: '項目数が変更されているため変更をコミットできません。',
|
61
65
|
commitBulkUpdateFieldName: '変更を反映',
|
@@ -1,85 +0,0 @@
|
|
1
|
-
import React, { useContext } from 'react';
|
2
|
-
import left from '../../../assets/icons/left.svg';
|
3
|
-
import right from '../../../assets/icons/right.svg';
|
4
|
-
import doubleLeft from '../../../assets/icons/double-left.svg';
|
5
|
-
import doubleRight from '../../../assets/icons/double-right.svg';
|
6
|
-
import { I18nContext } from '../../../contexts';
|
7
|
-
|
8
|
-
const btnStyle: React.CSSProperties = {
|
9
|
-
cursor: 'pointer',
|
10
|
-
border: 'none',
|
11
|
-
background: 'none',
|
12
|
-
display: 'flex',
|
13
|
-
alignItems: 'center',
|
14
|
-
};
|
15
|
-
|
16
|
-
type Props = {
|
17
|
-
pageCursor: number;
|
18
|
-
pageNum: number;
|
19
|
-
setPageCursor: (page: number) => void;
|
20
|
-
};
|
21
|
-
|
22
|
-
const Pager = ({ pageCursor, pageNum, setPageCursor }: Props) => {
|
23
|
-
const i18n = useContext(I18nContext);
|
24
|
-
|
25
|
-
if (pageNum <= 1) return <></>;
|
26
|
-
|
27
|
-
return (
|
28
|
-
<div
|
29
|
-
style={{
|
30
|
-
position: 'sticky',
|
31
|
-
top: '90%',
|
32
|
-
zIndex: 1,
|
33
|
-
display: 'flex',
|
34
|
-
alignItems: 'center',
|
35
|
-
justifyContent: 'center',
|
36
|
-
width: '100%',
|
37
|
-
}}
|
38
|
-
>
|
39
|
-
<div
|
40
|
-
style={{
|
41
|
-
display: 'flex',
|
42
|
-
alignItems: 'center',
|
43
|
-
justifyContent: 'center',
|
44
|
-
background: '#777777e6',
|
45
|
-
borderRadius: 2,
|
46
|
-
padding: '0.5rem',
|
47
|
-
}}
|
48
|
-
>
|
49
|
-
<button
|
50
|
-
style={{ paddingLeft: '0.5rem', ...btnStyle }}
|
51
|
-
disabled={pageCursor <= 0}
|
52
|
-
onClick={() => setPageCursor(0)}
|
53
|
-
>
|
54
|
-
<img src={doubleLeft} alt={i18n('goToFirst')} style={{ width: 20 }} />
|
55
|
-
</button>
|
56
|
-
<button
|
57
|
-
style={{ paddingLeft: '0.5rem', ...btnStyle }}
|
58
|
-
disabled={pageCursor <= 0}
|
59
|
-
onClick={() => setPageCursor(pageCursor - 1)}
|
60
|
-
>
|
61
|
-
<img src={left} alt={i18n('goToPrevious')} style={{ width: 20 }} />
|
62
|
-
</button>
|
63
|
-
<strong style={{ color: 'white' }}>
|
64
|
-
{pageCursor + 1}/{pageNum}
|
65
|
-
</strong>
|
66
|
-
<button
|
67
|
-
style={{ paddingRight: '0.5rem', ...btnStyle }}
|
68
|
-
disabled={pageCursor + 1 >= pageNum}
|
69
|
-
onClick={() => setPageCursor(pageCursor + 1)}
|
70
|
-
>
|
71
|
-
<img src={right} alt={i18n('goToNext')} style={{ width: 20 }} />
|
72
|
-
</button>
|
73
|
-
<button
|
74
|
-
style={{ paddingRight: '0.5rem', ...btnStyle }}
|
75
|
-
disabled={pageCursor + 1 >= pageNum}
|
76
|
-
onClick={() => setPageCursor(pageNum - 1)}
|
77
|
-
>
|
78
|
-
<img src={doubleRight} alt={i18n('goToFirst')} style={{ width: 20 }} />
|
79
|
-
</button>
|
80
|
-
</div>
|
81
|
-
</div>
|
82
|
-
);
|
83
|
-
};
|
84
|
-
|
85
|
-
export default Pager;
|