Skip to content

Commit 662389b

Browse files
committed
Add a placeholderSrc prop to LazyLoadImage
1 parent c89f2a3 commit 662389b

File tree

2 files changed

+77
-8
lines changed

2 files changed

+77
-8
lines changed

src/components/LazyLoadImage.jsx

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import { PropTypes } from 'prop-types';
23

34
import LazyLoadComponent from './LazyLoadComponent.jsx';
45

@@ -9,11 +10,11 @@ class LazyLoadImage extends React.Component {
910

1011
render() {
1112
const { afterLoad, beforeLoad, delayMethod, delayTime, placeholder,
12-
scrollPosition, threshold, visibleByDefault, ...imgProps } = this.props;
13+
placeholderSrc, scrollPosition, threshold, visibleByDefault,
14+
...imgProps } = this.props;
1315

14-
return (
16+
const lazyLoadComponent = (
1517
<LazyLoadComponent
16-
afterLoad={afterLoad}
1718
beforeLoad={beforeLoad}
1819
className={this.props.className}
1920
delayMethod={delayMethod}
@@ -25,10 +26,31 @@ class LazyLoadImage extends React.Component {
2526
threshold={threshold}
2627
visibleByDefault={visibleByDefault}
2728
width={this.props.width}>
28-
<img {...imgProps} />
29+
<img onLoad={afterLoad} {...imgProps} />
2930
</LazyLoadComponent>
3031
);
32+
33+
if (!placeholderSrc || visibleByDefault) {
34+
return lazyLoadComponent;
35+
}
36+
37+
return (
38+
<span style={{
39+
backgroundImage: 'url( ' + placeholderSrc + ')',
40+
backgroundSize: '100% 100%',
41+
color: 'transparent',
42+
display: 'inline-block',
43+
height: this.props.height,
44+
width: this.props.width
45+
}}>
46+
{lazyLoadComponent}
47+
</span>
48+
);
3149
}
3250
}
3351

52+
LazyLoadImage.propTypes = {
53+
placeholderSrc: PropTypes.string
54+
};
55+
3456
export default LazyLoadImage;

src/components/LazyLoadImage.spec.js

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ configure({ adapter: new Adapter() });
1010

1111
const {
1212
findRenderedComponentWithType,
13-
findRenderedDOMComponentWithTag
13+
findRenderedDOMComponentWithTag,
14+
scryRenderedDOMComponentsWithTag,
15+
Simulate
1416
} = ReactTestUtils;
1517

1618
describe('LazyLoadImage', function() {
1719
it('renders a LazyLoadComponent with the correct props', function() {
1820
const props = {
19-
afterLoad: () => null,
2021
beforeLoad: () => null,
2122
delayMethod: 'debounce',
2223
delayTime: 600,
@@ -28,7 +29,6 @@ describe('LazyLoadImage', function() {
2829
};
2930
const lazyLoadImage = mount(
3031
<LazyLoadImage
31-
afterLoad={props.afterLoad}
3232
beforeLoad={props.beforeLoad}
3333
delayMethod={props.delayMethod}
3434
delayTime={props.delayTime}
@@ -42,7 +42,6 @@ describe('LazyLoadImage', function() {
4242
const lazyLoadComponent = findRenderedComponentWithType(lazyLoadImage.instance(), LazyLoadComponent);
4343
const img = findRenderedDOMComponentWithTag(lazyLoadImage.instance(), 'img');
4444

45-
expect(lazyLoadComponent.props.afterLoad).toEqual(props.afterLoad);
4645
expect(lazyLoadComponent.props.beforeLoad).toEqual(props.beforeLoad);
4746
expect(lazyLoadComponent.props.delayMethod).toEqual(props.delayMethod);
4847
expect(lazyLoadComponent.props.delayTime).toEqual(props.delayTime);
@@ -52,4 +51,52 @@ describe('LazyLoadImage', function() {
5251
expect(lazyLoadComponent.props.visibleByDefault).toEqual(props.visibleByDefault);
5352
expect(img.src).toEqual(props.src);
5453
});
54+
55+
it('calls afterLoad when img triggers onLoad', function() {
56+
const afterLoad = jest.fn();
57+
const lazyLoadImage = mount(
58+
<LazyLoadImage
59+
afterLoad={afterLoad} />
60+
);
61+
62+
const img = findRenderedDOMComponentWithTag(lazyLoadImage.instance(), 'img');
63+
64+
Simulate.load(img);
65+
66+
expect(afterLoad).toHaveBeenCalledTimes(1);
67+
});
68+
69+
it('doesn\'t render placeholder background when not defined', function() {
70+
const lazyLoadImage = mount(
71+
<LazyLoadImage />
72+
);
73+
74+
const span = scryRenderedDOMComponentsWithTag(lazyLoadImage.instance(), 'span');
75+
76+
expect(span.length).toEqual(0);
77+
});
78+
79+
it('renders placeholder background when defined', function() {
80+
const lazyLoadImage = mount(
81+
<LazyLoadImage
82+
placeholderSrc='lorem-ipsum.jpg'
83+
visibleByDefault={false} />
84+
);
85+
86+
const span = scryRenderedDOMComponentsWithTag(lazyLoadImage.instance(), 'span');
87+
88+
expect(span.length).toEqual(1);
89+
});
90+
91+
it('doesn\'t render placeholder background when visibleByDefault is true', function() {
92+
const lazyLoadImage = mount(
93+
<LazyLoadImage
94+
placeholderSrc='lorem-ipsum.jpg'
95+
visibleByDefault={true} />
96+
);
97+
98+
const span = scryRenderedDOMComponentsWithTag(lazyLoadImage.instance(), 'span');
99+
100+
expect(span.length).toEqual(0);
101+
});
55102
});

0 commit comments

Comments
 (0)