Socket
Socket
Sign inDemoInstall

react-lazy-images

Package Overview
Dependencies
12
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.9.1 to 1.0.0-rc.1

src/react-intersection-observer.d.ts

5

dist/fallbackUtils.d.ts

@@ -1,3 +0,2 @@

/// <reference types="react" />
import React from 'react';
import React from "react";
/** Display this if JS is disabled

@@ -19,2 +18,2 @@ * @see https://github.com/facebook/react/issues/11423 for why

*/
export declare const Fallback: (fallback: React.Component<{}, {}, never>) => JSX.Element;
export declare const Fallback: (fallback: React.ReactElement<{}>) => JSX.Element;

4

dist/index.d.ts

@@ -1,2 +0,2 @@

export * from './LazyImage';
export * from './LazyImageFull';
export * from "./LazyImage";
export * from "./LazyImageFull";

@@ -1,4 +0,3 @@

/// <reference types="react" />
import React from 'react';
import { CommonLazyImageProps } from './LazyImageFull';
import React from "react";
import { CommonLazyImageProps, ImageProps } from "./LazyImageFull";
/**

@@ -8,6 +7,8 @@ * Valid props for LazyImage

export interface LazyImageRenderPropArgs {
src?: string;
srcSet?: string;
alt?: string;
imageProps: ImageProps;
}
export interface RefArg {
/** When not loading eagerly, a ref to bind to the DOM element. This is needed for the intersection calculation to work. */
ref?: React.RefObject<any>;
}
export interface LazyImageProps extends CommonLazyImageProps {

@@ -19,3 +20,3 @@ /** Component to display once image has loaded */

*/
placeholder?: (args: Pick<LazyImageRenderPropArgs, 'alt'>) => React.ReactElement<{}>;
placeholder: (args: LazyImageRenderPropArgs & RefArg) => React.ReactElement<{}>;
/** Component to display while the image is loading

@@ -22,0 +23,0 @@ * @default placeholder, if defined

@@ -1,13 +0,6 @@

/// <reference types="react" />
import React from 'react';
import React from "react";
/**
* Valid props for LazyImage components
*/
export interface CommonLazyImageProps {
/** The source of the image to load */
src: string;
/** The source set of the image to load */
srcSet?: string;
/** The alt text description of the image you are loading */
alt?: string;
export declare type CommonLazyImageProps = ImageProps & {
/** Whether to skip checking for viewport and always show the 'actual' component

@@ -21,16 +14,31 @@ * @see https://github.com/fpapado/react-lazy-images/#eager-loading--server-side-rendering-ssr

observerProps?: ObserverProps;
}
/** Use the Image Decode API;
* The call to a new HTML <img> element’s decode() function returns a promise, which,
* when fulfilled, ensures that the image can be appended to the DOM without causing
* a decoding delay on the next frame.
* @see: https://www.chromestatus.com/feature/5637156160667648
*/
experimentalDecode?: boolean;
};
/** Valid props for LazyImageFull */
export interface LazyImageFullProps extends CommonLazyImageProps {
/** Children should be either a function or a node */
children?: ((args: LazyImageFullRenderPropArgs) => React.ReactNode) | React.ReactNode;
/** Render prop boolean indicating inView state */
render?: (args: LazyImageFullRenderPropArgs) => React.ReactNode;
children: (args: RenderCallbackArgs) => React.ReactNode;
}
/** Values that the render props take */
export interface LazyImageFullRenderPropArgs {
export interface RenderCallbackArgs {
imageState: ImageState;
src?: string;
imageProps: ImageProps;
/** When not loading eagerly, a ref to bind to the DOM element. This is needed for the intersection calculation to work. */
ref?: React.RefObject<any>;
}
export interface ImageProps {
/** The source of the image to load */
src: string;
/** The source set of the image to load */
srcSet?: string;
/** The alt text description of the image you are loading */
alt?: string;
/** Sizes descriptor */
sizes?: string;
}

@@ -65,3 +73,3 @@ /** Subset of react-intersection-observer's props */

LoadSuccess = "LoadSuccess",
LoadError = "LoadError",
LoadError = "LoadError"
}

@@ -75,9 +83,11 @@ /**

static displayName: string;
constructor(props: any);
onInView(inView: any): void;
initialState: {
hasBeenInView: boolean;
imageState: ImageState;
};
constructor(props: LazyImageFullProps);
onInView(inView: boolean): void;
onLoadSuccess(): void;
onLoadError(): void;
render(): JSX.Element;
renderLazy(props: any, state: any): JSX.Element;
renderInner(props: any, state: any): JSX.Element;
render(): {} | null | undefined;
}

@@ -1,2 +0,2 @@

import e from"react";var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])};var r=Object.assign||function(e){for(var t,r=1,o=arguments.length;r<o;r++)for(var n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e};function o(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function n(e,t){return e(t={exports:{}},t.exports),t.exports}var a,i=n(function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.observe=n,t.unobserve=a,t.destroy=i;var r=new Map,o=new Map;function n(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{threshold:0},a=arguments[3],i=n.root,c=n.rootMargin,u=n.threshold||0;if(e&&t){var l=c?u.toString()+"_"+c:""+u.toString();i&&(l=a?a+"_"+l:null);var d=l?o.get(l):null;d||(d=new IntersectionObserver(s,n),l&&o.set(l,d));var p={callback:t,visible:!1,options:n,observerId:l,observer:l?void 0:d};return r.set(e,p),d.observe(e),p}}function a(e){if(e){var t=r.get(e);if(t){var n=t.observerId,a=t.observer,i=n?o.get(n):a;i&&i.unobserve(e);var s=!1;n&&r.forEach(function(t,r){t&&t.observerId===n&&r!==e&&(s=!0)}),i&&!s&&(i.disconnect(),o.delete(n)),r.delete(e)}}}function i(){o.forEach(function(e){e.disconnect()}),o.clear(),r.clear()}function s(e){e.forEach(function(e){var t=e.isIntersecting,o=e.intersectionRatio,n=r.get(e.target);if(n&&o>=0){var a=n.options,i=!1;Array.isArray(a.threshold)?i=a.threshold.some(function(e){return n.visible?o>e:o>=e}):void 0!==a.threshold&&(i=n.visible?o>a.threshold:o>=a.threshold),void 0!==t&&(i=i&&t),n.callback&&n.callback(i)}})}t.default={observe:n,unobserve:a,destroy:i}}),s=o(i),c={default:s,__moduleExports:i,observe:i.observe,unobserve:i.unobserve,destroy:i.destroy},u=c&&s||c,l=o(n(function(t,r){Object.defineProperty(r,"__esModule",{value:!0});var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e},n=function(){function e(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,r,o){return r&&e(t.prototype,r),o&&e(t,o),t}}(),a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(e);function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}var s=function(e){function t(){var e,r,o;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);for(var n=arguments.length,a=Array(n),s=0;s<n;s++)a[s]=arguments[s];return r=o=i(this,(e=t.__proto__||Object.getPrototypeOf(t)).call.apply(e,[this].concat(a))),o.state={inView:!1},o.node=null,o.handleNode=function(e){o.node&&(0,u.unobserve)(o.node),o.node=e,o.observeNode(),o.props.innerRef&&o.props.innerRef(e)},o.handleChange=function(e){o.setState({inView:e}),o.props.onChange&&o.props.onChange(e)},i(o,r)}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,a.Component),n(t,[{key:"componentDidUpdate",value:function(e,t){e.rootMargin===this.props.rootMargin&&e.root===this.props.root&&e.threshold===this.props.threshold||((0,u.unobserve)(this.node),this.observeNode()),t.inView!==this.state.inView&&this.state.inView&&this.props.triggerOnce&&((0,u.unobserve)(this.node),this.node=null)}},{key:"componentWillUnmount",value:function(){this.node&&((0,u.unobserve)(this.node),this.node=null)}},{key:"observeNode",value:function(){if(this.node){var e=this.props;(0,u.observe)(this.node,this.handleChange,{threshold:e.threshold,root:e.root,rootMargin:e.rootMargin},e.rootId)}}},{key:"render",value:function(){var e=this.props,t=e.children,r=e.render,n=e.tag,i=function(e,t){var r={};for(var o in e)t.indexOf(o)>=0||Object.prototype.hasOwnProperty.call(e,o)&&(r[o]=e[o]);return r}(e,["children","render","tag","innerRef","triggerOnce","threshold","root","rootId","rootMargin"]),s=this.state.inView;return a.createElement(n,o({},i,{ref:this.handleNode}),"function"==typeof r?r(s):null,"function"==typeof t?t(s):t)}}]),t}();s.defaultProps={tag:"div",threshold:0,triggerOnce:!1},r.default=s}));!function(e){e.NotAsked="NotAsked",e.Loading="Loading",e.LoadSuccess="LoadSuccess",e.LoadError="LoadError"}(a||(a={}));var d=function(o){function n(e){var t=o.call(this,e)||this;return t.state={hasBeenInView:!1,imageState:a.NotAsked},t.renderInner=t.renderInner.bind(t),t.renderLazy=t.renderLazy.bind(t),t.onInView=t.onInView.bind(t),t.onLoadSuccess=t.onLoadSuccess.bind(t),t.onLoadError=t.onLoadError.bind(t),t}return function(e,r){function o(){this.constructor=e}t(e,r),e.prototype=null===r?Object.create(r):(o.prototype=r.prototype,new o)}(n,o),n.prototype.onInView=function(e){!0===e&&(this.props.src?(this.setState(function(e,t){return r({},e,{imageState:a.Loading})}),p({src:this.props.src,srcSet:this.props.srcSet,alt:this.props.alt}).then(this.onLoadSuccess).catch(this.onLoadError)):this.setState(function(e,t){return r({},e,{imageState:a.LoadSuccess})}))},n.prototype.onLoadSuccess=function(){this.setState(function(e,t){return r({},e,{imageState:a.LoadSuccess})})},n.prototype.onLoadError=function(){this.setState(function(e,t){return r({},e,{imageState:a.LoadError})})},n.prototype.render=function(){return this.props.loadEagerly?this.renderInner(this.props,{imageState:a.LoadSuccess}):this.renderLazy(this.props,this.state)},n.prototype.renderLazy=function(t,o){return e.createElement(l,r({rootMargin:"50px 0px",threshold:.01},t.observerProps,{onChange:this.onInView,triggerOnce:!0}),this.renderInner(t,o))},n.prototype.renderInner=function(t,r){var o=t.src,n=t.srcSet,a=t.alt,i=t.render,s=t.children,c=r.imageState;return e.createElement(e.Fragment,null,"function"==typeof i?i({src:o,srcSet:n,alt:a,imageState:c}):"function"==typeof s?s({src:o,srcSet:n,alt:a,imageState:c}):null)},n.displayName="LazyImageFull",n}(e.Component),p=function(e){var t=e.src,r=e.srcSet,o=e.alt;return new Promise(function(e,n){var a=new Image;r&&(a.srcset=r),o&&(a.alt=o),a.src=t,a.onload=e,a.onerror=n})},f=function(t){var o=t.actual,n=t.placeholder,i=t.loading,s=t.error,c=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++)t.indexOf(o[n])<0&&(r[o[n]]=e[o[n]])}return r}(t,["actual","placeholder","loading","error"]);return e.createElement(d,r({},c),function(e){var t=e.src,r=e.srcSet,c=e.alt;switch(e.imageState){case a.NotAsked:return!!n&&n({alt:c});case a.Loading:return i?i():!!n&&n({alt:c});case a.LoadSuccess:return o({src:t,alt:c,srcSet:r});case a.LoadError:return s?s():o({src:t,alt:c,srcSet:r})}})};f.displayName="LazyImage";export{f as LazyImage,a as ImageState,d as LazyImageFull};
import e from"react";import t from"react-intersection-observer";var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};var o,n=function(){return(n=Object.assign||function(e){for(var t,r=1,o=arguments.length;r<o;r++)for(var n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e}).apply(this,arguments)};function a(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++)t.indexOf(o[n])<0&&(r[o[n]]=e[o[n]])}return r}!function(e){e.NotAsked="NotAsked",e.Loading="Loading",e.LoadSuccess="LoadSuccess",e.LoadError="LoadError"}(o||(o={}));var i=function(i){function c(e){var t=i.call(this,e)||this;return t.initialState={hasBeenInView:!1,imageState:o.NotAsked},t.state=t.initialState,t.onInView=t.onInView.bind(t),t.onLoadSuccess=t.onLoadSuccess.bind(t),t.onLoadError=t.onLoadError.bind(t),t}return function(e,t){function o(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(o.prototype=t.prototype,new o)}(c,i),c.prototype.onInView=function(e){!0===e&&(this.props.src?(this.setState(function(e,t){return n({},e,{imageState:o.Loading})}),s({src:this.props.src,srcSet:this.props.srcSet,alt:this.props.alt,sizes:this.props.sizes},this.props.experimentalDecode).then(this.onLoadSuccess).catch(this.onLoadError)):this.setState(function(e,t){return n({},e,{imageState:o.LoadSuccess})}))},c.prototype.onLoadSuccess=function(){this.setState(function(e,t){return n({},e,{imageState:o.LoadSuccess})})},c.prototype.onLoadError=function(){this.setState(function(e,t){return n({},e,{imageState:o.LoadError})})},c.prototype.render=function(){var r=this,i=this.props,s=i.children,c=i.loadEagerly,p=i.observerProps,u=a(i,["children","loadEagerly","observerProps","experimentalDecode"]);return c?s({imageState:o.LoadSuccess,imageProps:u}):e.createElement(t,n({rootMargin:"50px 0px",threshold:.01},p,{onChange:this.onInView,triggerOnce:!0}),function(e){return s({imageState:r.state.imageState,imageProps:u,ref:e.ref})})},c.displayName="LazyImageFull",c}(e.Component),s=function(e,t){var r=e.src,o=e.srcSet,n=e.alt,a=e.sizes;return void 0===t&&(t=!1),new Promise(function(e,i){var s=new Image;o&&(s.srcset=o),n&&(s.alt=n),a&&(s.sizes=a),s.src=r,t&&"decode"in s?s.decode().then(function(){return e()}).catch(function(e){return i(e)}):(s.onload=e,s.onerror=i)})},c=function(t){var r=t.actual,s=t.placeholder,c=t.loading,p=t.error,u=a(t,["actual","placeholder","loading","error"]);return e.createElement(i,n({},u),function(e){var t=e.imageProps,n=e.ref;switch(e.imageState){case o.NotAsked:return!!s&&s({imageProps:t,ref:n});case o.Loading:return c?c():!!s&&s({imageProps:t,ref:n});case o.LoadSuccess:return r({imageProps:t});case o.LoadError:return p?p():r({imageProps:t})}})};c.displayName="LazyImage";export{c as LazyImage,o as ImageState,i as LazyImageFull};
//# sourceMappingURL=react-lazy-images.es.js.map

@@ -1,2 +0,2 @@

var e,t=(e=require("react"))&&"object"==typeof e&&"default"in e?e.default:e,r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])};var o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r<o;r++)for(var n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function a(e,t){return e(t={exports:{}},t.exports),t.exports}var s=a(function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.observe=n,t.unobserve=a,t.destroy=s;var r=new Map,o=new Map;function n(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{threshold:0},a=arguments[3],s=n.root,c=n.rootMargin,u=n.threshold||0;if(e&&t){var l=c?u.toString()+"_"+c:""+u.toString();s&&(l=a?a+"_"+l:null);var p=l?o.get(l):null;p||(p=new IntersectionObserver(i,n),l&&o.set(l,p));var d={callback:t,visible:!1,options:n,observerId:l,observer:l?void 0:p};return r.set(e,d),p.observe(e),d}}function a(e){if(e){var t=r.get(e);if(t){var n=t.observerId,a=t.observer,s=n?o.get(n):a;s&&s.unobserve(e);var i=!1;n&&r.forEach(function(t,r){t&&t.observerId===n&&r!==e&&(i=!0)}),s&&!i&&(s.disconnect(),o.delete(n)),r.delete(e)}}}function s(){o.forEach(function(e){e.disconnect()}),o.clear(),r.clear()}function i(e){e.forEach(function(e){var t=e.isIntersecting,o=e.intersectionRatio,n=r.get(e.target);if(n&&o>=0){var a=n.options,s=!1;Array.isArray(a.threshold)?s=a.threshold.some(function(e){return n.visible?o>e:o>=e}):void 0!==a.threshold&&(s=n.visible?o>a.threshold:o>=a.threshold),void 0!==t&&(s=s&&t),n.callback&&n.callback(s)}})}t.default={observe:n,unobserve:a,destroy:s}});n(s);var i,c=n(a(function(e,r){Object.defineProperty(r,"__esModule",{value:!0});var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e},n=function(){function e(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,r,o){return r&&e(t.prototype,r),o&&e(t,o),t}}(),a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(t);function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}var c=function(e){function t(){var e,r,o;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);for(var n=arguments.length,a=Array(n),c=0;c<n;c++)a[c]=arguments[c];return r=o=i(this,(e=t.__proto__||Object.getPrototypeOf(t)).call.apply(e,[this].concat(a))),o.state={inView:!1},o.node=null,o.handleNode=function(e){o.node&&(0,s.unobserve)(o.node),o.node=e,o.observeNode(),o.props.innerRef&&o.props.innerRef(e)},o.handleChange=function(e){o.setState({inView:e}),o.props.onChange&&o.props.onChange(e)},i(o,r)}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,a.Component),n(t,[{key:"componentDidUpdate",value:function(e,t){e.rootMargin===this.props.rootMargin&&e.root===this.props.root&&e.threshold===this.props.threshold||((0,s.unobserve)(this.node),this.observeNode()),t.inView!==this.state.inView&&this.state.inView&&this.props.triggerOnce&&((0,s.unobserve)(this.node),this.node=null)}},{key:"componentWillUnmount",value:function(){this.node&&((0,s.unobserve)(this.node),this.node=null)}},{key:"observeNode",value:function(){if(this.node){var e=this.props;(0,s.observe)(this.node,this.handleChange,{threshold:e.threshold,root:e.root,rootMargin:e.rootMargin},e.rootId)}}},{key:"render",value:function(){var e=this.props,t=e.children,r=e.render,n=e.tag,s=function(e,t){var r={};for(var o in e)t.indexOf(o)>=0||Object.prototype.hasOwnProperty.call(e,o)&&(r[o]=e[o]);return r}(e,["children","render","tag","innerRef","triggerOnce","threshold","root","rootId","rootMargin"]),i=this.state.inView;return a.createElement(n,o({},s,{ref:this.handleNode}),"function"==typeof r?r(i):null,"function"==typeof t?t(i):t)}}]),t}();c.defaultProps={tag:"div",threshold:0,triggerOnce:!1},r.default=c}));(i=exports.ImageState||(exports.ImageState={})).NotAsked="NotAsked",i.Loading="Loading",i.LoadSuccess="LoadSuccess",i.LoadError="LoadError";var u=function(e){function n(t){var r=e.call(this,t)||this;return r.state={hasBeenInView:!1,imageState:exports.ImageState.NotAsked},r.renderInner=r.renderInner.bind(r),r.renderLazy=r.renderLazy.bind(r),r.onInView=r.onInView.bind(r),r.onLoadSuccess=r.onLoadSuccess.bind(r),r.onLoadError=r.onLoadError.bind(r),r}return function(e,t){function o(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(o.prototype=t.prototype,new o)}(n,e),n.prototype.onInView=function(e){!0===e&&(this.props.src?(this.setState(function(e,t){return o({},e,{imageState:exports.ImageState.Loading})}),l({src:this.props.src,srcSet:this.props.srcSet,alt:this.props.alt}).then(this.onLoadSuccess).catch(this.onLoadError)):this.setState(function(e,t){return o({},e,{imageState:exports.ImageState.LoadSuccess})}))},n.prototype.onLoadSuccess=function(){this.setState(function(e,t){return o({},e,{imageState:exports.ImageState.LoadSuccess})})},n.prototype.onLoadError=function(){this.setState(function(e,t){return o({},e,{imageState:exports.ImageState.LoadError})})},n.prototype.render=function(){return this.props.loadEagerly?this.renderInner(this.props,{imageState:exports.ImageState.LoadSuccess}):this.renderLazy(this.props,this.state)},n.prototype.renderLazy=function(e,r){return t.createElement(c,o({rootMargin:"50px 0px",threshold:.01},e.observerProps,{onChange:this.onInView,triggerOnce:!0}),this.renderInner(e,r))},n.prototype.renderInner=function(e,r){var o=e.src,n=e.srcSet,a=e.alt,s=e.render,i=e.children,c=r.imageState;return t.createElement(t.Fragment,null,"function"==typeof s?s({src:o,srcSet:n,alt:a,imageState:c}):"function"==typeof i?i({src:o,srcSet:n,alt:a,imageState:c}):null)},n.displayName="LazyImageFull",n}(t.Component),l=function(e){var t=e.src,r=e.srcSet,o=e.alt;return new Promise(function(e,n){var a=new Image;r&&(a.srcset=r),o&&(a.alt=o),a.src=t,a.onload=e,a.onerror=n})},p=function(e){var r=e.actual,n=e.placeholder,a=e.loading,s=e.error,i=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++)t.indexOf(o[n])<0&&(r[o[n]]=e[o[n]])}return r}(e,["actual","placeholder","loading","error"]);return t.createElement(u,o({},i),function(e){var t=e.src,o=e.srcSet,i=e.alt;switch(e.imageState){case exports.ImageState.NotAsked:return!!n&&n({alt:i});case exports.ImageState.Loading:return a?a():!!n&&n({alt:i});case exports.ImageState.LoadSuccess:return r({src:t,alt:i,srcSet:o});case exports.ImageState.LoadError:return s?s():r({src:t,alt:i,srcSet:o})}})};p.displayName="LazyImage",exports.LazyImage=p,exports.LazyImageFull=u;
function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var t=e(require("react")),r=e(require("react-intersection-observer")),o=function(e,t){return(o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};var a,n=function(){return(n=Object.assign||function(e){for(var t,r=1,o=arguments.length;r<o;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e}).apply(this,arguments)};function s(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(o=Object.getOwnPropertySymbols(e);a<o.length;a++)t.indexOf(o[a])<0&&(r[o[a]]=e[o[a]])}return r}(a=exports.ImageState||(exports.ImageState={})).NotAsked="NotAsked",a.Loading="Loading",a.LoadSuccess="LoadSuccess",a.LoadError="LoadError";var i=function(e){function a(t){var r=e.call(this,t)||this;return r.initialState={hasBeenInView:!1,imageState:exports.ImageState.NotAsked},r.state=r.initialState,r.onInView=r.onInView.bind(r),r.onLoadSuccess=r.onLoadSuccess.bind(r),r.onLoadError=r.onLoadError.bind(r),r}return function(e,t){function r(){this.constructor=e}o(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}(a,e),a.prototype.onInView=function(e){!0===e&&(this.props.src?(this.setState(function(e,t){return n({},e,{imageState:exports.ImageState.Loading})}),c({src:this.props.src,srcSet:this.props.srcSet,alt:this.props.alt,sizes:this.props.sizes},this.props.experimentalDecode).then(this.onLoadSuccess).catch(this.onLoadError)):this.setState(function(e,t){return n({},e,{imageState:exports.ImageState.LoadSuccess})}))},a.prototype.onLoadSuccess=function(){this.setState(function(e,t){return n({},e,{imageState:exports.ImageState.LoadSuccess})})},a.prototype.onLoadError=function(){this.setState(function(e,t){return n({},e,{imageState:exports.ImageState.LoadError})})},a.prototype.render=function(){var e=this,o=this.props,a=o.children,i=o.loadEagerly,c=o.observerProps,p=s(o,["children","loadEagerly","observerProps","experimentalDecode"]);return i?a({imageState:exports.ImageState.LoadSuccess,imageProps:p}):t.createElement(r,n({rootMargin:"50px 0px",threshold:.01},c,{onChange:this.onInView,triggerOnce:!0}),function(t){return a({imageState:e.state.imageState,imageProps:p,ref:t.ref})})},a.displayName="LazyImageFull",a}(t.Component),c=function(e,t){var r=e.src,o=e.srcSet,a=e.alt,n=e.sizes;return void 0===t&&(t=!1),new Promise(function(e,s){var i=new Image;o&&(i.srcset=o),a&&(i.alt=a),n&&(i.sizes=n),i.src=r,t&&"decode"in i?i.decode().then(function(){return e()}).catch(function(e){return s(e)}):(i.onload=e,i.onerror=s)})},p=function(e){var r=e.actual,o=e.placeholder,a=e.loading,c=e.error,p=s(e,["actual","placeholder","loading","error"]);return t.createElement(i,n({},p),function(e){var t=e.imageProps,n=e.ref;switch(e.imageState){case exports.ImageState.NotAsked:return!!o&&o({imageProps:t,ref:n});case exports.ImageState.Loading:return a?a():!!o&&o({imageProps:t,ref:n});case exports.ImageState.LoadSuccess:return r({imageProps:t});case exports.ImageState.LoadError:return c?c():r({imageProps:t})}})};p.displayName="LazyImage",exports.LazyImage=p,exports.LazyImageFull=i;
//# sourceMappingURL=react-lazy-images.js.map

@@ -1,2 +0,2 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t(e.reactLazyImages={},e.react)}(this,function(e,t){t=t&&t.hasOwnProperty("default")?t.default:t;var r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])};var o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r<o;r++)for(var n in t=arguments[r])Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e};function n(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function a(e,t){return e(t={exports:{}},t.exports),t.exports}var i,s=a(function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.observe=n,t.unobserve=a,t.destroy=i;var r=new Map,o=new Map;function n(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{threshold:0},a=arguments[3],i=n.root,c=n.rootMargin,u=n.threshold||0;if(e&&t){var l=c?u.toString()+"_"+c:""+u.toString();i&&(l=a?a+"_"+l:null);var d=l?o.get(l):null;d||(d=new IntersectionObserver(s,n),l&&o.set(l,d));var p={callback:t,visible:!1,options:n,observerId:l,observer:l?void 0:d};return r.set(e,p),d.observe(e),p}}function a(e){if(e){var t=r.get(e);if(t){var n=t.observerId,a=t.observer,i=n?o.get(n):a;i&&i.unobserve(e);var s=!1;n&&r.forEach(function(t,r){t&&t.observerId===n&&r!==e&&(s=!0)}),i&&!s&&(i.disconnect(),o.delete(n)),r.delete(e)}}}function i(){o.forEach(function(e){e.disconnect()}),o.clear(),r.clear()}function s(e){e.forEach(function(e){var t=e.isIntersecting,o=e.intersectionRatio,n=r.get(e.target);if(n&&o>=0){var a=n.options,i=!1;Array.isArray(a.threshold)?i=a.threshold.some(function(e){return n.visible?o>e:o>=e}):void 0!==a.threshold&&(i=n.visible?o>a.threshold:o>=a.threshold),void 0!==t&&(i=i&&t),n.callback&&n.callback(i)}})}t.default={observe:n,unobserve:a,destroy:i}}),c=n(s),u={default:c,__moduleExports:s,observe:s.observe,unobserve:s.unobserve,destroy:s.destroy},l=u&&c||u,d=n(a(function(e,r){Object.defineProperty(r,"__esModule",{value:!0});var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e},n=function(){function e(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,r,o){return r&&e(t.prototype,r),o&&e(t,o),t}}(),a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(t);function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}var s=function(e){function t(){var e,r,o;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t);for(var n=arguments.length,a=Array(n),s=0;s<n;s++)a[s]=arguments[s];return r=o=i(this,(e=t.__proto__||Object.getPrototypeOf(t)).call.apply(e,[this].concat(a))),o.state={inView:!1},o.node=null,o.handleNode=function(e){o.node&&(0,l.unobserve)(o.node),o.node=e,o.observeNode(),o.props.innerRef&&o.props.innerRef(e)},o.handleChange=function(e){o.setState({inView:e}),o.props.onChange&&o.props.onChange(e)},i(o,r)}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,a.Component),n(t,[{key:"componentDidUpdate",value:function(e,t){e.rootMargin===this.props.rootMargin&&e.root===this.props.root&&e.threshold===this.props.threshold||((0,l.unobserve)(this.node),this.observeNode()),t.inView!==this.state.inView&&this.state.inView&&this.props.triggerOnce&&((0,l.unobserve)(this.node),this.node=null)}},{key:"componentWillUnmount",value:function(){this.node&&((0,l.unobserve)(this.node),this.node=null)}},{key:"observeNode",value:function(){if(this.node){var e=this.props;(0,l.observe)(this.node,this.handleChange,{threshold:e.threshold,root:e.root,rootMargin:e.rootMargin},e.rootId)}}},{key:"render",value:function(){var e=this.props,t=e.children,r=e.render,n=e.tag,i=function(e,t){var r={};for(var o in e)t.indexOf(o)>=0||Object.prototype.hasOwnProperty.call(e,o)&&(r[o]=e[o]);return r}(e,["children","render","tag","innerRef","triggerOnce","threshold","root","rootId","rootMargin"]),s=this.state.inView;return a.createElement(n,o({},i,{ref:this.handleNode}),"function"==typeof r?r(s):null,"function"==typeof t?t(s):t)}}]),t}();s.defaultProps={tag:"div",threshold:0,triggerOnce:!1},r.default=s}));(i=e.ImageState||(e.ImageState={})).NotAsked="NotAsked",i.Loading="Loading",i.LoadSuccess="LoadSuccess",i.LoadError="LoadError";var p=function(n){function a(t){var r=n.call(this,t)||this;return r.state={hasBeenInView:!1,imageState:e.ImageState.NotAsked},r.renderInner=r.renderInner.bind(r),r.renderLazy=r.renderLazy.bind(r),r.onInView=r.onInView.bind(r),r.onLoadSuccess=r.onLoadSuccess.bind(r),r.onLoadError=r.onLoadError.bind(r),r}return function(e,t){function o(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(o.prototype=t.prototype,new o)}(a,n),a.prototype.onInView=function(t){!0===t&&(this.props.src?(this.setState(function(t,r){return o({},t,{imageState:e.ImageState.Loading})}),f({src:this.props.src,srcSet:this.props.srcSet,alt:this.props.alt}).then(this.onLoadSuccess).catch(this.onLoadError)):this.setState(function(t,r){return o({},t,{imageState:e.ImageState.LoadSuccess})}))},a.prototype.onLoadSuccess=function(){this.setState(function(t,r){return o({},t,{imageState:e.ImageState.LoadSuccess})})},a.prototype.onLoadError=function(){this.setState(function(t,r){return o({},t,{imageState:e.ImageState.LoadError})})},a.prototype.render=function(){return this.props.loadEagerly?this.renderInner(this.props,{imageState:e.ImageState.LoadSuccess}):this.renderLazy(this.props,this.state)},a.prototype.renderLazy=function(e,r){return t.createElement(d,o({rootMargin:"50px 0px",threshold:.01},e.observerProps,{onChange:this.onInView,triggerOnce:!0}),this.renderInner(e,r))},a.prototype.renderInner=function(e,r){var o=e.src,n=e.srcSet,a=e.alt,i=e.render,s=e.children,c=r.imageState;return t.createElement(t.Fragment,null,"function"==typeof i?i({src:o,srcSet:n,alt:a,imageState:c}):"function"==typeof s?s({src:o,srcSet:n,alt:a,imageState:c}):null)},a.displayName="LazyImageFull",a}(t.Component),f=function(e){var t=e.src,r=e.srcSet,o=e.alt;return new Promise(function(e,n){var a=new Image;r&&(a.srcset=r),o&&(a.alt=o),a.src=t,a.onload=e,a.onerror=n})},h=function(r){var n=r.actual,a=r.placeholder,i=r.loading,s=r.error,c=function(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++)t.indexOf(o[n])<0&&(r[o[n]]=e[o[n]])}return r}(r,["actual","placeholder","loading","error"]);return t.createElement(p,o({},c),function(t){var r=t.src,o=t.srcSet,c=t.alt;switch(t.imageState){case e.ImageState.NotAsked:return!!a&&a({alt:c});case e.ImageState.Loading:return i?i():!!a&&a({alt:c});case e.ImageState.LoadSuccess:return n({src:r,alt:c,srcSet:o});case e.ImageState.LoadError:return s?s():n({src:r,alt:c,srcSet:o})}})};h.displayName="LazyImage",e.LazyImage=h,e.LazyImageFull=p});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("react-intersection-observer")):"function"==typeof define&&define.amd?define(["exports","react","react-intersection-observer"],t):t(e.reactLazyImages={},e.react,null)}(this,function(e,t,r){t=t&&t.hasOwnProperty("default")?t.default:t,r=r&&r.hasOwnProperty("default")?r.default:r;var o=function(e,t){return(o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};var a,n=function(){return(n=Object.assign||function(e){for(var t,r=1,o=arguments.length;r<o;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e}).apply(this,arguments)};function i(e,t){var r={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(o=Object.getOwnPropertySymbols(e);a<o.length;a++)t.indexOf(o[a])<0&&(r[o[a]]=e[o[a]])}return r}(a=e.ImageState||(e.ImageState={})).NotAsked="NotAsked",a.Loading="Loading",a.LoadSuccess="LoadSuccess",a.LoadError="LoadError";var s=function(a){function s(t){var r=a.call(this,t)||this;return r.initialState={hasBeenInView:!1,imageState:e.ImageState.NotAsked},r.state=r.initialState,r.onInView=r.onInView.bind(r),r.onLoadSuccess=r.onLoadSuccess.bind(r),r.onLoadError=r.onLoadError.bind(r),r}return function(e,t){function r(){this.constructor=e}o(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}(s,a),s.prototype.onInView=function(t){!0===t&&(this.props.src?(this.setState(function(t,r){return n({},t,{imageState:e.ImageState.Loading})}),c({src:this.props.src,srcSet:this.props.srcSet,alt:this.props.alt,sizes:this.props.sizes},this.props.experimentalDecode).then(this.onLoadSuccess).catch(this.onLoadError)):this.setState(function(t,r){return n({},t,{imageState:e.ImageState.LoadSuccess})}))},s.prototype.onLoadSuccess=function(){this.setState(function(t,r){return n({},t,{imageState:e.ImageState.LoadSuccess})})},s.prototype.onLoadError=function(){this.setState(function(t,r){return n({},t,{imageState:e.ImageState.LoadError})})},s.prototype.render=function(){var o=this,a=this.props,s=a.children,c=a.loadEagerly,u=a.observerProps,p=i(a,["children","loadEagerly","observerProps","experimentalDecode"]);return c?s({imageState:e.ImageState.LoadSuccess,imageProps:p}):t.createElement(r,n({rootMargin:"50px 0px",threshold:.01},u,{onChange:this.onInView,triggerOnce:!0}),function(e){return s({imageState:o.state.imageState,imageProps:p,ref:e.ref})})},s.displayName="LazyImageFull",s}(t.Component),c=function(e,t){var r=e.src,o=e.srcSet,a=e.alt,n=e.sizes;return void 0===t&&(t=!1),new Promise(function(e,i){var s=new Image;o&&(s.srcset=o),a&&(s.alt=a),n&&(s.sizes=n),s.src=r,t&&"decode"in s?s.decode().then(function(){return e()}).catch(function(e){return i(e)}):(s.onload=e,s.onerror=i)})},u=function(r){var o=r.actual,a=r.placeholder,c=r.loading,u=r.error,p=i(r,["actual","placeholder","loading","error"]);return t.createElement(s,n({},p),function(t){var r=t.imageProps,n=t.ref;switch(t.imageState){case e.ImageState.NotAsked:return!!a&&a({imageProps:r,ref:n});case e.ImageState.Loading:return c?c():!!a&&a({imageProps:r,ref:n});case e.ImageState.LoadSuccess:return o({imageProps:r});case e.ImageState.LoadError:return u?u():o({imageProps:r})}})};u.displayName="LazyImage",e.LazyImage=u,e.LazyImageFull=s});
//# sourceMappingURL=react-lazy-images.umd.js.map
{
"name": "react-lazy-images",
"description": "React utilities for lazy image loading",
"version": "0.9.1",
"version": "1.0.0-rc.1",
"source": "src/index.tsx",

@@ -11,13 +11,12 @@ "module": "dist/react-lazy-images.es.js",

"scripts": {
"dev": "npm-run-all --parallel bundle:dev storybook",
"dev": "npm-run-all bundle:prod storybook",
"dev:ts": "tsc --watch --pretty",
"build": "npm-run-all bundle:prod size",
"bundle:dev": "./microbundle/dist/cli.js watch --compress false --external all",
"bundle:prod": "./microbundle/dist/cli.js build --external all",
"bundle:storybook": "./microbundle/dist/cli.js build --compress false --external all",
"size": "bundlesize",
"bundle:prod": "microbundle build",
"bundle:watch": "microbundle watch",
"storybook": "start-storybook -p 8080 -s ./stories/demo",
"build-storybook": "npm run bundle:storybook && build-storybook -c .storybook -s ./stories/demo -o .out",
"deploy-storybook": "storybook-to-ghpages --existing-output-dir=.out",
"storybook:build": "npm run bundle:prod && build-storybook -c .storybook -s ./stories/demo -o .out",
"storybook:deploy": "storybook-to-ghpages --existing-output-dir=.out",
"test": "npm run build",
"prepare": "npm t",
"size": "bundlesize",
"release": "npm t && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish"

@@ -31,2 +30,17 @@ },

],
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,ts,tsx}": [
"eslint",
"git add"
],
"*.{js,ts,tsx,json,css,md}": [
"prettier --write",
"git add"
]
},
"files": [

@@ -53,24 +67,4 @@ "src",

"homepage": "https://github.com/fpapado/react-lazy-images#readme",
"devDependencies": {
"@storybook/addon-actions": "4.0.0-alpha.3",
"@storybook/addon-info": "4.0.0-alpha.3",
"@storybook/addon-options": "4.0.0-alpha.3",
"@storybook/addons": "4.0.0-alpha.3",
"@storybook/react": "4.0.0-alpha.3",
"@storybook/storybook-deployer": "^2.3.0",
"@types/react": "^16.0.41",
"awesome-typescript-loader": "^5.0",
"babel-core": "^6.26.0",
"bundlesize": "^0.17.0",
"gzip-size": "^4.1.0",
"microbundle": "^0.4.4",
"npm-run-all": "^4.1.2",
"prettier": "^1.11.1",
"react": "^16.2.0",
"react-docgen-typescript": "^1.2.6",
"react-docgen-typescript-loader": "^2.0.3",
"react-docgen-typescript-webpack-plugin": "^1.1.0",
"react-dom": "^16.2.0",
"tachyons": "^4.9.1",
"typescript": "^2.7.2"
"dependencies": {
"react-intersection-observer": "^6.1.0"
},

@@ -81,5 +75,33 @@ "peerDependencies": {

},
"dependencies": {
"react-intersection-observer": "^3.0.3"
"devDependencies": {
"@storybook/addon-actions": "4.0.0-alpha.14",
"@storybook/addon-info": "4.0.0-alpha.14",
"@storybook/addon-options": "4.0.0-alpha.14",
"@storybook/addons": "4.0.0-alpha.14",
"@storybook/react": "4.0.0-alpha.14",
"@storybook/storybook-deployer": "^2.3.0",
"@types/react": "^16.4.6",
"@types/react-dom": "^16.0.6",
"@types/storybook__addon-actions": "^3.0.3",
"@types/storybook__addon-info": "^3.2.3",
"@types/storybook__react": "^3.0.8",
"awesome-typescript-loader": "^5.2",
"babel-core": "^6.26.3",
"bundlesize": "^0.17.0",
"eslint": "^5.1.0",
"eslint-plugin-jsx-a11y": "^6.1.1",
"husky": "^1.0.0-rc.13",
"lint-staged": "^7.2.0",
"microbundle": "^0.5.1",
"npm-run-all": "^4.1.3",
"prettier": "^1.13.7",
"react": "^16.4.1",
"react-docgen-typescript": "^1.6.2",
"react-docgen-typescript-loader": "^2.1.1",
"react-docgen-typescript-webpack-plugin": "^1.1.0",
"react-dom": "^16.4.1",
"tachyons": "^4.10.0",
"typescript": "^2.9.2",
"typescript-eslint-parser": "^16.0.1"
}
}

@@ -15,29 +15,29 @@ # React Lazy Images

* [Features](#features)
* [Install](#install)
* [Motivation](#motivation)
* [Usage](#usage)
* [Examples](#examples)
* [API Reference](#api-reference)
* [Feedback](#feedback)
* [Roadmap](#roadmap)
* [Contributing](#contributing)
* [Thanks](#thanks-and-inspiration)
* [License](#license)
- [Features](#features)
- [Install](#install)
- [Motivation](#motivation)
- [Usage](#usage)
- [Examples](#examples)
- [API Reference](#api-reference)
- [Feedback](#feedback)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Thanks](#thanks-and-inspiration)
- [License](#license)
## Features
* Composable pieces, preloading images and handling failures.
* Full presentational control for the caller (render props).
* Modern, performant implementation, using [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) and providing [polyfill information](#polyfill-intersection-observer).
* [Eager loading / Server-side rendering support](#eager-loading--server-side-rendering-ssr).
* Works with horizontal scrolling, supports background images.
* [Fallbacks for SEO / when Javascript is disabled](#fallback-without-javascript).
* Easy to understand source code. You should be able to fork and do your thing if desired.
* Ample documentation to help you understand the problem, in addition to the solutions.
- Composable pieces, preloading images and handling failures.
- Full presentational control for the caller (render props).
- Modern, performant implementation, using [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) and providing [polyfill information](#polyfill-intersection-observer).
- [Eager loading / Server-side rendering support](#eager-loading--server-side-rendering-ssr).
- Works with horizontal scrolling, supports background images.
- [Fallbacks for SEO / when Javascript is disabled](#fallback-without-javascript).
- Easy to understand source code. You should be able to fork and do your thing if desired.
- Ample documentation to help you understand the problem, in addition to the solutions.
What it does not do by itself:
* Polyfill `IntersectionObserver`. Adding polyfills is something you should do consciously at the application level. See [Polyfilling IntersectionObserver](#polyfill-intersectionobserver) for how to do this.
* Dictate the kind of placeholders displayed. There are many ways to do it; you can use a simple box with a background color, a low-resolution image, some gradient, etc.
- Polyfill `IntersectionObserver`. Adding polyfills is something you should do consciously at the application level. See [Polyfilling IntersectionObserver](#polyfill-intersectionobserver) for how to do this.
- Dictate the kind of placeholders displayed. There are many ways to do it; you can use a simple box with a background color, a low-resolution image, some gradient, etc.
In other words, this library focuses on loading the images once in view and supporting **loading patterns** around that.

@@ -82,5 +82,5 @@ The presentational patterns are yours to decide!

* Have a way to observe the visibility of the DOM elements
* Prevent the browser from loading images directly
* Once an image is in view, instruct the browser to load it and place it in the element
- Have a way to observe the visibility of the DOM elements
- Prevent the browser from loading images directly
- Once an image is in view, instruct the browser to load it and place it in the element

@@ -112,9 +112,11 @@ In vanilla JS, this means "hiding" the actual `src` in a `data-src` attribute, and using classes to indicate state, e.g. `.isLazyLoaded .lazyLoad`.

alt="Buildings with tiled exteriors, lit by the sunset."
placeholder={({ alt }) => (
<img src="/img/porto_buildings_lowres.jpg" alt={alt} />
placeholder={({ imageProps, ref }) => (
<img ref={ref} src="/img/porto_buildings_lowres.jpg" alt={imageProps.alt} />
)}
actual={({ src, alt, srcSet }) => <img src={src} alt={alt} />}
actual={({ imageProps }) => <img {...imageProps} />}
/>;
```
:warning: It is important that you pass on the ref in placeholder, otherwise the detection of the element intersecting is impossible. :warning:
Note that while you can set the rendered components to be anything you want, you most likely want to use the same `src`, `srcSet` and `alt` attributes in an `<img>` eventually.

@@ -129,5 +131,5 @@ To keep this consistent, and reduce repetition, the render callbacks pass those attributes back to you.

* If you want to learn more about the API and the problem space, read the rest of this section.
* If you need more fine-grained rendering, [read about `LazyImageFull`](#more-control-with-lazyimagefull).
* If you want to list the props, see the [API reference](#api-reference).
- If you want to learn more about the API and the problem space, read the rest of this section.
- If you need more fine-grained rendering, [read about `LazyImageFull`](#more-control-with-lazyimagefull).
- If you want to list the props, see the [API reference](#api-reference).

@@ -144,12 +146,11 @@ ### Customising what is displayed

alt="Buildings with tiled exteriors, lit by the sunset."
// This is rendered first, notice how the src is different
placeholder={
({alt}) =>
<img src="/img/porto_buildings_lowres.jpg" alt={alt} />
({imageProps, ref}) =>
<img ref={ref} src="/img/porto_buildings_lowres.jpg" alt={imageProps.alt} />
}
// This is rendered once in view; we use the src and alt above for consistency
actual={
({src, alt}) =>
<img src={src} alt={alt} />
({imageProps}) =>
<img {...imageProps} />
}

@@ -163,11 +164,11 @@ />

placeholder={
({alt}) =>
<div className={'LazyImage-Placeholder'}">
<img src="/img/porto_buildings_lowres.jpg" alt={alt} />
({imageProps, ref}) =>
<div ref={ref} className={'LazyImage-Placeholder'}>
<img src="/img/porto_buildings_lowres.jpg" alt={imageProps.alt} />
</div>
}
actual={
({src, alt}) =>
({imageProps}) =>
<div className={'LazyImage-Actual'}>
<img src={src} alt={alt} />
<img {...imageProps} />
</div>

@@ -187,27 +188,20 @@ }

```jsx
import {LazyImageFull, ImageState} from 'react-lazy-images';
import { LazyImageFull, ImageState } from "react-lazy-images";
// Function as child
// `src`, `alt` and `srcSet` are passed back to the render callback for convenience/consistency
<LazyImageFull src='/img/porto_buildings_large.jpg'>
{({src, alt, srcSet, imageState}) =>
<LazyImageFull src="/img/porto_buildings_large.jpg">
{({ imageProps, imageState, ref }) => (
<img
src={imageState === ImageState.LoadSuccess ? src : '/img/porto_buildings_lowres.jpg'}
alt={alt}
style={{opacity: ImageState.LoadSuccess ? '1' : '0.5'}}
{...imageProps}
ref={ref}
src={
imageState === ImageState.LoadSuccess
? imageProps.src
: "/img/porto_buildings_lowres.jpg"
}
style={{ opacity: ImageState.LoadSuccess ? "1" : "0.5" }}
/>
}
</LazyImageFull>
// render prop
<LazyImageFull
src='/img/porto_buildings_large.jpg'
render={({src, alt, srcSet, imageState}) =>
<img
src={imageState === ImageState.LoadSuccess ? src : '/img/porto_buildings_lowres.jpg'}
alt={alt}
style={{opacity: ImageState.LoadSuccess ? '1' : '0.5'}}
/>
}
/>
)}
</LazyImageFull>;
```

@@ -217,3 +211,2 @@

The various image states are imported as `{ImageState}`, and you can conditionally render based on them.
You can also pass this function as a `render` prop.

@@ -241,11 +234,11 @@ This technique can give you more fine-grained rendering if needed, but can potentially be more verbose.

placeholder={
({alt}) =>
<div className={`LazyImage-Placeholder`}">
<img src="/img/porto_buildings_lowres.jpg" alt={alt} />
({imageProps, ref}) =>
<div ref={ref} className={`LazyImage-Placeholder`}">
<img src="/img/porto_buildings_lowres.jpg" alt={imageProps.alt} />
</div>
}
actual={
({src, alt}) =>
({imageProps}) =>
<div className={`LazyImage-Actual`}>
<img src={src} alt={alt} />
<img {...imageProps} />
</div>

@@ -267,3 +260,4 @@ }

alt="Buildings with tiled exteriors, lit by the sunset."
actual={({ src, alt }) => <img src={src} alt={alt} />}
actual={({ imageProps }) => <img {...imageProps} />}
placeholder={({ ref }) => <div ref={ref} />}
loading={() => (

@@ -299,6 +293,6 @@ <div>

alt="Buildings with tiled exteriors, lit by the sunset."
placeholder={({ alt }) => (
<img src="/img/porto_buildings_lowres.jpg" alt={alt} />
placeholder={({ imageProps, ref }) => (
<img ref={ref} src="/img/porto_buildings_lowres.jpg" alt={imageProps.alt} />
)}
actual={({ src, alt }) => <img src={src} alt={alt} />}
actual={({ imageProps }) => <img {...imageProps} />}
/>

@@ -430,25 +424,28 @@ ```

| Name | Type | Default | Required | Description |
| ----------------- | -------------------------------------------------------------------------- | ----------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| **src** | String | | true | The source of the image to load |
| **alt** | String | | false | The alt text description of the image you are loading |
| **srcSet** | String | | false | If your images use srcset, you can pass the `srcSet` prop to provide that information for preloading. |
| **actual** | Function (render callback) of type ({src, alt, srcSet}) => React.ReactNode | | true | Component to display once image has loaded |
| **placeholder** | Function (render callback) of type ({alt}) => React.ReactNode | undefined | false | Component to display while no request for the actual image has been made |
| **loading** | Function (render callback) of type () => React.ReactNode | placeholder | false | Component to display while the image is loading |
| **error** | Function (render callback) of type () => React.ReactNode | actual (broken image) | false | Component to display if the image loading has failed (render prop) |
| **loadEagerly** | Boolean | false | false | Whether to skip checking for viewport and always show the 'actual' component |
| **observerProps** | {threshold: number, rootMargin: string} | {threshold: 0.01, rootMargin: "50px 0px"} | false | Subset of props for the IntersectionObserver |
| Name | Type | Default | Required | Description |
| ---------------------- | ------------------------------------------------------------------------- | ----------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| **src** | String | | true | The source of the image to load |
| **alt** | String | | false | The alt text description of the image you are loading |
| **srcSet** | String | | false | If your images use srcset, you can pass the `srcSet` prop to provide that information for preloading. |
| **sizes** | String | | false | If your images use srcset, the sizes attribute helps the browser decide which source to load. |
| **actual** | Function (render callback) of type ({imageProps}) => React.ReactNode | | true | Component to display once image has loaded |
| **placeholder** | Function (render callback) of type ({imageProps, ref}) => React.ReactNode | undefined | true | Component to display while no request for the actual image has been made |
| **loading** | Function (render callback) of type () => React.ReactNode | placeholder | false | Component to display while the image is loading |
| **error** | Function (render callback) of type () => React.ReactNode | actual (broken image) | false | Component to display if the image loading has failed (render prop) |
| **loadEagerly** | Boolean | false | false | Whether to skip checking for viewport and always show the 'actual' component |
| **observerProps** | {threshold: number, rootMargin: string} | {threshold: 0.01, rootMargin: "50px 0px"} | false | Subset of props for the IntersectionObserver |
| **experimentalDecode** | Boolean | false | false | Decode the image off-main-thread using the Image Decode API. Test before using! |
**`<LazyImageFull />`** accepts the following props:
| Name | Type | Default | Required | Description |
| ----------------- | -------------------------------------------------------------------- | ----------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------- |
| **src** | String | | true | The source of the image to load |
| **alt** | String | | false | The alt text description of the image you are loading |
| **srcSet** | String | | false | If your images use srcset, you can pass the `srcSet` prop to provide that information for preloading. |
| **loadEagerly** | Boolean | false | false | Whether to skip checking for viewport and always show the 'actual' component |
| **observerProps** | {threshold: number, rootMargin: string} | {threshold: 0.01, rootMargin: "50px 0px"} | false | Subset of props for the IntersectionObserver |
| **render** | Function of type ({src, alt, srcSet, imageState}) => React.ReactNode | | true (or `children`) | Function to call that renders based on the props and state provided to it by LazyImageFull |
| **children** | Function of type ({src, alt, srcSet, imageState}) => React.ReactNode | | true (or `render`) | Function to call that renders based on the props and state provided to it by LazyImageFull |
| Name | Type | Default | Required | Description |
| ---------------------- | ------------------------------------------------------------------- | ----------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| **src** | String | | true | The source of the image to load |
| **alt** | String | | false | The alt text description of the image you are loading |
| **srcSet** | String | | false | If your images use srcset, you can pass the `srcSet` prop to provide that information for preloading. |
| **sizes** | String | | false | If your images use srcset, the sizes attribute helps the browser decide which source to load. |
| **loadEagerly** | Boolean | false | false | Whether to skip checking for viewport and always show the 'actual' component |
| **observerProps** | {threshold: number, rootMargin: string} | {threshold: 0.01, rootMargin: "50px 0px"} | false | Subset of props for the IntersectionObserver |
| **children** | Function of type ({imageProps, imageState, ref}) => React.ReactNode | | true | Function to call that renders based on the props and state provided to it by LazyImageFull |
| **experimentalDecode** | Boolean | false | false | Decode the image off-main-thread using the Image Decode API. Test before using! |

@@ -473,12 +470,12 @@ [You can consult Typescript types in the code](./src/LazyImage.tsx) for more context.

* Jeremy Wagner's writing on [Lazy Loading Images and Video](https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video/) is a good reference for the problem and solutions space.
- Jeremy Wagner's writing on [Lazy Loading Images and Video](https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video/) is a good reference for the problem and solutions space.
* The library backing this one, [react-intersection-observer](https://github.com/thebuilder/react-intersection-observer).
- The library backing this one, [react-intersection-observer](https://github.com/thebuilder/react-intersection-observer).
Further thanks for demonstrating Storybook as documentation for lazy-loading.
* [José M. Pérez has a good resource on lazy loading](https://jmperezperez.com/high-performance-lazy-loading/)
- [José M. Pérez has a good resource on lazy loading](https://jmperezperez.com/high-performance-lazy-loading/)
* [Paul Lewis' implementation of lazy image loading](https://github.com/GoogleChromeLabs/sample-media-pwa/blob/master/src/client/scripts/helpers/lazy-load-images.js) has the concept of pre-loading images before swapping.
- [Paul Lewis' implementation of lazy image loading](https://github.com/GoogleChromeLabs/sample-media-pwa/blob/master/src/client/scripts/helpers/lazy-load-images.js) has the concept of pre-loading images before swapping.
* [Dave Rupert has a good guide on intrinsic image placeholders](https://daverupert.com/2015/12/intrinsic-placeholders-with-picture/)
- [Dave Rupert has a good guide on intrinsic image placeholders](https://daverupert.com/2015/12/intrinsic-placeholders-with-picture/)

@@ -485,0 +482,0 @@ ## License

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc