UNPKG

qrcode-studio

Version:

A comprehensive Capacitor plugin for QR code and barcode scanning/generation. Supports 22+ QR data types and 14+ barcode formats (EAN, UPC, Code 128, etc.), with customizable designs, analytics, and React components. Works seamlessly across web, iOS, and

114 lines 5.89 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { useEffect, useRef, useState, useCallback } from 'react'; import { QRCodeStudio } from '../../index'; // import './QRScanner.css'; // CSS should be imported by the consuming app export const QRScanner = ({ onScan, onError, options, className = '', style, showOverlay = true, overlayComponent, }) => { const [isScanning, setIsScanning] = useState(false); const [permissionStatus, setPermissionStatus] = useState('prompt'); const [error, setError] = useState(null); const containerRef = useRef(null); const scanningRef = useRef(false); // Check permissions on mount useEffect(() => { checkPermissions(); }, []); // Handle scan results useEffect(() => { if (!isScanning) return; const handleScanResult = (result) => { onScan(result); }; const handleScanError = (error) => { setError(error.message); onError === null || onError === void 0 ? void 0 : onError(error); }; const resultListener = QRCodeStudio.addListener('scanResult', handleScanResult); const errorListener = QRCodeStudio.addListener('scanError', handleScanError); return () => { resultListener.then(l => l.remove()); errorListener.then(l => l.remove()); }; }, [isScanning, onScan, onError]); const checkPermissions = async () => { try { const result = await QRCodeStudio.checkPermissions(); setPermissionStatus(result.camera); } catch (_a) { setError('Failed to check camera permissions'); } }; const requestPermissions = async () => { try { const result = await QRCodeStudio.requestPermissions(); setPermissionStatus(result.camera); if (result.camera === 'granted') { startScanning(); } } catch (_a) { setError('Failed to request camera permissions'); } }; const startScanning = useCallback(async () => { if (scanningRef.current) return; try { scanningRef.current = true; setError(null); await QRCodeStudio.startScan(options); setIsScanning(true); } catch (err) { scanningRef.current = false; setError(err instanceof Error ? err.message : 'Failed to start scanner'); onError === null || onError === void 0 ? void 0 : onError({ code: 'START_SCAN_ERROR', message: err instanceof Error ? err.message : 'Failed to start scanner', }); } }, [options, onError]); const stopScanning = useCallback(async () => { if (!scanningRef.current) return; try { await QRCodeStudio.stopScan(); setIsScanning(false); scanningRef.current = false; } catch (err) { setError(err instanceof Error ? err.message : 'Failed to stop scanner'); } }, []); // Cleanup on unmount useEffect(() => { return () => { if (scanningRef.current) { QRCodeStudio.stopScan().catch(console.error); } }; }, []); const renderPermissionRequest = () => (_jsxs("div", { className: "qr-scanner-permission", children: [_jsx("div", { className: "permission-icon", children: "\uD83D\uDCF7" }), _jsx("h3", { children: "Camera Permission Required" }), _jsx("p", { children: "This app needs camera access to scan QR codes" }), _jsx("button", { className: "permission-button", onClick: requestPermissions, children: "Grant Permission" })] })); const renderError = () => (_jsxs("div", { className: "qr-scanner-error", children: [_jsx("div", { className: "error-icon", children: "\u26A0\uFE0F" }), _jsx("h3", { children: "Scanner Error" }), _jsx("p", { children: error }), _jsx("button", { className: "retry-button", onClick: () => { setError(null); if (permissionStatus === 'granted') { startScanning(); } else { requestPermissions(); } }, children: "Retry" })] })); const renderScanner = () => (_jsxs(_Fragment, { children: [_jsx("div", { className: "qr-scanner-video" }), showOverlay && (overlayComponent || (_jsxs("div", { className: "qr-scanner-overlay", children: [_jsxs("div", { className: "scan-region", children: [_jsx("div", { className: "corner top-left" }), _jsx("div", { className: "corner top-right" }), _jsx("div", { className: "corner bottom-left" }), _jsx("div", { className: "corner bottom-right" })] }), _jsx("div", { className: "scan-line" }), _jsx("p", { className: "scan-hint", children: "Position QR code within the frame" })] }))), _jsx("button", { className: "stop-scan-button", onClick: stopScanning, children: "Stop Scanning" })] })); const renderControls = () => (_jsx("div", { className: "qr-scanner-controls", children: _jsx("button", { className: "start-scan-button", onClick: () => { if (permissionStatus === 'granted') { startScanning(); } else { requestPermissions(); } }, children: "Start Scanner" }) })); return (_jsxs("div", { ref: containerRef, className: `qr-scanner-container ${className}`, style: style, children: [error && renderError(), !error && permissionStatus === 'denied' && renderPermissionRequest(), !error && permissionStatus === 'granted' && !isScanning && renderControls(), !error && isScanning && renderScanner()] })); }; export default QRScanner; //# sourceMappingURL=QRScanner.js.map