@@ -77,6 +77,18 @@ export class TabContainerElement extends HTMLElement {
7777 }
7878 }
7979
80+ get #beforeTabsSlot( ) {
81+ return this . shadowRoot ! . querySelector < HTMLSlotElement > ( 'slot[part="before-tabs"]' ) !
82+ }
83+
84+ get #afterTabsSlot( ) {
85+ return this . shadowRoot ! . querySelector < HTMLSlotElement > ( 'slot[part="after-tabs"]' ) !
86+ }
87+
88+ get #afterPanelsSlot( ) {
89+ return this . shadowRoot ! . querySelector < HTMLSlotElement > ( 'slot[part="after-panels"]' ) !
90+ }
91+
8092 get #tabListSlot( ) {
8193 return this . shadowRoot ! . querySelector < HTMLSlotElement > ( 'slot[part="tablist"]' ) !
8294 }
@@ -94,8 +106,12 @@ export class TabContainerElement extends HTMLElement {
94106 )
95107 }
96108
109+ get activePanel ( ) {
110+ return this . #panelSlot. assignedNodes ( ) [ 0 ] as HTMLElement
111+ }
112+
97113 get vertical ( ) : boolean {
98- return this . #tabList. getAttribute ( 'aria-orientation' ) === 'vertical'
114+ return this . #tabList? .getAttribute ( 'aria-orientation' ) === 'vertical'
99115 }
100116
101117 set vertical ( isVertical : boolean ) {
@@ -112,12 +128,21 @@ export class TabContainerElement extends HTMLElement {
112128 connectedCallback ( ) : void {
113129 this . #internals ||= this . attachInternals ? this . attachInternals ( ) : null
114130 const shadowRoot = this . shadowRoot || this . attachShadow ( { mode : 'open' , slotAssignment : 'manual' } )
131+ const tabListContainer = document . createElement ( 'div' )
132+ tabListContainer . style . display = 'flex'
115133 const tabListSlot = document . createElement ( 'slot' )
116134 tabListSlot . setAttribute ( 'part' , 'tablist' )
117135 const panelSlot = document . createElement ( 'slot' )
118136 panelSlot . setAttribute ( 'part' , 'panel' )
119137 panelSlot . setAttribute ( 'role' , 'presentation' )
120- shadowRoot . replaceChildren ( tabListSlot , panelSlot )
138+ const beforeTabSlot = document . createElement ( 'slot' )
139+ beforeTabSlot . setAttribute ( 'part' , 'before-tabs' )
140+ const afterTabSlot = document . createElement ( 'slot' )
141+ afterTabSlot . setAttribute ( 'part' , 'after-tabs' )
142+ tabListContainer . append ( beforeTabSlot , tabListSlot , afterTabSlot )
143+ const afterSlot = document . createElement ( 'slot' )
144+ afterSlot . setAttribute ( 'part' , 'after-panels' )
145+ shadowRoot . replaceChildren ( tabListContainer , panelSlot , afterSlot )
121146
122147 if ( this . #internals && 'role' in this . #internals) {
123148 this . #internals. role = 'presentation'
@@ -186,7 +211,7 @@ export class TabContainerElement extends HTMLElement {
186211
187212 selectTab ( index : number ) : void {
188213 if ( ! this . #setup) {
189- const tabListSlot = this . #tabListSlot;
214+ const tabListSlot = this . #tabListSlot
190215 const customTabList = this . querySelector ( '[role=tablist]' )
191216 if ( customTabList && customTabList . closest ( this . tagName ) === this ) {
192217 tabListSlot . assign ( customTabList )
@@ -207,6 +232,30 @@ export class TabContainerElement extends HTMLElement {
207232 if ( this . vertical ) {
208233 this . #tabList. setAttribute ( 'aria-orientation' , 'vertical' )
209234 }
235+ const beforeSlotted : Element [ ] = [ ]
236+ const afterTabSlotted : Element [ ] = [ ]
237+ const afterSlotted : Element [ ] = [ ]
238+ let autoSlotted = beforeSlotted
239+ for ( const child of this . children ) {
240+ if ( child . getAttribute ( 'role' ) === 'tab' || child . getAttribute ( 'role' ) === 'tablist' ) {
241+ autoSlotted = afterTabSlotted
242+ continue
243+ }
244+ if ( child . getAttribute ( 'role' ) === 'tabpanel' ) {
245+ autoSlotted = afterSlotted
246+ continue
247+ }
248+ if ( child . getAttribute ( 'slot' ) === 'before-tabs' ) {
249+ beforeSlotted . push ( child )
250+ } else if ( child . getAttribute ( 'slot' ) === 'after-tabs' ) {
251+ afterTabSlotted . push ( child )
252+ } else {
253+ autoSlotted . push ( child )
254+ }
255+ }
256+ this . #beforeTabsSlot. assign ( ...beforeSlotted )
257+ this . #afterTabsSlot. assign ( ...afterTabSlotted )
258+ this . #afterPanelsSlot. assign ( ...afterSlotted )
210259 }
211260
212261 const tabs = this . #tabs
0 commit comments