@@ -95,6 +95,10 @@ export class TabContainerElement extends HTMLElement {
95
95
static observedAttributes = [ 'vertical' ]
96
96
97
97
get #tabList( ) {
98
+ const wrapper = this . querySelector ( '[slot=tablist-wrapper],[slot=tablist-tab-wrapper]' )
99
+ if ( wrapper ?. closest ( this . tagName ) === this ) {
100
+ return wrapper . querySelector ( '[role=tablist]' ) as HTMLElement
101
+ }
98
102
const slot = this . #tabListSlot
99
103
if ( this . #tabListTabWrapper. hasAttribute ( 'role' ) ) {
100
104
return this . #tabListTabWrapper
@@ -103,6 +107,10 @@ export class TabContainerElement extends HTMLElement {
103
107
}
104
108
}
105
109
110
+ get #tabListWrapper( ) {
111
+ return this . shadowRoot ! . querySelector < HTMLSlotElement > ( 'slot[part="tablist-wrapper"]' ) !
112
+ }
113
+
106
114
get #tabListTabWrapper( ) {
107
115
return this . shadowRoot ! . querySelector < HTMLSlotElement > ( 'slot[part="tablist-tab-wrapper"]' ) !
108
116
}
@@ -162,9 +170,10 @@ export class TabContainerElement extends HTMLElement {
162
170
connectedCallback ( ) : void {
163
171
this . #internals ||= this . attachInternals ? this . attachInternals ( ) : null
164
172
const shadowRoot = this . shadowRoot || this . attachShadow ( { mode : 'open' , slotAssignment : 'manual' } )
165
- const tabListContainer = document . createElement ( 'div ' )
173
+ const tabListContainer = document . createElement ( 'slot ' )
166
174
tabListContainer . style . display = 'flex'
167
175
tabListContainer . setAttribute ( 'part' , 'tablist-wrapper' )
176
+ tabListContainer . setAttribute ( 'name' , 'tablist-wrapper' )
168
177
const tabListTabWrapper = document . createElement ( 'slot' )
169
178
tabListTabWrapper . setAttribute ( 'part' , 'tablist-tab-wrapper' )
170
179
tabListTabWrapper . setAttribute ( 'name' , 'tablist-tab-wrapper' )
@@ -275,13 +284,22 @@ export class TabContainerElement extends HTMLElement {
275
284
selectTab ( index : number ) : void {
276
285
if ( ! this . #setupComplete) {
277
286
const tabListSlot = this . #tabListSlot
287
+ const tabListWrapper = this . #tabListWrapper
288
+ const tabListTabWrapper = this . #tabListTabWrapper
278
289
const customTabList = this . querySelector ( '[role=tablist]' )
279
- const customTabListWrapper = this . querySelector ( '[slot=tablist-tab-wrapper]' )
290
+ const customTabListWrapper = this . querySelector ( '[slot=tablist-wrapper]' )
291
+ const customTabListTabWrapper = this . querySelector ( '[slot=tablist-tab-wrapper]' )
280
292
if ( customTabListWrapper && customTabListWrapper . closest ( this . tagName ) === this ) {
281
293
if ( manualSlotsSupported ) {
282
- tabListSlot . assign ( customTabListWrapper )
294
+ tabListWrapper . assign ( customTabListWrapper )
283
295
} else {
284
- customTabListWrapper . setAttribute ( 'slot' , 'tablist' )
296
+ customTabListWrapper . setAttribute ( 'slot' , 'tablist-wrapper' )
297
+ }
298
+ } else if ( customTabListTabWrapper && customTabListTabWrapper . closest ( this . tagName ) === this ) {
299
+ if ( manualSlotsSupported ) {
300
+ tabListTabWrapper . assign ( customTabListTabWrapper )
301
+ } else {
302
+ customTabListTabWrapper . setAttribute ( 'slot' , 'tablist-tab-wrapper' )
285
303
}
286
304
} else if ( customTabList && customTabList . closest ( this . tagName ) === this ) {
287
305
if ( manualSlotsSupported ) {
@@ -305,40 +323,43 @@ export class TabContainerElement extends HTMLElement {
305
323
if ( this . vertical ) {
306
324
this . #tabList. setAttribute ( 'aria-orientation' , 'vertical' )
307
325
}
308
- const beforeSlotted : Element [ ] = [ ]
309
- const afterTabSlotted : Element [ ] = [ ]
310
- const afterSlotted : Element [ ] = [ ]
311
- let autoSlotted = beforeSlotted
312
- for ( const child of this . children ) {
313
- if (
314
- child . getAttribute ( 'role' ) === 'tab' ||
315
- child . getAttribute ( 'role' ) === 'tablist' ||
316
- child . getAttribute ( 'slot' ) === 'tablist-tab-wrapper'
317
- ) {
318
- autoSlotted = afterTabSlotted
319
- continue
320
- }
321
- if ( child . getAttribute ( 'role' ) === 'tabpanel' ) {
322
- autoSlotted = afterSlotted
323
- continue
326
+ const bringsOwnWrapper = this . querySelector ( '[slot=tablist-wrapper]' ) ?. closest ( this . tagName ) === this
327
+ if ( ! bringsOwnWrapper ) {
328
+ const beforeSlotted : Element [ ] = [ ]
329
+ const afterTabSlotted : Element [ ] = [ ]
330
+ const afterSlotted : Element [ ] = [ ]
331
+ let autoSlotted = beforeSlotted
332
+ for ( const child of this . children ) {
333
+ if (
334
+ child . getAttribute ( 'role' ) === 'tab' ||
335
+ child . getAttribute ( 'role' ) === 'tablist' ||
336
+ child . getAttribute ( 'slot' ) === 'tablist-tab-wrapper'
337
+ ) {
338
+ autoSlotted = afterTabSlotted
339
+ continue
340
+ }
341
+ if ( child . getAttribute ( 'role' ) === 'tabpanel' ) {
342
+ autoSlotted = afterSlotted
343
+ continue
344
+ }
345
+ if ( child . getAttribute ( 'slot' ) === 'before-tabs' ) {
346
+ beforeSlotted . push ( child )
347
+ } else if ( child . getAttribute ( 'slot' ) === 'after-tabs' ) {
348
+ afterTabSlotted . push ( child )
349
+ } else {
350
+ autoSlotted . push ( child )
351
+ }
324
352
}
325
- if ( child . getAttribute ( 'slot' ) === 'before-tabs' ) {
326
- beforeSlotted . push ( child )
327
- } else if ( child . getAttribute ( 'slot' ) === 'after-tabs' ) {
328
- afterTabSlotted . push ( child )
353
+ if ( manualSlotsSupported ) {
354
+ this . #beforeTabsSlot . assign ( ... beforeSlotted )
355
+ this . #afterTabsSlot . assign ( ... afterTabSlotted )
356
+ this . #afterPanelsSlot . assign ( ... afterSlotted )
329
357
} else {
330
- autoSlotted . push ( child )
358
+ for ( const el of beforeSlotted ) el . setAttribute ( 'slot' , 'before-tabs' )
359
+ for ( const el of afterTabSlotted ) el . setAttribute ( 'slot' , 'after-tabs' )
360
+ for ( const el of afterSlotted ) el . setAttribute ( 'slot' , 'after-panels' )
331
361
}
332
362
}
333
- if ( manualSlotsSupported ) {
334
- this . #beforeTabsSlot. assign ( ...beforeSlotted )
335
- this . #afterTabsSlot. assign ( ...afterTabSlotted )
336
- this . #afterPanelsSlot. assign ( ...afterSlotted )
337
- } else {
338
- for ( const el of beforeSlotted ) el . setAttribute ( 'slot' , 'before-tabs' )
339
- for ( const el of afterTabSlotted ) el . setAttribute ( 'slot' , 'after-tabs' )
340
- for ( const el of afterSlotted ) el . setAttribute ( 'slot' , 'after-panels' )
341
- }
342
363
const defaultTab = this . defaultTabIndex
343
364
const defaultIndex = defaultTab >= 0 ? defaultTab : this . selectedTabIndex
344
365
index = index >= 0 ? index : Math . max ( 0 , defaultIndex )
0 commit comments