You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

286 regels
14 KiB

  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. import { S as Swiper } from './shared/swiper-core.mjs';
  13. import { p as paramsList, n as needsNavigation, a as needsPagination, b as needsScrollbar, u as updateSwiper, c as attrToProp } from './shared/update-swiper.mjs';
  14. import { g as getParams } from './shared/get-element-params.mjs';
  15. /* eslint-disable spaced-comment */
  16. const 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)}`
  17. const 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}`
  18. class DummyHTMLElement {}
  19. const ClassToExtend = typeof window === 'undefined' || typeof HTMLElement === 'undefined' ? DummyHTMLElement : HTMLElement;
  20. const 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>
  21. `;
  22. const addStyle = (shadowRoot, styles) => {
  23. if (typeof CSSStyleSheet !== 'undefined' && shadowRoot.adoptedStyleSheets) {
  24. const styleSheet = new CSSStyleSheet();
  25. styleSheet.replaceSync(styles);
  26. shadowRoot.adoptedStyleSheets = [styleSheet];
  27. } else {
  28. const style = document.createElement('style');
  29. style.rel = 'stylesheet';
  30. style.textContent = styles;
  31. shadowRoot.appendChild(style);
  32. }
  33. };
  34. class SwiperContainer extends ClassToExtend {
  35. constructor() {
  36. super();
  37. this.attachShadow({
  38. mode: 'open'
  39. });
  40. }
  41. static get nextButtonSvg() {
  42. return arrowSvg;
  43. }
  44. static get prevButtonSvg() {
  45. return arrowSvg.replace('/></svg>', ' transform-origin="center" transform="rotate(180)"/></svg>');
  46. }
  47. cssStyles() {
  48. return [SwiperCSS,
  49. // eslint-disable-line
  50. ...(this.injectStyles && Array.isArray(this.injectStyles) ? this.injectStyles : [])].join('\n');
  51. }
  52. cssLinks() {
  53. return this.injectStylesUrls || [];
  54. }
  55. calcSlideSlots() {
  56. const currentSideSlots = this.slideSlots || 0;
  57. // slide slots
  58. const slideSlotChildren = [...this.querySelectorAll(`[slot^=slide-]`)].map(child => {
  59. return parseInt(child.getAttribute('slot').split('slide-')[1], 10);
  60. });
  61. this.slideSlots = slideSlotChildren.length ? Math.max(...slideSlotChildren) + 1 : 0;
  62. if (!this.rendered) return;
  63. if (this.slideSlots > currentSideSlots) {
  64. for (let i = currentSideSlots; i < this.slideSlots; i += 1) {
  65. const slideEl = document.createElement('swiper-slide');
  66. slideEl.setAttribute('part', `slide slide-${i + 1}`);
  67. const slotEl = document.createElement('slot');
  68. slotEl.setAttribute('name', `slide-${i + 1}`);
  69. slideEl.appendChild(slotEl);
  70. this.shadowRoot.querySelector('.swiper-wrapper').appendChild(slideEl);
  71. }
  72. } else if (this.slideSlots < currentSideSlots) {
  73. const slides = this.swiper.slides;
  74. for (let i = slides.length - 1; i >= 0; i -= 1) {
  75. if (i > this.slideSlots) {
  76. slides[i].remove();
  77. }
  78. }
  79. }
  80. }
  81. render() {
  82. if (this.rendered) return;
  83. this.calcSlideSlots();
  84. // local styles
  85. let localStyles = this.cssStyles();
  86. if (this.slideSlots > 0) {
  87. localStyles = localStyles.replace(/::slotted\(([a-z-0-9.]*)\)/g, '$1');
  88. }
  89. if (localStyles.length) {
  90. addStyle(this.shadowRoot, localStyles);
  91. }
  92. this.cssLinks().forEach(url => {
  93. const linkExists = this.shadowRoot.querySelector(`link[href="${url}"]`);
  94. if (linkExists) return;
  95. const linkEl = document.createElement('link');
  96. linkEl.rel = 'stylesheet';
  97. linkEl.href = url;
  98. this.shadowRoot.appendChild(linkEl);
  99. });
  100. // prettier-ignore
  101. const el = document.createElement('div');
  102. el.classList.add('swiper');
  103. el.part = 'container';
  104. // prettier-ignore
  105. el.innerHTML = `
  106. <slot name="container-start"></slot>
  107. <div class="swiper-wrapper" part="wrapper">
  108. <slot></slot>
  109. ${Array.from({
  110. length: this.slideSlots
  111. }).map((_, index) => `
  112. <swiper-slide part="slide slide-${index}">
  113. <slot name="slide-${index}"></slot>
  114. </swiper-slide>
  115. `).join('')}
  116. </div>
  117. <slot name="container-end"></slot>
  118. ${needsNavigation(this.passedParams) ? `
  119. <div part="button-prev" class="swiper-button-prev">${this.constructor.prevButtonSvg}</div>
  120. <div part="button-next" class="swiper-button-next">${this.constructor.nextButtonSvg}</div>
  121. ` : ''}
  122. ${needsPagination(this.passedParams) ? `
  123. <div part="pagination" class="swiper-pagination"></div>
  124. ` : ''}
  125. ${needsScrollbar(this.passedParams) ? `
  126. <div part="scrollbar" class="swiper-scrollbar"></div>
  127. ` : ''}
  128. `;
  129. this.shadowRoot.appendChild(el);
  130. this.rendered = true;
  131. }
  132. initialize() {
  133. var _this = this;
  134. if (this.initialized) return;
  135. this.initialized = true;
  136. const {
  137. params: swiperParams,
  138. passedParams
  139. } = getParams(this);
  140. this.swiperParams = swiperParams;
  141. this.passedParams = passedParams;
  142. delete this.swiperParams.init;
  143. this.render();
  144. // eslint-disable-next-line
  145. this.swiper = new Swiper(this.shadowRoot.querySelector('.swiper'), {
  146. ...(swiperParams.virtual ? {} : {
  147. observer: true
  148. }),
  149. ...swiperParams,
  150. touchEventsTarget: 'container',
  151. onAny: function (name) {
  152. if (name === 'observerUpdate') {
  153. _this.calcSlideSlots();
  154. }
  155. const eventName = swiperParams.eventsPrefix ? `${swiperParams.eventsPrefix}${name.toLowerCase()}` : name.toLowerCase();
  156. for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  157. args[_key - 1] = arguments[_key];
  158. }
  159. const event = new CustomEvent(eventName, {
  160. detail: args,
  161. bubbles: name !== 'hashChange',
  162. cancelable: true
  163. });
  164. _this.dispatchEvent(event);
  165. }
  166. });
  167. }
  168. connectedCallback() {
  169. if (this.initialized && this.nested && this.closest('swiper-slide') && this.closest('swiper-slide').swiperLoopMoveDOM) {
  170. return;
  171. }
  172. if (this.init === false || this.getAttribute('init') === 'false') {
  173. return;
  174. }
  175. this.initialize();
  176. }
  177. disconnectedCallback() {
  178. if (this.nested && this.closest('swiper-slide') && this.closest('swiper-slide').swiperLoopMoveDOM) {
  179. return;
  180. }
  181. if (this.swiper && this.swiper.destroy) {
  182. this.swiper.destroy();
  183. }
  184. this.initialized = false;
  185. }
  186. updateSwiperOnPropChange(propName, propValue) {
  187. const {
  188. params: swiperParams,
  189. passedParams
  190. } = getParams(this, propName, propValue);
  191. this.passedParams = passedParams;
  192. this.swiperParams = swiperParams;
  193. if (this.swiper && this.swiper.params[propName] === propValue) {
  194. return;
  195. }
  196. updateSwiper({
  197. swiper: this.swiper,
  198. passedParams: this.passedParams,
  199. changedParams: [attrToProp(propName)],
  200. ...(propName === 'navigation' && passedParams[propName] ? {
  201. prevEl: '.swiper-button-prev',
  202. nextEl: '.swiper-button-next'
  203. } : {}),
  204. ...(propName === 'pagination' && passedParams[propName] ? {
  205. paginationEl: '.swiper-pagination'
  206. } : {}),
  207. ...(propName === 'scrollbar' && passedParams[propName] ? {
  208. scrollbarEl: '.swiper-scrollbar'
  209. } : {})
  210. });
  211. }
  212. attributeChangedCallback(attr, prevValue, newValue) {
  213. if (!this.initialized) return;
  214. if (prevValue === 'true' && newValue === null) {
  215. newValue = false;
  216. }
  217. this.updateSwiperOnPropChange(attr, newValue);
  218. }
  219. static get observedAttributes() {
  220. const attrs = paramsList.filter(param => param.includes('_')).map(param => param.replace(/[A-Z]/g, v => `-${v}`).replace('_', '').toLowerCase());
  221. return attrs;
  222. }
  223. }
  224. paramsList.forEach(paramName => {
  225. if (paramName === 'init') return;
  226. paramName = paramName.replace('_', '');
  227. Object.defineProperty(SwiperContainer.prototype, paramName, {
  228. configurable: true,
  229. get() {
  230. return (this.passedParams || {})[paramName];
  231. },
  232. set(value) {
  233. if (!this.passedParams) this.passedParams = {};
  234. this.passedParams[paramName] = value;
  235. if (!this.initialized) return;
  236. this.updateSwiperOnPropChange(paramName, value);
  237. }
  238. });
  239. });
  240. class SwiperSlide extends ClassToExtend {
  241. constructor() {
  242. super();
  243. this.attachShadow({
  244. mode: 'open'
  245. });
  246. }
  247. render() {
  248. const lazy = this.lazy || this.getAttribute('lazy') === '' || this.getAttribute('lazy') === 'true';
  249. addStyle(this.shadowRoot, SwiperSlideCSS);
  250. this.shadowRoot.appendChild(document.createElement('slot'));
  251. if (lazy) {
  252. const lazyDiv = document.createElement('div');
  253. lazyDiv.classList.add('swiper-lazy-preloader');
  254. lazyDiv.part.add('preloader');
  255. this.shadowRoot.appendChild(lazyDiv);
  256. }
  257. }
  258. initialize() {
  259. this.render();
  260. }
  261. connectedCallback() {
  262. this.initialize();
  263. }
  264. }
  265. // eslint-disable-next-line
  266. const register = () => {
  267. if (typeof window === 'undefined') return;
  268. if (!window.customElements.get('swiper-container')) window.customElements.define('swiper-container', SwiperContainer);
  269. if (!window.customElements.get('swiper-slide')) window.customElements.define('swiper-slide', SwiperSlide);
  270. };
  271. if (typeof window !== 'undefined') {
  272. window.SwiperElementRegisterParams = params => {
  273. paramsList.push(...params);
  274. };
  275. }
  276. export { SwiperContainer, SwiperSlide, register };