diff --git a/.all-contributorsrc b/.all-contributorsrc
index fc422a1..d50495d 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -72,6 +72,17 @@
"contributions": [
"doc"
]
+ },
+ {
+ "login": "GeKorm",
+ "name": "George Kormaris",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/6104345?v=4",
+ "profile": "http://www.gekorm.com",
+ "contributions": [
+ "code",
+ "doc",
+ "ideas"
+ ]
}
],
"repoType": "github"
diff --git a/README.md b/README.md
index fb80361..a2e49fa 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
[![downloads][downloads-badge]][npmtrends]
[![MIT License][license-badge]][license]
-[](#contributors)
+[](#contributors)
[![PRs Welcome][prs-badge]][prs]
[![Code of Conduct][coc-badge]][coc]
@@ -48,6 +48,8 @@ Read the [introduction](introduction.md).
- [theme](#theme)
- [threshold](#threshold)
- [width](#width)
+ - [observer](#observer)
+ - [children](#children)
- [Other Solutions](#other-solutions)
- [Contributors](#contributors)
- [LICENSE](#license)
@@ -73,6 +75,7 @@ Example for create-react-app (you need v2 for macros) based project
```js
import React from 'react'
import lqip from 'lqip.macro'
+import Waypoint from 'react-waypoint'
import IdealImage from 'react-ideal-image'
import image from './images/doggo.jpg'
@@ -85,6 +88,7 @@ const App = () => (
alt="doggo"
width={3500}
height={2095}
+ observer={Waypoint}
/>
)
```
@@ -217,6 +221,33 @@ Tells how much to wait in milliseconds until consider the download to be slow.
Width of the image in px.
+### observer
+
+> `function({onEnter, onLeave, children})` | optional
+
+A visibility observer component, like react-waypoint, used for lazy-loading.
+
+### children
+
+> `function({onEnter, onLeave, children}) | React.Element` | optional
+
+Observer, used instead of the `observer` prop. Can either be a render prop or a React element
+
+```js
+
+ // onEnter and onLeave are passed automatically
+
+```
+
+If neither `observer` nor `children` is passed, the image will be treated as visible in the viewport
+
## Other Solutions
- [react-progressive-image](https://github.com/FormidableLabs/react-progressive-image)
@@ -239,7 +270,7 @@ Thanks goes to these people ([emoji key][emojis]):
| [
stereobooster](https://github.com/stereobooster)
[💻](https://github.com/stereobooster/react-ideal-image/commits?author=stereobooster "Code") [📖](https://github.com/stereobooster/react-ideal-image/commits?author=stereobooster "Documentation") [🚇](#infra-stereobooster "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/stereobooster/react-ideal-image/commits?author=stereobooster "Tests") | [
Ivan Babak](https://github.com/sompylasar)
[📖](https://github.com/stereobooster/react-ideal-image/commits?author=sompylasar "Documentation") | [
Arun Kumar](https://github.com/palerdot)
[📖](https://github.com/stereobooster/react-ideal-image/commits?author=palerdot "Documentation") | [
Andrew Lisowski](http://hipstersmoothie.com)
[💻](https://github.com/stereobooster/react-ideal-image/commits?author=hipstersmoothie "Code") | [
Timothy Vernon](https://github.com/tvthatsme)
[⚠️](https://github.com/stereobooster/react-ideal-image/commits?author=tvthatsme "Tests") | [
vishalShinde](http://vs1682.github.io)
[📖](https://github.com/stereobooster/react-ideal-image/commits?author=vs1682 "Documentation") | [
Evgeniy Kumachev](https://github.com/EvgeniyKumachev)
[📖](https://github.com/stereobooster/react-ideal-image/commits?author=EvgeniyKumachev "Documentation") |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
-
+| [
George Kormaris](http://www.gekorm.com)
[💻](https://github.com/stereobooster/react-ideal-image/commits?author=GeKorm "Code") [📖](https://github.com/stereobooster/react-ideal-image/commits?author=GeKorm "Documentation") [🤔](#ideas-GeKorm "Ideas, Planning, & Feedback") |
This project follows the [all-contributors][all-contributors] specification.
diff --git a/src/components/IdealImage/index.js b/src/components/IdealImage/index.js
index 778de3e..ec201ce 100644
--- a/src/components/IdealImage/index.js
+++ b/src/components/IdealImage/index.js
@@ -1,6 +1,5 @@
-import React, {Component} from 'react'
+import React, {Component, cloneElement} from 'react'
import PropTypes from 'prop-types'
-import Waypoint from 'react-waypoint'
import Media from '../Media'
import {icons, loadStates} from '../constants'
import {xhrLoader, imageLoader, timeout, combineCancel} from '../loaders'
@@ -162,6 +161,10 @@ export default class IdealImage extends Component {
icons: PropTypes.object.isRequired,
/** theme object - CSS Modules or React styles */
theme: PropTypes.object.isRequired,
+ /** visibility observer component, like react-waypoint */
+ observer: PropTypes.func,
+ /** visibility observer component, like react-waypoint */
+ children: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
}
static defaultProps = {
@@ -320,8 +323,10 @@ export default class IdealImage extends Component {
...this.state,
size: pickedSrc.size,
})
- this.setState({pickedSrc, shouldAutoDownload, url})
- if (shouldAutoDownload) this.load(false)
+ this.setState(
+ {pickedSrc, shouldAutoDownload, url},
+ shouldAutoDownload ? () => this.load(false) : undefined,
+ )
}
onLeave = () => {
@@ -332,20 +337,41 @@ export default class IdealImage extends Component {
}
render() {
+ const {children, observer} = this.props
const icon = this.props.getIcon(this.state)
const message = this.props.getMessage(icon, this.state)
- return (
-
- this.setState({dimensions})}
- message={message}
- />
-
+ const observerMethod = observer || children
+ const media = (
+
+ this.setState(
+ {dimensions},
+ observerMethod ? undefined : this.onEnter,
+ )
+ }
+ message={message}
+ />
)
+
+ if (observer || typeof children === 'function') {
+ return (
+
+ {media}
+
+ )
+ } else if (children) {
+ return cloneElement(
+ children,
+ {onEnter: this.onEnter, onLeave: this.onLeave},
+ media,
+ )
+ } else {
+ return media
+ }
}
}