
package.swiper-react.mjs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swiper Show documentation
Show all versions of swiper Show documentation
Most modern mobile touch slider and framework with hardware accelerated transitions
/**
* Swiper React 11.1.14
* Most modern mobile touch slider and framework with hardware accelerated transitions
* https://swiperjs.com
*
* Copyright 2014-2024 Vladimir Kharlampidi
*
* Released under the MIT License
*
* Released on: September 12, 2024
*/
import React, { useEffect, useLayoutEffect, useContext, createContext, forwardRef, useState, useRef } from 'react';
import { S as Swiper$1 } from './shared/swiper-core.mjs';
import { g as getParams, m as mountSwiper, a as getChangedParams, u as updateOnVirtualData } from './shared/update-on-virtual-data.mjs';
import { d as uniqueClasses, w as wrapperClass, n as needsNavigation, b as needsScrollbar, a as needsPagination, e as extend, u as updateSwiper } from './shared/update-swiper.mjs';
function _extends() {
_extends = Object.assign ? Object.assign.bind() : function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function isChildSwiperSlide(child) {
return child.type && child.type.displayName && child.type.displayName.includes('SwiperSlide');
}
function processChildren(c) {
const slides = [];
React.Children.toArray(c).forEach(child => {
if (isChildSwiperSlide(child)) {
slides.push(child);
} else if (child.props && child.props.children) {
processChildren(child.props.children).forEach(slide => slides.push(slide));
}
});
return slides;
}
function getChildren(c) {
const slides = [];
const slots = {
'container-start': [],
'container-end': [],
'wrapper-start': [],
'wrapper-end': []
};
React.Children.toArray(c).forEach(child => {
if (isChildSwiperSlide(child)) {
slides.push(child);
} else if (child.props && child.props.slot && slots[child.props.slot]) {
slots[child.props.slot].push(child);
} else if (child.props && child.props.children) {
const foundSlides = processChildren(child.props.children);
if (foundSlides.length > 0) {
foundSlides.forEach(slide => slides.push(slide));
} else {
slots['container-end'].push(child);
}
} else {
slots['container-end'].push(child);
}
});
return {
slides,
slots
};
}
function renderVirtual(swiper, slides, virtualData) {
if (!virtualData) return null;
const getSlideIndex = index => {
let slideIndex = index;
if (index < 0) {
slideIndex = slides.length + index;
} else if (slideIndex >= slides.length) {
// eslint-disable-next-line
slideIndex = slideIndex - slides.length;
}
return slideIndex;
};
const style = swiper.isHorizontal() ? {
[swiper.rtlTranslate ? 'right' : 'left']: `${virtualData.offset}px`
} : {
top: `${virtualData.offset}px`
};
const {
from,
to
} = virtualData;
const loopFrom = swiper.params.loop ? -slides.length : 0;
const loopTo = swiper.params.loop ? slides.length * 2 : slides.length;
const slidesToRender = [];
for (let i = loopFrom; i < loopTo; i += 1) {
if (i >= from && i <= to) {
slidesToRender.push(slides[getSlideIndex(i)]);
}
}
return slidesToRender.map((child, index) => {
return /*#__PURE__*/React.cloneElement(child, {
swiper,
style,
key: child.props.virtualIndex || child.key || `slide-${index}`
});
});
}
function useIsomorphicLayoutEffect(callback, deps) {
// eslint-disable-next-line
if (typeof window === 'undefined') return useEffect(callback, deps);
return useLayoutEffect(callback, deps);
}
const SwiperSlideContext = /*#__PURE__*/createContext(null);
const useSwiperSlide = () => {
return useContext(SwiperSlideContext);
};
const SwiperContext = /*#__PURE__*/createContext(null);
const useSwiper = () => {
return useContext(SwiperContext);
};
const Swiper = /*#__PURE__*/forwardRef(function (_temp, externalElRef) {
let {
className,
tag: Tag = 'div',
wrapperTag: WrapperTag = 'div',
children,
onSwiper,
...rest
} = _temp === void 0 ? {} : _temp;
let eventsAssigned = false;
const [containerClasses, setContainerClasses] = useState('swiper');
const [virtualData, setVirtualData] = useState(null);
const [breakpointChanged, setBreakpointChanged] = useState(false);
const initializedRef = useRef(false);
const swiperElRef = useRef(null);
const swiperRef = useRef(null);
const oldPassedParamsRef = useRef(null);
const oldSlides = useRef(null);
const nextElRef = useRef(null);
const prevElRef = useRef(null);
const paginationElRef = useRef(null);
const scrollbarElRef = useRef(null);
const {
params: swiperParams,
passedParams,
rest: restProps,
events
} = getParams(rest);
const {
slides,
slots
} = getChildren(children);
const onBeforeBreakpoint = () => {
setBreakpointChanged(!breakpointChanged);
};
Object.assign(swiperParams.on, {
_containerClasses(swiper, classes) {
setContainerClasses(classes);
}
});
const initSwiper = () => {
// init swiper
Object.assign(swiperParams.on, events);
eventsAssigned = true;
const passParams = {
...swiperParams
};
delete passParams.wrapperClass;
swiperRef.current = new Swiper$1(passParams);
if (swiperRef.current.virtual && swiperRef.current.params.virtual.enabled) {
swiperRef.current.virtual.slides = slides;
const extendWith = {
cache: false,
slides,
renderExternal: setVirtualData,
renderExternalUpdate: false
};
extend(swiperRef.current.params.virtual, extendWith);
extend(swiperRef.current.originalParams.virtual, extendWith);
}
};
if (!swiperElRef.current) {
initSwiper();
}
// Listen for breakpoints change
if (swiperRef.current) {
swiperRef.current.on('_beforeBreakpoint', onBeforeBreakpoint);
}
const attachEvents = () => {
if (eventsAssigned || !events || !swiperRef.current) return;
Object.keys(events).forEach(eventName => {
swiperRef.current.on(eventName, events[eventName]);
});
};
const detachEvents = () => {
if (!events || !swiperRef.current) return;
Object.keys(events).forEach(eventName => {
swiperRef.current.off(eventName, events[eventName]);
});
};
useEffect(() => {
return () => {
if (swiperRef.current) swiperRef.current.off('_beforeBreakpoint', onBeforeBreakpoint);
};
});
// set initialized flag
useEffect(() => {
if (!initializedRef.current && swiperRef.current) {
swiperRef.current.emitSlidesClasses();
initializedRef.current = true;
}
});
// mount swiper
useIsomorphicLayoutEffect(() => {
if (externalElRef) {
externalElRef.current = swiperElRef.current;
}
if (!swiperElRef.current) return;
if (swiperRef.current.destroyed) {
initSwiper();
}
mountSwiper({
el: swiperElRef.current,
nextEl: nextElRef.current,
prevEl: prevElRef.current,
paginationEl: paginationElRef.current,
scrollbarEl: scrollbarElRef.current,
swiper: swiperRef.current
}, swiperParams);
if (onSwiper && !swiperRef.current.destroyed) onSwiper(swiperRef.current);
// eslint-disable-next-line
return () => {
if (swiperRef.current && !swiperRef.current.destroyed) {
swiperRef.current.destroy(true, false);
}
};
}, []);
// watch for params change
useIsomorphicLayoutEffect(() => {
attachEvents();
const changedParams = getChangedParams(passedParams, oldPassedParamsRef.current, slides, oldSlides.current, c => c.key);
oldPassedParamsRef.current = passedParams;
oldSlides.current = slides;
if (changedParams.length && swiperRef.current && !swiperRef.current.destroyed) {
updateSwiper({
swiper: swiperRef.current,
slides,
passedParams,
changedParams,
nextEl: nextElRef.current,
prevEl: prevElRef.current,
scrollbarEl: scrollbarElRef.current,
paginationEl: paginationElRef.current
});
}
return () => {
detachEvents();
};
});
// update on virtual update
useIsomorphicLayoutEffect(() => {
updateOnVirtualData(swiperRef.current);
}, [virtualData]);
// bypass swiper instance to slides
function renderSlides() {
if (swiperParams.virtual) {
return renderVirtual(swiperRef.current, slides, virtualData);
}
return slides.map((child, index) => {
return /*#__PURE__*/React.cloneElement(child, {
swiper: swiperRef.current,
swiperSlideIndex: index
});
});
}
return /*#__PURE__*/React.createElement(Tag, _extends({
ref: swiperElRef,
className: uniqueClasses(`${containerClasses}${className ? ` ${className}` : ''}`)
}, restProps), /*#__PURE__*/React.createElement(SwiperContext.Provider, {
value: swiperRef.current
}, slots['container-start'], /*#__PURE__*/React.createElement(WrapperTag, {
className: wrapperClass(swiperParams.wrapperClass)
}, slots['wrapper-start'], renderSlides(), slots['wrapper-end']), needsNavigation(swiperParams) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
ref: prevElRef,
className: "swiper-button-prev"
}), /*#__PURE__*/React.createElement("div", {
ref: nextElRef,
className: "swiper-button-next"
})), needsScrollbar(swiperParams) && /*#__PURE__*/React.createElement("div", {
ref: scrollbarElRef,
className: "swiper-scrollbar"
}), needsPagination(swiperParams) && /*#__PURE__*/React.createElement("div", {
ref: paginationElRef,
className: "swiper-pagination"
}), slots['container-end']));
});
Swiper.displayName = 'Swiper';
const SwiperSlide = /*#__PURE__*/forwardRef(function (_temp, externalRef) {
let {
tag: Tag = 'div',
children,
className = '',
swiper,
zoom,
lazy,
virtualIndex,
swiperSlideIndex,
...rest
} = _temp === void 0 ? {} : _temp;
const slideElRef = useRef(null);
const [slideClasses, setSlideClasses] = useState('swiper-slide');
const [lazyLoaded, setLazyLoaded] = useState(false);
function updateClasses(_s, el, classNames) {
if (el === slideElRef.current) {
setSlideClasses(classNames);
}
}
useIsomorphicLayoutEffect(() => {
if (typeof swiperSlideIndex !== 'undefined') {
slideElRef.current.swiperSlideIndex = swiperSlideIndex;
}
if (externalRef) {
externalRef.current = slideElRef.current;
}
if (!slideElRef.current || !swiper) {
return;
}
if (swiper.destroyed) {
if (slideClasses !== 'swiper-slide') {
setSlideClasses('swiper-slide');
}
return;
}
swiper.on('_slideClass', updateClasses);
// eslint-disable-next-line
return () => {
if (!swiper) return;
swiper.off('_slideClass', updateClasses);
};
});
useIsomorphicLayoutEffect(() => {
if (swiper && slideElRef.current && !swiper.destroyed) {
setSlideClasses(swiper.getSlideClasses(slideElRef.current));
}
}, [swiper]);
const slideData = {
isActive: slideClasses.indexOf('swiper-slide-active') >= 0,
isVisible: slideClasses.indexOf('swiper-slide-visible') >= 0,
isPrev: slideClasses.indexOf('swiper-slide-prev') >= 0,
isNext: slideClasses.indexOf('swiper-slide-next') >= 0
};
const renderChildren = () => {
return typeof children === 'function' ? children(slideData) : children;
};
const onLoad = () => {
setLazyLoaded(true);
};
return /*#__PURE__*/React.createElement(Tag, _extends({
ref: slideElRef,
className: uniqueClasses(`${slideClasses}${className ? ` ${className}` : ''}`),
"data-swiper-slide-index": virtualIndex,
onLoad: onLoad
}, rest), zoom && /*#__PURE__*/React.createElement(SwiperSlideContext.Provider, {
value: slideData
}, /*#__PURE__*/React.createElement("div", {
className: "swiper-zoom-container",
"data-swiper-zoom": typeof zoom === 'number' ? zoom : undefined
}, renderChildren(), lazy && !lazyLoaded && /*#__PURE__*/React.createElement("div", {
className: "swiper-lazy-preloader"
}))), !zoom && /*#__PURE__*/React.createElement(SwiperSlideContext.Provider, {
value: slideData
}, renderChildren(), lazy && !lazyLoaded && /*#__PURE__*/React.createElement("div", {
className: "swiper-lazy-preloader"
})));
});
SwiperSlide.displayName = 'SwiperSlide';
export { Swiper, SwiperSlide, useSwiper, useSwiperSlide };
© 2015 - 2025 Weber Informatics LLC | Privacy Policy