react-id-card-generator 1.0.20 → 1.0.21
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/dist/cjs/core/qrUtils.js
CHANGED
|
@@ -59,18 +59,19 @@ function getQrCodeSize(width, height = width, scale = 1) {
|
|
|
59
59
|
*/
|
|
60
60
|
function generateQrCodeDataURL(data, size = DEFAULT_QR_SIZE, options) {
|
|
61
61
|
const background = options?.background ?? 'transparent';
|
|
62
|
-
const
|
|
62
|
+
const normalizedSize = Math.max(MIN_QR_SIZE, Math.round(size));
|
|
63
|
+
const padding = Math.max(0, Math.round(options?.padding ?? 0));
|
|
63
64
|
const qr = new qrious({
|
|
64
65
|
value: JSON.stringify(data),
|
|
65
|
-
size,
|
|
66
|
+
size: normalizedSize,
|
|
66
67
|
level: options?.level || 'H', // High error correction by default
|
|
67
|
-
padding
|
|
68
|
-
background,
|
|
69
|
-
backgroundAlpha:
|
|
68
|
+
padding,
|
|
69
|
+
background: 'transparent',
|
|
70
|
+
backgroundAlpha: 0,
|
|
70
71
|
foreground: options?.foreground || 'black',
|
|
71
72
|
foregroundAlpha: 1,
|
|
72
73
|
});
|
|
73
|
-
return qr.
|
|
74
|
+
return renderQrToTargetSize(qr.canvas, normalizedSize, background, padding);
|
|
74
75
|
}
|
|
75
76
|
/**
|
|
76
77
|
* Generate QR code from specific fields in the card data
|
|
@@ -119,6 +120,74 @@ function setQrCodeOnElement(elementId, data, size = DEFAULT_QR_SIZE, container =
|
|
|
119
120
|
}
|
|
120
121
|
return false;
|
|
121
122
|
}
|
|
123
|
+
function renderQrToTargetSize(sourceCanvas, targetSize, background, padding) {
|
|
124
|
+
if (!sourceCanvas) {
|
|
125
|
+
return '';
|
|
126
|
+
}
|
|
127
|
+
const bounds = getOpaqueBounds(sourceCanvas);
|
|
128
|
+
const outputCanvas = document.createElement('canvas');
|
|
129
|
+
outputCanvas.width = targetSize;
|
|
130
|
+
outputCanvas.height = targetSize;
|
|
131
|
+
const context = outputCanvas.getContext('2d');
|
|
132
|
+
if (!context) {
|
|
133
|
+
return sourceCanvas.toDataURL('image/png');
|
|
134
|
+
}
|
|
135
|
+
if (background !== 'transparent') {
|
|
136
|
+
context.fillStyle = background;
|
|
137
|
+
context.fillRect(0, 0, targetSize, targetSize);
|
|
138
|
+
}
|
|
139
|
+
context.imageSmoothingEnabled = false;
|
|
140
|
+
const destinationPadding = Math.min(Math.max(0, padding), Math.floor((targetSize - 1) / 2));
|
|
141
|
+
const destinationSize = Math.max(1, targetSize - (destinationPadding * 2));
|
|
142
|
+
if (bounds) {
|
|
143
|
+
context.drawImage(sourceCanvas, bounds.x, bounds.y, bounds.width, bounds.height, destinationPadding, destinationPadding, destinationSize, destinationSize);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
context.drawImage(sourceCanvas, destinationPadding, destinationPadding, destinationSize, destinationSize);
|
|
147
|
+
}
|
|
148
|
+
return outputCanvas.toDataURL('image/png');
|
|
149
|
+
}
|
|
150
|
+
function getOpaqueBounds(canvas) {
|
|
151
|
+
const context = canvas.getContext('2d', { willReadFrequently: true });
|
|
152
|
+
if (!context) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
const { width, height } = canvas;
|
|
156
|
+
const { data } = context.getImageData(0, 0, width, height);
|
|
157
|
+
let minX = width;
|
|
158
|
+
let minY = height;
|
|
159
|
+
let maxX = -1;
|
|
160
|
+
let maxY = -1;
|
|
161
|
+
for (let y = 0; y < height; y += 1) {
|
|
162
|
+
for (let x = 0; x < width; x += 1) {
|
|
163
|
+
const alpha = data[((y * width) + x) * 4 + 3];
|
|
164
|
+
if (alpha === 0) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (x < minX) {
|
|
168
|
+
minX = x;
|
|
169
|
+
}
|
|
170
|
+
if (y < minY) {
|
|
171
|
+
minY = y;
|
|
172
|
+
}
|
|
173
|
+
if (x > maxX) {
|
|
174
|
+
maxX = x;
|
|
175
|
+
}
|
|
176
|
+
if (y > maxY) {
|
|
177
|
+
maxY = y;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (maxX < minX || maxY < minY) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
x: minX,
|
|
186
|
+
y: minY,
|
|
187
|
+
width: (maxX - minX) + 1,
|
|
188
|
+
height: (maxY - minY) + 1,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
122
191
|
|
|
123
192
|
exports.generateQrCodeDataURL = generateQrCodeDataURL;
|
|
124
193
|
exports.generateQrCodeFromFields = generateQrCodeFromFields;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qrUtils.js","sources":["../../../src/core/qrUtils.ts"],"sourcesContent":["import QRious from 'qrious';\nimport type { IDCardData } from '../types';\n\nconst DEFAULT_QR_SIZE = 200;\nconst MIN_QR_SIZE = 32;\n\nfunction normalizeQrScale(scale = 1): number {\n return Number.isFinite(scale) && scale > 0 ? scale : 1;\n}\n\nfunction resolveQrTargetElement(\n elementId: string,\n container: Document | HTMLElement\n): HTMLElement | null {\n if (container instanceof HTMLElement) {\n if (container.id === elementId) {\n return container;\n }\n\n return container.querySelector<HTMLElement>(`#${elementId}`);\n }\n\n return container.getElementById(elementId);\n}\n\nfunction resolveQrImageElement(targetElement: HTMLElement | null): HTMLImageElement | null {\n if (!targetElement) {\n return null;\n }\n\n if (targetElement instanceof HTMLImageElement) {\n return targetElement;\n }\n\n return targetElement.querySelector<HTMLImageElement>('img[data-qr-code-image=\"true\"], img');\n}\n\nfunction hasQrFieldValue(value: IDCardData[string]): boolean {\n if (value === undefined) {\n return false;\n }\n\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n\n if (Array.isArray(value)) {\n return value.some((item) => String(item).trim().length > 0);\n }\n\n return true;\n}\n\nexport function getQrCodeSize(\n width: number,\n height = width,\n scale = 1\n): number {\n const normalizedWidth = Number.isFinite(width) ? width : 0;\n const normalizedHeight = Number.isFinite(height) ? height : 0;\n const hasWidth = normalizedWidth > 0;\n const hasHeight = normalizedHeight > 0;\n const baseSize = hasWidth && hasHeight\n ? Math.min(normalizedWidth, normalizedHeight)\n : Math.max(normalizedWidth, normalizedHeight);\n\n if (baseSize <= 0) {\n return Math.max(MIN_QR_SIZE, Math.round(DEFAULT_QR_SIZE * normalizeQrScale(scale)));\n }\n\n return Math.max(MIN_QR_SIZE, Math.round(baseSize * normalizeQrScale(scale)));\n}\n\n/**\n * Generate a QR code as a base64 data URL\n * @param data - Data to encode in the QR code (will be JSON stringified)\n * @param size - QR code size in pixels\n * @param options - Customization options (error correction level, colors, etc.)\r\n * @returns Base64 PNG data URL\r\n */\r\nexport function generateQrCodeDataURL(\n data: Record<string, unknown>,\n size = DEFAULT_QR_SIZE,\n options?: {\n level?: 'L' | 'M' | 'Q' | 'H'; // Error correction level\n padding?: number;\n background?: string;\n foreground?: string;\n }\n): string {\n const background = options?.background ?? 'transparent';\n const isTransparentBackground = background === 'transparent';\n const qr = new (QRious as any)({\n value: JSON.stringify(data),\n size,\n level: options?.level || 'H', // High error correction by default\n padding: options?.padding ?? 0,\n background,\n backgroundAlpha: isTransparentBackground ? 0 : 1,\n foreground: options?.foreground || 'black',\n foregroundAlpha: 1,\n });\n return qr.toDataURL('image/png');\n}\n\r\n/**\r\n * Generate QR code from specific fields in the card data\r\n * Only includes fields that exist in the data object\r\n * @param data - Full card data object\r\n * @param fields - Array of field keys to include in QR code\r\n * @param size - QR code size in pixels\r\n * @returns Base64 PNG data URL\r\n */\r\nexport function generateQrCodeFromFields(\n data: IDCardData,\n fields: string[],\n size = DEFAULT_QR_SIZE\n): string {\n const qrData = getQrCodeDataFromFields(data, fields);\n if (Object.keys(qrData).length === 0) {\n return '';\n }\n\n return generateQrCodeDataURL(qrData, size);\n}\n\nexport function getQrCodeDataFromFields(\n data: IDCardData,\n fields: string[]\n): Record<string, unknown> {\n // Build object with only the specified fields that actually contain data\n const qrData: Record<string, unknown> = {};\n\n for (const field of fields) {\n const value = data[field];\n if (hasQrFieldValue(value)) {\n qrData[field] = value;\n }\n }\n\n return qrData;\n}\n\r\n/**\r\n * Set QR code image src on a DOM element\r\n */\r\nexport function setQrCodeOnElement(\n elementId: string,\n data: Record<string, unknown>,\n size = DEFAULT_QR_SIZE,\n container: Document | HTMLElement = document\n): boolean {\n const qrDataURL = generateQrCodeDataURL(data, size);\n const targetElement = resolveQrTargetElement(elementId, container);\n const imgTag = resolveQrImageElement(targetElement);\n\n if (imgTag) {\n imgTag.setAttribute('src', qrDataURL);\n imgTag.setAttribute('data-qr-code-image', 'true');\n imgTag.style.display = 'block';\n imgTag.style.opacity = '1';\n imgTag.style.visibility = 'visible';\n imgTag.style.backgroundColor = 'transparent';\n if (targetElement) {\n targetElement.style.backgroundColor = 'transparent';\n }\n return true;\n }\n return false;\n}\n"],"names":["QRious"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"qrUtils.js","sources":["../../../src/core/qrUtils.ts"],"sourcesContent":["import QRious from 'qrious';\nimport type { IDCardData } from '../types';\n\nconst DEFAULT_QR_SIZE = 200;\nconst MIN_QR_SIZE = 32;\n\ntype QrRenderOptions = {\n level?: 'L' | 'M' | 'Q' | 'H';\n padding?: number;\n background?: string;\n foreground?: string;\n};\n\nfunction normalizeQrScale(scale = 1): number {\n return Number.isFinite(scale) && scale > 0 ? scale : 1;\n}\n\nfunction resolveQrTargetElement(\n elementId: string,\n container: Document | HTMLElement\n): HTMLElement | null {\n if (container instanceof HTMLElement) {\n if (container.id === elementId) {\n return container;\n }\n\n return container.querySelector<HTMLElement>(`#${elementId}`);\n }\n\n return container.getElementById(elementId);\n}\n\nfunction resolveQrImageElement(targetElement: HTMLElement | null): HTMLImageElement | null {\n if (!targetElement) {\n return null;\n }\n\n if (targetElement instanceof HTMLImageElement) {\n return targetElement;\n }\n\n return targetElement.querySelector<HTMLImageElement>('img[data-qr-code-image=\"true\"], img');\n}\n\nfunction hasQrFieldValue(value: IDCardData[string]): boolean {\n if (value === undefined) {\n return false;\n }\n\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n\n if (Array.isArray(value)) {\n return value.some((item) => String(item).trim().length > 0);\n }\n\n return true;\n}\n\nexport function getQrCodeSize(\n width: number,\n height = width,\n scale = 1\n): number {\n const normalizedWidth = Number.isFinite(width) ? width : 0;\n const normalizedHeight = Number.isFinite(height) ? height : 0;\n const hasWidth = normalizedWidth > 0;\n const hasHeight = normalizedHeight > 0;\n const baseSize = hasWidth && hasHeight\n ? Math.min(normalizedWidth, normalizedHeight)\n : Math.max(normalizedWidth, normalizedHeight);\n\n if (baseSize <= 0) {\n return Math.max(MIN_QR_SIZE, Math.round(DEFAULT_QR_SIZE * normalizeQrScale(scale)));\n }\n\n return Math.max(MIN_QR_SIZE, Math.round(baseSize * normalizeQrScale(scale)));\n}\n\n/**\n * Generate a QR code as a base64 data URL\n * @param data - Data to encode in the QR code (will be JSON stringified)\n * @param size - QR code size in pixels\n * @param options - Customization options (error correction level, colors, etc.)\r\n * @returns Base64 PNG data URL\r\n */\r\nexport function generateQrCodeDataURL(\n data: Record<string, unknown>,\n size = DEFAULT_QR_SIZE,\n options?: QrRenderOptions\n): string {\n const background = options?.background ?? 'transparent';\n const normalizedSize = Math.max(MIN_QR_SIZE, Math.round(size));\n const padding = Math.max(0, Math.round(options?.padding ?? 0));\n const qr = new (QRious as any)({\n value: JSON.stringify(data),\n size: normalizedSize,\n level: options?.level || 'H', // High error correction by default\n padding,\n background: 'transparent',\n backgroundAlpha: 0,\n foreground: options?.foreground || 'black',\n foregroundAlpha: 1,\n });\n\n return renderQrToTargetSize(qr.canvas, normalizedSize, background, padding);\n}\n\r\n/**\r\n * Generate QR code from specific fields in the card data\r\n * Only includes fields that exist in the data object\r\n * @param data - Full card data object\r\n * @param fields - Array of field keys to include in QR code\r\n * @param size - QR code size in pixels\r\n * @returns Base64 PNG data URL\r\n */\r\nexport function generateQrCodeFromFields(\n data: IDCardData,\n fields: string[],\n size = DEFAULT_QR_SIZE\n): string {\n const qrData = getQrCodeDataFromFields(data, fields);\n if (Object.keys(qrData).length === 0) {\n return '';\n }\n\n return generateQrCodeDataURL(qrData, size);\n}\n\nexport function getQrCodeDataFromFields(\n data: IDCardData,\n fields: string[]\n): Record<string, unknown> {\n // Build object with only the specified fields that actually contain data\n const qrData: Record<string, unknown> = {};\n\n for (const field of fields) {\n const value = data[field];\n if (hasQrFieldValue(value)) {\n qrData[field] = value;\n }\n }\n\n return qrData;\n}\n\r\n/**\r\n * Set QR code image src on a DOM element\r\n */\r\nexport function setQrCodeOnElement(\n elementId: string,\n data: Record<string, unknown>,\n size = DEFAULT_QR_SIZE,\n container: Document | HTMLElement = document\n): boolean {\n const qrDataURL = generateQrCodeDataURL(data, size);\n const targetElement = resolveQrTargetElement(elementId, container);\n const imgTag = resolveQrImageElement(targetElement);\n\n if (imgTag) {\n imgTag.setAttribute('src', qrDataURL);\n imgTag.setAttribute('data-qr-code-image', 'true');\n imgTag.style.display = 'block';\n imgTag.style.opacity = '1';\n imgTag.style.visibility = 'visible';\n imgTag.style.backgroundColor = 'transparent';\n if (targetElement) {\n targetElement.style.backgroundColor = 'transparent';\n }\n return true;\n }\n return false;\n}\n\nfunction renderQrToTargetSize(\n sourceCanvas: HTMLCanvasElement | undefined,\n targetSize: number,\n background: string,\n padding: number\n): string {\n if (!sourceCanvas) {\n return '';\n }\n\n const bounds = getOpaqueBounds(sourceCanvas);\n const outputCanvas = document.createElement('canvas');\n outputCanvas.width = targetSize;\n outputCanvas.height = targetSize;\n\n const context = outputCanvas.getContext('2d');\n if (!context) {\n return sourceCanvas.toDataURL('image/png');\n }\n\n if (background !== 'transparent') {\n context.fillStyle = background;\n context.fillRect(0, 0, targetSize, targetSize);\n }\n\n context.imageSmoothingEnabled = false;\n const destinationPadding = Math.min(Math.max(0, padding), Math.floor((targetSize - 1) / 2));\n const destinationSize = Math.max(1, targetSize - (destinationPadding * 2));\n\n if (bounds) {\n context.drawImage(\n sourceCanvas,\n bounds.x,\n bounds.y,\n bounds.width,\n bounds.height,\n destinationPadding,\n destinationPadding,\n destinationSize,\n destinationSize\n );\n } else {\n context.drawImage(\n sourceCanvas,\n destinationPadding,\n destinationPadding,\n destinationSize,\n destinationSize\n );\n }\n\n return outputCanvas.toDataURL('image/png');\n}\n\nfunction getOpaqueBounds(\n canvas: HTMLCanvasElement\n): { x: number; y: number; width: number; height: number } | null {\n const context = canvas.getContext('2d', { willReadFrequently: true });\n if (!context) {\n return null;\n }\n\n const { width, height } = canvas;\n const { data } = context.getImageData(0, 0, width, height);\n\n let minX = width;\n let minY = height;\n let maxX = -1;\n let maxY = -1;\n\n for (let y = 0; y < height; y += 1) {\n for (let x = 0; x < width; x += 1) {\n const alpha = data[((y * width) + x) * 4 + 3];\n if (alpha === 0) {\n continue;\n }\n\n if (x < minX) {\n minX = x;\n }\n if (y < minY) {\n minY = y;\n }\n if (x > maxX) {\n maxX = x;\n }\n if (y > maxY) {\n maxY = y;\n }\n }\n }\n\n if (maxX < minX || maxY < minY) {\n return null;\n }\n\n return {\n x: minX,\n y: minY,\n width: (maxX - minX) + 1,\n height: (maxY - minY) + 1,\n };\n}\n"],"names":["QRious"],"mappings":"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"}
|
package/dist/esm/core/qrUtils.js
CHANGED
|
@@ -57,18 +57,19 @@ function getQrCodeSize(width, height = width, scale = 1) {
|
|
|
57
57
|
*/
|
|
58
58
|
function generateQrCodeDataURL(data, size = DEFAULT_QR_SIZE, options) {
|
|
59
59
|
const background = options?.background ?? 'transparent';
|
|
60
|
-
const
|
|
60
|
+
const normalizedSize = Math.max(MIN_QR_SIZE, Math.round(size));
|
|
61
|
+
const padding = Math.max(0, Math.round(options?.padding ?? 0));
|
|
61
62
|
const qr = new QRious({
|
|
62
63
|
value: JSON.stringify(data),
|
|
63
|
-
size,
|
|
64
|
+
size: normalizedSize,
|
|
64
65
|
level: options?.level || 'H', // High error correction by default
|
|
65
|
-
padding
|
|
66
|
-
background,
|
|
67
|
-
backgroundAlpha:
|
|
66
|
+
padding,
|
|
67
|
+
background: 'transparent',
|
|
68
|
+
backgroundAlpha: 0,
|
|
68
69
|
foreground: options?.foreground || 'black',
|
|
69
70
|
foregroundAlpha: 1,
|
|
70
71
|
});
|
|
71
|
-
return qr.
|
|
72
|
+
return renderQrToTargetSize(qr.canvas, normalizedSize, background, padding);
|
|
72
73
|
}
|
|
73
74
|
/**
|
|
74
75
|
* Generate QR code from specific fields in the card data
|
|
@@ -117,6 +118,74 @@ function setQrCodeOnElement(elementId, data, size = DEFAULT_QR_SIZE, container =
|
|
|
117
118
|
}
|
|
118
119
|
return false;
|
|
119
120
|
}
|
|
121
|
+
function renderQrToTargetSize(sourceCanvas, targetSize, background, padding) {
|
|
122
|
+
if (!sourceCanvas) {
|
|
123
|
+
return '';
|
|
124
|
+
}
|
|
125
|
+
const bounds = getOpaqueBounds(sourceCanvas);
|
|
126
|
+
const outputCanvas = document.createElement('canvas');
|
|
127
|
+
outputCanvas.width = targetSize;
|
|
128
|
+
outputCanvas.height = targetSize;
|
|
129
|
+
const context = outputCanvas.getContext('2d');
|
|
130
|
+
if (!context) {
|
|
131
|
+
return sourceCanvas.toDataURL('image/png');
|
|
132
|
+
}
|
|
133
|
+
if (background !== 'transparent') {
|
|
134
|
+
context.fillStyle = background;
|
|
135
|
+
context.fillRect(0, 0, targetSize, targetSize);
|
|
136
|
+
}
|
|
137
|
+
context.imageSmoothingEnabled = false;
|
|
138
|
+
const destinationPadding = Math.min(Math.max(0, padding), Math.floor((targetSize - 1) / 2));
|
|
139
|
+
const destinationSize = Math.max(1, targetSize - (destinationPadding * 2));
|
|
140
|
+
if (bounds) {
|
|
141
|
+
context.drawImage(sourceCanvas, bounds.x, bounds.y, bounds.width, bounds.height, destinationPadding, destinationPadding, destinationSize, destinationSize);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
context.drawImage(sourceCanvas, destinationPadding, destinationPadding, destinationSize, destinationSize);
|
|
145
|
+
}
|
|
146
|
+
return outputCanvas.toDataURL('image/png');
|
|
147
|
+
}
|
|
148
|
+
function getOpaqueBounds(canvas) {
|
|
149
|
+
const context = canvas.getContext('2d', { willReadFrequently: true });
|
|
150
|
+
if (!context) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const { width, height } = canvas;
|
|
154
|
+
const { data } = context.getImageData(0, 0, width, height);
|
|
155
|
+
let minX = width;
|
|
156
|
+
let minY = height;
|
|
157
|
+
let maxX = -1;
|
|
158
|
+
let maxY = -1;
|
|
159
|
+
for (let y = 0; y < height; y += 1) {
|
|
160
|
+
for (let x = 0; x < width; x += 1) {
|
|
161
|
+
const alpha = data[((y * width) + x) * 4 + 3];
|
|
162
|
+
if (alpha === 0) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (x < minX) {
|
|
166
|
+
minX = x;
|
|
167
|
+
}
|
|
168
|
+
if (y < minY) {
|
|
169
|
+
minY = y;
|
|
170
|
+
}
|
|
171
|
+
if (x > maxX) {
|
|
172
|
+
maxX = x;
|
|
173
|
+
}
|
|
174
|
+
if (y > maxY) {
|
|
175
|
+
maxY = y;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (maxX < minX || maxY < minY) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
x: minX,
|
|
184
|
+
y: minY,
|
|
185
|
+
width: (maxX - minX) + 1,
|
|
186
|
+
height: (maxY - minY) + 1,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
120
189
|
|
|
121
190
|
export { generateQrCodeDataURL, generateQrCodeFromFields, getQrCodeDataFromFields, getQrCodeSize, setQrCodeOnElement };
|
|
122
191
|
//# sourceMappingURL=qrUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qrUtils.js","sources":["../../../src/core/qrUtils.ts"],"sourcesContent":["import QRious from 'qrious';\nimport type { IDCardData } from '../types';\n\nconst DEFAULT_QR_SIZE = 200;\nconst MIN_QR_SIZE = 32;\n\nfunction normalizeQrScale(scale = 1): number {\n return Number.isFinite(scale) && scale > 0 ? scale : 1;\n}\n\nfunction resolveQrTargetElement(\n elementId: string,\n container: Document | HTMLElement\n): HTMLElement | null {\n if (container instanceof HTMLElement) {\n if (container.id === elementId) {\n return container;\n }\n\n return container.querySelector<HTMLElement>(`#${elementId}`);\n }\n\n return container.getElementById(elementId);\n}\n\nfunction resolveQrImageElement(targetElement: HTMLElement | null): HTMLImageElement | null {\n if (!targetElement) {\n return null;\n }\n\n if (targetElement instanceof HTMLImageElement) {\n return targetElement;\n }\n\n return targetElement.querySelector<HTMLImageElement>('img[data-qr-code-image=\"true\"], img');\n}\n\nfunction hasQrFieldValue(value: IDCardData[string]): boolean {\n if (value === undefined) {\n return false;\n }\n\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n\n if (Array.isArray(value)) {\n return value.some((item) => String(item).trim().length > 0);\n }\n\n return true;\n}\n\nexport function getQrCodeSize(\n width: number,\n height = width,\n scale = 1\n): number {\n const normalizedWidth = Number.isFinite(width) ? width : 0;\n const normalizedHeight = Number.isFinite(height) ? height : 0;\n const hasWidth = normalizedWidth > 0;\n const hasHeight = normalizedHeight > 0;\n const baseSize = hasWidth && hasHeight\n ? Math.min(normalizedWidth, normalizedHeight)\n : Math.max(normalizedWidth, normalizedHeight);\n\n if (baseSize <= 0) {\n return Math.max(MIN_QR_SIZE, Math.round(DEFAULT_QR_SIZE * normalizeQrScale(scale)));\n }\n\n return Math.max(MIN_QR_SIZE, Math.round(baseSize * normalizeQrScale(scale)));\n}\n\n/**\n * Generate a QR code as a base64 data URL\n * @param data - Data to encode in the QR code (will be JSON stringified)\n * @param size - QR code size in pixels\n * @param options - Customization options (error correction level, colors, etc.)\r\n * @returns Base64 PNG data URL\r\n */\r\nexport function generateQrCodeDataURL(\n data: Record<string, unknown>,\n size = DEFAULT_QR_SIZE,\n options?: {\n level?: 'L' | 'M' | 'Q' | 'H'; // Error correction level\n padding?: number;\n background?: string;\n foreground?: string;\n }\n): string {\n const background = options?.background ?? 'transparent';\n const isTransparentBackground = background === 'transparent';\n const qr = new (QRious as any)({\n value: JSON.stringify(data),\n size,\n level: options?.level || 'H', // High error correction by default\n padding: options?.padding ?? 0,\n background,\n backgroundAlpha: isTransparentBackground ? 0 : 1,\n foreground: options?.foreground || 'black',\n foregroundAlpha: 1,\n });\n return qr.toDataURL('image/png');\n}\n\r\n/**\r\n * Generate QR code from specific fields in the card data\r\n * Only includes fields that exist in the data object\r\n * @param data - Full card data object\r\n * @param fields - Array of field keys to include in QR code\r\n * @param size - QR code size in pixels\r\n * @returns Base64 PNG data URL\r\n */\r\nexport function generateQrCodeFromFields(\n data: IDCardData,\n fields: string[],\n size = DEFAULT_QR_SIZE\n): string {\n const qrData = getQrCodeDataFromFields(data, fields);\n if (Object.keys(qrData).length === 0) {\n return '';\n }\n\n return generateQrCodeDataURL(qrData, size);\n}\n\nexport function getQrCodeDataFromFields(\n data: IDCardData,\n fields: string[]\n): Record<string, unknown> {\n // Build object with only the specified fields that actually contain data\n const qrData: Record<string, unknown> = {};\n\n for (const field of fields) {\n const value = data[field];\n if (hasQrFieldValue(value)) {\n qrData[field] = value;\n }\n }\n\n return qrData;\n}\n\r\n/**\r\n * Set QR code image src on a DOM element\r\n */\r\nexport function setQrCodeOnElement(\n elementId: string,\n data: Record<string, unknown>,\n size = DEFAULT_QR_SIZE,\n container: Document | HTMLElement = document\n): boolean {\n const qrDataURL = generateQrCodeDataURL(data, size);\n const targetElement = resolveQrTargetElement(elementId, container);\n const imgTag = resolveQrImageElement(targetElement);\n\n if (imgTag) {\n imgTag.setAttribute('src', qrDataURL);\n imgTag.setAttribute('data-qr-code-image', 'true');\n imgTag.style.display = 'block';\n imgTag.style.opacity = '1';\n imgTag.style.visibility = 'visible';\n imgTag.style.backgroundColor = 'transparent';\n if (targetElement) {\n targetElement.style.backgroundColor = 'transparent';\n }\n return true;\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"qrUtils.js","sources":["../../../src/core/qrUtils.ts"],"sourcesContent":["import QRious from 'qrious';\nimport type { IDCardData } from '../types';\n\nconst DEFAULT_QR_SIZE = 200;\nconst MIN_QR_SIZE = 32;\n\ntype QrRenderOptions = {\n level?: 'L' | 'M' | 'Q' | 'H';\n padding?: number;\n background?: string;\n foreground?: string;\n};\n\nfunction normalizeQrScale(scale = 1): number {\n return Number.isFinite(scale) && scale > 0 ? scale : 1;\n}\n\nfunction resolveQrTargetElement(\n elementId: string,\n container: Document | HTMLElement\n): HTMLElement | null {\n if (container instanceof HTMLElement) {\n if (container.id === elementId) {\n return container;\n }\n\n return container.querySelector<HTMLElement>(`#${elementId}`);\n }\n\n return container.getElementById(elementId);\n}\n\nfunction resolveQrImageElement(targetElement: HTMLElement | null): HTMLImageElement | null {\n if (!targetElement) {\n return null;\n }\n\n if (targetElement instanceof HTMLImageElement) {\n return targetElement;\n }\n\n return targetElement.querySelector<HTMLImageElement>('img[data-qr-code-image=\"true\"], img');\n}\n\nfunction hasQrFieldValue(value: IDCardData[string]): boolean {\n if (value === undefined) {\n return false;\n }\n\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n\n if (Array.isArray(value)) {\n return value.some((item) => String(item).trim().length > 0);\n }\n\n return true;\n}\n\nexport function getQrCodeSize(\n width: number,\n height = width,\n scale = 1\n): number {\n const normalizedWidth = Number.isFinite(width) ? width : 0;\n const normalizedHeight = Number.isFinite(height) ? height : 0;\n const hasWidth = normalizedWidth > 0;\n const hasHeight = normalizedHeight > 0;\n const baseSize = hasWidth && hasHeight\n ? Math.min(normalizedWidth, normalizedHeight)\n : Math.max(normalizedWidth, normalizedHeight);\n\n if (baseSize <= 0) {\n return Math.max(MIN_QR_SIZE, Math.round(DEFAULT_QR_SIZE * normalizeQrScale(scale)));\n }\n\n return Math.max(MIN_QR_SIZE, Math.round(baseSize * normalizeQrScale(scale)));\n}\n\n/**\n * Generate a QR code as a base64 data URL\n * @param data - Data to encode in the QR code (will be JSON stringified)\n * @param size - QR code size in pixels\n * @param options - Customization options (error correction level, colors, etc.)\r\n * @returns Base64 PNG data URL\r\n */\r\nexport function generateQrCodeDataURL(\n data: Record<string, unknown>,\n size = DEFAULT_QR_SIZE,\n options?: QrRenderOptions\n): string {\n const background = options?.background ?? 'transparent';\n const normalizedSize = Math.max(MIN_QR_SIZE, Math.round(size));\n const padding = Math.max(0, Math.round(options?.padding ?? 0));\n const qr = new (QRious as any)({\n value: JSON.stringify(data),\n size: normalizedSize,\n level: options?.level || 'H', // High error correction by default\n padding,\n background: 'transparent',\n backgroundAlpha: 0,\n foreground: options?.foreground || 'black',\n foregroundAlpha: 1,\n });\n\n return renderQrToTargetSize(qr.canvas, normalizedSize, background, padding);\n}\n\r\n/**\r\n * Generate QR code from specific fields in the card data\r\n * Only includes fields that exist in the data object\r\n * @param data - Full card data object\r\n * @param fields - Array of field keys to include in QR code\r\n * @param size - QR code size in pixels\r\n * @returns Base64 PNG data URL\r\n */\r\nexport function generateQrCodeFromFields(\n data: IDCardData,\n fields: string[],\n size = DEFAULT_QR_SIZE\n): string {\n const qrData = getQrCodeDataFromFields(data, fields);\n if (Object.keys(qrData).length === 0) {\n return '';\n }\n\n return generateQrCodeDataURL(qrData, size);\n}\n\nexport function getQrCodeDataFromFields(\n data: IDCardData,\n fields: string[]\n): Record<string, unknown> {\n // Build object with only the specified fields that actually contain data\n const qrData: Record<string, unknown> = {};\n\n for (const field of fields) {\n const value = data[field];\n if (hasQrFieldValue(value)) {\n qrData[field] = value;\n }\n }\n\n return qrData;\n}\n\r\n/**\r\n * Set QR code image src on a DOM element\r\n */\r\nexport function setQrCodeOnElement(\n elementId: string,\n data: Record<string, unknown>,\n size = DEFAULT_QR_SIZE,\n container: Document | HTMLElement = document\n): boolean {\n const qrDataURL = generateQrCodeDataURL(data, size);\n const targetElement = resolveQrTargetElement(elementId, container);\n const imgTag = resolveQrImageElement(targetElement);\n\n if (imgTag) {\n imgTag.setAttribute('src', qrDataURL);\n imgTag.setAttribute('data-qr-code-image', 'true');\n imgTag.style.display = 'block';\n imgTag.style.opacity = '1';\n imgTag.style.visibility = 'visible';\n imgTag.style.backgroundColor = 'transparent';\n if (targetElement) {\n targetElement.style.backgroundColor = 'transparent';\n }\n return true;\n }\n return false;\n}\n\nfunction renderQrToTargetSize(\n sourceCanvas: HTMLCanvasElement | undefined,\n targetSize: number,\n background: string,\n padding: number\n): string {\n if (!sourceCanvas) {\n return '';\n }\n\n const bounds = getOpaqueBounds(sourceCanvas);\n const outputCanvas = document.createElement('canvas');\n outputCanvas.width = targetSize;\n outputCanvas.height = targetSize;\n\n const context = outputCanvas.getContext('2d');\n if (!context) {\n return sourceCanvas.toDataURL('image/png');\n }\n\n if (background !== 'transparent') {\n context.fillStyle = background;\n context.fillRect(0, 0, targetSize, targetSize);\n }\n\n context.imageSmoothingEnabled = false;\n const destinationPadding = Math.min(Math.max(0, padding), Math.floor((targetSize - 1) / 2));\n const destinationSize = Math.max(1, targetSize - (destinationPadding * 2));\n\n if (bounds) {\n context.drawImage(\n sourceCanvas,\n bounds.x,\n bounds.y,\n bounds.width,\n bounds.height,\n destinationPadding,\n destinationPadding,\n destinationSize,\n destinationSize\n );\n } else {\n context.drawImage(\n sourceCanvas,\n destinationPadding,\n destinationPadding,\n destinationSize,\n destinationSize\n );\n }\n\n return outputCanvas.toDataURL('image/png');\n}\n\nfunction getOpaqueBounds(\n canvas: HTMLCanvasElement\n): { x: number; y: number; width: number; height: number } | null {\n const context = canvas.getContext('2d', { willReadFrequently: true });\n if (!context) {\n return null;\n }\n\n const { width, height } = canvas;\n const { data } = context.getImageData(0, 0, width, height);\n\n let minX = width;\n let minY = height;\n let maxX = -1;\n let maxY = -1;\n\n for (let y = 0; y < height; y += 1) {\n for (let x = 0; x < width; x += 1) {\n const alpha = data[((y * width) + x) * 4 + 3];\n if (alpha === 0) {\n continue;\n }\n\n if (x < minX) {\n minX = x;\n }\n if (y < minY) {\n minY = y;\n }\n if (x > maxX) {\n maxX = x;\n }\n if (y > maxY) {\n maxY = y;\n }\n }\n }\n\n if (maxX < minX || maxY < minY) {\n return null;\n }\n\n return {\n x: minX,\n y: minY,\n width: (maxX - minX) + 1,\n height: (maxY - minY) + 1,\n };\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -326,6 +326,12 @@ interface UseFieldMappingOptions {
|
|
|
326
326
|
}
|
|
327
327
|
declare function useFieldMapping(options?: UseFieldMappingOptions): UseFieldMappingReturn;
|
|
328
328
|
|
|
329
|
+
type QrRenderOptions = {
|
|
330
|
+
level?: 'L' | 'M' | 'Q' | 'H';
|
|
331
|
+
padding?: number;
|
|
332
|
+
background?: string;
|
|
333
|
+
foreground?: string;
|
|
334
|
+
};
|
|
329
335
|
/**
|
|
330
336
|
* Generate a QR code as a base64 data URL
|
|
331
337
|
* @param data - Data to encode in the QR code (will be JSON stringified)
|
|
@@ -333,12 +339,7 @@ declare function useFieldMapping(options?: UseFieldMappingOptions): UseFieldMapp
|
|
|
333
339
|
* @param options - Customization options (error correction level, colors, etc.)
|
|
334
340
|
* @returns Base64 PNG data URL
|
|
335
341
|
*/
|
|
336
|
-
declare function generateQrCodeDataURL(data: Record<string, unknown>, size?: number, options?:
|
|
337
|
-
level?: 'L' | 'M' | 'Q' | 'H';
|
|
338
|
-
padding?: number;
|
|
339
|
-
background?: string;
|
|
340
|
-
foreground?: string;
|
|
341
|
-
}): string;
|
|
342
|
+
declare function generateQrCodeDataURL(data: Record<string, unknown>, size?: number, options?: QrRenderOptions): string;
|
|
342
343
|
/**
|
|
343
344
|
* Generate QR code from specific fields in the card data
|
|
344
345
|
* Only includes fields that exist in the data object
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { IDCardData } from '../types';
|
|
2
|
+
type QrRenderOptions = {
|
|
3
|
+
level?: 'L' | 'M' | 'Q' | 'H';
|
|
4
|
+
padding?: number;
|
|
5
|
+
background?: string;
|
|
6
|
+
foreground?: string;
|
|
7
|
+
};
|
|
2
8
|
export declare function getQrCodeSize(width: number, height?: number, scale?: number): number;
|
|
3
9
|
/**
|
|
4
10
|
* Generate a QR code as a base64 data URL
|
|
@@ -7,12 +13,7 @@ export declare function getQrCodeSize(width: number, height?: number, scale?: nu
|
|
|
7
13
|
* @param options - Customization options (error correction level, colors, etc.)
|
|
8
14
|
* @returns Base64 PNG data URL
|
|
9
15
|
*/
|
|
10
|
-
export declare function generateQrCodeDataURL(data: Record<string, unknown>, size?: number, options?:
|
|
11
|
-
level?: 'L' | 'M' | 'Q' | 'H';
|
|
12
|
-
padding?: number;
|
|
13
|
-
background?: string;
|
|
14
|
-
foreground?: string;
|
|
15
|
-
}): string;
|
|
16
|
+
export declare function generateQrCodeDataURL(data: Record<string, unknown>, size?: number, options?: QrRenderOptions): string;
|
|
16
17
|
/**
|
|
17
18
|
* Generate QR code from specific fields in the card data
|
|
18
19
|
* Only includes fields that exist in the data object
|
|
@@ -27,3 +28,4 @@ export declare function getQrCodeDataFromFields(data: IDCardData, fields: string
|
|
|
27
28
|
* Set QR code image src on a DOM element
|
|
28
29
|
*/
|
|
29
30
|
export declare function setQrCodeOnElement(elementId: string, data: Record<string, unknown>, size?: number, container?: Document | HTMLElement): boolean;
|
|
31
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-id-card-generator",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"description": "A flexible React library for designing, configuring, and generating ID cards with drag-and-drop field positioning",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|