|
1 | 1 | const HTMLElement = globalThis.HTMLElement || (null as unknown as (typeof window)['HTMLElement'])
|
| 2 | +const manualSlotsSupported = 'assign' in HTMLSlotElement.prototype |
2 | 3 |
|
3 | 4 | export class TabContainerChangeEvent extends Event {
|
4 | 5 | constructor(type: string, {tab, panel, ...init}: EventInit & {tab?: Element; panel?: Element}) {
|
@@ -132,16 +133,21 @@ export class TabContainerElement extends HTMLElement {
|
132 | 133 | tabListContainer.style.display = 'flex'
|
133 | 134 | const tabListSlot = document.createElement('slot')
|
134 | 135 | tabListSlot.setAttribute('part', 'tablist')
|
| 136 | + tabListSlot.setAttribute('name', 'tablist') |
135 | 137 | const panelSlot = document.createElement('slot')
|
136 | 138 | panelSlot.setAttribute('part', 'panel')
|
| 139 | + panelSlot.setAttribute('name', 'panel') |
137 | 140 | panelSlot.setAttribute('role', 'presentation')
|
138 | 141 | const beforeTabSlot = document.createElement('slot')
|
139 | 142 | beforeTabSlot.setAttribute('part', 'before-tabs')
|
| 143 | + beforeTabSlot.setAttribute('name', 'before-tabs') |
140 | 144 | const afterTabSlot = document.createElement('slot')
|
141 | 145 | afterTabSlot.setAttribute('part', 'after-tabs')
|
| 146 | + afterTabSlot.setAttribute('name', 'after-tabs') |
142 | 147 | tabListContainer.append(beforeTabSlot, tabListSlot, afterTabSlot)
|
143 | 148 | const afterSlot = document.createElement('slot')
|
144 | 149 | afterSlot.setAttribute('part', 'after-panels')
|
| 150 | + afterSlot.setAttribute('name', 'after-panels') |
145 | 151 | shadowRoot.replaceChildren(tabListContainer, panelSlot, afterSlot)
|
146 | 152 |
|
147 | 153 | if (this.#internals && 'role' in this.#internals) {
|
@@ -217,9 +223,19 @@ export class TabContainerElement extends HTMLElement {
|
217 | 223 | const tabListSlot = this.#tabListSlot
|
218 | 224 | const customTabList = this.querySelector('[role=tablist]')
|
219 | 225 | 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 | + } |
221 | 231 | } 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 | + } |
223 | 239 | tabListSlot.role = 'tablist'
|
224 | 240 | tabListSlot.style.display = 'block'
|
225 | 241 | }
|
@@ -250,9 +266,15 @@ export class TabContainerElement extends HTMLElement {
|
250 | 266 | autoSlotted.push(child)
|
251 | 267 | }
|
252 | 268 | }
|
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 | + } |
256 | 278 | const defaultTab = Number(this.getAttribute('default-tab') || -1)
|
257 | 279 | const defaultIndex = defaultTab >= 0 ? defaultTab : this.#tabs.findIndex(el => el.matches('[aria-selected=true]'))
|
258 | 280 | index = index >= 0 ? index : Math.max(0, defaultIndex)
|
@@ -293,11 +315,18 @@ export class TabContainerElement extends HTMLElement {
|
293 | 315 | if (!panel.hasAttribute('tabindex') && !panel.hasAttribute('data-tab-container-no-tabstop')) {
|
294 | 316 | panel.setAttribute('tabindex', '0')
|
295 | 317 | }
|
| 318 | + if (!manualSlotsSupported && panel.hasAttribute('slot')) { |
| 319 | + panel.removeAttribute('slot') |
| 320 | + } |
296 | 321 | }
|
297 | 322 |
|
298 | 323 | selectedTab.setAttribute('aria-selected', 'true')
|
299 | 324 | 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 | + } |
301 | 330 | selectedPanel.hidden = false
|
302 | 331 |
|
303 | 332 | if (this.#setupComplete) {
|
|
0 commit comments