diff --git a/examples/index.html b/examples/index.html index 4e3553e..e752ef6 100644 --- a/examples/index.html +++ b/examples/index.html @@ -46,6 +46,27 @@

Horizontal (custom tablist)

+

Horizontal (custom tablist and tablist-wrapper)

+ + +
+
+ + + +
+
+
+ Panel 1 +
+ + +
+

Vertical (shadow tablist)

@@ -140,7 +161,7 @@

Panel with extra buttons

- + diff --git a/src/tab-container-element.ts b/src/tab-container-element.ts index 831409d..bdd9f1a 100644 --- a/src/tab-container-element.ts +++ b/src/tab-container-element.ts @@ -104,7 +104,7 @@ export class TabContainerElement extends HTMLElement { } get #tabListTabWrapper() { - return this.shadowRoot!.querySelector('div[part="tablist-tab-wrapper"]')! + return this.shadowRoot!.querySelector('slot[part="tablist-tab-wrapper"]')! } get #beforeTabsSlot() { @@ -165,8 +165,9 @@ export class TabContainerElement extends HTMLElement { const tabListContainer = document.createElement('div') tabListContainer.style.display = 'flex' tabListContainer.setAttribute('part', 'tablist-wrapper') - const tabListTabWrapper = document.createElement('div') + const tabListTabWrapper = document.createElement('slot') tabListTabWrapper.setAttribute('part', 'tablist-tab-wrapper') + tabListTabWrapper.setAttribute('name', 'tablist-tab-wrapper') const tabListSlot = document.createElement('slot') tabListSlot.setAttribute('part', 'tablist') tabListSlot.setAttribute('name', 'tablist') @@ -275,7 +276,14 @@ export class TabContainerElement extends HTMLElement { if (!this.#setupComplete) { const tabListSlot = this.#tabListSlot const customTabList = this.querySelector('[role=tablist]') - if (customTabList && customTabList.closest(this.tagName) === this) { + const customTabListWrapper = this.querySelector('[slot=tablist-tab-wrapper]') + if (customTabListWrapper && customTabListWrapper.closest(this.tagName) === this) { + if (manualSlotsSupported) { + tabListSlot.assign(customTabListWrapper) + } else { + customTabListWrapper.setAttribute('slot', 'tablist') + } + } else if (customTabList && customTabList.closest(this.tagName) === this) { if (manualSlotsSupported) { tabListSlot.assign(customTabList) } else { @@ -302,7 +310,11 @@ export class TabContainerElement extends HTMLElement { const afterSlotted: Element[] = [] let autoSlotted = beforeSlotted for (const child of this.children) { - if (child.getAttribute('role') === 'tab' || child.getAttribute('role') === 'tablist') { + if ( + child.getAttribute('role') === 'tab' || + child.getAttribute('role') === 'tablist' || + child.getAttribute('slot') === 'tablist-tab-wrapper' + ) { autoSlotted = afterTabSlotted continue } diff --git a/test/test.js b/test/test.js index 441aa41..28cb708 100644 --- a/test/test.js +++ b/test/test.js @@ -669,4 +669,53 @@ describe('tab-container', function () { ) }) }) + describe('with custom tablist-tab-wrapper', function () { + beforeEach(function () { + document.body.innerHTML = ` + +
+
+ + + +
+
+ +
+ Panel 2 +
+ +
+ ` + tabs = Array.from(document.querySelectorAll('button')) + panels = Array.from(document.querySelectorAll('[role="tabpanel"]')) + }) + + afterEach(function () { + // Check to make sure we still have accessible markup after the test finishes running. + expect(document.body).to.be.accessible() + + document.body.innerHTML = '' + }) + + it('has accessible markup', function () { + expect(document.body).to.be.accessible() + }) + + it('the second tab is still selected', 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') + }) + + it('selects the clicked tab', function () { + tabs[0].click() + + assert.deepStrictEqual(tabs.map(isSelected), [true, false, false], 'First tab is selected') + assert.deepStrictEqual(panels.map(isHidden), [false, true, true], 'First panel is visible') + }) + }) })