1 | import $ from '../../shared/dom.js';
|
2 | import classesToSelector from '../../shared/classes-to-selector.js';
|
3 | import createElementIfNotDefined from '../../shared/create-element-if-not-defined.js';
|
4 | export default function Pagination(_ref) {
|
5 | let {
|
6 | swiper,
|
7 | extendParams,
|
8 | on,
|
9 | emit
|
10 | } = _ref;
|
11 | const pfx = 'swiper-pagination';
|
12 | extendParams({
|
13 | pagination: {
|
14 | el: null,
|
15 | bulletElement: 'span',
|
16 | clickable: false,
|
17 | hideOnClick: false,
|
18 | renderBullet: null,
|
19 | renderProgressbar: null,
|
20 | renderFraction: null,
|
21 | renderCustom: null,
|
22 | progressbarOpposite: false,
|
23 | type: 'bullets',
|
24 |
|
25 | dynamicBullets: false,
|
26 | dynamicMainBullets: 1,
|
27 | formatFractionCurrent: number => number,
|
28 | formatFractionTotal: number => number,
|
29 | bulletClass: `${pfx}-bullet`,
|
30 | bulletActiveClass: `${pfx}-bullet-active`,
|
31 | modifierClass: `${pfx}-`,
|
32 | currentClass: `${pfx}-current`,
|
33 | totalClass: `${pfx}-total`,
|
34 | hiddenClass: `${pfx}-hidden`,
|
35 | progressbarFillClass: `${pfx}-progressbar-fill`,
|
36 | progressbarOppositeClass: `${pfx}-progressbar-opposite`,
|
37 | clickableClass: `${pfx}-clickable`,
|
38 | lockClass: `${pfx}-lock`,
|
39 | horizontalClass: `${pfx}-horizontal`,
|
40 | verticalClass: `${pfx}-vertical`
|
41 | }
|
42 | });
|
43 | swiper.pagination = {
|
44 | el: null,
|
45 | $el: null,
|
46 | bullets: []
|
47 | };
|
48 | let bulletSize;
|
49 | let dynamicBulletIndex = 0;
|
50 |
|
51 | function isPaginationDisabled() {
|
52 | return !swiper.params.pagination.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0;
|
53 | }
|
54 |
|
55 | function setSideBullets($bulletEl, position) {
|
56 | const {
|
57 | bulletActiveClass
|
58 | } = swiper.params.pagination;
|
59 | $bulletEl[position]().addClass(`${bulletActiveClass}-${position}`)[position]().addClass(`${bulletActiveClass}-${position}-${position}`);
|
60 | }
|
61 |
|
62 | function update() {
|
63 |
|
64 | const rtl = swiper.rtl;
|
65 | const params = swiper.params.pagination;
|
66 | if (isPaginationDisabled()) return;
|
67 | const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
|
68 | const $el = swiper.pagination.$el;
|
69 |
|
70 | let current;
|
71 | const total = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
|
72 |
|
73 | if (swiper.params.loop) {
|
74 | current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup);
|
75 |
|
76 | if (current > slidesLength - 1 - swiper.loopedSlides * 2) {
|
77 | current -= slidesLength - swiper.loopedSlides * 2;
|
78 | }
|
79 |
|
80 | if (current > total - 1) current -= total;
|
81 | if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current;
|
82 | } else if (typeof swiper.snapIndex !== 'undefined') {
|
83 | current = swiper.snapIndex;
|
84 | } else {
|
85 | current = swiper.activeIndex || 0;
|
86 | }
|
87 |
|
88 |
|
89 | if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
|
90 | const bullets = swiper.pagination.bullets;
|
91 | let firstIndex;
|
92 | let lastIndex;
|
93 | let midIndex;
|
94 |
|
95 | if (params.dynamicBullets) {
|
96 | bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true);
|
97 | $el.css(swiper.isHorizontal() ? 'width' : 'height', `${bulletSize * (params.dynamicMainBullets + 4)}px`);
|
98 |
|
99 | if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {
|
100 | dynamicBulletIndex += current - (swiper.previousIndex - swiper.loopedSlides || 0);
|
101 |
|
102 | if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
|
103 | dynamicBulletIndex = params.dynamicMainBullets - 1;
|
104 | } else if (dynamicBulletIndex < 0) {
|
105 | dynamicBulletIndex = 0;
|
106 | }
|
107 | }
|
108 |
|
109 | firstIndex = Math.max(current - dynamicBulletIndex, 0);
|
110 | lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
|
111 | midIndex = (lastIndex + firstIndex) / 2;
|
112 | }
|
113 |
|
114 | bullets.removeClass(['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(suffix => `${params.bulletActiveClass}${suffix}`).join(' '));
|
115 |
|
116 | if ($el.length > 1) {
|
117 | bullets.each(bullet => {
|
118 | const $bullet = $(bullet);
|
119 | const bulletIndex = $bullet.index();
|
120 |
|
121 | if (bulletIndex === current) {
|
122 | $bullet.addClass(params.bulletActiveClass);
|
123 | }
|
124 |
|
125 | if (params.dynamicBullets) {
|
126 | if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
|
127 | $bullet.addClass(`${params.bulletActiveClass}-main`);
|
128 | }
|
129 |
|
130 | if (bulletIndex === firstIndex) {
|
131 | setSideBullets($bullet, 'prev');
|
132 | }
|
133 |
|
134 | if (bulletIndex === lastIndex) {
|
135 | setSideBullets($bullet, 'next');
|
136 | }
|
137 | }
|
138 | });
|
139 | } else {
|
140 | const $bullet = bullets.eq(current);
|
141 | const bulletIndex = $bullet.index();
|
142 | $bullet.addClass(params.bulletActiveClass);
|
143 |
|
144 | if (params.dynamicBullets) {
|
145 | const $firstDisplayedBullet = bullets.eq(firstIndex);
|
146 | const $lastDisplayedBullet = bullets.eq(lastIndex);
|
147 |
|
148 | for (let i = firstIndex; i <= lastIndex; i += 1) {
|
149 | bullets.eq(i).addClass(`${params.bulletActiveClass}-main`);
|
150 | }
|
151 |
|
152 | if (swiper.params.loop) {
|
153 | if (bulletIndex >= bullets.length) {
|
154 | for (let i = params.dynamicMainBullets; i >= 0; i -= 1) {
|
155 | bullets.eq(bullets.length - i).addClass(`${params.bulletActiveClass}-main`);
|
156 | }
|
157 |
|
158 | bullets.eq(bullets.length - params.dynamicMainBullets - 1).addClass(`${params.bulletActiveClass}-prev`);
|
159 | } else {
|
160 | setSideBullets($firstDisplayedBullet, 'prev');
|
161 | setSideBullets($lastDisplayedBullet, 'next');
|
162 | }
|
163 | } else {
|
164 | setSideBullets($firstDisplayedBullet, 'prev');
|
165 | setSideBullets($lastDisplayedBullet, 'next');
|
166 | }
|
167 | }
|
168 | }
|
169 |
|
170 | if (params.dynamicBullets) {
|
171 | const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
|
172 | const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
|
173 | const offsetProp = rtl ? 'right' : 'left';
|
174 | bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`);
|
175 | }
|
176 | }
|
177 |
|
178 | if (params.type === 'fraction') {
|
179 | $el.find(classesToSelector(params.currentClass)).text(params.formatFractionCurrent(current + 1));
|
180 | $el.find(classesToSelector(params.totalClass)).text(params.formatFractionTotal(total));
|
181 | }
|
182 |
|
183 | if (params.type === 'progressbar') {
|
184 | let progressbarDirection;
|
185 |
|
186 | if (params.progressbarOpposite) {
|
187 | progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
|
188 | } else {
|
189 | progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
|
190 | }
|
191 |
|
192 | const scale = (current + 1) / total;
|
193 | let scaleX = 1;
|
194 | let scaleY = 1;
|
195 |
|
196 | if (progressbarDirection === 'horizontal') {
|
197 | scaleX = scale;
|
198 | } else {
|
199 | scaleY = scale;
|
200 | }
|
201 |
|
202 | $el.find(classesToSelector(params.progressbarFillClass)).transform(`translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`).transition(swiper.params.speed);
|
203 | }
|
204 |
|
205 | if (params.type === 'custom' && params.renderCustom) {
|
206 | $el.html(params.renderCustom(swiper, current + 1, total));
|
207 | emit('paginationRender', $el[0]);
|
208 | } else {
|
209 | emit('paginationUpdate', $el[0]);
|
210 | }
|
211 |
|
212 | if (swiper.params.watchOverflow && swiper.enabled) {
|
213 | $el[swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);
|
214 | }
|
215 | }
|
216 |
|
217 | function render() {
|
218 |
|
219 | const params = swiper.params.pagination;
|
220 | if (isPaginationDisabled()) return;
|
221 | const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
|
222 | const $el = swiper.pagination.$el;
|
223 | let paginationHTML = '';
|
224 |
|
225 | if (params.type === 'bullets') {
|
226 | let numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
|
227 |
|
228 | if (swiper.params.freeMode && swiper.params.freeMode.enabled && !swiper.params.loop && numberOfBullets > slidesLength) {
|
229 | numberOfBullets = slidesLength;
|
230 | }
|
231 |
|
232 | for (let i = 0; i < numberOfBullets; i += 1) {
|
233 | if (params.renderBullet) {
|
234 | paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
|
235 | } else {
|
236 | paginationHTML += `<${params.bulletElement} class="${params.bulletClass}"></${params.bulletElement}>`;
|
237 | }
|
238 | }
|
239 |
|
240 | $el.html(paginationHTML);
|
241 | swiper.pagination.bullets = $el.find(classesToSelector(params.bulletClass));
|
242 | }
|
243 |
|
244 | if (params.type === 'fraction') {
|
245 | if (params.renderFraction) {
|
246 | paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
|
247 | } else {
|
248 | paginationHTML = `<span class="${params.currentClass}"></span>` + ' / ' + `<span class="${params.totalClass}"></span>`;
|
249 | }
|
250 |
|
251 | $el.html(paginationHTML);
|
252 | }
|
253 |
|
254 | if (params.type === 'progressbar') {
|
255 | if (params.renderProgressbar) {
|
256 | paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
|
257 | } else {
|
258 | paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
|
259 | }
|
260 |
|
261 | $el.html(paginationHTML);
|
262 | }
|
263 |
|
264 | if (params.type !== 'custom') {
|
265 | emit('paginationRender', swiper.pagination.$el[0]);
|
266 | }
|
267 | }
|
268 |
|
269 | function init() {
|
270 | swiper.params.pagination = createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, {
|
271 | el: 'swiper-pagination'
|
272 | });
|
273 | const params = swiper.params.pagination;
|
274 | if (!params.el) return;
|
275 | let $el = $(params.el);
|
276 | if ($el.length === 0) return;
|
277 |
|
278 | if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1) {
|
279 | $el = swiper.$el.find(params.el);
|
280 |
|
281 | if ($el.length > 1) {
|
282 | $el = $el.filter(el => {
|
283 | if ($(el).parents('.swiper')[0] !== swiper.el) return false;
|
284 | return true;
|
285 | });
|
286 | }
|
287 | }
|
288 |
|
289 | if (params.type === 'bullets' && params.clickable) {
|
290 | $el.addClass(params.clickableClass);
|
291 | }
|
292 |
|
293 | $el.addClass(params.modifierClass + params.type);
|
294 | $el.addClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
|
295 |
|
296 | if (params.type === 'bullets' && params.dynamicBullets) {
|
297 | $el.addClass(`${params.modifierClass}${params.type}-dynamic`);
|
298 | dynamicBulletIndex = 0;
|
299 |
|
300 | if (params.dynamicMainBullets < 1) {
|
301 | params.dynamicMainBullets = 1;
|
302 | }
|
303 | }
|
304 |
|
305 | if (params.type === 'progressbar' && params.progressbarOpposite) {
|
306 | $el.addClass(params.progressbarOppositeClass);
|
307 | }
|
308 |
|
309 | if (params.clickable) {
|
310 | $el.on('click', classesToSelector(params.bulletClass), function onClick(e) {
|
311 | e.preventDefault();
|
312 | let index = $(this).index() * swiper.params.slidesPerGroup;
|
313 | if (swiper.params.loop) index += swiper.loopedSlides;
|
314 | swiper.slideTo(index);
|
315 | });
|
316 | }
|
317 |
|
318 | Object.assign(swiper.pagination, {
|
319 | $el,
|
320 | el: $el[0]
|
321 | });
|
322 |
|
323 | if (!swiper.enabled) {
|
324 | $el.addClass(params.lockClass);
|
325 | }
|
326 | }
|
327 |
|
328 | function destroy() {
|
329 | const params = swiper.params.pagination;
|
330 | if (isPaginationDisabled()) return;
|
331 | const $el = swiper.pagination.$el;
|
332 | $el.removeClass(params.hiddenClass);
|
333 | $el.removeClass(params.modifierClass + params.type);
|
334 | $el.removeClass(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
|
335 | if (swiper.pagination.bullets && swiper.pagination.bullets.removeClass) swiper.pagination.bullets.removeClass(params.bulletActiveClass);
|
336 |
|
337 | if (params.clickable) {
|
338 | $el.off('click', classesToSelector(params.bulletClass));
|
339 | }
|
340 | }
|
341 |
|
342 | on('init', () => {
|
343 | init();
|
344 | render();
|
345 | update();
|
346 | });
|
347 | on('activeIndexChange', () => {
|
348 | if (swiper.params.loop) {
|
349 | update();
|
350 | } else if (typeof swiper.snapIndex === 'undefined') {
|
351 | update();
|
352 | }
|
353 | });
|
354 | on('snapIndexChange', () => {
|
355 | if (!swiper.params.loop) {
|
356 | update();
|
357 | }
|
358 | });
|
359 | on('slidesLengthChange', () => {
|
360 | if (swiper.params.loop) {
|
361 | render();
|
362 | update();
|
363 | }
|
364 | });
|
365 | on('snapGridLengthChange', () => {
|
366 | if (!swiper.params.loop) {
|
367 | render();
|
368 | update();
|
369 | }
|
370 | });
|
371 | on('destroy', () => {
|
372 | destroy();
|
373 | });
|
374 | on('enable disable', () => {
|
375 | const {
|
376 | $el
|
377 | } = swiper.pagination;
|
378 |
|
379 | if ($el) {
|
380 | $el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.pagination.lockClass);
|
381 | }
|
382 | });
|
383 | on('lock unlock', () => {
|
384 | update();
|
385 | });
|
386 | on('click', (_s, e) => {
|
387 | const targetEl = e.target;
|
388 | const {
|
389 | $el
|
390 | } = swiper.pagination;
|
391 |
|
392 | if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && $el.length > 0 && !$(targetEl).hasClass(swiper.params.pagination.bulletClass)) {
|
393 | if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return;
|
394 | const isHidden = $el.hasClass(swiper.params.pagination.hiddenClass);
|
395 |
|
396 | if (isHidden === true) {
|
397 | emit('paginationShow');
|
398 | } else {
|
399 | emit('paginationHide');
|
400 | }
|
401 |
|
402 | $el.toggleClass(swiper.params.pagination.hiddenClass);
|
403 | }
|
404 | });
|
405 | Object.assign(swiper.pagination, {
|
406 | render,
|
407 | update,
|
408 | init,
|
409 | destroy
|
410 | });
|
411 | } |
\ | No newline at end of file |