@pdfme/ui 1.0.0-beta.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/.eslintrc.js +45 -0
- package/README.md +280 -0
- package/declaration.d.ts +8 -0
- package/dist/@pdfme/ui.js +3 -0
- package/dist/@pdfme/ui.js.LICENSE.txt +95 -0
- package/dist/@pdfme/ui.js.map +1 -0
- package/dist/types/common/src/barcode.d.ts +2 -0
- package/dist/types/common/src/constants.d.ts +6 -0
- package/dist/types/common/src/helper.d.ts +15 -0
- package/dist/types/common/src/index.d.ts +4 -0
- package/dist/types/common/src/schema.d.ts +3613 -0
- package/dist/types/common/src/type.d.ts +64 -0
- package/dist/types/common/src/utils.d.ts +12 -0
- package/dist/types/ui/src/Designer.d.ts +13 -0
- package/dist/types/ui/src/Form.d.ts +13 -0
- package/dist/types/ui/src/Viewer.d.ts +7 -0
- package/dist/types/ui/src/class.d.ts +72 -0
- package/dist/types/ui/src/components/Designer/Main/Guides.d.ts +9 -0
- package/dist/types/ui/src/components/Designer/Main/Mask.d.ts +3 -0
- package/dist/types/ui/src/components/Designer/Main/Moveable.d.ts +31 -0
- package/dist/types/ui/src/components/Designer/Main/Selecto.d.ts +8 -0
- package/dist/types/ui/src/components/Designer/Main/index.d.ts +24 -0
- package/dist/types/ui/src/components/Designer/Sidebar/DetailView/ExampleInputEditor.d.ts +3 -0
- package/dist/types/ui/src/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.d.ts +3 -0
- package/dist/types/ui/src/components/Designer/Sidebar/DetailView/TextPropEditor.d.ts +3 -0
- package/dist/types/ui/src/components/Designer/Sidebar/DetailView/TypeAndKeyEditor.d.ts +3 -0
- package/dist/types/ui/src/components/Designer/Sidebar/DetailView/index.d.ts +3 -0
- package/dist/types/ui/src/components/Designer/Sidebar/ListView.d.ts +3 -0
- package/dist/types/ui/src/components/Designer/Sidebar/index.d.ts +26 -0
- package/dist/types/ui/src/components/Designer/index.d.ts +99 -0
- package/dist/types/ui/src/components/Divider.d.ts +2 -0
- package/dist/types/ui/src/components/Error.d.ts +7 -0
- package/dist/types/ui/src/components/Paper.d.ts +19 -0
- package/dist/types/ui/src/components/Preview/Pager/Page.d.ts +8 -0
- package/dist/types/ui/src/components/Preview/Pager/Unit.d.ts +8 -0
- package/dist/types/ui/src/components/Preview/index.d.ts +4 -0
- package/dist/types/ui/src/components/Root.d.ts +9 -0
- package/dist/types/ui/src/components/Schemas/BarcodeSchema.d.ts +15 -0
- package/dist/types/ui/src/components/Schemas/ImageSchema.d.ts +15 -0
- package/dist/types/ui/src/components/Schemas/SchemaUI.d.ts +14 -0
- package/dist/types/ui/src/components/Schemas/TextSchema.d.ts +22 -0
- package/dist/types/ui/src/components/Spinner.d.ts +2 -0
- package/dist/types/ui/src/constants.d.ts +5 -0
- package/dist/types/ui/src/contexts.d.ts +7 -0
- package/dist/types/ui/src/helper.d.ts +91 -0
- package/dist/types/ui/src/hooks.d.ts +26 -0
- package/dist/types/ui/src/i18n.d.ts +30 -0
- package/dist/types/ui/src/index.d.ts +5 -0
- package/dist/types/ui/src/libs/class.d.ts +84 -0
- package/dist/types/ui/src/libs/contexts.d.ts +7 -0
- package/dist/types/ui/src/libs/helper.d.ts +64 -0
- package/dist/types/ui/src/libs/hooks.d.ts +26 -0
- package/dist/types/ui/src/libs/i18n.d.ts +30 -0
- package/dist/types/ui/src/libs/ui.d.ts +64 -0
- package/package.json +80 -0
- package/public/Designer.html +90 -0
- package/public/Form.html +74 -0
- package/public/SauceHanSansJP.ttf +0 -0
- package/public/SauceHanSerifJP.ttf +0 -0
- package/public/Viewer.html +73 -0
- package/public/helper.js +51 -0
- package/public/index.html +54 -0
- package/src/Designer.tsx +72 -0
- package/src/Form.tsx +45 -0
- package/src/Viewer.tsx +27 -0
- package/src/assets/barcodeExamples/code128.png +0 -0
- package/src/assets/barcodeExamples/code39.png +0 -0
- package/src/assets/barcodeExamples/ean13.png +0 -0
- package/src/assets/barcodeExamples/ean8.png +0 -0
- package/src/assets/barcodeExamples/itf14.png +0 -0
- package/src/assets/barcodeExamples/japanpost.png +0 -0
- package/src/assets/barcodeExamples/nw7.png +0 -0
- package/src/assets/barcodeExamples/qrcode.png +0 -0
- package/src/assets/barcodeExamples/upca.png +0 -0
- package/src/assets/barcodeExamples/upce.png +0 -0
- package/src/assets/icons/back.svg +4 -0
- package/src/assets/icons/double-left.svg +11 -0
- package/src/assets/icons/double-right.svg +11 -0
- package/src/assets/icons/drag.svg +3 -0
- package/src/assets/icons/forward.svg +4 -0
- package/src/assets/icons/left.svg +4 -0
- package/src/assets/icons/right.svg +4 -0
- package/src/assets/icons/warning.svg +4 -0
- package/src/assets/imageExample.png +0 -0
- package/src/class.ts +147 -0
- package/src/components/Designer/Main/Guides.tsx +53 -0
- package/src/components/Designer/Main/Mask.tsx +19 -0
- package/src/components/Designer/Main/Moveable.tsx +79 -0
- package/src/components/Designer/Main/Selecto.tsx +29 -0
- package/src/components/Designer/Main/index.tsx +314 -0
- package/src/components/Designer/Sidebar/DetailView/ExampleInputEditor.tsx +62 -0
- package/src/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.tsx +98 -0
- package/src/components/Designer/Sidebar/DetailView/TextPropEditor.tsx +178 -0
- package/src/components/Designer/Sidebar/DetailView/TypeAndKeyEditor.tsx +79 -0
- package/src/components/Designer/Sidebar/DetailView/index.tsx +39 -0
- package/src/components/Designer/Sidebar/ListView.tsx +180 -0
- package/src/components/Designer/Sidebar/index.tsx +102 -0
- package/src/components/Designer/index.tsx +283 -0
- package/src/components/Divider.tsx +7 -0
- package/src/components/Error.tsx +31 -0
- package/src/components/Paper.tsx +77 -0
- package/src/components/Preview/Pager/Page.tsx +85 -0
- package/src/components/Preview/Pager/Unit.tsx +87 -0
- package/src/components/Preview/index.tsx +102 -0
- package/src/components/Root.tsx +52 -0
- package/src/components/Schemas/BarcodeSchema.tsx +111 -0
- package/src/components/Schemas/ImageSchema.tsx +81 -0
- package/src/components/Schemas/SchemaUI.tsx +64 -0
- package/src/components/Schemas/TextSchema.tsx +62 -0
- package/src/components/Spinner.tsx +37 -0
- package/src/constants.ts +9 -0
- package/src/contexts.ts +8 -0
- package/src/helper.ts +516 -0
- package/src/hooks.ts +107 -0
- package/src/i18n.ts +64 -0
- package/src/index.ts +77 -0
- package/tsconfig.json +21 -0
- package/webpack.config.js +73 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<title>Webpack App</title>
|
6
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
7
|
+
</head>
|
8
|
+
<body style="margin: 0">
|
9
|
+
<div>
|
10
|
+
<a href="./">Back</a>
|
11
|
+
/
|
12
|
+
<button onclick="init()">init</button>
|
13
|
+
/
|
14
|
+
<button onclick="destroy()">destroy</button>
|
15
|
+
/
|
16
|
+
<button onclick="getInputs()">getInputs</button>
|
17
|
+
/
|
18
|
+
<button onclick="setInputs()">setInputs</button>
|
19
|
+
/
|
20
|
+
<button onclick="generate()">generate</button>
|
21
|
+
</div>
|
22
|
+
<div id="app"></div>
|
23
|
+
<script src="./helper.js"></script>
|
24
|
+
<script>
|
25
|
+
let viewer = null;
|
26
|
+
|
27
|
+
async function init() {
|
28
|
+
const font = await getFont();
|
29
|
+
viewer = new pdfme.Viewer({
|
30
|
+
domContainer,
|
31
|
+
template: getTemplate(),
|
32
|
+
inputs: [
|
33
|
+
{ field1: 'bb', field2: 'aaaaaaaaaaaa' },
|
34
|
+
{ field1: 'bb', field2: 'aaaaaaaaaaaa' },
|
35
|
+
{ field1: 'bb', field2: 'aaaaaaaaaaaa' },
|
36
|
+
],
|
37
|
+
options: {
|
38
|
+
font,
|
39
|
+
},
|
40
|
+
});
|
41
|
+
}
|
42
|
+
|
43
|
+
function destroy() {
|
44
|
+
viewer.destroy();
|
45
|
+
}
|
46
|
+
|
47
|
+
function getInputs() {
|
48
|
+
console.log(viewer.getInputs());
|
49
|
+
}
|
50
|
+
|
51
|
+
function setInputs() {
|
52
|
+
viewer.setInputs([{ field1: 'wwwww', field2: 'wwwww' }]);
|
53
|
+
}
|
54
|
+
|
55
|
+
async function generate() {
|
56
|
+
const font = await getFont();
|
57
|
+
pdfme
|
58
|
+
.generate({
|
59
|
+
inputs: viewer.getInputs(),
|
60
|
+
template: getTemplate(),
|
61
|
+
options: {
|
62
|
+
font,
|
63
|
+
},
|
64
|
+
})
|
65
|
+
.then((pdf) => {
|
66
|
+
const blob = new Blob([pdf.buffer], { type: 'application/pdf' });
|
67
|
+
window.open(URL.createObjectURL(blob));
|
68
|
+
});
|
69
|
+
}
|
70
|
+
window.onload = init;
|
71
|
+
</script>
|
72
|
+
</body>
|
73
|
+
</html>
|
package/public/helper.js
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
const size = { height: window.innerHeight, width: window.innerWidth };
|
2
|
+
const domContainer = document.getElementById('app');
|
3
|
+
|
4
|
+
const getSampleTemplate = () => ({
|
5
|
+
columns: ['field1', 'field2'],
|
6
|
+
sampledata: [
|
7
|
+
{
|
8
|
+
field1: 'bb',
|
9
|
+
field2: 'aaaaaaaaaaaa',
|
10
|
+
},
|
11
|
+
],
|
12
|
+
basePdf: pdfme.blankPdf,
|
13
|
+
// basePdf: '/DeliveryNote.pdf',
|
14
|
+
schemas: [
|
15
|
+
{
|
16
|
+
field1: {
|
17
|
+
type: 'text',
|
18
|
+
position: { x: 20, y: 20 },
|
19
|
+
width: 100,
|
20
|
+
height: 15,
|
21
|
+
alignment: 'left',
|
22
|
+
fontSize: 30,
|
23
|
+
characterSpacing: 0,
|
24
|
+
lineHeight: 1,
|
25
|
+
},
|
26
|
+
field2: {
|
27
|
+
type: 'text',
|
28
|
+
position: { x: 20, y: 35 },
|
29
|
+
width: 100,
|
30
|
+
height: 40,
|
31
|
+
alignment: 'left',
|
32
|
+
fontSize: 20,
|
33
|
+
characterSpacing: 0,
|
34
|
+
lineHeight: 1,
|
35
|
+
},
|
36
|
+
},
|
37
|
+
],
|
38
|
+
});
|
39
|
+
|
40
|
+
const getTemplate = () => {
|
41
|
+
return JSON.parse(localStorage.getItem('template')) || getSampleTemplate();
|
42
|
+
};
|
43
|
+
|
44
|
+
const getFont = async () => {
|
45
|
+
const SauceHanSansJP = await fetch('/SauceHanSansJP.ttf').then((res) => res.arrayBuffer());
|
46
|
+
const SauceHanSerifJP = await fetch('/SauceHanSerifJP.ttf').then((res) => res.arrayBuffer());
|
47
|
+
return {
|
48
|
+
'Noto Sans JP': { data: SauceHanSansJP, fallback: false },
|
49
|
+
'Noto Serif JP': { data: SauceHanSerifJP, fallback: true },
|
50
|
+
};
|
51
|
+
};
|
@@ -0,0 +1,54 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<title>Webpack App</title>
|
6
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
7
|
+
</head>
|
8
|
+
<body style="margin: 0">
|
9
|
+
<div>
|
10
|
+
<a href="./Designer.html">Designer</a>
|
11
|
+
/
|
12
|
+
<a href="./Form.html">Form</a>
|
13
|
+
/
|
14
|
+
<a href="./Viewer.html">Viewer</a>
|
15
|
+
</div>
|
16
|
+
<div>
|
17
|
+
<button onclick="fetchTemplates()">fetchTemplates</button>
|
18
|
+
/
|
19
|
+
<button onclick="setTemplate()">setTemplate</button>
|
20
|
+
</div>
|
21
|
+
</body>
|
22
|
+
<script>
|
23
|
+
function fetchTemplates() {
|
24
|
+
fetch('https://api.labelmake.jp/v1/templates?team=labelmake', {
|
25
|
+
method: 'GET',
|
26
|
+
headers: {
|
27
|
+
'X-Labelmake-API-Token': 'c02ee5a0-2590-11ec-bcde-1b4557d524f3',
|
28
|
+
},
|
29
|
+
})
|
30
|
+
.then((response) => response.json())
|
31
|
+
.then((json) => {
|
32
|
+
alert('saved');
|
33
|
+
localStorage.setItem('templates', JSON.stringify(json));
|
34
|
+
});
|
35
|
+
}
|
36
|
+
|
37
|
+
function setTemplate() {
|
38
|
+
const input = window.prompt('enter index');
|
39
|
+
const templates = JSON.parse(localStorage.getItem('templates'));
|
40
|
+
let template = null;
|
41
|
+
if (isNaN(input)) {
|
42
|
+
template = templates.find((t) => t.id === input);
|
43
|
+
} else {
|
44
|
+
template = templates[input];
|
45
|
+
}
|
46
|
+
if (!template) {
|
47
|
+
alert('invalid input');
|
48
|
+
return;
|
49
|
+
}
|
50
|
+
alert('set');
|
51
|
+
localStorage.setItem('template', JSON.stringify(template));
|
52
|
+
}
|
53
|
+
</script>
|
54
|
+
</html>
|
package/src/Designer.tsx
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import ReactDOM from 'react-dom';
|
3
|
+
import { Template, DesignerProps, checkDesignerProps } from '@pdfme/common';
|
4
|
+
import { BaseUIClass } from './class';
|
5
|
+
import { DESTROYED_ERR_MSG } from './constants';
|
6
|
+
import { I18nContext, FontContext } from './contexts';
|
7
|
+
import DesignerComponent from './components/Designer';
|
8
|
+
|
9
|
+
class Designer extends BaseUIClass {
|
10
|
+
private onSaveTemplateCallback?: (template: Template) => void;
|
11
|
+
private onChangeTemplateCallback?: (template: Template) => void;
|
12
|
+
|
13
|
+
constructor(props: DesignerProps) {
|
14
|
+
super(props);
|
15
|
+
checkDesignerProps(props);
|
16
|
+
|
17
|
+
this.render();
|
18
|
+
}
|
19
|
+
|
20
|
+
public saveTemplate() {
|
21
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
22
|
+
if (this.onSaveTemplateCallback) {
|
23
|
+
this.onSaveTemplateCallback(this.template);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
public updateTemplate(template: Template) {
|
28
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
29
|
+
this.template = template;
|
30
|
+
if (this.onChangeTemplateCallback) {
|
31
|
+
this.onChangeTemplateCallback(template);
|
32
|
+
}
|
33
|
+
this.render();
|
34
|
+
}
|
35
|
+
|
36
|
+
public onSaveTemplate(cb: (template: Template) => void) {
|
37
|
+
this.onSaveTemplateCallback = cb;
|
38
|
+
}
|
39
|
+
|
40
|
+
public onChangeTemplate(cb: (template: Template) => void) {
|
41
|
+
this.onChangeTemplateCallback = cb;
|
42
|
+
}
|
43
|
+
|
44
|
+
protected render() {
|
45
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
46
|
+
ReactDOM.render(
|
47
|
+
<I18nContext.Provider value={this.getI18n()}>
|
48
|
+
<FontContext.Provider value={this.getFont()}>
|
49
|
+
<DesignerComponent
|
50
|
+
template={this.template}
|
51
|
+
onSaveTemplate={(template) => {
|
52
|
+
this.template = template;
|
53
|
+
if (this.onSaveTemplateCallback) {
|
54
|
+
this.onSaveTemplateCallback(template);
|
55
|
+
}
|
56
|
+
}}
|
57
|
+
onChangeTemplate={(template) => {
|
58
|
+
this.template = template;
|
59
|
+
if (this.onChangeTemplateCallback) {
|
60
|
+
this.onChangeTemplateCallback(template);
|
61
|
+
}
|
62
|
+
}}
|
63
|
+
size={this.size}
|
64
|
+
/>
|
65
|
+
</FontContext.Provider>
|
66
|
+
</I18nContext.Provider>,
|
67
|
+
this.domContainer
|
68
|
+
);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
export default Designer;
|
package/src/Form.tsx
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import ReactDOM from 'react-dom';
|
3
|
+
import { PreviewProps } from '@pdfme/common';
|
4
|
+
import { PreviewUI } from './class';
|
5
|
+
import { DESTROYED_ERR_MSG } from './constants';
|
6
|
+
import { I18nContext, FontContext } from './contexts';
|
7
|
+
import Preview from './components/Preview';
|
8
|
+
|
9
|
+
class Form extends PreviewUI {
|
10
|
+
private onChangeInputCallback?: (arg: { index: number; value: string; key: string }) => void;
|
11
|
+
|
12
|
+
constructor(props: PreviewProps) {
|
13
|
+
super(props);
|
14
|
+
}
|
15
|
+
|
16
|
+
public onChangeInput(cb: (arg: { index: number; value: string; key: string }) => void) {
|
17
|
+
this.onChangeInputCallback = cb;
|
18
|
+
}
|
19
|
+
|
20
|
+
protected render() {
|
21
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
22
|
+
ReactDOM.render(
|
23
|
+
<I18nContext.Provider value={this.getI18n()}>
|
24
|
+
<FontContext.Provider value={this.getFont()}>
|
25
|
+
<Preview
|
26
|
+
template={this.template}
|
27
|
+
size={this.size}
|
28
|
+
inputs={this.inputs}
|
29
|
+
onChangeInput={(arg: { index: number; value: string; key: string }) => {
|
30
|
+
const { index, value, key } = arg;
|
31
|
+
if (this.onChangeInputCallback) {
|
32
|
+
this.onChangeInputCallback({ index, value, key });
|
33
|
+
}
|
34
|
+
this.inputs[index][key] = value;
|
35
|
+
this.render();
|
36
|
+
}}
|
37
|
+
/>
|
38
|
+
</FontContext.Provider>
|
39
|
+
</I18nContext.Provider>,
|
40
|
+
this.domContainer
|
41
|
+
);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
export default Form;
|
package/src/Viewer.tsx
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import ReactDOM from 'react-dom';
|
3
|
+
import { PreviewProps } from '@pdfme/common';
|
4
|
+
import { PreviewUI } from './class';
|
5
|
+
import { DESTROYED_ERR_MSG } from './constants';
|
6
|
+
import { I18nContext, FontContext } from './contexts';
|
7
|
+
import Preview from './components/Preview';
|
8
|
+
|
9
|
+
class Viewer extends PreviewUI {
|
10
|
+
constructor(props: PreviewProps) {
|
11
|
+
super(props);
|
12
|
+
}
|
13
|
+
|
14
|
+
protected render() {
|
15
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
16
|
+
ReactDOM.render(
|
17
|
+
<I18nContext.Provider value={this.getI18n()}>
|
18
|
+
<FontContext.Provider value={this.getFont()}>
|
19
|
+
<Preview template={this.template} size={this.size} inputs={this.inputs} />
|
20
|
+
</FontContext.Provider>
|
21
|
+
</I18nContext.Provider>,
|
22
|
+
this.domContainer
|
23
|
+
);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
export default Viewer;
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#ffffff">
|
2
|
+
<g>
|
3
|
+
<rect fill="none" height="24" width="24" />
|
4
|
+
</g>
|
5
|
+
<g>
|
6
|
+
<g>
|
7
|
+
<polygon points="17.59,18 19,16.59 14.42,12 19,7.41 17.59,6 11.59,12" />
|
8
|
+
<polygon points="11,18 12.41,16.59 7.83,12 12.41,7.41 11,6 5,12" />
|
9
|
+
</g>
|
10
|
+
</g>
|
11
|
+
</svg>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#ffffff">
|
2
|
+
<g>
|
3
|
+
<rect fill="none" height="24" width="24" />
|
4
|
+
</g>
|
5
|
+
<g>
|
6
|
+
<g>
|
7
|
+
<polygon points="6.41,6 5,7.41 9.58,12 5,16.59 6.41,18 12.41,12" />
|
8
|
+
<polygon points="13,6 11.59,7.41 16.17,12 11.59,16.59 13,18 19,12" />
|
9
|
+
</g>
|
10
|
+
</g>
|
11
|
+
</svg>
|
@@ -0,0 +1,3 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="16" height="16">
|
2
|
+
<path d="M10 13a1 1 0 100-2 1 1 0 000 2zm-4 0a1 1 0 100-2 1 1 0 000 2zm1-5a1 1 0 11-2 0 1 1 0 012 0zm3 1a1 1 0 100-2 1 1 0 000 2zm1-5a1 1 0 11-2 0 1 1 0 012 0zM6 5a1 1 0 100-2 1 1 0 000 2z"></path>
|
3
|
+
</svg>
|
Binary file
|
package/src/class.ts
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
import ReactDOM from 'react-dom';
|
2
|
+
import { curriedI18n } from './i18n';
|
3
|
+
import { DESTROYED_ERR_MSG, DEFAULT_LANG } from './constants';
|
4
|
+
import { debounce, flatten } from './helper';
|
5
|
+
import {
|
6
|
+
Template,
|
7
|
+
Size,
|
8
|
+
Lang,
|
9
|
+
Font,
|
10
|
+
UIProps,
|
11
|
+
PreviewProps,
|
12
|
+
getDefaultFont,
|
13
|
+
checkUIProps,
|
14
|
+
checkPreviewProps,
|
15
|
+
} from '@pdfme/common';
|
16
|
+
|
17
|
+
const generateColumnsAndSampledataIfNeeded = (template: Template) => {
|
18
|
+
const { schemas, columns, sampledata } = template;
|
19
|
+
|
20
|
+
const flatSchemaLength = schemas
|
21
|
+
.map((schema) => Object.keys(schema).length)
|
22
|
+
.reduce((acc, cur) => acc + cur, 0);
|
23
|
+
|
24
|
+
const neetColumns = !columns || flatSchemaLength !== columns.length;
|
25
|
+
|
26
|
+
const needSampledata = !sampledata || flatSchemaLength !== Object.keys(sampledata[0]).length;
|
27
|
+
|
28
|
+
// columns
|
29
|
+
if (neetColumns) {
|
30
|
+
template.columns = flatten(schemas.map((schema) => Object.keys(schema)));
|
31
|
+
}
|
32
|
+
|
33
|
+
// sampledata
|
34
|
+
if (needSampledata) {
|
35
|
+
template.sampledata = [
|
36
|
+
schemas.reduce(
|
37
|
+
(acc, cur) =>
|
38
|
+
Object.assign(
|
39
|
+
acc,
|
40
|
+
Object.keys(cur).reduce(
|
41
|
+
(a, c) => Object.assign(a, { [c]: '' }),
|
42
|
+
{} as { [key: string]: string }
|
43
|
+
)
|
44
|
+
),
|
45
|
+
{} as { [key: string]: string }
|
46
|
+
),
|
47
|
+
];
|
48
|
+
}
|
49
|
+
|
50
|
+
return template;
|
51
|
+
};
|
52
|
+
|
53
|
+
export abstract class BaseUIClass {
|
54
|
+
protected domContainer!: HTMLElement | null;
|
55
|
+
|
56
|
+
protected template!: Template;
|
57
|
+
|
58
|
+
protected size!: Size;
|
59
|
+
|
60
|
+
private readonly lang: Lang = DEFAULT_LANG;
|
61
|
+
|
62
|
+
private readonly font: Font = getDefaultFont();
|
63
|
+
|
64
|
+
private readonly setSize = debounce(() => {
|
65
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
66
|
+
this.size = {
|
67
|
+
height: this.domContainer.clientHeight || window.innerHeight,
|
68
|
+
width: this.domContainer.clientWidth || window.innerWidth,
|
69
|
+
};
|
70
|
+
this.render();
|
71
|
+
}, 100);
|
72
|
+
|
73
|
+
constructor(props: UIProps) {
|
74
|
+
checkUIProps(props);
|
75
|
+
|
76
|
+
const { domContainer, template, options } = props;
|
77
|
+
const { lang, font } = options || {};
|
78
|
+
this.domContainer = domContainer;
|
79
|
+
this.template = generateColumnsAndSampledataIfNeeded(template);
|
80
|
+
this.size = {
|
81
|
+
height: this.domContainer.clientHeight || window.innerHeight,
|
82
|
+
width: this.domContainer.clientWidth || window.innerWidth,
|
83
|
+
};
|
84
|
+
window.addEventListener('resize', this.setSize);
|
85
|
+
|
86
|
+
if (lang) {
|
87
|
+
this.lang = lang;
|
88
|
+
}
|
89
|
+
if (font) {
|
90
|
+
this.font = font;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
protected getI18n() {
|
95
|
+
return curriedI18n(this.lang);
|
96
|
+
}
|
97
|
+
|
98
|
+
protected getFont() {
|
99
|
+
return this.font;
|
100
|
+
}
|
101
|
+
|
102
|
+
public getTemplate() {
|
103
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
104
|
+
|
105
|
+
return this.template;
|
106
|
+
}
|
107
|
+
|
108
|
+
public updateTemplate(template: Template) {
|
109
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
110
|
+
this.template = template;
|
111
|
+
this.render();
|
112
|
+
}
|
113
|
+
|
114
|
+
public destroy() {
|
115
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
116
|
+
ReactDOM.unmountComponentAtNode(this.domContainer);
|
117
|
+
this.domContainer = null;
|
118
|
+
window.removeEventListener('resize', this.setSize);
|
119
|
+
}
|
120
|
+
|
121
|
+
protected abstract render(): void;
|
122
|
+
}
|
123
|
+
export abstract class PreviewUI extends BaseUIClass {
|
124
|
+
protected inputs!: { [key: string]: string }[];
|
125
|
+
|
126
|
+
constructor(props: PreviewProps) {
|
127
|
+
super(props);
|
128
|
+
checkPreviewProps(props);
|
129
|
+
|
130
|
+
this.inputs = props.inputs;
|
131
|
+
this.render();
|
132
|
+
}
|
133
|
+
|
134
|
+
public getInputs() {
|
135
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
136
|
+
|
137
|
+
return this.inputs;
|
138
|
+
}
|
139
|
+
|
140
|
+
public setInputs(inputs: { [key: string]: string }[]) {
|
141
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
142
|
+
this.inputs = inputs;
|
143
|
+
this.render();
|
144
|
+
}
|
145
|
+
|
146
|
+
protected abstract render(): void;
|
147
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import React, { Ref } from 'react';
|
2
|
+
import Guides from '@scena/react-guides';
|
3
|
+
import { Size } from '@pdfme/common';
|
4
|
+
import { ZOOM, RULER_HEIGHT } from '../../../constants';
|
5
|
+
|
6
|
+
const _Guides = ({
|
7
|
+
paperSize,
|
8
|
+
horizontalRef,
|
9
|
+
verticalRef,
|
10
|
+
}: {
|
11
|
+
paperSize: Size;
|
12
|
+
horizontalRef: Ref<Guides> | undefined;
|
13
|
+
verticalRef: Ref<Guides> | undefined;
|
14
|
+
}) => (
|
15
|
+
<>
|
16
|
+
<div
|
17
|
+
style={{
|
18
|
+
width: RULER_HEIGHT,
|
19
|
+
height: RULER_HEIGHT,
|
20
|
+
position: 'absolute',
|
21
|
+
top: -RULER_HEIGHT,
|
22
|
+
left: -RULER_HEIGHT,
|
23
|
+
background: '#333',
|
24
|
+
}}
|
25
|
+
></div>
|
26
|
+
<Guides
|
27
|
+
zoom={ZOOM}
|
28
|
+
style={{
|
29
|
+
position: 'absolute',
|
30
|
+
top: -RULER_HEIGHT,
|
31
|
+
left: 0,
|
32
|
+
height: RULER_HEIGHT,
|
33
|
+
width: paperSize.width,
|
34
|
+
}}
|
35
|
+
type="horizontal"
|
36
|
+
ref={horizontalRef}
|
37
|
+
/>
|
38
|
+
<Guides
|
39
|
+
zoom={ZOOM}
|
40
|
+
style={{
|
41
|
+
position: 'absolute',
|
42
|
+
top: 0,
|
43
|
+
left: -RULER_HEIGHT,
|
44
|
+
height: paperSize.height,
|
45
|
+
width: RULER_HEIGHT,
|
46
|
+
}}
|
47
|
+
type="vertical"
|
48
|
+
ref={verticalRef}
|
49
|
+
/>
|
50
|
+
</>
|
51
|
+
);
|
52
|
+
|
53
|
+
export default _Guides;
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { Size } from '@pdfme/common';
|
3
|
+
import { RULER_HEIGHT } from '../../../constants';
|
4
|
+
|
5
|
+
const Mask = ({ width, height }: Size) => (
|
6
|
+
<div
|
7
|
+
style={{
|
8
|
+
position: 'absolute',
|
9
|
+
top: -RULER_HEIGHT,
|
10
|
+
left: -RULER_HEIGHT,
|
11
|
+
zIndex: 100,
|
12
|
+
background: 'rgba(158, 158, 158, 0.58)',
|
13
|
+
width,
|
14
|
+
height,
|
15
|
+
}}
|
16
|
+
/>
|
17
|
+
);
|
18
|
+
|
19
|
+
export default Mask;
|