Files
WebDrop/web/src/ui/QrCode.tsx
T
2026-10-02 00:59:37 +08:00

30 lines
894 B
TypeScript

import { useMemo } from 'react';
import { encodeQr } from '@/lib/qr';
import styles from './QrCode.module.css';
const QUIET = 4; // 码周围的静区(模块数),规范要求 ≥ 4
export function QrCode({ text, label }: { text: string; label: string }) {
const grid = useMemo(() => {
try {
return encodeQr(text);
} catch {
return null;
}
}, [text]);
if (!grid) return <p className={styles.fail}>内容太长,无法生成二维码。</p>;
const n = grid.length + QUIET * 2;
const path = grid
.flatMap((row, y) => row.map((dark, x) => (dark ? `M${x + QUIET} ${y + QUIET}h1v1h-1z` : '')))
.join('');
return (
<svg className={styles.qr} viewBox={`0 0 ${n} ${n}`} role="img" aria-label={label} shapeRendering="crispEdges">
<rect width={n} height={n} className={styles.bg} />
<path d={path} className={styles.fg} />
</svg>
);
}