@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.
Files changed (118) hide show
  1. package/.eslintrc.js +45 -0
  2. package/README.md +280 -0
  3. package/declaration.d.ts +8 -0
  4. package/dist/@pdfme/ui.js +3 -0
  5. package/dist/@pdfme/ui.js.LICENSE.txt +95 -0
  6. package/dist/@pdfme/ui.js.map +1 -0
  7. package/dist/types/common/src/barcode.d.ts +2 -0
  8. package/dist/types/common/src/constants.d.ts +6 -0
  9. package/dist/types/common/src/helper.d.ts +15 -0
  10. package/dist/types/common/src/index.d.ts +4 -0
  11. package/dist/types/common/src/schema.d.ts +3613 -0
  12. package/dist/types/common/src/type.d.ts +64 -0
  13. package/dist/types/common/src/utils.d.ts +12 -0
  14. package/dist/types/ui/src/Designer.d.ts +13 -0
  15. package/dist/types/ui/src/Form.d.ts +13 -0
  16. package/dist/types/ui/src/Viewer.d.ts +7 -0
  17. package/dist/types/ui/src/class.d.ts +72 -0
  18. package/dist/types/ui/src/components/Designer/Main/Guides.d.ts +9 -0
  19. package/dist/types/ui/src/components/Designer/Main/Mask.d.ts +3 -0
  20. package/dist/types/ui/src/components/Designer/Main/Moveable.d.ts +31 -0
  21. package/dist/types/ui/src/components/Designer/Main/Selecto.d.ts +8 -0
  22. package/dist/types/ui/src/components/Designer/Main/index.d.ts +24 -0
  23. package/dist/types/ui/src/components/Designer/Sidebar/DetailView/ExampleInputEditor.d.ts +3 -0
  24. package/dist/types/ui/src/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.d.ts +3 -0
  25. package/dist/types/ui/src/components/Designer/Sidebar/DetailView/TextPropEditor.d.ts +3 -0
  26. package/dist/types/ui/src/components/Designer/Sidebar/DetailView/TypeAndKeyEditor.d.ts +3 -0
  27. package/dist/types/ui/src/components/Designer/Sidebar/DetailView/index.d.ts +3 -0
  28. package/dist/types/ui/src/components/Designer/Sidebar/ListView.d.ts +3 -0
  29. package/dist/types/ui/src/components/Designer/Sidebar/index.d.ts +26 -0
  30. package/dist/types/ui/src/components/Designer/index.d.ts +99 -0
  31. package/dist/types/ui/src/components/Divider.d.ts +2 -0
  32. package/dist/types/ui/src/components/Error.d.ts +7 -0
  33. package/dist/types/ui/src/components/Paper.d.ts +19 -0
  34. package/dist/types/ui/src/components/Preview/Pager/Page.d.ts +8 -0
  35. package/dist/types/ui/src/components/Preview/Pager/Unit.d.ts +8 -0
  36. package/dist/types/ui/src/components/Preview/index.d.ts +4 -0
  37. package/dist/types/ui/src/components/Root.d.ts +9 -0
  38. package/dist/types/ui/src/components/Schemas/BarcodeSchema.d.ts +15 -0
  39. package/dist/types/ui/src/components/Schemas/ImageSchema.d.ts +15 -0
  40. package/dist/types/ui/src/components/Schemas/SchemaUI.d.ts +14 -0
  41. package/dist/types/ui/src/components/Schemas/TextSchema.d.ts +22 -0
  42. package/dist/types/ui/src/components/Spinner.d.ts +2 -0
  43. package/dist/types/ui/src/constants.d.ts +5 -0
  44. package/dist/types/ui/src/contexts.d.ts +7 -0
  45. package/dist/types/ui/src/helper.d.ts +91 -0
  46. package/dist/types/ui/src/hooks.d.ts +26 -0
  47. package/dist/types/ui/src/i18n.d.ts +30 -0
  48. package/dist/types/ui/src/index.d.ts +5 -0
  49. package/dist/types/ui/src/libs/class.d.ts +84 -0
  50. package/dist/types/ui/src/libs/contexts.d.ts +7 -0
  51. package/dist/types/ui/src/libs/helper.d.ts +64 -0
  52. package/dist/types/ui/src/libs/hooks.d.ts +26 -0
  53. package/dist/types/ui/src/libs/i18n.d.ts +30 -0
  54. package/dist/types/ui/src/libs/ui.d.ts +64 -0
  55. package/package.json +80 -0
  56. package/public/Designer.html +90 -0
  57. package/public/Form.html +74 -0
  58. package/public/SauceHanSansJP.ttf +0 -0
  59. package/public/SauceHanSerifJP.ttf +0 -0
  60. package/public/Viewer.html +73 -0
  61. package/public/helper.js +51 -0
  62. package/public/index.html +54 -0
  63. package/src/Designer.tsx +72 -0
  64. package/src/Form.tsx +45 -0
  65. package/src/Viewer.tsx +27 -0
  66. package/src/assets/barcodeExamples/code128.png +0 -0
  67. package/src/assets/barcodeExamples/code39.png +0 -0
  68. package/src/assets/barcodeExamples/ean13.png +0 -0
  69. package/src/assets/barcodeExamples/ean8.png +0 -0
  70. package/src/assets/barcodeExamples/itf14.png +0 -0
  71. package/src/assets/barcodeExamples/japanpost.png +0 -0
  72. package/src/assets/barcodeExamples/nw7.png +0 -0
  73. package/src/assets/barcodeExamples/qrcode.png +0 -0
  74. package/src/assets/barcodeExamples/upca.png +0 -0
  75. package/src/assets/barcodeExamples/upce.png +0 -0
  76. package/src/assets/icons/back.svg +4 -0
  77. package/src/assets/icons/double-left.svg +11 -0
  78. package/src/assets/icons/double-right.svg +11 -0
  79. package/src/assets/icons/drag.svg +3 -0
  80. package/src/assets/icons/forward.svg +4 -0
  81. package/src/assets/icons/left.svg +4 -0
  82. package/src/assets/icons/right.svg +4 -0
  83. package/src/assets/icons/warning.svg +4 -0
  84. package/src/assets/imageExample.png +0 -0
  85. package/src/class.ts +147 -0
  86. package/src/components/Designer/Main/Guides.tsx +53 -0
  87. package/src/components/Designer/Main/Mask.tsx +19 -0
  88. package/src/components/Designer/Main/Moveable.tsx +79 -0
  89. package/src/components/Designer/Main/Selecto.tsx +29 -0
  90. package/src/components/Designer/Main/index.tsx +314 -0
  91. package/src/components/Designer/Sidebar/DetailView/ExampleInputEditor.tsx +62 -0
  92. package/src/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.tsx +98 -0
  93. package/src/components/Designer/Sidebar/DetailView/TextPropEditor.tsx +178 -0
  94. package/src/components/Designer/Sidebar/DetailView/TypeAndKeyEditor.tsx +79 -0
  95. package/src/components/Designer/Sidebar/DetailView/index.tsx +39 -0
  96. package/src/components/Designer/Sidebar/ListView.tsx +180 -0
  97. package/src/components/Designer/Sidebar/index.tsx +102 -0
  98. package/src/components/Designer/index.tsx +283 -0
  99. package/src/components/Divider.tsx +7 -0
  100. package/src/components/Error.tsx +31 -0
  101. package/src/components/Paper.tsx +77 -0
  102. package/src/components/Preview/Pager/Page.tsx +85 -0
  103. package/src/components/Preview/Pager/Unit.tsx +87 -0
  104. package/src/components/Preview/index.tsx +102 -0
  105. package/src/components/Root.tsx +52 -0
  106. package/src/components/Schemas/BarcodeSchema.tsx +111 -0
  107. package/src/components/Schemas/ImageSchema.tsx +81 -0
  108. package/src/components/Schemas/SchemaUI.tsx +64 -0
  109. package/src/components/Schemas/TextSchema.tsx +62 -0
  110. package/src/components/Spinner.tsx +37 -0
  111. package/src/constants.ts +9 -0
  112. package/src/contexts.ts +8 -0
  113. package/src/helper.ts +516 -0
  114. package/src/hooks.ts +107 -0
  115. package/src/i18n.ts +64 -0
  116. package/src/index.ts +77 -0
  117. package/tsconfig.json +21 -0
  118. 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>
@@ -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>
@@ -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;
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
2
+ <path d="M0 0h24v24H0z" fill="none" />
3
+ <path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z" />
4
+ </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="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>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
2
+ <path d="M0 0h24v24H0z" fill="none" />
3
+ <path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z" />
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#ffffff">
2
+ <path d="M0 0h24v24H0V0z" fill="none" />
3
+ <path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z" />
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#ffffff">
2
+ <path d="M0 0h24v24H0V0z" fill="none" />
3
+ <path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z" />
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
2
+ <path d="M0 0h24v24H0z" fill="none" />
3
+ <path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" />
4
+ </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;