UNPKG

21.2 kBJavaScriptView Raw
1/**
2 * Swiper Vue 10.0.4
3 * Most modern mobile touch slider and framework with hardware accelerated transitions
4 * https://swiperjs.com
5 *
6 * Copyright 2014-2023 Vladimir Kharlampidi
7 *
8 * Released under the MIT License
9 *
10 * Released on: July 8, 2023
11 */
12
13import { h, ref, onUpdated, provide, watch, nextTick, onMounted, onBeforeUnmount, onBeforeUpdate, computed, inject } from 'vue';
14import { S as Swiper$1 } from './shared/swiper-core.mjs';
15import { g as getParams, a as getChangedParams, u as updateOnVirtualData, m as mountSwiper } from './shared/update-on-virtual-data.mjs';
16import { e as extend, u as updateSwiper, d as uniqueClasses, w as wrapperClass, n as needsNavigation, b as needsScrollbar, a as needsPagination } from './shared/update-swiper.mjs';
17
18function getChildren(originalSlots, slidesRef, oldSlidesRef) {
19 if (originalSlots === void 0) {
20 originalSlots = {};
21 }
22 const slides = [];
23 const slots = {
24 'container-start': [],
25 'container-end': [],
26 'wrapper-start': [],
27 'wrapper-end': []
28 };
29 const getSlidesFromElements = (els, slotName) => {
30 if (!Array.isArray(els)) {
31 return;
32 }
33 els.forEach(vnode => {
34 const isFragment = typeof vnode.type === 'symbol';
35 if (slotName === 'default') slotName = 'container-end';
36 if (isFragment && vnode.children) {
37 getSlidesFromElements(vnode.children, slotName);
38 } else if (vnode.type && (vnode.type.name === 'SwiperSlide' || vnode.type.name === 'AsyncComponentWrapper')) {
39 slides.push(vnode);
40 } else if (slots[slotName]) {
41 slots[slotName].push(vnode);
42 }
43 });
44 };
45 Object.keys(originalSlots).forEach(slotName => {
46 if (typeof originalSlots[slotName] !== 'function') return;
47 const els = originalSlots[slotName]();
48 getSlidesFromElements(els, slotName);
49 });
50 oldSlidesRef.value = slidesRef.value;
51 slidesRef.value = slides;
52 return {
53 slides,
54 slots
55 };
56}
57
58function renderVirtual(swiperRef, slides, virtualData) {
59 if (!virtualData) return null;
60 const getSlideIndex = index => {
61 let slideIndex = index;
62 if (index < 0) {
63 slideIndex = slides.length + index;
64 } else if (slideIndex >= slides.length) {
65 // eslint-disable-next-line
66 slideIndex = slideIndex - slides.length;
67 }
68 return slideIndex;
69 };
70 const style = swiperRef.value.isHorizontal() ? {
71 [swiperRef.value.rtlTranslate ? 'right' : 'left']: `${virtualData.offset}px`
72 } : {
73 top: `${virtualData.offset}px`
74 };
75 const {
76 from,
77 to
78 } = virtualData;
79 const loopFrom = swiperRef.value.params.loop ? -slides.length : 0;
80 const loopTo = swiperRef.value.params.loop ? slides.length * 2 : slides.length;
81 const slidesToRender = [];
82 for (let i = loopFrom; i < loopTo; i += 1) {
83 if (i >= from && i <= to) {
84 slidesToRender.push(slides[getSlideIndex(i)]);
85 }
86 }
87 return slidesToRender.map(slide => {
88 if (!slide.props) slide.props = {};
89 if (!slide.props.style) slide.props.style = {};
90 slide.props.swiperRef = swiperRef;
91 slide.props.style = style;
92 return h(slide.type, {
93 ...slide.props
94 }, slide.children);
95 });
96}
97
98const Swiper = {
99 name: 'Swiper',
100 props: {
101 tag: {
102 type: String,
103 default: 'div'
104 },
105 wrapperTag: {
106 type: String,
107 default: 'div'
108 },
109 modules: {
110 type: Array,
111 default: undefined
112 },
113 init: {
114 type: Boolean,
115 default: undefined
116 },
117 direction: {
118 type: String,
119 default: undefined
120 },
121 oneWayMovement: {
122 type: Boolean,
123 default: undefined
124 },
125 touchEventsTarget: {
126 type: String,
127 default: undefined
128 },
129 initialSlide: {
130 type: Number,
131 default: undefined
132 },
133 speed: {
134 type: Number,
135 default: undefined
136 },
137 cssMode: {
138 type: Boolean,
139 default: undefined
140 },
141 updateOnWindowResize: {
142 type: Boolean,
143 default: undefined
144 },
145 resizeObserver: {
146 type: Boolean,
147 default: undefined
148 },
149 nested: {
150 type: Boolean,
151 default: undefined
152 },
153 focusableElements: {
154 type: String,
155 default: undefined
156 },
157 width: {
158 type: Number,
159 default: undefined
160 },
161 height: {
162 type: Number,
163 default: undefined
164 },
165 preventInteractionOnTransition: {
166 type: Boolean,
167 default: undefined
168 },
169 userAgent: {
170 type: String,
171 default: undefined
172 },
173 url: {
174 type: String,
175 default: undefined
176 },
177 edgeSwipeDetection: {
178 type: [Boolean, String],
179 default: undefined
180 },
181 edgeSwipeThreshold: {
182 type: Number,
183 default: undefined
184 },
185 autoHeight: {
186 type: Boolean,
187 default: undefined
188 },
189 setWrapperSize: {
190 type: Boolean,
191 default: undefined
192 },
193 virtualTranslate: {
194 type: Boolean,
195 default: undefined
196 },
197 effect: {
198 type: String,
199 default: undefined
200 },
201 breakpoints: {
202 type: Object,
203 default: undefined
204 },
205 spaceBetween: {
206 type: [Number, String],
207 default: undefined
208 },
209 slidesPerView: {
210 type: [Number, String],
211 default: undefined
212 },
213 maxBackfaceHiddenSlides: {
214 type: Number,
215 default: undefined
216 },
217 slidesPerGroup: {
218 type: Number,
219 default: undefined
220 },
221 slidesPerGroupSkip: {
222 type: Number,
223 default: undefined
224 },
225 slidesPerGroupAuto: {
226 type: Boolean,
227 default: undefined
228 },
229 centeredSlides: {
230 type: Boolean,
231 default: undefined
232 },
233 centeredSlidesBounds: {
234 type: Boolean,
235 default: undefined
236 },
237 slidesOffsetBefore: {
238 type: Number,
239 default: undefined
240 },
241 slidesOffsetAfter: {
242 type: Number,
243 default: undefined
244 },
245 normalizeSlideIndex: {
246 type: Boolean,
247 default: undefined
248 },
249 centerInsufficientSlides: {
250 type: Boolean,
251 default: undefined
252 },
253 watchOverflow: {
254 type: Boolean,
255 default: undefined
256 },
257 roundLengths: {
258 type: Boolean,
259 default: undefined
260 },
261 touchRatio: {
262 type: Number,
263 default: undefined
264 },
265 touchAngle: {
266 type: Number,
267 default: undefined
268 },
269 simulateTouch: {
270 type: Boolean,
271 default: undefined
272 },
273 shortSwipes: {
274 type: Boolean,
275 default: undefined
276 },
277 longSwipes: {
278 type: Boolean,
279 default: undefined
280 },
281 longSwipesRatio: {
282 type: Number,
283 default: undefined
284 },
285 longSwipesMs: {
286 type: Number,
287 default: undefined
288 },
289 followFinger: {
290 type: Boolean,
291 default: undefined
292 },
293 allowTouchMove: {
294 type: Boolean,
295 default: undefined
296 },
297 threshold: {
298 type: Number,
299 default: undefined
300 },
301 touchMoveStopPropagation: {
302 type: Boolean,
303 default: undefined
304 },
305 touchStartPreventDefault: {
306 type: Boolean,
307 default: undefined
308 },
309 touchStartForcePreventDefault: {
310 type: Boolean,
311 default: undefined
312 },
313 touchReleaseOnEdges: {
314 type: Boolean,
315 default: undefined
316 },
317 uniqueNavElements: {
318 type: Boolean,
319 default: undefined
320 },
321 resistance: {
322 type: Boolean,
323 default: undefined
324 },
325 resistanceRatio: {
326 type: Number,
327 default: undefined
328 },
329 watchSlidesProgress: {
330 type: Boolean,
331 default: undefined
332 },
333 grabCursor: {
334 type: Boolean,
335 default: undefined
336 },
337 preventClicks: {
338 type: Boolean,
339 default: undefined
340 },
341 preventClicksPropagation: {
342 type: Boolean,
343 default: undefined
344 },
345 slideToClickedSlide: {
346 type: Boolean,
347 default: undefined
348 },
349 loop: {
350 type: Boolean,
351 default: undefined
352 },
353 loopedSlides: {
354 type: Number,
355 default: undefined
356 },
357 loopPreventsSliding: {
358 type: Boolean,
359 default: undefined
360 },
361 rewind: {
362 type: Boolean,
363 default: undefined
364 },
365 allowSlidePrev: {
366 type: Boolean,
367 default: undefined
368 },
369 allowSlideNext: {
370 type: Boolean,
371 default: undefined
372 },
373 swipeHandler: {
374 type: Boolean,
375 default: undefined
376 },
377 noSwiping: {
378 type: Boolean,
379 default: undefined
380 },
381 noSwipingClass: {
382 type: String,
383 default: undefined
384 },
385 noSwipingSelector: {
386 type: String,
387 default: undefined
388 },
389 passiveListeners: {
390 type: Boolean,
391 default: undefined
392 },
393 containerModifierClass: {
394 type: String,
395 default: undefined
396 },
397 slideClass: {
398 type: String,
399 default: undefined
400 },
401 slideActiveClass: {
402 type: String,
403 default: undefined
404 },
405 slideVisibleClass: {
406 type: String,
407 default: undefined
408 },
409 slideNextClass: {
410 type: String,
411 default: undefined
412 },
413 slidePrevClass: {
414 type: String,
415 default: undefined
416 },
417 wrapperClass: {
418 type: String,
419 default: undefined
420 },
421 lazyPreloaderClass: {
422 type: String,
423 default: undefined
424 },
425 lazyPreloadPrevNext: {
426 type: Number,
427 default: undefined
428 },
429 runCallbacksOnInit: {
430 type: Boolean,
431 default: undefined
432 },
433 observer: {
434 type: Boolean,
435 default: undefined
436 },
437 observeParents: {
438 type: Boolean,
439 default: undefined
440 },
441 observeSlideChildren: {
442 type: Boolean,
443 default: undefined
444 },
445 a11y: {
446 type: [Boolean, Object],
447 default: undefined
448 },
449 autoplay: {
450 type: [Boolean, Object],
451 default: undefined
452 },
453 controller: {
454 type: Object,
455 default: undefined
456 },
457 coverflowEffect: {
458 type: Object,
459 default: undefined
460 },
461 cubeEffect: {
462 type: Object,
463 default: undefined
464 },
465 fadeEffect: {
466 type: Object,
467 default: undefined
468 },
469 flipEffect: {
470 type: Object,
471 default: undefined
472 },
473 creativeEffect: {
474 type: Object,
475 default: undefined
476 },
477 cardsEffect: {
478 type: Object,
479 default: undefined
480 },
481 hashNavigation: {
482 type: [Boolean, Object],
483 default: undefined
484 },
485 history: {
486 type: [Boolean, Object],
487 default: undefined
488 },
489 keyboard: {
490 type: [Boolean, Object],
491 default: undefined
492 },
493 mousewheel: {
494 type: [Boolean, Object],
495 default: undefined
496 },
497 navigation: {
498 type: [Boolean, Object],
499 default: undefined
500 },
501 pagination: {
502 type: [Boolean, Object],
503 default: undefined
504 },
505 parallax: {
506 type: [Boolean, Object],
507 default: undefined
508 },
509 scrollbar: {
510 type: [Boolean, Object],
511 default: undefined
512 },
513 thumbs: {
514 type: Object,
515 default: undefined
516 },
517 virtual: {
518 type: [Boolean, Object],
519 default: undefined
520 },
521 zoom: {
522 type: [Boolean, Object],
523 default: undefined
524 },
525 grid: {
526 type: [Object],
527 default: undefined
528 },
529 freeMode: {
530 type: [Boolean, Object],
531 default: undefined
532 },
533 enabled: {
534 type: Boolean,
535 default: undefined
536 }
537 },
538 emits: ['_beforeBreakpoint', '_containerClasses', '_slideClass', '_slideClasses', '_swiper', '_freeModeNoMomentumRelease', 'activeIndexChange', 'afterInit', 'autoplay', 'autoplayStart', 'autoplayStop', 'autoplayPause', 'autoplayResume', 'autoplayTimeLeft', 'beforeDestroy', 'beforeInit', 'beforeLoopFix', 'beforeResize', 'beforeSlideChangeStart', 'beforeTransitionStart', 'breakpoint', 'changeDirection', 'click', 'disable', 'doubleTap', 'doubleClick', 'destroy', 'enable', 'fromEdge', 'hashChange', 'hashSet', 'init', 'keyPress', 'lock', 'loopFix', 'momentumBounce', 'navigationHide', 'navigationShow', 'navigationPrev', 'navigationNext', 'observerUpdate', 'orientationchange', 'paginationHide', 'paginationRender', 'paginationShow', 'paginationUpdate', 'progress', 'reachBeginning', 'reachEnd', 'realIndexChange', 'resize', 'scroll', 'scrollbarDragEnd', 'scrollbarDragMove', 'scrollbarDragStart', 'setTransition', 'setTranslate', 'slideChange', 'slideChangeTransitionEnd', 'slideChangeTransitionStart', 'slideNextTransitionEnd', 'slideNextTransitionStart', 'slidePrevTransitionEnd', 'slidePrevTransitionStart', 'slideResetTransitionStart', 'slideResetTransitionEnd', 'sliderMove', 'sliderFirstMove', 'slidesLengthChange', 'slidesGridLengthChange', 'snapGridLengthChange', 'snapIndexChange', 'swiper', 'tap', 'toEdge', 'touchEnd', 'touchMove', 'touchMoveOpposite', 'touchStart', 'transitionEnd', 'transitionStart', 'unlock', 'update', 'virtualUpdate', 'zoomChange'],
539 setup(props, _ref) {
540 let {
541 slots: originalSlots,
542 emit
543 } = _ref;
544 const {
545 tag: Tag,
546 wrapperTag: WrapperTag
547 } = props;
548 const containerClasses = ref('swiper');
549 const virtualData = ref(null);
550 const breakpointChanged = ref(false);
551 const initializedRef = ref(false);
552 const swiperElRef = ref(null);
553 const swiperRef = ref(null);
554 const oldPassedParamsRef = ref(null);
555 const slidesRef = {
556 value: []
557 };
558 const oldSlidesRef = {
559 value: []
560 };
561 const nextElRef = ref(null);
562 const prevElRef = ref(null);
563 const paginationElRef = ref(null);
564 const scrollbarElRef = ref(null);
565 const {
566 params: swiperParams,
567 passedParams
568 } = getParams(props, false);
569 getChildren(originalSlots, slidesRef, oldSlidesRef);
570 oldPassedParamsRef.value = passedParams;
571 oldSlidesRef.value = slidesRef.value;
572 const onBeforeBreakpoint = () => {
573 getChildren(originalSlots, slidesRef, oldSlidesRef);
574 breakpointChanged.value = true;
575 };
576 swiperParams.onAny = function (event) {
577 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
578 args[_key - 1] = arguments[_key];
579 }
580 emit(event, ...args);
581 };
582 Object.assign(swiperParams.on, {
583 _beforeBreakpoint: onBeforeBreakpoint,
584 _containerClasses(swiper, classes) {
585 containerClasses.value = classes;
586 }
587 });
588
589 // init Swiper
590 const passParams = {
591 ...swiperParams
592 };
593 delete passParams.wrapperClass;
594 swiperRef.value = new Swiper$1(passParams);
595 if (swiperRef.value.virtual && swiperRef.value.params.virtual.enabled) {
596 swiperRef.value.virtual.slides = slidesRef.value;
597 const extendWith = {
598 cache: false,
599 slides: slidesRef.value,
600 renderExternal: data => {
601 virtualData.value = data;
602 },
603 renderExternalUpdate: false
604 };
605 extend(swiperRef.value.params.virtual, extendWith);
606 extend(swiperRef.value.originalParams.virtual, extendWith);
607 }
608 onUpdated(() => {
609 // set initialized flag
610 if (!initializedRef.value && swiperRef.value) {
611 swiperRef.value.emitSlidesClasses();
612 initializedRef.value = true;
613 }
614 // watch for params change
615 const {
616 passedParams: newPassedParams
617 } = getParams(props, false);
618 const changedParams = getChangedParams(newPassedParams, oldPassedParamsRef.value, slidesRef.value, oldSlidesRef.value, c => c.props && c.props.key);
619 oldPassedParamsRef.value = newPassedParams;
620 if ((changedParams.length || breakpointChanged.value) && swiperRef.value && !swiperRef.value.destroyed) {
621 updateSwiper({
622 swiper: swiperRef.value,
623 slides: slidesRef.value,
624 passedParams: newPassedParams,
625 changedParams,
626 nextEl: nextElRef.value,
627 prevEl: prevElRef.value,
628 scrollbarEl: scrollbarElRef.value,
629 paginationEl: paginationElRef.value
630 });
631 }
632 breakpointChanged.value = false;
633 });
634 provide('swiper', swiperRef);
635
636 // update on virtual update
637 watch(virtualData, () => {
638 nextTick(() => {
639 updateOnVirtualData(swiperRef.value);
640 });
641 });
642
643 // mount swiper
644 onMounted(() => {
645 if (!swiperElRef.value) return;
646 mountSwiper({
647 el: swiperElRef.value,
648 nextEl: nextElRef.value,
649 prevEl: prevElRef.value,
650 paginationEl: paginationElRef.value,
651 scrollbarEl: scrollbarElRef.value,
652 swiper: swiperRef.value
653 }, swiperParams);
654 emit('swiper', swiperRef.value);
655 });
656 onBeforeUnmount(() => {
657 if (swiperRef.value && !swiperRef.value.destroyed) {
658 swiperRef.value.destroy(true, false);
659 }
660 });
661
662 // bypass swiper instance to slides
663 function renderSlides(slides) {
664 if (swiperParams.virtual) {
665 return renderVirtual(swiperRef, slides, virtualData.value);
666 }
667 slides.forEach((slide, index) => {
668 if (!slide.props) slide.props = {};
669 slide.props.swiperRef = swiperRef;
670 slide.props.swiperSlideIndex = index;
671 });
672 return slides;
673 }
674 return () => {
675 const {
676 slides,
677 slots
678 } = getChildren(originalSlots, slidesRef, oldSlidesRef);
679 return h(Tag, {
680 ref: swiperElRef,
681 class: uniqueClasses(containerClasses.value)
682 }, [slots['container-start'], h(WrapperTag, {
683 class: wrapperClass(swiperParams.wrapperClass)
684 }, [slots['wrapper-start'], renderSlides(slides), slots['wrapper-end']]), needsNavigation(props) && [h('div', {
685 ref: prevElRef,
686 class: 'swiper-button-prev'
687 }), h('div', {
688 ref: nextElRef,
689 class: 'swiper-button-next'
690 })], needsScrollbar(props) && h('div', {
691 ref: scrollbarElRef,
692 class: 'swiper-scrollbar'
693 }), needsPagination(props) && h('div', {
694 ref: paginationElRef,
695 class: 'swiper-pagination'
696 }), slots['container-end']]);
697 };
698 }
699};
700
701const SwiperSlide = {
702 name: 'SwiperSlide',
703 props: {
704 tag: {
705 type: String,
706 default: 'div'
707 },
708 swiperRef: {
709 type: Object,
710 required: false
711 },
712 swiperSlideIndex: {
713 type: Number,
714 default: undefined,
715 required: false
716 },
717 zoom: {
718 type: Boolean,
719 default: undefined,
720 required: false
721 },
722 lazy: {
723 type: Boolean,
724 default: false,
725 required: false
726 },
727 virtualIndex: {
728 type: [String, Number],
729 default: undefined
730 }
731 },
732 setup(props, _ref) {
733 let {
734 slots
735 } = _ref;
736 let eventAttached = false;
737 const {
738 swiperRef
739 } = props;
740 const slideElRef = ref(null);
741 const slideClasses = ref('swiper-slide');
742 const lazyLoaded = ref(false);
743 function updateClasses(swiper, el, classNames) {
744 if (el === slideElRef.value) {
745 slideClasses.value = classNames;
746 }
747 }
748 onMounted(() => {
749 if (!swiperRef || !swiperRef.value) return;
750 swiperRef.value.on('_slideClass', updateClasses);
751 eventAttached = true;
752 });
753 onBeforeUpdate(() => {
754 if (eventAttached || !swiperRef || !swiperRef.value) return;
755 swiperRef.value.on('_slideClass', updateClasses);
756 eventAttached = true;
757 });
758 onUpdated(() => {
759 if (!slideElRef.value || !swiperRef || !swiperRef.value) return;
760 if (typeof props.swiperSlideIndex !== 'undefined') {
761 slideElRef.value.swiperSlideIndex = props.swiperSlideIndex;
762 }
763 if (swiperRef.value.destroyed) {
764 if (slideClasses.value !== 'swiper-slide') {
765 slideClasses.value = 'swiper-slide';
766 }
767 }
768 });
769 onBeforeUnmount(() => {
770 if (!swiperRef || !swiperRef.value) return;
771 swiperRef.value.off('_slideClass', updateClasses);
772 });
773 const slideData = computed(() => ({
774 isActive: slideClasses.value.indexOf('swiper-slide-active') >= 0,
775 isVisible: slideClasses.value.indexOf('swiper-slide-visible') >= 0,
776 isPrev: slideClasses.value.indexOf('swiper-slide-prev') >= 0,
777 isNext: slideClasses.value.indexOf('swiper-slide-next') >= 0
778 }));
779 provide('swiperSlide', slideData);
780 const onLoad = () => {
781 lazyLoaded.value = true;
782 };
783 return () => {
784 return h(props.tag, {
785 class: uniqueClasses(`${slideClasses.value}`),
786 ref: slideElRef,
787 'data-swiper-slide-index': typeof props.virtualIndex === 'undefined' && swiperRef && swiperRef.value && swiperRef.value.params.loop ? props.swiperSlideIndex : props.virtualIndex,
788 onLoadCapture: onLoad
789 }, props.zoom ? h('div', {
790 class: 'swiper-zoom-container',
791 'data-swiper-zoom': typeof props.zoom === 'number' ? props.zoom : undefined
792 }, [slots.default && slots.default(slideData.value), props.lazy && !lazyLoaded.value && h('div', {
793 class: 'swiper-lazy-preloader'
794 })]) : [slots.default && slots.default(slideData.value), props.lazy && !lazyLoaded.value && h('div', {
795 class: 'swiper-lazy-preloader'
796 })]);
797 };
798 }
799};
800
801const useSwiperSlide = () => {
802 return inject('swiperSlide');
803};
804const useSwiper = () => {
805 return inject('swiper');
806};
807
808export { Swiper, SwiperSlide, useSwiper, useSwiperSlide };