@otterscan/react-qr-reader
Version:
A React Component for reading QR codes from the webcam
125 lines (111 loc) • 3.21 kB
JavaScript
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