UNPKG

@eureca/eureca-ui

Version:

UI component library of Eureca's user and admin apps

146 lines (133 loc) 3.52 kB
import React, { useState, useCallback } from 'react'; import PropTypes from 'prop-types'; import Slider from 'react-slick'; import { Box } from '@material-ui/core'; import { useTheme } from '@material-ui/core/styles'; import { FiChevronLeft, FiChevronRight } from 'react-icons/fi'; import { colors } from '../../theme/colors'; import { useWindowSize } from '../../hooks/useWindowSizeSSR'; const settings = { dots: { dots: true, arrows: false, }, default: { arrows: true, dots: false, nextArrow: <Arrow side="right" />, prevArrow: <Arrow side="left" />, }, }; const arrowStyle = { cursor: 'pointer', position: 'absolute', top: '50%', transform: 'translate(0,-50%)', zIndex: 500, }; function Arrow({ onClick, side }) { const isClickable = typeof onClick !== 'object'; const boxProps = { style: arrowStyle, onClick, [side]: 16 }; return ( isClickable && ( <Box {...boxProps}> {side === 'left' ? ( <FiChevronLeft color={colors.gray5} size={48} /> ) : ( <FiChevronRight color={colors.gray5} size={48} /> )} </Box> ) ); } const outerWidth = el => { let width = el.offsetWidth; const elementStyle = getComputedStyle(el); width += parseInt(elementStyle.marginLeft, 10) + parseInt(elementStyle.marginRight, 10); return width; }; function Carousel({ children, variant = 'default', boxProps, ...props }) { const [slides, setSlides] = useState(1); const theme = useTheme(); const size = useWindowSize(); const sliderRef = useCallback( ref => { if (ref !== null && size?.width) { const slider = ref.innerSlider.list; const { clientWidth, firstChild } = slider; const itemsPerPage = Math.floor(clientWidth / outerWidth(firstChild.firstChild)); setSlides(itemsPerPage); } }, [size] ); const { xs, sm, md, lg, xl } = theme.breakpoints.values; return ( <Box style={{ minWidth: '100%', width: 0 }} {...boxProps}> <Slider slidesToShow={slides} slidesToScroll={slides} speed={500} {...settings[variant]} ref={sliderRef} responsive={[ // fixes the loading issue when using flex-box { breakpoint: xs, settings: { mobileFirst: false, infinite: true, slidesToShow: slides, }, }, { breakpoint: sm, settings: { mobileFirst: false, infinite: true, slidesToShow: slides, }, }, { breakpoint: md, settings: { mobileFirst: false, infinite: true, slidesToShow: slides, }, }, { breakpoint: lg, settings: { mobileFirst: false, infinite: true, slidesToShow: slides, }, }, { breakpoint: xl, settings: { mobileFirst: false, infinite: true, slidesToShow: slides, }, }, ]} {...props} > {children} </Slider> </Box> ); } Carousel.propTypes = { variant: PropTypes.string, children: PropTypes.oneOfType([PropTypes.any]), boxProps: PropTypes.object, }; Carousel.defaulProps = { variant: 'default', children: null, boxProps: {}, }; export { Carousel };