|
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}) {
|
@@ -133,16 +134,21 @@ export class TabContainerElement extends HTMLElement {
|
133 | 134 | tabListContainer.setAttribute('part', 'tablist-wrapper')
|
134 | 135 | const tabListSlot = document.createElement('slot')
|
135 | 136 | tabListSlot.setAttribute('part', 'tablist')
|
| 137 | + tabListSlot.setAttribute('name', 'tablist') |
136 | 138 | const panelSlot = document.createElement('slot')
|
137 | 139 | panelSlot.setAttribute('part', 'panel')
|
| 140 | + panelSlot.setAttribute('name', 'panel') |
138 | 141 | panelSlot.setAttribute('role', 'presentation')
|
139 | 142 | const beforeTabSlot = document.createElement('slot')
|
140 | 143 | beforeTabSlot.setAttribute('part', 'before-tabs')
|
| 144 | + beforeTabSlot.setAttribute('name', 'before-tabs') |
141 | 145 | const afterTabSlot = document.createElement('slot')
|
142 | 146 | afterTabSlot.setAttribute('part', 'after-tabs')
|
| 147 | + afterTabSlot.setAttribute('name', 'after-tabs') |
143 | 148 | tabListContainer.append(beforeTabSlot, tabListSlot, afterTabSlot)
|
144 | 149 | const afterSlot = document.createElement('slot')
|
145 | 150 | afterSlot.setAttribute('part', 'after-panels')
|
| 151 | + afterSlot.setAttribute('name', 'after-panels') |
146 | 152 | shadowRoot.replaceChildren(tabListContainer, panelSlot, afterSlot)
|
147 | 153 |
|
148 | 154 | if (this.#internals && 'role' in this.#internals) {
|
@@ -218,9 +224,19 @@ export class TabContainerElement extends HTMLElement {
|
218 | 224 | const tabListSlot = this.#tabListSlot
|
219 | 225 | const customTabList = this.querySelector('[role=tablist]')
|
220 | 226 | 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 | + } |
222 | 232 | } 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 | + } |
224 | 240 | tabListSlot.role = 'tablist'
|
225 | 241 | tabListSlot.style.display = 'block'
|
226 | 242 | }
|
@@ -251,9 +267,15 @@ export class TabContainerElement extends HTMLElement {
|
251 | 267 | autoSlotted.push(child)
|
252 | 268 | }
|
253 | 269 | }
|
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 | + } |
257 | 279 | const defaultTab = Number(this.getAttribute('default-tab') || -1)
|
258 | 280 | const defaultIndex = defaultTab >= 0 ? defaultTab : this.#tabs.findIndex(el => el.matches('[aria-selected=true]'))
|
259 | 281 | index = index >= 0 ? index : Math.max(0, defaultIndex)
|
@@ -294,11 +316,18 @@ export class TabContainerElement extends HTMLElement {
|
294 | 316 | if (!panel.hasAttribute('tabindex') && !panel.hasAttribute('data-tab-container-no-tabstop')) {
|
295 | 317 | panel.setAttribute('tabindex', '0')
|
296 | 318 | }
|
| 319 | + if (!manualSlotsSupported && panel.hasAttribute('slot')) { |
| 320 | + panel.removeAttribute('slot') |
| 321 | + } |
297 | 322 | }
|
298 | 323 |
|
299 | 324 | selectedTab.setAttribute('aria-selected', 'true')
|
300 | 325 | 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 | + } |
302 | 331 | selectedPanel.hidden = false
|
303 | 332 |
|
304 | 333 | if (this.#setupComplete) {
|
|
0 commit comments