1import Swiper from "https://cdn.jsdelivr.net/npm/[email protected]/swiper-bundle.min.mjs"; 2export default function swiperComponent(options = {}) { 3 return { 4 swiper: null, 5 initialized: false, 6 $options: options, 7 swiperInstanceId: options.id || `swiper-${Date.now()}-${Math.floor(Math.random() * 1e3)}`, 8 swiperContainerSelector: null, 9 paginationSelector: null, 10 nextButtonSelector: null, 11 prevButtonSelector: null, 12 defaultOptions: { 13 slidesPerView: 1, 14 spaceBetween: 20, 15 autoplay: { delay: 3e3, disableOnInteraction: false }, 16 loop: false, 17 effect: void 0, 18 displayMode: "mobile-only", 19 20 breakpoint: 740, 21 breakpointCustom: 980, 22 waitForLoad: false 23 }, 24 init() { 25 this.prepareDOM(); 26 this.$el.addEventListener("click", (e) => this.arrowClickFallback(e)); 27 let resizeTimeout; 28 const debouncedResize = () => { 29 clearTimeout(resizeTimeout); 30 resizeTimeout = setTimeout(() => { 31 this.checkBreakpoint(); 32 }, 150); 33 }; 34 const onReady = () => { 35 setTimeout(() => { 36 this.checkBreakpoint(); 37 }, 200); 38 }; 39 if (document.readyState === "complete") { 40 onReady(); 41 } else { 42 document.addEventListener("DOMContentLoaded", onReady); 43 window.addEventListener("load", () => { 44 setTimeout(() => { 45 this.checkBreakpoint(); 46 }, 100); 47 }); 48 } 49 window.addEventListener("resize", debouncedResize); 50 }, 51 52 arrowClickFallback(e) { 53 const nav = this.$options.navigation; 54 if (!nav || !this.swiper) return; 55 const prevHit = nav.prevEl && e.target.closest(nav.prevEl); 56 const nextHit = nav.nextEl && e.target.closest(nav.nextEl); 57 if (!prevHit && !nextHit) return; 58 const hit = prevHit || nextHit; 59 const bound = prevHit ? this.prevButtonSelector : this.nextButtonSelector; 60 if (bound && hit.matches(bound)) return; 61 if (prevHit) this.swiper.slidePrev(); 62 else this.swiper.slideNext(); 63 }, 64 prepareDOM() { 65 const swiperEl = this.$el.querySelector(".swiper"); 66 if (!swiperEl) { 67 console.warn("Swiper container element not found"); 68 return; 69 } 70 if (!swiperEl.id) swiperEl.id = this.swiperInstanceId; 71 this.swiperContainerSelector = `#${swiperEl.id}`; 72 if (this.$options.pagination !== false) { 73 let pag = null; 74 if (this.$options.pagination?.el) { 75 pag = this.$el.querySelector(this.$options.pagination.el); 76 } 77 if (!pag) { 78 pag = this.$el.querySelector(".swiper-pagination"); 79 } 80 if (pag) { 81 const pid = `pagination-${this.swiperInstanceId}`; 82 pag.id = pid; 83 this.paginationSelector = `#${pid}`; 84 } 85 } 86 if (this.$options.navigation !== false) { 87 let prev = null; 88 let next = null; 89 if (this.$options.navigation?.prevEl) { 90 prev = this.$el.querySelector(this.$options.navigation.prevEl); 91 } 92 if (this.$options.navigation?.nextEl) { 93 next = this.$el.querySelector(this.$options.navigation.nextEl); 94 } 95 if (!prev) { 96 prev = this.$el.querySelector(".swiper-button-prev"); 97 } 98 if (!next) { 99 next = this.$el.querySelector(".swiper-button-next"); 100 } 101 if (prev) { 102 const prid = `prev-${this.swiperInstanceId}`; 103 prev.id = prid; 104 this.prevButtonSelector = `#${prid}`; 105 } 106 if (next) { 107 const nid = `next-${this.swiperInstanceId}`; 108 next.id = nid; 109 this.nextButtonSelector = `#${nid}`; 110 } 111 } 112 }, 113 checkBreakpoint() { 114 const width = window.innerWidth; 115 const isMobile = width < this.defaultOptions.breakpoint; 116 const isCustom = width < this.defaultOptions.breakpointCustom; 117 let active = true; 118 switch (this.$options.displayMode || this.defaultOptions.displayMode) { 119 case "mobile-only": 120 active = isMobile; 121 break; 122 case "desktop-only": 123 active = !isMobile; 124 break;
125 case "custom": 126 active = isCustom; 127 break; 128 case "always": 129 default: 130 active = true; 131 break; 132 } 133 if (this.$el.offsetParent === null) active = false; 134 if (active && !this.initialized) { 135 setTimeout(() => this.initSwiper(), 100); 136 } else if (!active && this.initialized) { 137 this.destroySwiper(); 138 } else if (active && this.initialized && this.swiper) { 139 setTimeout(() => { 140 if (this.swiper && this.swiper.update) { 141 this.swiper.update(); 142 if (this.swiper.updateSlidesClasses) { 143 this.swiper.updateSlidesClasses(); 144 } 145 if (this.swiper.updateSlides) { 146 this.swiper.updateSlides(); 147 } 148 if (this.swiper.updateProgress) { 149 this.swiper.updateProgress(); 150 } 151 if (this.swiper.pagination && this.swiper.pagination.update) { 152 this.swiper.pagination.update(); 153 } 154 } 155 }, 50); 156 } 157 }, 158 initSwiper() { 159 this.prepareDOM(); 160 const minSlidesToInit = this.$options.minSlidesToInit || 1; 161 if (this.$el.querySelectorAll(".swiper-slide").length < minSlidesToInit) return; 162 const base = JSON.parse(JSON.stringify(this.defaultOptions)); 163 const opts = Object.assign(base, this.$options); 164 if (opts.loop) { 165 const spvValues = [ 166 opts.slidesPerView, 167 ...Object.values(opts.breakpoints || {}).map((b) => b.slidesPerView) 168 ].filter((v) => typeof v === "number"); 169 const needed = Math.max(...spvValues, 1) + (opts.slidesPerGroup || 1); 170 if (this.$el.querySelectorAll(".swiper-slide").length < needed) { 171 opts.loop = false; 172 opts.rewind = true; 173 } 174 } 175 if (opts.pagination !== false && this.paginationSelector) { 176 opts.pagination = { 177 el: this.paginationSelector, 178 clickable: true, 179 type: "bullets", 180 dynamicBullets: false, 181 renderBullet: function(index, className) { 182 return '<span class="' + className + ' swiper-pagination-bullet-custom"></span>'; 183 }, 184 ...this.$options.paginationOptions || {} 185 }; 186 } else { 187 opts.pagination = false; 188 } 189 if (opts.navigation !== false && this.prevButtonSelector && this.nextButtonSelector) { 190 opts.navigation = { 191 prevEl: this.prevButtonSelector, 192 nextEl: this.nextButtonSelector 193 }; 194 } else { 195 opts.navigation = false; 196 } 197 if (["flip", "cube", "cards"].includes(opts.effect)) { 198 opts.slidesPerView = 1; 199 opts.slidesPerGroup = 1; 200 } 201 const originalOn = opts.on || {}; 202 opts.on = { 203 ...originalOn, 204 init: function() { 205 if (originalOn.init) originalOn.init.call(this); 206 if (this.pagination && this.pagination.update) { 207 setTimeout(() => { 208 if (!this.pagination) return; 209 this.pagination.render(); 210 this.pagination.update(); 211 }, 10); 212 } 213 }, 214 slideChange: function() { 215 if (originalOn.slideChange) originalOn.slideChange.call(this); 216 if (this.pagination) { 217 requestAnimationFrame(() => { 218 if (!this.pagination) return; 219 if (this.pagination.render) this.pagination.render(); 220 if (this.pagination.update) this.pagination.update(); 221 }); 222 } 223 }, 224 transitionStart: function() { 225 if (originalOn.transitionStart) originalOn.transitionStart.call(this); 226 if (this.pagination && this.pagination.update) { 227 this.pagination.update(); 228 } 229 }, 230 transitionEnd: function() { 231 if (originalOn.transitionEnd) originalOn.transitionEnd.call(this); 232 if (this.pagination) { 233 requestAnimationFrame(() => { 234 if (this.pagination && this.pagination.update) this.pagination.update(); 235 }); 236 } 237 }, 238 touchMove: function() { 239 if (originalOn.touchMove) originalOn.touchMove.call(this); 240 if (this.pagination && this.pagination.update) { 241 this.pagination.update(); 242 } 243 }, 244 setTranslate: function() { 245 if (originalOn.setTranslate) originalOn.setTranslate.call(this); 246 if (this.pagination && this.pagination.update) { 247 this.pagination.update(); 248 } 249 } 250 };
251 try { 252 this.swiper = new Swiper(this.swiperContainerSelector, opts); 253 if (this.swiper.pagination) { 254 setTimeout(() => { 255 if (!this.swiper || !this.swiper.pagination) return; 256 this.swiper.pagination.render(); 257 this.swiper.pagination.update(); 258 }, 100); 259 } 260 if (opts.autoplay && this.swiper.autoplay) { 261 setTimeout(() => { 262 if (this.swiper && this.swiper.autoplay) this.swiper.autoplay.start(); 263 }, 100); 264 } 265 this.initialized = true; 266 if (typeof window !== "undefined") { 267 window.swiperInstance = this.swiper; 268 } 269 } catch (e) { 270 console.error("Swiper init error:", e); 271 } 272 }, 273 destroySwiper() { 274 if (this.swiper) { 275 this.swiper.destroy(true, true); 276 this.swiper = null; 277 } 278 this.initialized = false; 279 if (typeof window !== "undefined" && window.swiperInstance === this.swiper) { 280 delete window.swiperInstance; 281 } 282 } 283 }; 284}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.