react-img-carousel
Advanced tools
Comparing version 1.4.2 to 1.5.0
@@ -27,6 +27,2 @@ 'use strict'; | ||
var _lodash5 = require('lodash.inrange'); | ||
var _lodash6 = _interopRequireDefault(_lodash5); | ||
var _ms = require('ms'); | ||
@@ -87,2 +83,3 @@ | ||
imagesToPrefetch: _propTypes2.default.number, | ||
maxRenderedSlides: _propTypes2.default.number, | ||
cellPadding: _propTypes2.default.number, | ||
@@ -129,2 +126,3 @@ slideWidth: _propTypes2.default.string, | ||
imagesToPrefetch: 5, | ||
maxRenderedSlides: 5, | ||
cellPadding: 0, | ||
@@ -166,5 +164,8 @@ transitionDuration: 500, | ||
// eslint-disable-next-line | ||
_createClass(Carousel, [{ | ||
key: 'componentWillReceiveProps', | ||
value: function componentWillReceiveProps(newProps) { | ||
key: 'UNSAFE_componentWillReceiveProps', | ||
value: function UNSAFE_componentWillReceiveProps(newProps) { | ||
var currentSlide = this.state.currentSlide; | ||
@@ -617,3 +618,4 @@ | ||
style = _props7.style, | ||
easing = _props7.easing; | ||
easing = _props7.easing, | ||
lazyLoad = _props7.lazyLoad; | ||
var _state4 = this.state, | ||
@@ -659,4 +661,7 @@ slideDimensions = _state4.slideDimensions, | ||
}); | ||
var slidesToRender = _this7.getIndicesToRender(); | ||
if (_this7.shouldRenderSlide(child, index)) { | ||
// Only render the actual slide content if lazy loading is disabled, the image is already loaded, or we | ||
// are within the configured proximity to the selected slide index. | ||
if (!lazyLoad || imgSrc && loadedImages[imgSrc] || slidesToRender.indexOf(index) > -1) { | ||
// If the slide contains an image, set explicit width/height and add load listener | ||
@@ -709,47 +714,47 @@ if (imgSrc && loadedImages[imgSrc]) { | ||
/** | ||
* If lazy loading is enabled, this method attempts to determine whether the given slide index should be rendered. | ||
* For img slides with src attributes, we render the slides only if the image has been fetched. For non-img slides, | ||
* we attempt to determine whether the slide content should be rendered based on the currentSlide index and the | ||
* transitioningFrom slide index, if set, to provide the best balance between showing the slides as they transition | ||
* and keeping the DOM light if there are many slides in the carousel. | ||
* This method returns the slides indices that should be fully rendered given the current lazyLoad and | ||
* maxRenderedSlides settings. | ||
* | ||
* @param {Object} slide The slide component to check. | ||
* @param {Number} index The index of the specified slide component. | ||
* @returns {Boolean} True if the slide should be rendered, else False. | ||
* @returns {Array} Array of slide indices indicating which indices should be fully rendered. | ||
*/ | ||
}, { | ||
key: 'shouldRenderSlide', | ||
value: function shouldRenderSlide(slide, index) { | ||
key: 'getIndicesToRender', | ||
value: function getIndicesToRender() { | ||
var _state5 = this.state, | ||
currentSlide = _state5.currentSlide, | ||
loadedImages = _state5.loadedImages, | ||
transitioningFrom = _state5.transitioningFrom; | ||
var _props8 = this.props, | ||
lazyLoad = _props8.lazyLoad, | ||
children = _props8.children, | ||
infinite = _props8.infinite; | ||
infinite = _props8.infinite, | ||
maxRenderedSlides = _props8.maxRenderedSlides; | ||
var numSlides = _react.Children.count(children); | ||
var imgSrc = slide.props.src; | ||
if (!lazyLoad) { | ||
return true; | ||
function genIndices(startIndex, endIndex) { | ||
var indices = []; | ||
for (var i = startIndex; i <= endIndex; i++) { | ||
if (infinite && i < 0) { | ||
indices.push(numSlides + i); | ||
} else if (infinite && i >= numSlides) { | ||
indices.push(i - numSlides); | ||
} else { | ||
indices.push(i); | ||
} | ||
} | ||
return indices; | ||
} | ||
if (imgSrc) { | ||
return !!loadedImages[imgSrc]; | ||
} | ||
// Figure out what slide indices need to be rendered | ||
var maxSlides = Math.max(1, maxRenderedSlides); | ||
var prevSlidesToRender = Math.floor((maxSlides - 1) / 2); | ||
var nextSlidesToRender = Math.floor(maxSlides / 2); | ||
var indices = genIndices(currentSlide - prevSlidesToRender, currentSlide + nextSlidesToRender); | ||
// Render at least 5 slides centered around the current slide, or the slide we just transitioned from | ||
if ((0, _lodash6.default)(index, currentSlide - 2, currentSlide + 3) || transitioningFrom !== null && (0, _lodash6.default)(index, transitioningFrom - 2, transitioningFrom + 3)) { | ||
return true; | ||
} else if (infinite) { | ||
// In infinite mode, we also want to render the adjacent slides if we're at the beginning or the end | ||
if (currentSlide <= 1 && index >= numSlides - 2 || currentSlide >= numSlides - 2 && index <= 1 || transitioningFrom !== null && (transitioningFrom <= 1 && index >= numSlides - 2 || transitioningFrom >= numSlides - 2 && index <= 1)) { | ||
return true; | ||
} | ||
if (transitioningFrom !== null) { | ||
// Also render the slides around the previous slide during a transition | ||
indices = indices.concat(genIndices(transitioningFrom - prevSlidesToRender, transitioningFrom + nextSlidesToRender)); | ||
} | ||
return false; | ||
return indices; | ||
} | ||
@@ -756,0 +761,0 @@ }, { |
{ | ||
"name": "react-img-carousel", | ||
"version": "1.4.2", | ||
"version": "1.5.0", | ||
"description": "Provides an image carousel React component.", | ||
@@ -32,3 +32,3 @@ "main": "lib/index.js", | ||
"prepublish": "npm run test && npm run build", | ||
"start": "webpack-dev-server" | ||
"start": "webpack-dev-server --open" | ||
}, | ||
@@ -40,15 +40,15 @@ "peerDependencies": { | ||
"class-autobind": "^0.1.0", | ||
"classnames": "^2.0.0", | ||
"classnames": "^2.2.6", | ||
"lodash.inrange": "^3.3.6", | ||
"lodash.merge": "^4.6.0", | ||
"lodash.merge": "^4.6.2", | ||
"lodash.nth": "^4.11.2", | ||
"ms": "^0.7.2", | ||
"prop-types": "^15.5.10" | ||
"prop-types": "^15.7.2" | ||
}, | ||
"devDependencies": { | ||
"autoprefixer": "^7.2.5", | ||
"autoprefixer": "^7.2.6", | ||
"babel-cli": "^6.26.0", | ||
"babel-core": "^6.26.0", | ||
"babel-eslint": "^8.2.1", | ||
"babel-loader": "^7.1.2", | ||
"babel-core": "^6.26.3", | ||
"babel-eslint": "^8.2.6", | ||
"babel-loader": "^7.1.5", | ||
"babel-polyfill": "^6.26.0", | ||
@@ -58,26 +58,27 @@ "babel-preset-es2015": "^6.24.1", | ||
"babel-preset-stage-2": "^6.24.1", | ||
"chai": "^4.1.2", | ||
"css-loader": "^0.28.9", | ||
"eslint": "^4.17.0", | ||
"eslint-config-godaddy-react": "^2.2.0", | ||
"eslint-plugin-json": "^1.2.0", | ||
"eslint-plugin-mocha": "^4.11.0", | ||
"eslint-plugin-react": "^7.6.1", | ||
"babel-register": "^6.26.0", | ||
"chai": "^4.2.0", | ||
"css-loader": "^0.28.11", | ||
"eslint": "^4.19.1", | ||
"eslint-config-godaddy-react": "^2.2.2", | ||
"eslint-plugin-json": "^1.4.0", | ||
"eslint-plugin-mocha": "^4.12.1", | ||
"eslint-plugin-react": "^7.14.3", | ||
"godaddy-test-tools": "^9.2.0", | ||
"gulp": "^3.9.1", | ||
"gulp": "3.9.0", | ||
"html-webpack-plugin": "^2.30.1", | ||
"jsdom": "^11.6.2", | ||
"jsdom": "^11.12.0", | ||
"less": "^2.7.3", | ||
"less-loader": "^4.0.5", | ||
"mocha": "^5.0.0", | ||
"postcss-cli": "^5.0.0", | ||
"react": "^16.2.0", | ||
"react-dom": "^16.2.0", | ||
"rimraf": "^2.6.2", | ||
"sinon": "^4.2.2", | ||
"less-loader": "^4.1.0", | ||
"mocha": "^5.2.0", | ||
"postcss-cli": "^5.0.1", | ||
"react": "^16.9.0", | ||
"react-dom": "^16.9.0", | ||
"rimraf": "^2.7.1", | ||
"sinon": "^4.5.0", | ||
"sinon-chai": "^2.14.0", | ||
"style-loader": "^0.20.1", | ||
"webpack": "^3.10.0", | ||
"webpack-dev-server": "^2.11.1" | ||
"style-loader": "^0.20.3", | ||
"webpack": "^3.12.0", | ||
"webpack-dev-server": "^2.11.5" | ||
} | ||
} |
@@ -87,4 +87,3 @@ # react-img-carousel | ||
If `false`, the carousel will render all children at mount time and will not attempt to lazy load images. Note that | ||
lazy loading will only work if the slides are `img` tags or if both `slideWidth` and `slideHeight` are specified. | ||
If `false`, the carousel will render all children at mount time and will not attempt to lazy load images. Note that lazy loading will only work if the slides are `img` tags or if both `slideWidth` and `slideHeight` are specified. | ||
@@ -94,5 +93,9 @@ #### imagesToPrefetch | ||
If `lazyLoad` is set to `true`, this value will be used to determine how many images to fetch at mount time. Defaults | ||
to `5`. | ||
If `lazyLoad` is set to `true`, this value will be used to determine how many images to fetch at mount time. If the slides are not simple `img` elements, this prop will have no effect. Defaults to `5`. | ||
#### maxRenderedSlides | ||
`PropTypes.number` | ||
If `lazyLoad` is set to `true`, this value will be used to determine how many slides to fully render (including the currently selected slide). For example, if the currently selected slide is slide `10`, and this prop is set to `5`, then slides `8-12` will be rendered, and all other slides will render a lightweight placeholder. Note that this prop is ignored for slides that are simply `img` tags - these carousels should use the `imagesToPrefetch` prop instead. Defaults to `5`. | ||
#### cellPadding | ||
@@ -99,0 +102,0 @@ `PropTypes.number` |
@@ -5,3 +5,2 @@ import React, { Component, Children, cloneElement } from 'react'; | ||
import merge from 'lodash.merge'; | ||
import inRange from 'lodash.inrange'; | ||
import ms from 'ms'; | ||
@@ -36,2 +35,3 @@ import autobind from 'class-autobind'; | ||
imagesToPrefetch: PropTypes.number, | ||
maxRenderedSlides: PropTypes.number, | ||
cellPadding: PropTypes.number, | ||
@@ -83,2 +83,3 @@ slideWidth: PropTypes.string, | ||
imagesToPrefetch: 5, | ||
maxRenderedSlides: 5, | ||
cellPadding: 0, | ||
@@ -115,3 +116,4 @@ transitionDuration: 500, | ||
componentWillReceiveProps(newProps) { | ||
// eslint-disable-next-line | ||
UNSAFE_componentWillReceiveProps(newProps) { | ||
const { currentSlide } = this.state; | ||
@@ -466,3 +468,3 @@ const numChildren = Children.count(newProps.children); | ||
const { children, infinite, cellPadding, slideWidth, slideHeight, transition, transitionDuration, | ||
style, easing } = this.props; | ||
style, easing, lazyLoad } = this.props; | ||
const { slideDimensions, currentSlide, loading, loadedImages } = this.state; | ||
@@ -507,4 +509,7 @@ this._allImagesLoaded = true; | ||
}); | ||
const slidesToRender = this.getIndicesToRender(); | ||
if (this.shouldRenderSlide(child, index)) { | ||
// Only render the actual slide content if lazy loading is disabled, the image is already loaded, or we | ||
// are within the configured proximity to the selected slide index. | ||
if (!lazyLoad || (imgSrc && loadedImages[imgSrc]) || slidesToRender.indexOf(index) > -1) { | ||
// If the slide contains an image, set explicit width/height and add load listener | ||
@@ -556,43 +561,38 @@ if (imgSrc && loadedImages[imgSrc]) { | ||
/** | ||
* If lazy loading is enabled, this method attempts to determine whether the given slide index should be rendered. | ||
* For img slides with src attributes, we render the slides only if the image has been fetched. For non-img slides, | ||
* we attempt to determine whether the slide content should be rendered based on the currentSlide index and the | ||
* transitioningFrom slide index, if set, to provide the best balance between showing the slides as they transition | ||
* and keeping the DOM light if there are many slides in the carousel. | ||
* This method returns the slides indices that should be fully rendered given the current lazyLoad and | ||
* maxRenderedSlides settings. | ||
* | ||
* @param {Object} slide The slide component to check. | ||
* @param {Number} index The index of the specified slide component. | ||
* @returns {Boolean} True if the slide should be rendered, else False. | ||
* @returns {Array} Array of slide indices indicating which indices should be fully rendered. | ||
*/ | ||
shouldRenderSlide(slide, index) { | ||
const { currentSlide, loadedImages, transitioningFrom } = this.state; | ||
const { lazyLoad, children, infinite } = this.props; | ||
getIndicesToRender() { | ||
const { currentSlide, transitioningFrom } = this.state; | ||
const { children, infinite, maxRenderedSlides } = this.props; | ||
const numSlides = Children.count(children); | ||
const imgSrc = slide.props.src; | ||
if (!lazyLoad) { | ||
return true; | ||
function genIndices(startIndex, endIndex) { | ||
const indices = []; | ||
for (let i = startIndex; i <= endIndex; i++) { | ||
if (infinite && i < 0) { | ||
indices.push(numSlides + i); | ||
} else if (infinite && i >= numSlides) { | ||
indices.push(i - numSlides); | ||
} else { | ||
indices.push(i); | ||
} | ||
} | ||
return indices; | ||
} | ||
if (imgSrc) { | ||
return !!loadedImages[imgSrc]; | ||
} | ||
// Figure out what slide indices need to be rendered | ||
const maxSlides = Math.max(1, maxRenderedSlides); | ||
const prevSlidesToRender = Math.floor((maxSlides - 1) / 2); | ||
const nextSlidesToRender = Math.floor(maxSlides / 2); | ||
let indices = genIndices(currentSlide - prevSlidesToRender, currentSlide + nextSlidesToRender); | ||
// Render at least 5 slides centered around the current slide, or the slide we just transitioned from | ||
if (inRange(index, currentSlide - 2, currentSlide + 3) || | ||
(transitioningFrom !== null && inRange(index, transitioningFrom - 2, transitioningFrom + 3))) { | ||
return true; | ||
} else if (infinite) { | ||
// In infinite mode, we also want to render the adjacent slides if we're at the beginning or the end | ||
if (currentSlide <= 1 && index >= numSlides - 2 || | ||
currentSlide >= numSlides - 2 && index <= 1 || | ||
transitioningFrom !== null && ( | ||
transitioningFrom <= 1 && index >= numSlides - 2 || | ||
transitioningFrom >= numSlides - 2 && index <= 1 | ||
)) { | ||
return true; | ||
} | ||
if (transitioningFrom !== null) { | ||
// Also render the slides around the previous slide during a transition | ||
indices = indices.concat(genIndices(transitioningFrom - prevSlidesToRender, transitioningFrom + nextSlidesToRender)); | ||
} | ||
return false; | ||
return indices; | ||
} | ||
@@ -599,0 +599,0 @@ |
@@ -384,2 +384,72 @@ import React, { Fragment } from 'react'; | ||
}); | ||
describe('maxRenderedSlides', () => { | ||
it('should only render the specified maxRenderedSlides', () => { | ||
renderToJsdom( | ||
<Carousel | ||
initialSlide={ 2 } | ||
slideWidth='300px' | ||
viewportWidth='300px' | ||
maxRenderedSlides={ 3 } | ||
infinite={ false } | ||
> | ||
<div id='slide1'/> | ||
<div id='slide2'/> | ||
<div id='slide3'/> | ||
<div id='slide4'/> | ||
<div id='slide5'/> | ||
<div id='slide6'/> | ||
<div id='slide7'/> | ||
<div id='slide8'/> | ||
<div id='slide9'/> | ||
<div id='slide10'/> | ||
</Carousel> | ||
); | ||
const loadingSlides = document.querySelectorAll('.carousel-slide.carousel-slide-loading'); | ||
expect(loadingSlides.length).to.equal(7); | ||
expect(document.getElementById('slide1')).to.not.exist; | ||
expect(document.getElementById('slide2')).to.exist; | ||
expect(document.getElementById('slide3')).to.exist; | ||
expect(document.getElementById('slide4')).to.exist; | ||
expect(document.getElementById('slide5')).to.not.exist; | ||
expect(document.getElementById('slide6')).to.not.exist; | ||
expect(document.getElementById('slide7')).to.not.exist; | ||
expect(document.getElementById('slide8')).to.not.exist; | ||
expect(document.getElementById('slide9')).to.not.exist; | ||
expect(document.getElementById('slide10')).to.not.exist; | ||
}); | ||
it('should render the correct slides when infinite is true and the selected slide is near the end', () => { | ||
renderToJsdom( | ||
<Carousel | ||
initialSlide={ 0 } | ||
slideWidth='300px' | ||
viewportWidth='300px' | ||
maxRenderedSlides={ 3 } | ||
infinite={ true } | ||
> | ||
<div id='slide1'/> | ||
<div id='slide2'/> | ||
<div id='slide3'/> | ||
<div id='slide4'/> | ||
<div id='slide5'/> | ||
<div id='slide6'/> | ||
<div id='slide7'/> | ||
<div id='slide8'/> | ||
<div id='slide9'/> | ||
<div id='slide10'/> | ||
</Carousel> | ||
); | ||
expect(document.getElementById('slide1')).to.exist; | ||
expect(document.getElementById('slide2')).to.exist; | ||
expect(document.getElementById('slide3')).to.not.exist; | ||
expect(document.getElementById('slide4')).to.not.exist; | ||
expect(document.getElementById('slide5')).to.not.exist; | ||
expect(document.getElementById('slide6')).to.not.exist; | ||
expect(document.getElementById('slide7')).to.not.exist; | ||
expect(document.getElementById('slide8')).to.not.exist; | ||
expect(document.getElementById('slide9')).to.not.exist; | ||
expect(document.getElementById('slide10')).to.exist; | ||
}); | ||
}); | ||
}); |
@@ -18,10 +18,10 @@ var webpack = require('webpack'); | ||
test: /\.css$/, | ||
loader: 'style!css' | ||
loader: 'style-loader!css' | ||
}, { | ||
test: /\.less$/, | ||
loader: 'style!css!less' | ||
loader: 'style-loader!css-loader!less-loader' | ||
}, | ||
{ | ||
test : /\.jsx?/, | ||
loader : 'babel' | ||
loader : 'babel-loader' | ||
} | ||
@@ -28,0 +28,0 @@ ] |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
114282
23
2754
224
33
Updatedclassnames@^2.2.6
Updatedlodash.merge@^4.6.2
Updatedprop-types@^15.7.2