UNPKG

14.8 kBJavaScriptView Raw
1/**
2 * Swiper Custom Element 11.1.4
3 * Most modern mobile touch slider and framework with hardware accelerated transitions
4 * https://swiperjs.com
5 *
6 * Copyright 2014-2024 Vladimir Kharlampidi
7 *
8 * Released under the MIT License
9 *
10 * Released on: May 30, 2024
11 */
12
13import { S as Swiper } from './shared/swiper-core.mjs';
14import { p as paramsList, n as needsNavigation, a as needsPagination, b as needsScrollbar, u as updateSwiper, c as attrToProp } from './shared/update-swiper.mjs';
15import { g as getParams } from './shared/get-element-params.mjs';
16
17/* eslint-disable spaced-comment */
18
19const SwiperCSS = `:host{--swiper-theme-color:#007aff}:host{position:relative;display:block;margin-left:auto;margin-right:auto;z-index:1}.swiper{width:100%;height:100%;margin-left:auto;margin-right:auto;position:relative;overflow:hidden;list-style:none;padding:0;z-index:1;display:block}.swiper-vertical>.swiper-wrapper{flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:flex;transition-property:transform;transition-timing-function:var(--swiper-wrapper-transition-timing-function,initial);box-sizing:content-box}.swiper-android ::slotted(swiper-slide),.swiper-ios ::slotted(swiper-slide),.swiper-wrapper{transform:translate3d(0px,0,0)}.swiper-horizontal{touch-action:pan-y}.swiper-vertical{touch-action:pan-x}::slotted(swiper-slide){flex-shrink:0;width:100%;height:100%;position:relative;transition-property:transform;display:block}::slotted(.swiper-slide-invisible-blank){visibility:hidden}.swiper-autoheight,.swiper-autoheight ::slotted(swiper-slide){height:auto}.swiper-autoheight .swiper-wrapper{align-items:flex-start;transition-property:transform,height}.swiper-backface-hidden ::slotted(swiper-slide){transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-3d.swiper-css-mode .swiper-wrapper{perspective:1200px}.swiper-3d .swiper-wrapper{transform-style:preserve-3d}.swiper-3d{perspective:1200px}.swiper-3d .swiper-cube-shadow,.swiper-3d ::slotted(swiper-slide){transform-style:preserve-3d}.swiper-css-mode>.swiper-wrapper{overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.swiper-css-mode>.swiper-wrapper::-webkit-scrollbar{display:none}.swiper-css-mode ::slotted(swiper-slide){scroll-snap-align:start start}.swiper-css-mode.swiper-horizontal>.swiper-wrapper{scroll-snap-type:x mandatory}.swiper-css-mode.swiper-vertical>.swiper-wrapper{scroll-snap-type:y mandatory}.swiper-css-mode.swiper-free-mode>.swiper-wrapper{scroll-snap-type:none}.swiper-css-mode.swiper-free-mode ::slotted(swiper-slide){scroll-snap-align:none}.swiper-css-mode.swiper-centered>.swiper-wrapper::before{content:'';flex-shrink:0;order:9999}.swiper-css-mode.swiper-centered ::slotted(swiper-slide){scroll-snap-align:center center;scroll-snap-stop:always}.swiper-css-mode.swiper-centered.swiper-horizontal ::slotted(swiper-slide):first-child{margin-inline-start:var(--swiper-centered-offset-before)}.swiper-css-mode.swiper-centered.swiper-horizontal>.swiper-wrapper::before{height:100%;min-height:1px;width:var(--swiper-centered-offset-after)}.swiper-css-mode.swiper-centered.swiper-vertical ::slotted(swiper-slide):first-child{margin-block-start:var(--swiper-centered-offset-before)}.swiper-css-mode.swiper-centered.swiper-vertical>.swiper-wrapper::before{width:100%;min-width:1px;height:var(--swiper-centered-offset-after)}`
20const SwiperSlideCSS = `::slotted(.swiper-slide-shadow),::slotted(.swiper-slide-shadow-bottom),::slotted(.swiper-slide-shadow-left),::slotted(.swiper-slide-shadow-right),::slotted(.swiper-slide-shadow-top){position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}::slotted(.swiper-slide-shadow){background:rgba(0,0,0,.15)}::slotted(.swiper-slide-shadow-left){background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}::slotted(.swiper-slide-shadow-right){background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}::slotted(.swiper-slide-shadow-top){background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}::slotted(.swiper-slide-shadow-bottom){background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-lazy-preloader{animation:swiper-preloader-spin 1s infinite linear;width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;transform-origin:50%;box-sizing:border-box;border:4px solid var(--swiper-preloader-color,var(--swiper-theme-color));border-radius:50%;border-top-color:transparent}@keyframes swiper-preloader-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}::slotted(.swiper-slide-shadow-cube.swiper-slide-shadow-bottom),::slotted(.swiper-slide-shadow-cube.swiper-slide-shadow-left),::slotted(.swiper-slide-shadow-cube.swiper-slide-shadow-right),::slotted(.swiper-slide-shadow-cube.swiper-slide-shadow-top){z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}::slotted(.swiper-slide-shadow-flip.swiper-slide-shadow-bottom),::slotted(.swiper-slide-shadow-flip.swiper-slide-shadow-left),::slotted(.swiper-slide-shadow-flip.swiper-slide-shadow-right),::slotted(.swiper-slide-shadow-flip.swiper-slide-shadow-top){z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}::slotted(.swiper-zoom-container){width:100%;height:100%;display:flex;justify-content:center;align-items:center;text-align:center}::slotted(.swiper-zoom-container)>canvas,::slotted(.swiper-zoom-container)>img,::slotted(.swiper-zoom-container)>svg{max-width:100%;max-height:100%;object-fit:contain}`
21
22class DummyHTMLElement {}
23const ClassToExtend = typeof window === 'undefined' || typeof HTMLElement === 'undefined' ? DummyHTMLElement : HTMLElement;
24const arrowSvg = `<svg width="11" height="20" viewBox="0 0 11 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0.38296 20.0762C0.111788 19.805 0.111788 19.3654 0.38296 19.0942L9.19758 10.2796L0.38296 1.46497C0.111788 1.19379 0.111788 0.754138 0.38296 0.482966C0.654131 0.211794 1.09379 0.211794 1.36496 0.482966L10.4341 9.55214C10.8359 9.9539 10.8359 10.6053 10.4341 11.007L1.36496 20.0762C1.09379 20.3474 0.654131 20.3474 0.38296 20.0762Z" fill="currentColor"/></svg>
25 `;
26const addStyle = (shadowRoot, styles) => {
27 if (typeof CSSStyleSheet !== 'undefined' && shadowRoot.adoptedStyleSheets) {
28 const styleSheet = new CSSStyleSheet();
29 styleSheet.replaceSync(styles);
30 shadowRoot.adoptedStyleSheets = [styleSheet];
31 } else {
32 const style = document.createElement('style');
33 style.rel = 'stylesheet';
34 style.textContent = styles;
35 shadowRoot.appendChild(style);
36 }
37};
38class SwiperContainer extends ClassToExtend {
39 constructor() {
40 super();
41 this.attachShadow({
42 mode: 'open'
43 });
44 }
45 static get nextButtonSvg() {
46 return arrowSvg;
47 }
48 static get prevButtonSvg() {
49 return arrowSvg.replace('/></svg>', ' transform-origin="center" transform="rotate(180)"/></svg>');
50 }
51 cssStyles() {
52 return [SwiperCSS,
53 // eslint-disable-line
54 ...(this.injectStyles && Array.isArray(this.injectStyles) ? this.injectStyles : [])].join('\n');
55 }
56 cssLinks() {
57 return this.injectStylesUrls || [];
58 }
59 calcSlideSlots() {
60 const currentSideSlots = this.slideSlots || 0;
61 // slide slots
62 const slideSlotChildren = [...this.querySelectorAll(`[slot^=slide-]`)].map(child => {
63 return parseInt(child.getAttribute('slot').split('slide-')[1], 10);
64 });
65 this.slideSlots = slideSlotChildren.length ? Math.max(...slideSlotChildren) + 1 : 0;
66 if (!this.rendered) return;
67 if (this.slideSlots > currentSideSlots) {
68 for (let i = currentSideSlots; i < this.slideSlots; i += 1) {
69 const slideEl = document.createElement('swiper-slide');
70 slideEl.setAttribute('part', `slide slide-${i + 1}`);
71 const slotEl = document.createElement('slot');
72 slotEl.setAttribute('name', `slide-${i + 1}`);
73 slideEl.appendChild(slotEl);
74 this.shadowRoot.querySelector('.swiper-wrapper').appendChild(slideEl);
75 }
76 } else if (this.slideSlots < currentSideSlots) {
77 const slides = this.swiper.slides;
78 for (let i = slides.length - 1; i >= 0; i -= 1) {
79 if (i > this.slideSlots) {
80 slides[i].remove();
81 }
82 }
83 }
84 }
85 render() {
86 if (this.rendered) return;
87 this.calcSlideSlots();
88
89 // local styles
90 let localStyles = this.cssStyles();
91 if (this.slideSlots > 0) {
92 localStyles = localStyles.replace(/::slotted\(([a-z-0-9.]*)\)/g, '$1');
93 }
94 if (localStyles.length) {
95 addStyle(this.shadowRoot, localStyles);
96 }
97 this.cssLinks().forEach(url => {
98 const linkExists = this.shadowRoot.querySelector(`link[href="${url}"]`);
99 if (linkExists) return;
100 const linkEl = document.createElement('link');
101 linkEl.rel = 'stylesheet';
102 linkEl.href = url;
103 this.shadowRoot.appendChild(linkEl);
104 });
105 // prettier-ignore
106 const el = document.createElement('div');
107 el.classList.add('swiper');
108 el.part = 'container';
109
110 // prettier-ignore
111 el.innerHTML = `
112 <slot name="container-start"></slot>
113 <div class="swiper-wrapper" part="wrapper">
114 <slot></slot>
115 ${Array.from({
116 length: this.slideSlots
117 }).map((_, index) => `
118 <swiper-slide part="slide slide-${index}">
119 <slot name="slide-${index}"></slot>
120 </swiper-slide>
121 `).join('')}
122 </div>
123 <slot name="container-end"></slot>
124 ${needsNavigation(this.passedParams) ? `
125 <div part="button-prev" class="swiper-button-prev">${this.constructor.prevButtonSvg}</div>
126 <div part="button-next" class="swiper-button-next">${this.constructor.nextButtonSvg}</div>
127 ` : ''}
128 ${needsPagination(this.passedParams) ? `
129 <div part="pagination" class="swiper-pagination"></div>
130 ` : ''}
131 ${needsScrollbar(this.passedParams) ? `
132 <div part="scrollbar" class="swiper-scrollbar"></div>
133 ` : ''}
134 `;
135 this.shadowRoot.appendChild(el);
136 this.rendered = true;
137 }
138 initialize() {
139 var _this = this;
140 if (this.initialized) return;
141 this.initialized = true;
142 const {
143 params: swiperParams,
144 passedParams
145 } = getParams(this);
146 this.swiperParams = swiperParams;
147 this.passedParams = passedParams;
148 delete this.swiperParams.init;
149 this.render();
150
151 // eslint-disable-next-line
152 this.swiper = new Swiper(this.shadowRoot.querySelector('.swiper'), {
153 ...(swiperParams.virtual ? {} : {
154 observer: true,
155 observeSlideChildren: this.slideSlots > 0
156 }),
157 ...swiperParams,
158 touchEventsTarget: 'container',
159 onAny: function (name) {
160 if (name === 'observerUpdate') {
161 _this.calcSlideSlots();
162 }
163 const eventName = swiperParams.eventsPrefix ? `${swiperParams.eventsPrefix}${name.toLowerCase()}` : name.toLowerCase();
164 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
165 args[_key - 1] = arguments[_key];
166 }
167 const event = new CustomEvent(eventName, {
168 detail: args,
169 bubbles: name !== 'hashChange',
170 cancelable: true
171 });
172 _this.dispatchEvent(event);
173 }
174 });
175 }
176 connectedCallback() {
177 if (this.initialized && this.nested && this.closest('swiper-slide') && this.closest('swiper-slide').swiperLoopMoveDOM) {
178 return;
179 }
180 if (this.init === false || this.getAttribute('init') === 'false') {
181 return;
182 }
183 this.initialize();
184 }
185 disconnectedCallback() {
186 if (this.nested && this.closest('swiper-slide') && this.closest('swiper-slide').swiperLoopMoveDOM) {
187 return;
188 }
189 if (this.swiper && this.swiper.destroy) {
190 this.swiper.destroy();
191 }
192 this.initialized = false;
193 }
194 updateSwiperOnPropChange(propName, propValue) {
195 const {
196 params: swiperParams,
197 passedParams
198 } = getParams(this, propName, propValue);
199 this.passedParams = passedParams;
200 this.swiperParams = swiperParams;
201 if (this.swiper && this.swiper.params[propName] === propValue) {
202 return;
203 }
204 updateSwiper({
205 swiper: this.swiper,
206 passedParams: this.passedParams,
207 changedParams: [attrToProp(propName)],
208 ...(propName === 'navigation' && passedParams[propName] ? {
209 prevEl: '.swiper-button-prev',
210 nextEl: '.swiper-button-next'
211 } : {}),
212 ...(propName === 'pagination' && passedParams[propName] ? {
213 paginationEl: '.swiper-pagination'
214 } : {}),
215 ...(propName === 'scrollbar' && passedParams[propName] ? {
216 scrollbarEl: '.swiper-scrollbar'
217 } : {})
218 });
219 }
220 attributeChangedCallback(attr, prevValue, newValue) {
221 if (!this.initialized) return;
222 if (prevValue === 'true' && newValue === null) {
223 newValue = false;
224 }
225 this.updateSwiperOnPropChange(attr, newValue);
226 }
227 static get observedAttributes() {
228 const attrs = paramsList.filter(param => param.includes('_')).map(param => param.replace(/[A-Z]/g, v => `-${v}`).replace('_', '').toLowerCase());
229 return attrs;
230 }
231}
232paramsList.forEach(paramName => {
233 if (paramName === 'init') return;
234 paramName = paramName.replace('_', '');
235 Object.defineProperty(SwiperContainer.prototype, paramName, {
236 configurable: true,
237 get() {
238 return (this.passedParams || {})[paramName];
239 },
240 set(value) {
241 if (!this.passedParams) this.passedParams = {};
242 this.passedParams[paramName] = value;
243 if (!this.initialized) return;
244 this.updateSwiperOnPropChange(paramName, value);
245 }
246 });
247});
248class SwiperSlide extends ClassToExtend {
249 constructor() {
250 super();
251 this.attachShadow({
252 mode: 'open'
253 });
254 }
255 render() {
256 const lazy = this.lazy || this.getAttribute('lazy') === '' || this.getAttribute('lazy') === 'true';
257 addStyle(this.shadowRoot, SwiperSlideCSS);
258 this.shadowRoot.appendChild(document.createElement('slot'));
259 if (lazy) {
260 const lazyDiv = document.createElement('div');
261 lazyDiv.classList.add('swiper-lazy-preloader');
262 lazyDiv.part.add('preloader');
263 this.shadowRoot.appendChild(lazyDiv);
264 }
265 }
266 initialize() {
267 this.render();
268 }
269 connectedCallback() {
270 this.initialize();
271 }
272}
273
274// eslint-disable-next-line
275const register = () => {
276 if (typeof window === 'undefined') return;
277 if (!window.customElements.get('swiper-container')) window.customElements.define('swiper-container', SwiperContainer);
278 if (!window.customElements.get('swiper-slide')) window.customElements.define('swiper-slide', SwiperSlide);
279};
280if (typeof window !== 'undefined') {
281 window.SwiperElementRegisterParams = params => {
282 paramsList.push(...params);
283 };
284}
285
286export { SwiperContainer, SwiperSlide, register };