UNPKG

7.1 kBJavaScriptView Raw
1function _extends() { _extends = Object.assign || 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); }
2
3import React, { useRef, useState, useEffect, forwardRef } from 'react';
4import SwiperCore from 'swiper';
5import { getParams } from './get-params.js';
6import { mountSwiper } from './mount-swiper.js';
7import { needsScrollbar, needsNavigation, needsPagination, uniqueClasses, extend } from './utils.js';
8import { renderLoop, calcLoopedSlides } from './loop.js';
9import { getChangedParams } from './get-changed-params.js';
10import { getChildren } from './get-children.js';
11import { updateSwiper } from './update-swiper.js';
12import { renderVirtual, updateOnVirtualData } from './virtual.js';
13import { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect.js';
14import { SwiperContext } from './context.js';
15const Swiper = /*#__PURE__*/forwardRef(function (_temp, externalElRef) {
16 let {
17 className,
18 tag: Tag = 'div',
19 wrapperTag: WrapperTag = 'div',
20 children,
21 onSwiper,
22 ...rest
23 } = _temp === void 0 ? {} : _temp;
24 let eventsAssigned = false;
25 const [containerClasses, setContainerClasses] = useState('swiper');
26 const [virtualData, setVirtualData] = useState(null);
27 const [breakpointChanged, setBreakpointChanged] = useState(false);
28 const initializedRef = useRef(false);
29 const swiperElRef = useRef(null);
30 const swiperRef = useRef(null);
31 const oldPassedParamsRef = useRef(null);
32 const oldSlides = useRef(null);
33 const nextElRef = useRef(null);
34 const prevElRef = useRef(null);
35 const paginationElRef = useRef(null);
36 const scrollbarElRef = useRef(null);
37 const {
38 params: swiperParams,
39 passedParams,
40 rest: restProps,
41 events
42 } = getParams(rest);
43 const {
44 slides,
45 slots
46 } = getChildren(children);
47
48 const onBeforeBreakpoint = () => {
49 setBreakpointChanged(!breakpointChanged);
50 };
51
52 Object.assign(swiperParams.on, {
53 _containerClasses(swiper, classes) {
54 setContainerClasses(classes);
55 }
56
57 });
58
59 const initSwiper = () => {
60 // init swiper
61 Object.assign(swiperParams.on, events);
62 eventsAssigned = true;
63 swiperRef.current = new SwiperCore(swiperParams);
64
65 swiperRef.current.loopCreate = () => {};
66
67 swiperRef.current.loopDestroy = () => {};
68
69 if (swiperParams.loop) {
70 swiperRef.current.loopedSlides = calcLoopedSlides(slides, swiperParams);
71 }
72
73 if (swiperRef.current.virtual && swiperRef.current.params.virtual.enabled) {
74 swiperRef.current.virtual.slides = slides;
75 const extendWith = {
76 cache: false,
77 slides,
78 renderExternal: setVirtualData,
79 renderExternalUpdate: false
80 };
81 extend(swiperRef.current.params.virtual, extendWith);
82 extend(swiperRef.current.originalParams.virtual, extendWith);
83 }
84 };
85
86 if (!swiperElRef.current) {
87 initSwiper();
88 } // Listen for breakpoints change
89
90
91 if (swiperRef.current) {
92 swiperRef.current.on('_beforeBreakpoint', onBeforeBreakpoint);
93 }
94
95 const attachEvents = () => {
96 if (eventsAssigned || !events || !swiperRef.current) return;
97 Object.keys(events).forEach(eventName => {
98 swiperRef.current.on(eventName, events[eventName]);
99 });
100 };
101
102 const detachEvents = () => {
103 if (!events || !swiperRef.current) return;
104 Object.keys(events).forEach(eventName => {
105 swiperRef.current.off(eventName, events[eventName]);
106 });
107 };
108
109 useEffect(() => {
110 return () => {
111 if (swiperRef.current) swiperRef.current.off('_beforeBreakpoint', onBeforeBreakpoint);
112 };
113 }); // set initialized flag
114
115 useEffect(() => {
116 if (!initializedRef.current && swiperRef.current) {
117 swiperRef.current.emitSlidesClasses();
118 initializedRef.current = true;
119 }
120 }); // mount swiper
121
122 useIsomorphicLayoutEffect(() => {
123 if (externalElRef) {
124 externalElRef.current = swiperElRef.current;
125 }
126
127 if (!swiperElRef.current) return;
128
129 if (swiperRef.current.destroyed) {
130 initSwiper();
131 }
132
133 mountSwiper({
134 el: swiperElRef.current,
135 nextEl: nextElRef.current,
136 prevEl: prevElRef.current,
137 paginationEl: paginationElRef.current,
138 scrollbarEl: scrollbarElRef.current,
139 swiper: swiperRef.current
140 }, swiperParams);
141 if (onSwiper) onSwiper(swiperRef.current); // eslint-disable-next-line
142
143 return () => {
144 if (swiperRef.current && !swiperRef.current.destroyed) {
145 swiperRef.current.destroy(true, false);
146 }
147 };
148 }, []); // watch for params change
149
150 useIsomorphicLayoutEffect(() => {
151 attachEvents();
152 const changedParams = getChangedParams(passedParams, oldPassedParamsRef.current, slides, oldSlides.current);
153 oldPassedParamsRef.current = passedParams;
154 oldSlides.current = slides;
155
156 if (changedParams.length && swiperRef.current && !swiperRef.current.destroyed) {
157 updateSwiper({
158 swiper: swiperRef.current,
159 slides,
160 passedParams,
161 changedParams,
162 nextEl: nextElRef.current,
163 prevEl: prevElRef.current,
164 scrollbarEl: scrollbarElRef.current,
165 paginationEl: paginationElRef.current
166 });
167 }
168
169 return () => {
170 detachEvents();
171 };
172 }); // update on virtual update
173
174 useIsomorphicLayoutEffect(() => {
175 updateOnVirtualData(swiperRef.current);
176 }, [virtualData]); // bypass swiper instance to slides
177
178 function renderSlides() {
179 if (swiperParams.virtual) {
180 return renderVirtual(swiperRef.current, slides, virtualData);
181 }
182
183 if (!swiperParams.loop || swiperRef.current && swiperRef.current.destroyed) {
184 return slides.map(child => {
185 return /*#__PURE__*/React.cloneElement(child, {
186 swiper: swiperRef.current
187 });
188 });
189 }
190
191 return renderLoop(swiperRef.current, slides, swiperParams);
192 }
193
194 return /*#__PURE__*/React.createElement(Tag, _extends({
195 ref: swiperElRef,
196 className: uniqueClasses(`${containerClasses}${className ? ` ${className}` : ''}`)
197 }, restProps), /*#__PURE__*/React.createElement(SwiperContext.Provider, {
198 value: swiperRef.current
199 }, slots['container-start'], /*#__PURE__*/React.createElement(WrapperTag, {
200 className: "swiper-wrapper"
201 }, slots['wrapper-start'], renderSlides(), slots['wrapper-end']), needsNavigation(swiperParams) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
202 ref: prevElRef,
203 className: "swiper-button-prev"
204 }), /*#__PURE__*/React.createElement("div", {
205 ref: nextElRef,
206 className: "swiper-button-next"
207 })), needsScrollbar(swiperParams) && /*#__PURE__*/React.createElement("div", {
208 ref: scrollbarElRef,
209 className: "swiper-scrollbar"
210 }), needsPagination(swiperParams) && /*#__PURE__*/React.createElement("div", {
211 ref: paginationElRef,
212 className: "swiper-pagination"
213 }), slots['container-end']));
214});
215Swiper.displayName = 'Swiper';
216export { Swiper };
\No newline at end of file