-
Notifications
You must be signed in to change notification settings - Fork 101
Expand file tree
/
Copy pathQRCode.tsx
More file actions
106 lines (96 loc) · 2.69 KB
/
QRCode.tsx
File metadata and controls
106 lines (96 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
'use client';
import { useCallback, useEffect, useRef, forwardRef } from 'react';
import { QRCodeCanvas } from 'qrcode.react';
import { DEFAULT_QR_OPTIONS } from '@/utils/generate-qr';
export interface QRCodeComponentProps {
/** URL or text to encode in QR code */
value: string;
/** Size of the QR code in pixels */
size?: number;
/** Error correction level */
level?: 'L' | 'M' | 'Q' | 'H';
/** Include margin/quiet zone */
includeMargin?: boolean;
/** Background color */
bgColor?: string;
/** Foreground/module color */
fgColor?: string;
/** Additional CSS class names */
className?: string;
/** Callback when QR code is rendered */
onRender?: (ref: HTMLCanvasElement | null) => void;
}
/**
* QRCode Component
* Renders a QR code for sharing URLs, text, or other data.
* Supports custom styling, sizing, and error correction levels.
*
* @example
* ```tsx
* <QRCodeComponent
* value="https://teachlink.com/post/123"
* size={256}
* fgColor="#3b82f6"
* />
* ```
*/
export const QRCodeComponent = forwardRef<HTMLCanvasElement, QRCodeComponentProps>(
(
{
value,
size = DEFAULT_QR_OPTIONS.size,
level = DEFAULT_QR_OPTIONS.level,
includeMargin = DEFAULT_QR_OPTIONS.includeMargin,
bgColor = DEFAULT_QR_OPTIONS.bgColor,
fgColor = DEFAULT_QR_OPTIONS.fgColor,
className = '',
onRender,
},
ref,
) => {
const containerRef = useRef<HTMLDivElement>(null);
const getCanvasElement = () => containerRef.current?.querySelector('canvas') ?? null;
const assignForwardedRef = useCallback(
(canvas: HTMLCanvasElement | null) => {
if (!ref) return;
if (typeof ref === 'function') {
ref(canvas);
} else {
ref.current = canvas;
}
},
[ref],
);
useEffect(() => {
const canvas = getCanvasElement();
assignForwardedRef(canvas);
if (onRender && canvas) {
onRender(canvas);
}
}, [assignForwardedRef, onRender, value, size, level, includeMargin, bgColor, fgColor]);
if (!value) {
return (
<div
className={`flex items-center justify-center ${className}`}
style={{ width: size, height: size }}
>
<p className="text-sm text-gray-500">No value provided</p>
</div>
);
}
return (
<div ref={containerRef} className={`qr-code-container ${className}`}>
<QRCodeCanvas
value={value}
size={size}
level={level}
includeMargin={includeMargin}
bgColor={bgColor}
fgColor={fgColor}
/>
</div>
);
},
);
QRCodeComponent.displayName = 'QRCodeComponent';
export default QRCodeComponent;