Refactor carousel (#5292)
* refactor: carousel * refactor: carousel * style: update vc-slick pathpull/5317/head
parent
5edc8cadca
commit
c7492a0b59
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
exports[`renders ./components/carousel/demo/autoplay.vue correctly 1`] = `
|
exports[`renders ./components/carousel/demo/autoplay.vue correctly 1`] = `
|
||||||
<div class="ant-carousel">
|
<div class="ant-carousel">
|
||||||
<div class="slick-slider slick-initialized">
|
<div class="slick-slider slick-initialized" dir="ltr">
|
||||||
<!---->
|
<!---->
|
||||||
<div class="slick-list">
|
<div class="slick-list">
|
||||||
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
||||||
|
@ -84,7 +84,7 @@ exports[`renders ./components/carousel/demo/autoplay.vue correctly 1`] = `
|
||||||
|
|
||||||
exports[`renders ./components/carousel/demo/basic.vue correctly 1`] = `
|
exports[`renders ./components/carousel/demo/basic.vue correctly 1`] = `
|
||||||
<div class="ant-carousel">
|
<div class="ant-carousel">
|
||||||
<div class="slick-slider slick-initialized">
|
<div class="slick-slider slick-initialized" dir="ltr">
|
||||||
<!---->
|
<!---->
|
||||||
<div class="slick-list">
|
<div class="slick-list">
|
||||||
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
||||||
|
@ -166,7 +166,7 @@ exports[`renders ./components/carousel/demo/basic.vue correctly 1`] = `
|
||||||
|
|
||||||
exports[`renders ./components/carousel/demo/customArrows.vue correctly 1`] = `
|
exports[`renders ./components/carousel/demo/customArrows.vue correctly 1`] = `
|
||||||
<div class="ant-carousel">
|
<div class="ant-carousel">
|
||||||
<div class="slick-slider slick-initialized">
|
<div class="slick-slider slick-initialized" dir="ltr">
|
||||||
<div class="custom-slick-arrow slick-arrow slick-prev" style="left: 10px; z-index: 1; display: block;"><span role="img" aria-label="left-circle" class="anticon anticon-left-circle"><svg focusable="false" class="" data-icon="left-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M603.3 327.5l-246 178a7.95 7.95 0 000 12.9l246 178c5.3 3.8 12.7 0 12.7-6.5V643c0-10.2-4.9-19.9-13.2-25.9L457.4 512l145.4-105.2c8.3-6 13.2-15.6 13.2-25.9V334c0-6.5-7.4-10.3-12.7-6.5z"></path><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"></path></svg></span></div>
|
<div class="custom-slick-arrow slick-arrow slick-prev" style="left: 10px; z-index: 1; display: block;"><span role="img" aria-label="left-circle" class="anticon anticon-left-circle"><svg focusable="false" class="" data-icon="left-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M603.3 327.5l-246 178a7.95 7.95 0 000 12.9l246 178c5.3 3.8 12.7 0 12.7-6.5V643c0-10.2-4.9-19.9-13.2-25.9L457.4 512l145.4-105.2c8.3-6 13.2-15.6 13.2-25.9V334c0-6.5-7.4-10.3-12.7-6.5z"></path><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"></path></svg></span></div>
|
||||||
<div class="slick-list">
|
<div class="slick-list">
|
||||||
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
||||||
|
@ -248,7 +248,7 @@ exports[`renders ./components/carousel/demo/customArrows.vue correctly 1`] = `
|
||||||
|
|
||||||
exports[`renders ./components/carousel/demo/customPaging.vue correctly 1`] = `
|
exports[`renders ./components/carousel/demo/customPaging.vue correctly 1`] = `
|
||||||
<div class="ant-carousel">
|
<div class="ant-carousel">
|
||||||
<div class="slick-slider slick-initialized"><button type="button" data-role="none" class="slick-arrow slick-prev" style="display: block;"> Previous</button>
|
<div class="slick-slider slick-initialized" dir="ltr"><button type="button" data-role="none" class="slick-arrow slick-prev" style="display: block;"> Previous</button>
|
||||||
<div class="slick-list">
|
<div class="slick-list">
|
||||||
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
||||||
<div class="slick-slide slick-cloned" tabindex="-1" data-index="-1" aria-hidden="true" style="width: 0px;">
|
<div class="slick-slide slick-cloned" tabindex="-1" data-index="-1" aria-hidden="true" style="width: 0px;">
|
||||||
|
@ -310,7 +310,7 @@ exports[`renders ./components/carousel/demo/customPaging.vue correctly 1`] = `
|
||||||
|
|
||||||
exports[`renders ./components/carousel/demo/fade.vue correctly 1`] = `
|
exports[`renders ./components/carousel/demo/fade.vue correctly 1`] = `
|
||||||
<div class="ant-carousel">
|
<div class="ant-carousel">
|
||||||
<div class="slick-slider slick-initialized">
|
<div class="slick-slider slick-initialized" dir="ltr">
|
||||||
<!---->
|
<!---->
|
||||||
<div class="slick-list">
|
<div class="slick-list">
|
||||||
<div class="slick-track" style="opacity: 1;">
|
<div class="slick-track" style="opacity: 1;">
|
||||||
|
@ -358,7 +358,7 @@ exports[`renders ./components/carousel/demo/fade.vue correctly 1`] = `
|
||||||
exports[`renders ./components/carousel/demo/position.vue correctly 1`] = `
|
exports[`renders ./components/carousel/demo/position.vue correctly 1`] = `
|
||||||
<div class="ant-radio-group ant-radio-group-outline ant-radio-group-default" style="margin-bottom: 8px;"><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="top"><span class="ant-radio-button-inner"></span></span><span>Top</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="bottom"><span class="ant-radio-button-inner"></span></span><span>Bottom</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="left"><span class="ant-radio-button-inner"></span></span><span>Left</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="right"><span class="ant-radio-button-inner"></span></span><span>Right</span></label></div>
|
<div class="ant-radio-group ant-radio-group-outline ant-radio-group-default" style="margin-bottom: 8px;"><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="top"><span class="ant-radio-button-inner"></span></span><span>Top</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="bottom"><span class="ant-radio-button-inner"></span></span><span>Bottom</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="left"><span class="ant-radio-button-inner"></span></span><span>Left</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="right"><span class="ant-radio-button-inner"></span></span><span>Right</span></label></div>
|
||||||
<div class="ant-carousel">
|
<div class="ant-carousel">
|
||||||
<div class="slick-slider slick-initialized">
|
<div class="slick-slider slick-initialized" dir="ltr">
|
||||||
<!---->
|
<!---->
|
||||||
<div class="slick-list">
|
<div class="slick-list">
|
||||||
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
<div class="slick-track" style="opacity: 1; transform: translate3d(0px, 0px, 0px);">
|
||||||
|
|
|
@ -21,9 +21,7 @@ describe('Carousel', () => {
|
||||||
sync: false,
|
sync: false,
|
||||||
};
|
};
|
||||||
const wrapper = mount(Carousel, props);
|
const wrapper = mount(Carousel, props);
|
||||||
const { innerSlider, slick } = wrapper.vm;
|
const { innerSlider } = wrapper.componentVM;
|
||||||
const innerSliderFromRefs = slick.innerSlider;
|
|
||||||
expect(innerSlider).toBe(innerSliderFromRefs);
|
|
||||||
expect(typeof innerSlider.slickNext).toBe('function');
|
expect(typeof innerSlider.slickNext).toBe('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -39,26 +37,25 @@ describe('Carousel', () => {
|
||||||
sync: false,
|
sync: false,
|
||||||
};
|
};
|
||||||
const wrapper = mount(Carousel, props);
|
const wrapper = mount(Carousel, props);
|
||||||
const { prev, next, goTo } = wrapper.vm;
|
const { prev, next, goTo, innerSlider } = wrapper.componentVM;
|
||||||
expect(typeof prev).toBe('function');
|
expect(typeof prev).toBe('function');
|
||||||
expect(typeof next).toBe('function');
|
expect(typeof next).toBe('function');
|
||||||
expect(typeof goTo).toBe('function');
|
expect(typeof goTo).toBe('function');
|
||||||
const slick = wrapper.vm.slick;
|
|
||||||
|
|
||||||
expect(slick.innerSlider.currentSlide).toBe(0);
|
expect(innerSlider.currentSlide).toBe(0);
|
||||||
wrapper.vm.goTo(2);
|
wrapper.vm.goTo(2);
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(slick.innerSlider.currentSlide).toBe(2);
|
expect(innerSlider.currentSlide).toBe(2);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
prev();
|
prev();
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(slick.innerSlider.currentSlide).toBe(1);
|
expect(innerSlider.currentSlide).toBe(1);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(slick.innerSlider.currentSlide).toBe(2);
|
expect(innerSlider.currentSlide).toBe(2);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -77,8 +74,8 @@ describe('Carousel', () => {
|
||||||
// sync: false,
|
// sync: false,
|
||||||
// };
|
// };
|
||||||
// const wrapper = mount(Carousel, props);
|
// const wrapper = mount(Carousel, props);
|
||||||
|
// await sleep(100);
|
||||||
// const spy = jest.spyOn(wrapper.vm.slick.innerSlider, 'handleAutoPlay');
|
// const spy = jest.spyOn(wrapper.componentVM.innerSlider, 'handleAutoPlay');
|
||||||
// window.resizeTo(1000);
|
// window.resizeTo(1000);
|
||||||
// expect(spy).not.toHaveBeenCalled();
|
// expect(spy).not.toHaveBeenCalled();
|
||||||
// await new Promise(resolve => setTimeout(resolve, 1000));
|
// await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
@ -100,12 +97,9 @@ describe('Carousel', () => {
|
||||||
sync: false,
|
sync: false,
|
||||||
};
|
};
|
||||||
const wrapper = mount(Carousel, props);
|
const wrapper = mount(Carousel, props);
|
||||||
const { onWindowResized } = wrapper.vm;
|
const spy = jest.spyOn(window, 'removeEventListener');
|
||||||
const spy = jest.spyOn(wrapper.vm.onWindowResized, 'cancel');
|
|
||||||
const spy2 = jest.spyOn(window, 'removeEventListener');
|
|
||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
expect(spy2).toHaveBeenCalledWith('resize', onWindowResized);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should works for dotPosition', () => {
|
describe('should works for dotPosition', () => {
|
||||||
|
|
|
@ -71,6 +71,7 @@ export default defineComponent({
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
filter: grayscale(100%);
|
filter: grayscale(100%);
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
.ant-carousel :deep .slick-thumb li.slick-active img {
|
.ant-carousel :deep .slick-thumb li.slick-active img {
|
||||||
filter: grayscale(0%);
|
filter: grayscale(0%);
|
||||||
|
|
|
@ -17,14 +17,14 @@ A carousel component. Scales with its container.
|
||||||
|
|
||||||
| Property | Description | Type | Default | Version |
|
| Property | Description | Type | Default | Version |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| afterChange | Callback function called after the current index changes | function(current) | - | |
|
|
||||||
| autoplay | Whether to scroll automatically | boolean | `false` | |
|
| autoplay | Whether to scroll automatically | boolean | `false` | |
|
||||||
| beforeChange | Callback function called before the current index changes | function(from, to) | - | |
|
|
||||||
| dots | Whether to show the dots at the bottom of the gallery | boolean | `true` | |
|
| dots | Whether to show the dots at the bottom of the gallery | boolean | `true` | |
|
||||||
| dotPosition | The position of the dots, which can be one of `top` `bottom` `left` `right` | string | bottom | 1.5.0 |
|
| dotPosition | The position of the dots, which can be one of `top` `bottom` `left` `right` | string | `bottom` | 1.5.0 |
|
||||||
| dotsClass | Class name of the dots | string | `slick-dots` | |
|
| dotsClass | Class name of the dots | string | `slick-dots` | |
|
||||||
| easing | Transition interpolation function name | string | `linear` | |
|
| easing | Transition interpolation function name | string | `linear` | |
|
||||||
| effect | Transition effect | `scrollx` \| `fade` | `scrollx` | |
|
| effect | Transition effect | `scrollx` \| `fade` | `scrollx` | |
|
||||||
|
| afterChange | Callback function called after the current index changes | function(current) | - | |
|
||||||
|
| beforeChange | Callback function called before the current index changes | function(from, to) | - | |
|
||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
|
@ -34,4 +34,4 @@ A carousel component. Scales with its container.
|
||||||
| next() | Change current slide to next slide | |
|
| next() | Change current slide to next slide | |
|
||||||
| prev() | Change current slide to previous slide | |
|
| prev() | Change current slide to previous slide | |
|
||||||
|
|
||||||
For more info on the parameters, refer to the [vc-slick props](https://github.com/vueComponent/ant-design-vue/blob/next/components/vc-slick/src/default-props.js#L3)
|
For more info on the props, refer to the [carousel props](https://github.com/vueComponent/ant-design-vue/blob/next/components/carousel/index.tsx)
|
||||||
|
|
|
@ -1,168 +1,148 @@
|
||||||
import type { ExtractPropTypes } from 'vue';
|
import type { ExtractPropTypes, PropType } from 'vue';
|
||||||
import { defineComponent, inject } from 'vue';
|
import { ref, computed, watchEffect, defineComponent } from 'vue';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import debounce from 'lodash-es/debounce';
|
|
||||||
import hasProp, { getComponent } from '../_util/props-util';
|
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
|
||||||
import warning from '../_util/warning';
|
import warning from '../_util/warning';
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import SlickCarousel from '../vc-slick/src';
|
import SlickCarousel from '../vc-slick';
|
||||||
import { tuple, withInstall } from '../_util/type';
|
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
|
// Carousel
|
||||||
export const carouselProps = {
|
export const carouselProps = () => ({
|
||||||
effect: PropTypes.oneOf(tuple('scrollx', 'fade')),
|
effect: String as PropType<CarouselEffect>,
|
||||||
dots: PropTypes.looseBool.def(true),
|
dots: { type: Boolean, default: true },
|
||||||
vertical: PropTypes.looseBool,
|
vertical: { type: Boolean, default: undefined },
|
||||||
autoplay: PropTypes.looseBool,
|
autoplay: { type: Boolean, default: undefined },
|
||||||
easing: PropTypes.string,
|
easing: String,
|
||||||
beforeChange: PropTypes.func,
|
beforeChange: Function as PropType<(currentSlide: number, nextSlide: number) => void>,
|
||||||
afterChange: PropTypes.func,
|
afterChange: Function as PropType<(currentSlide: number) => void>,
|
||||||
// style: PropTypes.React.CSSProperties,
|
// style: PropTypes.React.CSSProperties,
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: String,
|
||||||
accessibility: PropTypes.looseBool,
|
accessibility: { type: Boolean, default: undefined },
|
||||||
nextArrow: PropTypes.any,
|
nextArrow: PropTypes.any,
|
||||||
prevArrow: PropTypes.any,
|
prevArrow: PropTypes.any,
|
||||||
pauseOnHover: PropTypes.looseBool,
|
pauseOnHover: { type: Boolean, default: undefined },
|
||||||
// className: PropTypes.string,
|
// className: String,
|
||||||
adaptiveHeight: PropTypes.looseBool,
|
adaptiveHeight: { type: Boolean, default: undefined },
|
||||||
arrows: PropTypes.looseBool.def(false),
|
arrows: { type: Boolean, default: false },
|
||||||
autoplaySpeed: PropTypes.number,
|
autoplaySpeed: Number,
|
||||||
centerMode: PropTypes.looseBool,
|
centerMode: { type: Boolean, default: undefined },
|
||||||
centerPadding: PropTypes.string,
|
centerPadding: String,
|
||||||
cssEase: PropTypes.string,
|
cssEase: String,
|
||||||
dotsClass: PropTypes.string,
|
dotsClass: String,
|
||||||
draggable: PropTypes.looseBool.def(false),
|
draggable: { type: Boolean, default: false },
|
||||||
fade: PropTypes.looseBool,
|
fade: { type: Boolean, default: undefined },
|
||||||
focusOnSelect: PropTypes.looseBool,
|
focusOnSelect: { type: Boolean, default: undefined },
|
||||||
infinite: PropTypes.looseBool,
|
infinite: { type: Boolean, default: undefined },
|
||||||
initialSlide: PropTypes.number,
|
initialSlide: Number,
|
||||||
lazyLoad: PropTypes.looseBool,
|
lazyLoad: String as PropType<LazyLoadTypes>,
|
||||||
rtl: PropTypes.looseBool,
|
rtl: { type: Boolean, default: undefined },
|
||||||
slide: PropTypes.string,
|
slide: String,
|
||||||
slidesToShow: PropTypes.number,
|
slidesToShow: Number,
|
||||||
slidesToScroll: PropTypes.number,
|
slidesToScroll: Number,
|
||||||
speed: PropTypes.number,
|
speed: Number,
|
||||||
swipe: PropTypes.looseBool,
|
swipe: { type: Boolean, default: undefined },
|
||||||
swipeToSlide: PropTypes.looseBool,
|
swipeToSlide: { type: Boolean, default: undefined },
|
||||||
touchMove: PropTypes.looseBool,
|
swipeEvent: Function as PropType<(swipeDirection: SwipeDirection) => void>,
|
||||||
touchThreshold: PropTypes.number,
|
touchMove: { type: Boolean, default: undefined },
|
||||||
variableWidth: PropTypes.looseBool,
|
touchThreshold: Number,
|
||||||
useCSS: PropTypes.looseBool,
|
variableWidth: { type: Boolean, default: undefined },
|
||||||
slickGoTo: PropTypes.number,
|
useCSS: { type: Boolean, default: undefined },
|
||||||
responsive: PropTypes.array,
|
slickGoTo: Number,
|
||||||
dotPosition: PropTypes.oneOf(tuple('top', 'bottom', 'left', 'right')),
|
responsive: Array,
|
||||||
verticalSwiping: PropTypes.looseBool.def(false),
|
dotPosition: { type: String as PropType<DotPosition>, default: undefined },
|
||||||
};
|
verticalSwiping: { type: Boolean, default: false },
|
||||||
export type CarouselProps = Partial<ExtractPropTypes<typeof carouselProps>>;
|
});
|
||||||
|
export type CarouselProps = Partial<ExtractPropTypes<ReturnType<typeof carouselProps>>>;
|
||||||
const Carousel = defineComponent({
|
const Carousel = defineComponent({
|
||||||
name: 'ACarousel',
|
name: 'ACarousel',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: carouselProps,
|
props: carouselProps(),
|
||||||
setup() {
|
setup(props, { slots, attrs, expose }) {
|
||||||
return {
|
const slickRef = ref();
|
||||||
configProvider: inject('configProvider', defaultConfigProvider),
|
|
||||||
slick: undefined,
|
const goTo = (slide: number, dontAnimate = false) => {
|
||||||
innerSlider: undefined,
|
slickRef.value?.slickGoTo(slide, dontAnimate);
|
||||||
};
|
};
|
||||||
},
|
|
||||||
beforeMount() {
|
expose({
|
||||||
this.onWindowResized = debounce(this.onWindowResized, 500, {
|
goTo,
|
||||||
leading: false,
|
autoplay: palyType => {
|
||||||
});
|
slickRef.value?.innerSlider?.handleAutoPlay(palyType);
|
||||||
},
|
},
|
||||||
mounted() {
|
prev: () => {
|
||||||
if (hasProp(this, 'vertical')) {
|
slickRef.value?.slickPrev();
|
||||||
|
},
|
||||||
|
next: () => {
|
||||||
|
slickRef.value?.slickNext();
|
||||||
|
},
|
||||||
|
innerSlider: computed(() => {
|
||||||
|
return slickRef.value?.innerSlider;
|
||||||
|
}),
|
||||||
|
} as CarouselRef);
|
||||||
|
watchEffect(() => {
|
||||||
warning(
|
warning(
|
||||||
!this.vertical,
|
props.vertical === undefined,
|
||||||
'Carousel',
|
'Carousel',
|
||||||
'`vertical` is deprecated, please use `dotPosition` instead.',
|
'`vertical` is deprecated, please use `dotPosition` instead.',
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
const { autoplay } = this;
|
const { prefixCls, direction } = useConfigInject('carousel', props);
|
||||||
if (autoplay) {
|
const dotPosition = computed(() => {
|
||||||
window.addEventListener('resize', this.onWindowResized);
|
if (props.dotPosition) return props.dotPosition;
|
||||||
}
|
if (props.vertical !== undefined) return props.vertical ? 'right' : 'bottom';
|
||||||
// https://github.com/ant-design/ant-design/issues/7191
|
|
||||||
this.innerSlider = this.slick && this.slick.innerSlider;
|
|
||||||
},
|
|
||||||
beforeUnmount() {
|
|
||||||
const { autoplay } = this;
|
|
||||||
if (autoplay) {
|
|
||||||
window.removeEventListener('resize', this.onWindowResized);
|
|
||||||
(this.onWindowResized as any).cancel();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getDotPosition() {
|
|
||||||
if (this.dotPosition) {
|
|
||||||
return this.dotPosition;
|
|
||||||
}
|
|
||||||
if (hasProp(this, 'vertical')) {
|
|
||||||
return this.vertical ? 'right' : 'bottom';
|
|
||||||
}
|
|
||||||
return 'bottom';
|
return 'bottom';
|
||||||
},
|
|
||||||
saveSlick(node: HTMLElement) {
|
|
||||||
this.slick = node;
|
|
||||||
},
|
|
||||||
onWindowResized() {
|
|
||||||
// Fix https://github.com/ant-design/ant-design/issues/2550
|
|
||||||
const { autoplay } = this;
|
|
||||||
if (autoplay && this.slick && this.slick.innerSlider && this.slick.innerSlider.autoPlay) {
|
|
||||||
this.slick.innerSlider.autoPlay();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
next() {
|
|
||||||
this.slick.slickNext();
|
|
||||||
},
|
|
||||||
|
|
||||||
prev() {
|
|
||||||
this.slick.slickPrev();
|
|
||||||
},
|
|
||||||
|
|
||||||
goTo(slide: number, dontAnimate = false) {
|
|
||||||
this.slick.slickGoTo(slide, dontAnimate);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const props = { ...this.$props };
|
|
||||||
const { $slots } = this;
|
|
||||||
|
|
||||||
if (props.effect === 'fade') {
|
|
||||||
props.fade = true;
|
|
||||||
}
|
|
||||||
const { class: cls, style, ...restAttrs } = this.$attrs as any;
|
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
|
||||||
let className = getPrefixCls('carousel', props.prefixCls);
|
|
||||||
const dotsClass = 'slick-dots';
|
|
||||||
const dotPosition = this.getDotPosition();
|
|
||||||
props.vertical = dotPosition === 'left' || dotPosition === 'right';
|
|
||||||
props.dotsClass = classNames(`${dotsClass}`, `${dotsClass}-${dotPosition || 'bottom'}`, {
|
|
||||||
[`${props.dotsClass}`]: !!props.dotsClass,
|
|
||||||
});
|
});
|
||||||
className = classNames({
|
const vertical = computed(() => dotPosition.value === 'left' || dotPosition.value === 'right');
|
||||||
[cls]: !!cls,
|
const dsClass = computed(() => {
|
||||||
[className]: !!className,
|
const dotsClass = 'slick-dots';
|
||||||
[`${className}-vertical`]: props.vertical,
|
return classNames({
|
||||||
|
[dotsClass]: true,
|
||||||
|
[`${dotsClass}-${dotPosition.value}`]: true,
|
||||||
|
[`${props.dotsClass}`]: !!props.dotsClass,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
const SlickCarouselProps = {
|
return () => {
|
||||||
...props,
|
const { dots, arrows, draggable, effect } = props;
|
||||||
...restAttrs,
|
const { class: cls, style, ...restAttrs } = attrs;
|
||||||
nextArrow: getComponent(this, 'nextArrow'),
|
const fade = effect === 'fade' ? true : props.fade;
|
||||||
prevArrow: getComponent(this, 'prevArrow'),
|
const className = classNames(prefixCls.value, {
|
||||||
|
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
|
||||||
|
[`${prefixCls.value}-vertical`]: vertical.value,
|
||||||
|
[`${cls}`]: !!cls,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<div class={className} style={style}>
|
||||||
|
<SlickCarousel
|
||||||
|
ref={slickRef}
|
||||||
|
{...props}
|
||||||
|
{...restAttrs}
|
||||||
|
dots={!!dots}
|
||||||
|
dotsClass={dsClass.value}
|
||||||
|
arrows={arrows}
|
||||||
|
draggable={draggable}
|
||||||
|
fade={fade}
|
||||||
|
vertical={vertical.value}
|
||||||
|
v-slots={slots}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
return (
|
|
||||||
<div class={className} style={style}>
|
|
||||||
<SlickCarousel
|
|
||||||
ref={this.saveSlick}
|
|
||||||
{...SlickCarouselProps}
|
|
||||||
v-slots={$slots}
|
|
||||||
></SlickCarousel>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,14 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/%24C9tmj978R/Carousel.svg
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| afterChange | 切换面板的回调 | function(current) | 无 | |
|
|
||||||
| autoplay | 是否自动切换 | boolean | false | |
|
| autoplay | 是否自动切换 | boolean | false | |
|
||||||
| beforeChange | 切换面板的回调 | function(from, to) | 无 | |
|
| dotPosition | 面板指示点位置,可选 `top` `bottom` `left` `right` | string | `bottom` | 1.5.0 |
|
||||||
| dotPosition | 面板指示点位置,可选 `top` `bottom` `left` `right` | string | bottom | 1.5.0 |
|
|
||||||
| dots | 是否显示面板指示点 | boolean | true | |
|
| dots | 是否显示面板指示点 | boolean | true | |
|
||||||
| dotsClass | 面板指示点类名 | string | `slick-dots` | |
|
| dotsClass | 面板指示点类名 | string | `slick-dots` | |
|
||||||
| easing | 动画效果 | string | linear | |
|
| easing | 动画效果 | string | `linear` | |
|
||||||
| effect | 动画效果函数,可取 scrollx, fade | string | scrollx | |
|
| effect | 动画效果函数 | `scrollx` \| `fade` | `scrollx` | |
|
||||||
|
| afterChange | 切换面板的回调 | function(current) | - | |
|
||||||
|
| beforeChange | 切换面板的回调 | function(from, to) | - | |
|
||||||
|
|
||||||
## 方法
|
## 方法
|
||||||
|
|
||||||
|
@ -35,4 +35,4 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/%24C9tmj978R/Carousel.svg
|
||||||
| next() | 切换到下一面板 | |
|
| next() | 切换到下一面板 | |
|
||||||
| prev() | 切换到上一面板 | |
|
| prev() | 切换到上一面板 | |
|
||||||
|
|
||||||
更多参数可参考:[vc-slick props](https://github.com/vueComponent/ant-design-vue/blob/next/components/vc-slick/src/default-props.js#L3)
|
更多属性可参考源码:[carousel props](https://github.com/vueComponent/ant-design-vue/blob/next/components/carousel/index.tsx)
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
@import '../../style/themes/index';
|
@import '../../style/themes/index';
|
||||||
@import '../../style/mixins/index';
|
@import '../../style/mixins/index';
|
||||||
|
|
||||||
.@{ant-prefix}-carousel {
|
@carousel-prefix-cls: ~'@{ant-prefix}-carousel';
|
||||||
|
|
||||||
|
.@{carousel-prefix-cls} {
|
||||||
.reset-component();
|
.reset-component();
|
||||||
|
|
||||||
.slick-slider {
|
.slick-slider {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-ms-touch-action: pan-y;
|
|
||||||
touch-action: pan-y;
|
touch-action: pan-y;
|
||||||
|
-webkit-touch-callout: none;
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slick-list {
|
.slick-list {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -45,11 +47,20 @@
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fix Carousel content height not match parent node
|
||||||
|
// when children is empty node
|
||||||
|
// https://github.com/ant-design/ant-design/issues/25878
|
||||||
|
> div > div {
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.slick-slider .slick-track,
|
.slick-slider .slick-track,
|
||||||
.slick-slider .slick-list {
|
.slick-slider .slick-list {
|
||||||
transform: translate3d(0, 0, 0);
|
transform: translate3d(0, 0, 0);
|
||||||
|
touch-action: pan-y;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slick-track {
|
.slick-track {
|
||||||
|
@ -72,17 +83,17 @@
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.slick-slide {
|
.slick-slide {
|
||||||
display: none;
|
display: none;
|
||||||
float: left;
|
float: left;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 1px;
|
min-height: 1px;
|
||||||
[dir='rtl'] & {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
img {
|
img {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.slick-loading img {
|
&.slick-loading img {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -103,8 +114,8 @@
|
||||||
.slick-vertical .slick-slide {
|
.slick-vertical .slick-slide {
|
||||||
display: block;
|
display: block;
|
||||||
height: auto;
|
height: auto;
|
||||||
border: @border-width-base @border-style-base transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.slick-arrow.slick-hidden {
|
.slick-arrow.slick-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -126,15 +137,18 @@
|
||||||
border: 0;
|
border: 0;
|
||||||
outline: none;
|
outline: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.slick-disabled::before {
|
&.slick-disabled::before {
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +156,7 @@
|
||||||
|
|
||||||
.slick-prev {
|
.slick-prev {
|
||||||
left: -25px;
|
left: -25px;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: '←';
|
content: '←';
|
||||||
}
|
}
|
||||||
|
@ -149,6 +164,7 @@
|
||||||
|
|
||||||
.slick-next {
|
.slick-next {
|
||||||
right: -25px;
|
right: -25px;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: '→';
|
content: '→';
|
||||||
}
|
}
|
||||||
|
@ -157,29 +173,45 @@
|
||||||
// Dots
|
// Dots
|
||||||
.slick-dots {
|
.slick-dots {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: block;
|
right: 0;
|
||||||
width: 100%;
|
bottom: 0;
|
||||||
height: @carousel-dot-height;
|
left: 0;
|
||||||
margin: 0;
|
z-index: 15;
|
||||||
padding: 0;
|
display: flex !important;
|
||||||
text-align: center;
|
justify-content: center;
|
||||||
|
margin-right: 15%;
|
||||||
|
margin-left: 15%;
|
||||||
|
padding-left: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
&-bottom {
|
&-bottom {
|
||||||
bottom: 12px;
|
bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-top {
|
&-top {
|
||||||
top: 12px;
|
top: 12px;
|
||||||
|
bottom: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
box-sizing: content-box;
|
||||||
|
width: @carousel-dot-width;
|
||||||
|
height: @carousel-dot-height;
|
||||||
margin: 0 2px;
|
margin: 0 2px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 3px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
text-indent: -999px;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
transition: all 0.5s;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
display: block;
|
display: block;
|
||||||
width: @carousel-dot-width;
|
width: 100%;
|
||||||
height: @carousel-dot-height;
|
height: @carousel-dot-height;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
color: transparent;
|
color: transparent;
|
||||||
|
@ -191,15 +223,21 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
transition: all 0.5s;
|
transition: all 0.5s;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.slick-active button {
|
|
||||||
|
&.slick-active {
|
||||||
width: @carousel-dot-active-width;
|
width: @carousel-dot-active-width;
|
||||||
background: @component-background;
|
|
||||||
opacity: 1;
|
& button {
|
||||||
|
background: @component-background;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
@ -213,26 +251,44 @@
|
||||||
.slick-dots {
|
.slick-dots {
|
||||||
top: 50%;
|
top: 50%;
|
||||||
bottom: auto;
|
bottom: auto;
|
||||||
|
flex-direction: column;
|
||||||
width: @carousel-dot-height;
|
width: @carousel-dot-height;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
margin: 0;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
|
|
||||||
&-left {
|
&-left {
|
||||||
|
right: auto;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-right {
|
&-right {
|
||||||
right: 12px;
|
right: 12px;
|
||||||
|
left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
margin: 0 2px;
|
width: @carousel-dot-height;
|
||||||
|
height: @carousel-dot-width;
|
||||||
|
margin: 4px 2px;
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
width: @carousel-dot-height;
|
width: @carousel-dot-height;
|
||||||
height: @carousel-dot-width;
|
height: @carousel-dot-width;
|
||||||
}
|
}
|
||||||
&.slick-active button {
|
|
||||||
|
&.slick-active {
|
||||||
width: @carousel-dot-height;
|
width: @carousel-dot-height;
|
||||||
height: @carousel-dot-active-width;
|
height: @carousel-dot-active-width;
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: @carousel-dot-height;
|
||||||
|
height: @carousel-dot-active-width;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@import './rtl';
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
@import '../../style/themes/index';
|
||||||
|
@import '../../style/mixins/index';
|
||||||
|
|
||||||
|
@carousel-prefix-cls: ~'@{ant-prefix}-carousel';
|
||||||
|
|
||||||
|
.@{carousel-prefix-cls} {
|
||||||
|
&-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slick-track {
|
||||||
|
.@{carousel-prefix-cls}-rtl & {
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.slick-prev {
|
||||||
|
.@{carousel-prefix-cls}-rtl & {
|
||||||
|
right: -25px;
|
||||||
|
left: auto;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '→';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.slick-next {
|
||||||
|
.@{carousel-prefix-cls}-rtl & {
|
||||||
|
right: auto;
|
||||||
|
left: -25px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '←';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dots
|
||||||
|
.slick-dots {
|
||||||
|
.@{carousel-prefix-cls}-rtl& {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-carousel-vertical {
|
||||||
|
.slick-dots {
|
||||||
|
.@{carousel-prefix-cls}-rtl& {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import classnames from '../../_util/classNames';
|
import classnames from '../_util/classNames';
|
||||||
import { cloneElement } from '../../_util/vnode';
|
import { cloneElement } from '../_util/vnode';
|
||||||
import { canGoNext } from './utils/innerSliderUtils';
|
import { canGoNext } from './utils/innerSliderUtils';
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
|
@ -1,4 +1,4 @@
|
||||||
import PropTypes from '../../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
accessibility: PropTypes.looseBool.def(true),
|
accessibility: PropTypes.looseBool.def(true),
|
|
@ -1,5 +1,6 @@
|
||||||
import classnames from '../../_util/classNames';
|
import classnames from '../_util/classNames';
|
||||||
import { cloneElement } from '../../_util/vnode';
|
import { cloneElement } from '../_util/vnode';
|
||||||
|
import { clamp } from './utils/innerSliderUtils';
|
||||||
|
|
||||||
const getDotCount = function (spec) {
|
const getDotCount = function (spec) {
|
||||||
let dots;
|
let dots;
|
||||||
|
@ -39,24 +40,26 @@ const Dots = (_, { attrs }) => {
|
||||||
//
|
//
|
||||||
// Credit: http://stackoverflow.com/a/13735425/1849458
|
// Credit: http://stackoverflow.com/a/13735425/1849458
|
||||||
const mouseEvents = { onMouseenter, onMouseover, onMouseleave };
|
const mouseEvents = { onMouseenter, onMouseover, onMouseleave };
|
||||||
const dots = Array.apply(
|
let dots = [];
|
||||||
null,
|
for (let i = 0; i < dotCount; i++) {
|
||||||
Array(dotCount + 1)
|
let _rightBound = (i + 1) * slidesToScroll - 1;
|
||||||
.join('0')
|
let rightBound = infinite ? _rightBound : clamp(_rightBound, 0, slideCount - 1);
|
||||||
.split(''),
|
let _leftBound = rightBound - (slidesToScroll - 1);
|
||||||
).map((x, i) => {
|
let leftBound = infinite ? _leftBound : clamp(_leftBound, 0, slideCount - 1);
|
||||||
const leftBound = i * slidesToScroll;
|
|
||||||
const rightBound = i * slidesToScroll + (slidesToScroll - 1);
|
let className = classnames({
|
||||||
const className = classnames({
|
'slick-active': infinite
|
||||||
'slick-active': currentSlide >= leftBound && currentSlide <= rightBound,
|
? currentSlide >= leftBound && currentSlide <= rightBound
|
||||||
|
: currentSlide === leftBound,
|
||||||
});
|
});
|
||||||
|
|
||||||
const dotOptions = {
|
let dotOptions = {
|
||||||
message: 'dots',
|
message: 'dots',
|
||||||
index: i,
|
index: i,
|
||||||
slidesToScroll,
|
slidesToScroll,
|
||||||
currentSlide,
|
currentSlide,
|
||||||
};
|
};
|
||||||
|
|
||||||
function onClick(e) {
|
function onClick(e) {
|
||||||
// In Autoplay the focus stays on clicked button even after transition
|
// In Autoplay the focus stays on clicked button even after transition
|
||||||
// to next slide. That only goes away by click somewhere outside
|
// to next slide. That only goes away by click somewhere outside
|
||||||
|
@ -65,14 +68,12 @@ const Dots = (_, { attrs }) => {
|
||||||
}
|
}
|
||||||
clickHandler(dotOptions);
|
clickHandler(dotOptions);
|
||||||
}
|
}
|
||||||
return (
|
dots = dots.concat(
|
||||||
<li key={i} class={className}>
|
<li key={i} class={className}>
|
||||||
{cloneElement(customPaging({ i }), {
|
{cloneElement(customPaging({ i }), { onClick })}
|
||||||
onClick,
|
</li>,
|
||||||
})}
|
|
||||||
</li>
|
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
return cloneElement(appendDots({ dots }), {
|
return cloneElement(appendDots({ dots }), {
|
||||||
class: dotsClass,
|
class: dotsClass,
|
|
@ -1,4 +1,4 @@
|
||||||
// base react-slick 0.23.2
|
// base react-slick 0.28.2
|
||||||
import Slider from './slider';
|
import Slider from './slider';
|
||||||
|
|
||||||
export default Slider;
|
export default Slider;
|
|
@ -21,6 +21,7 @@ const initialState = {
|
||||||
touchObject: { startX: 0, startY: 0, curX: 0, curY: 0 },
|
touchObject: { startX: 0, startY: 0, curX: 0, curY: 0 },
|
||||||
trackStyle: {},
|
trackStyle: {},
|
||||||
trackWidth: 0,
|
trackWidth: 0,
|
||||||
|
targetSlide: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default initialState;
|
export default initialState;
|
|
@ -1,7 +1,7 @@
|
||||||
import debounce from 'lodash-es/debounce';
|
import debounce from 'lodash-es/debounce';
|
||||||
import ResizeObserver from 'resize-observer-polyfill';
|
import ResizeObserver from 'resize-observer-polyfill';
|
||||||
import classnames from '../../_util/classNames';
|
import classnames from '../_util/classNames';
|
||||||
import BaseMixin from '../../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
import defaultProps from './default-props';
|
import defaultProps from './default-props';
|
||||||
import initialState from './initial-state';
|
import initialState from './initial-state';
|
||||||
import {
|
import {
|
||||||
|
@ -24,7 +24,7 @@ import {
|
||||||
import Track from './track';
|
import Track from './track';
|
||||||
import Dots from './dots';
|
import Dots from './dots';
|
||||||
import { PrevArrow, NextArrow } from './arrows';
|
import { PrevArrow, NextArrow } from './arrows';
|
||||||
import supportsPassive from '../../_util/supportsPassive';
|
import supportsPassive from '../_util/supportsPassive';
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
|
|
||||||
|
@ -42,10 +42,12 @@ export default {
|
||||||
this.callbackTimers = [];
|
this.callbackTimers = [];
|
||||||
this.clickable = true;
|
this.clickable = true;
|
||||||
this.debouncedResize = null;
|
this.debouncedResize = null;
|
||||||
|
const ssrState = this.ssrInit();
|
||||||
return {
|
return {
|
||||||
...initialState,
|
...initialState,
|
||||||
currentSlide: this.initialSlide,
|
currentSlide: this.initialSlide,
|
||||||
slideCount: this.children.length,
|
slideCount: this.children.length,
|
||||||
|
...ssrState,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -83,7 +85,9 @@ export default {
|
||||||
currentSlide: this.currentSlide,
|
currentSlide: this.currentSlide,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (nextProps.autoplay) {
|
if (!this.preProps.autoplay && nextProps.autoplay) {
|
||||||
|
this.handleAutoPlay('playing');
|
||||||
|
} else if (nextProps.autoplay) {
|
||||||
this.handleAutoPlay('update');
|
this.handleAutoPlay('update');
|
||||||
} else {
|
} else {
|
||||||
this.pause('paused');
|
this.pause('paused');
|
||||||
|
@ -92,8 +96,7 @@ export default {
|
||||||
this.preProps = { ...nextProps };
|
this.preProps = { ...nextProps };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeMount() {
|
mounted() {
|
||||||
this.ssrInit();
|
|
||||||
this.__emit('init');
|
this.__emit('init');
|
||||||
if (this.lazyLoad) {
|
if (this.lazyLoad) {
|
||||||
const slidesToLoad = getOnDemandLazySlides({
|
const slidesToLoad = getOnDemandLazySlides({
|
||||||
|
@ -107,8 +110,6 @@ export default {
|
||||||
this.__emit('lazyLoad', slidesToLoad);
|
this.__emit('lazyLoad', slidesToLoad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const spec = {
|
const spec = {
|
||||||
listRef: this.list,
|
listRef: this.list,
|
||||||
|
@ -118,7 +119,7 @@ export default {
|
||||||
};
|
};
|
||||||
this.updateState(spec, true, () => {
|
this.updateState(spec, true, () => {
|
||||||
this.adaptHeight();
|
this.adaptHeight();
|
||||||
this.autoplay && this.handleAutoPlay('update');
|
this.autoplay && this.handleAutoPlay('playing');
|
||||||
});
|
});
|
||||||
if (this.lazyLoad === 'progressive') {
|
if (this.lazyLoad === 'progressive') {
|
||||||
this.lazyLoadTimer = setInterval(this.progressiveLazyLoad, 1000);
|
this.lazyLoadTimer = setInterval(this.progressiveLazyLoad, 1000);
|
||||||
|
@ -132,14 +133,11 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.ro.observe(this.list);
|
this.ro.observe(this.list);
|
||||||
Array.prototype.forEach.call(document.querySelectorAll('.slick-slide'), slide => {
|
document.querySelectorAll &&
|
||||||
slide.onfocus = this.$props.pauseOnFocus ? this.onSlideFocus : null;
|
Array.prototype.forEach.call(document.querySelectorAll('.slick-slide'), slide => {
|
||||||
slide.onblur = this.$props.pauseOnFocus ? this.onSlideBlur : null;
|
slide.onfocus = this.$props.pauseOnFocus ? this.onSlideFocus : null;
|
||||||
});
|
slide.onblur = this.$props.pauseOnFocus ? this.onSlideBlur : null;
|
||||||
// To support server-side rendering
|
});
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (window.addEventListener) {
|
if (window.addEventListener) {
|
||||||
window.addEventListener('resize', this.onWindowResized);
|
window.addEventListener('resize', this.onWindowResized);
|
||||||
} else {
|
} else {
|
||||||
|
@ -166,6 +164,7 @@ export default {
|
||||||
if (this.autoplayTimer) {
|
if (this.autoplayTimer) {
|
||||||
clearInterval(this.autoplayTimer);
|
clearInterval(this.autoplayTimer);
|
||||||
}
|
}
|
||||||
|
this.ro?.disconnect();
|
||||||
},
|
},
|
||||||
updated() {
|
updated() {
|
||||||
this.checkImagesLoad();
|
this.checkImagesLoad();
|
||||||
|
@ -206,7 +205,8 @@ export default {
|
||||||
this.debouncedResize();
|
this.debouncedResize();
|
||||||
},
|
},
|
||||||
resizeWindow(setTrackStyle = true) {
|
resizeWindow(setTrackStyle = true) {
|
||||||
if (!this.track) return;
|
const isTrackMounted = Boolean(this.track);
|
||||||
|
if (!isTrackMounted) return;
|
||||||
const spec = {
|
const spec = {
|
||||||
listRef: this.list,
|
listRef: this.list,
|
||||||
trackRef: this.track,
|
trackRef: this.track,
|
||||||
|
@ -278,10 +278,9 @@ export default {
|
||||||
const currentWidth = `${childrenWidths[this.currentSlide]}px`;
|
const currentWidth = `${childrenWidths[this.currentSlide]}px`;
|
||||||
trackStyle.left = `calc(${trackStyle.left} + (100% - ${currentWidth}) / 2 ) `;
|
trackStyle.left = `calc(${trackStyle.left} + (100% - ${currentWidth}) / 2 ) `;
|
||||||
}
|
}
|
||||||
this.setState({
|
return {
|
||||||
trackStyle,
|
trackStyle,
|
||||||
});
|
};
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const childrenCount = children.length;
|
const childrenCount = children.length;
|
||||||
const spec = { ...this.$props, ...this.$data, slideCount: childrenCount };
|
const spec = { ...this.$props, ...this.$data, slideCount: childrenCount };
|
||||||
|
@ -296,13 +295,17 @@ export default {
|
||||||
width: trackWidth + '%',
|
width: trackWidth + '%',
|
||||||
left: trackLeft + '%',
|
left: trackLeft + '%',
|
||||||
};
|
};
|
||||||
this.setState({
|
return {
|
||||||
slideWidth: slideWidth + '%',
|
slideWidth: slideWidth + '%',
|
||||||
trackStyle,
|
trackStyle,
|
||||||
});
|
};
|
||||||
},
|
},
|
||||||
checkImagesLoad() {
|
checkImagesLoad() {
|
||||||
const images = document.querySelectorAll('.slick-slide img');
|
let images =
|
||||||
|
(this.list &&
|
||||||
|
this.list.querySelectorAll &&
|
||||||
|
this.list.querySelectorAll('.slick-slide img')) ||
|
||||||
|
[];
|
||||||
const imagesCount = images.length;
|
const imagesCount = images.length;
|
||||||
let loadedCount = 0;
|
let loadedCount = 0;
|
||||||
Array.prototype.forEach.call(images, image => {
|
Array.prototype.forEach.call(images, image => {
|
||||||
|
@ -376,10 +379,16 @@ export default {
|
||||||
if (this.$attrs.onLazyLoad && slidesToLoad.length > 0) {
|
if (this.$attrs.onLazyLoad && slidesToLoad.length > 0) {
|
||||||
this.__emit('lazyLoad', slidesToLoad);
|
this.__emit('lazyLoad', slidesToLoad);
|
||||||
}
|
}
|
||||||
|
if (!this.$props.waitForAnimate && this.animationEndCallback) {
|
||||||
|
clearTimeout(this.animationEndCallback);
|
||||||
|
afterChange && afterChange(currentSlide);
|
||||||
|
delete this.animationEndCallback;
|
||||||
|
}
|
||||||
this.setState(state, () => {
|
this.setState(state, () => {
|
||||||
asNavFor &&
|
if (asNavFor && this.asNavForIndex !== index) {
|
||||||
asNavFor.innerSlider.currentSlide !== currentSlide &&
|
this.asNavForIndex = index;
|
||||||
asNavFor.innerSlider.slideHandler(index);
|
asNavFor.innerSlider.slideHandler(index);
|
||||||
|
}
|
||||||
if (!nextState) return;
|
if (!nextState) return;
|
||||||
this.animationEndCallback = setTimeout(() => {
|
this.animationEndCallback = setTimeout(() => {
|
||||||
const { animating, ...firstBatch } = nextState;
|
const { animating, ...firstBatch } = nextState;
|
||||||
|
@ -400,6 +409,11 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
this.slideHandler(targetSlide);
|
this.slideHandler(targetSlide);
|
||||||
}
|
}
|
||||||
|
this.$props.autoplay && this.handleAutoPlay('update');
|
||||||
|
if (this.$props.focusOnSelect) {
|
||||||
|
const nodes = this.list.querySelectorAll('.slick-current');
|
||||||
|
nodes[0] && nodes[0].focus();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
clickHandler(e) {
|
clickHandler(e) {
|
||||||
if (this.clickable === false) {
|
if (this.clickable === false) {
|
||||||
|
@ -465,6 +479,10 @@ export default {
|
||||||
this.enableBodyScroll();
|
this.enableBodyScroll();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
touchEnd(e) {
|
||||||
|
this.swipeEnd(e);
|
||||||
|
this.clickable = true;
|
||||||
|
},
|
||||||
slickPrev() {
|
slickPrev() {
|
||||||
// this and fellow methods are wrapped in setTimeout
|
// this and fellow methods are wrapped in setTimeout
|
||||||
// to make sure initialize setState has happened before
|
// to make sure initialize setState has happened before
|
||||||
|
@ -599,11 +617,13 @@ export default {
|
||||||
'variableWidth',
|
'variableWidth',
|
||||||
'unslick',
|
'unslick',
|
||||||
'centerPadding',
|
'centerPadding',
|
||||||
|
'targetSlide',
|
||||||
|
'useCSS',
|
||||||
]);
|
]);
|
||||||
const { pauseOnHover } = this.$props;
|
const { pauseOnHover } = this.$props;
|
||||||
trackProps = {
|
trackProps = {
|
||||||
...trackProps,
|
...trackProps,
|
||||||
focusOnSelect: this.focusOnSelect ? this.selectHandler : null,
|
focusOnSelect: this.focusOnSelect && this.clickable ? this.selectHandler : null,
|
||||||
ref: this.trackRefHandler,
|
ref: this.trackRefHandler,
|
||||||
onMouseleave: pauseOnHover ? this.onTrackLeave : noop,
|
onMouseleave: pauseOnHover ? this.onTrackLeave : noop,
|
||||||
onMouseover: pauseOnHover ? this.onTrackOver : noop,
|
onMouseover: pauseOnHover ? this.onTrackOver : noop,
|
||||||
|
@ -701,14 +721,15 @@ export default {
|
||||||
: noop,
|
: noop,
|
||||||
[supportsPassive ? 'onTouchmovePassive' : 'onTouchmove']:
|
[supportsPassive ? 'onTouchmovePassive' : 'onTouchmove']:
|
||||||
this.dragging && touchMove ? this.swipeMove : noop,
|
this.dragging && touchMove ? this.swipeMove : noop,
|
||||||
onTouchend: touchMove ? this.swipeEnd : noop,
|
onTouchend: touchMove ? this.touchEnd : noop,
|
||||||
onTouchcancel: this.dragging && touchMove ? this.swipeEnd : noop,
|
onTouchcancel: this.dragging && touchMove ? this.swipeEnd : noop,
|
||||||
onKeydown: this.accessibility ? this.keyHandler : noop,
|
onKeydown: this.accessibility ? this.keyHandler : noop,
|
||||||
};
|
};
|
||||||
|
|
||||||
let innerSliderProps = {
|
let innerSliderProps = {
|
||||||
class: className,
|
class: className,
|
||||||
// dir: 'ltr',
|
dir: 'ltr',
|
||||||
|
style: this.$attrs.style,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.unslick) {
|
if (this.unslick) {
|
|
@ -1,10 +1,10 @@
|
||||||
import json2mq from '../../_util/json2mq';
|
import json2mq from '../_util/json2mq';
|
||||||
import BaseMixin from '../../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
import { cloneElement } from '../../_util/vnode';
|
import { cloneElement } from '../_util/vnode';
|
||||||
import InnerSlider from './inner-slider';
|
import InnerSlider from './inner-slider';
|
||||||
import defaultProps from './default-props';
|
import defaultProps from './default-props';
|
||||||
import { canUseDOM } from './utils/innerSliderUtils';
|
import { canUseDOM } from './utils/innerSliderUtils';
|
||||||
import { getSlot } from '../../_util/props-util';
|
import { getSlot } from '../_util/props-util';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
@ -21,7 +21,7 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
// handles responsive breakpoints
|
// handles responsive breakpoints
|
||||||
beforeMount() {
|
mounted() {
|
||||||
if (this.responsive) {
|
if (this.responsive) {
|
||||||
const breakpoints = this.responsive.map(breakpt => breakpt.breakpoint);
|
const breakpoints = this.responsive.map(breakpt => breakpt.breakpoint);
|
||||||
// sort them in increasing order of their numerical value
|
// sort them in increasing order of their numerical value
|
||||||
|
@ -77,19 +77,19 @@ export default defineComponent({
|
||||||
this._responsiveMediaHandlers.push({ mql, query, listener });
|
this._responsiveMediaHandlers.push({ mql, query, listener });
|
||||||
},
|
},
|
||||||
slickPrev() {
|
slickPrev() {
|
||||||
this.innerSlider.slickPrev();
|
this.innerSlider?.slickPrev();
|
||||||
},
|
},
|
||||||
slickNext() {
|
slickNext() {
|
||||||
this.innerSlider.slickNext();
|
this.innerSlider?.slickNext();
|
||||||
},
|
},
|
||||||
slickGoTo(slide, dontAnimate = false) {
|
slickGoTo(slide, dontAnimate = false) {
|
||||||
this.innerSlider.slickGoTo(slide, dontAnimate);
|
this.innerSlider?.slickGoTo(slide, dontAnimate);
|
||||||
},
|
},
|
||||||
slickPause() {
|
slickPause() {
|
||||||
this.innerSlider.pause('paused');
|
this.innerSlider?.pause('paused');
|
||||||
},
|
},
|
||||||
slickPlay() {
|
slickPlay() {
|
||||||
this.innerSlider.handleAutoPlay('play');
|
this.innerSlider?.handleAutoPlay('play');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ export default defineComponent({
|
||||||
|
|
||||||
if (settings === 'unslick') {
|
if (settings === 'unslick') {
|
||||||
const className = 'regular slider ' + (this.className || '');
|
const className = 'regular slider ' + (this.className || '');
|
||||||
return <div class={className}>{newChildren}</div>;
|
return <div class={className}>{children}</div>;
|
||||||
} else if (newChildren.length <= settings.slidesToShow) {
|
} else if (newChildren.length <= settings.slidesToShow) {
|
||||||
settings.unslick = true;
|
settings.unslick = true;
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import { createVNode } from 'vue';
|
import { createVNode } from 'vue';
|
||||||
import classnames from '../../_util/classNames';
|
import classnames from '../_util/classNames';
|
||||||
import { cloneElement } from '../../_util/vnode';
|
import { cloneElement } from '../_util/vnode';
|
||||||
import { flattenChildren } from '../../_util/props-util';
|
import { flattenChildren } from '../_util/props-util';
|
||||||
import { lazyStartIndex, lazyEndIndex, getPreClones } from './utils/innerSliderUtils';
|
import { lazyStartIndex, lazyEndIndex, getPreClones } from './utils/innerSliderUtils';
|
||||||
|
|
||||||
// given specifications/props for a slide, fetch all the classes that need to be applied to the slide
|
// given specifications/props for a slide, fetch all the classes that need to be applied to the slide
|
||||||
|
@ -24,7 +24,15 @@ const getSlideClasses = spec => {
|
||||||
} else {
|
} else {
|
||||||
slickActive = spec.currentSlide <= index && index < spec.currentSlide + spec.slidesToShow;
|
slickActive = spec.currentSlide <= index && index < spec.currentSlide + spec.slidesToShow;
|
||||||
}
|
}
|
||||||
const slickCurrent = index === spec.currentSlide;
|
let focusedSlide;
|
||||||
|
if (spec.targetSlide < 0) {
|
||||||
|
focusedSlide = spec.targetSlide + spec.slideCount;
|
||||||
|
} else if (spec.targetSlide >= spec.slideCount) {
|
||||||
|
focusedSlide = spec.targetSlide - spec.slideCount;
|
||||||
|
} else {
|
||||||
|
focusedSlide = spec.targetSlide;
|
||||||
|
}
|
||||||
|
let slickCurrent = index === focusedSlide;
|
||||||
return {
|
return {
|
||||||
'slick-slide': true,
|
'slick-slide': true,
|
||||||
'slick-active': slickActive,
|
'slick-active': slickActive,
|
||||||
|
@ -49,32 +57,24 @@ const getSlideStyle = function (spec) {
|
||||||
style.left = -spec.index * parseInt(spec.slideWidth) + 'px';
|
style.left = -spec.index * parseInt(spec.slideWidth) + 'px';
|
||||||
}
|
}
|
||||||
style.opacity = spec.currentSlide === spec.index ? 1 : 0;
|
style.opacity = spec.currentSlide === spec.index ? 1 : 0;
|
||||||
style.transition =
|
if (spec.useCSS) {
|
||||||
'opacity ' +
|
style.transition =
|
||||||
spec.speed +
|
'opacity ' +
|
||||||
'ms ' +
|
spec.speed +
|
||||||
spec.cssEase +
|
'ms ' +
|
||||||
', ' +
|
spec.cssEase +
|
||||||
'visibility ' +
|
', ' +
|
||||||
spec.speed +
|
'visibility ' +
|
||||||
'ms ' +
|
spec.speed +
|
||||||
spec.cssEase;
|
'ms ' +
|
||||||
style.WebkitTransition =
|
spec.cssEase;
|
||||||
'opacity ' +
|
}
|
||||||
spec.speed +
|
|
||||||
'ms ' +
|
|
||||||
spec.cssEase +
|
|
||||||
', ' +
|
|
||||||
'visibility ' +
|
|
||||||
spec.speed +
|
|
||||||
'ms ' +
|
|
||||||
spec.cssEase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return style;
|
return style;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getKey = (child, fallbackKey) => child.key || (child.key === 0 && '0') || fallbackKey;
|
const getKey = (child, fallbackKey) => child.key + '-' + fallbackKey;
|
||||||
|
|
||||||
const renderSlides = function (spec, children) {
|
const renderSlides = function (spec, children) {
|
||||||
let key;
|
let key;
|
|
@ -1,4 +1,15 @@
|
||||||
import supportsPassive from '../../../_util/supportsPassive';
|
// import supportsPassive from '../../../_util/supportsPassive';
|
||||||
|
|
||||||
|
export function clamp(number, lowerBound, upperBound) {
|
||||||
|
return Math.max(lowerBound, Math.min(number, upperBound));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const safePreventDefault = event => {
|
||||||
|
const passiveEvents = ['touchstart', 'touchmove', 'wheel'];
|
||||||
|
if (!passiveEvents.includes(event.type)) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const getOnDemandLazySlides = spec => {
|
export const getOnDemandLazySlides = spec => {
|
||||||
const onDemandSlides = [];
|
const onDemandSlides = [];
|
||||||
|
@ -91,8 +102,10 @@ export const extractObject = (spec, keys) => {
|
||||||
export const initializedState = spec => {
|
export const initializedState = spec => {
|
||||||
// spec also contains listRef, trackRef
|
// spec also contains listRef, trackRef
|
||||||
const slideCount = spec.children.length;
|
const slideCount = spec.children.length;
|
||||||
const listWidth = Math.ceil(getWidth(spec.listRef));
|
const listNode = spec.listRef;
|
||||||
const trackWidth = Math.ceil(getWidth(spec.trackRef));
|
const listWidth = Math.ceil(getWidth(listNode));
|
||||||
|
const trackNode = spec.trackRef;
|
||||||
|
const trackWidth = Math.ceil(getWidth(trackNode));
|
||||||
let slideWidth;
|
let slideWidth;
|
||||||
if (!spec.vertical) {
|
if (!spec.vertical) {
|
||||||
let centerPaddingAdj = spec.centerMode && parseInt(spec.centerPadding) * 2;
|
let centerPaddingAdj = spec.centerMode && parseInt(spec.centerPadding) * 2;
|
||||||
|
@ -103,15 +116,15 @@ export const initializedState = spec => {
|
||||||
} else {
|
} else {
|
||||||
slideWidth = listWidth;
|
slideWidth = listWidth;
|
||||||
}
|
}
|
||||||
const slideHeight = spec.listRef && getHeight(spec.listRef.querySelector('[data-index="0"]'));
|
const slideHeight = listNode && getHeight(listNode.querySelector('[data-index="0"]'));
|
||||||
const listHeight = slideHeight * spec.slidesToShow;
|
const listHeight = slideHeight * spec.slidesToShow;
|
||||||
let currentSlide = spec.currentSlide === undefined ? spec.initialSlide : spec.currentSlide;
|
let currentSlide = spec.currentSlide === undefined ? spec.initialSlide : spec.currentSlide;
|
||||||
if (spec.rtl && spec.currentSlide === undefined) {
|
if (spec.rtl && spec.currentSlide === undefined) {
|
||||||
currentSlide = slideCount - 1 - spec.initialSlide;
|
currentSlide = slideCount - 1 - spec.initialSlide;
|
||||||
}
|
}
|
||||||
const lazyLoadedList = spec.lazyLoadedList || [];
|
let lazyLoadedList = spec.lazyLoadedList || [];
|
||||||
const slidesToLoad = getOnDemandLazySlides({ currentSlide, lazyLoadedList }, spec);
|
const slidesToLoad = getOnDemandLazySlides({ ...spec, currentSlide, lazyLoadedList }, spec);
|
||||||
lazyLoadedList.concat(slidesToLoad);
|
lazyLoadedList = lazyLoadedList.concat(slidesToLoad);
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
slideCount,
|
slideCount,
|
||||||
|
@ -139,7 +152,6 @@ export const slideHandler = spec => {
|
||||||
infinite,
|
infinite,
|
||||||
index,
|
index,
|
||||||
slideCount,
|
slideCount,
|
||||||
lazyLoadedList,
|
|
||||||
lazyLoad,
|
lazyLoad,
|
||||||
currentSlide,
|
currentSlide,
|
||||||
centerMode,
|
centerMode,
|
||||||
|
@ -147,6 +159,7 @@ export const slideHandler = spec => {
|
||||||
slidesToShow,
|
slidesToShow,
|
||||||
useCSS,
|
useCSS,
|
||||||
} = spec;
|
} = spec;
|
||||||
|
let { lazyLoadedList } = spec;
|
||||||
if (waitForAnimate && animating) return {};
|
if (waitForAnimate && animating) return {};
|
||||||
let animationSlide = index;
|
let animationSlide = index;
|
||||||
let finalSlide;
|
let finalSlide;
|
||||||
|
@ -154,6 +167,7 @@ export const slideHandler = spec => {
|
||||||
let finalLeft;
|
let finalLeft;
|
||||||
let state = {};
|
let state = {};
|
||||||
let nextState = {};
|
let nextState = {};
|
||||||
|
const targetSlide = infinite ? index : clamp(index, 0, slideCount - 1);
|
||||||
if (fade) {
|
if (fade) {
|
||||||
if (!infinite && (index < 0 || index >= slideCount)) return {};
|
if (!infinite && (index < 0 || index >= slideCount)) return {};
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
|
@ -162,14 +176,15 @@ export const slideHandler = spec => {
|
||||||
animationSlide = index - slideCount;
|
animationSlide = index - slideCount;
|
||||||
}
|
}
|
||||||
if (lazyLoad && lazyLoadedList.indexOf(animationSlide) < 0) {
|
if (lazyLoad && lazyLoadedList.indexOf(animationSlide) < 0) {
|
||||||
lazyLoadedList.push(animationSlide);
|
lazyLoadedList = lazyLoadedList.concat(animationSlide);
|
||||||
}
|
}
|
||||||
state = {
|
state = {
|
||||||
animating: true,
|
animating: true,
|
||||||
currentSlide: animationSlide,
|
currentSlide: animationSlide,
|
||||||
lazyLoadedList,
|
lazyLoadedList,
|
||||||
|
targetSlide: animationSlide,
|
||||||
};
|
};
|
||||||
nextState = { animating: false };
|
nextState = { animating: false, targetSlide: animationSlide };
|
||||||
} else {
|
} else {
|
||||||
finalSlide = animationSlide;
|
finalSlide = animationSlide;
|
||||||
if (animationSlide < 0) {
|
if (animationSlide < 0) {
|
||||||
|
@ -188,19 +203,28 @@ export const slideHandler = spec => {
|
||||||
if (!infinite) finalSlide = slideCount - slidesToShow;
|
if (!infinite) finalSlide = slideCount - slidesToShow;
|
||||||
else if (slideCount % slidesToScroll !== 0) finalSlide = 0;
|
else if (slideCount % slidesToScroll !== 0) finalSlide = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!infinite && animationSlide + slidesToShow >= slideCount) {
|
||||||
|
finalSlide = slideCount - slidesToShow;
|
||||||
|
}
|
||||||
|
|
||||||
animationLeft = getTrackLeft({ ...spec, slideIndex: animationSlide });
|
animationLeft = getTrackLeft({ ...spec, slideIndex: animationSlide });
|
||||||
finalLeft = getTrackLeft({ ...spec, slideIndex: finalSlide });
|
finalLeft = getTrackLeft({ ...spec, slideIndex: finalSlide });
|
||||||
if (!infinite) {
|
if (!infinite) {
|
||||||
if (animationLeft === finalLeft) animationSlide = finalSlide;
|
if (animationLeft === finalLeft) animationSlide = finalSlide;
|
||||||
animationLeft = finalLeft;
|
animationLeft = finalLeft;
|
||||||
}
|
}
|
||||||
lazyLoad &&
|
if (lazyLoad) {
|
||||||
lazyLoadedList.concat(getOnDemandLazySlides({ ...spec, currentSlide: animationSlide }));
|
lazyLoadedList = lazyLoadedList.concat(
|
||||||
|
getOnDemandLazySlides({ ...spec, currentSlide: animationSlide }),
|
||||||
|
);
|
||||||
|
}
|
||||||
if (!useCSS) {
|
if (!useCSS) {
|
||||||
state = {
|
state = {
|
||||||
currentSlide: finalSlide,
|
currentSlide: finalSlide,
|
||||||
trackStyle: getTrackCSS({ ...spec, left: finalLeft }),
|
trackStyle: getTrackCSS({ ...spec, left: finalLeft }),
|
||||||
lazyLoadedList,
|
lazyLoadedList,
|
||||||
|
targetSlide,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
state = {
|
state = {
|
||||||
|
@ -208,12 +232,14 @@ export const slideHandler = spec => {
|
||||||
currentSlide: finalSlide,
|
currentSlide: finalSlide,
|
||||||
trackStyle: getTrackAnimateCSS({ ...spec, left: animationLeft }),
|
trackStyle: getTrackAnimateCSS({ ...spec, left: animationLeft }),
|
||||||
lazyLoadedList,
|
lazyLoadedList,
|
||||||
|
targetSlide,
|
||||||
};
|
};
|
||||||
nextState = {
|
nextState = {
|
||||||
animating: false,
|
animating: false,
|
||||||
currentSlide: finalSlide,
|
currentSlide: finalSlide,
|
||||||
trackStyle: getTrackCSS({ ...spec, left: finalLeft }),
|
trackStyle: getTrackCSS({ ...spec, left: finalLeft }),
|
||||||
swipeLeft: null,
|
swipeLeft: null,
|
||||||
|
targetSlide,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,7 +248,15 @@ export const slideHandler = spec => {
|
||||||
|
|
||||||
export const changeSlide = (spec, options) => {
|
export const changeSlide = (spec, options) => {
|
||||||
let previousInt, slideOffset, targetSlide;
|
let previousInt, slideOffset, targetSlide;
|
||||||
const { slidesToScroll, slidesToShow, slideCount, currentSlide, lazyLoad, infinite } = spec;
|
const {
|
||||||
|
slidesToScroll,
|
||||||
|
slidesToShow,
|
||||||
|
slideCount,
|
||||||
|
currentSlide,
|
||||||
|
targetSlide: previousTargetSlide,
|
||||||
|
lazyLoad,
|
||||||
|
infinite,
|
||||||
|
} = spec;
|
||||||
const unevenOffset = slideCount % slidesToScroll !== 0;
|
const unevenOffset = slideCount % slidesToScroll !== 0;
|
||||||
const indexOffset = unevenOffset ? 0 : (slideCount - currentSlide) % slidesToScroll;
|
const indexOffset = unevenOffset ? 0 : (slideCount - currentSlide) % slidesToScroll;
|
||||||
|
|
||||||
|
@ -233,24 +267,25 @@ export const changeSlide = (spec, options) => {
|
||||||
previousInt = currentSlide - slideOffset;
|
previousInt = currentSlide - slideOffset;
|
||||||
targetSlide = previousInt === -1 ? slideCount - 1 : previousInt;
|
targetSlide = previousInt === -1 ? slideCount - 1 : previousInt;
|
||||||
}
|
}
|
||||||
|
if (!infinite) {
|
||||||
|
targetSlide = previousTargetSlide - slidesToScroll;
|
||||||
|
}
|
||||||
} else if (options.message === 'next') {
|
} else if (options.message === 'next') {
|
||||||
slideOffset = indexOffset === 0 ? slidesToScroll : indexOffset;
|
slideOffset = indexOffset === 0 ? slidesToScroll : indexOffset;
|
||||||
targetSlide = currentSlide + slideOffset;
|
targetSlide = currentSlide + slideOffset;
|
||||||
if (lazyLoad && !infinite) {
|
if (lazyLoad && !infinite) {
|
||||||
targetSlide = ((currentSlide + slidesToScroll) % slideCount) + indexOffset;
|
targetSlide = ((currentSlide + slidesToScroll) % slideCount) + indexOffset;
|
||||||
}
|
}
|
||||||
|
if (!infinite) {
|
||||||
|
targetSlide = previousTargetSlide + slidesToScroll;
|
||||||
|
}
|
||||||
} else if (options.message === 'dots') {
|
} else if (options.message === 'dots') {
|
||||||
// Click on dots
|
// Click on dots
|
||||||
targetSlide = options.index * options.slidesToScroll;
|
targetSlide = options.index * options.slidesToScroll;
|
||||||
if (targetSlide === options.currentSlide) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else if (options.message === 'children') {
|
} else if (options.message === 'children') {
|
||||||
// Click on the slides
|
// Click on the slides
|
||||||
targetSlide = options.index;
|
targetSlide = options.index;
|
||||||
if (targetSlide === options.currentSlide) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (infinite) {
|
if (infinite) {
|
||||||
const direction = siblingDirection({ ...spec, targetSlide });
|
const direction = siblingDirection({ ...spec, targetSlide });
|
||||||
if (targetSlide > options.currentSlide && direction === 'left') {
|
if (targetSlide > options.currentSlide && direction === 'left') {
|
||||||
|
@ -261,9 +296,6 @@ export const changeSlide = (spec, options) => {
|
||||||
}
|
}
|
||||||
} else if (options.message === 'index') {
|
} else if (options.message === 'index') {
|
||||||
targetSlide = Number(options.index);
|
targetSlide = Number(options.index);
|
||||||
if (targetSlide === options.currentSlide) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return targetSlide;
|
return targetSlide;
|
||||||
};
|
};
|
||||||
|
@ -277,7 +309,7 @@ export const keyHandler = (e, accessibility, rtl) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const swipeStart = (e, swipe, draggable) => {
|
export const swipeStart = (e, swipe, draggable) => {
|
||||||
e.target.tagName === 'IMG' && !supportsPassive && e.preventDefault();
|
e.target.tagName === 'IMG' && safePreventDefault.preventDefault();
|
||||||
if (!swipe || (!draggable && e.type.indexOf('mouse') !== -1)) return '';
|
if (!swipe || (!draggable && e.type.indexOf('mouse') !== -1)) return '';
|
||||||
return {
|
return {
|
||||||
dragging: true,
|
dragging: true,
|
||||||
|
@ -313,11 +345,8 @@ export const swipeMove = (e, spec) => {
|
||||||
listWidth,
|
listWidth,
|
||||||
} = spec;
|
} = spec;
|
||||||
if (scrolling) return;
|
if (scrolling) return;
|
||||||
if (animating) {
|
if (animating) return safePreventDefault(e);
|
||||||
!supportsPassive && e.preventDefault();
|
if (vertical && swipeToSlide && verticalSwiping) safePreventDefault(e);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (vertical && swipeToSlide && verticalSwiping) !supportsPassive && e.preventDefault();
|
|
||||||
let swipeLeft;
|
let swipeLeft;
|
||||||
let state = {};
|
let state = {};
|
||||||
const curLeft = getTrackLeft(spec);
|
const curLeft = getTrackLeft(spec);
|
||||||
|
@ -343,9 +372,9 @@ export const swipeMove = (e, spec) => {
|
||||||
let touchSwipeLength = touchObject.swipeLength;
|
let touchSwipeLength = touchObject.swipeLength;
|
||||||
if (!infinite) {
|
if (!infinite) {
|
||||||
if (
|
if (
|
||||||
(currentSlide === 0 && swipeDirection === 'right') ||
|
(currentSlide === 0 && (swipeDirection === 'right' || swipeDirection === 'down')) ||
|
||||||
(currentSlide + 1 >= dotCount && swipeDirection === 'left') ||
|
(currentSlide + 1 >= dotCount && (swipeDirection === 'left' || swipeDirection === 'up')) ||
|
||||||
(!canGoNext(spec) && swipeDirection === 'left')
|
(!canGoNext(spec) && (swipeDirection === 'left' || swipeDirection === 'up'))
|
||||||
) {
|
) {
|
||||||
touchSwipeLength = touchObject.swipeLength * edgeFriction;
|
touchSwipeLength = touchObject.swipeLength * edgeFriction;
|
||||||
if (edgeDragged === false && onEdge) {
|
if (edgeDragged === false && onEdge) {
|
||||||
|
@ -384,7 +413,7 @@ export const swipeMove = (e, spec) => {
|
||||||
}
|
}
|
||||||
if (touchObject.swipeLength > 10) {
|
if (touchObject.swipeLength > 10) {
|
||||||
state['swiping'] = true;
|
state['swiping'] = true;
|
||||||
!supportsPassive && e.preventDefault();
|
safePreventDefault(e);
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
@ -397,13 +426,15 @@ export const swipeEnd = (e, spec) => {
|
||||||
touchThreshold,
|
touchThreshold,
|
||||||
verticalSwiping,
|
verticalSwiping,
|
||||||
listHeight,
|
listHeight,
|
||||||
currentSlide,
|
|
||||||
swipeToSlide,
|
swipeToSlide,
|
||||||
scrolling,
|
scrolling,
|
||||||
onSwipe,
|
onSwipe,
|
||||||
|
targetSlide,
|
||||||
|
currentSlide,
|
||||||
|
infinite,
|
||||||
} = spec;
|
} = spec;
|
||||||
if (!dragging) {
|
if (!dragging) {
|
||||||
if (swipe) e.preventDefault();
|
if (swipe) safePreventDefault(e);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const minSwipe = verticalSwiping ? listHeight / touchThreshold : listWidth / touchThreshold;
|
const minSwipe = verticalSwiping ? listHeight / touchThreshold : listWidth / touchThreshold;
|
||||||
|
@ -425,26 +456,27 @@ export const swipeEnd = (e, spec) => {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
if (touchObject.swipeLength > minSwipe) {
|
if (touchObject.swipeLength > minSwipe) {
|
||||||
e.preventDefault();
|
safePreventDefault(e);
|
||||||
if (onSwipe) {
|
if (onSwipe) {
|
||||||
onSwipe(swipeDirection);
|
onSwipe(swipeDirection);
|
||||||
}
|
}
|
||||||
let slideCount, newSlide;
|
let slideCount, newSlide;
|
||||||
|
let activeSlide = infinite ? currentSlide : targetSlide;
|
||||||
switch (swipeDirection) {
|
switch (swipeDirection) {
|
||||||
case 'left':
|
case 'left':
|
||||||
case 'up':
|
case 'up':
|
||||||
newSlide = currentSlide + getSlideCount(spec);
|
newSlide = activeSlide + getSlideCount(spec);
|
||||||
slideCount = swipeToSlide ? checkNavigable(spec, newSlide) : newSlide;
|
slideCount = swipeToSlide ? checkNavigable(spec, newSlide) : newSlide;
|
||||||
state['currentDirection'] = 0;
|
state['currentDirection'] = 0;
|
||||||
break;
|
break;
|
||||||
case 'right':
|
case 'right':
|
||||||
case 'down':
|
case 'down':
|
||||||
newSlide = currentSlide - getSlideCount(spec);
|
newSlide = activeSlide - getSlideCount(spec);
|
||||||
slideCount = swipeToSlide ? checkNavigable(spec, newSlide) : newSlide;
|
slideCount = swipeToSlide ? checkNavigable(spec, newSlide) : newSlide;
|
||||||
state['currentDirection'] = 1;
|
state['currentDirection'] = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
slideCount = currentSlide;
|
slideCount = activeSlide;
|
||||||
}
|
}
|
||||||
state['triggerSlideHandler'] = slideCount;
|
state['triggerSlideHandler'] = slideCount;
|
||||||
} else {
|
} else {
|
||||||
|
@ -487,7 +519,7 @@ export const getSlideCount = spec => {
|
||||||
if (spec.swipeToSlide) {
|
if (spec.swipeToSlide) {
|
||||||
let swipedSlide;
|
let swipedSlide;
|
||||||
const slickList = spec.listRef;
|
const slickList = spec.listRef;
|
||||||
const slides = slickList.querySelectorAll('.slick-slide');
|
const slides = (slickList.querySelectorAll && slickList.querySelectorAll('.slick-slide')) || [];
|
||||||
Array.from(slides).every(slide => {
|
Array.from(slides).every(slide => {
|
||||||
if (!spec.vertical) {
|
if (!spec.vertical) {
|
||||||
if (slide.offsetLeft - centerOffset + getWidth(slide) / 2 > spec.swipeLeft * -1) {
|
if (slide.offsetLeft - centerOffset + getWidth(slide) / 2 > spec.swipeLeft * -1) {
|
Loading…
Reference in New Issue