├── LICENSE ├── README.md ├── demo ├── example1.pdf ├── example2.pdf ├── ignore.template ├── index.html ├── index.js ├── package.json └── src │ └── index.js ├── ignore.template ├── index.js ├── package.json ├── screenshot.png └── src └── index.js /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | This is Simple PDF React component with vertical scroll bar. However, If your pdf document has only one page there will not be any scroll bar by default. If you still need scroll bars, just use CSS example (see demo [index.html](https://github.com/javascriptiscoolpl/npm-simple-react-pdf/blob/master/demo/index.html) code for more details). 4 | 5 | This version uses [pdfjs-dist](https://www.npmjs.com/package/pdfjs-dist) (npm [PDF.js](https://mozilla.github.io/pdf.js/) version) and ES6 syntax. Has been built with [Babel](https://babeljs.io/) and contains demo built with [Browserify](http://browserify.org/). 6 | 7 | Screenshot example (3 x Simple PDF React component): 8 | 9 | ![demo](https://raw.githubusercontent.com/javascriptiscoolpl/npm-simple-react-pdf/master/screenshot.png) 10 | 11 | # Install 12 | 13 | npm install simple-react-pdf 14 | 15 | However, in production or if you do not plan to re-build it, do not install devDependencies. See [npm documentation page](https://docs.npmjs.com/cli/install). 16 | 17 | # Usage - quickstart 18 | 19 | ##### index.html 20 | 21 | This is simple example that should be used in most cases. The pdf size (each canvas) will be automatically adjusted to the box size (div with class SimplePDF). 22 | 23 | .SimplePDF { 24 | width: 350px; /* width of pdf document box should be != 0 */ 25 | height: 500px; /* height of pdf document box should be != 0 */ 26 | border: 1px dashed red; /* optional */ 27 | margin: 15px; /* optional */ 28 | padding: 15px; /* optional */ 29 | float: left; /* optional */ 30 | } 31 | 32 | ##### index.js 33 | 34 | The JavaScript React component code you have to use in your project: 35 | 36 | import React from "react"; 37 | import ReactDOM from "react-dom"; 38 | import spdf from "simple-react-pdf"; 39 | 40 | 41 | 42 | *) Of course change the "example1.pdf" to your pdf document filename and re-build the JavaScript code. 43 | 44 | # Usage - with update 45 | 46 | To update React component (e.g. load new pdf file after button click), you just have to send new props to the React component again (see demo [index.js](https://github.com/javascriptiscoolpl/npm-simple-react-pdf/blob/master/demo/src/index.js) for more details). 47 | 48 | # Demo 49 | 50 | The demo is available in module directory. To test the demo just go to demo directory in module folder and open index.html in your browser. 51 | 52 | cd node_modules/simple-react-pdf/demo 53 | firefox index.html 54 | 55 | For other browsers: 56 | 57 | google-chrome --allow-file-access-from-files index.html 58 | opera --allow-file-access-from-files index.html 59 | 60 | In order to avoid [Cross-Origin Resource Sharing (CORS) issue](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-xhr) consider [simple-react-pdf-service](https://www.npmjs.com/package/simple-react-pdf-service). 61 | 62 | # Demo re-build 63 | 64 | However, you can build the demo again with npm tool (e.g. after your private changes). To re-build the demo just go to demo directory in module folder (if you are not there already): 65 | 66 | cd node_modules/simple-react-pdf/demo 67 | 68 | and run command: 69 | 70 | npm run build 71 | 72 | This should download all packages and build the demo index.js file again. After it, you can open index.html in your browser. Should work :-) 73 | 74 | # License 75 | 76 | MIT 77 | -------------------------------------------------------------------------------- /demo/example1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascriptiscoolpl/npm-simple-react-pdf/9c6bc06f99a650d63c70a2bb8b0e4b94663f9818/demo/example1.pdf -------------------------------------------------------------------------------- /demo/example2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascriptiscoolpl/npm-simple-react-pdf/9c6bc06f99a650d63c70a2bb8b0e4b94663f9818/demo/example2.pdf -------------------------------------------------------------------------------- /demo/ignore.template: -------------------------------------------------------------------------------- 1 | ./node_modules 2 | .git 3 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | demo 6 | 54 | 55 | 56 |
57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo", 3 | "version": "1.0.0", 4 | "description": "demo", 5 | "main": "index.js", 6 | "dependencies": { 7 | "react": "^15.0.0", 8 | "react-dom": "^15.0.0", 9 | "simple-react-pdf": "^1.0.3" 10 | }, 11 | "devDependencies": { 12 | "babel-cli": "^6.7.7", 13 | "babel-core": "^6.7.7", 14 | "babel-loader": "^6.2.4", 15 | "babel-plugin-transform-react-jsx": "^6.7.5", 16 | "babel-preset-es2015": "^6.6.0", 17 | "babel-preset-react": "^6.5.0", 18 | "babel-preset-stage-2": "^6.5.0", 19 | "babelify": "^7.2.0", 20 | "browserify": "^13.0.0", 21 | "react": "^15.0.0", 22 | "react-dom": "^15.0.0" 23 | }, 24 | "scripts": { 25 | "get": "npm install", 26 | "transform": "./node_modules/.bin/browserify -t [ ./node_modules/babelify --presets [ es2015 react ] ] ./src/index.js -o ./index.js", 27 | "ignore": "cat ./ignore.template > ./.gitignore; cat ./ignore.template > ./.npmignore", 28 | "clean": "rm -rf ./node_modules ./.npmignore ./.gitignore", 29 | "build": "npm run get; npm run transform; npm run ignore" 30 | }, 31 | "author": "Darek L", 32 | "license": "MIT", 33 | "homepage": "http://javascript.iscool.pl" 34 | } 35 | -------------------------------------------------------------------------------- /demo/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import spdf from "simple-react-pdf"; 4 | 5 | // sample page content 6 | class App extends React.Component { 7 | 8 | render() { 9 | return ( 10 |
11 | 12 | 13 | 14 |
15 | ); 16 | } 17 | } 18 | 19 | ReactDOM.render( , document.getElementById('app') ); 20 | 21 | // sample page content with update 22 | /* 23 | class App extends React.Component { 24 | 25 | constructor() { 26 | super(); 27 | this.load1 = this.load1.bind(this); 28 | this.load2 = this.load2.bind(this); 29 | this.state = { filename: "./example1.pdf" }; 30 | } 31 | 32 | load1() { 33 | this.state.filename = "./example1.pdf"; 34 | this.forceUpdate(); 35 | } 36 | 37 | load2() { 38 | this.state.filename = "./example2.pdf"; 39 | this.forceUpdate(); 40 | } 41 | 42 | render() { 43 | return ( 44 |
45 | 46 | 47 | 48 |
49 | 50 | 51 |
52 | ); 53 | } 54 | } 55 | 56 | ReactDOM.render( , document.getElementById('app') ); 57 | */ 58 | -------------------------------------------------------------------------------- /ignore.template: -------------------------------------------------------------------------------- 1 | ./node_modules 2 | .git 3 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | var _react = require('react'); 10 | 11 | var _react2 = _interopRequireDefault(_react); 12 | 13 | var _reactDom = require('react-dom'); 14 | 15 | var _reactDom2 = _interopRequireDefault(_reactDom); 16 | 17 | var _pdfCombined = require('pdfjs-dist/build/pdf.combined.js'); 18 | 19 | var _pdfCombined2 = _interopRequireDefault(_pdfCombined); 20 | 21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 22 | 23 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 24 | 25 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 26 | 27 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 28 | 29 | var SimplePDF = function (_React$Component) { 30 | _inherits(SimplePDF, _React$Component); 31 | 32 | function SimplePDF(props) { 33 | _classCallCheck(this, SimplePDF); 34 | 35 | // bind 36 | 37 | var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SimplePDF).call(this, props)); 38 | 39 | _this.loadPDF = _this.loadPDF.bind(_this); 40 | return _this; 41 | } 42 | 43 | _createClass(SimplePDF, [{ 44 | key: 'loadPDF', 45 | value: function loadPDF() { 46 | 47 | // get node for this react component 48 | var node = _reactDom2.default.findDOMNode(this).getElementsByClassName("S-PDF-ID")[0]; 49 | 50 | // clean for update 51 | node.innerHTML = ""; 52 | 53 | // set styles 54 | node.style.width = "100%"; 55 | node.style.height = "100%"; 56 | node.style.overflowX = "hidden"; 57 | node.style.overflowY = "scroll"; 58 | node.style.padding = '0px'; 59 | 60 | _pdfCombined2.default.getDocument(this.props.file).then(function (pdf) { 61 | 62 | // no scrollbar if pdf has only one page 63 | if (pdf.numPages === 1) { 64 | node.style.overflowY = "hidden"; 65 | } 66 | 67 | for (var id = 1, i = 1; i <= pdf.numPages; i++) { 68 | 69 | pdf.getPage(i).then(function (page) { 70 | 71 | // calculate scale according to the box size 72 | var boxWidth = node.clientWidth; 73 | var pdfWidth = page.getViewport(1).width; 74 | var scale = boxWidth / pdfWidth; 75 | var viewport = page.getViewport(scale); 76 | 77 | // set canvas for page 78 | var canvas = document.createElement('canvas'); 79 | canvas.id = "page-" + id;id++; 80 | canvas.width = viewport.width; 81 | canvas.height = viewport.height; 82 | node.appendChild(canvas); 83 | 84 | // get context and render page 85 | var context = canvas.getContext('2d'); 86 | var renderContext = { 87 | canvasContext: context, 88 | viewport: viewport 89 | }; 90 | page.render(renderContext); 91 | }); 92 | } 93 | }); 94 | } 95 | }, { 96 | key: 'render', 97 | value: function render() { 98 | return _react2.default.createElement( 99 | 'div', 100 | { className: 'SimplePDF' }, 101 | _react2.default.createElement('div', { className: 'S-PDF-ID' }) 102 | ); 103 | } 104 | }, { 105 | key: 'componentDidMount', 106 | value: function componentDidMount() { 107 | this.loadPDF(); 108 | } 109 | }, { 110 | key: 'componentDidUpdate', 111 | value: function componentDidUpdate() { 112 | this.loadPDF(); 113 | } 114 | }]); 115 | 116 | return SimplePDF; 117 | }(_react2.default.Component); 118 | 119 | exports.default = SimplePDF; 120 | 121 | 122 | module.exports = { SimplePDF: SimplePDF }; 123 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-react-pdf", 3 | "version": "1.0.9", 4 | "description": "Simple PDF React component with vertical scroll bar (pdfjs-dist, ES6 syntax, Babel, Browserify).", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/javascriptiscoolpl/npm-simple-react-pdf" 9 | }, 10 | "keywords": [ 11 | "ES6", 12 | "ECMAScript 6", 13 | "babel", 14 | "es2015", 15 | "react", 16 | "pdf", 17 | "pdfjs", 18 | "pdfjs-dist", 19 | "react-pdf", 20 | "react-pdfjs", 21 | "react-pdfjs-dist", 22 | "pdf.js", 23 | "simple" 24 | ], 25 | "dependencies": { 26 | "pdfjs-dist": "^1.5.222", 27 | "react": "^15.0.0", 28 | "react-dom": "^15.0.0" 29 | }, 30 | "devDependencies": { 31 | "babel-cli": "^6.7.7", 32 | "babel-core": "^6.7.7", 33 | "babel-loader": "^6.2.4", 34 | "babel-plugin-transform-react-jsx": "^6.7.5", 35 | "babel-preset-es2015": "^6.6.0", 36 | "babel-preset-react": "^6.5.0", 37 | "babel-preset-stage-2": "^6.5.0", 38 | "react": "^15.0.0", 39 | "react-dom": "^15.0.0" 40 | }, 41 | "scripts": { 42 | "get": "npm install", 43 | "transform": "./node_modules/.bin/babel --plugins transform-react-jsx --presets es2015,react ./src/index.js -o ./index.js", 44 | "ignore": "cat ./ignore.template > ./.gitignore; cat ./ignore.template > ./.npmignore", 45 | "build": "npm run get; npm run transform; npm run ignore", 46 | "clean": "rm -rf ./node_modules ./.npmignore ./.gitignore", 47 | "sent": "npm version patch; npm publish", 48 | "git": "git init; git add .; git commit -m \"init\"; git remote add origin https://github.com/javascriptiscoolpl/npm-simple-react-pdf.git; git push -u origin master" 49 | }, 50 | "author": "Darek L", 51 | "license": "MIT", 52 | "homepage": "http://javascript.iscool.pl" 53 | } 54 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javascriptiscoolpl/npm-simple-react-pdf/9c6bc06f99a650d63c70a2bb8b0e4b94663f9818/screenshot.png -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import PDF from 'pdfjs-dist/build/pdf.combined.js'; 4 | 5 | export default class SimplePDF extends React.Component { 6 | 7 | constructor(props) { 8 | super(props); 9 | 10 | // bind 11 | this.loadPDF = this.loadPDF.bind(this); 12 | } 13 | 14 | loadPDF() { 15 | 16 | // get node for this react component 17 | var node = ReactDOM.findDOMNode(this).getElementsByClassName("S-PDF-ID")[0]; 18 | 19 | // clean for update 20 | node.innerHTML = ""; 21 | 22 | // set styles 23 | node.style.width = "100%"; 24 | node.style.height = "100%"; 25 | node.style.overflowX = "hidden"; 26 | node.style.overflowY = "scroll"; 27 | node.style.padding = '0px'; 28 | 29 | PDF.getDocument(this.props.file).then(function(pdf) { 30 | 31 | // no scrollbar if pdf has only one page 32 | if (pdf.numPages===1) { 33 | node.style.overflowY = "hidden"; 34 | } 35 | 36 | for (var id=1,i=1; i<=pdf.numPages; i++) { 37 | 38 | pdf.getPage(i).then(function(page) { 39 | 40 | // calculate scale according to the box size 41 | var boxWidth = node.clientWidth; 42 | var pdfWidth = page.getViewport(1).width; 43 | var scale = boxWidth / pdfWidth; 44 | var viewport = page.getViewport(scale); 45 | 46 | // set canvas for page 47 | var canvas = document.createElement('canvas'); 48 | canvas.id = "page-"+id; id++; 49 | canvas.width = viewport.width; 50 | canvas.height = viewport.height; 51 | node.appendChild(canvas); 52 | 53 | // get context and render page 54 | var context = canvas.getContext('2d'); 55 | var renderContext = { 56 | canvasContext : context, 57 | viewport : viewport 58 | }; 59 | page.render(renderContext); 60 | }); 61 | } 62 | }); 63 | } 64 | 65 | render() { 66 | return ( 67 |
68 |
69 |
70 | ); 71 | } 72 | 73 | componentDidMount() { 74 | this.loadPDF(); 75 | } 76 | 77 | componentDidUpdate() { 78 | this.loadPDF(); 79 | } 80 | } 81 | 82 | module.exports = { SimplePDF: SimplePDF }; 83 | --------------------------------------------------------------------------------