diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..4514d7c --- /dev/null +++ b/.babelrc @@ -0,0 +1,7 @@ +{ + "presets": [ + "es2015", + "stage-0", + "react" + ] +} \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..67ba88c --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,80 @@ +{ + "parser": "babel-eslint", + "env": { + "es6": true, + "node": true, + "browser": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 7, + "sourceType": "module", + "ecmaFeatures": { + "jsx": true, + "experimentalObjectRestSpread": true, + "classes": true + } + }, + "plugins": [ + "react" + ], + "rules": { + "indent": [ + "error", + 2 + ], + "quotes": [ + "error", + "single" + ], + "linebreak-style": [ + "error", + "unix" + ], + "semi": [ + "error", + "never" + ], + "comma-dangle": [ + "warn", + "always-multiline" + ], + "constructor-super": "error", + "no-confusing-arrow": "error", + "no-constant-condition": "error", + "no-class-assign": "error", + "no-const-assign": "error", + "no-dupe-class-members": "error", + "no-var": "warn", + "no-this-before-super": "error", + "no-extra-boolean-cast": "off", + "object-shorthand": [ + "error", + "always" + ], + "prefer-spread": "warn", + "prefer-template": "warn", + "require-yield": "error", + "jsx-quotes": "warn", + "react/jsx-boolean-value": "warn", + "react/jsx-curly-spacing": "warn", + "react/jsx-no-duplicate-props": "warn", + "react/jsx-no-undef": "warn", + "react/jsx-uses-react": "warn", + "react/jsx-uses-vars": "warn", + "react/no-danger": "warn", + "react/no-did-mount-set-state": "warn", + "react/no-did-update-set-state": "warn", + "react/no-direct-mutation-state": "warn", + "react/no-multi-comp": "warn", + "react/no-set-state": "warn", + "react/no-unknown-property": "warn", + "react/prefer-es6-class": "warn", + "react/prop-types": "warn", + "react/react-in-jsx-scope": "warn", + "react/require-extension": "warn", + "react/self-closing-comp": "warn", + "react/sort-comp": "warn", + "react/wrap-multilines": "warn" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b4067e --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +node_modules + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + + +lib/worker.js \ No newline at end of file diff --git a/.storybook/config.js b/.storybook/config.js new file mode 100644 index 0000000..e799e71 --- /dev/null +++ b/.storybook/config.js @@ -0,0 +1,7 @@ +import { configure } from '@kadira/storybook' + +function loadStories() { + require('../story.js') +} + +configure(loadStories, module) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9f8a0c6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Thomas Billiet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..124e43b --- /dev/null +++ b/README.md @@ -0,0 +1,175 @@ +[![npm version](https://badge.fury.io/js/react-qr-scanner.svg)](https://badge.fury.io/js/react-qr-scanner) + +## Introduction +A [React](https://facebook.github.io/react/) component for reading QR codes from the webcam. It uses the WebRTC standards for reading webcam data and [jsQR](https://github.com/cozmo/jsQR) is used for detecting QR codes in that data. To optimise the speed and experience, a web-worker is used to offload the heavy QR code algorithm on a separate process. The web worker is inlined and loaded on creation of the component. +Thanks to initial repo https://github.com/JodusNodus/react-qr-reader + +## Demo +[thomasbilliet.com/react-qr-scanner](https://thomasbilliet.com/react-qr-scanner) + +## Known Issues +- Due to browser implementations the camera can only be accessed over https or localhost. +- Not compatible with macOS/iOS Safari. Use `legacyMode` to support these platforms. +- In Firefox a prompt will be shown to the user asking which camera to use, so `facingMode` will not affect it. + +## Install +`npm install --save react-qr-scanner` + +## Example + +```js +import React, { Component } from 'react' +import QrReader from 'react-qr-scanner' + +class Test extends Component { + constructor(props){ + super(props) + this.state = { + delay: 100, + result: 'No result', + } + + this.handleScan = this.handleScan.bind(this) + } + handleScan(data){ + this.setState({ + result: data, + }) + } + handleError(err){ + console.error(err) + } + render(){ + const previewStyle = { + height: 240, + width: 320, + } + + return( +
{this.state.result}
+{this.state.result}
+{this.state.result}
+