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 | this.setState((prevState) => {
|
44 | const nextIndex =
|
45 | prevState.activeIndex === this.props.items.length - 1
|
46 | ? 0
|
47 | : prevState.activeIndex + 1;
|
48 | return { activeIndex: nextIndex };
|
49 | });
|
50 | }
|
51 |
|
52 | previous() {
|
53 | if (this.animating) return;
|
54 | this.setState((prevState) => {
|
55 | const nextIndex =
|
56 | prevState.activeIndex === 0
|
57 | ? this.props.items.length - 1
|
58 | : prevState.activeIndex - 1;
|
59 | return { activeIndex: nextIndex };
|
60 | });
|
61 | }
|
62 |
|
63 | goToIndex(newIndex) {
|
64 | if (this.animating) return;
|
65 | this.setState({ activeIndex: newIndex });
|
66 | }
|
67 |
|
68 | render() {
|
69 | const {
|
70 | defaultActiveIndex,
|
71 | autoPlay = true,
|
72 | indicators = true,
|
73 | controls = true,
|
74 | items,
|
75 | goToIndex,
|
76 | ...props
|
77 | } = this.props;
|
78 | const { activeIndex } = this.state;
|
79 |
|
80 | const slides = items.map((item) => {
|
81 | const key = item.key || item.src;
|
82 | return (
|
83 | <CarouselItem
|
84 | onExiting={this.onExiting}
|
85 | onExited={this.onExited}
|
86 | key={key}
|
87 | >
|
88 | <img className="d-block w-100" src={item.src} alt={item.altText} />
|
89 | <CarouselCaption
|
90 | captionText={item.caption}
|
91 | captionHeader={item.header || item.caption}
|
92 | />
|
93 | </CarouselItem>
|
94 | );
|
95 | });
|
96 |
|
97 | return (
|
98 | <Carousel
|
99 | activeIndex={activeIndex}
|
100 | next={this.next}
|
101 | previous={this.previous}
|
102 | ride={autoPlay ? 'carousel' : undefined}
|
103 | {...props}
|
104 | >
|
105 | {indicators && (
|
106 | <CarouselIndicators
|
107 | items={items}
|
108 | activeIndex={props.activeIndex || activeIndex}
|
109 | onClickHandler={goToIndex || this.goToIndex}
|
110 | />
|
111 | )}
|
112 | {slides}
|
113 | {controls && (
|
114 | <CarouselControl
|
115 | direction="prev"
|
116 | directionText="Previous"
|
117 | onClickHandler={props.previous || this.previous}
|
118 | />
|
119 | )}
|
120 | {controls && (
|
121 | <CarouselControl
|
122 | direction="next"
|
123 | directionText="Next"
|
124 | onClickHandler={props.next || this.next}
|
125 | />
|
126 | )}
|
127 | </Carousel>
|
128 | );
|
129 | }
|
130 | }
|
131 |
|
132 | UncontrolledCarousel.propTypes = propTypes;
|
133 |
|
134 | export default UncontrolledCarousel;
|