From d2d7712ba4db217f88f0382af1432537c11d281a Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Wed, 6 Mar 2024 14:34:12 +0000 Subject: [PATCH] add activeTab, selectedTabIndex props --- src/tab-container-element.ts | 16 ++++++++++++++-- test/test.js | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/tab-container-element.ts b/src/tab-container-element.ts index d1fa04f..96ef090 100644 --- a/src/tab-container-element.ts +++ b/src/tab-container-element.ts @@ -107,6 +107,10 @@ export class TabContainerElement extends HTMLElement { ) } + get activeTab() { + return this.#tabs.find(e => e.matches('[aria-selected=true]')) + } + get activePanel() { return this.#panelSlot.assignedNodes()[0] as HTMLElement } @@ -181,7 +185,7 @@ export class TabContainerElement extends HTMLElement { const tabs = this.#tabs if (!tabs.includes(tab as HTMLElement)) return - const currentIndex = tabs.indexOf(tabs.find(e => e.matches('[aria-selected="true"]'))!) + const currentIndex = this.selectedTabIndex const vertical = tab.closest('[role="tablist"]')?.getAttribute('aria-orientation') === 'vertical' const prevTab = event.code === 'ArrowLeft' || (vertical && event.code === 'ArrowUp') const nextTab = event.code === 'ArrowRight' || (vertical && event.code === 'ArrowDown') @@ -218,6 +222,14 @@ export class TabContainerElement extends HTMLElement { } } + get selectedTabIndex(): number { + return this.#tabs.findIndex(el => el.matches('[aria-selected=true]')) + } + + set selectedTabIndex(i: number) { + this.selectTab(i) + } + selectTab(index: number): void { if (!this.#setupComplete) { const tabListSlot = this.#tabListSlot @@ -276,7 +288,7 @@ export class TabContainerElement extends HTMLElement { for (const el of afterSlotted) el.setAttribute('slot', 'after-panels') } const defaultTab = Number(this.getAttribute('default-tab') || -1) - const defaultIndex = defaultTab >= 0 ? defaultTab : this.#tabs.findIndex(el => el.matches('[aria-selected=true]')) + const defaultIndex = defaultTab >= 0 ? defaultTab : this.selectedTabIndex index = index >= 0 ? index : Math.max(0, defaultIndex) } diff --git a/test/test.js b/test/test.js index e7d607a..1dcb40a 100644 --- a/test/test.js +++ b/test/test.js @@ -162,6 +162,8 @@ describe('tab-container', function () { 'change events point to second panel', ) assert.equal(document.activeElement, tabs[1]) + assert.equal(tabContainer.activeTab, tabs[1]) + assert.equal(tabContainer.selectedTabIndex, 1) }) it('keyboard shortcuts work and `tab-container-changed` events are dispatched', function () { @@ -187,6 +189,8 @@ describe('tab-container', function () { assert.deepStrictEqual(tabs.map(isSelected), [true, false, false], 'First tab is selected') assert.deepStrictEqual(panels.map(isHidden), [false, true, true], 'First panel is visible') assert.equal(document.activeElement, tabs[0]) + assert.equal(tabContainer.activeTab, tabs[0]) + assert.equal(tabContainer.selectedTabIndex, 0) assert.equal(events.length, 2, 'tab-container-change(d) called') assert.deepStrictEqual( events.map(e => e.type), @@ -280,6 +284,8 @@ describe('tab-container', function () { 'change events point to second panel', ) assert.equal(document.activeElement, tabs[1]) + assert.equal(tabContainer.activeTab, tabs[1]) + assert.equal(tabContainer.selectedTabIndex, 1) }) it('result in noop, when selectTab receives out of bounds index', function () { @@ -417,6 +423,8 @@ describe('tab-container', function () { assert.deepStrictEqual(tabs.map(isSelected), [false, false, true], 'Third tab is selected') assert.deepStrictEqual(panels.map(isHidden), [true, true, false], 'Third panel is visible') assert.equal(document.activeElement, tabs[2]) + assert.equal(tabContainer.activeTab, tabs[2]) + assert.equal(tabContainer.selectedTabIndex, 2) assert.equal(events.length, 2, 'tab-container-change(d) called') assert.deepStrictEqual( events.map(e => e.type), @@ -439,6 +447,8 @@ describe('tab-container', function () { assert.deepStrictEqual(tabs.map(isSelected), [true, false, false], 'First tab is selected') assert.deepStrictEqual(panels.map(isHidden), [false, true, true], 'First panel is visible') assert.equal(document.activeElement, tabs[0]) + assert.equal(tabContainer.activeTab, tabs[0]) + assert.equal(tabContainer.selectedTabIndex, 0) assert.equal(events.length, 2, 'tab-container-change(d) called') assert.deepStrictEqual( events.map(e => e.type), @@ -461,6 +471,8 @@ describe('tab-container', function () { assert.deepStrictEqual(tabs.map(isSelected), [false, true, false], 'Second tab is selected') assert.deepStrictEqual(panels.map(isHidden), [true, false, true], 'Second panel is visible') assert.equal(document.activeElement, tabs[1]) + assert.equal(tabContainer.activetab, tabs[1]) + assert.equal(tabContainer.selectedTabIndex, 1) assert.equal(events.length, 2, 'tab-container-change(d) called') assert.deepStrictEqual( events.map(e => e.type), @@ -483,6 +495,8 @@ describe('tab-container', function () { assert.deepStrictEqual(tabs.map(isSelected), [false, false, true], 'Third tab is selected') assert.deepStrictEqual(panels.map(isHidden), [true, true, false], 'Third panel is visible') assert.equal(document.activeElement, tabs[2]) + assert.equal(tabContainer.activetab, tabs[2]) + assert.equal(tabContainer.selectedTabIndex, 2) assert.equal(events.length, 2, 'tab-container-change(d) called') assert.deepStrictEqual( events.map(e => e.type), @@ -506,6 +520,8 @@ describe('tab-container', function () { assert.deepStrictEqual(tabs.map(isSelected), [false, false, true], 'Third tab is selected') assert.deepStrictEqual(panels.map(isHidden), [true, true, false], 'Third panel is visible') assert.equal(document.activeElement, tabs[2]) + assert.equal(tabContainer.activetab, tabs[2]) + assert.equal(tabContainer.selectedTabIndex, 2) assert.equal(events.length, 2, 'tab-container-change(d) called') assert.deepStrictEqual( events.map(e => e.type), @@ -528,6 +544,8 @@ describe('tab-container', function () { assert.deepStrictEqual(tabs.map(isSelected), [true, false, false], 'First tab is selected') assert.deepStrictEqual(panels.map(isHidden), [false, true, true], 'First panel is visible') assert.equal(document.activeElement, tabs[0]) + assert.equal(tabContainer.activetab, tabs[0]) + assert.equal(tabContainer.selectedTabIndex, 0) assert.equal(events.length, 2, 'tab-container-change(d) called') assert.deepStrictEqual( events.map(e => e.type), @@ -550,6 +568,8 @@ describe('tab-container', function () { assert.deepStrictEqual(tabs.map(isSelected), [false, true, false], 'Second tab is selected') assert.deepStrictEqual(panels.map(isHidden), [true, false, true], 'Second panel is visible') assert.equal(document.activeElement, tabs[1]) + assert.equal(tabContainer.activetab, tabs[1]) + assert.equal(tabContainer.selectedTabIndex, 1) assert.equal(events.length, 2, 'tab-container-change(d) called') assert.deepStrictEqual( events.map(e => e.type), @@ -572,6 +592,8 @@ describe('tab-container', function () { assert.deepStrictEqual(tabs.map(isSelected), [false, false, true], 'Third tab is selected') assert.deepStrictEqual(panels.map(isHidden), [true, true, false], 'Third panel is visible') assert.equal(document.activeElement, tabs[2]) + assert.equal(tabContainer.activetab, tabs[2]) + assert.equal(tabContainer.selectedTabIndex, 2) assert.equal(events.length, 2, 'tab-container-change(d) called') assert.deepStrictEqual( events.map(e => e.type),