import { g as getDocument } from '../shared/ssr-window.esm.mjs'; import { h as classesToTokens, c as createElement, n as nextTick, b as elementOffset } from '../shared/utils.mjs'; import { c as createElementIfNotDefined } from '../shared/create-element-if-not-defined.mjs'; import { c as classesToSelector } from '../shared/classes-to-selector.mjs'; function Scrollbar(_ref) { let { swiper, extendParams, on, emit } = _ref; const document = getDocument(); let isTouched = false; let timeout = null; let dragTimeout = null; let dragStartPos; let dragSize; let trackSize; let divider; extendParams({ scrollbar: { el: null, dragSize: 'auto', hide: false, draggable: false, snapOnRelease: true, lockClass: 'swiper-scrollbar-lock', dragClass: 'swiper-scrollbar-drag', scrollbarDisabledClass: 'swiper-scrollbar-disabled', horizontalClass: `swiper-scrollbar-horizontal`, verticalClass: `swiper-scrollbar-vertical` } }); swiper.scrollbar = { el: null, dragEl: null }; function setTranslate() { if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; const { scrollbar, rtlTranslate: rtl } = swiper; const { dragEl, el } = scrollbar; const params = swiper.params.scrollbar; const progress = swiper.params.loop ? swiper.progressLoop : swiper.progress; let newSize = dragSize; let newPos = (trackSize - dragSize) * progress; if (rtl) { newPos = -newPos; if (newPos > 0) { newSize = dragSize - newPos; newPos = 0; } else if (-newPos + dragSize > trackSize) { newSize = trackSize + newPos; } } else if (newPos < 0) { newSize = dragSize + newPos; newPos = 0; } else if (newPos + dragSize > trackSize) { newSize = trackSize - newPos; } if (swiper.isHorizontal()) { dragEl.style.transform = `translate3d(${newPos}px, 0, 0)`; dragEl.style.width = `${newSize}px`; } else { dragEl.style.transform = `translate3d(0px, ${newPos}px, 0)`; dragEl.style.height = `${newSize}px`; } if (params.hide) { clearTimeout(timeout); el.style.opacity = 1; timeout = setTimeout(() => { el.style.opacity = 0; el.style.transitionDuration = '400ms'; }, 1000); } } function setTransition(duration) { if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; swiper.scrollbar.dragEl.style.transitionDuration = `${duration}ms`; } function updateSize() { if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; const { scrollbar } = swiper; const { dragEl, el } = scrollbar; dragEl.style.width = ''; dragEl.style.height = ''; trackSize = swiper.isHorizontal() ? el.offsetWidth : el.offsetHeight; divider = swiper.size / (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0)); if (swiper.params.scrollbar.dragSize === 'auto') { dragSize = trackSize * divider; } else { dragSize = parseInt(swiper.params.scrollbar.dragSize, 10); } if (swiper.isHorizontal()) { dragEl.style.width = `${dragSize}px`; } else { dragEl.style.height = `${dragSize}px`; } if (divider >= 1) { el.style.display = 'none'; } else { el.style.display = ''; } if (swiper.params.scrollbar.hide) { el.style.opacity = 0; } if (swiper.params.watchOverflow && swiper.enabled) { scrollbar.el.classList[swiper.isLocked ? 'add' : 'remove'](swiper.params.scrollbar.lockClass); } } function getPointerPosition(e) { return swiper.isHorizontal() ? e.clientX : e.clientY; } function setDragPosition(e) { const { scrollbar, rtlTranslate: rtl } = swiper; const { el } = scrollbar; let positionRatio; positionRatio = (getPointerPosition(e) - elementOffset(el)[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize); positionRatio = Math.max(Math.min(positionRatio, 1), 0); if (rtl) { positionRatio = 1 - positionRatio; } const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio; swiper.updateProgress(position); swiper.setTranslate(position); swiper.updateActiveIndex(); swiper.updateSlidesClasses(); } function onDragStart(e) { const params = swiper.params.scrollbar; const { scrollbar, wrapperEl } = swiper; const { el, dragEl } = scrollbar; isTouched = true; dragStartPos = e.target === dragEl ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null; e.preventDefault(); e.stopPropagation(); wrapperEl.style.transitionDuration = '100ms'; dragEl.style.transitionDuration = '100ms'; setDragPosition(e); clearTimeout(dragTimeout); el.style.transitionDuration = '0ms'; if (params.hide) { el.style.opacity = 1; } if (swiper.params.cssMode) { swiper.wrapperEl.style['scroll-snap-type'] = 'none'; } emit('scrollbarDragStart', e); } function onDragMove(e) { const { scrollbar, wrapperEl } = swiper; const { el, dragEl } = scrollbar; if (!isTouched) return; if (e.preventDefault) e.preventDefault();else e.returnValue = false; setDragPosition(e); wrapperEl.style.transitionDuration = '0ms'; el.style.transitionDuration = '0ms'; dragEl.style.transitionDuration = '0ms'; emit('scrollbarDragMove', e); } function onDragEnd(e) { const params = swiper.params.scrollbar; const { scrollbar, wrapperEl } = swiper; const { el } = scrollbar; if (!isTouched) return; isTouched = false; if (swiper.params.cssMode) { swiper.wrapperEl.style['scroll-snap-type'] = ''; wrapperEl.style.transitionDuration = ''; } if (params.hide) { clearTimeout(dragTimeout); dragTimeout = nextTick(() => { el.style.opacity = 0; el.style.transitionDuration = '400ms'; }, 1000); } emit('scrollbarDragEnd', e); if (params.snapOnRelease) { swiper.slideToClosest(); } } function events(method) { const { scrollbar, params } = swiper; const el = scrollbar.el; if (!el) return; const target = el; const activeListener = params.passiveListeners ? { passive: false, capture: false } : false; const passiveListener = params.passiveListeners ? { passive: true, capture: false } : false; if (!target) return; const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener'; target[eventMethod]('pointerdown', onDragStart, activeListener); document[eventMethod]('pointermove', onDragMove, activeListener); document[eventMethod]('pointerup', onDragEnd, passiveListener); } function enableDraggable() { if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; events('on'); } function disableDraggable() { if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; events('off'); } function init() { const { scrollbar, el: swiperEl } = swiper; swiper.params.scrollbar = createElementIfNotDefined(swiper, swiper.originalParams.scrollbar, swiper.params.scrollbar, { el: 'swiper-scrollbar' }); const params = swiper.params.scrollbar; if (!params.el) return; let el; if (typeof params.el === 'string' && swiper.isElement) { el = swiper.el.querySelector(params.el); } if (!el && typeof params.el === 'string') { el = document.querySelectorAll(params.el); if (!el.length) return; } else if (!el) { el = params.el; } if (swiper.params.uniqueNavElements && typeof params.el === 'string' && el.length > 1 && swiperEl.querySelectorAll(params.el).length === 1) { el = swiperEl.querySelector(params.el); } if (el.length > 0) el = el[0]; el.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); let dragEl; if (el) { dragEl = el.querySelector(classesToSelector(swiper.params.scrollbar.dragClass)); if (!dragEl) { dragEl = createElement('div', swiper.params.scrollbar.dragClass); el.append(dragEl); } } Object.assign(scrollbar, { el, dragEl }); if (params.draggable) { enableDraggable(); } if (el) { el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass)); } } function destroy() { const params = swiper.params.scrollbar; const el = swiper.scrollbar.el; if (el) { el.classList.remove(...classesToTokens(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass)); } disableDraggable(); } on('init', () => { if (swiper.params.scrollbar.enabled === false) { // eslint-disable-next-line disable(); } else { init(); updateSize(); setTranslate(); } }); on('update resize observerUpdate lock unlock', () => { updateSize(); }); on('setTranslate', () => { setTranslate(); }); on('setTransition', (_s, duration) => { setTransition(duration); }); on('enable disable', () => { const { el } = swiper.scrollbar; if (el) { el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass)); } }); on('destroy', () => { destroy(); }); const enable = () => { swiper.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass)); if (swiper.scrollbar.el) { swiper.scrollbar.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass)); } init(); updateSize(); setTranslate(); }; const disable = () => { swiper.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass)); if (swiper.scrollbar.el) { swiper.scrollbar.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass)); } destroy(); }; Object.assign(swiper.scrollbar, { enable, disable, updateSize, setTranslate, init, destroy }); } export { Scrollbar as default };