UNPKG

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