Skip to content

Commit

Permalink
feat(element): support slides as slots
Browse files Browse the repository at this point in the history
  • Loading branch information
nolimits4web committed Jul 11, 2023
1 parent 22e89d1 commit 697b028
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 20 deletions.
24 changes: 12 additions & 12 deletions playground/element/index.html
Expand Up @@ -8,17 +8,17 @@
</head>

<body>
<swiper-container>
<swiper-slide>Slide 1</swiper-slide>
<swiper-slide>Slide 2</swiper-slide>
<swiper-slide>Slide 3</swiper-slide>
<swiper-slide>Slide 4</swiper-slide>
<swiper-slide>Slide 5</swiper-slide>
<swiper-slide>Slide 6</swiper-slide>
<swiper-slide>Slide 7</swiper-slide>
<swiper-slide>Slide 8</swiper-slide>
<swiper-slide>Slide 9</swiper-slide>
<swiper-slide>Slide 10</swiper-slide>
<swiper-container effect="cube">
<div slot="slide-0">Slide 1</div>
<div slot="slide-1">Slide 2</div>
<div slot="slide-2">Slide 3</div>
<div slot="slide-3">Slide 4</div>
<div slot="slide-4">Slide 5</div>
<div slot="slide-5">Slide 6</div>
<div slot="slide-6">Slide 7</div>
<div slot="slide-7">Slide 8</div>
<div slot="slide-8">Slide 9</div>
<div slot="slide-9">Slide 10</div>
</swiper-container>
<style>
body,
Expand All @@ -35,7 +35,7 @@
margin: 50px auto;
}

swiper-slide {
swiper-container::part(slide) {
background: #f1f1f1;
color: #000;
text-align: center;
Expand Down
5 changes: 2 additions & 3 deletions src/components-shared/get-params.mjs
@@ -1,15 +1,14 @@
import { Swiper } from '../swiper.mjs';
import { isObject, extend } from './utils.mjs';
import { paramsList } from './params-list.mjs';
import defaults from '../core/defaults.mjs';

function getParams(obj = {}, splitEvents = true) {
const params = {
on: {},
};
const events = {};
const passedParams = {};
extend(params, Swiper.defaults);
extend(params, Swiper.extendedDefaults);
extend(params, defaults);
params._emitClasses = true;
params.init = false;

Expand Down
2 changes: 1 addition & 1 deletion src/core/core.mjs
Expand Up @@ -514,7 +514,7 @@ class Swiper {
Object.assign(swiper, {
el,
wrapperEl,
slidesEl: swiper.isElement ? el.parentNode.host : wrapperEl,
slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl,
hostEl: swiper.isElement ? el.parentNode.host : el,
mounted: true,

Expand Down
4 changes: 2 additions & 2 deletions src/core/modules/observer/observer.mjs
Expand Up @@ -38,13 +38,13 @@ export default function Observer({ swiper, extendParams, on, emit }) {
const init = () => {
if (!swiper.params.observer) return;
if (swiper.params.observeParents) {
const containerParents = elementParents(swiper.el);
const containerParents = elementParents(swiper.hostEl);
for (let i = 0; i < containerParents.length; i += 1) {
attach(containerParents[i]);
}
}
// Observe container
attach(swiper.el, {
attach(swiper.hostEl, {
childList: swiper.params.observeSlideChildren,
});

Expand Down
48 changes: 46 additions & 2 deletions src/swiper-element.mjs
Expand Up @@ -65,11 +65,43 @@ class SwiperContainer extends ClassToExtend {
return this.injectStylesUrls || [];
}

calcSlideSlots() {
const currentSideSlots = this.slideSlots || 0;
// slide slots
const slideSlotChildren = [...this.querySelectorAll(`[slot^=slide-]`)].map((child) => {
return parseInt(child.getAttribute('slot').split('slide-')[1], 10);
});
this.slideSlots = slideSlotChildren.length ? Math.max(...slideSlotChildren) + 1 : 0;
if (!this.rendered) return;
if (this.slideSlots > currentSideSlots) {
for (let i = currentSideSlots; i < this.slideSlots; i += 1) {
const slideEl = document.createElement('swiper-slide');
slideEl.setAttribute('part', `slide slide-${i + 1}`);
const slotEl = document.createElement('slot');
slotEl.setAttribute('name', `slide-${i + 1}`);
slideEl.appendChild(slotEl);
this.shadowRoot.querySelector('.swiper-wrapper').appendChild(slideEl);
}
} else if (this.slideSlots < currentSideSlots) {
const slides = this.swiper.slides;
for (let i = slides.length - 1; i >= 0; i -= 1) {
if (i > this.slideSlots) {
slides[i].remove();
}
}
}
}

render() {
if (this.rendered) return;

this.calcSlideSlots();

// local styles
const localStyles = this.cssStyles();
let localStyles = this.cssStyles();
if (this.slideSlots > 0) {
localStyles = localStyles.replace(/::slotted\(([a-z-0-9.]*)\)/g, '$1');
}
if (localStyles.length) {
addStyle(this.shadowRoot, localStyles);
}
Expand All @@ -86,11 +118,17 @@ class SwiperContainer extends ClassToExtend {
const el = document.createElement('div');
el.classList.add('swiper');
el.part = 'container';

// prettier-ignore
el.innerHTML = `
<slot name="container-start"></slot>
<div class="swiper-wrapper" part="wrapper">
<slot></slot>
${Array.from({length: this.slideSlots}).map((_, index) => `
<swiper-slide part="slide slide-${index}">
<slot name="slide-${index}"></slot>
</swiper-slide>
`).join('')}
</div>
<slot name="container-end"></slot>
${needsNavigation(this.passedParams) ? `
Expand All @@ -117,12 +155,18 @@ class SwiperContainer extends ClassToExtend {
delete this.swiperParams.init;

this.render();

// eslint-disable-next-line
this.swiper = new Swiper(this.shadowRoot.querySelector('.swiper'), {
...(swiperParams.virtual
? {}
: { observer: true, observeSlideChildren: this.slideSlots > 0 }),
...swiperParams,
touchEventsTarget: 'container',
...(swiperParams.virtual ? {} : { observer: true }),
onAny: (name, ...args) => {
if (name === 'observerUpdate') {
this.calcSlideSlots();
}
const eventName = swiperParams.eventsPrefix
? `${swiperParams.eventsPrefix}${name.toLowerCase()}`
: name.toLowerCase();
Expand Down

0 comments on commit 697b028

Please sign in to comment.