File: /var/www/html/wp-content/themes/thegem-elementor/js/ethnic-shared-case-study-showcase.js
(function () {
'use strict';
const ready = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback, { once: true });
return;
}
callback();
};
ready(() => {
const reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
const sliders = Array.from(document.querySelectorAll('[data-ethnic-case-showcase][data-loop-slider]'));
if (!sliders.length) {
return;
}
sliders.forEach((slider) => {
const track = slider.querySelector('[data-loop-track]');
const originalSlides = Array.from(slider.querySelectorAll('[data-loop-slide]'));
const previousButton = slider.querySelector('[data-loop-prev]');
const nextButton = slider.querySelector('[data-loop-next]');
const dots = Array.from(slider.querySelectorAll('[data-loop-dot]'));
const currentCounter = slider.querySelector('[data-loop-current]');
const cloneCount = Math.min(
Math.max(Number.parseInt(slider.dataset.loopClones || '1', 10) || 1, 1),
originalSlides.length
);
if (!track || originalSlides.length < 2) {
return;
}
const createClone = (slide, position) => {
const clone = slide.cloneNode(true);
clone.classList.remove('is-active');
clone.setAttribute('aria-hidden', 'true');
clone.removeAttribute('data-loop-slide');
clone.dataset.loopClone = position;
return clone;
};
const startClones = originalSlides.slice(-cloneCount).map((slide) => createClone(slide, 'start'));
const endClones = originalSlides.slice(0, cloneCount).map((slide) => createClone(slide, 'end'));
startClones.forEach((clone) => {
track.insertBefore(clone, track.firstChild);
});
endClones.forEach((clone) => {
track.appendChild(clone);
});
const trackSlides = Array.from(track.children);
const loopStart = cloneCount;
const loopEnd = cloneCount + originalSlides.length - 1;
let activePosition = loopStart;
let activeIndex = 0;
let pendingResetPosition = null;
let isTransitioning = false;
const wrapPosition = (index) => ((index % trackSlides.length) + trackSlides.length) % trackSlides.length;
const originalIndexFromPosition = (position) => ((position - loopStart) % originalSlides.length + originalSlides.length) % originalSlides.length;
const getStepSize = () => {
const slide = originalSlides[0];
if (!slide) {
return 0;
}
const styles = window.getComputedStyle(track);
const gapValue = styles.columnGap || styles.gap || '0';
const gap = Number.parseFloat(gapValue) || 0;
const width = slide.getBoundingClientRect().width;
return width + gap;
};
const updateState = (nextPosition) => {
activePosition = wrapPosition(nextPosition);
activeIndex = originalIndexFromPosition(activePosition);
trackSlides.forEach((slide, index) => {
const isActive = index === activePosition;
slide.classList.toggle('is-active', isActive);
slide.setAttribute('aria-hidden', isActive ? 'false' : 'true');
Array.from(slide.querySelectorAll('[data-loop-primary-link]')).forEach((link) => {
link.tabIndex = isActive ? 0 : -1;
});
});
dots.forEach((dot, index) => {
const isActive = index === activeIndex;
dot.classList.toggle('is-active', isActive);
dot.setAttribute('aria-selected', isActive ? 'true' : 'false');
dot.tabIndex = isActive ? 0 : -1;
});
if (currentCounter) {
currentCounter.textContent = String(activeIndex + 1).padStart(2, '0');
}
};
const renderPosition = (animate) => {
const stepSize = getStepSize();
if (!stepSize) {
return;
}
track.classList.toggle('is-instant', !animate);
track.style.transform = `translate3d(${-activePosition * stepSize}px, 0, 0)`;
if (!animate) {
track.offsetHeight;
track.classList.remove('is-instant');
}
};
const snapIfNeeded = () => {
if (pendingResetPosition === null) {
isTransitioning = false;
return;
}
updateState(pendingResetPosition);
renderPosition(false);
pendingResetPosition = null;
isTransitioning = false;
};
track.addEventListener('transitionend', (event) => {
if (event.target !== track || event.propertyName !== 'transform') {
return;
}
snapIfNeeded();
});
const goToPosition = (nextPosition, animate = true) => {
if (isTransitioning && animate) {
return;
}
const wrappedPosition = wrapPosition(nextPosition);
const needsReset = wrappedPosition < loopStart
? wrappedPosition + originalSlides.length
: wrappedPosition > loopEnd
? wrappedPosition - originalSlides.length
: null;
updateState(wrappedPosition);
pendingResetPosition = needsReset;
isTransitioning = animate && !reducedMotionQuery.matches;
renderPosition(animate && !reducedMotionQuery.matches);
if (!isTransitioning) {
snapIfNeeded();
}
};
previousButton?.addEventListener('click', () => {
goToPosition(activePosition - 1);
});
nextButton?.addEventListener('click', () => {
goToPosition(activePosition + 1);
});
dots.forEach((dot) => {
dot.addEventListener('click', () => {
const nextIndex = Number.parseInt(dot.dataset.loopDot || '0', 10);
goToPosition(loopStart + nextIndex);
});
});
track.addEventListener('keydown', (event) => {
if (event.key === 'ArrowLeft') {
event.preventDefault();
goToPosition(activePosition - 1);
return;
}
if (event.key === 'ArrowRight') {
event.preventDefault();
goToPosition(activePosition + 1);
return;
}
if (event.key === 'Home') {
event.preventDefault();
goToPosition(loopStart);
return;
}
if (event.key === 'End') {
event.preventDefault();
goToPosition(loopEnd);
}
});
window.addEventListener('resize', () => {
renderPosition(false);
}, { passive: true });
if (typeof ResizeObserver === 'function') {
const resizeObserver = new ResizeObserver(() => {
renderPosition(false);
});
resizeObserver.observe(slider);
trackSlides.forEach((slide) => resizeObserver.observe(slide));
}
if (document.fonts && typeof document.fonts.ready === 'object') {
document.fonts.ready.then(() => {
renderPosition(false);
}).catch(() => {});
}
updateState(activePosition);
renderPosition(false);
});
});
})();