@@ -178,6 +178,12 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
178178 // sub-tree and no node in the entire tree can be focused
179179 const previousNode = this . subTree . querySelector ( "[tabindex='0']" )
180180 previousNode ?. setAttribute ( 'tabindex' , '-1' )
181+
182+ // Also check if the subtree element itself is an include-fragment with role="treeitem" and has focus
183+ if ( this . #isIncludeFragment( ) && this . subTree . getAttribute ( 'tabindex' ) === '0' ) {
184+ this . subTree . setAttribute ( 'tabindex' , '-1' )
185+ }
186+
181187 this . node . setAttribute ( 'tabindex' , '0' )
182188
183189 this . treeView . dispatchEvent (
@@ -263,6 +269,10 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
263269 // request succeeded but element has not yet been replaced
264270 case 'include-fragment-replace' :
265271 this . #activeElementIsLoader = document . activeElement === this . loadingIndicator . closest ( '[role=treeitem]' )
272+ // Also check if the include-fragment itself has focus (when it has role="treeitem")
273+ if ( ! this . #activeElementIsLoader && document . activeElement === this . subTree && this . #isIncludeFragment( ) ) {
274+ this . #activeElementIsLoader = true
275+ }
266276 this . loadingState = 'success'
267277 break
268278
@@ -410,6 +420,13 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
410420 #update( ) {
411421 if ( this . expanded ) {
412422 if ( this . subTree ) this . subTree . hidden = false
423+ if ( this . #isIncludeFragment( ) ) {
424+ this . subTree . setAttribute ( 'role' , 'treeitem' )
425+ // Ensure the include-fragment can participate in roving tab index
426+ if ( ! this . subTree . hasAttribute ( 'tabindex' ) ) {
427+ this . subTree . setAttribute ( 'tabindex' , '-1' )
428+ }
429+ }
413430 this . node . setAttribute ( 'aria-expanded' , 'true' )
414431 this . treeView ?. expandAncestorsForNode ( this )
415432
@@ -423,6 +440,11 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
423440 }
424441 } else {
425442 if ( this . subTree ) this . subTree . hidden = true
443+ if ( this . #isIncludeFragment( ) ) {
444+ this . subTree . removeAttribute ( 'role' )
445+ // Remove tabindex when role is removed
446+ this . subTree . removeAttribute ( 'tabindex' )
447+ }
426448 this . node . setAttribute ( 'aria-expanded' , 'false' )
427449
428450 if ( this . iconPair ) {
@@ -453,6 +475,10 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
453475 }
454476 }
455477
478+ #isIncludeFragment( ) : boolean {
479+ return this . subTree ?. getAttribute ( 'data-target' ) ?. includes ( 'tree-view-sub-tree-node.includeFragment' ) ?? false
480+ }
481+
456482 get #checkboxElement( ) : HTMLElement | null {
457483 return this . querySelector ( '.TreeViewItemCheckbox' )
458484 }
0 commit comments