Files
self/sdk/qrcode/components/QRCode.tsx
Kartik Mehta bebaebc872 QR code SDK Redesign (#1536)
* Refactor NFC scanner tests to use a global variable for platform OS, allowing dynamic switching between iOS and Android during tests. This change improves test isolation and avoids hoisting issues with jest.mock.

* Triggering GitHub workflows

* Add status animations and self logos

* Update utilities and styles for statuses

* Remove old LED implementation and occurences

* Update Self QR Code with new design

* Add status banner

* Remove console and use QRcodeSteps in styles

* Add ARIA and use Memo to prevent re-renders

* Add refs for success and error callbacks

* Use ref for self app in qrcode

* Use selfapp ref consistently

* Update connected state animtion

* Skip 'parses Android response' test in nfcScanner

---------

Co-authored-by: Justin Hernandez <justin.hernandez@self.xyz>
Co-authored-by: Javier Cortejoso <javier.cortejoso@gmail.com>
2026-01-21 23:07:24 +10:00

68 lines
1.9 KiB
TypeScript

import Lottie from 'lottie-react';
import { QRCodeSVG } from 'qrcode.react';
import React, { memo } from 'react';
import { qrAnimationOverlayStyle, qrContainerStyle } from '../utils/styles.js';
import { getStatusAnimation, getStatusIcon, QRcodeSteps } from '../utils/utils.js';
const LottieComponent = Lottie.default || Lottie;
const QR_IMAGE_SIZE_RATIO = 0.32;
interface QRCodeProps {
value: string;
size: number;
darkMode: boolean;
proofStep: number;
}
const QRCode = memo(({ value, size, darkMode, proofStep }: QRCodeProps) => {
const isInitialState =
proofStep === QRcodeSteps.DISCONNECTED || proofStep === QRcodeSteps.WAITING_FOR_MOBILE;
const isConnectingState =
proofStep === QRcodeSteps.MOBILE_CONNECTED ||
proofStep === QRcodeSteps.PROOF_GENERATION_STARTED ||
proofStep === QRcodeSteps.PROOF_GENERATED;
const showAnimation = !isInitialState;
const statusIcon = getStatusIcon(proofStep);
const bgColor = darkMode ? '#000000' : '#ffffff';
const fgColor = darkMode ? '#ffffff' : '#000000';
const imageSize = size * QR_IMAGE_SIZE_RATIO;
return (
<div style={qrContainerStyle(size)}>
<QRCodeSVG
value={value}
size={size}
bgColor={bgColor}
fgColor={fgColor}
level="H"
imageSettings={
statusIcon
? {
src: statusIcon,
height: imageSize,
width: imageSize,
excavate: true,
}
: undefined
}
/>
{showAnimation && (
<div style={qrAnimationOverlayStyle(imageSize)}>
{/* @ts-expect-error Lottie typings don't match the default export shape */}
<LottieComponent
animationData={getStatusAnimation(proofStep)}
loop={isConnectingState}
speed={1}
/>
</div>
)}
</div>
);
});
export default QRCode;