sh-react-carousel
Version:
A carousel component written for ReactJS application written in TypeScript.
85 lines • 3.71 kB
JavaScript
"use strict";
const React = require('react');
const ReactDOM = require('react-dom');
const lodash_1 = require('lodash');
const CarouselItem_1 = require('./CarouselItem');
class ReactCarousel extends React.Component {
constructor(props) {
super(props);
this.onItemClick = this.onItemClick.bind(this);
this.onNext = this.onNext.bind(this);
this.onPrev = this.onPrev.bind(this);
this.onResize = lodash_1.debounce(this.onResize.bind(this), 300);
window.addEventListener('resize', this.onResize);
this.state = {
selIndex: props.selIndex,
viewIndex: props.selIndex,
width: props.width || 200
};
}
onNext() {
let idx = this.state.viewIndex;
if (idx < this.props.items.length && this.itemsLeft > 0) {
idx++;
this.setState({
viewIndex: idx
});
}
}
onPrev() {
let idx = this.state.viewIndex;
if (idx > 0) {
idx--;
this.setState({
viewIndex: idx
});
}
}
onItemClick(idx, key) {
this.props.onItemClick(idx, key);
}
componentDidUpdate() {
if (this.itemsLeft < 0) {
let vi = this.state.viewIndex;
vi += this.itemsLeft;
this.itemsLeft = 0;
this.setState({
viewIndex: vi
});
}
}
componentWillReceiveProps(props) {
this.setState({
selIndex: props.selIndex
});
}
_calculatePosition() {
let props = this.props, state = this.state, buttonWidth = this.props.buttonWidth || 42, width = state.width - buttonWidth * 2, gutter = props.gutter || 0, viewIndex = state.viewIndex, totalItems = props.items.length, availableSpaces = Math.floor(width / (props.minItemWidth + gutter)), visibleItems = availableSpaces > totalItems ? totalItems : availableSpaces, itemsLeft = totalItems - visibleItems - viewIndex, itemWidth = (width - (gutter * visibleItems)) / visibleItems, xPos = -viewIndex * (itemWidth + gutter);
this.itemsLeft = itemsLeft;
return {
x: xPos,
itemWidth: itemWidth,
};
}
componentDidMount() {
this.onResize();
}
onResize() {
let v = ReactDOM.findDOMNode(this);
let c = v.getBoundingClientRect();
this.setState({
width: c.width
});
}
render() {
let props = this.props, state = this.state, clz = props.className || "", gutterWidth = props.gutter || 0, pos = this._calculatePosition(), itemRenderer = props.itemRenderer || null, xPos = pos.x, style = {
width: ((pos.itemWidth + gutterWidth) * props.items.length) + 'px',
transform: 'translate(' + [xPos + 'px', '0px'] + ')'
}, items = this.props.items.map((e, i) => {
return (itemRenderer && itemRenderer(e, i, pos.itemWidth, this.onItemClick)) || (React.createElement(CarouselItem_1.CarouselItem, {label: e.label, key: e.key, onClick: this.onItemClick, index: i, width: pos.itemWidth, itemKey: e.key, isSelected: props.selIndex === i}));
});
return (React.createElement("div", {className: "react-carousel " + clz}, React.createElement("div", {className: "rc-btn prev", onClick: this.onPrev}, props.prevButton), React.createElement("div", {className: "rc-viewport"}, React.createElement("div", {className: "rc-viewport-wrapper", style: style}, items)), React.createElement("div", {className: "rc-btn next", onClick: this.onNext}, props.nextButton)));
}
}
exports.ReactCarousel = ReactCarousel;
//# sourceMappingURL=ReactCarousel.js.map