UNPKG

@otterscan/react-qr-reader

Version:

A React Component for reading QR codes from the webcam

125 lines (111 loc) 3.21 kB
import { useRef, useEffect, createElement } from 'react'; import { BrowserQRCodeReader } from '@zxing/browser'; const isMediaDevicesSupported = () => { const isMediaDevicesSupported = typeof navigator !== 'undefined' && !!navigator.mediaDevices; if (!isMediaDevicesSupported) { console.warn(`[ReactQrReader]: MediaDevices API has no support for your browser. You can fix this by running "npm i webrtc-adapter"`); } return isMediaDevicesSupported; }; const isValidType = (value, name, type) => { const isValid = typeof value === type; if (!isValid) { console.warn(`[ReactQrReader]: Expected "${name}" to be a of type "${type}".`); } return isValid; }; const useQrReader = ({ scanDelay: delayBetweenScanAttempts, constraints: video, onResult, videoId }) => { const controlsRef = useRef(null); useEffect(() => { const codeReader = new BrowserQRCodeReader(null, { delayBetweenScanAttempts }); if (!isMediaDevicesSupported() && isValidType(onResult, 'onResult', 'function')) { const message = 'MediaDevices API has no support for your browser. You can fix this by running "npm i webrtc-adapter"'; onResult(null, new Error(message), codeReader); } if (isValidType(video, 'constraints', 'object')) { codeReader.decodeFromConstraints({ video }, videoId, (result, error) => { if (isValidType(onResult, 'onResult', 'function')) { onResult(result, error, codeReader); } }).then(controls => controlsRef.current = controls).catch(error => { if (isValidType(onResult, 'onResult', 'function')) { onResult(null, error, codeReader); } }); } return () => { var _controlsRef$current; (_controlsRef$current = controlsRef.current) === null || _controlsRef$current === void 0 ? void 0 : _controlsRef$current.stop(); }; }, []); }; const styles = { container: { width: '100%', paddingTop: '100%', overflow: 'hidden', position: 'relative' }, video: { top: 0, left: 0, width: '100%', height: '100%', display: 'block', overflow: 'hidden', position: 'absolute', transform: undefined } }; const QrReader = ({ videoContainerStyle, containerStyle, videoStyle, constraints, ViewFinder, scanDelay, className, onResult, videoId }) => { useQrReader({ constraints, scanDelay, onResult, videoId }); return /*#__PURE__*/createElement("section", { className: className, style: containerStyle }, /*#__PURE__*/createElement("div", { style: { ...styles.container, ...videoContainerStyle } }, !!ViewFinder && /*#__PURE__*/createElement(ViewFinder, null), /*#__PURE__*/createElement("video", { muted: true, id: videoId, style: { ...styles.video, ...videoStyle, transform: (constraints === null || constraints === void 0 ? void 0 : constraints.facingMode) === 'user' && 'scaleX(-1)' } }))); }; QrReader.displayName = 'QrReader'; QrReader.defaultProps = { constraints: { facingMode: 'user' }, videoId: 'video', scanDelay: 500 }; export { QrReader, useQrReader }; //# sourceMappingURL=index.js.map