├── index.js
├── .gitignore
├── gulpfile.js
├── README.md
├── LICENSE
├── package.json
├── lib
└── BackgroundImage.js
└── dist
└── BackgroundImage.js
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./dist/BackgroundImage.js');
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # exclude osx meta-files
2 | .DS_Store
3 | .npmignore
4 | .npmrc
5 | # exclude all node_modules
6 | node_modules/
7 |
8 | # ignore npm error logs
9 | npm-debug.log
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var path = require('path');
3 | var babel = require('gulp-babel');
4 |
5 | function build() {
6 | return gulp
7 | .src(['lib/**/*.js'])
8 | .pipe(babel({
9 | optional: ['runtime', 'es7.decorators']
10 | }))
11 | .pipe(gulp.dest(__dirname + '/dist'));
12 | }
13 |
14 | function watch() {
15 | gulp.watch(['lib/**/*.js'], ['build']);
16 | build();
17 | }
18 |
19 | gulp.task('build', build);
20 | gulp.task('watch', watch);
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-background-image-loader
2 | Allows you display a placeholder image while the actual background image loads
3 |
4 | ## Installation
5 | `npm install react-background-image-loader --save`
6 |
7 | In order to build / modify the component locally just run `npm watch`.
8 |
9 | ## Usage
10 | ```javascript
11 | import React from 'react';
12 | import BackgroundImage from 'react-background-image-loader';
13 |
14 | export default (props) => {
15 | const {source, ...otherProps} = props;
16 | const localImage = '/path/to/local/asset';
17 |
18 | return(
19 |
20 |
21 | Some more markup
22 |
23 |
24 |
25 | );
26 | }
27 | ```
28 |
29 | ## Props
30 | prop | type | notes
31 | ------------|--------|-----------------------------------------
32 | src | string | Remote image to be loaded
33 | placeholder | string | Local image to be immediately displayed
34 |
35 | ## License
36 |
37 | MIT License
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Jed Watson
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.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-background-image-loader",
3 | "version": "0.0.5",
4 | "description": "This package allows you to display a placeholder image while the actual background image loads",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "build": "gulp build",
9 | "watch": "gulp watch"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/danieltimpone/react-background-image-loader.git"
14 | },
15 | "keywords": [
16 | "react",
17 | "image",
18 | "loader",
19 | "background"
20 | ],
21 | "author": "Daniel Timpone",
22 | "license": "ISC",
23 | "bugs": {
24 | "url": "https://github.com/danieltimpone/react-background-image-loader/issues"
25 | },
26 | "homepage": "https://github.com/danieltimpone/react-background-image-loader#readme",
27 | "dependencies": {
28 | "prop-types": "^15.5.10",
29 | "react": "^15.5.4"
30 | },
31 | "devDependencies": {
32 | "babel-core": "^5.8.22",
33 | "babel-loader": "^5.3.2",
34 | "babel-runtime": "^5.8.25",
35 | "gulp": "^3.8.11",
36 | "gulp-babel": "^5.3.0"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/BackgroundImage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | /*
4 | This component displays a placeholder image that is hosted locally
5 | while it waits for a remote image to load.
6 |
7 | Usage:
8 | {...child components}
9 |
10 | */
11 | export default class BackgroundLoader extends React.Component {
12 | static get propTypes () {
13 | return {
14 | src: PropTypes.string.isRequired,
15 | placeholder: PropTypes.string.isRequired,
16 | className: PropTypes.string,
17 | style: PropTypes.object,
18 | children: PropTypes.node,
19 | };
20 | }
21 |
22 | constructor(props) {
23 | super(props);
24 |
25 | this.state = {
26 | loaded: false,
27 | error: false,
28 | };
29 |
30 | this.handleLoad = this.handleLoad.bind(this);
31 | this.handleError = this.handleError.bind(this);
32 | }
33 |
34 | componentDidMount() {
35 | // Making this a global so it can be later
36 | // nullified when the component unmounts
37 | this.image = new Image();
38 |
39 | this.image.src = this.props.src;
40 | this.image.onload = this.handleLoad;
41 | this.image.onerror = this.handleError;
42 | }
43 |
44 | shouldComponentUpdate(nextState, nextProps) {
45 | return !this.state.loaded;
46 | }
47 |
48 | componentWillUnmount() {
49 | this.image.onerror = null;
50 | this.image.onload = null;
51 | this.image = null;
52 | }
53 |
54 | handleLoad(e) {
55 | this.setState({
56 | loaded: true,
57 | });
58 | }
59 |
60 | handleError(e) {
61 | console.error('Failed to load ', this.props.src);
62 |
63 | this.setState({
64 | error: true,
65 | });
66 | }
67 |
68 | render() {
69 | const {src, placeholder, children, ...props} = this.props;
70 | const source = !this.state.loaded || this.state.error ? placeholder : src;
71 |
72 | return (
73 |
74 | {children}
75 |
76 | );
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/dist/BackgroundImage.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _get = require('babel-runtime/helpers/get')['default'];
4 |
5 | var _inherits = require('babel-runtime/helpers/inherits')['default'];
6 |
7 | var _createClass = require('babel-runtime/helpers/create-class')['default'];
8 |
9 | var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default'];
10 |
11 | var _objectWithoutProperties = require('babel-runtime/helpers/object-without-properties')['default'];
12 |
13 | var _extends = require('babel-runtime/helpers/extends')['default'];
14 |
15 | var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
16 |
17 | Object.defineProperty(exports, '__esModule', {
18 | value: true
19 | });
20 |
21 | var _react = require('react');
22 |
23 | var _react2 = _interopRequireDefault(_react);
24 |
25 | var _propTypes = require('prop-types');
26 |
27 | var _propTypes2 = _interopRequireDefault(_propTypes);
28 |
29 | /*
30 | This component displays a placeholder image that is hosted locally
31 | while it waits for a remote image to load.
32 |
33 | Usage:
34 | {...child components}
35 |
36 | */
37 |
38 | var BackgroundLoader = (function (_React$Component) {
39 | _inherits(BackgroundLoader, _React$Component);
40 |
41 | _createClass(BackgroundLoader, null, [{
42 | key: 'propTypes',
43 | get: function get() {
44 | return {
45 | src: _propTypes2['default'].string.isRequired,
46 | placeholder: _propTypes2['default'].string.isRequired,
47 | className: _propTypes2['default'].string,
48 | style: _propTypes2['default'].object,
49 | children: _propTypes2['default'].node
50 | };
51 | }
52 | }]);
53 |
54 | function BackgroundLoader(props) {
55 | _classCallCheck(this, BackgroundLoader);
56 |
57 | _get(Object.getPrototypeOf(BackgroundLoader.prototype), 'constructor', this).call(this, props);
58 |
59 | this.state = {
60 | loaded: false,
61 | error: false
62 | };
63 |
64 | this.handleLoad = this.handleLoad.bind(this);
65 | this.handleError = this.handleError.bind(this);
66 | }
67 |
68 | _createClass(BackgroundLoader, [{
69 | key: 'componentDidMount',
70 | value: function componentDidMount() {
71 | // Making this a global so it can be later
72 | // nullified when the component unmounts
73 | this.image = new Image();
74 |
75 | this.image.src = this.props.src;
76 | this.image.onload = this.handleLoad;
77 | this.image.onerror = this.handleError;
78 | }
79 | }, {
80 | key: 'shouldComponentUpdate',
81 | value: function shouldComponentUpdate(nextState, nextProps) {
82 | return !this.state.loaded;
83 | }
84 | }, {
85 | key: 'componentWillUnmount',
86 | value: function componentWillUnmount() {
87 | this.image.onerror = null;
88 | this.image.onload = null;
89 | this.image = null;
90 | }
91 | }, {
92 | key: 'handleLoad',
93 | value: function handleLoad(e) {
94 | this.setState({
95 | loaded: true
96 | });
97 | }
98 | }, {
99 | key: 'handleError',
100 | value: function handleError(e) {
101 | console.error('Failed to load ', this.props.src);
102 |
103 | this.setState({
104 | error: true
105 | });
106 | }
107 | }, {
108 | key: 'render',
109 | value: function render() {
110 | var _props = this.props;
111 | var src = _props.src;
112 | var placeholder = _props.placeholder;
113 | var children = _props.children;
114 |
115 | var props = _objectWithoutProperties(_props, ['src', 'placeholder', 'children']);
116 |
117 | var source = !this.state.loaded || this.state.error ? placeholder : src;
118 |
119 | return _react2['default'].createElement(
120 | 'div',
121 | _extends({ style: { backgroundImage: 'url(' + source + ')' } }, props),
122 | children
123 | );
124 | }
125 | }]);
126 |
127 | return BackgroundLoader;
128 | })(_react2['default'].Component);
129 |
130 | exports['default'] = BackgroundLoader;
131 | module.exports = exports['default'];
--------------------------------------------------------------------------------