@coin-voyage/paykit
Version:
Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.
55 lines (54 loc) • 3.3 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import QRCodeUtil from "qrcode";
import { useMemo } from "react";
const generateMatrix = (value, errorCorrectionLevel) => {
const arr = Array.prototype.slice.call(QRCodeUtil.create(value, { errorCorrectionLevel }).modules.data, 0);
const sqrt = Math.sqrt(arr.length);
return arr.reduce((rows, key, index) => (index % sqrt === 0 ? rows.push([key]) : rows[rows.length - 1].push(key)) && rows, []);
};
export function QRCode({ ecl = "M", size: sizeProp = 200, uri, clearArea = false, image, imageBackground = "transparent", }) {
const logoSize = clearArea ? 168 : 0;
const size = sizeProp - 10 * 2;
const dots = useMemo(() => {
const elements = [];
const matrix = generateMatrix(uri, ecl);
const cellSize = size / matrix.length;
// Position squares
const qrList = [
{ x: 0, y: 0 },
{ x: 1, y: 0 },
{ x: 0, y: 1 },
];
qrList.forEach(({ x, y }) => {
const x1 = (matrix.length - 7) * cellSize * x;
const y1 = (matrix.length - 7) * cellSize * y;
for (let i = 0; i < 3; i++) {
elements.push(_jsx("rect", { fill: i % 2 !== 0 ? "var(--ck-qr-background, var(--ck-body-background))" : "var(--ck-qr-dot-color)", rx: (i - 2) * -5 + (i === 0 ? 2 : 3), ry: (i - 2) * -5 + (i === 0 ? 2 : 3), width: cellSize * (7 - i * 2), height: cellSize * (7 - i * 2), x: x1 + cellSize * i, y: y1 + cellSize * i }, `pos-${i}-${x}-${y}`));
}
});
// Image overlay
if (image) {
const x1 = (matrix.length - 7) * cellSize;
const y1 = (matrix.length - 7) * cellSize;
elements.push(_jsx("rect", { fill: imageBackground, rx: 2, ry: 2, width: cellSize * 7, height: cellSize * 7, x: x1, y: y1 }, "image-bg"), _jsx("foreignObject", { width: cellSize * 7, height: cellSize * 7, x: x1, y: y1, children: _jsx("div", { style: { borderRadius: 2, overflow: "hidden" }, children: image }) }, "image-fo"));
}
// Remaining QR dots
const clearArenaSize = Math.floor((logoSize + 25) / cellSize);
const matrixMiddleStart = matrix.length / 2 - clearArenaSize / 2;
const matrixMiddleEnd = matrix.length / 2 + clearArenaSize / 2 - 1;
matrix.forEach((row, i) => {
row.forEach((cell, j) => {
if (cell) {
if (!((i < 7 && j < 7) || (i > matrix.length - 8 && j < 7) || (i < 7 && j > matrix.length - 8))) {
if (image ||
!(i > matrixMiddleStart && i < matrixMiddleEnd && j > matrixMiddleStart && j < matrixMiddleEnd)) {
elements.push(_jsx("circle", { cx: i * cellSize + cellSize / 2, cy: j * cellSize + cellSize / 2, fill: "var(--ck-qr-dot-color)", r: cellSize / 3 }, `dot-${i}-${j}`));
}
}
}
});
});
return elements;
}, [ecl, size, uri, image, imageBackground, logoSize]);
return (_jsxs("svg", { height: size, width: size, viewBox: `0 0 ${size} ${size}`, style: { width: size, height: size }, children: [_jsx("rect", { fill: "transparent", height: size, width: size }), dots] }));
}