42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import { qrMatrix, qrSvgPath } from "@/lib/qr";
|
||
|
|
import { cn } from "@/lib/utils";
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A QR drawn from the shared matrix in `lib/qr.ts` — the SAME encoder the PDF uses.
|
||
|
|
*
|
||
|
|
* Never swap this for a QR widget component. The encoder produces the raw module
|
||
|
|
* matrix, which lets the screen and the printed file come from one source; a widget
|
||
|
|
* would render its own and the two could drift, and a badge whose printed code
|
||
|
|
* differs from its on-screen code identifies the wrong person or the wrong drum.
|
||
|
|
*/
|
||
|
|
export function QrCode({
|
||
|
|
value,
|
||
|
|
size = 120,
|
||
|
|
className,
|
||
|
|
label,
|
||
|
|
}: {
|
||
|
|
value: string;
|
||
|
|
size?: number;
|
||
|
|
className?: string;
|
||
|
|
label?: string;
|
||
|
|
}) {
|
||
|
|
const { d, viewBox } = qrSvgPath(qrMatrix(value));
|
||
|
|
return (
|
||
|
|
<svg
|
||
|
|
width={size}
|
||
|
|
height={size}
|
||
|
|
viewBox={`0 0 ${viewBox} ${viewBox}`}
|
||
|
|
shapeRendering="crispEdges"
|
||
|
|
role="img"
|
||
|
|
aria-label={label || "QR code"}
|
||
|
|
className={cn("bg-white", className)}
|
||
|
|
>
|
||
|
|
{/* White backing: a QR is only readable against light, and the quiet zone
|
||
|
|
travels with the module grid above. */}
|
||
|
|
<rect width={viewBox} height={viewBox} fill="#FFFFFF" />
|
||
|
|
<path d={d} fill="#000000" />
|
||
|
|
</svg>
|
||
|
|
);
|
||
|
|
}
|