react-free-carousel
Advanced tools
Comparing version 0.2.8 to 1.0.0
@@ -6,2 +6,3 @@ 'use strict'; | ||
}); | ||
exports.ReactFreeCarouselTile = undefined; | ||
@@ -18,6 +19,2 @@ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _jquery = require('jquery'); | ||
var _jquery2 = _interopRequireDefault(_jquery); | ||
var _lodash = require('lodash.debounce'); | ||
@@ -31,2 +28,6 @@ | ||
var _defaultStyles = require('./example/defaultStyles.css'); | ||
var _defaultStyles2 = _interopRequireDefault(_defaultStyles); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -42,3 +43,3 @@ | ||
var RESIZE = 'resize orientationchange'; | ||
var RENDER_DEBOUNCING_TIMEOUT = 600; | ||
var toArray = function toArray(item) { | ||
@@ -48,2 +49,21 @@ return item instanceof Array ? item : [item]; | ||
var prepareParam = function prepareParam(param, basis) { | ||
var decrement = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; | ||
if (typeof param === 'string') { | ||
if (param.includes('%') && basis) { | ||
return Math.floor(parseInt(param, 10) / 100 * basis) - decrement + 'px'; | ||
} else if (!basis && decrement !== 0) { | ||
return 'calc(' + param + ' - ' + decrement + 'px)'; | ||
} | ||
return param; | ||
} | ||
if (typeof param === 'number') { | ||
return param - decrement + 'px'; | ||
} | ||
return '100%'; | ||
}; | ||
var ReactFreeCarousel = function (_React$Component) { | ||
@@ -71,2 +91,4 @@ _inherits(ReactFreeCarousel, _React$Component); | ||
this.debouncingRender = (0, _lodash2.default)(this.reRender, RENDER_DEBOUNCING_TIMEOUT); | ||
setTimeout(function () { | ||
@@ -82,3 +104,4 @@ var totalPages = _this2.calculateTotalPages(); | ||
} | ||
(0, _jquery2.default)(window).on(RESIZE, (0, _lodash2.default)(_this2.reRender, 500)); | ||
window.addEventListener('resize', _this2.debouncingRender); | ||
window.addEventListener('orientationchange', _this2.debouncingRender); | ||
}, 100); | ||
@@ -105,3 +128,4 @@ } | ||
this.stopCarousel(); | ||
(0, _jquery2.default)(window).off(RESIZE, this.reRender); | ||
window.removeEventListener('resize', this.debouncingRender); | ||
window.removeEventListener('orientationchange', this.debouncingRender); | ||
} | ||
@@ -115,2 +139,4 @@ }, { | ||
this.stopCarousel(); | ||
var totalPages = this.calculateTotalPages(); | ||
@@ -123,6 +149,6 @@ var page = scrollToStart && this.state.pages !== totalPages ? 0 : this.state.page; | ||
this.stopCarousel(); | ||
if (page === 0) { | ||
(0, _jquery2.default)(this.container).css('margin-left', '0px'); | ||
if (page === 0 && this.container) { | ||
this.container.style.transition = 'none'; | ||
this.container.style.marginLeft = '0px'; | ||
this.container.style.transition = 'margin-left ' + this.props.transitionSpeed + 'ms'; | ||
} | ||
@@ -172,3 +198,3 @@ | ||
}); | ||
(0, _jquery2.default)(this.container).css('margin-left', '-' + this.pageToOffset(newPage) + 'px'); | ||
this.container.style.marginLeft = '-' + this.pageToOffset(newPage) + 'px'; | ||
} | ||
@@ -178,7 +204,6 @@ }, { | ||
value: function gotoTile(index) { | ||
var $container = (0, _jquery2.default)(this.container); | ||
var $tile = (0, _jquery2.default)($container.children().get(index)); | ||
var tile = this.container.children[index]; | ||
if ($tile.length) { | ||
this.gotoPage(Number($tile.attr('data-page'))); | ||
if (tile) { | ||
this.gotoPage(Number(tile.getAttribute('data-page'))); | ||
} | ||
@@ -189,7 +214,6 @@ } | ||
value: function pageToOffset(page) { | ||
var $container = (0, _jquery2.default)(this.container); | ||
var $target = $container.children('[data-page=' + page + '][data-first=true]'); | ||
var pageElement = this.container.querySelector('[data-page="' + page + '"]'); | ||
if ($target.length) { | ||
return parseInt((0, _jquery2.default)($target.get(0)).attr('data-offset'), 10); | ||
if (pageElement && pageElement.getAttribute('data-first') === 'true') { | ||
return parseInt(pageElement.getAttribute('data-offset'), 10); | ||
} | ||
@@ -206,5 +230,5 @@ return 0; | ||
value: function calculateTotalPages() { | ||
var $container = (0, _jquery2.default)(this.container); | ||
var $children = $container.children(); | ||
var wrapperWidth = this.wrapper.clientWidth; | ||
var _this7 = this; | ||
var wrapperWidth = this.wrapper ? this.wrapper.clientWidth : 0; | ||
var offsetPage = new Map(); | ||
@@ -214,31 +238,32 @@ var pageOffset = new Map(); | ||
$children.each(function (index, tile) { | ||
var $tile = (0, _jquery2.default)(tile); | ||
var tileLeft = tile.offsetLeft - parseInt(window.getComputedStyle(tile).marginLeft, 10); | ||
var tileWidth = tile.clientWidth; | ||
if (this.container.children.length) { | ||
Array.from(this.container.children).forEach(function (tile, index) { | ||
var tileLeft = tile.offsetLeft - _this7.container.offsetLeft - parseInt(window.getComputedStyle(tile).marginLeft, 10); | ||
var tileWidth = tile.clientWidth; | ||
if (offsetPage.has(tileLeft)) { | ||
$tile.attr('data-first', 'false'); | ||
$tile.attr('data-page', offsetPage.get(tileLeft)); | ||
$tile.attr('data-offset', tileLeft); | ||
} else { | ||
var currentPageOffset = pageOffset.get(pages) || 0; | ||
if (offsetPage.has(tileLeft)) { | ||
tile.setAttribute('data-first', 'false'); | ||
tile.setAttribute('data-page', '' + offsetPage.get(tileLeft)); | ||
tile.setAttribute('data-offset', '' + tileLeft); | ||
} else { | ||
var currentPageOffset = pageOffset.get(pages) || 0; | ||
// check if the tile fully fit in the current page | ||
if (tileLeft >= currentPageOffset && tileLeft + tileWidth <= currentPageOffset + wrapperWidth) { | ||
if (index === 0) { | ||
$tile.attr('data-first', 'true'); | ||
// check if the tile fully fit in the current page | ||
if (tileLeft >= currentPageOffset && tileLeft + tileWidth <= currentPageOffset + wrapperWidth) { | ||
if (index === 0) { | ||
tile.setAttribute('data-first', 'true'); | ||
} | ||
} else { | ||
pages = pages + 1; | ||
tile.setAttribute('data-first', 'true'); | ||
} | ||
} else { | ||
pages = pages + 1; | ||
$tile.attr('data-first', 'true'); | ||
tile.setAttribute('data-page', '' + pages); | ||
tile.setAttribute('data-offset', '' + tileLeft); | ||
offsetPage.set(tileLeft, pages); | ||
if (!pageOffset.has(pages)) { | ||
pageOffset.set(pages, tileLeft); | ||
} | ||
} | ||
$tile.attr('data-page', pages); | ||
$tile.attr('data-offset', tileLeft); | ||
offsetPage.set(tileLeft, pages); | ||
if (!pageOffset.has(pages)) { | ||
pageOffset.set(pages, tileLeft); | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
@@ -248,18 +273,5 @@ return pages; | ||
}, { | ||
key: 'prepareParam', | ||
value: function prepareParam(param) { | ||
if (typeof param === 'string') { | ||
return param; | ||
} | ||
if (typeof param === 'number') { | ||
return param + 'px'; | ||
} | ||
return '100%'; | ||
} | ||
}, { | ||
key: 'renderPagination', | ||
value: function renderPagination() { | ||
var _this7 = this; | ||
var _this8 = this; | ||
@@ -269,5 +281,5 @@ return _react2.default.createElement( | ||
{ | ||
className: this.props.paginationClass, | ||
className: this.props.paginationClass || _defaultStyles2.default.defaultPaginationClass, | ||
ref: function ref(node) { | ||
_this7.pagination = node; | ||
_this8.pagination = node; | ||
}, | ||
@@ -280,7 +292,7 @@ role: 'navigation' }, | ||
'aria-label': 'Goto Page ' + (i + 1), | ||
className: '\n ' + _this7.props.paginationDotClass + '\n ' + (i === _this7.state.page ? _this7.props.paginationDotActiveClass : ''), | ||
'data-active': i === _this7.state.page ? 'true' : 'false', | ||
className: '\n ' + _this8.props.paginationDotClass + '\n ' + (i === _this8.state.page ? _this8.props.paginationDotActiveClass : ''), | ||
'data-active': i === _this8.state.page ? 'true' : 'false', | ||
key: i, | ||
onClick: function onClick() { | ||
_this7.gotoPage(i); | ||
_this8.gotoPage(i); | ||
} }, | ||
@@ -295,10 +307,10 @@ i + 1 | ||
value: function renderArrows(kind) { | ||
var _this8 = this; | ||
var _this9 = this; | ||
var calculateNextPage = function calculateNextPage(direction) { | ||
if (direction === 'next' && _this8.state.page < _this8.state.pages) { | ||
return _this8.state.page + 1; | ||
if (direction === 'next' && _this9.state.page < _this9.state.pages) { | ||
return _this9.state.page + 1; | ||
} | ||
if (direction === 'prev' && _this8.state.page > 0) { | ||
return _this8.state.page - 1; | ||
if (direction === 'prev' && _this9.state.page > 0) { | ||
return _this9.state.page - 1; | ||
} | ||
@@ -309,8 +321,9 @@ return null; | ||
var nextPage = calculateNextPage(kind); | ||
var classPart = (0, _lodash4.default)(kind) + 'Class'; | ||
return _react2.default.createElement('button', { | ||
className: this.props['arrow' + (0, _lodash4.default)(kind) + 'Class'], | ||
className: this.props['arrow' + classPart] || _defaultStyles2.default['defaultArrow' + classPart], | ||
disabled: nextPage === null, | ||
onClick: function onClick() { | ||
_this8.gotoPage(nextPage); | ||
_this9.gotoPage(nextPage); | ||
}, | ||
@@ -323,3 +336,3 @@ role: 'button', | ||
value: function render() { | ||
var _this9 = this; | ||
var _this10 = this; | ||
@@ -334,11 +347,22 @@ var _props = this.props, | ||
minPagesToShowPagination = _props.minPagesToShowPagination, | ||
arrows = _props.arrows; | ||
arrows = _props.arrows, | ||
tileMargin = _props.tileMargin; | ||
var childrenToRender = Array.isArray(children) ? children : [children]; | ||
var childrenToRender = _react2.default.Children.map(Array.from(toArray(children)), function (child) { | ||
if (child.type === ReactFreeCarouselTile) { | ||
return _react2.default.cloneElement(child, { | ||
parent: _this10, | ||
tileMargin: tileMargin, | ||
parentWidth: _this10.wrapper && _this10.wrapper.clientWidth + tileMargin, | ||
updateParent: _this10.reRender | ||
}); | ||
} | ||
return child; | ||
}); | ||
var wrapperStyling = { | ||
position: 'relative', | ||
width: this.prepareParam(width), | ||
height: this.prepareParam(height) | ||
width: prepareParam(width, null), | ||
height: prepareParam(height, null) | ||
}; | ||
@@ -348,5 +372,5 @@ | ||
position: 'relative', | ||
width: '100%', | ||
overflow: 'hidden', | ||
height: '100%' | ||
width: 'calc(100% + ' + prepareParam(tileMargin) + ')', | ||
height: 'calc(100% + ' + prepareParam(tileMargin) + ')' | ||
}; | ||
@@ -356,3 +380,3 @@ | ||
overflow: 'hidden', | ||
position: 'relative', | ||
position: 'static', | ||
alignContent: 'flex-start', | ||
@@ -363,2 +387,3 @@ display: 'flex', | ||
height: '100%', | ||
transform: 'translate(-' + prepareParam(tileMargin) + ', -' + prepareParam(tileMargin) + ')', | ||
transition: 'margin-left ' + transitionSpeed + 'ms' | ||
@@ -372,3 +397,3 @@ }; | ||
ref: function ref(node) { | ||
_this9.wrapper = node; | ||
_this10.wrapper = node; | ||
}, | ||
@@ -383,3 +408,3 @@ style: wrapperStyling }, | ||
ref: function ref(node) { | ||
_this9.container = node; | ||
_this10.container = node; | ||
}, | ||
@@ -408,2 +433,3 @@ style: containerStyling }, | ||
width: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]), | ||
tileMargin: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]), | ||
interval: _propTypes2.default.number, | ||
@@ -433,2 +459,3 @@ autoplay: _propTypes2.default.bool, | ||
page: 0, | ||
tileMargin: 0, | ||
slide: null, | ||
@@ -442,2 +469,80 @@ minPagesToShowPagination: 2, | ||
arrowNextClass: '' | ||
}; | ||
/* Tile*/ | ||
var ReactFreeCarouselTile = exports.ReactFreeCarouselTile = function (_React$Component2) { | ||
_inherits(ReactFreeCarouselTile, _React$Component2); | ||
function ReactFreeCarouselTile(props) { | ||
_classCallCheck(this, ReactFreeCarouselTile); | ||
var _this11 = _possibleConstructorReturn(this, (ReactFreeCarouselTile.__proto__ || Object.getPrototypeOf(ReactFreeCarouselTile)).call(this, props)); | ||
_this11.state = { | ||
parentWidth: null | ||
}; | ||
return _this11; | ||
} | ||
_createClass(ReactFreeCarouselTile, [{ | ||
key: 'componentWillReceiveProps', | ||
value: function componentWillReceiveProps(nextProps) { | ||
var _this12 = this; | ||
if (nextProps.parentWidth !== this.props.parentWidth) { | ||
setTimeout(function () { | ||
_this12.props.updateParent(); | ||
}, 0); | ||
} | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var _this13 = this; | ||
var _props2 = this.props, | ||
parentWidth = _props2.parentWidth, | ||
height = _props2.height, | ||
width = _props2.width, | ||
tileMargin = _props2.tileMargin; | ||
var style = { | ||
height: prepareParam(height, null, tileMargin), | ||
width: prepareParam(width, parentWidth, tileMargin), | ||
marginTop: '' + prepareParam(tileMargin), | ||
marginLeft: '' + prepareParam(tileMargin) | ||
}; | ||
return _react2.default.createElement( | ||
'div', | ||
{ | ||
className: this.props.className || _defaultStyles2.default.defaultTile, | ||
ref: function ref(node) { | ||
_this13.tile = node; | ||
}, | ||
style: style }, | ||
this.props.children | ||
); | ||
} | ||
}]); | ||
return ReactFreeCarouselTile; | ||
}(_react2.default.Component); | ||
ReactFreeCarouselTile.propTypes = { | ||
children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.arrayOf(_react2.default.PropTypes.node), _react2.default.PropTypes.node]), | ||
updateParent: _propTypes2.default.func.isRequired, | ||
parentWidth: _propTypes2.default.number, | ||
className: _propTypes2.default.string, | ||
tileMargin: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]), | ||
height: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]), | ||
width: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]) | ||
}; | ||
ReactFreeCarouselTile.defaultProps = { | ||
className: null, | ||
tileMargin: 0, | ||
width: '100%', | ||
height: '100%' | ||
}; |
{ | ||
"name": "react-free-carousel", | ||
"version": "0.2.8", | ||
"version": "1.0.0", | ||
"description": "Carousel component for free flex-box layout built with React.", | ||
@@ -42,3 +42,2 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"jquery": "3.2.1", | ||
"lodash.capitalize": "4.2.1", | ||
@@ -45,0 +44,0 @@ "lodash.debounce": "4.0.8" |
@@ -25,2 +25,4 @@ # react-free-carousel [![npm](https://img.shields.io/npm/v/react-free-carousel.svg?style=flat-square)](https://www.npmjs.com/package/react-free-carousel) | ||
## Usage | ||
### Carousel with custom tiles | ||
```js | ||
@@ -32,14 +34,10 @@ import React from 'react'; | ||
const App = () => ( | ||
<div className={css.carousel}> | ||
<ReactFreeCarousel> | ||
<div className={css.tileBig}>1</div> | ||
<div className={css.tileBigTripple}>2</div> | ||
<div className={css.tileMedium}>3</div> | ||
<div className={css.tileMedium}>4</div> | ||
<div className={css.tileBigTripple}>5</div> | ||
<div className={css.tileBig}>6</div> | ||
<div className={css.tileBig}>7</div> | ||
<div className={css.tileSmall}>8</div> | ||
<div className={css.tileSmall}>9</div> | ||
<div className={css.tileBigDouble}>10</div> | ||
<div> | ||
<ReactFreeCarousel width={'600px'} height={'400px'}> | ||
<div className={css.smallTileClass}>1</div> | ||
<div className={css.smallTileClass}>2</div> | ||
<div className={css.mediumTileClass}>3</div> | ||
<div className={css.mediumTileClass}>4</div> | ||
<div className={css.bigTileClass}>5</div> | ||
<div className={css.bigTileClass}>6</div> | ||
</ReactFreeCarousel> | ||
@@ -54,4 +52,36 @@ </div> | ||
### Carousel with ReactFreeCarouselTile | ||
```js | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import ReactFreeCarousel, { ReactFreeCarouselTile } from 'react-free-carousel'; | ||
const App = () => ( | ||
<div style={{width: '70vw', height: '30vh'}}> | ||
<ReactFreeCarousel | ||
arrows={true} | ||
autoplay={false} | ||
tileMargin={10}> | ||
<ReactFreeCarouselTile width={140} height={'100%'}>Tile 1</ReactFreeCarouselTile> | ||
<ReactFreeCarouselTile width={280} height={'50%'}>Tile 2</ReactFreeCarouselTile> | ||
<ReactFreeCarouselTile width={280} height={'50%'}>Tile 3</ReactFreeCarouselTile> | ||
<ReactFreeCarouselTile width={'50%'} height={'100%'}>Tile 4</ReactFreeCarouselTile> | ||
<ReactFreeCarouselTile width={'25%'} height={`${100/3}%`}>Tile 5</ReactFreeCarouselTile> | ||
<ReactFreeCarouselTile width={'25%'} height={`${100/3}%`}>Tile 6</ReactFreeCarouselTile> | ||
<ReactFreeCarouselTile width={'25%'} height={`${100/3}%`}>Tile 7</ReactFreeCarouselTile> | ||
<ReactFreeCarouselTile width={'25%'} height="50%">Tile 8</ReactFreeCarouselTile> | ||
<ReactFreeCarouselTile width={'25%'} height="50%">Tile 9</ReactFreeCarouselTile> | ||
</ReactFreeCarousel> | ||
</div> | ||
); | ||
const appRoot = document.createElement('div'); | ||
document.body.appendChild(appRoot); | ||
ReactDOM.render(<App />, appRoot); | ||
``` | ||
### Properties | ||
#### ReactFreeCarousel | ||
| Propertie | Type | Default Value | Description | | ||
@@ -64,2 +94,3 @@ |----------------------------|---------------------|---------------|-------------| | ||
| `width` | string or number | '100%' | Carousel width. | ||
| `tileMargin` | string or number | 0 | Margin between `ReactFreeCarouselTile` tiles. | ||
| `autoplay` | boolean | true | Autostart carousel. | ||
@@ -77,2 +108,11 @@ | `page` | number | 0 | Page to show (0-indexed). | ||
#### ReactFreeCarouselTile | ||
| Propertie | Type | Default Value | Description | | ||
|----------------------------|---------------------|---------------|-------------| | ||
| `className` | string | null | Tile custom className. | ||
| `height` | string or number | '100%' | Tile height. | ||
| `width` | string or number | '100%' | Tile width. | ||
## Development and testing | ||
@@ -79,0 +119,0 @@ |
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import $ from 'jquery'; | ||
import debounce from 'lodash.debounce'; | ||
import capitalize from 'lodash.capitalize'; | ||
const RESIZE = 'resize orientationchange'; | ||
import styles from './example/defaultStyles.css'; | ||
const RENDER_DEBOUNCING_TIMEOUT = 600; | ||
const toArray = item => item instanceof Array ? item : [item]; | ||
const prepareParam = (param, basis, decrement = 0) => { | ||
if (typeof param === 'string') { | ||
if (param.includes('%') && basis) { | ||
return `${Math.floor(parseInt(param, 10) / 100 * basis) - decrement}px`; | ||
} else if (!basis && decrement !== 0) { | ||
return `calc(${param} - ${decrement}px)`; | ||
} | ||
return param; | ||
} | ||
if (typeof param === 'number') { | ||
return `${param - decrement}px`; | ||
} | ||
return '100%'; | ||
}; | ||
export default class ReactFreeCarousel extends React.Component { | ||
@@ -22,2 +40,4 @@ constructor(props) { | ||
componentDidMount() { | ||
this.debouncingRender = debounce(this.reRender, RENDER_DEBOUNCING_TIMEOUT); | ||
setTimeout(() => { | ||
@@ -33,3 +53,4 @@ const totalPages = this.calculateTotalPages(); | ||
} | ||
$(window).on(RESIZE, debounce(this.reRender, 500)); | ||
window.addEventListener('resize', this.debouncingRender); | ||
window.addEventListener('orientationchange', this.debouncingRender); | ||
}, 100); | ||
@@ -52,6 +73,9 @@ } | ||
this.stopCarousel(); | ||
$(window).off(RESIZE, this.reRender); | ||
window.removeEventListener('resize', this.debouncingRender); | ||
window.removeEventListener('orientationchange', this.debouncingRender); | ||
} | ||
reRender(scrollToStart = true) { | ||
this.stopCarousel(); | ||
const totalPages = this.calculateTotalPages(); | ||
@@ -64,6 +88,6 @@ let page = scrollToStart && this.state.pages !== totalPages ? 0 : this.state.page; | ||
this.stopCarousel(); | ||
if (page === 0) { | ||
$(this.container).css('margin-left', '0px'); | ||
if (page === 0 && this.container) { | ||
this.container.style.transition = 'none'; | ||
this.container.style.marginLeft = '0px'; | ||
this.container.style.transition = `margin-left ${this.props.transitionSpeed}ms`; | ||
} | ||
@@ -106,11 +130,10 @@ | ||
}); | ||
$(this.container).css('margin-left', `-${this.pageToOffset(newPage)}px`); | ||
this.container.style.marginLeft = `-${this.pageToOffset(newPage)}px`; | ||
} | ||
gotoTile(index) { | ||
const $container = $(this.container); | ||
const $tile = $($container.children().get(index)); | ||
const tile = this.container.children[index]; | ||
if ($tile.length) { | ||
this.gotoPage(Number($tile.attr('data-page'))); | ||
if (tile) { | ||
this.gotoPage(Number(tile.getAttribute('data-page'))); | ||
} | ||
@@ -120,7 +143,6 @@ } | ||
pageToOffset(page) { | ||
const $container = $(this.container); | ||
const $target = $container.children(`[data-page=${page}][data-first=true]`); | ||
const pageElement = this.container.querySelector(`[data-page="${page}"]`); | ||
if ($target.length) { | ||
return parseInt($($target.get(0)).attr('data-offset'), 10); | ||
if (pageElement && pageElement.getAttribute('data-first') === 'true') { | ||
return parseInt(pageElement.getAttribute('data-offset'), 10); | ||
} | ||
@@ -135,5 +157,3 @@ return 0; | ||
calculateTotalPages() { | ||
const $container = $(this.container); | ||
const $children = $container.children(); | ||
const wrapperWidth = this.wrapper.clientWidth; | ||
const wrapperWidth = this.wrapper ? this.wrapper.clientWidth : 0; | ||
const offsetPage = new Map(); | ||
@@ -143,32 +163,35 @@ const pageOffset = new Map(); | ||
$children.each((index, tile) => { | ||
const $tile = $(tile); | ||
const tileLeft = tile.offsetLeft - parseInt(window.getComputedStyle(tile).marginLeft, 10); | ||
const tileWidth = tile.clientWidth; | ||
if (this.container.children.length) { | ||
Array.from(this.container.children).forEach((tile, index) => { | ||
const tileLeft = tile.offsetLeft - | ||
this.container.offsetLeft - | ||
parseInt(window.getComputedStyle(tile).marginLeft, 10); | ||
const tileWidth = tile.clientWidth; | ||
if (offsetPage.has(tileLeft)) { | ||
$tile.attr('data-first', 'false'); | ||
$tile.attr('data-page', offsetPage.get(tileLeft)); | ||
$tile.attr('data-offset', tileLeft); | ||
} else { | ||
const currentPageOffset = pageOffset.get(pages) || 0; | ||
if (offsetPage.has(tileLeft)) { | ||
tile.setAttribute('data-first', 'false'); | ||
tile.setAttribute('data-page', `${offsetPage.get(tileLeft)}`); | ||
tile.setAttribute('data-offset', `${tileLeft}`); | ||
} else { | ||
const currentPageOffset = pageOffset.get(pages) || 0; | ||
// check if the tile fully fit in the current page | ||
if (tileLeft >= currentPageOffset && | ||
// check if the tile fully fit in the current page | ||
if (tileLeft >= currentPageOffset && | ||
tileLeft + tileWidth <= currentPageOffset + wrapperWidth) { | ||
if (index === 0) { | ||
$tile.attr('data-first', 'true'); | ||
if (index === 0) { | ||
tile.setAttribute('data-first', 'true'); | ||
} | ||
} else { | ||
pages = pages + 1; | ||
tile.setAttribute('data-first', 'true'); | ||
} | ||
} else { | ||
pages = pages + 1; | ||
$tile.attr('data-first', 'true'); | ||
tile.setAttribute('data-page', `${pages}`); | ||
tile.setAttribute('data-offset', `${tileLeft}`); | ||
offsetPage.set(tileLeft, pages); | ||
if (!pageOffset.has(pages)) { | ||
pageOffset.set(pages, tileLeft); | ||
} | ||
} | ||
$tile.attr('data-page', pages); | ||
$tile.attr('data-offset', tileLeft); | ||
offsetPage.set(tileLeft, pages); | ||
if (!pageOffset.has(pages)) { | ||
pageOffset.set(pages, tileLeft); | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
@@ -178,18 +201,6 @@ return pages; | ||
prepareParam(param) { | ||
if (typeof param === 'string') { | ||
return param; | ||
} | ||
if (typeof param === 'number') { | ||
return `${param}px`; | ||
} | ||
return '100%'; | ||
} | ||
renderPagination() { | ||
return ( | ||
<div | ||
className={this.props.paginationClass} | ||
className={this.props.paginationClass || styles.defaultPaginationClass} | ||
ref={node => { | ||
@@ -231,6 +242,7 @@ this.pagination = node; | ||
const nextPage = calculateNextPage(kind); | ||
const classPart = `${capitalize(kind)}Class`; | ||
return ( | ||
<button | ||
className={this.props[`arrow${capitalize(kind)}Class`]} | ||
className={this.props[`arrow${classPart}`] || styles[`defaultArrow${classPart}`]} | ||
disabled={nextPage === null} | ||
@@ -247,10 +259,20 @@ onClick={() => { | ||
const {children, className, width, height, transitionSpeed, showPagination, | ||
minPagesToShowPagination, arrows} = this.props; | ||
minPagesToShowPagination, arrows, tileMargin} = this.props; | ||
const childrenToRender = Array.isArray(children) ? children : [children]; | ||
const childrenToRender = React.Children.map(Array.from(toArray(children)), child => { | ||
if (child.type === ReactFreeCarouselTile) { | ||
return React.cloneElement(child, { | ||
parent: this, | ||
tileMargin, | ||
parentWidth: this.wrapper && this.wrapper.clientWidth + tileMargin, | ||
updateParent: this.reRender | ||
}); | ||
} | ||
return child; | ||
}); | ||
const wrapperStyling = { | ||
position: 'relative', | ||
width: this.prepareParam(width), | ||
height: this.prepareParam(height) | ||
width: prepareParam(width, null), | ||
height: prepareParam(height, null) | ||
}; | ||
@@ -260,5 +282,5 @@ | ||
position: 'relative', | ||
width: '100%', | ||
overflow: 'hidden', | ||
height: '100%' | ||
width: `calc(100% + ${prepareParam(tileMargin)})`, | ||
height: `calc(100% + ${prepareParam(tileMargin)})` | ||
}; | ||
@@ -268,3 +290,3 @@ | ||
overflow: 'hidden', | ||
position: 'relative', | ||
position: 'static', | ||
alignContent: 'flex-start', | ||
@@ -275,2 +297,3 @@ display: 'flex', | ||
height: '100%', | ||
transform: `translate(-${prepareParam(tileMargin)}, -${prepareParam(tileMargin)})`, | ||
transition: `margin-left ${transitionSpeed}ms` | ||
@@ -329,2 +352,6 @@ }; | ||
]), | ||
tileMargin: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number | ||
]), | ||
interval: PropTypes.number, | ||
@@ -354,2 +381,3 @@ autoplay: PropTypes.bool, | ||
page: 0, | ||
tileMargin: 0, | ||
slide: null, | ||
@@ -364,1 +392,71 @@ minPagesToShowPagination: 2, | ||
}; | ||
/* Tile*/ | ||
export class ReactFreeCarouselTile extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
parentWidth: null | ||
}; | ||
} | ||
componentWillReceiveProps(nextProps) { | ||
if (nextProps.parentWidth !== this.props.parentWidth) { | ||
setTimeout(() => { | ||
this.props.updateParent(); | ||
}, 0); | ||
} | ||
} | ||
render() { | ||
const {parentWidth, height, width, tileMargin} = this.props; | ||
const style = { | ||
height: prepareParam(height, null, tileMargin), | ||
width: prepareParam(width, parentWidth, tileMargin), | ||
marginTop: `${prepareParam(tileMargin)}`, | ||
marginLeft: `${prepareParam(tileMargin)}` | ||
}; | ||
return ( | ||
<div | ||
className={this.props.className || styles.defaultTile} | ||
ref={node => { | ||
this.tile = node; | ||
}} | ||
style={style}> | ||
{ this.props.children } | ||
</div> | ||
); | ||
} | ||
} | ||
ReactFreeCarouselTile.propTypes = { | ||
children: React.PropTypes.oneOfType([ | ||
React.PropTypes.arrayOf(React.PropTypes.node), | ||
React.PropTypes.node | ||
]), | ||
updateParent: PropTypes.func.isRequired, | ||
parentWidth: PropTypes.number, | ||
className: PropTypes.string, | ||
tileMargin: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number | ||
]), | ||
height: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number | ||
]), | ||
width: PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number | ||
]) | ||
}; | ||
ReactFreeCarouselTile.defaultProps = { | ||
className: null, | ||
tileMargin: 0, | ||
width: '100%', | ||
height: '100%' | ||
}; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
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
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
3
1
145
359593
4510
4
- Removedjquery@3.2.1
- Removedjquery@3.2.1(transitive)