1 changed files with 45 additions and 37 deletions
@ -1,54 +1,62 @@ |
|||||||
import { publicAssetUrl } from '@/constants' |
|
||||||
import QRCodeStyling from 'qr-code-styling' |
import QRCodeStyling from 'qr-code-styling' |
||||||
import { useEffect, useRef } from 'react' |
import { useEffect, useRef } from 'react' |
||||||
|
|
||||||
|
/** Standard black-on-white QR (square modules, no logo) for broad wallet/scanner compatibility. */ |
||||||
export default function QrCode({ value, size = 180 }: { value: string; size?: number }) { |
export default function QrCode({ value, size = 180 }: { value: string; size?: number }) { |
||||||
const ref = useRef<HTMLDivElement>(null) |
const ref = useRef<HTMLDivElement>(null) |
||||||
|
|
||||||
useEffect(() => { |
useEffect(() => { |
||||||
setTimeout(() => { |
if (!value.trim()) return |
||||||
const pixelRatio = window.devicePixelRatio || 2 |
|
||||||
|
const pixelRatio = window.devicePixelRatio || 2 |
||||||
const qrCode = new QRCodeStyling({ |
const qrCode = new QRCodeStyling({ |
||||||
qrOptions: { |
width: size * pixelRatio, |
||||||
errorCorrectionLevel: 'M' |
height: size * pixelRatio, |
||||||
}, |
data: value, |
||||||
image: publicAssetUrl('favicon.svg'), |
margin: 8, |
||||||
width: size * pixelRatio, |
qrOptions: { |
||||||
height: size * pixelRatio, |
errorCorrectionLevel: 'M' |
||||||
data: value, |
}, |
||||||
dotsOptions: { |
dotsOptions: { |
||||||
type: 'extra-rounded' |
type: 'square', |
||||||
}, |
color: '#000000' |
||||||
cornersDotOptions: { |
}, |
||||||
type: 'extra-rounded' |
backgroundOptions: { |
||||||
}, |
color: '#ffffff' |
||||||
cornersSquareOptions: { |
}, |
||||||
type: 'extra-rounded' |
cornersSquareOptions: { |
||||||
} |
type: 'square', |
||||||
}) |
color: '#000000' |
||||||
|
}, |
||||||
if (ref.current) { |
cornersDotOptions: { |
||||||
ref.current.innerHTML = '' |
type: 'square', |
||||||
qrCode.append(ref.current) |
color: '#000000' |
||||||
const canvas = ref.current.querySelector('canvas') |
|
||||||
if (canvas) { |
|
||||||
canvas.style.width = `${size}px` |
|
||||||
canvas.style.height = `${size}px` |
|
||||||
canvas.style.maxWidth = '100%' |
|
||||||
canvas.style.height = 'auto' |
|
||||||
} |
|
||||||
} |
} |
||||||
}, 0) |
}) |
||||||
|
|
||||||
|
const container = ref.current |
||||||
|
if (!container) return |
||||||
|
|
||||||
|
container.innerHTML = '' |
||||||
|
qrCode.append(container) |
||||||
|
const canvas = container.querySelector('canvas') |
||||||
|
if (canvas) { |
||||||
|
canvas.style.width = `${size}px` |
||||||
|
canvas.style.height = `${size}px` |
||||||
|
canvas.style.maxWidth = '100%' |
||||||
|
canvas.style.display = 'block' |
||||||
|
} |
||||||
|
|
||||||
return () => { |
return () => { |
||||||
if (ref.current) ref.current.innerHTML = '' |
container.innerHTML = '' |
||||||
} |
} |
||||||
}, [value, size]) |
}, [value, size]) |
||||||
|
|
||||||
|
if (!value.trim()) return null |
||||||
|
|
||||||
return ( |
return ( |
||||||
<div className="rounded-2xl overflow-hidden p-2 bg-white"> |
<div className="rounded-lg border border-border/40 bg-white p-3"> |
||||||
<div ref={ref} /> |
<div ref={ref} className="mx-auto w-fit" /> |
||||||
</div> |
</div> |
||||||
) |
) |
||||||
} |
} |
||||||
|
|||||||
Loading…
Reference in new issue