import type { CSSProperties, ExtractPropTypes, PropType } from 'vue'; import { ref, computed, watchEffect, defineComponent } from 'vue'; import PropTypes from '../_util/vue-types'; import warning from '../_util/warning'; import classNames from '../_util/classNames'; import SlickCarousel from '../vc-slick'; import { withInstall } from '../_util/type'; import useConfigInject from '../_util/hooks/useConfigInject'; export type SwipeDirection = 'left' | 'down' | 'right' | 'up' | string; export type LazyLoadTypes = 'ondemand' | 'progressive'; export type CarouselEffect = 'scrollx' | 'fade'; export type DotPosition = 'top' | 'bottom' | 'left' | 'right'; export interface CarouselRef { goTo: (slide: number, dontAnimate?: boolean) => void; next: () => void; prev: () => void; autoplay: (palyType?: 'update' | 'leave' | 'blur') => void; innerSlider: any; } // Carousel export const carouselProps = () => ({ effect: String as PropType, dots: { type: Boolean, default: true }, vertical: { type: Boolean, default: undefined }, autoplay: { type: Boolean, default: undefined }, easing: String, beforeChange: Function as PropType<(currentSlide: number, nextSlide: number) => void>, afterChange: Function as PropType<(currentSlide: number) => void>, // style: PropTypes.React.CSSProperties, prefixCls: String, accessibility: { type: Boolean, default: undefined }, nextArrow: PropTypes.any, prevArrow: PropTypes.any, pauseOnHover: { type: Boolean, default: undefined }, // className: String, adaptiveHeight: { type: Boolean, default: undefined }, arrows: { type: Boolean, default: false }, autoplaySpeed: Number, centerMode: { type: Boolean, default: undefined }, centerPadding: String, cssEase: String, dotsClass: String, draggable: { type: Boolean, default: false }, fade: { type: Boolean, default: undefined }, focusOnSelect: { type: Boolean, default: undefined }, infinite: { type: Boolean, default: undefined }, initialSlide: Number, lazyLoad: String as PropType, rtl: { type: Boolean, default: undefined }, slide: String, slidesToShow: Number, slidesToScroll: Number, speed: Number, swipe: { type: Boolean, default: undefined }, swipeToSlide: { type: Boolean, default: undefined }, swipeEvent: Function as PropType<(swipeDirection: SwipeDirection) => void>, touchMove: { type: Boolean, default: undefined }, touchThreshold: Number, variableWidth: { type: Boolean, default: undefined }, useCSS: { type: Boolean, default: undefined }, slickGoTo: Number, responsive: Array, dotPosition: { type: String as PropType, default: undefined }, verticalSwiping: { type: Boolean, default: false }, }); export type CarouselProps = Partial>>; const Carousel = defineComponent({ compatConfig: { MODE: 3 }, name: 'ACarousel', inheritAttrs: false, props: carouselProps(), setup(props, { slots, attrs, expose }) { const slickRef = ref(); const goTo = (slide: number, dontAnimate = false) => { slickRef.value?.slickGoTo(slide, dontAnimate); }; expose({ goTo, autoplay: palyType => { slickRef.value?.innerSlider?.handleAutoPlay(palyType); }, prev: () => { slickRef.value?.slickPrev(); }, next: () => { slickRef.value?.slickNext(); }, innerSlider: computed(() => { return slickRef.value?.innerSlider; }), } as CarouselRef); watchEffect(() => { warning( props.vertical === undefined, 'Carousel', '`vertical` is deprecated, please use `dotPosition` instead.', ); }); const { prefixCls, direction } = useConfigInject('carousel', props); const dotPosition = computed(() => { if (props.dotPosition) return props.dotPosition; if (props.vertical !== undefined) return props.vertical ? 'right' : 'bottom'; return 'bottom'; }); const vertical = computed(() => dotPosition.value === 'left' || dotPosition.value === 'right'); const dsClass = computed(() => { const dotsClass = 'slick-dots'; return classNames({ [dotsClass]: true, [`${dotsClass}-${dotPosition.value}`]: true, [`${props.dotsClass}`]: !!props.dotsClass, }); }); return () => { const { dots, arrows, draggable, effect } = props; const { class: cls, style, ...restAttrs } = attrs; const fade = effect === 'fade' ? true : props.fade; const className = classNames(prefixCls.value, { [`${prefixCls.value}-rtl`]: direction.value === 'rtl', [`${prefixCls.value}-vertical`]: vertical.value, [`${cls}`]: !!cls, }); return (
); }; }, }); export default withInstall(Carousel);