@pdfme/schemas 2.2.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 +31 -0
- package/dist/cjs/__tests__/barcode.test.js +341 -0
- package/dist/cjs/__tests__/barcode.test.js.map +1 -0
- package/dist/cjs/__tests__/text.test.js +318 -0
- package/dist/cjs/__tests__/text.test.js.map +1 -0
- package/dist/cjs/src/barcodes/constants.js +19 -0
- package/dist/cjs/src/barcodes/constants.js.map +1 -0
- package/dist/cjs/src/barcodes/helper.js +147 -0
- package/dist/cjs/src/barcodes/helper.js.map +1 -0
- package/dist/cjs/src/barcodes/index.js +11 -0
- package/dist/cjs/src/barcodes/index.js.map +1 -0
- package/dist/cjs/src/barcodes/pdfRender.js +37 -0
- package/dist/cjs/src/barcodes/pdfRender.js.map +1 -0
- package/dist/cjs/src/barcodes/propPanel.js +69 -0
- package/dist/cjs/src/barcodes/propPanel.js.map +1 -0
- package/dist/cjs/src/barcodes/types.js +3 -0
- package/dist/cjs/src/barcodes/types.js.map +1 -0
- package/dist/cjs/src/barcodes/uiRender.js +92 -0
- package/dist/cjs/src/barcodes/uiRender.js.map +1 -0
- package/dist/cjs/src/image/constants.js +3 -0
- package/dist/cjs/src/image/constants.js.map +1 -0
- package/dist/cjs/src/image/helper.js +3 -0
- package/dist/cjs/src/image/helper.js.map +1 -0
- package/dist/cjs/src/image/index.js +8 -0
- package/dist/cjs/src/image/index.js.map +1 -0
- package/dist/cjs/src/image/pdfRender.js +34 -0
- package/dist/cjs/src/image/pdfRender.js.map +1 -0
- package/dist/cjs/src/image/propPanel.js +9 -0
- package/dist/cjs/src/image/propPanel.js.map +1 -0
- package/dist/cjs/src/image/types.js +3 -0
- package/dist/cjs/src/image/types.js.map +1 -0
- package/dist/cjs/src/image/uiRender.js +108 -0
- package/dist/cjs/src/image/uiRender.js.map +1 -0
- package/dist/cjs/src/index.js +13 -0
- package/dist/cjs/src/index.js.map +1 -0
- package/dist/cjs/src/renderUtils.js +65 -0
- package/dist/cjs/src/renderUtils.js.map +1 -0
- package/dist/cjs/src/text/constants.js +22 -0
- package/dist/cjs/src/text/constants.js.map +1 -0
- package/dist/cjs/src/text/helper.js +270 -0
- package/dist/cjs/src/text/helper.js.map +1 -0
- package/dist/cjs/src/text/index.js +8 -0
- package/dist/cjs/src/text/index.js.map +1 -0
- package/dist/cjs/src/text/pdfRender.js +111 -0
- package/dist/cjs/src/text/pdfRender.js.map +1 -0
- package/dist/cjs/src/text/propPanel.js +122 -0
- package/dist/cjs/src/text/propPanel.js.map +1 -0
- package/dist/cjs/src/text/types.js +3 -0
- package/dist/cjs/src/text/types.js.map +1 -0
- package/dist/cjs/src/text/uiRender.js +118 -0
- package/dist/cjs/src/text/uiRender.js.map +1 -0
- package/dist/esm/__tests__/barcode.test.js +336 -0
- package/dist/esm/__tests__/barcode.test.js.map +1 -0
- package/dist/esm/__tests__/text.test.js +293 -0
- package/dist/esm/__tests__/text.test.js.map +1 -0
- package/dist/esm/src/barcodes/constants.js +16 -0
- package/dist/esm/src/barcodes/constants.js.map +1 -0
- package/dist/esm/src/barcodes/helper.js +137 -0
- package/dist/esm/src/barcodes/helper.js.map +1 -0
- package/dist/esm/src/barcodes/index.js +9 -0
- package/dist/esm/src/barcodes/index.js.map +1 -0
- package/dist/esm/src/barcodes/pdfRender.js +33 -0
- package/dist/esm/src/barcodes/pdfRender.js.map +1 -0
- package/dist/esm/src/barcodes/propPanel.js +65 -0
- package/dist/esm/src/barcodes/propPanel.js.map +1 -0
- package/dist/esm/src/barcodes/types.js +2 -0
- package/dist/esm/src/barcodes/types.js.map +1 -0
- package/dist/esm/src/barcodes/uiRender.js +88 -0
- package/dist/esm/src/barcodes/uiRender.js.map +1 -0
- package/dist/esm/src/image/constants.js +2 -0
- package/dist/esm/src/image/constants.js.map +1 -0
- package/dist/esm/src/image/helper.js +2 -0
- package/dist/esm/src/image/helper.js.map +1 -0
- package/dist/esm/src/image/index.js +6 -0
- package/dist/esm/src/image/index.js.map +1 -0
- package/dist/esm/src/image/pdfRender.js +30 -0
- package/dist/esm/src/image/pdfRender.js.map +1 -0
- package/dist/esm/src/image/propPanel.js +6 -0
- package/dist/esm/src/image/propPanel.js.map +1 -0
- package/dist/esm/src/image/types.js +2 -0
- package/dist/esm/src/image/types.js.map +1 -0
- package/dist/esm/src/image/uiRender.js +104 -0
- package/dist/esm/src/image/uiRender.js.map +1 -0
- package/dist/esm/src/index.js +7 -0
- package/dist/esm/src/index.js.map +1 -0
- package/dist/esm/src/renderUtils.js +56 -0
- package/dist/esm/src/renderUtils.js.map +1 -0
- package/dist/esm/src/text/constants.js +19 -0
- package/dist/esm/src/text/constants.js.map +1 -0
- package/dist/esm/src/text/helper.js +237 -0
- package/dist/esm/src/text/helper.js.map +1 -0
- package/dist/esm/src/text/index.js +6 -0
- package/dist/esm/src/text/index.js.map +1 -0
- package/dist/esm/src/text/pdfRender.js +107 -0
- package/dist/esm/src/text/pdfRender.js.map +1 -0
- package/dist/esm/src/text/propPanel.js +119 -0
- package/dist/esm/src/text/propPanel.js.map +1 -0
- package/dist/esm/src/text/types.js +2 -0
- package/dist/esm/src/text/types.js.map +1 -0
- package/dist/esm/src/text/uiRender.js +114 -0
- package/dist/esm/src/text/uiRender.js.map +1 -0
- package/dist/types/__tests__/barcode.test.d.ts +1 -0
- package/dist/types/__tests__/text.test.d.ts +1 -0
- package/dist/types/src/barcodes/constants.d.ts +3 -0
- package/dist/types/src/barcodes/helper.d.ts +20 -0
- package/dist/types/src/barcodes/index.d.ts +4 -0
- package/dist/types/src/barcodes/pdfRender.d.ts +3 -0
- package/dist/types/src/barcodes/propPanel.d.ts +3 -0
- package/dist/types/src/barcodes/types.d.ts +9 -0
- package/dist/types/src/barcodes/uiRender.d.ts +3 -0
- package/dist/types/src/image/constants.d.ts +1 -0
- package/dist/types/src/image/helper.d.ts +1 -0
- package/dist/types/src/image/index.d.ts +4 -0
- package/dist/types/src/image/pdfRender.d.ts +3 -0
- package/dist/types/src/image/propPanel.d.ts +3 -0
- package/dist/types/src/image/types.d.ts +3 -0
- package/dist/types/src/image/uiRender.d.ts +3 -0
- package/dist/types/src/index.d.ts +3 -0
- package/dist/types/src/renderUtils.d.ts +16 -0
- package/dist/types/src/text/constants.d.ts +19 -0
- package/dist/types/src/text/helper.d.ts +29 -0
- package/dist/types/src/text/index.d.ts +4 -0
- package/dist/types/src/text/pdfRender.d.ts +3 -0
- package/dist/types/src/text/propPanel.d.ts +3 -0
- package/dist/types/src/text/types.d.ts +26 -0
- package/dist/types/src/text/uiRender.d.ts +3 -0
- package/package.json +86 -0
- package/src/barcodes/constants.ts +17 -0
- package/src/barcodes/helper.ts +161 -0
- package/src/barcodes/index.ts +16 -0
- package/src/barcodes/pdfRender.ts +29 -0
- package/src/barcodes/propPanel.ts +133 -0
- package/src/barcodes/types.ts +11 -0
- package/src/barcodes/uiRender.ts +116 -0
- package/src/image/constants.ts +1 -0
- package/src/image/helper.ts +1 -0
- package/src/image/index.ts +8 -0
- package/src/image/pdfRender.ts +24 -0
- package/src/image/propPanel.ts +8 -0
- package/src/image/types.ts +3 -0
- package/src/image/uiRender.ts +118 -0
- package/src/index.ts +7 -0
- package/src/renderUtils.ts +74 -0
- package/src/text/constants.ts +22 -0
- package/src/text/helper.ts +317 -0
- package/src/text/index.ts +9 -0
- package/src/text/pdfRender.ts +155 -0
- package/src/text/propPanel.ts +148 -0
- package/src/text/types.ts +29 -0
- package/src/text/uiRender.ts +153 -0
- package/tsconfig.cjs.json +10 -0
- package/tsconfig.esm.json +10 -0
- package/tsconfig.json +6 -0
package/package.json
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
{
|
2
|
+
"name": "@pdfme/schemas",
|
3
|
+
"version": "2.2.1",
|
4
|
+
"sideEffects": false,
|
5
|
+
"author": "hand-dot",
|
6
|
+
"license": "MIT",
|
7
|
+
"keywords": [
|
8
|
+
"pdf",
|
9
|
+
"pdf-generation",
|
10
|
+
"pdf-designer",
|
11
|
+
"pdf-viewer",
|
12
|
+
"typescript",
|
13
|
+
"react"
|
14
|
+
],
|
15
|
+
"description": "TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!",
|
16
|
+
"homepage": "https://pdfme.com",
|
17
|
+
"repository": {
|
18
|
+
"type": "git",
|
19
|
+
"url": "git@github.com:pdfme/pdfme.git"
|
20
|
+
},
|
21
|
+
"bugs": {
|
22
|
+
"url": "https://github.com/pdfme/pdfme/issues"
|
23
|
+
},
|
24
|
+
"main": "dist/cjs/src/index.js",
|
25
|
+
"module": "dist/esm/src/index.js",
|
26
|
+
"types": "dist/types/src/index.d.ts",
|
27
|
+
"exports": {
|
28
|
+
".": {
|
29
|
+
"import": "./dist/esm/src/index.js",
|
30
|
+
"require": "./dist/cjs/src/index.js"
|
31
|
+
}
|
32
|
+
},
|
33
|
+
"engines": {
|
34
|
+
"node": ">=16"
|
35
|
+
},
|
36
|
+
"scripts": {
|
37
|
+
"develop": "tsc -p tsconfig.esm.json -w",
|
38
|
+
"build": "npm run build:cjs && npm run build:esm",
|
39
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
40
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
41
|
+
"clean": "rimraf dist",
|
42
|
+
"lint": "tsc --noEmit",
|
43
|
+
"test": "jest",
|
44
|
+
"lint:watch": "tsc -w --noEmit",
|
45
|
+
"test:watch": "jest --coverage --watch",
|
46
|
+
"prune": "ts-prune src",
|
47
|
+
"prettier": "prettier --write 'src/**/*.ts'"
|
48
|
+
},
|
49
|
+
"dependencies": {
|
50
|
+
"@pdfme/pdf-lib": "^1.17.3",
|
51
|
+
"bwip-js": "^4.1.1",
|
52
|
+
"fontkit": "^2.0.2"
|
53
|
+
},
|
54
|
+
"devDependencies": {
|
55
|
+
"@pdfme/common": "file:../common",
|
56
|
+
"@types/bwip-js": "^3.2.1",
|
57
|
+
"@types/fontkit": "^2.0.4",
|
58
|
+
"@types/pngjs": "^6.0.2",
|
59
|
+
"jsqr": "^1.4.0",
|
60
|
+
"pngjs": "^7.0.0"
|
61
|
+
},
|
62
|
+
"peerDependencies": {
|
63
|
+
"@pdfme/common": "latest"
|
64
|
+
},
|
65
|
+
"jest": {
|
66
|
+
"resolver": "ts-jest-resolver",
|
67
|
+
"moduleFileExtensions": [
|
68
|
+
"js",
|
69
|
+
"ts"
|
70
|
+
],
|
71
|
+
"transform": {
|
72
|
+
"^.+\\.ts$": "ts-jest"
|
73
|
+
},
|
74
|
+
"globals": {
|
75
|
+
"ts-jest": {
|
76
|
+
"tsconfig": "tsconfig.esm.json"
|
77
|
+
}
|
78
|
+
},
|
79
|
+
"testMatch": [
|
80
|
+
"**/*.test.ts"
|
81
|
+
]
|
82
|
+
},
|
83
|
+
"publishConfig": {
|
84
|
+
"access": "public"
|
85
|
+
}
|
86
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
export const BARCODE_TYPES = [
|
2
|
+
'qrcode',
|
3
|
+
'japanpost',
|
4
|
+
'ean13',
|
5
|
+
'ean8',
|
6
|
+
'code39',
|
7
|
+
'code128',
|
8
|
+
'nw7',
|
9
|
+
'itf14',
|
10
|
+
'upca',
|
11
|
+
'upce',
|
12
|
+
'gs1datamatrix',
|
13
|
+
] as const;
|
14
|
+
|
15
|
+
export const DEFAULT_BARCODE_BG_COLOR = '#ffffff';
|
16
|
+
|
17
|
+
export const DEFAULT_BARCODE_COLOR = '#000000';
|
@@ -0,0 +1,161 @@
|
|
1
|
+
import { b64toUint8Array } from '@pdfme/common';
|
2
|
+
import bwipjs, { RenderOptions } from 'bwip-js';
|
3
|
+
import { Buffer } from 'buffer';
|
4
|
+
import { BARCODE_TYPES } from './constants';
|
5
|
+
import { BarcodeTypes } from './types';
|
6
|
+
|
7
|
+
// GTIN-13, GTIN-8, GTIN-12, GTIN-14
|
8
|
+
const validateCheckDigit = (input: string, checkDigitPos: number) => {
|
9
|
+
let passCheckDigit = true;
|
10
|
+
|
11
|
+
if (input.length === checkDigitPos) {
|
12
|
+
const ds = input.slice(0, -1).replace(/[^0-9]/g, '');
|
13
|
+
let sum = 0;
|
14
|
+
let odd = 1;
|
15
|
+
for (let i = ds.length - 1; i > -1; i -= 1) {
|
16
|
+
sum += Number(ds[i]) * (odd ? 3 : 1);
|
17
|
+
odd ^= 1;
|
18
|
+
if (sum > 0xffffffffffff) {
|
19
|
+
// ~2^48 at max
|
20
|
+
sum %= 10;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
passCheckDigit = String(10 - (sum % 10)).slice(-1) === input.slice(-1);
|
24
|
+
}
|
25
|
+
|
26
|
+
return passCheckDigit;
|
27
|
+
};
|
28
|
+
|
29
|
+
export const validateBarcodeInput = (type: BarcodeTypes, input: string) => {
|
30
|
+
if (!input) return false;
|
31
|
+
|
32
|
+
if (!BARCODE_TYPES.includes(type)) return false;
|
33
|
+
|
34
|
+
if (type === 'qrcode') {
|
35
|
+
// 500文字以下
|
36
|
+
return input.length < 500;
|
37
|
+
}
|
38
|
+
if (type === 'japanpost') {
|
39
|
+
// 郵便番号は数字(0-9)のみ。住所表示番号は英数字(0-9,A-Z)とハイフン(-)が使用可能です。
|
40
|
+
const regexp = /^(\d{7})(\d|[A-Z]|-)+$/;
|
41
|
+
|
42
|
+
return regexp.test(input);
|
43
|
+
}
|
44
|
+
if (type === 'ean13') {
|
45
|
+
// 有効文字は数値(0-9)のみ。チェックデジットを含まない12桁orチェックデジットを含む13桁。
|
46
|
+
const regexp = /^\d{12}$|^\d{13}$/;
|
47
|
+
|
48
|
+
return regexp.test(input) && validateCheckDigit(input, 13);
|
49
|
+
}
|
50
|
+
if (type === 'ean8') {
|
51
|
+
// 有効文字は数値(0-9)のみ。チェックデジットを含まない7桁orチェックデジットを含む8桁。
|
52
|
+
const regexp = /^\d{7}$|^\d{8}$/;
|
53
|
+
|
54
|
+
return regexp.test(input) && validateCheckDigit(input, 8);
|
55
|
+
}
|
56
|
+
if (type === 'code39') {
|
57
|
+
// 有効文字は数字(0-9)。アルファベット大文字(A-Z)、記号(-.$/+%)、半角スペース。
|
58
|
+
const regexp = /^(\d|[A-Z]|\-|\.|\$|\/|\+|\%|\s)+$/;
|
59
|
+
|
60
|
+
return regexp.test(input);
|
61
|
+
}
|
62
|
+
if (type === 'code128') {
|
63
|
+
// 有効文字は漢字、ひらがな、カタカナ以外。
|
64
|
+
// https://qiita.com/graminume/items/2ac8dd9c32277fa9da64
|
65
|
+
return !input.match(
|
66
|
+
/([\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf]|[A-Za-z0-9!"#$%&'()*+,-./:;<=>?@[\]^_`{|}〜 ])+/
|
67
|
+
);
|
68
|
+
}
|
69
|
+
if (type === 'nw7') {
|
70
|
+
// 有効文字はNW-7は数字(0-9)と記号(-.$:/+)。
|
71
|
+
// スタートコード/ストップコードとして、コードの始まりと終わりはアルファベット(A-D)のいずれかを使用してください。
|
72
|
+
const regexp = /^[A-Da-d]([0-9\-\.\$\:\/\+])+[A-Da-d]$/;
|
73
|
+
|
74
|
+
return regexp.test(input);
|
75
|
+
}
|
76
|
+
if (type === 'itf14') {
|
77
|
+
// 有効文字は数値(0-9)のみ。 チェックデジットを含まない13桁orチェックデジットを含む14桁。
|
78
|
+
const regexp = /^\d{13}$|^\d{14}$/;
|
79
|
+
|
80
|
+
return regexp.test(input) && validateCheckDigit(input, 14);
|
81
|
+
}
|
82
|
+
if (type === 'upca') {
|
83
|
+
// 有効文字は数値(0-9)のみ。 チェックデジットを含まない11桁orチェックデジットを含む12桁。
|
84
|
+
const regexp = /^\d{11}$|^\d{12}$/;
|
85
|
+
|
86
|
+
return regexp.test(input) && validateCheckDigit(input, 12);
|
87
|
+
}
|
88
|
+
if (type === 'upce') {
|
89
|
+
// 有効文字は数値(0-9)のみ。 1桁目に指定できる数字(ナンバーシステムキャラクタ)は0のみ。
|
90
|
+
// チェックデジットを含まない7桁orチェックデジットを含む8桁。
|
91
|
+
const regexp = /^0(\d{6}$|\d{7}$)/;
|
92
|
+
|
93
|
+
return regexp.test(input) && validateCheckDigit(input, 8);
|
94
|
+
}
|
95
|
+
if (type === 'gs1datamatrix') {
|
96
|
+
let ret = false;
|
97
|
+
// find the GTIN application identifier, regex for "(01)" and the digits after it until another "("
|
98
|
+
const regexp = /\((01)\)(\d*)(\(|$)/;
|
99
|
+
let res = input.match(regexp);
|
100
|
+
if (
|
101
|
+
res != null &&
|
102
|
+
input.length <= 52 && // 52 is the max length of a GS1 DataMatrix barcode before bwip-js throws an error
|
103
|
+
res[1] === '01' &&
|
104
|
+
(res[2].length === 14 || res[2].length === 8 || res[2].length === 12 || res[2].length === 13)
|
105
|
+
) {
|
106
|
+
let gtin = res[2];
|
107
|
+
ret = validateCheckDigit(gtin, gtin.length);
|
108
|
+
}
|
109
|
+
|
110
|
+
return ret;
|
111
|
+
}
|
112
|
+
|
113
|
+
return false;
|
114
|
+
};
|
115
|
+
|
116
|
+
/**
|
117
|
+
* The bwip.js lib has a different name for nw7 type barcodes
|
118
|
+
*/
|
119
|
+
export const barCodeType2Bcid = (type: BarcodeTypes) =>
|
120
|
+
type === 'nw7' ? 'rationalizedCodabar' : type;
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Strip hash from the beginning of HTML hex color codes for the bwip.js lib
|
124
|
+
*/
|
125
|
+
export const mapHexColorForBwipJsLib = (color: string | undefined, fallback?: string) =>
|
126
|
+
color ? color.replace('#', '') : fallback ? fallback.replace('#', '') : '000000';
|
127
|
+
|
128
|
+
export const createBarCode = async (arg: {
|
129
|
+
type: BarcodeTypes;
|
130
|
+
input: string;
|
131
|
+
width: number;
|
132
|
+
height: number;
|
133
|
+
backgroundColor?: string;
|
134
|
+
barColor?: string;
|
135
|
+
textColor?: string;
|
136
|
+
}): Promise<Buffer> => {
|
137
|
+
const { type, input, width, height, backgroundColor, barColor, textColor } = arg;
|
138
|
+
|
139
|
+
const bcid = barCodeType2Bcid(type);
|
140
|
+
const includetext = true;
|
141
|
+
const scale = 5;
|
142
|
+
const bwipjsArg: RenderOptions = { bcid, text: input, width, height, scale, includetext };
|
143
|
+
|
144
|
+
if (backgroundColor) bwipjsArg.backgroundcolor = mapHexColorForBwipJsLib(backgroundColor);
|
145
|
+
if (barColor) bwipjsArg.barcolor = mapHexColorForBwipJsLib(barColor);
|
146
|
+
if (textColor) bwipjsArg.textcolor = mapHexColorForBwipJsLib(textColor);
|
147
|
+
|
148
|
+
let res: Buffer;
|
149
|
+
|
150
|
+
if (typeof window !== 'undefined') {
|
151
|
+
const canvas = document.createElement('canvas');
|
152
|
+
// @ts-ignore
|
153
|
+
bwipjs.toCanvas(canvas, bwipjsArg);
|
154
|
+
const dataUrl = canvas.toDataURL('image/png');
|
155
|
+
res = b64toUint8Array(dataUrl).buffer as Buffer;
|
156
|
+
} else {
|
157
|
+
res = await bwipjs.toBuffer(bwipjsArg);
|
158
|
+
}
|
159
|
+
|
160
|
+
return res;
|
161
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { pdfRender } from './pdfRender';
|
2
|
+
import { getPropPanelByBarcodeType } from './propPanel';
|
3
|
+
import { uiRender } from './uiRender';
|
4
|
+
import type { BarcodeSchema, BarcodeTypes } from './types';
|
5
|
+
import { BARCODE_TYPES } from './constants';
|
6
|
+
import { Plugin } from '@pdfme/common';
|
7
|
+
|
8
|
+
const schemas = BARCODE_TYPES.reduce(
|
9
|
+
(acc, type) =>
|
10
|
+
Object.assign(acc, {
|
11
|
+
[type]: { pdf: pdfRender, ui: uiRender, propPanel: getPropPanelByBarcodeType(type) },
|
12
|
+
}),
|
13
|
+
{} as Record<BarcodeTypes, Plugin<BarcodeSchema>>
|
14
|
+
);
|
15
|
+
|
16
|
+
export default schemas;
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { PDFRenderProps } from '@pdfme/common';
|
2
|
+
import { calcX, calcY, convertSchemaDimensionsToPt, getCacheKey } from '../renderUtils';
|
3
|
+
import type { BarcodeSchema } from './types';
|
4
|
+
import { createBarCode, validateBarcodeInput } from './helper';
|
5
|
+
|
6
|
+
export const pdfRender = async (arg: PDFRenderProps<BarcodeSchema>) => {
|
7
|
+
const { value, schema, pdfDoc, page, _cache } = arg;
|
8
|
+
if (!validateBarcodeInput(schema.type, value)) return;
|
9
|
+
|
10
|
+
const { width, height, rotate } = convertSchemaDimensionsToPt(schema);
|
11
|
+
const opt = {
|
12
|
+
x: calcX(schema.position.x, 'left', width, width),
|
13
|
+
y: calcY(schema.position.y, page.getHeight(), height),
|
14
|
+
rotate,
|
15
|
+
width,
|
16
|
+
height,
|
17
|
+
};
|
18
|
+
const inputBarcodeCacheKey = getCacheKey(schema, value);
|
19
|
+
let image = _cache.get(inputBarcodeCacheKey);
|
20
|
+
if (!image) {
|
21
|
+
const imageBuf = await createBarCode(
|
22
|
+
Object.assign(schema, { type: schema.type, input: value })
|
23
|
+
);
|
24
|
+
image = await pdfDoc.embedPng(imageBuf);
|
25
|
+
_cache.set(inputBarcodeCacheKey, image);
|
26
|
+
}
|
27
|
+
|
28
|
+
page.drawImage(image, opt);
|
29
|
+
};
|
@@ -0,0 +1,133 @@
|
|
1
|
+
import type { PropPanel } from '@pdfme/common';
|
2
|
+
import type { BarcodeSchema } from './types';
|
3
|
+
import { DEFAULT_BARCODE_COLOR, DEFAULT_BARCODE_BG_COLOR } from './constants';
|
4
|
+
|
5
|
+
const defaultColors = {
|
6
|
+
backgroundColor: DEFAULT_BARCODE_BG_COLOR,
|
7
|
+
barColor: DEFAULT_BARCODE_COLOR,
|
8
|
+
};
|
9
|
+
const defaultTextColors = { textColor: DEFAULT_BARCODE_COLOR };
|
10
|
+
const position = { x: 0, y: 0 };
|
11
|
+
const default40x20 = { width: 40, height: 20 };
|
12
|
+
|
13
|
+
const barcodeDefaults: { defaultValue: string; defaultSchema: BarcodeSchema }[] = [
|
14
|
+
{
|
15
|
+
defaultValue: 'https://pdfme.com/',
|
16
|
+
defaultSchema: { type: 'qrcode', position, ...defaultColors, width: 30, height: 30 },
|
17
|
+
},
|
18
|
+
{
|
19
|
+
defaultValue: '6540123789-A-K-Z',
|
20
|
+
defaultSchema: {
|
21
|
+
type: 'japanpost',
|
22
|
+
position,
|
23
|
+
...defaultColors,
|
24
|
+
...defaultTextColors,
|
25
|
+
width: 80,
|
26
|
+
height: 7.2,
|
27
|
+
},
|
28
|
+
},
|
29
|
+
{
|
30
|
+
defaultValue: '2112345678900',
|
31
|
+
defaultSchema: {
|
32
|
+
type: 'ean13',
|
33
|
+
position,
|
34
|
+
...defaultColors,
|
35
|
+
...defaultTextColors,
|
36
|
+
...default40x20,
|
37
|
+
height: 16,
|
38
|
+
},
|
39
|
+
},
|
40
|
+
{
|
41
|
+
defaultValue: '02345673',
|
42
|
+
defaultSchema: {
|
43
|
+
type: 'ean8',
|
44
|
+
position,
|
45
|
+
...defaultColors,
|
46
|
+
...defaultTextColors,
|
47
|
+
...default40x20,
|
48
|
+
},
|
49
|
+
},
|
50
|
+
{
|
51
|
+
defaultValue: 'THIS IS CODE 39',
|
52
|
+
defaultSchema: {
|
53
|
+
type: 'code39',
|
54
|
+
position,
|
55
|
+
...defaultColors,
|
56
|
+
...defaultTextColors,
|
57
|
+
...default40x20,
|
58
|
+
},
|
59
|
+
},
|
60
|
+
{
|
61
|
+
defaultValue: 'This is Code 128!',
|
62
|
+
defaultSchema: {
|
63
|
+
type: 'code128',
|
64
|
+
position,
|
65
|
+
...defaultColors,
|
66
|
+
...defaultTextColors,
|
67
|
+
...default40x20,
|
68
|
+
},
|
69
|
+
},
|
70
|
+
{
|
71
|
+
defaultValue: 'A0123456789B',
|
72
|
+
defaultSchema: {
|
73
|
+
type: 'nw7',
|
74
|
+
position,
|
75
|
+
...defaultColors,
|
76
|
+
...defaultTextColors,
|
77
|
+
...default40x20,
|
78
|
+
},
|
79
|
+
},
|
80
|
+
{
|
81
|
+
defaultValue: '04601234567893',
|
82
|
+
defaultSchema: {
|
83
|
+
type: 'itf14',
|
84
|
+
position,
|
85
|
+
...defaultColors,
|
86
|
+
...defaultTextColors,
|
87
|
+
...default40x20,
|
88
|
+
height: 12,
|
89
|
+
},
|
90
|
+
},
|
91
|
+
{
|
92
|
+
defaultValue: '416000336108',
|
93
|
+
defaultSchema: {
|
94
|
+
type: 'upca',
|
95
|
+
position,
|
96
|
+
...defaultColors,
|
97
|
+
...defaultTextColors,
|
98
|
+
...default40x20,
|
99
|
+
height: 16,
|
100
|
+
},
|
101
|
+
},
|
102
|
+
{
|
103
|
+
defaultValue: '00123457',
|
104
|
+
defaultSchema: {
|
105
|
+
type: 'upce',
|
106
|
+
position,
|
107
|
+
...defaultColors,
|
108
|
+
...defaultTextColors,
|
109
|
+
...default40x20,
|
110
|
+
},
|
111
|
+
},
|
112
|
+
{
|
113
|
+
defaultValue: '(01)03453120000011(17)191125(10)ABCD1234',
|
114
|
+
defaultSchema: { type: 'gs1datamatrix', position, ...defaultColors, width: 30, height: 30 },
|
115
|
+
},
|
116
|
+
];
|
117
|
+
|
118
|
+
export const getPropPanelByBarcodeType = (barcodeType: string): PropPanel<BarcodeSchema> => {
|
119
|
+
const barcodeHasText = barcodeType !== 'qrcode' && barcodeType !== 'gs1datamatrix';
|
120
|
+
|
121
|
+
const schema = {
|
122
|
+
barColor: { title: 'Bar Color', type: 'string', widget: 'color' },
|
123
|
+
backgroundColor: { title: 'Background', type: 'string', widget: 'color' },
|
124
|
+
...(barcodeHasText
|
125
|
+
? { textColor: { title: 'Text Color', type: 'string', widget: 'color' } }
|
126
|
+
: {}),
|
127
|
+
};
|
128
|
+
const defaults = barcodeDefaults.find(({ defaultSchema }) => defaultSchema.type === barcodeType);
|
129
|
+
|
130
|
+
if (!defaults) throw new Error(`No default for barcode type ${barcodeType}`);
|
131
|
+
|
132
|
+
return { propPanelSchema: schema, ...defaults };
|
133
|
+
};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { Schema } from '@pdfme/common';
|
2
|
+
import { BARCODE_TYPES } from './constants';
|
3
|
+
|
4
|
+
export interface BarcodeSchema extends Schema {
|
5
|
+
type: (typeof BARCODE_TYPES)[number];
|
6
|
+
backgroundColor: string;
|
7
|
+
barColor: string;
|
8
|
+
textColor?: string;
|
9
|
+
}
|
10
|
+
|
11
|
+
export type BarcodeTypes = (typeof BARCODE_TYPES)[number];
|
@@ -0,0 +1,116 @@
|
|
1
|
+
import type * as CSS from 'csstype';
|
2
|
+
import { UIRenderProps } from '@pdfme/common';
|
3
|
+
import type { BarcodeSchema } from './types';
|
4
|
+
import { validateBarcodeInput, createBarCode } from './helper';
|
5
|
+
|
6
|
+
const fullSize = { width: '100%', height: '100%' };
|
7
|
+
|
8
|
+
const createErrorBarcodeElm = () => {
|
9
|
+
const container = document.createElement('div');
|
10
|
+
const containerStyle: CSS.Properties = {
|
11
|
+
display: 'flex',
|
12
|
+
alignItems: 'center',
|
13
|
+
justifyContent: 'center',
|
14
|
+
...fullSize,
|
15
|
+
};
|
16
|
+
Object.assign(container.style, containerStyle);
|
17
|
+
|
18
|
+
const span = document.createElement('span');
|
19
|
+
const spanStyle: CSS.Properties = {
|
20
|
+
color: 'white',
|
21
|
+
background: 'red',
|
22
|
+
padding: '0.25rem',
|
23
|
+
fontSize: '12pt',
|
24
|
+
fontWeight: 'bold',
|
25
|
+
borderRadius: '2px',
|
26
|
+
};
|
27
|
+
Object.assign(span.style, spanStyle);
|
28
|
+
|
29
|
+
span.textContent = 'ERROR';
|
30
|
+
container.appendChild(span);
|
31
|
+
|
32
|
+
return container;
|
33
|
+
};
|
34
|
+
|
35
|
+
const blobToDataURL = (blob: Blob): Promise<string> =>
|
36
|
+
new Promise((resolve, reject) => {
|
37
|
+
const reader = new FileReader();
|
38
|
+
reader.onloadend = () => resolve(reader.result as string);
|
39
|
+
reader.onerror = reject;
|
40
|
+
reader.readAsDataURL(blob);
|
41
|
+
});
|
42
|
+
|
43
|
+
const createBarcodeImage = async (schema: BarcodeSchema, value: string) => {
|
44
|
+
const imageBuf = await createBarCode({
|
45
|
+
...schema,
|
46
|
+
input: value,
|
47
|
+
});
|
48
|
+
const barcodeData = new Blob([new Uint8Array(imageBuf)], { type: 'image/png' });
|
49
|
+
const barcodeDataURL = await blobToDataURL(barcodeData);
|
50
|
+
return barcodeDataURL;
|
51
|
+
};
|
52
|
+
|
53
|
+
const createBarcodeImageElm = async (schema: BarcodeSchema, value: string) => {
|
54
|
+
const barcodeDataURL = await createBarcodeImage(schema, value);
|
55
|
+
const img = document.createElement('img');
|
56
|
+
img.src = barcodeDataURL;
|
57
|
+
const imgStyle: CSS.Properties = { ...fullSize, borderRadius: 0 };
|
58
|
+
Object.assign(img.style, imgStyle);
|
59
|
+
return img;
|
60
|
+
};
|
61
|
+
|
62
|
+
export const uiRender = async (arg: UIRenderProps<BarcodeSchema>) => {
|
63
|
+
const { value, rootElement, mode, onChange, stopEditing, tabIndex, placeholder, schema } = arg;
|
64
|
+
|
65
|
+
const container = document.createElement('div');
|
66
|
+
const containerStyle: CSS.Properties = {
|
67
|
+
...fullSize,
|
68
|
+
display: 'flex',
|
69
|
+
alignItems: 'center',
|
70
|
+
justifyContent: 'center',
|
71
|
+
fontFamily: "'Open Sans', sans-serif",
|
72
|
+
};
|
73
|
+
Object.assign(container.style, containerStyle);
|
74
|
+
rootElement.appendChild(container);
|
75
|
+
const isForm = mode === 'form';
|
76
|
+
if (isForm) {
|
77
|
+
const input = document.createElement('input');
|
78
|
+
const inputStyle: CSS.Properties = {
|
79
|
+
...fullSize,
|
80
|
+
position: 'absolute',
|
81
|
+
textAlign: 'center',
|
82
|
+
fontSize: '1rem',
|
83
|
+
color: '#000',
|
84
|
+
backgroundColor: isForm || value ? 'rgb(242 244 255 / 75%)' : 'none',
|
85
|
+
border: 'none',
|
86
|
+
display: 'flex',
|
87
|
+
alignItems: 'center',
|
88
|
+
justifyContent: 'center',
|
89
|
+
overflow: 'auto',
|
90
|
+
};
|
91
|
+
Object.assign(input.style, inputStyle);
|
92
|
+
input.value = value;
|
93
|
+
input.placeholder = placeholder || '';
|
94
|
+
input.tabIndex = tabIndex || 0;
|
95
|
+
input.addEventListener('change', (e: Event) => {
|
96
|
+
onChange && onChange((e.target as HTMLInputElement).value);
|
97
|
+
});
|
98
|
+
input.addEventListener('blur', () => {
|
99
|
+
stopEditing && stopEditing();
|
100
|
+
});
|
101
|
+
container.appendChild(input);
|
102
|
+
input.setSelectionRange(value.length, value.length);
|
103
|
+
input.focus();
|
104
|
+
}
|
105
|
+
|
106
|
+
if (!value) return;
|
107
|
+
try {
|
108
|
+
if (!validateBarcodeInput(schema.type, value)) throw new Error('Invalid barcode input');
|
109
|
+
const imgElm = await createBarcodeImageElm(schema, value);
|
110
|
+
container.appendChild(imgElm);
|
111
|
+
} catch (err) {
|
112
|
+
console.error(err);
|
113
|
+
const errorBarcodeElm = createErrorBarcodeElm();
|
114
|
+
container.appendChild(errorBarcodeElm);
|
115
|
+
}
|
116
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { Plugin } from '@pdfme/common';
|
2
|
+
import { pdfRender } from './pdfRender';
|
3
|
+
import { propPanel } from './propPanel';
|
4
|
+
import { uiRender } from './uiRender';
|
5
|
+
import type { ImageSchema } from './types';
|
6
|
+
|
7
|
+
const schema: Plugin<ImageSchema> = { pdf: pdfRender, ui: uiRender, propPanel };
|
8
|
+
export default schema;
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import type { PDFRenderProps } from '@pdfme/common';
|
2
|
+
import type { ImageSchema } from './types';
|
3
|
+
import { calcX, calcY, convertSchemaDimensionsToPt, getCacheKey } from '../renderUtils';
|
4
|
+
|
5
|
+
export const pdfRender = async (arg: PDFRenderProps<ImageSchema>) => {
|
6
|
+
const { value, schema, pdfDoc, page, _cache } = arg;
|
7
|
+
|
8
|
+
const { width, height, rotate } = convertSchemaDimensionsToPt(schema);
|
9
|
+
const opt = {
|
10
|
+
x: calcX(schema.position.x, 'left', width, width),
|
11
|
+
y: calcY(schema.position.y, page.getHeight(), height),
|
12
|
+
rotate,
|
13
|
+
width,
|
14
|
+
height,
|
15
|
+
};
|
16
|
+
const inputImageCacheKey = getCacheKey(schema, value);
|
17
|
+
let image = _cache.get(inputImageCacheKey);
|
18
|
+
if (!image) {
|
19
|
+
const isPng = value.startsWith('data:image/png;');
|
20
|
+
image = await (isPng ? pdfDoc.embedPng(value) : pdfDoc.embedJpg(value));
|
21
|
+
_cache.set(inputImageCacheKey, image);
|
22
|
+
}
|
23
|
+
page.drawImage(image, opt);
|
24
|
+
};
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { PropPanel } from '@pdfme/common';
|
2
|
+
import type { ImageSchema } from './types';
|
3
|
+
export const propPanel: PropPanel<ImageSchema> = {
|
4
|
+
propPanelSchema: {},
|
5
|
+
defaultValue:
|
6
|
+
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAu4AAALuAQMAAADL0wGJAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAGUExURbzAw+rv8fKruy0AAAPoSURBVHja7dwxbtwwEEBRCkKwRQodYftcYk+ROkcJz5NTsEuZK/AIKlIQAUEnke0VqQ0pA5zxWvFnZcD2s0CNuENxPOZBc0QDDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD/+P8bkxvnTzzjTG0M2b5rh08rHNT518aPOnTt63+aGTd23edPJ2h//ax+/oO6Gzx6c78+cuPu7x01vmwx5/6uLnO/PjO+b/rGifvtWH3VnT9vmh/e3eqx/bc9d79af2YwEPDw8P/6r8r1GVt5VcUoZPtXxGhp9rGYEM72vbEBne1hJ5Gb6ayIvwqZppi/CxmgqL8KGaTIrwc3WDfATeV/ffIryr7r+PwNvq/vsIfH17D5/qbw/gb/mLKp/OqnycFPj14yqcJPm4vfp5VJ0cP6jyzqjy9rr2q/Dr4qzBp3V5E1wxp/V3rl8LXn32qF6fAY31Psv2NXi/5lQaH+Vuzak0eLsmPRppVPa3FPiU3QiFFDZmD4FCAh6yxV+Bn7O9isLmx2d/TGHr5rI7obDxtFkcKWyb89M2+U1/sX7Kv7Io8gaxFy5l2D/faRk++3x6PgsalV52+fwUW4j/+eGhDPuneyH/otHmp9jyfHHMLM6n4phZnI/FObA4H4qDWnF+Lo46xXlflG+I864o3xDnbVG+Ic6X9RXSfCrrK6T5WBZASPOhrFCQ5ufyjF+a92XdkjTvyrolad6WdUvS/KawSI7/sQn7JfDl+O+bsF8CX44fN2FvHnNnIT4Nm7BfAl+ON5uwXwJfjA/LCuk2BXvCvN0U7InxflmAtxV1gvx0U2N3luPtdZOlwj/FoR5vbuq85Pi48F6LD0scOk3+sq1cleP9ohlNfkpq/N9pGaMuH7T4ZVqGWYt/nBavyxstftblfaVIWJU/y72yODCfzJH5oMvPh+adLm+PzCdzZD5U/61ClT9Lnvyo8e7QvFHlE3ydj0zOu5ucickhcpgcJofJedUVk8j5b/nGgIeHh4d/I3x/RwLlhgfNH3DavSwGXf7YjT76uqCEQ/P37p9z7uKVmwspd17S7hul3PXK6fbsmnvWhO6GZlMnn3ri8gXN5GzHnX0B35ydj91814CHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHl+d/A9cKjmiL040TAAAAAElFTkSuQmCC',
|
7
|
+
defaultSchema: { type: 'image', position: { x: 0, y: 0 }, width: 40, height: 40 },
|
8
|
+
};
|