1 | import React, { Component } from 'react';
|
2 | import PropTypes from 'prop-types';
|
3 | import Carousel from './Carousel';
|
4 | import CarouselItem from './CarouselItem';
|
5 | import CarouselControl from './CarouselControl';
|
6 | import CarouselIndicators from './CarouselIndicators';
|
7 | import CarouselCaption from './CarouselCaption';
|
8 |
|
9 | const propTypes = {
|
10 | items: PropTypes.array.isRequired,
|
11 | indicators: PropTypes.bool,
|
12 | controls: PropTypes.bool,
|
13 | autoPlay: PropTypes.bool,
|
14 | defaultActiveIndex: PropTypes.number,
|
15 | activeIndex: PropTypes.number,
|
16 | next: PropTypes.func,
|
17 | previous: PropTypes.func,
|
18 | goToIndex: PropTypes.func,
|
19 | };
|
20 |
|
21 | class UncontrolledCarousel extends Component {
|
22 | constructor(props) {
|
23 | super(props);
|
24 | this.animating = false;
|
25 | this.state = { activeIndex: props.defaultActiveIndex || 0 };
|
26 | this.next = this.next.bind(this);
|
27 | this.previous = this.previous.bind(this);
|
28 | this.goToIndex = this.goToIndex.bind(this);
|
29 | this.onExiting = this.onExiting.bind(this);
|
30 | this.onExited = this.onExited.bind(this);
|
31 | }
|
32 |
|
33 | onExiting() {
|
34 | this.animating = true;
|
35 | }
|
36 |
|
37 | onExited() {
|
38 | this.animating = false;
|
39 | }
|
40 |
|
41 | next() {
|
42 | if (this.animating) return;
|
43 | const nextIndex = this.state.activeIndex === this.props.items.length - 1 ? 0 : this.state.activeIndex + 1;
|
44 | this.setState({ activeIndex: nextIndex });
|
45 | }
|
46 |
|
47 | previous() {
|
48 | if (this.animating) return;
|
49 | const nextIndex = this.state.activeIndex === 0 ? this.props.items.length - 1 : this.state.activeIndex - 1;
|
50 | this.setState({ activeIndex: nextIndex });
|
51 | }
|
52 |
|
53 | goToIndex(newIndex) {
|
54 | if (this.animating) return;
|
55 | this.setState({ activeIndex: newIndex });
|
56 | }
|
57 |
|
58 | render() {
|
59 | const { defaultActiveIndex, autoPlay, indicators, controls, items, goToIndex, ...props } = this.props;
|
60 | const { activeIndex } = this.state;
|
61 |
|
62 | const slides = items.map((item) => {
|
63 | const key = item.key || item.src;
|
64 | return (
|
65 | <CarouselItem
|
66 | onExiting={this.onExiting}
|
67 | onExited={this.onExited}
|
68 | key={key}
|
69 | >
|
70 | <img className="d-block w-100" src={item.src} alt={item.altText} />
|
71 | <CarouselCaption captionText={item.caption} captionHeader={item.header || item.caption} />
|
72 | </CarouselItem>
|
73 | );
|
74 | });
|
75 |
|
76 | return (
|
77 | <Carousel
|
78 | activeIndex={activeIndex}
|
79 | next={this.next}
|
80 | previous={this.previous}
|
81 | ride={autoPlay ? 'carousel' : undefined}
|
82 | {...props}
|
83 | >
|
84 | {indicators && <CarouselIndicators
|
85 | items={items}
|
86 | activeIndex={props.activeIndex || activeIndex}
|
87 | onClickHandler={goToIndex || this.goToIndex}
|
88 | />}
|
89 | {slides}
|
90 | {controls && <CarouselControl
|
91 | direction="prev"
|
92 | directionText="Previous"
|
93 | onClickHandler={props.previous || this.previous}
|
94 | />}
|
95 | {controls && <CarouselControl
|
96 | direction="next"
|
97 | directionText="Next"
|
98 | onClickHandler={props.next || this.next}
|
99 | />}
|
100 | </Carousel>
|
101 | );
|
102 | }
|
103 | }
|
104 |
|
105 | UncontrolledCarousel.propTypes = propTypes;
|
106 | UncontrolledCarousel.defaultProps = {
|
107 | controls: true,
|
108 | indicators: true,
|
109 | autoPlay: true,
|
110 | };
|
111 |
|
112 | export default UncontrolledCarousel;
|