From 30dbfc8435c298e8f68083553ddc0fca1309fdf8 Mon Sep 17 00:00:00 2001 From: Westbrook Johnson Date: Thu, 30 Sep 2021 22:18:51 -0500 Subject: [PATCH] fix(accordion): ensure item toggle events can be prevented from the outside --- packages/accordion/src/Accordion.ts | 23 +++++++++++++++-------- packages/accordion/test/accordion.test.ts | 8 ++++---- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/packages/accordion/src/Accordion.ts b/packages/accordion/src/Accordion.ts index 9b4a2d45bb..6e9873a42b 100644 --- a/packages/accordion/src/Accordion.ts +++ b/packages/accordion/src/Accordion.ts @@ -116,20 +116,27 @@ export class Accordion extends Focusable { nextItem.focus(); } - private onToggle(event: Event): void { + private async onToggle(event: Event): Promise { + // Let the event pass through the DOM so that it can be + // prevented from the outside if a user so desires. + await 0; + if (this.allowMultiple || event.defaultPrevented) { + // No toggling when `allowMultiple` or the user prevents it. + return; + } const target = event.target as AccordionItem; const items = [...this.items] as AccordionItem[]; /* c8 ignore next 3 */ if (items && !items.length) { + // no toggling when there aren't items. return; } - if (!this.allowMultiple && !event.defaultPrevented) { - items.forEach((item) => { - if (item.open && item !== target) { - item.open = false; - } - }); - } + items.forEach((item) => { + if (item !== target) { + // Close all the items that didn't dispatch the event. + item.open = false; + } + }); } protected render(): TemplateResult { diff --git a/packages/accordion/test/accordion.test.ts b/packages/accordion/test/accordion.test.ts index 49619a960a..a4f27848c8 100644 --- a/packages/accordion/test/accordion.test.ts +++ b/packages/accordion/test/accordion.test.ts @@ -133,8 +133,8 @@ describe('Accordion', () => { firstButton.click(); await elementUpdated(el); - expect(firstItem.open); - expect(!secondItem.open); + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.false; el.addEventListener('sp-accordion-item-toggle', (event: Event) => event.preventDefault() @@ -142,8 +142,8 @@ describe('Accordion', () => { secondButton.click(); await elementUpdated(el); - expect(firstItem.open); - expect(!secondItem.open); + expect(firstItem.open).to.be.true; + expect(secondItem.open).to.be.false; }); it('allows more than one open item when `[allow-multiple]`', async () => { const el = await fixture(Default());