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