Skip to content

Commit f24eac6

Browse files
committed
ensure support for browsers without manual slot assignment
1 parent 8ff3dbe commit f24eac6

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}) {
@@ -132,16 +133,21 @@ export class TabContainerElement extends HTMLElement {
132133
tabListContainer.style.display = 'flex'
133134
const tabListSlot = document.createElement('slot')
134135
tabListSlot.setAttribute('part', 'tablist')
136+
tabListSlot.setAttribute('name', 'tablist')
135137
const panelSlot = document.createElement('slot')
136138
panelSlot.setAttribute('part', 'panel')
139+
panelSlot.setAttribute('name', 'panel')
137140
panelSlot.setAttribute('role', 'presentation')
138141
const beforeTabSlot = document.createElement('slot')
139142
beforeTabSlot.setAttribute('part', 'before-tabs')
143+
beforeTabSlot.setAttribute('name', 'before-tabs')
140144
const afterTabSlot = document.createElement('slot')
141145
afterTabSlot.setAttribute('part', 'after-tabs')
146+
afterTabSlot.setAttribute('name', 'after-tabs')
142147
tabListContainer.append(beforeTabSlot, tabListSlot, afterTabSlot)
143148
const afterSlot = document.createElement('slot')
144149
afterSlot.setAttribute('part', 'after-panels')
150+
afterSlot.setAttribute('name', 'after-panels')
145151
shadowRoot.replaceChildren(tabListContainer, panelSlot, afterSlot)
146152

147153
if (this.#internals && 'role' in this.#internals) {
@@ -217,9 +223,19 @@ export class TabContainerElement extends HTMLElement {
217223
const tabListSlot = this.#tabListSlot
218224
const customTabList = this.querySelector('[role=tablist]')
219225
if (customTabList && customTabList.closest(this.tagName) === this) {
220-
tabListSlot.assign(customTabList)
226+
if (manualSlotsSupported) {
227+
tabListSlot.assign(customTabList)
228+
} else {
229+
customTabList.setAttribute('slot', 'tablist')
230+
}
221231
} else {
222-
tabListSlot.assign(...[...this.children].filter(e => e.matches('[role=tab]')))
232+
if (manualSlotsSupported) {
233+
tabListSlot.assign(...[...this.children].filter(e => e.matches('[role=tab]')))
234+
} else {
235+
for (const e of this.children) {
236+
if (e.matches('[role=tab]')) e.setAttribute('slot', 'tablist')
237+
}
238+
}
223239
tabListSlot.role = 'tablist'
224240
tabListSlot.style.display = 'block'
225241
}
@@ -250,9 +266,15 @@ export class TabContainerElement extends HTMLElement {
250266
autoSlotted.push(child)
251267
}
252268
}
253-
this.#beforeTabsSlot.assign(...beforeSlotted)
254-
this.#afterTabsSlot.assign(...afterTabSlotted)
255-
this.#afterPanelsSlot.assign(...afterSlotted)
269+
if (manualSlotsSupported) {
270+
this.#beforeTabsSlot.assign(...beforeSlotted)
271+
this.#afterTabsSlot.assign(...afterTabSlotted)
272+
this.#afterPanelsSlot.assign(...afterSlotted)
273+
} else {
274+
for (const el of beforeSlotted) el.setAttribute('slot', 'before-tabs')
275+
for (const el of afterTabSlotted) el.setAttribute('slot', 'after-tabs')
276+
for (const el of afterSlotted) el.setAttribute('slot', 'after-panels')
277+
}
256278
const defaultTab = Number(this.getAttribute('default-tab') || -1)
257279
const defaultIndex = defaultTab >= 0 ? defaultTab : this.#tabs.findIndex(el => el.matches('[aria-selected=true]'))
258280
index = index >= 0 ? index : Math.max(0, defaultIndex)
@@ -293,11 +315,18 @@ export class TabContainerElement extends HTMLElement {
293315
if (!panel.hasAttribute('tabindex') && !panel.hasAttribute('data-tab-container-no-tabstop')) {
294316
panel.setAttribute('tabindex', '0')
295317
}
318+
if (!manualSlotsSupported && panel.hasAttribute('slot')) {
319+
panel.removeAttribute('slot')
320+
}
296321
}
297322

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

303332
if (this.#setupComplete) {

0 commit comments

Comments
 (0)