@thewirv/react-barcode-scanner
Version:
A React component for scanning QR codes and other barcodes via webcam
2 lines (1 loc) • 2.19 kB
JavaScript
import{jsxs as e,jsx as r}from"react/jsx-runtime";import{useState as o,useMemo as n,useRef as i,useEffect as t}from"react";import{FiCameraOff as a}from"react-icons/fi";import{BrowserMultiFormatReader as c}from"@zxing/browser";import{NotFoundException as d,ChecksumException as s,FormatException as l}from"@zxing/library";const f={barcodeScannerError:{border:"8px #eee solid",borderRadius:"10px",padding:"2rem"},barcodeScannerErrorSvg:{width:"75%",height:"75%",display:"block",opacity:.2,margin:"0 auto"},container:{width:"100%",paddingTop:"100%",overflow:"hidden",position:"relative",display:"none"},barcodeScannerVisible:{display:"block"},video:{top:0,left:0,width:"100%",height:"100%",display:"block",overflow:"hidden",position:"absolute",transform:void 0}};function p({doScan:p=!0,constraints:u={facingMode:"environment"},onSuccess:m,onError:v,onLoad:y,Viewfinder:b,containerStyle:S,videoContainerStyle:g,videoStyle:h,videoProps:w}){const[E,x]=o(!1),A=n((()=>new c),[]),D=i(null),M=!E||!p;t((()=>{if(p){if(!navigator?.mediaDevices){const e='Your browser has no support for the MediaDevices API. You could fix this by running "npm i webrtc-adapter"';return console.warn("[ReactBarcodeScanner]: "+e),void v(Error(e))}(async(e,r,{constraints:o,onSuccess:n,onError:i})=>{if(r.current)try{n((await e.decodeOnceFromConstraints({audio:!1,video:o,preferCurrentTab:!0},r.current)).getText())}catch(e){e&&!(e instanceof d||e instanceof s||e instanceof l)&&i(e)}})(A,D,{constraints:u,onSuccess:m,onError:v})}}),[m,v,p,A,u]);const P=n((()=>{const e={playsInline:!0,disablePictureInPicture:!0,muted:!0,onLoadedData:({nativeEvent:e})=>{const r=e.target;r?.readyState&&r.readyState===r.HAVE_ENOUGH_DATA&&(x(!0),y?.())},style:{...f.video,...h,transform:`${h?.transform??""} ${"user"===u.facingMode?"scaleX(-1)":""}`}};return w?"function"!=typeof w?w:w(e):e}),[u.facingMode,y,w,h]);return e("section",{style:S,children:[M&&r("div",{style:f.barcodeScannerError,children:r(a,{size:300,style:f.barcodeScannerErrorSvg})}),e("div",{style:{...f.container,...M?{}:f.barcodeScannerVisible,...g},children:[r("video",{ref:D,...P}),!!b&&r(b,{})]})]})}p.displayName="BarcodeScanner";export{p as BarcodeScanner};