1 | import _extends from 'babel-runtime/helpers/extends';
|
2 | import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
|
3 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
4 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
5 | import _inherits from 'babel-runtime/helpers/inherits';
|
6 | import classNames from 'classnames';
|
7 | import React, { cloneElement } from 'react';
|
8 | import PropTypes from 'prop-types';
|
9 |
|
10 | import CarouselCaption from './CarouselCaption';
|
11 | import CarouselItem from './CarouselItem';
|
12 | import Glyphicon from './Glyphicon';
|
13 | import SafeAnchor from './SafeAnchor';
|
14 | import { bsClass, getClassSet, prefix, splitBsPropsAndOmit } from './utils/bootstrapUtils';
|
15 | import ValidComponentChildren from './utils/ValidComponentChildren';
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | var propTypes = {
|
22 | slide: PropTypes.bool,
|
23 | indicators: PropTypes.bool,
|
24 | |
25 |
|
26 |
|
27 |
|
28 | interval: PropTypes.number,
|
29 | controls: PropTypes.bool,
|
30 | pauseOnHover: PropTypes.bool,
|
31 | wrap: PropTypes.bool,
|
32 | |
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | onSelect: PropTypes.func,
|
44 | onSlideEnd: PropTypes.func,
|
45 | activeIndex: PropTypes.number,
|
46 | defaultActiveIndex: PropTypes.number,
|
47 | direction: PropTypes.oneOf(['prev', 'next']),
|
48 | prevIcon: PropTypes.node,
|
49 | |
50 |
|
51 |
|
52 |
|
53 |
|
54 | prevLabel: PropTypes.string,
|
55 | nextIcon: PropTypes.node,
|
56 | |
57 |
|
58 |
|
59 |
|
60 |
|
61 | nextLabel: PropTypes.string
|
62 | };
|
63 |
|
64 | var defaultProps = {
|
65 | slide: true,
|
66 | interval: 5000,
|
67 | pauseOnHover: true,
|
68 | wrap: true,
|
69 | indicators: true,
|
70 | controls: true,
|
71 | prevIcon: React.createElement(Glyphicon, { glyph: 'chevron-left' }),
|
72 | prevLabel: 'Previous',
|
73 | nextIcon: React.createElement(Glyphicon, { glyph: 'chevron-right' }),
|
74 | nextLabel: 'Next'
|
75 | };
|
76 |
|
77 | var Carousel = function (_React$Component) {
|
78 | _inherits(Carousel, _React$Component);
|
79 |
|
80 | function Carousel(props, context) {
|
81 | _classCallCheck(this, Carousel);
|
82 |
|
83 | var _this = _possibleConstructorReturn(this, _React$Component.call(this, props, context));
|
84 |
|
85 | _this.handleMouseOver = _this.handleMouseOver.bind(_this);
|
86 | _this.handleMouseOut = _this.handleMouseOut.bind(_this);
|
87 | _this.handlePrev = _this.handlePrev.bind(_this);
|
88 | _this.handleNext = _this.handleNext.bind(_this);
|
89 | _this.handleItemAnimateOutEnd = _this.handleItemAnimateOutEnd.bind(_this);
|
90 |
|
91 | var defaultActiveIndex = props.defaultActiveIndex;
|
92 |
|
93 |
|
94 | _this.state = {
|
95 | activeIndex: defaultActiveIndex != null ? defaultActiveIndex : 0,
|
96 | previousActiveIndex: null,
|
97 | direction: null
|
98 | };
|
99 |
|
100 | _this.isUnmounted = false;
|
101 | return _this;
|
102 | }
|
103 |
|
104 | Carousel.prototype.componentDidMount = function componentDidMount() {
|
105 | this.waitForNext();
|
106 | };
|
107 |
|
108 | Carousel.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
|
109 | var activeIndex = this.getActiveIndex();
|
110 |
|
111 | if (nextProps.activeIndex != null && nextProps.activeIndex !== activeIndex) {
|
112 | clearTimeout(this.timeout);
|
113 |
|
114 | this.setState({
|
115 | previousActiveIndex: activeIndex,
|
116 | direction: nextProps.direction != null ? nextProps.direction : this.getDirection(activeIndex, nextProps.activeIndex)
|
117 | });
|
118 | }
|
119 |
|
120 | if (nextProps.activeIndex == null && this.state.activeIndex >= nextProps.children.length) {
|
121 | this.setState({
|
122 | activeIndex: 0,
|
123 | previousActiveIndex: null,
|
124 | direction: null
|
125 | });
|
126 | }
|
127 | };
|
128 |
|
129 | Carousel.prototype.componentWillUnmount = function componentWillUnmount() {
|
130 | clearTimeout(this.timeout);
|
131 | this.isUnmounted = true;
|
132 | };
|
133 |
|
134 | Carousel.prototype.getActiveIndex = function getActiveIndex() {
|
135 | var activeIndexProp = this.props.activeIndex;
|
136 | return activeIndexProp != null ? activeIndexProp : this.state.activeIndex;
|
137 | };
|
138 |
|
139 | Carousel.prototype.getDirection = function getDirection(prevIndex, index) {
|
140 | if (prevIndex === index) {
|
141 | return null;
|
142 | }
|
143 |
|
144 | return prevIndex > index ? 'prev' : 'next';
|
145 | };
|
146 |
|
147 | Carousel.prototype.handleItemAnimateOutEnd = function handleItemAnimateOutEnd() {
|
148 | var _this2 = this;
|
149 |
|
150 | this.setState({
|
151 | previousActiveIndex: null,
|
152 | direction: null
|
153 | }, function () {
|
154 | _this2.waitForNext();
|
155 |
|
156 | if (_this2.props.onSlideEnd) {
|
157 | _this2.props.onSlideEnd();
|
158 | }
|
159 | });
|
160 | };
|
161 |
|
162 | Carousel.prototype.handleMouseOut = function handleMouseOut() {
|
163 | if (this.isPaused) {
|
164 | this.play();
|
165 | }
|
166 | };
|
167 |
|
168 | Carousel.prototype.handleMouseOver = function handleMouseOver() {
|
169 | if (this.props.pauseOnHover) {
|
170 | this.pause();
|
171 | }
|
172 | };
|
173 |
|
174 | Carousel.prototype.handleNext = function handleNext(e) {
|
175 | var index = this.getActiveIndex() + 1;
|
176 | var count = ValidComponentChildren.count(this.props.children);
|
177 |
|
178 | if (index > count - 1) {
|
179 | if (!this.props.wrap) {
|
180 | return;
|
181 | }
|
182 | index = 0;
|
183 | }
|
184 |
|
185 | this.select(index, e, 'next');
|
186 | };
|
187 |
|
188 | Carousel.prototype.handlePrev = function handlePrev(e) {
|
189 | var index = this.getActiveIndex() - 1;
|
190 |
|
191 | if (index < 0) {
|
192 | if (!this.props.wrap) {
|
193 | return;
|
194 | }
|
195 | index = ValidComponentChildren.count(this.props.children) - 1;
|
196 | }
|
197 |
|
198 | this.select(index, e, 'prev');
|
199 | };
|
200 |
|
201 |
|
202 |
|
203 |
|
204 | Carousel.prototype.pause = function pause() {
|
205 | this.isPaused = true;
|
206 | clearTimeout(this.timeout);
|
207 | };
|
208 |
|
209 |
|
210 |
|
211 |
|
212 | Carousel.prototype.play = function play() {
|
213 | this.isPaused = false;
|
214 | this.waitForNext();
|
215 | };
|
216 |
|
217 | Carousel.prototype.select = function select(index, e, direction) {
|
218 | clearTimeout(this.timeout);
|
219 |
|
220 |
|
221 |
|
222 | if (this.isUnmounted) {
|
223 | return;
|
224 | }
|
225 |
|
226 | var previousActiveIndex = this.props.slide ? this.getActiveIndex() : null;
|
227 | direction = direction || this.getDirection(previousActiveIndex, index);
|
228 |
|
229 | var onSelect = this.props.onSelect;
|
230 |
|
231 |
|
232 | if (onSelect) {
|
233 | if (onSelect.length > 1) {
|
234 |
|
235 |
|
236 |
|
237 |
|
238 | if (e) {
|
239 | e.persist();
|
240 | e.direction = direction;
|
241 | } else {
|
242 | e = { direction: direction };
|
243 | }
|
244 |
|
245 | onSelect(index, e);
|
246 | } else {
|
247 | onSelect(index);
|
248 | }
|
249 | }
|
250 |
|
251 | if (this.props.activeIndex == null && index !== previousActiveIndex) {
|
252 | if (this.state.previousActiveIndex != null) {
|
253 |
|
254 |
|
255 |
|
256 | return;
|
257 | }
|
258 |
|
259 | this.setState({
|
260 | activeIndex: index,
|
261 | previousActiveIndex: previousActiveIndex,
|
262 | direction: direction
|
263 | });
|
264 | }
|
265 | };
|
266 |
|
267 | Carousel.prototype.waitForNext = function waitForNext() {
|
268 | var _props = this.props,
|
269 | slide = _props.slide,
|
270 | interval = _props.interval,
|
271 | activeIndexProp = _props.activeIndex;
|
272 |
|
273 |
|
274 | if (!this.isPaused && slide && interval && activeIndexProp == null) {
|
275 | this.timeout = setTimeout(this.handleNext, interval);
|
276 | }
|
277 | };
|
278 |
|
279 | Carousel.prototype.renderControls = function renderControls(properties) {
|
280 | var wrap = properties.wrap,
|
281 | children = properties.children,
|
282 | activeIndex = properties.activeIndex,
|
283 | prevIcon = properties.prevIcon,
|
284 | nextIcon = properties.nextIcon,
|
285 | bsProps = properties.bsProps,
|
286 | prevLabel = properties.prevLabel,
|
287 | nextLabel = properties.nextLabel;
|
288 |
|
289 | var controlClassName = prefix(bsProps, 'control');
|
290 | var count = ValidComponentChildren.count(children);
|
291 |
|
292 | return [(wrap || activeIndex !== 0) && React.createElement(
|
293 | SafeAnchor,
|
294 | {
|
295 | key: 'prev',
|
296 | className: classNames(controlClassName, 'left'),
|
297 | onClick: this.handlePrev
|
298 | },
|
299 | prevIcon,
|
300 | prevLabel && React.createElement(
|
301 | 'span',
|
302 | { className: 'sr-only' },
|
303 | prevLabel
|
304 | )
|
305 | ), (wrap || activeIndex !== count - 1) && React.createElement(
|
306 | SafeAnchor,
|
307 | {
|
308 | key: 'next',
|
309 | className: classNames(controlClassName, 'right'),
|
310 | onClick: this.handleNext
|
311 | },
|
312 | nextIcon,
|
313 | nextLabel && React.createElement(
|
314 | 'span',
|
315 | { className: 'sr-only' },
|
316 | nextLabel
|
317 | )
|
318 | )];
|
319 | };
|
320 |
|
321 | Carousel.prototype.renderIndicators = function renderIndicators(children, activeIndex, bsProps) {
|
322 | var _this3 = this;
|
323 |
|
324 | var indicators = [];
|
325 |
|
326 | ValidComponentChildren.forEach(children, function (child, index) {
|
327 | indicators.push(React.createElement('li', {
|
328 | key: index,
|
329 | className: index === activeIndex ? 'active' : null,
|
330 | onClick: function onClick(e) {
|
331 | return _this3.select(index, e);
|
332 | }
|
333 | }),
|
334 |
|
335 |
|
336 |
|
337 | ' ');
|
338 | });
|
339 |
|
340 | return React.createElement(
|
341 | 'ol',
|
342 | { className: prefix(bsProps, 'indicators') },
|
343 | indicators
|
344 | );
|
345 | };
|
346 |
|
347 | Carousel.prototype.render = function render() {
|
348 | var _this4 = this;
|
349 |
|
350 | var _props2 = this.props,
|
351 | slide = _props2.slide,
|
352 | indicators = _props2.indicators,
|
353 | controls = _props2.controls,
|
354 | wrap = _props2.wrap,
|
355 | prevIcon = _props2.prevIcon,
|
356 | prevLabel = _props2.prevLabel,
|
357 | nextIcon = _props2.nextIcon,
|
358 | nextLabel = _props2.nextLabel,
|
359 | className = _props2.className,
|
360 | children = _props2.children,
|
361 | props = _objectWithoutProperties(_props2, ['slide', 'indicators', 'controls', 'wrap', 'prevIcon', 'prevLabel', 'nextIcon', 'nextLabel', 'className', 'children']);
|
362 |
|
363 | var _state = this.state,
|
364 | previousActiveIndex = _state.previousActiveIndex,
|
365 | direction = _state.direction;
|
366 |
|
367 | var _splitBsPropsAndOmit = splitBsPropsAndOmit(props, ['interval', 'pauseOnHover', 'onSelect', 'onSlideEnd', 'activeIndex',
|
368 | 'defaultActiveIndex', 'direction']),
|
369 | bsProps = _splitBsPropsAndOmit[0],
|
370 | elementProps = _splitBsPropsAndOmit[1];
|
371 |
|
372 | var activeIndex = this.getActiveIndex();
|
373 |
|
374 | var classes = _extends({}, getClassSet(bsProps), {
|
375 | slide: slide
|
376 | });
|
377 |
|
378 | return React.createElement(
|
379 | 'div',
|
380 | _extends({}, elementProps, {
|
381 | className: classNames(className, classes),
|
382 | onMouseOver: this.handleMouseOver,
|
383 | onMouseOut: this.handleMouseOut
|
384 | }),
|
385 | indicators && this.renderIndicators(children, activeIndex, bsProps),
|
386 | React.createElement(
|
387 | 'div',
|
388 | { className: prefix(bsProps, 'inner') },
|
389 | ValidComponentChildren.map(children, function (child, index) {
|
390 | var active = index === activeIndex;
|
391 | var previousActive = slide && index === previousActiveIndex;
|
392 |
|
393 | return cloneElement(child, {
|
394 | active: active,
|
395 | index: index,
|
396 | animateOut: previousActive,
|
397 | animateIn: active && previousActiveIndex != null && slide,
|
398 | direction: direction,
|
399 | onAnimateOutEnd: previousActive ? _this4.handleItemAnimateOutEnd : null
|
400 | });
|
401 | })
|
402 | ),
|
403 | controls && this.renderControls({
|
404 | wrap: wrap,
|
405 | children: children,
|
406 | activeIndex: activeIndex,
|
407 | prevIcon: prevIcon,
|
408 | prevLabel: prevLabel,
|
409 | nextIcon: nextIcon,
|
410 | nextLabel: nextLabel,
|
411 | bsProps: bsProps
|
412 | })
|
413 | );
|
414 | };
|
415 |
|
416 | return Carousel;
|
417 | }(React.Component);
|
418 |
|
419 | Carousel.propTypes = propTypes;
|
420 | Carousel.defaultProps = defaultProps;
|
421 |
|
422 | Carousel.Caption = CarouselCaption;
|
423 | Carousel.Item = CarouselItem;
|
424 |
|
425 | export default bsClass('carousel', Carousel); |
\ | No newline at end of file |