UNPKG

code-craft-studio

Version:

A comprehensive QR code and barcode scanning/generation library for React. Works with or without Capacitor. Supports 22+ QR data types and 14+ barcode formats (EAN, UPC, Code 128, etc.), with customizable designs, analytics, and React components. Provider

94 lines 6.93 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { useEffect, useRef, useState, useCallback } from 'react'; import { useCodeCraftStudio } from '../../hooks'; // 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); const { isReady, scanQRCode, checkPermissions: checkPlatformPermissions, requestPermissions: requestPlatformPermissions } = useCodeCraftStudio({ onError: (err) => { setError(err.message); onError === null || onError === void 0 ? void 0 : onError({ message: err.message, code: 'PLATFORM_ERROR' }); } }); // Check permissions on mount useEffect(() => { if (isReady) { checkPermissions(); } }, [isReady]); const checkPermissions = async () => { try { const result = await checkPlatformPermissions(); setPermissionStatus(result.camera || 'prompt'); } catch (_a) { setError('Failed to check camera permissions'); } }; const requestPermissions = async () => { try { const result = await requestPlatformPermissions(); setPermissionStatus(result.camera || 'prompt'); if (result.camera === 'granted') { startScanning(); } } catch (_a) { setError('Failed to request camera permissions'); } }; const startScanning = useCallback(async () => { if (scanningRef.current || !isReady) return; try { scanningRef.current = true; setError(null); setIsScanning(true); const result = await scanQRCode(options); // Successfully scanned setIsScanning(false); scanningRef.current = false; onScan(result); } catch (err) { scanningRef.current = false; setIsScanning(false); setError(err instanceof Error ? err.message : 'Failed to scan'); onError === null || onError === void 0 ? void 0 : onError({ code: 'SCAN_ERROR', message: err instanceof Error ? err.message : 'Failed to scan', }); } }, [isReady, options, onError, onScan, scanQRCode]); const stopScanning = useCallback(() => { setIsScanning(false); scanningRef.current = false; }, []); const handleContainerClick = () => { if (permissionStatus === 'prompt' || permissionStatus === 'denied') { requestPermissions(); } else if (permissionStatus === 'granted' && !isScanning) { startScanning(); } }; // Render permission prompt if (!isReady) { return (_jsx("div", { className: `qr-scanner-container ${className}`, style: style, ref: containerRef, children: _jsxs("div", { className: "qr-scanner-loading", children: [_jsx("div", { className: "spinner" }), _jsx("p", { children: "Initializing scanner..." })] }) })); } if (permissionStatus === 'denied') { return (_jsx("div", { className: `qr-scanner-container ${className}`, style: style, ref: containerRef, children: _jsxs("div", { className: "qr-scanner-permission-denied", children: [_jsx("svg", { className: "icon", viewBox: "0 0 24 24", width: "48", height: "48", children: _jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" }) }), _jsx("h3", { children: "Camera Permission Denied" }), _jsx("p", { children: "Please enable camera permissions in your browser settings to use the QR scanner." })] }) })); } if (error) { return (_jsx("div", { className: `qr-scanner-container ${className}`, style: style, ref: containerRef, children: _jsxs("div", { className: "qr-scanner-error", children: [_jsx("svg", { className: "icon", viewBox: "0 0 24 24", width: "48", height: "48", children: _jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z" }) }), _jsx("h3", { children: "Scanner Error" }), _jsx("p", { children: error }), _jsx("button", { onClick: () => setError(null), className: "qr-scanner-button", children: "Try Again" })] }) })); } return (_jsxs("div", { className: `qr-scanner-container ${className}`, style: style, ref: containerRef, onClick: handleContainerClick, children: [permissionStatus === 'prompt' && !isScanning && (_jsxs("div", { className: "qr-scanner-prompt", children: [_jsx("svg", { className: "icon", viewBox: "0 0 24 24", width: "48", height: "48", children: _jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" }) }), _jsx("h3", { children: "Enable Camera Access" }), _jsx("p", { children: "Click to enable camera access for QR code scanning" }), _jsx("button", { className: "qr-scanner-button qr-scanner-button-primary", children: "Enable Camera" })] })), permissionStatus === 'granted' && !isScanning && (_jsxs("div", { className: "qr-scanner-ready", children: [_jsx("svg", { className: "icon", viewBox: "0 0 24 24", width: "48", height: "48", children: _jsx("path", { d: "M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" }) }), _jsx("h3", { children: "Ready to Scan" }), _jsx("p", { children: "Click to start scanning QR codes" }), _jsx("button", { className: "qr-scanner-button qr-scanner-button-primary", children: "Start Scanning" })] })), isScanning && (_jsxs(_Fragment, { children: [showOverlay && !overlayComponent && (_jsxs("div", { className: "qr-scanner-overlay", children: [_jsxs("div", { className: "qr-scanner-frame", children: [_jsx("div", { className: "corner corner-tl" }), _jsx("div", { className: "corner corner-tr" }), _jsx("div", { className: "corner corner-bl" }), _jsx("div", { className: "corner corner-br" })] }), _jsx("p", { className: "qr-scanner-hint", children: "Align QR code within the frame" }), _jsx("button", { className: "qr-scanner-button qr-scanner-cancel-button", onClick: (e) => { e.stopPropagation(); stopScanning(); }, children: "Cancel" })] })), overlayComponent] }))] })); }; //# sourceMappingURL=QRScanner.js.map