From 9fb14fa1c5ea17fe8940f9aba1dfcf46e03781f8 Mon Sep 17 00:00:00 2001 From: Danny Moerkerke Date: Thu, 12 Jan 2023 15:55:39 +0100 Subject: [PATCH] fix: - rearranging invokers and content for a correct tab order is now implemented by changing the slot attributes of both instead of moving them - changed css for this implementation - fixed tests - added changeset --- .changeset/tricky-squids-dress.md | 5 ++ .../components/accordion/src/LionAccordion.js | 31 +++++++--- .../accordion/test/lion-accordion.test.js | 61 +++++++++---------- 3 files changed, 56 insertions(+), 41 deletions(-) create mode 100644 .changeset/tricky-squids-dress.md diff --git a/.changeset/tricky-squids-dress.md b/.changeset/tricky-squids-dress.md new file mode 100644 index 000000000..7e4e8e9cc --- /dev/null +++ b/.changeset/tricky-squids-dress.md @@ -0,0 +1,5 @@ +--- +'@lion/ui': patch +--- + +`accordion`: rearranging invokers and content for a correct tab order is now implemented by changing the slot attributes of both instead of moving them, changed css for this implementation, updated tests diff --git a/packages/ui/components/accordion/src/LionAccordion.js b/packages/ui/components/accordion/src/LionAccordion.js index c00e72ed2..079f12aff 100644 --- a/packages/ui/components/accordion/src/LionAccordion.js +++ b/packages/ui/components/accordion/src/LionAccordion.js @@ -44,21 +44,21 @@ export class LionAccordion extends LitElement { flex-direction: column; } - .accordion [slot='invoker'] { + .accordion ::slotted(.invoker) { margin: 0; } - .accordion [slot='invoker'][expanded] { + .accordion ::slotted(.invoker)[expanded] { font-weight: bold; } - .accordion [slot='content'] { + .accordion ::slotted(.content) { margin: 0; visibility: hidden; display: none; } - .accordion [slot='content'][expanded] { + .accordion ::slotted(.content[expanded]) { visibility: visible; display: block; } @@ -159,9 +159,15 @@ export class LionAccordion extends LitElement { * @private */ __setupStore() { - const accordion = this.shadowRoot?.querySelector('slot[name=_accordion]'); - const existingInvokers = accordion ? accordion.querySelectorAll('[slot=invoker]') : []; - const existingContent = accordion ? accordion.querySelectorAll('[slot=content]') : []; + const accordion = /** @type {HTMLSlotElement} */ ( + this.shadowRoot?.querySelector('slot[name=_accordion]') + ); + const existingInvokers = accordion + ? accordion.assignedElements().filter(child => child.classList.contains('invoker')) + : []; + const existingContent = accordion + ? accordion.assignedElements().filter(child => child.classList.contains('content')) + : []; const invokers = /** @type {HTMLElement[]} */ ([ ...Array.from(existingInvokers), @@ -212,14 +218,21 @@ export class LionAccordion extends LitElement { const invokers = /** @type {HTMLElement[]} */ ( Array.from(this.children).filter(child => child.slot === 'invoker') ); + const contents = /** @type {HTMLElement[]} */ ( Array.from(this.children).filter(child => child.slot === 'content') ); + const accordion = this.shadowRoot?.querySelector('slot[name=_accordion]'); + if (accordion) { invokers.forEach((invoker, index) => { - accordion.insertAdjacentElement('beforeend', invoker); - accordion.insertAdjacentElement('beforeend', contents[index]); + invoker.classList.add('invoker'); + // eslint-disable-next-line no-param-reassign + invoker.slot = '_accordion'; + + contents[index].classList.add('content'); + contents[index].slot = '_accordion'; }); } } diff --git a/packages/ui/components/accordion/test/lion-accordion.test.js b/packages/ui/components/accordion/test/lion-accordion.test.js index 966f74eee..9dff2f1a0 100644 --- a/packages/ui/components/accordion/test/lion-accordion.test.js +++ b/packages/ui/components/accordion/test/lion-accordion.test.js @@ -23,27 +23,27 @@ const basicAccordion = html` * @param {Element} el */ function getAccordionChildren(el) { - const slot = el.shadowRoot?.querySelector('slot[name=_accordion]'); + if (el.shadowRoot) { + const slot = el.shadowRoot?.querySelector('slot[name=_accordion]'); - return slot ? slot.children : []; + return slot && slot instanceof HTMLSlotElement ? slot.assignedElements() : []; + } + + return []; } /** * @param {Element} el */ function getInvokers(el) { - const slot = el.shadowRoot?.querySelector('slot[name=_accordion]'); - - return slot ? slot.querySelectorAll('[slot=invoker]') : []; + return getAccordionChildren(el).filter(child => child.classList.contains('invoker')); } /** * @param {Element} el */ function getContents(el) { - const slot = el.shadowRoot?.querySelector('slot[name=_accordion]'); - - return slot ? slot.querySelectorAll('[slot=content]') : []; + return getAccordionChildren(el).filter(child => child.classList.contains('content')); } describe('', () => { @@ -68,14 +68,14 @@ describe('', () => { expect( Array.from(getAccordionChildren(el)).find( - child => child.slot === 'invoker' && child.hasAttribute('expanded'), + child => child.className === 'invoker' && child.hasAttribute('expanded'), )?.textContent, ).to.equal('invoker 2'); el.expanded = [0]; expect( Array.from(getAccordionChildren(el)).find( - child => child.slot === 'invoker' && child.hasAttribute('expanded'), + child => child.className === 'invoker' && child.hasAttribute('expanded'), )?.textContent, ).to.equal('invoker 1'); }); @@ -146,17 +146,16 @@ describe('', () => { `) ); expect(el.focusedIndex).to.equal(1); + expect( - Array.from(getAccordionChildren(el)).find( - child => child.slot === 'invoker' && child.firstElementChild?.hasAttribute('focused'), - )?.textContent, + Array.from(getInvokers(el)).find(child => child.firstElementChild?.hasAttribute('focused')) + ?.textContent, ).to.equal('invoker 2'); el.focusedIndex = 0; expect( - Array.from(getAccordionChildren(el)).find( - child => child.slot === 'invoker' && child.firstElementChild?.hasAttribute('focused'), - )?.textContent, + Array.from(getInvokers(el)).find(child => child.firstElementChild?.hasAttribute('focused')) + ?.textContent, ).to.equal('invoker 1'); }); @@ -360,14 +359,10 @@ describe('', () => { await el.updateComplete; expect( - Array.from(getAccordionChildren(el)).find( - child => child.slot === 'invoker' && child.hasAttribute('expanded'), - )?.textContent, + Array.from(getInvokers(el)).find(child => child.hasAttribute('expanded'))?.textContent, ).to.equal('invoker 5'); expect( - Array.from(getAccordionChildren(el)).find( - child => child.slot === 'content' && child.hasAttribute('expanded'), - )?.textContent, + Array.from(getContents(el)).find(child => child.hasAttribute('expanded'))?.textContent, ).to.equal('content 5'); }); @@ -410,11 +405,13 @@ describe('', () => {
content 2
`); + + // console.log(getAccordionChildren(el)); expect( - Array.from(getAccordionChildren(el)).find(child => child.slot === 'content'), + Array.from(getAccordionChildren(el)).find(child => child.classList.contains('content')), ).to.not.have.attribute('tabindex'); expect( - Array.from(getAccordionChildren(el)).find(child => child.slot === 'content'), + Array.from(getAccordionChildren(el)).find(child => child.classList.contains('content')), ).to.not.have.attribute('tabindex'); }); @@ -445,10 +442,10 @@ describe('', () => {
content
`); - expect( - Array.from(getAccordionChildren(el)).find(child => child.slot === 'invoker') - ?.firstElementChild, - ).to.have.attribute('aria-expanded', 'false'); + expect(Array.from(getInvokers(el))[0]?.firstElementChild).to.have.attribute( + 'aria-expanded', + 'false', + ); }); it('adds aria-expanded="true" to invoker when its content is expanded', async () => { @@ -461,10 +458,10 @@ describe('', () => { `) ); el.expanded = [0]; - expect( - Array.from(getAccordionChildren(el)).find(child => child.slot === 'invoker') - ?.firstElementChild, - ).to.have.attribute('aria-expanded', 'true'); + expect(Array.from(getInvokers(el))[0]?.firstElementChild).to.have.attribute( + 'aria-expanded', + 'true', + ); }); });