Skip to content

Commit 47345a3

Browse files
authored
Merge pull request #82 from github/ensure-support-for-browsers-without-manual-slot-assignment
ensure support for browsers without manual slot assignment
2 parents 7a12588 + f24eac6 commit 47345a3

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed

src/tab-container-element.ts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const HTMLElement = globalThis.HTMLElement || (null as unknown as (typeof window)['HTMLElement'])
2+
const manualSlotsSupported = 'assign' in HTMLSlotElement.prototype
23

34
export class TabContainerChangeEvent extends Event {
45
constructor(type: string, {tab, panel, ...init}: EventInit & {tab?: Element; panel?: Element}) {
@@ -133,16 +134,21 @@ export class TabContainerElement extends HTMLElement {
133134
tabListContainer.setAttribute('part', 'tablist-wrapper')
134135
const tabListSlot = document.createElement('slot')
135136
tabListSlot.setAttribute('part', 'tablist')
137+
tabListSlot.setAttribute('name', 'tablist')
136138
const panelSlot = document.createElement('slot')
137139
panelSlot.setAttribute('part', 'panel')
140+
panelSlot.setAttribute('name', 'panel')
138141
panelSlot.setAttribute('role', 'presentation')
139142
const beforeTabSlot = document.createElement('slot')
140143
beforeTabSlot.setAttribute('part', 'before-tabs')
144+
beforeTabSlot.setAttribute('name', 'before-tabs')
141145
const afterTabSlot = document.createElement('slot')
142146
afterTabSlot.setAttribute('part', 'after-tabs')
147+
afterTabSlot.setAttribute('name', 'after-tabs')
143148
tabListContainer.append(beforeTabSlot, tabListSlot, afterTabSlot)
144149
const afterSlot = document.createElement('slot')
145150
afterSlot.setAttribute('part', 'after-panels')
151+
afterSlot.setAttribute('name', 'after-panels')
146152
shadowRoot.replaceChildren(tabListContainer, panelSlot, afterSlot)
147153

148154
if (this.#internals && 'role' in this.#internals) {
@@ -218,9 +224,19 @@ export class TabContainerElement extends HTMLElement {
218224
const tabListSlot = this.#tabListSlot
219225
const customTabList = this.querySelector('[role=tablist]')
220226
if (customTabList && customTabList.closest(this.tagName) === this) {
221-
tabListSlot.assign(customTabList)
227+
if (manualSlotsSupported) {
228+
tabListSlot.assign(customTabList)
229+
} else {
230+
customTabList.setAttribute('slot', 'tablist')
231+
}
222232
} else {
223-
tabListSlot.assign(...[...this.children].filter(e => e.matches('[role=tab]')))
233+
if (manualSlotsSupported) {
234+
tabListSlot.assign(...[...this.children].filter(e => e.matches('[role=tab]')))
235+
} else {
236+
for (const e of this.children) {
237+
if (e.matches('[role=tab]')) e.setAttribute('slot', 'tablist')
238+
}
239+
}
224240
tabListSlot.role = 'tablist'
225241
tabListSlot.style.display = 'block'
226242
}
@@ -251,9 +267,15 @@ export class TabContainerElement extends HTMLElement {
251267
autoSlotted.push(child)
252268
}
253269
}
254-
this.#beforeTabsSlot.assign(...beforeSlotted)
255-
this.#afterTabsSlot.assign(...afterTabSlotted)
256-
this.#afterPanelsSlot.assign(...afterSlotted)
270+
if (manualSlotsSupported) {
271+
this.#beforeTabsSlot.assign(...beforeSlotted)
272+
this.#afterTabsSlot.assign(...afterTabSlotted)
273+
this.#afterPanelsSlot.assign(...afterSlotted)
274+
} else {
275+
for (const el of beforeSlotted) el.setAttribute('slot', 'before-tabs')
276+
for (const el of afterTabSlotted) el.setAttribute('slot', 'after-tabs')
277+
for (const el of afterSlotted) el.setAttribute('slot', 'after-panels')
278+
}
257279
const defaultTab = Number(this.getAttribute('default-tab') || -1)
258280
const defaultIndex = defaultTab >= 0 ? defaultTab : this.#tabs.findIndex(el => el.matches('[aria-selected=true]'))
259281
index = index >= 0 ? index : Math.max(0, defaultIndex)
@@ -294,11 +316,18 @@ export class TabContainerElement extends HTMLElement {
294316
if (!panel.hasAttribute('tabindex') && !panel.hasAttribute('data-tab-container-no-tabstop')) {
295317
panel.setAttribute('tabindex', '0')
296318
}
319+
if (!manualSlotsSupported && panel.hasAttribute('slot')) {
320+
panel.removeAttribute('slot')
321+
}
297322
}
298323

299324
selectedTab.setAttribute('aria-selected', 'true')
300325
selectedTab.setAttribute('tabindex', '0')
301-
this.#panelSlot.assign(selectedPanel)
326+
if (manualSlotsSupported) {
327+
this.#panelSlot.assign(selectedPanel)
328+
} else {
329+
selectedPanel.setAttribute('slot', 'panel')
330+
}
302331
selectedPanel.hidden = false
303332

304333
if (this.#setupComplete) {

0 commit comments

Comments
 (0)