UNPKG

14.8 kBJavaScriptView Raw
1/**
2 * Swiper Custom Element 11.1.14
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: September 12, 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 }),
156 ...swiperParams,
157 touchEventsTarget: 'container',
158 onAny: function (name) {
159 if (name === 'observerUpdate') {
160 _this.calcSlideSlots();
161 }
162 const eventName = swiperParams.eventsPrefix ? `${swiperParams.eventsPrefix}${name.toLowerCase()}` : name.toLowerCase();
163 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
164 args[_key - 1] = arguments[_key];
165 }
166 const event = new CustomEvent(eventName, {
167 detail: args,
168 bubbles: name !== 'hashChange',
169 cancelable: true
170 });
171 _this.dispatchEvent(event);
172 }
173 });
174 }
175 connectedCallback() {
176 if (this.initialized && this.nested && this.closest('swiper-slide') && this.closest('swiper-slide').swiperLoopMoveDOM) {
177 return;
178 }
179 if (this.init === false || this.getAttribute('init') === 'false') {
180 return;
181 }
182 this.initialize();
183 }
184 disconnectedCallback() {
185 if (this.nested && this.closest('swiper-slide') && this.closest('swiper-slide').swiperLoopMoveDOM) {
186 return;
187 }
188 if (this.swiper && this.swiper.destroy) {
189 this.swiper.destroy();
190 }
191 this.initialized = false;
192 }
193 updateSwiperOnPropChange(propName, propValue) {
194 const {
195 params: swiperParams,
196 passedParams
197 } = getParams(this, propName, propValue);
198 this.passedParams = passedParams;
199 this.swiperParams = swiperParams;
200 if (this.swiper && this.swiper.params[propName] === propValue) {
201 return;
202 }
203 updateSwiper({
204 swiper: this.swiper,
205 passedParams: this.passedParams,
206 changedParams: [attrToProp(propName)],
207 ...(propName === 'navigation' && passedParams[propName] ? {
208 prevEl: '.swiper-button-prev',
209 nextEl: '.swiper-button-next'
210 } : {}),
211 ...(propName === 'pagination' && passedParams[propName] ? {
212 paginationEl: '.swiper-pagination'
213 } : {}),
214 ...(propName === 'scrollbar' && passedParams[propName] ? {
215 scrollbarEl: '.swiper-scrollbar'
216 } : {})
217 });
218 }
219 attributeChangedCallback(attr, prevValue, newValue) {
220 if (!this.initialized) return;
221 if (prevValue === 'true' && newValue === null) {
222 newValue = false;
223 }
224 this.updateSwiperOnPropChange(attr, newValue);
225 }
226 static get observedAttributes() {
227 const attrs = paramsList.filter(param => param.includes('_')).map(param => param.replace(/[A-Z]/g, v => `-${v}`).replace('_', '').toLowerCase());
228 return attrs;
229 }
230}
231paramsList.forEach(paramName => {
232 if (paramName === 'init') return;
233 paramName = paramName.replace('_', '');
234 Object.defineProperty(SwiperContainer.prototype, paramName, {
235 configurable: true,
236 get() {
237 return (this.passedParams || {})[paramName];
238 },
239 set(value) {
240 if (!this.passedParams) this.passedParams = {};
241 this.passedParams[paramName] = value;
242 if (!this.initialized) return;
243 this.updateSwiperOnPropChange(paramName, value);
244 }
245 });
246});
247class SwiperSlide extends ClassToExtend {
248 constructor() {
249 super();
250 this.attachShadow({
251 mode: 'open'
252 });
253 }
254 render() {
255 const lazy = this.lazy || this.getAttribute('lazy') === '' || this.getAttribute('lazy') === 'true';
256 addStyle(this.shadowRoot, SwiperSlideCSS);
257 this.shadowRoot.appendChild(document.createElement('slot'));
258 if (lazy) {
259 const lazyDiv = document.createElement('div');
260 lazyDiv.classList.add('swiper-lazy-preloader');
261 lazyDiv.part.add('preloader');
262 this.shadowRoot.appendChild(lazyDiv);
263 }
264 }
265 initialize() {
266 this.render();
267 }
268 connectedCallback() {
269 this.initialize();
270 }
271}
272
273// eslint-disable-next-line
274const register = () => {
275 if (typeof window === 'undefined') return;
276 if (!window.customElements.get('swiper-container')) window.customElements.define('swiper-container', SwiperContainer);
277 if (!window.customElements.get('swiper-slide')) window.customElements.define('swiper-slide', SwiperSlide);
278};
279if (typeof window !== 'undefined') {
280 window.SwiperElementRegisterParams = params => {
281 paramsList.push(...params);
282 };
283}
284
285export { SwiperContainer, SwiperSlide, register };