From dca55bd37e70042cd455aa788b7e51ea797f3b8c Mon Sep 17 00:00:00 2001 From: Oliver Kucharzewski Date: Wed, 24 Sep 2025 17:17:27 +1000 Subject: [PATCH] feat: resolve autoplay bug and enhance swiper configuration --- .changeset/tiny-yaks-reflect.md | 5 ++ package.json | 2 +- .../swiper/swiper.extension.spec.ts | 62 +++++++++++++++++ .../extensions/swiper/swiper.extension.ts | 66 ++++++++++++------- 4 files changed, 109 insertions(+), 26 deletions(-) create mode 100644 .changeset/tiny-yaks-reflect.md create mode 100644 src/libs/extensions/swiper/swiper.extension.spec.ts diff --git a/.changeset/tiny-yaks-reflect.md b/.changeset/tiny-yaks-reflect.md new file mode 100644 index 0000000..eb062f8 --- /dev/null +++ b/.changeset/tiny-yaks-reflect.md @@ -0,0 +1,5 @@ +--- +"@stackla/widget-utils": patch +--- + +Resolve bug around autoplay not working diff --git a/package.json b/package.json index 55c84d0..05977fa 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "new-change": "changeset", "presnapshot": "npm run new-change", "snapshot": "npx changeset version --snapshot", - "postsnapshot": "npm publish --no-git-checks" + "postsnapshot": "npm publish --no-git-checks --tag snapshot" }, "author": "", "license": "ISC", diff --git a/src/libs/extensions/swiper/swiper.extension.spec.ts b/src/libs/extensions/swiper/swiper.extension.spec.ts new file mode 100644 index 0000000..bf79cd9 --- /dev/null +++ b/src/libs/extensions/swiper/swiper.extension.spec.ts @@ -0,0 +1,62 @@ +import { Autoplay } from "swiper/modules" +import { establishSwiperConfig } from "./swiper.extension" + +beforeAll(() => { + document.body.innerHTML = ` +
+
+ ` +}) + +describe("establishSwiperConfig", () => { + const userProperties = { + prev: window.document.querySelector(".swiper-button-prev") as HTMLElement, + next: window.document.querySelector(".swiper-button-next") as HTMLElement, + paramsOverrides: { + slidesPerView: 3, + spaceBetween: 10 + } + } + it("should create a valid swiper config and not contain autoplay", () => { + const config = establishSwiperConfig(userProperties) + expect(config).toBeDefined() + + if (config.navigation && typeof config.navigation === "object") { + expect(config.navigation.nextEl).toBe(userProperties.next) + expect(config.navigation.prevEl).toBe(userProperties.prev) + } else { + throw new Error("config.navigation is not NavigationOptions") + } + + expect(config.slidesPerView).toBe(3) + expect(config.spaceBetween).toBe(10) + expect(config.modules).not.toContain(Autoplay) + }) + + it("should create a valid swiper config and contain autoplay", () => { + const mutatedUserProperties = { + ...userProperties, + paramsOverrides: { + autoplay: { + delay: 3000, + disableOnInteraction: false, + pauseOnMouseEnter: true + } + } + } + + const config = establishSwiperConfig(mutatedUserProperties) + expect(config).toBeDefined() + + if (config.navigation && typeof config.navigation === "object") { + expect(config.navigation.nextEl).toBe(userProperties.next) + expect(config.navigation.prevEl).toBe(userProperties.prev) + } else { + throw new Error("config.navigation is not NavigationOptions") + } + + expect(config.slidesPerView).toBe(undefined) + expect(config.spaceBetween).toBe(10) + expect(config.modules).toContain(Autoplay) + }) +}) diff --git a/src/libs/extensions/swiper/swiper.extension.ts b/src/libs/extensions/swiper/swiper.extension.ts index 6312f1d..936e476 100644 --- a/src/libs/extensions/swiper/swiper.extension.ts +++ b/src/libs/extensions/swiper/swiper.extension.ts @@ -11,6 +11,7 @@ import { Pagination } from "swiper/modules" import Swiper from "swiper" +import { SwiperOptions } from "swiper/types" export interface SwiperWithExtensions extends Swiper { getSlideIndex?: (element: HTMLElement) => number | undefined @@ -25,6 +26,44 @@ export type LookupAttr = { value: string } +type SwiperConfigContainer = { + prev: HTMLElement | null | undefined + next: HTMLElement | null | undefined + paramsOverrides: SwiperOptions | undefined +} + +export function establishSwiperConfig(userConfig: SwiperConfigContainer) { + const { prev, next, paramsOverrides } = userConfig + const config = { + modules: [Navigation, Manipulation, Keyboard, Mousewheel, EffectCoverflow, Pagination, FreeMode], + spaceBetween: 10, + observer: true, + grabCursor: true, + allowTouchMove: true, + direction: "horizontal", + watchSlidesProgress: true, + normalizeSlideIndex: true, + watchOverflow: true, + mousewheel: { + enabled: false + }, + touchStartPreventDefault: false, + navigation: { + enabled: !!(prev && next), + nextEl: next, + prevEl: prev + }, + resizeObserver: true, + ...paramsOverrides + } + + if (config.autoplay) { + config.modules.push(Autoplay) + } + + return config as SwiperOptions +} + export function initializeSwiper(sdk: ISdk, swiperProps: SwiperProps) { // check if constructor is available if (!window.ugc.libs.Swiper) { @@ -64,32 +103,9 @@ export function initializeSwiper(sdk: ISdk, swiperProps: SwiperProps) { window.ugc.swiperContainer[mutatedId] = { pageIndex: 1 } } - const settings = new window.ugc.libs.Swiper(widgetSelector, { - modules: [Navigation, Manipulation, Keyboard, Mousewheel, EffectCoverflow, Pagination, FreeMode], - spaceBetween: 10, - observer: true, - grabCursor: true, - allowTouchMove: true, - direction: "horizontal", - watchSlidesProgress: true, - normalizeSlideIndex: true, - watchOverflow: true, - mousewheel: { - enabled: false - }, - touchStartPreventDefault: false, - navigation: { - enabled: !!(prev && next), - nextEl: next, - prevEl: prev - }, - resizeObserver: true, - ...paramsOverrides - }) + const config = establishSwiperConfig({ prev, next, paramsOverrides }) - if (settings.autoplay) { - settings.modules.push(Autoplay) - } + const settings = new window.ugc.libs.Swiper(widgetSelector, config) window.ugc.swiperContainer[mutatedId]!.instance = settings }