@pdfme/ui 3.0.1 → 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__/assetsTransformer.js +7 -0
- package/__mocks__/pdfjs-dist.js +15 -0
- package/dist/__vite-browser-external-jWVCDlBL.js +4 -0
- package/dist/index.js +1115 -3
- 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 -11
- 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/index.js.map +0 -1
- 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 -40
package/src/Designer.tsx
CHANGED
@@ -1,39 +1,16 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import ReactDOM from 'react-dom';
|
3
|
-
import {
|
4
|
-
import { Template, DesignerProps, checkDesignerProps, checkTemplate, Plugins } from '@pdfme/common';
|
5
|
-
import { builtInPlugins } from '@pdfme/schemas';
|
3
|
+
import { Template, DesignerProps, checkDesignerProps, checkTemplate } from '@pdfme/common';
|
6
4
|
import { BaseUIClass } from './class';
|
7
|
-
import { DESTROYED_ERR_MSG } from './constants';
|
8
|
-
import {
|
9
|
-
I18nContext,
|
10
|
-
FontContext,
|
11
|
-
PluginsRegistry,
|
12
|
-
OptionsContext,
|
13
|
-
} from './contexts';
|
5
|
+
import { DESTROYED_ERR_MSG } from './constants.js';
|
14
6
|
import DesignerComponent from './components/Designer/index';
|
15
|
-
import
|
16
|
-
|
17
|
-
// TODO Custom Design for UI #243
|
18
|
-
// - https://github.com/pdfme/pdfme/issues/243
|
19
|
-
// - https://ant.design/docs/react/customize-theme
|
20
|
-
const theme: ThemeConfig = {
|
21
|
-
token: {
|
22
|
-
fontSize: 12,
|
23
|
-
},
|
24
|
-
components: {
|
25
|
-
Form: {
|
26
|
-
itemMarginBottom: 8,
|
27
|
-
verticalLabelPadding: '0 0 2px',
|
28
|
-
},
|
29
|
-
},
|
30
|
-
};
|
7
|
+
import AppContextProvider from './components/AppContextProvider';
|
8
|
+
import { cloneDeep } from './helper.js';
|
31
9
|
|
32
10
|
class Designer extends BaseUIClass {
|
33
11
|
private onSaveTemplateCallback?: (template: Template) => void;
|
34
12
|
private onChangeTemplateCallback?: (template: Template) => void;
|
35
13
|
|
36
|
-
|
37
14
|
constructor(props: DesignerProps) {
|
38
15
|
super(props);
|
39
16
|
checkDesignerProps(props);
|
@@ -69,32 +46,29 @@ class Designer extends BaseUIClass {
|
|
69
46
|
protected render() {
|
70
47
|
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
71
48
|
ReactDOM.render(
|
72
|
-
<
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
</FontContext.Provider>
|
96
|
-
</I18nContext.Provider>
|
97
|
-
</ConfigProvider>,
|
49
|
+
<AppContextProvider
|
50
|
+
lang={this.getLang()}
|
51
|
+
font={this.getFont()}
|
52
|
+
plugins={this.getPluginsRegistry()}
|
53
|
+
options={this.getOptions()}
|
54
|
+
>
|
55
|
+
<DesignerComponent
|
56
|
+
template={this.template}
|
57
|
+
onSaveTemplate={(template) => {
|
58
|
+
this.template = template;
|
59
|
+
if (this.onSaveTemplateCallback) {
|
60
|
+
this.onSaveTemplateCallback(template);
|
61
|
+
}
|
62
|
+
}}
|
63
|
+
onChangeTemplate={(template) => {
|
64
|
+
this.template = template;
|
65
|
+
if (this.onChangeTemplateCallback) {
|
66
|
+
this.onChangeTemplateCallback(template);
|
67
|
+
}
|
68
|
+
}}
|
69
|
+
size={this.size}
|
70
|
+
/>
|
71
|
+
</AppContextProvider>,
|
98
72
|
this.domContainer
|
99
73
|
);
|
100
74
|
}
|
package/src/Form.tsx
CHANGED
@@ -2,8 +2,8 @@ import React from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
3
3
|
import { PreviewProps } from '@pdfme/common';
|
4
4
|
import { PreviewUI } from './class';
|
5
|
-
import { DESTROYED_ERR_MSG } from './constants';
|
6
|
-
import
|
5
|
+
import { DESTROYED_ERR_MSG } from './constants.js';
|
6
|
+
import AppContextProvider from './components/AppContextProvider';
|
7
7
|
import Preview from './components/Preview';
|
8
8
|
|
9
9
|
class Form extends PreviewUI {
|
@@ -21,27 +21,26 @@ class Form extends PreviewUI {
|
|
21
21
|
protected render() {
|
22
22
|
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
23
23
|
ReactDOM.render(
|
24
|
-
<
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
</I18nContext.Provider>,
|
24
|
+
<AppContextProvider
|
25
|
+
lang={this.getLang()}
|
26
|
+
font={this.getFont()}
|
27
|
+
plugins={this.getPluginsRegistry()}
|
28
|
+
options={this.getOptions()}
|
29
|
+
>
|
30
|
+
<Preview
|
31
|
+
template={this.template}
|
32
|
+
size={this.size}
|
33
|
+
inputs={this.inputs}
|
34
|
+
onChangeInput={(arg: { index: number; value: string; key: string }) => {
|
35
|
+
const { index, value, key } = arg;
|
36
|
+
if (this.onChangeInputCallback) {
|
37
|
+
this.onChangeInputCallback({ index, value, key });
|
38
|
+
}
|
39
|
+
this.inputs[index][key] = value;
|
40
|
+
this.render();
|
41
|
+
}}
|
42
|
+
/>
|
43
|
+
</AppContextProvider>,
|
45
44
|
this.domContainer
|
46
45
|
);
|
47
46
|
}
|
package/src/Viewer.tsx
CHANGED
@@ -2,9 +2,9 @@ import React from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
3
3
|
import { PreviewProps } from '@pdfme/common';
|
4
4
|
import { PreviewUI } from './class';
|
5
|
-
import { DESTROYED_ERR_MSG } from './constants';
|
6
|
-
import { I18nContext, FontContext, PluginsRegistry, OptionsContext } from './contexts';
|
5
|
+
import { DESTROYED_ERR_MSG } from './constants.js';
|
7
6
|
import Preview from './components/Preview';
|
7
|
+
import AppContextProvider from './components/AppContextProvider';
|
8
8
|
|
9
9
|
class Viewer extends PreviewUI {
|
10
10
|
constructor(props: PreviewProps) {
|
@@ -15,15 +15,14 @@ class Viewer extends PreviewUI {
|
|
15
15
|
protected render() {
|
16
16
|
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
17
17
|
ReactDOM.render(
|
18
|
-
<
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
</I18nContext.Provider>,
|
18
|
+
<AppContextProvider
|
19
|
+
lang={this.getLang()}
|
20
|
+
font={this.getFont()}
|
21
|
+
plugins={this.getPluginsRegistry()}
|
22
|
+
options={this.getOptions()}
|
23
|
+
>
|
24
|
+
<Preview template={this.template} size={this.size} inputs={this.inputs} />
|
25
|
+
</AppContextProvider>,
|
27
26
|
this.domContainer
|
28
27
|
);
|
29
28
|
}
|
package/src/class.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import ReactDOM from 'react-dom';
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import { debounce, flatten, cloneDeep } from './helper';
|
2
|
+
import { DESTROYED_ERR_MSG, DEFAULT_LANG } from './constants.js';
|
3
|
+
import { debounce, flatten, cloneDeep } from './helper.js';
|
5
4
|
import {
|
6
5
|
Template,
|
7
6
|
Size,
|
@@ -108,8 +107,8 @@ export abstract class BaseUIClass {
|
|
108
107
|
}
|
109
108
|
}
|
110
109
|
|
111
|
-
protected
|
112
|
-
return
|
110
|
+
protected getLang() {
|
111
|
+
return this.lang;
|
113
112
|
}
|
114
113
|
|
115
114
|
protected getFont() {
|
@@ -148,6 +147,7 @@ export abstract class BaseUIClass {
|
|
148
147
|
if (font) {
|
149
148
|
this.font = font;
|
150
149
|
}
|
150
|
+
this.options = Object.assign(this.options, options);
|
151
151
|
this.render();
|
152
152
|
}
|
153
153
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { ConfigProvider as ThemeConfigProvider } from 'antd';
|
3
|
+
import { I18nContext, FontContext, PluginsRegistry, OptionsContext } from '../contexts';
|
4
|
+
import { i18n, getDict } from '../i18n';
|
5
|
+
import { defaultTheme } from '../theme';
|
6
|
+
import type { Dict, Plugins, Font, Lang, UIOptions } from '@pdfme/common';
|
7
|
+
|
8
|
+
type Props = {
|
9
|
+
children: React.ReactNode;
|
10
|
+
lang: Lang;
|
11
|
+
font: Font;
|
12
|
+
plugins: Plugins;
|
13
|
+
options: UIOptions;
|
14
|
+
};
|
15
|
+
|
16
|
+
const isObject = (item: any): item is Record<string, any> =>
|
17
|
+
item && typeof item === 'object' && !Array.isArray(item);
|
18
|
+
|
19
|
+
const deepMerge = <T extends Record<string, any>, U extends Record<string, any>>(
|
20
|
+
target: T,
|
21
|
+
source: U
|
22
|
+
): T & U => {
|
23
|
+
let output = { ...target } as T & U;
|
24
|
+
|
25
|
+
if (isObject(target) && isObject(source)) {
|
26
|
+
Object.keys(source).forEach((key: keyof U) => {
|
27
|
+
if (isObject(source[key])) {
|
28
|
+
if (!(key in target)) {
|
29
|
+
Object.assign(output, { [key]: source[key] });
|
30
|
+
} else {
|
31
|
+
output[key as keyof T & U] = deepMerge(target[key as keyof T] as any, source[key] as any);
|
32
|
+
}
|
33
|
+
} else {
|
34
|
+
Object.assign(output, { [key]: source[key] });
|
35
|
+
}
|
36
|
+
});
|
37
|
+
}
|
38
|
+
return output;
|
39
|
+
};
|
40
|
+
|
41
|
+
export default ({ children, lang, font, plugins, options }: Props) => {
|
42
|
+
let theme = defaultTheme;
|
43
|
+
if (options.theme) {
|
44
|
+
theme = deepMerge(theme, options.theme);
|
45
|
+
}
|
46
|
+
|
47
|
+
let dict = getDict(lang);
|
48
|
+
if (options.labels) {
|
49
|
+
dict = deepMerge(dict, options.labels);
|
50
|
+
}
|
51
|
+
|
52
|
+
return (
|
53
|
+
<ThemeConfigProvider theme={theme}>
|
54
|
+
<I18nContext.Provider value={(key: keyof Dict) => i18n(key, dict)}>
|
55
|
+
<FontContext.Provider value={font}>
|
56
|
+
<PluginsRegistry.Provider value={plugins}>
|
57
|
+
<OptionsContext.Provider value={options}>{children}</OptionsContext.Provider>
|
58
|
+
</PluginsRegistry.Provider>
|
59
|
+
</FontContext.Provider>
|
60
|
+
</I18nContext.Provider>
|
61
|
+
</ThemeConfigProvider>
|
62
|
+
);
|
63
|
+
};
|
@@ -0,0 +1,125 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { Size } from '@pdfme/common';
|
3
|
+
import { MinusOutlined, PlusOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons';
|
4
|
+
import { theme, Typography, Button } from 'antd';
|
5
|
+
|
6
|
+
const { Text } = Typography;
|
7
|
+
|
8
|
+
type TextStyle = { color: string; fontSize: number; margin: number };
|
9
|
+
type ZoomProps = {
|
10
|
+
zoomLevel: number;
|
11
|
+
setZoomLevel: (zoom: number) => void;
|
12
|
+
style: { textStyle: TextStyle };
|
13
|
+
};
|
14
|
+
|
15
|
+
const Zoom = ({ zoomLevel, setZoomLevel, style }: ZoomProps) => {
|
16
|
+
const zoomStep = 0.25;
|
17
|
+
const maxZoom = 2;
|
18
|
+
const minZoom = 0.25;
|
19
|
+
|
20
|
+
const nextZoomOut = zoomLevel - zoomStep;
|
21
|
+
const nextZoomIn = zoomLevel + zoomStep;
|
22
|
+
|
23
|
+
return (
|
24
|
+
<div style={{ display: 'flex', alignItems: 'center' }}>
|
25
|
+
<Button
|
26
|
+
type="text"
|
27
|
+
disabled={minZoom >= nextZoomOut}
|
28
|
+
onClick={() => setZoomLevel(nextZoomOut)}
|
29
|
+
icon={<MinusOutlined style={{ color: style.textStyle.color }} />}
|
30
|
+
/>
|
31
|
+
<Text strong style={style.textStyle}>
|
32
|
+
{Math.round(zoomLevel * 100)}%
|
33
|
+
</Text>
|
34
|
+
<Button
|
35
|
+
type="text"
|
36
|
+
disabled={maxZoom < nextZoomIn}
|
37
|
+
onClick={() => setZoomLevel(nextZoomIn)}
|
38
|
+
icon={<PlusOutlined style={{ color: style.textStyle.color }} />}
|
39
|
+
/>
|
40
|
+
</div>
|
41
|
+
);
|
42
|
+
};
|
43
|
+
|
44
|
+
type PagerProps = {
|
45
|
+
pageCursor: number;
|
46
|
+
pageNum: number;
|
47
|
+
setPageCursor: (page: number) => void;
|
48
|
+
style: { textStyle: TextStyle };
|
49
|
+
};
|
50
|
+
|
51
|
+
const Pager = ({ pageCursor, pageNum, setPageCursor, style }: PagerProps) => {
|
52
|
+
return (
|
53
|
+
<div style={{ display: 'flex', alignItems: 'center' }}>
|
54
|
+
<Button type="text" disabled={pageCursor <= 0} onClick={() => setPageCursor(pageCursor - 1)}>
|
55
|
+
<LeftOutlined style={{ color: style.textStyle.color }} />
|
56
|
+
</Button>
|
57
|
+
<Text strong style={style.textStyle}>
|
58
|
+
{pageCursor + 1}/{pageNum}
|
59
|
+
</Text>
|
60
|
+
<Button
|
61
|
+
type="text"
|
62
|
+
disabled={pageCursor + 1 >= pageNum}
|
63
|
+
onClick={() => setPageCursor(pageCursor + 1)}
|
64
|
+
>
|
65
|
+
<RightOutlined style={{ color: style.textStyle.color }} />
|
66
|
+
</Button>
|
67
|
+
</div>
|
68
|
+
);
|
69
|
+
};
|
70
|
+
|
71
|
+
type CtlBarProps = {
|
72
|
+
size: Size;
|
73
|
+
pageCursor: number;
|
74
|
+
pageNum: number;
|
75
|
+
setPageCursor: (page: number) => void;
|
76
|
+
zoomLevel: number;
|
77
|
+
setZoomLevel: (zoom: number) => void;
|
78
|
+
};
|
79
|
+
|
80
|
+
const CtlBar = (props: CtlBarProps) => {
|
81
|
+
const { token } = theme.useToken();
|
82
|
+
|
83
|
+
const barWidth = 300;
|
84
|
+
const { size, pageCursor, pageNum, setPageCursor, zoomLevel, setZoomLevel } = props;
|
85
|
+
const width = pageNum > 1 ? barWidth : barWidth / 2;
|
86
|
+
|
87
|
+
const textStyle = {
|
88
|
+
color: token.colorWhite,
|
89
|
+
fontSize: token.fontSize,
|
90
|
+
margin: token.marginXS,
|
91
|
+
};
|
92
|
+
|
93
|
+
return (
|
94
|
+
<div style={{ position: 'absolute', top: 'auto', bottom: '6%', width: size.width }}>
|
95
|
+
<div
|
96
|
+
style={{
|
97
|
+
display: 'flex',
|
98
|
+
alignItems: 'center',
|
99
|
+
justifyContent: 'center',
|
100
|
+
position: 'relative',
|
101
|
+
zIndex: 1,
|
102
|
+
left: `calc(50% - ${width / 2}px)`,
|
103
|
+
width,
|
104
|
+
height: 40,
|
105
|
+
boxSizing: 'border-box',
|
106
|
+
padding: token.paddingSM,
|
107
|
+
borderRadius: token.borderRadius,
|
108
|
+
backgroundColor: token.colorBgMask,
|
109
|
+
}}
|
110
|
+
>
|
111
|
+
{pageNum > 1 && (
|
112
|
+
<Pager
|
113
|
+
style={{ textStyle }}
|
114
|
+
pageCursor={pageCursor}
|
115
|
+
pageNum={pageNum}
|
116
|
+
setPageCursor={setPageCursor}
|
117
|
+
/>
|
118
|
+
)}
|
119
|
+
<Zoom style={{ textStyle }} zoomLevel={zoomLevel} setZoomLevel={setZoomLevel} />
|
120
|
+
</div>
|
121
|
+
</div>
|
122
|
+
);
|
123
|
+
};
|
124
|
+
|
125
|
+
export default CtlBar;
|
@@ -3,6 +3,20 @@ import Guides from '@scena/react-guides';
|
|
3
3
|
import { ZOOM, Size } from '@pdfme/common';
|
4
4
|
import { RULER_HEIGHT } from '../../../constants';
|
5
5
|
|
6
|
+
const guideStyle = (
|
7
|
+
top: number,
|
8
|
+
left: number,
|
9
|
+
height: number,
|
10
|
+
width: number
|
11
|
+
): React.CSSProperties => ({
|
12
|
+
position: 'absolute',
|
13
|
+
top,
|
14
|
+
left,
|
15
|
+
height,
|
16
|
+
width,
|
17
|
+
background: '#333333',
|
18
|
+
});
|
19
|
+
|
6
20
|
const _Guides = ({
|
7
21
|
paperSize,
|
8
22
|
horizontalRef,
|
@@ -15,36 +29,17 @@ const _Guides = ({
|
|
15
29
|
<>
|
16
30
|
<div
|
17
31
|
className="ruler-container"
|
18
|
-
style={
|
19
|
-
|
20
|
-
height: RULER_HEIGHT,
|
21
|
-
position: 'absolute',
|
22
|
-
top: -RULER_HEIGHT,
|
23
|
-
left: -RULER_HEIGHT,
|
24
|
-
background: '#333',
|
25
|
-
}}
|
26
|
-
></div>
|
32
|
+
style={guideStyle(-RULER_HEIGHT, -RULER_HEIGHT, RULER_HEIGHT, RULER_HEIGHT)}
|
33
|
+
/>
|
27
34
|
<Guides
|
28
35
|
zoom={ZOOM}
|
29
|
-
style={
|
30
|
-
position: 'absolute',
|
31
|
-
top: -RULER_HEIGHT,
|
32
|
-
left: 0,
|
33
|
-
height: RULER_HEIGHT,
|
34
|
-
width: paperSize.width,
|
35
|
-
}}
|
36
|
+
style={guideStyle(-RULER_HEIGHT, 0, RULER_HEIGHT, paperSize.width)}
|
36
37
|
type="horizontal"
|
37
38
|
ref={horizontalRef}
|
38
39
|
/>
|
39
40
|
<Guides
|
40
41
|
zoom={ZOOM}
|
41
|
-
style={
|
42
|
-
position: 'absolute',
|
43
|
-
top: 0,
|
44
|
-
left: -RULER_HEIGHT,
|
45
|
-
height: paperSize.height,
|
46
|
-
width: RULER_HEIGHT,
|
47
|
-
}}
|
42
|
+
style={guideStyle(0, -RULER_HEIGHT, paperSize.height, RULER_HEIGHT)}
|
48
43
|
type="vertical"
|
49
44
|
ref={verticalRef}
|
50
45
|
/>
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { Size } from '@pdfme/common';
|
3
3
|
import { RULER_HEIGHT } from '../../../constants';
|
4
|
+
import { theme } from 'antd';
|
4
5
|
|
5
6
|
const Mask = ({ width, height }: Size) => (
|
6
7
|
<div
|
@@ -9,9 +10,9 @@ const Mask = ({ width, height }: Size) => (
|
|
9
10
|
top: -RULER_HEIGHT,
|
10
11
|
left: -RULER_HEIGHT,
|
11
12
|
zIndex: 100,
|
12
|
-
background: 'rgba(158, 158, 158, 0.58)',
|
13
13
|
width,
|
14
14
|
height,
|
15
|
+
background: theme.useToken().token.colorBgMask,
|
15
16
|
}}
|
16
17
|
/>
|
17
18
|
);
|
@@ -1,5 +1,6 @@
|
|
1
|
-
import React, { forwardRef, Ref } from 'react';
|
1
|
+
import React, { useEffect, forwardRef, Ref } from 'react';
|
2
2
|
import Moveable, { OnDrag, OnResize, OnRotate, OnRotateEnd, OnClick } from 'react-moveable';
|
3
|
+
import { theme } from 'antd';
|
3
4
|
|
4
5
|
type Props = {
|
5
6
|
target: HTMLElement[];
|
@@ -20,64 +21,63 @@ type Props = {
|
|
20
21
|
onClick: (e: OnClick) => void;
|
21
22
|
};
|
22
23
|
|
23
|
-
const
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
);
|
24
|
+
const className = 'pdfme-moveable';
|
25
|
+
|
26
|
+
const _Moveable = (props: Props, ref: Ref<any>) => {
|
27
|
+
const { token } = theme.useToken();
|
28
|
+
useEffect(() => {
|
29
|
+
const containerElement = document.querySelector(`.${className}`) as HTMLElement | null;
|
30
|
+
const containerElement2 = document.querySelectorAll(
|
31
|
+
`.${className} .moveable-line`
|
32
|
+
) as NodeListOf<HTMLElement>;
|
33
|
+
if (containerElement) {
|
34
|
+
containerElement.style.setProperty('--moveable-color', token.colorPrimary);
|
35
|
+
Array.from(containerElement2).map((e) =>
|
36
|
+
e.style.setProperty('--moveable-color', token.colorPrimary)
|
37
|
+
);
|
38
|
+
}
|
39
|
+
}, [props.target]);
|
40
|
+
|
41
|
+
return (
|
42
|
+
<Moveable
|
43
|
+
style={{ zIndex: 1 }}
|
44
|
+
className={className}
|
45
|
+
rootContainer={document ? document.body : undefined}
|
46
|
+
snappable
|
47
|
+
snapCenter
|
48
|
+
draggable
|
49
|
+
rotatable={props.rotatable}
|
50
|
+
resizable
|
51
|
+
throttleDrag={1}
|
52
|
+
throttleRotate={1}
|
53
|
+
throttleResize={1}
|
54
|
+
ref={ref}
|
55
|
+
target={props.target}
|
56
|
+
bounds={props.bounds}
|
57
|
+
horizontalGuidelines={props.horizontalGuidelines}
|
58
|
+
verticalGuidelines={props.verticalGuidelines}
|
59
|
+
keepRatio={props.keepRatio}
|
60
|
+
onRotate={props.onRotate}
|
61
|
+
onRotateEnd={props.onRotateEnd}
|
62
|
+
onRotateGroup={({ events }) => {
|
63
|
+
events.forEach(props.onRotate);
|
64
|
+
}}
|
65
|
+
onRotateGroupEnd={props.onRotateGroupEnd}
|
66
|
+
onDrag={props.onDrag}
|
67
|
+
onDragGroup={({ events }) => {
|
68
|
+
events.forEach(props.onDrag);
|
69
|
+
}}
|
70
|
+
onDragEnd={props.onDragEnd}
|
71
|
+
onDragGroupEnd={props.onDragGroupEnd}
|
72
|
+
onResize={props.onResize}
|
73
|
+
onResizeGroup={({ events }) => {
|
74
|
+
events.forEach(props.onResize);
|
75
|
+
}}
|
76
|
+
onResizeEnd={props.onResizeEnd}
|
77
|
+
onResizeGroupEnd={props.onResizeGroupEnd}
|
78
|
+
onClick={props.onClick}
|
79
|
+
/>
|
80
|
+
);
|
81
|
+
};
|
82
82
|
|
83
83
|
export default forwardRef<any, Props>(_Moveable);
|