@pdfme/schemas 3.1.5 → 3.2.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/README.md +303 -0
- package/dist/cjs/__tests__/{renderUtils.test.js → utils.test.js} +38 -12
- package/dist/cjs/__tests__/utils.test.js.map +1 -0
- package/dist/cjs/src/barcodes/constants.js +2 -1
- package/dist/cjs/src/barcodes/constants.js.map +1 -1
- package/dist/cjs/src/barcodes/helper.js +1 -2
- package/dist/cjs/src/barcodes/helper.js.map +1 -1
- package/dist/cjs/src/barcodes/index.js +2 -2
- package/dist/cjs/src/barcodes/index.js.map +1 -1
- package/dist/cjs/src/barcodes/pdfRender.js +3 -3
- package/dist/cjs/src/barcodes/pdfRender.js.map +1 -1
- package/dist/cjs/src/barcodes/propPanel.js +45 -30
- package/dist/cjs/src/barcodes/propPanel.js.map +1 -1
- package/dist/cjs/src/barcodes/uiRender.js +11 -37
- package/dist/cjs/src/barcodes/uiRender.js.map +1 -1
- package/dist/cjs/src/graphics/helper.js +115 -0
- package/dist/cjs/src/graphics/helper.js.map +1 -0
- package/dist/cjs/src/graphics/image.js +179 -0
- package/dist/cjs/src/graphics/image.js.map +1 -0
- package/dist/cjs/src/graphics/svg.js +96 -0
- package/dist/cjs/src/graphics/svg.js.map +1 -0
- package/dist/cjs/src/index.js +42 -9
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/shapes/line.js +57 -0
- package/dist/cjs/src/shapes/line.js.map +1 -0
- package/dist/cjs/src/shapes/rectAndEllipse.js +100 -0
- package/dist/cjs/src/shapes/rectAndEllipse.js.map +1 -0
- package/dist/cjs/src/text/helper.js.map +1 -1
- package/dist/cjs/src/text/index.js +16 -2
- package/dist/cjs/src/text/index.js.map +1 -1
- package/dist/cjs/src/text/pdfRender.js +9 -32
- package/dist/cjs/src/text/pdfRender.js.map +1 -1
- package/dist/cjs/src/text/propPanel.js +2 -2
- package/dist/cjs/src/text/propPanel.js.map +1 -1
- package/dist/cjs/src/text/uiRender.js +12 -18
- package/dist/cjs/src/text/uiRender.js.map +1 -1
- package/dist/cjs/src/utils.js +134 -0
- package/dist/cjs/src/utils.js.map +1 -0
- package/dist/esm/__tests__/{renderUtils.test.js → utils.test.js} +34 -8
- package/dist/esm/__tests__/utils.test.js.map +1 -0
- package/dist/esm/src/barcodes/constants.js +1 -0
- package/dist/esm/src/barcodes/constants.js.map +1 -1
- package/dist/esm/src/barcodes/helper.js +2 -3
- package/dist/esm/src/barcodes/helper.js.map +1 -1
- package/dist/esm/src/barcodes/index.js +2 -2
- package/dist/esm/src/barcodes/index.js.map +1 -1
- package/dist/esm/src/barcodes/pdfRender.js +2 -2
- package/dist/esm/src/barcodes/pdfRender.js.map +1 -1
- package/dist/esm/src/barcodes/propPanel.js +46 -31
- package/dist/esm/src/barcodes/propPanel.js.map +1 -1
- package/dist/esm/src/barcodes/uiRender.js +11 -37
- package/dist/esm/src/barcodes/uiRender.js.map +1 -1
- package/dist/esm/src/graphics/helper.js +111 -0
- package/dist/esm/src/graphics/helper.js.map +1 -0
- package/dist/esm/src/graphics/image.js +176 -0
- package/dist/esm/src/graphics/image.js.map +1 -0
- package/dist/esm/src/graphics/svg.js +93 -0
- package/dist/esm/src/graphics/svg.js.map +1 -0
- package/dist/esm/src/index.js +7 -4
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/shapes/line.js +55 -0
- package/dist/esm/src/shapes/line.js.map +1 -0
- package/dist/esm/src/shapes/rectAndEllipse.js +97 -0
- package/dist/esm/src/shapes/rectAndEllipse.js.map +1 -0
- package/dist/esm/src/text/helper.js.map +1 -1
- package/dist/esm/src/text/index.js +15 -2
- package/dist/esm/src/text/index.js.map +1 -1
- package/dist/esm/src/text/pdfRender.js +6 -29
- package/dist/esm/src/text/pdfRender.js.map +1 -1
- package/dist/esm/src/text/propPanel.js +2 -2
- package/dist/esm/src/text/propPanel.js.map +1 -1
- package/dist/esm/src/text/uiRender.js +12 -18
- package/dist/esm/src/text/uiRender.js.map +1 -1
- package/dist/esm/src/utils.js +124 -0
- package/dist/esm/src/utils.js.map +1 -0
- package/dist/types/src/barcodes/constants.d.ts +1 -0
- package/dist/types/src/barcodes/helper.d.ts +1 -0
- package/dist/types/src/barcodes/index.d.ts +2 -2
- package/dist/types/src/barcodes/types.d.ts +1 -0
- package/dist/types/src/graphics/helper.d.ts +5 -0
- package/dist/types/src/graphics/image.d.ts +7 -0
- package/dist/types/src/graphics/svg.d.ts +6 -0
- package/dist/types/src/index.d.ts +7 -4
- package/dist/types/src/shapes/line.d.ts +6 -0
- package/dist/types/src/shapes/rectAndEllipse.d.ts +144 -0
- package/dist/types/src/text/index.d.ts +3 -2
- package/dist/types/src/text/pdfRender.d.ts +1 -1
- package/dist/types/src/{renderUtils.d.ts → utils.d.ts} +5 -1
- package/package.json +4 -3
- package/src/barcodes/constants.ts +2 -0
- package/src/barcodes/helper.ts +12 -3
- package/src/barcodes/index.ts +2 -2
- package/src/barcodes/pdfRender.ts +2 -2
- package/src/barcodes/propPanel.ts +50 -30
- package/src/barcodes/types.ts +1 -0
- package/src/barcodes/uiRender.ts +11 -41
- package/src/graphics/helper.ts +147 -0
- package/src/graphics/image.ts +207 -0
- package/src/graphics/svg.ts +98 -0
- package/src/index.ts +21 -4
- package/src/shapes/line.ts +67 -0
- package/src/shapes/rectAndEllipse.ts +110 -0
- package/src/text/helper.ts +0 -1
- package/src/text/index.ts +16 -2
- package/src/text/pdfRender.ts +6 -42
- package/src/text/propPanel.ts +2 -2
- package/src/text/uiRender.ts +14 -29
- package/src/utils.ts +161 -0
- package/dist/cjs/__tests__/renderUtils.test.js.map +0 -1
- package/dist/cjs/src/image/index.js +0 -8
- package/dist/cjs/src/image/index.js.map +0 -1
- package/dist/cjs/src/image/pdfRender.js +0 -20
- package/dist/cjs/src/image/pdfRender.js.map +0 -1
- package/dist/cjs/src/image/propPanel.js +0 -19
- package/dist/cjs/src/image/propPanel.js.map +0 -1
- package/dist/cjs/src/image/types.js +0 -3
- package/dist/cjs/src/image/types.js.map +0 -1
- package/dist/cjs/src/image/uiRender.js +0 -111
- package/dist/cjs/src/image/uiRender.js.map +0 -1
- package/dist/cjs/src/renderUtils.js +0 -59
- package/dist/cjs/src/renderUtils.js.map +0 -1
- package/dist/esm/__tests__/renderUtils.test.js.map +0 -1
- package/dist/esm/src/image/index.js +0 -6
- package/dist/esm/src/image/index.js.map +0 -1
- package/dist/esm/src/image/pdfRender.js +0 -16
- package/dist/esm/src/image/pdfRender.js.map +0 -1
- package/dist/esm/src/image/propPanel.js +0 -16
- package/dist/esm/src/image/propPanel.js.map +0 -1
- package/dist/esm/src/image/types.js +0 -2
- package/dist/esm/src/image/types.js.map +0 -1
- package/dist/esm/src/image/uiRender.js +0 -107
- package/dist/esm/src/image/uiRender.js.map +0 -1
- package/dist/esm/src/renderUtils.js +0 -53
- package/dist/esm/src/renderUtils.js.map +0 -1
- package/dist/types/src/image/index.d.ts +0 -4
- package/dist/types/src/image/pdfRender.d.ts +0 -3
- package/dist/types/src/image/propPanel.d.ts +0 -3
- package/dist/types/src/image/types.d.ts +0 -3
- package/dist/types/src/image/uiRender.d.ts +0 -3
- package/src/image/index.ts +0 -8
- package/src/image/pdfRender.ts +0 -28
- package/src/image/propPanel.ts +0 -19
- package/src/image/types.ts +0 -3
- package/src/image/uiRender.ts +0 -121
- package/src/renderUtils.ts +0 -73
- /package/dist/types/__tests__/{renderUtils.test.d.ts → utils.test.d.ts} +0 -0
@@ -0,0 +1,207 @@
|
|
1
|
+
import type { ChangeEvent } from 'react';
|
2
|
+
import type { PDFImage } from '@pdfme/pdf-lib';
|
3
|
+
import type { Plugin } from '@pdfme/common';
|
4
|
+
import type { PDFRenderProps, Schema } from '@pdfme/common';
|
5
|
+
import type * as CSS from 'csstype';
|
6
|
+
import { Buffer } from 'buffer';
|
7
|
+
import { UIRenderProps } from '@pdfme/common';
|
8
|
+
import { convertForPdfLayoutProps, addAlphaToHex, isEditable, readFile } from '../utils.js';
|
9
|
+
import { DEFAULT_OPACITY } from '../constants.js';
|
10
|
+
import { imageSize } from './helper.js';
|
11
|
+
|
12
|
+
const px2mm = (px: number): number => {
|
13
|
+
// http://www.endmemo.com/sconvert/millimeterpixel.php
|
14
|
+
const ratio = 0.26458333333333;
|
15
|
+
return parseFloat(String(px)) * ratio;
|
16
|
+
};
|
17
|
+
|
18
|
+
const getCacheKey = (schema: Schema, input: string) => `${schema.type}${input}`;
|
19
|
+
const fullSize = { width: '100%', height: '100%' };
|
20
|
+
const defaultValue =
|
21
|
+
'data:image/png;base64,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';
|
22
|
+
|
23
|
+
interface ImageSchema extends Schema {}
|
24
|
+
|
25
|
+
const imageSchema: Plugin<ImageSchema> = {
|
26
|
+
pdf: async (arg: PDFRenderProps<ImageSchema>) => {
|
27
|
+
const { value, schema, pdfDoc, page, _cache } = arg;
|
28
|
+
if (!value || !value.startsWith('data:image/')) return;
|
29
|
+
|
30
|
+
const inputImageCacheKey = getCacheKey(schema, value);
|
31
|
+
let image = _cache.get(inputImageCacheKey) as PDFImage;
|
32
|
+
if (!image) {
|
33
|
+
const isPng = value.startsWith('data:image/png;');
|
34
|
+
image = await (isPng ? pdfDoc.embedPng(value) : pdfDoc.embedJpg(value));
|
35
|
+
_cache.set(inputImageCacheKey, image);
|
36
|
+
}
|
37
|
+
|
38
|
+
const _schema = { ...schema, position: { ...schema.position } };
|
39
|
+
const dataUriPrefix = ';base64,';
|
40
|
+
const idx = value.indexOf(dataUriPrefix);
|
41
|
+
const imgBase64 = value.substring(idx + dataUriPrefix.length, value.length);
|
42
|
+
const dimension = imageSize(Buffer.from(imgBase64, 'base64'));
|
43
|
+
|
44
|
+
const imageWidth = px2mm(dimension.width);
|
45
|
+
const imageHeight = px2mm(dimension.height);
|
46
|
+
const boxWidth = _schema.width;
|
47
|
+
const boxHeight = _schema.height;
|
48
|
+
|
49
|
+
const imageRatio = imageWidth / imageHeight;
|
50
|
+
const boxRatio = boxWidth / boxHeight;
|
51
|
+
|
52
|
+
if (imageRatio > boxRatio) {
|
53
|
+
_schema.width = boxWidth;
|
54
|
+
_schema.height = boxWidth / imageRatio;
|
55
|
+
_schema.position.y += (boxHeight - _schema.height) / 2;
|
56
|
+
} else {
|
57
|
+
_schema.width = boxHeight * imageRatio;
|
58
|
+
_schema.height = boxHeight;
|
59
|
+
_schema.position.x += (boxWidth - _schema.width) / 2;
|
60
|
+
}
|
61
|
+
|
62
|
+
const pageHeight = page.getHeight();
|
63
|
+
const lProps = convertForPdfLayoutProps({ schema: _schema, pageHeight });
|
64
|
+
const { width, height, rotate, position, opacity } = lProps;
|
65
|
+
const { x, y } = position;
|
66
|
+
page.drawImage(image, { x, y, rotate, width, height, opacity });
|
67
|
+
},
|
68
|
+
ui: (arg: UIRenderProps<ImageSchema>) => {
|
69
|
+
const {
|
70
|
+
value,
|
71
|
+
rootElement,
|
72
|
+
mode,
|
73
|
+
onChange,
|
74
|
+
stopEditing,
|
75
|
+
tabIndex,
|
76
|
+
placeholder,
|
77
|
+
theme,
|
78
|
+
schema,
|
79
|
+
} = arg;
|
80
|
+
const editable = isEditable(mode, schema);
|
81
|
+
const isDefault = value === defaultValue;
|
82
|
+
|
83
|
+
const container = document.createElement('div');
|
84
|
+
const backgroundStyle = placeholder ? `url(${placeholder})` : 'none';
|
85
|
+
const containerStyle: CSS.Properties = {
|
86
|
+
...fullSize,
|
87
|
+
backgroundImage: value ? 'none' : backgroundStyle,
|
88
|
+
backgroundSize: `contain`,
|
89
|
+
backgroundRepeat: 'no-repeat',
|
90
|
+
backgroundPosition: 'center',
|
91
|
+
};
|
92
|
+
Object.assign(container.style, containerStyle);
|
93
|
+
container.addEventListener('click', (e) => {
|
94
|
+
if (editable) {
|
95
|
+
e.stopPropagation();
|
96
|
+
}
|
97
|
+
});
|
98
|
+
rootElement.appendChild(container);
|
99
|
+
|
100
|
+
// image tag
|
101
|
+
if (value) {
|
102
|
+
const img = document.createElement('img');
|
103
|
+
const imgStyle: CSS.Properties = {
|
104
|
+
height: '100%',
|
105
|
+
width: '100%',
|
106
|
+
borderRadius: 0,
|
107
|
+
objectFit: 'contain',
|
108
|
+
};
|
109
|
+
Object.assign(img.style, imgStyle);
|
110
|
+
img.src = value;
|
111
|
+
container.appendChild(img);
|
112
|
+
}
|
113
|
+
|
114
|
+
// remove button
|
115
|
+
if (value && !isDefault && editable) {
|
116
|
+
const button = document.createElement('button');
|
117
|
+
button.textContent = 'x';
|
118
|
+
const buttonStyle: CSS.Properties = {
|
119
|
+
position: 'absolute',
|
120
|
+
top: 0,
|
121
|
+
left: 0,
|
122
|
+
zIndex: 1,
|
123
|
+
display: 'flex',
|
124
|
+
justifyContent: 'center',
|
125
|
+
alignItems: 'center',
|
126
|
+
color: '#333',
|
127
|
+
background: '#f2f2f2',
|
128
|
+
borderRadius: '2px',
|
129
|
+
border: '1px solid #767676',
|
130
|
+
cursor: 'pointer',
|
131
|
+
height: '24px',
|
132
|
+
width: '24px',
|
133
|
+
};
|
134
|
+
Object.assign(button.style, buttonStyle);
|
135
|
+
button.addEventListener('click', () => {
|
136
|
+
onChange && onChange('');
|
137
|
+
});
|
138
|
+
container.appendChild(button);
|
139
|
+
}
|
140
|
+
|
141
|
+
// file input
|
142
|
+
if ((!value || isDefault) && editable) {
|
143
|
+
const label = document.createElement('label');
|
144
|
+
const labelStyle: CSS.Properties = {
|
145
|
+
...fullSize,
|
146
|
+
display: editable ? 'flex' : 'none',
|
147
|
+
position: 'absolute',
|
148
|
+
top: 0,
|
149
|
+
backgroundColor: editable || value ? addAlphaToHex(theme.colorPrimaryBg, 30) : 'none',
|
150
|
+
cursor: 'pointer',
|
151
|
+
};
|
152
|
+
Object.assign(label.style, labelStyle);
|
153
|
+
container.appendChild(label);
|
154
|
+
const input = document.createElement('input');
|
155
|
+
const inputStyle: CSS.Properties = {
|
156
|
+
...fullSize,
|
157
|
+
position: 'absolute',
|
158
|
+
top: '50%',
|
159
|
+
left: '50%',
|
160
|
+
width: '180px',
|
161
|
+
height: '30px',
|
162
|
+
marginLeft: '-90px',
|
163
|
+
marginTop: '-15px',
|
164
|
+
};
|
165
|
+
Object.assign(input.style, inputStyle);
|
166
|
+
input.tabIndex = tabIndex || 0;
|
167
|
+
input.type = 'file';
|
168
|
+
input.accept = 'image/jpeg, image/png';
|
169
|
+
input.addEventListener('change', (event: Event) => {
|
170
|
+
const changeEvent = event as unknown as ChangeEvent<HTMLInputElement>;
|
171
|
+
readFile(changeEvent.target.files).then((result) => onChange && onChange(result as string));
|
172
|
+
});
|
173
|
+
input.addEventListener('blur', () => stopEditing && stopEditing());
|
174
|
+
label.appendChild(input);
|
175
|
+
}
|
176
|
+
},
|
177
|
+
propPanel: {
|
178
|
+
schema: {},
|
179
|
+
defaultValue,
|
180
|
+
defaultSchema: {
|
181
|
+
type: 'image',
|
182
|
+
position: { x: 0, y: 0 },
|
183
|
+
width: 40,
|
184
|
+
height: 40,
|
185
|
+
// If the value of "rotate" is set to undefined or not set at all, rotation will be disabled in the UI.
|
186
|
+
// Check this document: https://pdfme.com//docs/custom-schemas#learning-how-to-create-from-pdfmeschemas-code
|
187
|
+
rotate: 0,
|
188
|
+
opacity: DEFAULT_OPACITY,
|
189
|
+
},
|
190
|
+
},
|
191
|
+
};
|
192
|
+
|
193
|
+
export default imageSchema;
|
194
|
+
|
195
|
+
export const readOnlyImage: Plugin<ImageSchema> = {
|
196
|
+
pdf: imageSchema.pdf,
|
197
|
+
ui: imageSchema.ui,
|
198
|
+
propPanel: {
|
199
|
+
...imageSchema.propPanel,
|
200
|
+
defaultSchema: {
|
201
|
+
...imageSchema.propPanel.defaultSchema,
|
202
|
+
type: 'readOnlyImage',
|
203
|
+
readOnly: true,
|
204
|
+
readOnlyValue: defaultValue,
|
205
|
+
},
|
206
|
+
},
|
207
|
+
};
|
@@ -0,0 +1,98 @@
|
|
1
|
+
import { Plugin, Schema } from '@pdfme/common';
|
2
|
+
import { XMLValidator } from 'fast-xml-parser';
|
3
|
+
import { convertForPdfLayoutProps, isEditable, addAlphaToHex, createErrorElm } from '../utils.js';
|
4
|
+
|
5
|
+
const isValidSVG = (svgString: string) => XMLValidator.validate(svgString) === true;
|
6
|
+
|
7
|
+
const defaultValue = `<svg viewBox="0 0 488 600" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
8
|
+
<g transform="matrix(1,0,0,1,-56,0)" fill="#000000" stroke="none">
|
9
|
+
<path d="M228.667,0L56,172.667L56.267,345.334L56.667,518L59.733,527.334C65.867,545.467 72.933,557.067 86,570.134C96.133,580.4 100,583.2 110.667,588.4C134.533,600.134 120,599.334 300,599.334C480,599.334 465.467,600.134 489.334,588.4C500,583.2 503.867,580.4 514,570.134C527.334,556.8 534.534,544.8 540.267,526.667L543.334,516.667L543.334,83.333L540.267,73.333C534.534,55.2 527.334,43.2 514,29.867C503.867,19.6 500,16.8 489.334,11.6C465.734,0 475.467,0.8 344.667,0.267L228.667,0ZM466.4,41.6C483.334,48.933 496.267,61.867 502.934,78.4L506,86L506,514L502.934,521.734C496,538.934 480.267,553.867 463.334,559.334C455.6,561.867 450.8,562 300,562C149.2,562 144.4,561.867 136.667,559.334C119.733,553.867 104,538.934 97.067,521.734L94,514L93.6,351.067L93.333,188.133L149.067,187.733L204.667,187.333L213.6,182.933C224.8,177.467 235.867,165.867 240.267,155.067C243.333,147.467 243.333,146.4 243.733,92.267L244.133,37.2L458,38L466.4,41.6ZM195.067,304C175.6,306.8 164,320.667 165.6,339.467C166,343.6 167.6,348.667 169.733,352.4C174.4,360.267 185.2,365.734 201.867,368.534C208.4,369.734 215.067,371.467 216.8,372.667C224,377.334 221.467,389.067 212.533,392C205.6,394.4 193.733,392.934 185.6,388.8C173.333,382.534 164,385.334 164,395.2C164,400.934 170.133,406.667 180.267,410.134C190.933,413.867 217.067,413.734 225.467,409.867C238.933,403.6 246.667,390 244.8,375.6C242.667,359.734 232.8,351.334 212.267,347.867C193.6,344.8 189.333,342.4 189.333,334.533C189.333,324.267 201.867,320.933 218.267,326.667C228.667,330.267 232.533,330.133 235.867,325.867C242.133,318 237.6,310.667 224.267,306.8C213.333,303.6 204.267,302.8 195.067,304ZM386,304.133C377.6,305.333 374,306.8 367.334,311.6C355.734,320.133 351.2,336.4 352.4,365.334C353.2,385.334 356,394.4 364.134,402.534C372.267,410.667 381.734,413.734 396.667,413.067C406.8,412.667 409.734,412 415.734,408.667C429.2,401.334 434.534,390.934 435.6,370.667C436.4,353.734 436,353.067 420.934,352.267C401.867,351.334 396,353.467 396,361.867C396,367.867 399.467,370.667 407.067,370.667C413.2,370.667 413.334,370.667 413.334,374.934C413.334,394 386.267,400.534 378.534,383.467C374.934,375.334 374.934,341.867 378.534,333.733C382,326.4 387.467,323.467 396.8,324.267C403.067,324.8 404.667,325.6 410.534,331.067C414.267,334.533 418.4,337.333 419.867,337.333C427.334,337.333 433.334,330.267 431.334,323.733C427.2,310.133 406.4,301.2 386,304.133ZM258.4,308C255.067,311.467 254.533,312.8 255.2,316.4C257.067,326.667 285.333,405.867 288.133,408.8C289.733,410.534 293.067,412.267 295.333,412.8C303.867,414.4 310.667,407.867 314.4,394.667C315.067,392.134 321.2,374.134 327.867,354.8C334.8,334.533 340,317.467 340,314.533C340,303.733 325.067,299.867 319.867,309.467C318.533,312.133 309.467,340.933 302.667,364C301.067,369.467 299.333,374.4 298.8,375.067C298.267,375.6 292.933,360.8 286.933,342C275.333,306 274.133,304 266.267,304C263.867,304 261.067,305.467 258.4,308Z" style="fill-rule:nonzero;"/>
|
10
|
+
</g>
|
11
|
+
</svg>`;
|
12
|
+
|
13
|
+
interface SVGSchema extends Schema {}
|
14
|
+
|
15
|
+
const svgSchema: Plugin<SVGSchema> = {
|
16
|
+
ui: (arg) => {
|
17
|
+
const { rootElement, value, mode, onChange, theme, schema } = arg;
|
18
|
+
const container = document.createElement(isEditable(mode, schema) ? 'textarea' : 'div');
|
19
|
+
container.style.width = '100%';
|
20
|
+
container.style.height = '100%';
|
21
|
+
container.style.boxSizing = 'border-box';
|
22
|
+
if (isEditable(mode, schema)) {
|
23
|
+
const textarea = container as HTMLTextAreaElement;
|
24
|
+
textarea.value = value;
|
25
|
+
textarea.style.position = 'absolute';
|
26
|
+
textarea.style.backgroundColor = addAlphaToHex(theme.colorPrimaryBg, 30);
|
27
|
+
|
28
|
+
if (isValidSVG(value)) {
|
29
|
+
const svgElement = new DOMParser().parseFromString(value, 'text/xml').childNodes[0];
|
30
|
+
if (svgElement instanceof SVGElement) {
|
31
|
+
svgElement.setAttribute('width', '100%');
|
32
|
+
svgElement.setAttribute('height', '100%');
|
33
|
+
svgElement.style.position = 'absolute';
|
34
|
+
}
|
35
|
+
rootElement.appendChild(svgElement);
|
36
|
+
} else if (value) {
|
37
|
+
const errorElm = createErrorElm();
|
38
|
+
errorElm.style.position = 'absolute';
|
39
|
+
rootElement.appendChild(errorElm);
|
40
|
+
}
|
41
|
+
|
42
|
+
textarea.addEventListener('change', (e: Event) => {
|
43
|
+
const newValue = (e.target as HTMLTextAreaElement).value;
|
44
|
+
onChange && onChange(newValue);
|
45
|
+
});
|
46
|
+
rootElement.appendChild(container);
|
47
|
+
textarea.setSelectionRange(value.length, value.length);
|
48
|
+
textarea.focus();
|
49
|
+
} else {
|
50
|
+
if (!value) return;
|
51
|
+
if (!isValidSVG(value)) {
|
52
|
+
rootElement.appendChild(createErrorElm());
|
53
|
+
return;
|
54
|
+
}
|
55
|
+
container.innerHTML = value;
|
56
|
+
const svgElement = container.childNodes[0];
|
57
|
+
if (svgElement instanceof SVGElement) {
|
58
|
+
svgElement.setAttribute('width', '100%');
|
59
|
+
svgElement.setAttribute('height', '100%');
|
60
|
+
rootElement.appendChild(container);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
},
|
64
|
+
pdf: async (arg) => {
|
65
|
+
const { page, schema, value } = arg;
|
66
|
+
if (!value || !isValidSVG(value)) return;
|
67
|
+
const pageHeight = page.getHeight();
|
68
|
+
const { width, height, position } = convertForPdfLayoutProps({ schema, pageHeight });
|
69
|
+
const { x, y } = position;
|
70
|
+
await page.drawSvg(value, { x, y: y + height, width, height });
|
71
|
+
},
|
72
|
+
propPanel: {
|
73
|
+
schema: {},
|
74
|
+
defaultValue,
|
75
|
+
defaultSchema: {
|
76
|
+
type: 'svg',
|
77
|
+
position: { x: 0, y: 0 },
|
78
|
+
width: 40,
|
79
|
+
height: 40,
|
80
|
+
},
|
81
|
+
},
|
82
|
+
};
|
83
|
+
|
84
|
+
export default svgSchema;
|
85
|
+
|
86
|
+
export const readOnlySvg: Plugin<SVGSchema> = {
|
87
|
+
pdf: svgSchema.pdf,
|
88
|
+
ui: svgSchema.ui,
|
89
|
+
propPanel: {
|
90
|
+
...svgSchema.propPanel,
|
91
|
+
defaultSchema: {
|
92
|
+
...svgSchema.propPanel.defaultSchema,
|
93
|
+
type: 'readOnlySvg',
|
94
|
+
readOnly: true,
|
95
|
+
readOnlyValue: defaultValue,
|
96
|
+
},
|
97
|
+
},
|
98
|
+
};
|
package/src/index.ts
CHANGED
@@ -1,8 +1,25 @@
|
|
1
|
-
import text from './text/index.js';
|
2
|
-
import image from './image
|
1
|
+
import text, { readOnlyText } from './text/index.js';
|
2
|
+
import image, { readOnlyImage } from './graphics/image.js';
|
3
|
+
import svg, { readOnlySvg } from './graphics/svg.js';
|
3
4
|
import barcodes from './barcodes/index.js';
|
4
|
-
import
|
5
|
+
import line from './shapes/line.js';
|
6
|
+
import { rectangle, ellipse } from './shapes/rectAndEllipse.js';
|
7
|
+
import { convertForPdfLayoutProps, rotatePoint } from './utils.js';
|
5
8
|
|
6
9
|
const builtInPlugins = { Text: text };
|
7
10
|
|
8
|
-
export {
|
11
|
+
export {
|
12
|
+
text,
|
13
|
+
readOnlyText,
|
14
|
+
image,
|
15
|
+
readOnlyImage,
|
16
|
+
svg,
|
17
|
+
readOnlySvg,
|
18
|
+
barcodes,
|
19
|
+
line,
|
20
|
+
rectangle,
|
21
|
+
ellipse,
|
22
|
+
builtInPlugins,
|
23
|
+
convertForPdfLayoutProps,
|
24
|
+
rotatePoint,
|
25
|
+
};
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import type { Schema, Plugin, PDFRenderProps, UIRenderProps } from '@pdfme/common';
|
2
|
+
import { rotatePoint, convertForPdfLayoutProps, hex2RgbColor } from '../utils.js';
|
3
|
+
import { HEX_COLOR_PATTERN } from '../constants.js';
|
4
|
+
|
5
|
+
const DEFAULT_LINE_COLOR = '#000000';
|
6
|
+
|
7
|
+
interface LineSchema extends Schema {
|
8
|
+
color: string;
|
9
|
+
}
|
10
|
+
|
11
|
+
const lineSchema: Plugin<LineSchema> = {
|
12
|
+
pdf: (arg: PDFRenderProps<LineSchema>) => {
|
13
|
+
const { page, schema } = arg;
|
14
|
+
const pageHeight = page.getHeight();
|
15
|
+
const {
|
16
|
+
width,
|
17
|
+
height,
|
18
|
+
rotate,
|
19
|
+
position: { x, y },
|
20
|
+
opacity,
|
21
|
+
} = convertForPdfLayoutProps({ schema, pageHeight, applyRotateTranslate: false });
|
22
|
+
const pivot = { x: x + width / 2, y: y + height / 2 };
|
23
|
+
page.drawLine({
|
24
|
+
start: rotatePoint({ x, y: y + height / 2 }, pivot, rotate.angle),
|
25
|
+
end: rotatePoint({ x: x + width, y: y + height / 2 }, pivot, rotate.angle),
|
26
|
+
thickness: height,
|
27
|
+
color: hex2RgbColor(schema.color ?? DEFAULT_LINE_COLOR),
|
28
|
+
opacity: opacity,
|
29
|
+
});
|
30
|
+
},
|
31
|
+
ui: (arg: UIRenderProps<LineSchema>) => {
|
32
|
+
const { schema, rootElement } = arg;
|
33
|
+
const div = document.createElement('div');
|
34
|
+
div.style.backgroundColor = schema.color ?? DEFAULT_LINE_COLOR;
|
35
|
+
div.style.width = '100%';
|
36
|
+
div.style.height = '100%';
|
37
|
+
rootElement.appendChild(div);
|
38
|
+
},
|
39
|
+
propPanel: {
|
40
|
+
schema: ({ i18n }) => ({
|
41
|
+
color: {
|
42
|
+
title: i18n('schemas.color'),
|
43
|
+
type: 'string',
|
44
|
+
widget: 'color',
|
45
|
+
required: true,
|
46
|
+
rules: [
|
47
|
+
{
|
48
|
+
pattern: HEX_COLOR_PATTERN,
|
49
|
+
message: i18n('hexColorPrompt'),
|
50
|
+
},
|
51
|
+
],
|
52
|
+
},
|
53
|
+
}),
|
54
|
+
defaultValue: '',
|
55
|
+
defaultSchema: {
|
56
|
+
type: 'line',
|
57
|
+
position: { x: 0, y: 0 },
|
58
|
+
width: 50,
|
59
|
+
height: 1,
|
60
|
+
rotate: 0,
|
61
|
+
opacity: 1,
|
62
|
+
readOnly: true,
|
63
|
+
color: DEFAULT_LINE_COLOR,
|
64
|
+
},
|
65
|
+
},
|
66
|
+
};
|
67
|
+
export default lineSchema;
|
@@ -0,0 +1,110 @@
|
|
1
|
+
import { Plugin, Schema, mm2pt } from '@pdfme/common';
|
2
|
+
import { HEX_COLOR_PATTERN } from '../constants.js';
|
3
|
+
import { hex2RgbColor, convertForPdfLayoutProps } from '../utils.js';
|
4
|
+
|
5
|
+
interface Shape extends Schema {
|
6
|
+
type: 'ellipse' | 'rectangle';
|
7
|
+
borderWidth: number;
|
8
|
+
borderColor: string;
|
9
|
+
color: string;
|
10
|
+
}
|
11
|
+
|
12
|
+
const shape: Plugin<Shape> = {
|
13
|
+
ui: (arg) => {
|
14
|
+
const { schema, rootElement } = arg;
|
15
|
+
const div = document.createElement('div');
|
16
|
+
div.style.width = '100%';
|
17
|
+
div.style.height = '100%';
|
18
|
+
div.style.boxSizing = 'border-box';
|
19
|
+
if (schema.type === 'ellipse') {
|
20
|
+
div.style.borderRadius = '50%';
|
21
|
+
}
|
22
|
+
div.style.borderWidth = `${schema.borderWidth ?? 0}mm`;
|
23
|
+
div.style.borderStyle = schema.borderWidth && schema.borderColor ? 'solid' : 'none';
|
24
|
+
div.style.borderColor = schema.borderColor ?? 'transparent';
|
25
|
+
div.style.backgroundColor = schema.color ?? 'transparent';
|
26
|
+
|
27
|
+
rootElement.appendChild(div);
|
28
|
+
},
|
29
|
+
pdf: (arg) => {
|
30
|
+
const { schema, page } = arg;
|
31
|
+
const pageHeight = page.getHeight();
|
32
|
+
const cArg = { schema, pageHeight };
|
33
|
+
const { position, width, height, rotate, opacity } = convertForPdfLayoutProps(cArg);
|
34
|
+
const {
|
35
|
+
position: { x: x4Ellipse, y: y4Ellipse },
|
36
|
+
} = convertForPdfLayoutProps({ ...cArg, applyRotateTranslate: false });
|
37
|
+
const borderWidth = schema.borderWidth ? mm2pt(schema.borderWidth) : 0;
|
38
|
+
|
39
|
+
const drawOptions = {
|
40
|
+
rotate,
|
41
|
+
borderWidth,
|
42
|
+
borderColor: hex2RgbColor(schema.borderColor),
|
43
|
+
color: hex2RgbColor(schema.color),
|
44
|
+
opacity,
|
45
|
+
borderOpacity: opacity,
|
46
|
+
};
|
47
|
+
if (schema.type === 'ellipse') {
|
48
|
+
page.drawEllipse({
|
49
|
+
x: x4Ellipse + width / 2,
|
50
|
+
y: y4Ellipse + height / 2,
|
51
|
+
xScale: width / 2 - borderWidth / 2,
|
52
|
+
yScale: height / 2 - borderWidth / 2,
|
53
|
+
...drawOptions,
|
54
|
+
});
|
55
|
+
} else if (schema.type === 'rectangle') {
|
56
|
+
page.drawRectangle({
|
57
|
+
x: position.x + borderWidth / 2,
|
58
|
+
y: position.y + borderWidth / 2,
|
59
|
+
width: width - borderWidth,
|
60
|
+
height: height - borderWidth,
|
61
|
+
...drawOptions,
|
62
|
+
});
|
63
|
+
}
|
64
|
+
},
|
65
|
+
propPanel: {
|
66
|
+
schema: ({ i18n }) => ({
|
67
|
+
borderWidth: {
|
68
|
+
title: i18n('schemas.borderWidth'),
|
69
|
+
type: 'number',
|
70
|
+
widget: 'inputNumber',
|
71
|
+
min: 0,
|
72
|
+
step: 1,
|
73
|
+
},
|
74
|
+
borderColor: {
|
75
|
+
title: i18n('schemas.borderColor'),
|
76
|
+
type: 'string',
|
77
|
+
widget: 'color',
|
78
|
+
rules: [{ pattern: HEX_COLOR_PATTERN, message: i18n('hexColorPrompt') }],
|
79
|
+
},
|
80
|
+
color: {
|
81
|
+
title: i18n('schemas.color'),
|
82
|
+
type: 'string',
|
83
|
+
widget: 'color',
|
84
|
+
rules: [{ pattern: HEX_COLOR_PATTERN, message: i18n('hexColorPrompt') }],
|
85
|
+
},
|
86
|
+
}),
|
87
|
+
defaultValue: '',
|
88
|
+
defaultSchema: {
|
89
|
+
type: 'rectangle',
|
90
|
+
position: { x: 0, y: 0 },
|
91
|
+
width: 62.5,
|
92
|
+
height: 37.5,
|
93
|
+
rotate: 0,
|
94
|
+
opacity: 1,
|
95
|
+
borderWidth: 5,
|
96
|
+
borderColor: '#000000',
|
97
|
+
color: '#ffffff',
|
98
|
+
readOnly: true,
|
99
|
+
},
|
100
|
+
},
|
101
|
+
};
|
102
|
+
|
103
|
+
const getPropPanelSchema = (type: 'rectangle' | 'ellipse') => ({
|
104
|
+
...shape.propPanel,
|
105
|
+
defaultSchema: { ...shape.propPanel.defaultSchema, type },
|
106
|
+
});
|
107
|
+
|
108
|
+
export const rectangle = { ...shape, propPanel: getPropPanelSchema('rectangle') };
|
109
|
+
|
110
|
+
export const ellipse = { ...shape, propPanel: getPropPanelSchema('ellipse') };
|
package/src/text/helper.ts
CHANGED
package/src/text/index.ts
CHANGED
@@ -4,6 +4,20 @@ import { propPanel } from './propPanel.js';
|
|
4
4
|
import { uiRender } from './uiRender.js';
|
5
5
|
import type { TextSchema } from './types';
|
6
6
|
|
7
|
-
const
|
7
|
+
const textSchema: Plugin<TextSchema> = { pdf: pdfRender, ui: uiRender, propPanel };
|
8
8
|
|
9
|
-
export default
|
9
|
+
export default textSchema;
|
10
|
+
|
11
|
+
export const readOnlyText: Plugin<TextSchema> = {
|
12
|
+
pdf: textSchema.pdf,
|
13
|
+
ui: textSchema.ui,
|
14
|
+
propPanel: {
|
15
|
+
...textSchema.propPanel,
|
16
|
+
defaultSchema: {
|
17
|
+
...textSchema.propPanel.defaultSchema,
|
18
|
+
type: 'readOnlyText',
|
19
|
+
readOnly: true,
|
20
|
+
readOnlyValue: textSchema.propPanel.defaultValue,
|
21
|
+
},
|
22
|
+
},
|
23
|
+
};
|
package/src/text/pdfRender.ts
CHANGED
@@ -1,13 +1,6 @@
|
|
1
|
-
import { PDFFont, PDFDocument
|
2
|
-
import {
|
3
|
-
PDFRenderProps,
|
4
|
-
Font,
|
5
|
-
getDefaultFont,
|
6
|
-
getFallbackFontName,
|
7
|
-
mm2pt,
|
8
|
-
isHexValid,
|
9
|
-
} from '@pdfme/common';
|
1
|
+
import { PDFFont, PDFDocument } from '@pdfme/pdf-lib';
|
10
2
|
import type { TextSchema, FontWidthCalcValues } from './types';
|
3
|
+
import { PDFRenderProps, Font, getDefaultFont, getFallbackFontName, mm2pt } from '@pdfme/common';
|
11
4
|
import {
|
12
5
|
VERTICAL_ALIGN_TOP,
|
13
6
|
VERTICAL_ALIGN_MIDDLE,
|
@@ -27,37 +20,7 @@ import {
|
|
27
20
|
getSplittedLines,
|
28
21
|
widthOfTextAtSize,
|
29
22
|
} from './helper.js';
|
30
|
-
import { convertForPdfLayoutProps, rotatePoint } from '../
|
31
|
-
|
32
|
-
const hex2rgb = (hex: string) => {
|
33
|
-
if (hex.slice(0, 1) === '#') hex = hex.slice(1);
|
34
|
-
if (hex.length === 3)
|
35
|
-
hex =
|
36
|
-
hex.slice(0, 1) +
|
37
|
-
hex.slice(0, 1) +
|
38
|
-
hex.slice(1, 2) +
|
39
|
-
hex.slice(1, 2) +
|
40
|
-
hex.slice(2, 3) +
|
41
|
-
hex.slice(2, 3);
|
42
|
-
|
43
|
-
return [hex.slice(0, 2), hex.slice(2, 4), hex.slice(4, 6)].map((str) => parseInt(str, 16));
|
44
|
-
};
|
45
|
-
|
46
|
-
const hex2RgbColor = (hexString: string | undefined) => {
|
47
|
-
if (hexString) {
|
48
|
-
const isValid = isHexValid(hexString);
|
49
|
-
|
50
|
-
if (!isValid) {
|
51
|
-
throw new Error(`Invalid hex color value ${hexString}`);
|
52
|
-
}
|
53
|
-
|
54
|
-
const [r, g, b] = hex2rgb(hexString);
|
55
|
-
|
56
|
-
return rgb(r / 255, g / 255, b / 255);
|
57
|
-
}
|
58
|
-
|
59
|
-
return undefined;
|
60
|
-
};
|
23
|
+
import { convertForPdfLayoutProps, rotatePoint, hex2RgbColor } from '../utils.js';
|
61
24
|
|
62
25
|
const embedAndGetFontObj = async (arg: {
|
63
26
|
pdfDoc: PDFDocument;
|
@@ -118,6 +81,7 @@ const getFontProp = async ({
|
|
118
81
|
|
119
82
|
export const pdfRender = async (arg: PDFRenderProps<TextSchema>) => {
|
120
83
|
const { value, pdfDoc, pdfLib, page, options, schema, _cache } = arg;
|
84
|
+
if (!value) return;
|
121
85
|
|
122
86
|
const { font = getDefaultFont() } = options;
|
123
87
|
|
@@ -132,7 +96,7 @@ export const pdfRender = async (arg: PDFRenderProps<TextSchema>) => {
|
|
132
96
|
const fontName = (
|
133
97
|
schema.fontName ? schema.fontName : getFallbackFontName(font)
|
134
98
|
) as keyof typeof pdfFontObj;
|
135
|
-
const pdfFontValue = pdfFontObj[fontName];
|
99
|
+
const pdfFontValue = pdfFontObj && pdfFontObj[fontName];
|
136
100
|
|
137
101
|
const pageHeight = page.getHeight();
|
138
102
|
const {
|
@@ -162,7 +126,7 @@ export const pdfRender = async (arg: PDFRenderProps<TextSchema>) => {
|
|
162
126
|
};
|
163
127
|
|
164
128
|
let lines: string[] = [];
|
165
|
-
value.split(/\r
|
129
|
+
value.split(/\r\n|\r|\n/g).forEach((line: string) => {
|
166
130
|
lines = lines.concat(getSplittedLines(line, fontWidthCalcValues));
|
167
131
|
});
|
168
132
|
|
package/src/text/propPanel.ts
CHANGED
@@ -153,7 +153,7 @@ export const propPanel: PropPanel<TextSchema> = {
|
|
153
153
|
rules: [
|
154
154
|
{
|
155
155
|
pattern: HEX_COLOR_PATTERN,
|
156
|
-
message: '
|
156
|
+
message: i18n('hexColorPrompt'),
|
157
157
|
},
|
158
158
|
],
|
159
159
|
},
|
@@ -164,7 +164,7 @@ export const propPanel: PropPanel<TextSchema> = {
|
|
164
164
|
rules: [
|
165
165
|
{
|
166
166
|
pattern: HEX_COLOR_PATTERN,
|
167
|
-
message: '
|
167
|
+
message: i18n('hexColorPrompt'),
|
168
168
|
},
|
169
169
|
],
|
170
170
|
},
|