import * as React from 'react'; import debounce from 'lodash/debounce'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; // matchMedia polyfill for // https://github.com/WickyNilliams/enquire.js/issues/82 if (typeof window !== 'undefined') { const matchMediaPolyfill = (mediaQuery: string) => { return { media: mediaQuery, matches: false, addListener() { }, removeListener() { }, }; }; window.matchMedia = window.matchMedia || matchMediaPolyfill; } // Use require over import (will be lifted up) // make sure matchMedia polyfill run before require('react-slick') // Fix https://github.com/ant-design/ant-design/issues/6560 // Fix https://github.com/ant-design/ant-design/issues/3308 const SlickCarousel = require('react-slick').default; export type CarouselEffect = 'scrollx' | 'fade'; // Carousel export interface CarouselProps { effect?: CarouselEffect; dots?: boolean; vertical?: boolean; autoplay?: boolean; easing?: string; beforeChange?: (from: number, to: number) => void; afterChange?: (current: number) => void; style?: React.CSSProperties; prefixCls?: string; accessibility?: boolean; nextArrow?: HTMLElement | any; prevArrow?: HTMLElement | any; pauseOnHover?: boolean; className?: string; adaptiveHeight?: boolean; arrows?: boolean; autoplaySpeed?: number; centerMode?: boolean; centerPadding?: string | any; cssEase?: string | any; dotsClass?: string; draggable?: boolean; fade?: boolean; focusOnSelect?: boolean; infinite?: boolean; initialSlide?: number; lazyLoad?: boolean; rtl?: boolean; slide?: string; slidesToShow?: number; slidesToScroll?: number; speed?: number; swipe?: boolean; swipeToSlide?: boolean; touchMove?: boolean; touchThreshold?: number; variableWidth?: boolean; useCSS?: boolean; slickGoTo?: number; } export default class Carousel extends React.Component { static defaultProps = { dots: true, arrows: false, draggable: false, }; innerSlider: any; private slick: any; constructor(props: CarouselProps) { super(props); this.onWindowResized = debounce(this.onWindowResized, 500, { leading: false, }); } componentDidMount() { const { autoplay } = this.props; if (autoplay) { window.addEventListener('resize', this.onWindowResized); } // https://github.com/ant-design/ant-design/issues/7191 this.innerSlider = this.slick && this.slick.innerSlider; } componentWillUnmount() { const { autoplay } = this.props; if (autoplay) { window.removeEventListener('resize', this.onWindowResized); (this.onWindowResized as any).cancel(); } } onWindowResized = () => { // Fix https://github.com/ant-design/ant-design/issues/2550 const { autoplay } = this.props; if (autoplay && this.slick && this.slick.innerSlider && this.slick.innerSlider.autoPlay) { this.slick.innerSlider.autoPlay(); } } saveSlick = (node: any) => { this.slick = node; } next() { this.slick.slickNext(); } prev() { this.slick.slickPrev(); } goTo(slide: number, dontAnimate = false) { this.slick.slickGoTo(slide, dontAnimate); } renderCarousel = ({ getPrefixCls }: ConfigConsumerProps) => { const props = { ...this.props, }; if (props.effect === 'fade') { props.fade = true; } let className = getPrefixCls('carousel', props.prefixCls); if (props.vertical) { className = `${className} ${className}-vertical`; } return (
); } render() { return ( {this.renderCarousel} ); } }