@pdfme/schemas
Version:
TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!
95 lines (87 loc) • 3.21 kB
text/typescript
import type * as CSS from 'csstype';
import { UIRenderProps } from '@pdfme/common';
import type { BarcodeSchema } from './types.js';
import { validateBarcodeInput, createBarCode } from './helper.js';
import { addAlphaToHex, isEditable, createErrorElm } from '../utils.js';
const fullSize = { width: '100%', height: '100%' };
const blobToDataURL = (blob: Blob): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result as string);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
const createBarcodeImage = async (schema: BarcodeSchema, value: string) => {
const imageBuf = await createBarCode({
...schema,
input: value,
});
const barcodeData = new Blob([new Uint8Array(imageBuf)], { type: 'image/png' });
const barcodeDataURL = await blobToDataURL(barcodeData);
return barcodeDataURL;
};
const createBarcodeImageElm = async (schema: BarcodeSchema, value: string) => {
const barcodeDataURL = await createBarcodeImage(schema, value);
const img = document.createElement('img');
img.src = barcodeDataURL;
const imgStyle: CSS.Properties = { ...fullSize, borderRadius: 0 };
Object.assign(img.style, imgStyle);
return img;
};
export const uiRender = async (arg: UIRenderProps<BarcodeSchema>) => {
const { value, rootElement, mode, onChange, stopEditing, tabIndex, placeholder, schema, theme } =
arg;
const container = document.createElement('div');
const containerStyle: CSS.Properties = {
...fullSize,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontFamily: "'Open Sans', sans-serif",
};
Object.assign(container.style, containerStyle);
rootElement.appendChild(container);
const editable = isEditable(mode, schema);
if (editable) {
const input = document.createElement('input');
const inputStyle: CSS.Properties = {
width: '100%',
position: 'absolute',
textAlign: 'center',
fontSize: '12pt',
fontWeight: 'bold',
color: theme.colorWhite,
backgroundColor: editable || value ? addAlphaToHex('#000000', 80) : 'none',
border: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
overflow: 'auto',
};
Object.assign(input.style, inputStyle);
input.value = value;
input.placeholder = placeholder || '';
input.tabIndex = tabIndex || 0;
input.addEventListener('change', (e: Event) => {
if (onChange) onChange({ key: 'content', value: (e.target as HTMLInputElement).value });
});
input.addEventListener('blur', () => {
if (stopEditing) stopEditing();
});
container.appendChild(input);
input.setSelectionRange(value.length, value.length);
if (mode === 'designer') {
input.focus();
}
}
if (!value) return;
try {
if (!validateBarcodeInput(schema.type, value))
throw new Error('[@pdfme/schemas/barcodes] Invalid barcode input');
const imgElm = await createBarcodeImageElm(schema, value);
container.appendChild(imgElm);
} catch (err) {
console.error(`[@pdfme/ui] ${String(err)}`);
container.appendChild(createErrorElm());
}
};