diff --git a/packages/split-layout/src/vaadin-split-layout-mixin.js b/packages/split-layout/src/vaadin-split-layout-mixin.js index 454025c4c79..9918554a9f5 100644 --- a/packages/split-layout/src/vaadin-split-layout-mixin.js +++ b/packages/split-layout/src/vaadin-split-layout-mixin.js @@ -63,17 +63,38 @@ export const SplitLayoutMixin = (superClass) => /** @private */ _processChildren() { - [...this.children].forEach((child, i) => { - if (i === 0) { - this._primaryChild = child; - child.setAttribute('slot', 'primary'); - } else if (i === 1) { - this._secondaryChild = child; - child.setAttribute('slot', 'secondary'); - } else { - child.removeAttribute('slot'); - } - }); + const children = [...this.children]; + + children.filter((child) => child.hasAttribute('slot')).forEach((child) => this._processChildWithSlot(child)); + + children + .filter((child) => !child.hasAttribute('slot')) + .forEach((child, i) => this._processChildWithoutSlot(child, i)); + } + + /** @private */ + _processChildWithSlot(child) { + const slot = child.getAttribute('slot'); + if (child.__autoSlotted) { + this[`_${slot}Child`] = null; + child.removeAttribute('slot'); + } else { + this[`_${slot}Child`] = child; + } + } + + /** @private */ + _processChildWithoutSlot(child, idx) { + let slotName; + if (this._primaryChild || this._secondaryChild) { + slotName = this._primaryChild ? 'secondary' : 'primary'; + } else { + slotName = idx === 0 ? 'primary' : 'secondary'; + } + + this[`_${slotName}Child`] = child; + child.setAttribute('slot', slotName); + child.__autoSlotted = true; } /** @private */ diff --git a/packages/split-layout/test/split-layout.common.js b/packages/split-layout/test/split-layout.common.js index 725b5867af9..4c583510488 100644 --- a/packages/split-layout/test/split-layout.common.js +++ b/packages/split-layout/test/split-layout.common.js @@ -73,6 +73,96 @@ describe('split layout', () => { expect(getComputedStyle(first).pointerEvents).to.equal('visible'); expect(getComputedStyle(second).pointerEvents).to.equal('visible'); }); + + describe('elements with slot pre-defined', () => { + it('should respect pre-defined slot values in both elements', async () => { + const layout = fixtureSync(` + +
secondary
+
primary
+
+ `); + await nextRender(); + expect(layout.querySelector('#first').slot).to.be.equal('primary'); + expect(layout.querySelector('#second').slot).to.be.equal('secondary'); + }); + + it('should assign a slot if only one element has "secondary" slot pre-defined', async () => { + const layout = fixtureSync(` + +
secondary
+
primary
+
+ `); + await nextRender(); + expect(layout.querySelector('#first').slot).to.be.equal('primary'); + expect(layout.querySelector('#second').slot).to.be.equal('secondary'); + }); + + it('should assign a slot if only element has "primary" slot pre-defined', async () => { + const layout = fixtureSync(` + +
secondary
+
primary
+
+ `); + await nextRender(); + expect(layout.querySelector('#first').slot).to.be.equal('primary'); + expect(layout.querySelector('#second').slot).to.be.equal('secondary'); + }); + + it('should respect assigned slot if only one element has slot pre-defined after order is inverted', async () => { + const layout = fixtureSync(` + +
secondary
+
primary
+
+ `); + await nextRender(); + + const first = layout.querySelector('#first'); + layout.prepend(first); + await nextRender(); + + expect(layout.querySelector('#first').slot).to.be.equal('primary'); + expect(layout.querySelector('#second').slot).to.be.equal('secondary'); + }); + + it('should swap slots if children without pre-defined slots invert order', async () => { + const layout = fixtureSync(` + +
secondary
+
primary
+
+ `); + await nextRender(); + + const second = layout.querySelector('#second'); + layout.prepend(second); + await nextRender(); + + expect(layout.querySelector('#first').slot).to.be.equal('secondary'); + expect(layout.querySelector('#second').slot).to.be.equal('primary'); + }); + + it('should assign slots only for direct children', async () => { + const layout = fixtureSync(` + +
primary
+ +
+
+
+
+ `); + await nextRender(); + + const first = layout.querySelector('#first'); + expect(first.slot).to.be.equal('primary'); + const second = layout.querySelector('#second'); + expect(second.slot).to.be.equal('secondary'); + }); + }); }); });