react-jam-ui
Version:
React JAM UI components
210 lines (175 loc) • 7.01 kB
JavaScript
import React from 'react'
import classNames from 'classnames';
import IconAngleLeft from '../Icons/feather/IconAngleLeft'
import IconAngleRight from '../Icons/feather/IconAngleRight'
import './styles.styl'
class Slider extends React.Component {
constructor(props) {
super();
this.state = {
activeId: props.children.length ? props.children[0].props.id : null,
slideOutId: false
};
}
componentDidMount() {
if (this.props.children.length) {
this.changeSlide(this.props.children[0].props.id)
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.children.length && nextProps.children.length !== this.props.children.length) {
this.changeSlide(nextProps.children[0].props.id)
}
}
componentWillUnmount() {
clearTimeout(this.tm)
}
nextSlide = () => {
if (this.props.children.length) {
const activeId = this.state.activeId;
const activeIndex = this.props.children.findIndex( el => el.props.id == activeId);
const max = this.props.children.length - 1;
const next = activeIndex >= max ? (this.props.infinity ? 0 : activeIndex) : activeIndex + 1;
this.changeSlide(this.props.children[next].props.id)
}
}
onClickPrev = e => {
if (this.props.children.length) {
const activeId = this.state.activeId;
const activeIndex = this.props.children.findIndex( el => el.props.id == activeId);
const max = this.props.children.length - 1;
const prev = activeIndex <= 0 ? (this.props.infinity ? max : activeIndex) : activeIndex - 1;
this.changeSlide(this.props.children[prev].props.id)
}
}
onClickNext = e => {
this.nextSlide()
}
onClickThumb = e => {
const next = e.target.dataset.slideId;
if (next) {
this.changeSlide(next)
}
}
changeSlide = id => {
const current = this.state.activeId;
clearTimeout(this.tm)
if (id !== current) {
this.setState({
slideOutId: current,
activeId: id
})
}
if (this.props.animationTimeout) {
this.tm = setTimeout(this.nextSlide, parseInt(this.props.animationTimeout))
}
}
onSlideAnimationEnd = e => {
const slideId = e.target.dataset.slideId;
if (this.state.slideOutId == slideId) {
this.setState({
slideOutId: false
})
}
}
onClickSlide = e => {
}
render() {
const classes = classNames(
'slider',
this.props.className,
{
[`slider--empty`]: !this.props.children || this.props.children.length == 0
}
);
return (
<div className={ classes }>
<div className='slider-slides'>
{
React.Children.map(this.props.children, (Child, i) => {
if (Child === null) {
return null;
}
const id = Child.props.id || `${i+1}`;
return React.cloneElement(Child, {
id,
active: id == this.state.activeId,
slideOut: id == this.state.slideOutId,
animationClass: Child.props.animationClass || this.props.animationClass,
onClick: this.onClickSlide,
onAnimationEnd: this.onSlideAnimationEnd
});
})
}
</div>
{
this.props.children.length > 1 && this.props.prev
? <div className='slider-prev' onClick={ this.onClickPrev } title='Prevoius'><IconAngleLeft /></div>
: null
}
{
this.props.children.length > 1 && this.props.next
? <div className='slider-next' onClick={ this.onClickNext } title='Next'><IconAngleRight /></div>
: null
}
{
this.props.thumbsType !== 'none'
? <div className={'slider-thumbs' + ` slider-thumbs--${this.props.thumbsType}` }>
{
React.Children.map(this.props.children, (Child, i) => {
if (Child === null) {
return null;
}
const id = Child.props.id || `${i+1}`;
return <div key={`slider-thumb-${id}`} className={'slider-thumb' + ( this.state.activeId == id ? ' active' : '')} onClick={ this.onClickThumb } data-slide-id={ id }>
{
this.props.thumbsType == 'image'
? <img src={ Child.props.thumb } />
: null
}
{
this.props.thumbsType == 'number'
? <span>{i}</span>
: null
}
</div>;
})
}
</div>
: null
}
</div>
)
}
}
class Slide extends React.Component {
constructor() {
super();
this.state = {
}
}
render() {
return (
<div className={'slider-slide' + ` ${this.props.animationClass}` + ( this.props.active ? ' active' : '') + ( this.props.slideOut ? ' out' : '')} data-slide-id={ this.props.id } onAnimationEnd={ this.props.onAnimationEnd }>{ this.props.children }</div>
)
}
}
Slider.Slide = Slide;
if (process.env.NODE_ENV == 'dev') {
/* Slider.propTypes = {
animationClass: PropTypes.shape()
}; */
}
export default Slider
{/* <Slider animationTimeout='10000' animationClass='slider-fade' thumbsType='empty' infinity>
<Slider.Slide id='1'>
<img src='1.jpg' />
<div className='slide-inner'>
<div className='slide-inner-title'>Title1</div>
<Link to='/' className='btn'>Подробнее</Link>
</div>
</Slider.Slide>
<Slider.Slide id='2'><img src='2.jpg' /></Slider.Slide>
<Slider.Slide id='3'><img src='3.jpg' /></Slider.Slide>
<Slider.Slide id='4'><img src='4.jpg' /></Slider.Slide>
</Slider> */}