Skip to content

Commit 66334bc

Browse files
authored
Merge pull request #90 from github/slot-tablist-wrapper
Custom tablist-tab-wrapper
2 parents 21f1e2b + 2a0e8d2 commit 66334bc

File tree

3 files changed

+87
-5
lines changed

3 files changed

+87
-5
lines changed

examples/index.html

+22-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,27 @@ <h2>Horizontal (custom tablist)</h2>
4646
</div>
4747
</tab-container>
4848

49+
<h2>Horizontal (custom tablist and tablist-wrapper)</h2>
50+
51+
<tab-container>
52+
<div slot="tablist-tab-wrapper">
53+
<div role="tablist" aria-label="Horizontal Tabs Example">
54+
<button type="button" id="tab-one" role="tab">Tab one</button>
55+
<button type="button" id="tab-two" role="tab">Tab two</button>
56+
<button type="button" id="tab-three" role="tab">Tab three</button>
57+
</div>
58+
</div>
59+
<div role="tabpanel" aria-labelledby="tab-one">
60+
Panel 1
61+
</div>
62+
<div role="tabpanel" aria-labelledby="tab-two" hidden>
63+
Panel 2
64+
</div>
65+
<div role="tabpanel" aria-labelledby="tab-three" hidden>
66+
Panel 3
67+
</div>
68+
</tab-container>
69+
4970
<h2>Vertical (shadow tablist)</h2>
5071

5172
<tab-container>
@@ -140,7 +161,7 @@ <h2>Panel with extra buttons</h2>
140161

141162
</main>
142163

143-
<!--<script src="../dist/index.js" type="module"></script>-->
164+
<!-- <script src="../dist/index.js" type="module"></script> -->
144165
<script src="https://unpkg.com/@github/tab-container-element@latest/dist/index.js" type="module"></script>
145166
</body>
146167
</html>

src/tab-container-element.ts

+16-4
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export class TabContainerElement extends HTMLElement {
104104
}
105105

106106
get #tabListTabWrapper() {
107-
return this.shadowRoot!.querySelector<HTMLSlotElement>('div[part="tablist-tab-wrapper"]')!
107+
return this.shadowRoot!.querySelector<HTMLSlotElement>('slot[part="tablist-tab-wrapper"]')!
108108
}
109109

110110
get #beforeTabsSlot() {
@@ -165,8 +165,9 @@ export class TabContainerElement extends HTMLElement {
165165
const tabListContainer = document.createElement('div')
166166
tabListContainer.style.display = 'flex'
167167
tabListContainer.setAttribute('part', 'tablist-wrapper')
168-
const tabListTabWrapper = document.createElement('div')
168+
const tabListTabWrapper = document.createElement('slot')
169169
tabListTabWrapper.setAttribute('part', 'tablist-tab-wrapper')
170+
tabListTabWrapper.setAttribute('name', 'tablist-tab-wrapper')
170171
const tabListSlot = document.createElement('slot')
171172
tabListSlot.setAttribute('part', 'tablist')
172173
tabListSlot.setAttribute('name', 'tablist')
@@ -275,7 +276,14 @@ export class TabContainerElement extends HTMLElement {
275276
if (!this.#setupComplete) {
276277
const tabListSlot = this.#tabListSlot
277278
const customTabList = this.querySelector('[role=tablist]')
278-
if (customTabList && customTabList.closest(this.tagName) === this) {
279+
const customTabListWrapper = this.querySelector('[slot=tablist-tab-wrapper]')
280+
if (customTabListWrapper && customTabListWrapper.closest(this.tagName) === this) {
281+
if (manualSlotsSupported) {
282+
tabListSlot.assign(customTabListWrapper)
283+
} else {
284+
customTabListWrapper.setAttribute('slot', 'tablist')
285+
}
286+
} else if (customTabList && customTabList.closest(this.tagName) === this) {
279287
if (manualSlotsSupported) {
280288
tabListSlot.assign(customTabList)
281289
} else {
@@ -302,7 +310,11 @@ export class TabContainerElement extends HTMLElement {
302310
const afterSlotted: Element[] = []
303311
let autoSlotted = beforeSlotted
304312
for (const child of this.children) {
305-
if (child.getAttribute('role') === 'tab' || child.getAttribute('role') === 'tablist') {
313+
if (
314+
child.getAttribute('role') === 'tab' ||
315+
child.getAttribute('role') === 'tablist' ||
316+
child.getAttribute('slot') === 'tablist-tab-wrapper'
317+
) {
306318
autoSlotted = afterTabSlotted
307319
continue
308320
}

test/test.js

+49
Original file line numberDiff line numberDiff line change
@@ -669,4 +669,53 @@ describe('tab-container', function () {
669669
)
670670
})
671671
})
672+
describe('with custom tablist-tab-wrapper', function () {
673+
beforeEach(function () {
674+
document.body.innerHTML = `
675+
<tab-container>
676+
<div slot="tablist-tab-wrapper">
677+
<div role="tablist">
678+
<button type="button" role="tab">Tab one</button>
679+
<button type="button" role="tab" aria-selected="true">Tab two</button>
680+
<button type="button" role="tab">Tab three</button>
681+
</div>
682+
</div>
683+
<div role="tabpanel" hidden>
684+
Panel 1
685+
</div>
686+
<div role="tabpanel">
687+
Panel 2
688+
</div>
689+
<div role="tabpanel" hidden data-tab-container-no-tabstop>
690+
Panel 3
691+
</div>
692+
</tab-container>
693+
`
694+
tabs = Array.from(document.querySelectorAll('button'))
695+
panels = Array.from(document.querySelectorAll('[role="tabpanel"]'))
696+
})
697+
698+
afterEach(function () {
699+
// Check to make sure we still have accessible markup after the test finishes running.
700+
expect(document.body).to.be.accessible()
701+
702+
document.body.innerHTML = ''
703+
})
704+
705+
it('has accessible markup', function () {
706+
expect(document.body).to.be.accessible()
707+
})
708+
709+
it('the second tab is still selected', function () {
710+
assert.deepStrictEqual(tabs.map(isSelected), [false, true, false], 'Second tab is selected')
711+
assert.deepStrictEqual(panels.map(isHidden), [true, false, true], 'Second panel is visible')
712+
})
713+
714+
it('selects the clicked tab', function () {
715+
tabs[0].click()
716+
717+
assert.deepStrictEqual(tabs.map(isSelected), [true, false, false], 'First tab is selected')
718+
assert.deepStrictEqual(panels.map(isHidden), [false, true, true], 'First panel is visible')
719+
})
720+
})
672721
})

0 commit comments

Comments
 (0)