/
Carousel.js
143 lines (133 loc) · 3.24 KB
/
Carousel.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import React, { useEffect, useRef } from 'react';
import cx from 'classnames';
import PropTypes from 'prop-types';
import idgen from './idgen';
const Carousel = ({
children,
className,
carouselId,
fixedItem,
images,
centerImages,
options
}) => {
const carouselRef = useRef(null);
useEffect(() => {
const instance = M.Carousel.init(carouselRef.current, options);
return () => instance.destroy();
}, [options, children, images]);
const elemsToRender = children || images || [];
const classes = cx(
'carousel',
{
'carousel-slider': options.fullWidth
},
className
);
return (
<div id={carouselId} ref={carouselRef} className={classes}>
{Boolean(fixedItem) && (
<div className="carousel-fixed-item center">{fixedItem}</div>
)}
{React.Children.map(elemsToRender, child => {
const classes = cx('carousel-item', { 'valign-wrapper': centerImages });
if (typeof child === 'string') {
return (
<a className={classes}>
<img src={child} alt={child} />
</a>
);
}
return React.cloneElement(child, {
className: cx(classes, child.props.className)
});
})}
</div>
);
};
Carousel.propTypes = {
/**
* Children to render as carousel elements
*/
children: PropTypes.any,
/**
* Array of image url's
*/
images: PropTypes.arrayOf(PropTypes.string),
/**
* Makes the images centered inside the carousel using '.valign-wrapper' CSS helper
*/
centerImages: PropTypes.bool,
/**
* Fixed element on slider
*/
fixedItem: PropTypes.node,
/**
* Additional classNames for carousel wrapper
*/
className: PropTypes.string,
/**
* Carousel ID for jQuery manipulating
* @default idgen()
*/
carouselId: PropTypes.string,
/**
* Carousel initialization options
* <a href="http://materializecss.com/carousel.html">http://materializecss.com/carousel.html</a>
*/
options: PropTypes.shape({
/**
* Transition duration in milliseconds. (Default: 200)
*/
duration: PropTypes.number,
/**
* Perspective zoom. If 0, all items are the same size. (Default: -100)
*/
dist: PropTypes.number,
/**
* Set the spacing of the center item. (Default: 0)
*/
shift: PropTypes.number,
/**
* Set the padding between non center items. (Default: 0)
*/
padding: PropTypes.number,
/**
* Set the number of visible items. (Default: 5)
*/
numVisible: PropTypes.number,
/**
* Make the carousel a full width slider. (Default: false)
*/
fullWidth: PropTypes.bool,
/**
* Set to true to show indicators. (Default: false)
*/
indicators: PropTypes.bool,
/**
* Don't wrap around and cycle through items. (Default: false)
*/
noWrap: PropTypes.bool,
/**
* Callback for when a new slide is cycled to. (Default: null)
*/
onCycleTo: PropTypes.func
})
};
Carousel.defaultProps = {
get carouselId() {
return `Carousel-${idgen()}`;
},
options: {
duration: 200,
dist: -100,
shift: 0,
padding: 0,
numVisible: 5,
fullWidth: false,
indicators: false,
noWrap: false,
onCycleTo: null
}
};
export default Carousel;