├── .gitignore
├── .npmignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── build
└── image.js
├── gulpfile.js
├── index.js
├── package.json
└── src
└── image.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | .DS_Store
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .gitignore
2 | node_modules
3 | src
4 | test
5 | gulpfile.js
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - "0.12"
5 |
6 | before_script:
7 | - "npm install -g gulp"
8 | - "npm install"
9 |
10 | script:
11 | - "npm run build"
12 |
13 | notifications:
14 | email:
15 | - ram@hiddentao.com
16 |
17 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribute to react-image-holder
2 |
3 | This guide guidelines for those wishing to contribute to react-image-holder.
4 |
5 | ## Contributor license agreement
6 |
7 | By submitting code as an individual or as an entity you agree that your code is licensed the same as react-image-holder.
8 |
9 | ## Issues and pull requests
10 |
11 | Issues and merge requests should be in English and contain appropriate language for audiences of all ages.
12 |
13 | We will only accept a merge requests which meets the following criteria:
14 |
15 | * Includes proper tests and all tests pass (unless it contains a test exposing a bug in existing code)
16 | * Can be merged without problems (if not please use: `git rebase master`)
17 | * Does not break any existing functionality
18 | * Fixes one specific issue or implements one specific feature (do not combine things, send separate merge requests if needed)
19 | * Keeps the code base clean and well structured
20 | * Contains functionality we think other users will benefit from too
21 | * Doesn't add unnessecary configuration options since they complicate future changes
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 [Ramesh Nair](http://www.hiddentao.com/)
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-image-holder
2 |
3 | [](http://travis-ci.org/hiddentao/react-image-holder)
4 |
5 | An `
` component for React which can render _real_ images as well use an offline _placeholder_ as a fallback if need be.
6 |
7 | All placeholders are rendered using [holder.js](https://github.com/imsky/holder), meaning they will work even when offline. You can even configure the component to always render a placeholder for all its instances.
8 |
9 | [View demo](https://hiddentao.github.io/react-image-holder)
10 |
11 | ## Installation
12 |
13 | ```bash
14 | $ npm install react-image-holder
15 | ```
16 |
17 | ## Examples
18 |
19 | All examples assume you have `require()`-d the component:
20 |
21 | ```js
22 | var Img = require('react-image-holder');
23 | ```
24 |
25 | **A real image**
26 |
27 | ```js
28 | var realImage = (
29 |
30 | );
31 | ```
32 |
33 | Output:
34 |
35 | ```html
36 |
37 | ```
38 |
39 | **Additional attributes**
40 |
41 | ```js
42 | var realImage = (
43 |
47 | );
48 | ```
49 |
50 | Output:
51 |
52 | ```html
53 |
54 | ```
55 |
56 |
57 | **Use a placeholder instead**
58 |
59 | ```js
60 | var realImage = (
61 |
67 | );
68 | ```
69 |
70 | Output:
71 |
72 | ```html
73 |
74 | ```
75 |
76 | _Holder.js then processes the above tag and renders a placeholder_.
77 |
78 |
79 |
80 | **Setting placeholder properties**
81 |
82 | ```js
83 | var placeholderProps = {
84 | theme: 'blue',
85 | size: 50,
86 | auto: false,
87 | };
88 |
89 | var realImage = (
90 |
96 | );
97 | ```
98 |
99 | Output:
100 |
101 | ```html
102 |
103 | ```
104 |
105 | _See [holder.js property list](https://github.com/imsky/holder) for all available properties_.
106 |
107 |
108 | **Global placeholders**
109 |
110 | Rather than passing the `usePlaceholder` property to each instance of the component you can
111 | also set this property's default value at the start of your app:
112 |
113 | ```js
114 | Img.DEFAULT_PROPS.usePlaceholder = true;
115 | ```
116 |
117 | Now all subsequent instances of the component will automatically use a
118 | placeholder image. And you can still override the setting on per-instance basis!
119 |
120 |
121 | ## Building
122 |
123 | ```bash
124 | $ npm install
125 | $ npm run build
126 | ```
127 |
128 | ## Contributing
129 |
130 | Contributions are welcome! Please see [CONTRIBUTING.md](https://github.com/hiddentao/react-image-holder/blob/master/CONTRIBUTING.md).
131 |
132 |
133 | ## License
134 |
135 | MIT - see [LICENSE.md](https://github.com/hiddentao/react-image-holder/blob/master/LICENSE.md)
--------------------------------------------------------------------------------
/build/image.js:
--------------------------------------------------------------------------------
1 | "use strict";var _extends=Object.assign||function(e){for(var r=1;r",
21 | "license": "MIT",
22 | "bugs": {
23 | "url": "https://github.com/hiddentao/react-image-holder/issues"
24 | },
25 | "homepage": "https://github.com/hiddentao/react-image-holder",
26 | "devDependencies": {
27 | "gulp": "~3.8.1",
28 | "gulp-babel": "~5.2.0",
29 | "gulp-uglify": "~0.3.0",
30 | "run-sequence": "~0.3.6"
31 | },
32 | "peerDependencies": {
33 | "react": ">=0.14.7",
34 | "react-dom": "*"
35 | },
36 | "dependencies": {
37 | "holderjs": "~2.8.1",
38 | "lodash": "~4.11.1",
39 | "query-string": "~2.4.0"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/image.js:
--------------------------------------------------------------------------------
1 | var omit = require('lodash/omit'),
2 | React = require('react'),
3 | ReactDOM = require('react-dom'),
4 | qs = require('query-string');
5 |
6 |
7 | var DEFAULT_PROPS = {
8 | usePlaceholder: false,
9 | placeholder: {
10 | /* See https://github.com/imsky/holder#placeholder-options for info on more props and themes */
11 | theme: 'vine',
12 | auto: true,
13 | },
14 | };
15 |
16 |
17 | var Img = React.createClass({
18 | propTypes: {
19 | src: React.PropTypes.string.isRequired,
20 | usePlaceholder: React.PropTypes.bool,
21 | placeholder: React.PropTypes.object,
22 | },
23 |
24 | getDefaultProps: function() {
25 | return DEFAULT_PROPS;
26 | },
27 |
28 | render: function() {
29 | let props = this.props;
30 |
31 | let { width, height } = this.props;
32 |
33 | let attrs = omit(props, 'src', 'usePlaceholder', 'placeholder');
34 |
35 | // placeholder
36 | if (props.usePlaceholder) {
37 | let query = qs.stringify(props.placeholder);
38 |
39 | let src = `holder.js/${width}x${height}?${query}`;
40 |
41 | let placeholderAttrs = omit(attrs, 'width', 'height');
42 |
43 | return (
44 |
45 | );
46 | }
47 | // real
48 | else {
49 | return (
50 |
51 | );
52 | }
53 | },
54 |
55 | componentDidMount: function() {
56 | this._initPlaceholderImage();
57 | },
58 |
59 |
60 | componentDidUpdate: function(oldProps) {
61 | this._initPlaceholderImage();
62 | },
63 |
64 |
65 | _initPlaceholderImage: function() {
66 | if (!(typeof window != 'undefined' && window.document)) {
67 | return;
68 | }
69 | if (!this.props.usePlaceholder) {
70 | return;
71 | }
72 |
73 | let node = ReactDOM.findDOMNode(this.refs.placeholder);
74 |
75 | // require in here to prevent errors during server-side rendering
76 | let Holder = require('holderjs');
77 |
78 | Holder.run({
79 | domain: 'holder.js',
80 | images: node,
81 | object: null,
82 | bgnodes: null,
83 | stylenodes: null,
84 | });
85 | },
86 |
87 | });
88 |
89 |
90 | // make
91 | Img.DEFAULT_PROPS = DEFAULT_PROPS;
92 |
93 |
94 | module.exports = Img;
95 |
--------------------------------------------------------------------------------