@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
package/dist/types/class.d.ts
CHANGED
@@ -7,7 +7,7 @@ export declare abstract class BaseUIClass {
|
|
7
7
|
private font;
|
8
8
|
private readonly setSize;
|
9
9
|
constructor(props: UIProps);
|
10
|
-
protected getI18n(): (key: "type" | "field" | "cancel" | "fieldName" | "require" | "uniq" | "inputExample" | "edit" | "plsSelect" | "plsInputName" | "plsAddNewField" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "goToFirst" | "goToPrevious" | "goToNext" | "goToEnd" | "select" | "errorOccurred" | "errorBulkUpdateFieldName" | "commitBulkUpdateFieldName" | "bulkUpdateFieldName") => string;
|
10
|
+
protected getI18n(): (key: "type" | "field" | "cancel" | "fieldName" | "require" | "uniq" | "inputExample" | "edit" | "plsSelect" | "plsInputName" | "plsAddNewField" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "goToFirst" | "goToPrevious" | "goToNext" | "goToEnd" | "select" | "zoomIn" | "zoomOut" | "errorOccurred" | "errorBulkUpdateFieldName" | "commitBulkUpdateFieldName" | "bulkUpdateFieldName") => string;
|
11
11
|
protected getFont(): Record<string, {
|
12
12
|
fallback?: boolean | undefined;
|
13
13
|
subset?: boolean | undefined;
|
File without changes
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import
|
1
|
+
import { MutableRefObject, ReactNode } from 'react';
|
2
2
|
import { SchemaForUI, Size } from '@pdfme/common';
|
3
3
|
declare const Paper: (porps: {
|
4
|
-
paperRefs
|
4
|
+
paperRefs: MutableRefObject<HTMLDivElement[]>;
|
5
5
|
scale: number;
|
6
6
|
size: Size;
|
7
7
|
schemasList: SchemaForUI[][];
|
File without changes
|
File without changes
|
package/dist/types/contexts.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/// <reference types="react" />
|
2
|
-
export declare const I18nContext: import("react").Context<(key: "type" | "field" | "cancel" | "fieldName" | "require" | "uniq" | "inputExample" | "edit" | "plsSelect" | "plsInputName" | "plsAddNewField" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "goToFirst" | "goToPrevious" | "goToNext" | "goToEnd" | "select" | "errorOccurred" | "errorBulkUpdateFieldName" | "commitBulkUpdateFieldName" | "bulkUpdateFieldName") => string>;
|
2
|
+
export declare const I18nContext: import("react").Context<(key: "type" | "field" | "cancel" | "fieldName" | "require" | "uniq" | "inputExample" | "edit" | "plsSelect" | "plsInputName" | "plsAddNewField" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "goToFirst" | "goToPrevious" | "goToNext" | "goToEnd" | "select" | "zoomIn" | "zoomOut" | "errorOccurred" | "errorBulkUpdateFieldName" | "commitBulkUpdateFieldName" | "bulkUpdateFieldName") => string>;
|
3
3
|
export declare const FontContext: import("react").Context<Record<string, {
|
4
4
|
fallback?: boolean | undefined;
|
5
5
|
subset?: boolean | undefined;
|
package/dist/types/helper.d.ts
CHANGED
@@ -19,6 +19,7 @@ export declare const initShortCuts: (arg: {
|
|
19
19
|
}) => void;
|
20
20
|
export declare const destroyShortCuts: () => void;
|
21
21
|
export declare const readFiles: (files: FileList | null, type: 'text' | 'dataURL' | 'arrayBuffer') => Promise<string | ArrayBuffer>;
|
22
|
+
export declare const px2mm: (px: number) => number;
|
22
23
|
export declare const getPdfPageSizes: (pdfBlob: Blob) => Promise<{
|
23
24
|
height: number;
|
24
25
|
width: number;
|
@@ -88,4 +89,8 @@ export declare const moveCommandToChangeSchemasArg: (props: {
|
|
88
89
|
value: number;
|
89
90
|
schemaId: string;
|
90
91
|
}[];
|
92
|
+
export declare const getPagesScrollTopByIndex: (pageSizes: {
|
93
|
+
width: number;
|
94
|
+
height: number;
|
95
|
+
}[], index: number, scale: number) => number;
|
91
96
|
export {};
|
package/dist/types/hooks.d.ts
CHANGED
@@ -4,9 +4,9 @@ export declare const usePrevious: <T>(value: T) => T | null;
|
|
4
4
|
declare type UIPreProcessorProps = {
|
5
5
|
template: Template;
|
6
6
|
size: Size;
|
7
|
-
|
7
|
+
zoomLevel: number;
|
8
8
|
};
|
9
|
-
export declare const useUIPreProcessor: ({ template, size,
|
9
|
+
export declare const useUIPreProcessor: ({ template, size, zoomLevel }: UIPreProcessorProps) => {
|
10
10
|
backgrounds: string[];
|
11
11
|
pageSizes: {
|
12
12
|
width: number;
|
@@ -16,12 +16,12 @@ export declare const useUIPreProcessor: ({ template, size, offset }: UIPreProces
|
|
16
16
|
error: Error | null;
|
17
17
|
};
|
18
18
|
declare type ScrollPageCursorProps = {
|
19
|
-
|
19
|
+
ref: RefObject<HTMLDivElement>;
|
20
20
|
pageSizes: Size[];
|
21
21
|
scale: number;
|
22
22
|
pageCursor: number;
|
23
23
|
onChangePageCursor: (page: number) => void;
|
24
24
|
};
|
25
|
-
export declare const useScrollPageCursor: ({
|
25
|
+
export declare const useScrollPageCursor: ({ ref, pageSizes, scale, pageCursor, onChangePageCursor, }: ScrollPageCursorProps) => void;
|
26
26
|
export declare const useMountStatus: () => boolean;
|
27
27
|
export {};
|
package/dist/types/i18n.d.ts
CHANGED
package/package.json
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
{
|
2
2
|
"name": "@pdfme/ui",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.6",
|
4
4
|
"author": "hand-dot",
|
5
5
|
"license": "MIT",
|
6
|
+
"keywords": [
|
7
|
+
"pdf",
|
8
|
+
"pdf-generation",
|
9
|
+
"pdf-designer",
|
10
|
+
"pdf-viewer",
|
11
|
+
"typescript",
|
12
|
+
"react"
|
13
|
+
],
|
6
14
|
"description": "TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!",
|
7
15
|
"homepage": "https://pdfme.com",
|
8
16
|
"repository": {
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import React, { useContext } from 'react';
|
2
|
+
import left from '../../assets/icons/left.svg';
|
3
|
+
import right from '../../assets/icons/right.svg';
|
4
|
+
import { I18nContext } from '../../contexts';
|
5
|
+
|
6
|
+
const btnStyle: React.CSSProperties = {
|
7
|
+
cursor: 'pointer',
|
8
|
+
border: 'none',
|
9
|
+
background: 'none',
|
10
|
+
display: 'flex',
|
11
|
+
alignItems: 'center',
|
12
|
+
};
|
13
|
+
|
14
|
+
type Props = {
|
15
|
+
pageCursor: number;
|
16
|
+
pageNum: number;
|
17
|
+
setPageCursor: (page: number) => void;
|
18
|
+
};
|
19
|
+
|
20
|
+
const Pager = ({ pageCursor, pageNum, setPageCursor }: Props) => {
|
21
|
+
const i18n = useContext(I18nContext);
|
22
|
+
|
23
|
+
return (
|
24
|
+
<div
|
25
|
+
style={{
|
26
|
+
display: 'flex',
|
27
|
+
alignItems: 'center',
|
28
|
+
justifyContent: 'center',
|
29
|
+
}}
|
30
|
+
>
|
31
|
+
<button
|
32
|
+
style={{ paddingLeft: '0.5rem', ...btnStyle }}
|
33
|
+
disabled={pageCursor <= 0}
|
34
|
+
onClick={() => setPageCursor(pageCursor - 1)}
|
35
|
+
>
|
36
|
+
<img src={left} alt={i18n('goToPrevious')} style={{ width: 20 }} />
|
37
|
+
</button>
|
38
|
+
<strong style={{ color: 'white', fontSize: '0.9rem' }}>
|
39
|
+
{pageCursor + 1}/{pageNum}
|
40
|
+
</strong>
|
41
|
+
<button
|
42
|
+
style={{ paddingRight: '0.5rem', ...btnStyle }}
|
43
|
+
disabled={pageCursor + 1 >= pageNum}
|
44
|
+
onClick={() => setPageCursor(pageCursor + 1)}
|
45
|
+
>
|
46
|
+
<img src={right} alt={i18n('goToNext')} style={{ width: 20 }} />
|
47
|
+
</button>
|
48
|
+
</div>
|
49
|
+
);
|
50
|
+
};
|
51
|
+
|
52
|
+
export default Pager;
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import React, { useContext } from 'react';
|
2
|
+
import { I18nContext } from '../../contexts';
|
3
|
+
import add from '../../assets/icons/add.svg';
|
4
|
+
import remove from '../../assets/icons/remove.svg';
|
5
|
+
|
6
|
+
const btnStyle: React.CSSProperties = {
|
7
|
+
cursor: 'pointer',
|
8
|
+
border: 'none',
|
9
|
+
background: 'none',
|
10
|
+
display: 'flex',
|
11
|
+
alignItems: 'center',
|
12
|
+
};
|
13
|
+
|
14
|
+
const zoomStep = 0.25;
|
15
|
+
const maxZoom = 3;
|
16
|
+
const minZoom = 0;
|
17
|
+
|
18
|
+
type Props = {
|
19
|
+
zoomLevel: number;
|
20
|
+
setZoomLevel: (zoom: number) => void;
|
21
|
+
};
|
22
|
+
|
23
|
+
const Pager = ({ zoomLevel, setZoomLevel }: Props) => {
|
24
|
+
const i18n = useContext(I18nContext);
|
25
|
+
const nextZoomOut = zoomLevel - zoomStep;
|
26
|
+
const nextZoomIn = zoomLevel + zoomStep;
|
27
|
+
|
28
|
+
return (
|
29
|
+
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
30
|
+
<button
|
31
|
+
style={{
|
32
|
+
paddingRight: '0.5rem',
|
33
|
+
...btnStyle,
|
34
|
+
cursor: minZoom >= nextZoomOut ? 'not-allowed' : 'pointer',
|
35
|
+
}}
|
36
|
+
onClick={() => setZoomLevel(nextZoomOut)}
|
37
|
+
disabled={minZoom >= nextZoomOut}
|
38
|
+
>
|
39
|
+
<img src={remove} alt={i18n('zoomOut')} style={{ width: 20 }} />
|
40
|
+
</button>
|
41
|
+
<strong style={{ color: 'white', fontSize: '0.9rem' }}>{Math.round(zoomLevel * 100)}%</strong>
|
42
|
+
<button
|
43
|
+
style={{
|
44
|
+
paddingRight: '0.5rem',
|
45
|
+
...btnStyle,
|
46
|
+
cursor: maxZoom < nextZoomIn ? 'not-allowed' : 'pointer',
|
47
|
+
}}
|
48
|
+
onClick={() => setZoomLevel(nextZoomIn)}
|
49
|
+
disabled={maxZoom < nextZoomIn}
|
50
|
+
>
|
51
|
+
<img src={add} alt={i18n('zoomIn')} style={{ width: 20 }} />
|
52
|
+
</button>
|
53
|
+
</div>
|
54
|
+
);
|
55
|
+
};
|
56
|
+
|
57
|
+
export default Pager;
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import Pager from './Pager';
|
3
|
+
import Zoom from './Zoom';
|
4
|
+
|
5
|
+
type Props = {
|
6
|
+
pageCursor: number;
|
7
|
+
pageNum: number;
|
8
|
+
setPageCursor: (page: number) => void;
|
9
|
+
zoomLevel: number;
|
10
|
+
setZoomLevel: (zoom: number) => void;
|
11
|
+
};
|
12
|
+
|
13
|
+
const barWidth = 220;
|
14
|
+
|
15
|
+
const CtlBar = (props: Props) => {
|
16
|
+
const { pageCursor, pageNum, setPageCursor, zoomLevel, setZoomLevel } = props;
|
17
|
+
const width = pageNum > 1 ? barWidth : barWidth / 2;
|
18
|
+
return (
|
19
|
+
<div
|
20
|
+
style={{
|
21
|
+
display: 'flex',
|
22
|
+
alignItems: 'center',
|
23
|
+
justifyContent: 'center',
|
24
|
+
position: 'fixed',
|
25
|
+
zIndex: 1,
|
26
|
+
top: '90%',
|
27
|
+
left: `calc(50% - ${width / 2}px)`,
|
28
|
+
width,
|
29
|
+
background: '#777777e6',
|
30
|
+
borderRadius: 2,
|
31
|
+
padding: '0.5rem',
|
32
|
+
margin: '0 auto',
|
33
|
+
}}
|
34
|
+
>
|
35
|
+
{pageNum > 1 && (
|
36
|
+
<>
|
37
|
+
<Pager pageCursor={pageCursor} pageNum={pageNum} setPageCursor={setPageCursor} />
|
38
|
+
<strong style={{ color: 'white', fontSize: '0.9rem', padding: 0 }}>|</strong>
|
39
|
+
</>
|
40
|
+
)}
|
41
|
+
<Zoom zoomLevel={zoomLevel} setZoomLevel={setZoomLevel} />
|
42
|
+
</div>
|
43
|
+
);
|
44
|
+
};
|
45
|
+
|
46
|
+
export default CtlBar;
|
@@ -218,7 +218,7 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
|
|
218
218
|
e.stopPropagation();
|
219
219
|
setEditing(false);
|
220
220
|
}}
|
221
|
-
style={{
|
221
|
+
style={{ overflowX: 'auto' }}
|
222
222
|
>
|
223
223
|
<Selecto
|
224
224
|
container={paperRefs.current[pageCursor]}
|
@@ -279,7 +279,7 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
|
|
279
279
|
{pageCursor !== index ? (
|
280
280
|
<Mask
|
281
281
|
width={paperSize.width + RULER_HEIGHT}
|
282
|
-
height={paperSize.height + RULER_HEIGHT}
|
282
|
+
height={paperSize.height + RULER_HEIGHT * scale}
|
283
283
|
/>
|
284
284
|
) : (
|
285
285
|
!editing && (
|
@@ -27,7 +27,6 @@ const Sidebar = (props: SidebarProps) => {
|
|
27
27
|
|
28
28
|
const i18n = useContext(I18nContext);
|
29
29
|
const [open, setOpen] = useState(true);
|
30
|
-
const top = 0;
|
31
30
|
|
32
31
|
const getActiveSchemas = () => {
|
33
32
|
const ids = activeElements.map((ae) => ae.id);
|
@@ -41,9 +40,15 @@ const Sidebar = (props: SidebarProps) => {
|
|
41
40
|
|
42
41
|
return (
|
43
42
|
<div
|
44
|
-
style={{
|
43
|
+
style={{
|
44
|
+
position: 'absolute',
|
45
|
+
right: 0,
|
46
|
+
zIndex: 1,
|
47
|
+
height: height ? height : '100%',
|
48
|
+
width: open ? SIDEBAR_WIDTH : 0,
|
49
|
+
}}
|
45
50
|
>
|
46
|
-
<div style={{ position: 'sticky', top, zIndex: 1, fontSize: '1rem' }}>
|
51
|
+
<div style={{ position: 'sticky', top: 0, zIndex: 1, fontSize: '1rem' }}>
|
47
52
|
<button
|
48
53
|
style={{
|
49
54
|
position: 'absolute',
|
@@ -66,7 +71,7 @@ const Sidebar = (props: SidebarProps) => {
|
|
66
71
|
width: SIDEBAR_WIDTH,
|
67
72
|
height: size.height - RULER_HEIGHT * ZOOM,
|
68
73
|
display: open ? 'block' : 'none',
|
69
|
-
top,
|
74
|
+
top: RULER_HEIGHT / 2,
|
70
75
|
right: 0,
|
71
76
|
position: 'absolute',
|
72
77
|
background: '#ffffffed',
|
@@ -17,10 +17,12 @@ import {
|
|
17
17
|
getKeepRatioHeightByWidth,
|
18
18
|
getUniqSchemaKey,
|
19
19
|
moveCommandToChangeSchemasArg,
|
20
|
+
getPagesScrollTopByIndex,
|
20
21
|
} from '../../helper';
|
21
22
|
import { useUIPreProcessor, useScrollPageCursor } from '../../hooks';
|
22
23
|
import Root from '../Root';
|
23
24
|
import Error from '../Error';
|
25
|
+
import CtlBar from '../CtlBar';
|
24
26
|
|
25
27
|
const TemplateEditor = ({
|
26
28
|
template,
|
@@ -31,22 +33,18 @@ const TemplateEditor = ({
|
|
31
33
|
const copiedSchemas = useRef<SchemaForUI[] | null>(null);
|
32
34
|
const past = useRef<SchemaForUI[][]>([]);
|
33
35
|
const future = useRef<SchemaForUI[][]>([]);
|
34
|
-
const rootRef = useRef<HTMLDivElement>(null);
|
35
36
|
const mainRef = useRef<HTMLDivElement>(null);
|
36
37
|
const paperRefs = useRef<HTMLDivElement[]>([]);
|
37
38
|
|
38
39
|
const i18n = useContext(I18nContext);
|
39
40
|
|
40
|
-
const { backgrounds, pageSizes, scale, error } = useUIPreProcessor({
|
41
|
-
template,
|
42
|
-
size,
|
43
|
-
offset: RULER_HEIGHT,
|
44
|
-
});
|
45
|
-
|
46
41
|
const [hoveringSchemaId, setHoveringSchemaId] = useState<string | null>(null);
|
47
42
|
const [activeElements, setActiveElements] = useState<HTMLElement[]>([]);
|
48
43
|
const [schemasList, setSchemasList] = useState<SchemaForUI[][]>([[]] as SchemaForUI[][]);
|
49
44
|
const [pageCursor, setPageCursor] = useState(0);
|
45
|
+
const [zoomLevel, setZoomLevel] = useState(1);
|
46
|
+
|
47
|
+
const { backgrounds, pageSizes, scale, error } = useUIPreProcessor({ template, size, zoomLevel });
|
50
48
|
|
51
49
|
const onEdit = (targets: HTMLElement[]) => {
|
52
50
|
setActiveElements(targets);
|
@@ -59,7 +57,7 @@ const TemplateEditor = ({
|
|
59
57
|
};
|
60
58
|
|
61
59
|
useScrollPageCursor({
|
62
|
-
|
60
|
+
ref: mainRef,
|
63
61
|
pageSizes,
|
64
62
|
scale,
|
65
63
|
pageCursor,
|
@@ -190,8 +188,8 @@ const TemplateEditor = ({
|
|
190
188
|
setSchemasList(sl);
|
191
189
|
onEditEnd();
|
192
190
|
setPageCursor(0);
|
193
|
-
if (
|
194
|
-
|
191
|
+
if (mainRef.current?.scroll) {
|
192
|
+
mainRef.current.scroll({ top: 0, behavior: 'smooth' });
|
195
193
|
}
|
196
194
|
}, []);
|
197
195
|
|
@@ -229,11 +227,29 @@ const TemplateEditor = ({
|
|
229
227
|
}
|
230
228
|
|
231
229
|
return (
|
232
|
-
<Root
|
230
|
+
<Root size={size} scale={scale}>
|
231
|
+
<CtlBar
|
232
|
+
pageCursor={pageCursor}
|
233
|
+
pageNum={schemasList.length}
|
234
|
+
setPageCursor={(p) => {
|
235
|
+
if (!mainRef.current) return;
|
236
|
+
mainRef.current.scrollTop = getPagesScrollTopByIndex(pageSizes, p, scale);
|
237
|
+
setPageCursor(p);
|
238
|
+
onEditEnd();
|
239
|
+
}}
|
240
|
+
zoomLevel={zoomLevel}
|
241
|
+
setZoomLevel={(zoom) => {
|
242
|
+
if (mainRef.current) {
|
243
|
+
const paper = paperRefs.current[pageCursor];
|
244
|
+
mainRef.current.scrollLeft = paper.clientHeight / 2;
|
245
|
+
}
|
246
|
+
setZoomLevel(zoom);
|
247
|
+
}}
|
248
|
+
/>
|
233
249
|
<Sidebar
|
234
250
|
hoveringSchemaId={hoveringSchemaId}
|
235
251
|
onChangeHoveringSchemaId={onChangeHoveringSchemaId}
|
236
|
-
height={mainRef.current ? mainRef.current.
|
252
|
+
height={mainRef.current ? mainRef.current.clientHeight : 0}
|
237
253
|
size={size}
|
238
254
|
pageSize={pageSizes[pageCursor]}
|
239
255
|
activeElements={activeElements}
|
package/src/components/Error.tsx
CHANGED
package/src/components/Paper.tsx
CHANGED
@@ -4,7 +4,7 @@ import { FontContext } from '../contexts';
|
|
4
4
|
import { ZOOM, RULER_HEIGHT } from '../constants';
|
5
5
|
|
6
6
|
const Paper = (porps: {
|
7
|
-
paperRefs
|
7
|
+
paperRefs: MutableRefObject<HTMLDivElement[]>;
|
8
8
|
scale: number;
|
9
9
|
size: Size;
|
10
10
|
schemasList: SchemaForUI[][];
|
@@ -28,6 +28,7 @@ const Paper = (porps: {
|
|
28
28
|
style={{
|
29
29
|
transform: `scale(${scale})`,
|
30
30
|
transformOrigin: size.width <= topPageWidth * ZOOM * scale ? `left top` : `center top`,
|
31
|
+
height: size.height,
|
31
32
|
}}
|
32
33
|
>
|
33
34
|
{backgrounds.map((background, paperIndex) => {
|
@@ -36,9 +37,10 @@ const Paper = (porps: {
|
|
36
37
|
|
37
38
|
return (
|
38
39
|
<div
|
40
|
+
id={`@pdfme/ui-paper${paperIndex}`}
|
39
41
|
key={paperIndex + JSON.stringify(paperSize)}
|
40
42
|
ref={(e) => {
|
41
|
-
if (e
|
43
|
+
if (e) {
|
42
44
|
paperRefs.current[paperIndex] = e;
|
43
45
|
}
|
44
46
|
}}
|
@@ -1,28 +1,26 @@
|
|
1
1
|
import React, { useCallback, useRef, useState, useEffect } from 'react';
|
2
2
|
import { PreviewReactProps, SchemaForUI } from '@pdfme/common';
|
3
|
-
import { ZOOM, RULER_HEIGHT } from '
|
4
|
-
import
|
5
|
-
import
|
6
|
-
import
|
7
|
-
import
|
8
|
-
import Paper from '
|
9
|
-
import SchemaUI from '
|
10
|
-
import { useUIPreProcessor, useScrollPageCursor } from '
|
11
|
-
import { templateSchemas2SchemasList } from '
|
3
|
+
import { ZOOM, RULER_HEIGHT } from '../constants';
|
4
|
+
import UnitPager from './UnitPager';
|
5
|
+
import Root from './Root';
|
6
|
+
import Error from './Error';
|
7
|
+
import CtlBar from './CtlBar';
|
8
|
+
import Paper from './Paper';
|
9
|
+
import SchemaUI from './Schemas/SchemaUI';
|
10
|
+
import { useUIPreProcessor, useScrollPageCursor } from '../hooks';
|
11
|
+
import { templateSchemas2SchemasList, getPagesScrollTopByIndex } from '../helper';
|
12
12
|
|
13
13
|
const Preview = ({ template, inputs, size, onChangeInput }: PreviewReactProps) => {
|
14
|
-
const { backgrounds, pageSizes, scale, error } = useUIPreProcessor({
|
15
|
-
template,
|
16
|
-
size,
|
17
|
-
offset: RULER_HEIGHT,
|
18
|
-
});
|
19
|
-
|
20
14
|
const rootRef = useRef<HTMLDivElement>(null);
|
15
|
+
const paperRefs = useRef<HTMLDivElement[]>([]);
|
21
16
|
|
22
17
|
const [unitCursor, setUnitCursor] = useState(0);
|
23
18
|
const [pageCursor, setPageCursor] = useState(0);
|
19
|
+
const [zoomLevel, setZoomLevel] = useState(1);
|
24
20
|
const [schemasList, setSchemasList] = useState<SchemaForUI[][]>([[]] as SchemaForUI[][]);
|
25
21
|
|
22
|
+
const { backgrounds, pageSizes, scale, error } = useUIPreProcessor({ template, size, zoomLevel });
|
23
|
+
|
26
24
|
const init = useCallback(async () => {
|
27
25
|
const sl = await templateSchemas2SchemasList(template);
|
28
26
|
setSchemasList(sl);
|
@@ -33,7 +31,7 @@ const Preview = ({ template, inputs, size, onChangeInput }: PreviewReactProps) =
|
|
33
31
|
}, [init]);
|
34
32
|
|
35
33
|
useScrollPageCursor({
|
36
|
-
rootRef,
|
34
|
+
ref: rootRef,
|
37
35
|
pageSizes,
|
38
36
|
scale,
|
39
37
|
pageCursor,
|
@@ -52,27 +50,26 @@ const Preview = ({ template, inputs, size, onChangeInput }: PreviewReactProps) =
|
|
52
50
|
|
53
51
|
return (
|
54
52
|
<Root ref={rootRef} size={size} scale={scale}>
|
55
|
-
<
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
<UnitPager unitCursor={unitCursor} unitNum={inputs.length} setUnitCursor={setUnitCursor} />
|
54
|
+
<CtlBar
|
55
|
+
pageCursor={pageCursor}
|
56
|
+
pageNum={schemasList.length}
|
57
|
+
setPageCursor={(p) => {
|
58
|
+
if (!rootRef.current) return;
|
59
|
+
rootRef.current.scrollTop = getPagesScrollTopByIndex(pageSizes, p, scale);
|
60
|
+
setPageCursor(p);
|
60
61
|
}}
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
.reduce((acc, cur) => acc + (cur.height * ZOOM + RULER_HEIGHT) * scale, 0);
|
71
|
-
setPageCursor(p);
|
72
|
-
}}
|
73
|
-
/>
|
74
|
-
</div>
|
62
|
+
zoomLevel={zoomLevel}
|
63
|
+
setZoomLevel={(zoom) => {
|
64
|
+
if (rootRef.current) {
|
65
|
+
const paper = paperRefs.current[pageCursor];
|
66
|
+
rootRef.current.scrollLeft = Number(paper.style.width.replace('px', '')) / 2;
|
67
|
+
}
|
68
|
+
setZoomLevel(zoom);
|
69
|
+
}}
|
70
|
+
/>
|
75
71
|
<Paper
|
72
|
+
paperRefs={paperRefs}
|
76
73
|
scale={scale}
|
77
74
|
size={size}
|
78
75
|
schemasList={schemasList}
|
package/src/components/Root.tsx
CHANGED
@@ -29,12 +29,11 @@ const Root = ({ size, scale, children }: Props, ref: Ref<HTMLDivElement>) => {
|
|
29
29
|
return (
|
30
30
|
<div
|
31
31
|
ref={ref}
|
32
|
-
style={{ position: 'relative', background: 'rgb(74, 74, 74)',
|
32
|
+
style={{ position: 'relative', background: 'rgb(74, 74, 74)', overflow: 'auto', ...size }}
|
33
33
|
>
|
34
34
|
<div
|
35
35
|
style={{
|
36
36
|
margin: '0 auto',
|
37
|
-
width: size.width - RULER_HEIGHT * scale,
|
38
37
|
height: size.height - RULER_HEIGHT * scale,
|
39
38
|
}}
|
40
39
|
>
|
@@ -32,7 +32,6 @@ const TextSchemaUI = (
|
|
32
32
|
wordBreak: 'break-all',
|
33
33
|
background: 'transparent',
|
34
34
|
border: 'none',
|
35
|
-
outline: 'none',
|
36
35
|
color: schema.fontColor ? schema.fontColor : DEFAULT_FONT_COLOR,
|
37
36
|
backgroundColor: schema.data && schema.backgroundColor ? schema.backgroundColor : 'transparent',
|
38
37
|
};
|