@@ -110,7 +110,6 @@ type RenderingData<T> =
110
110
'class' : 'cdk-tree' ,
111
111
'role' : 'tree' ,
112
112
'(keydown)' : '_sendKeydownToKeyManager($event)' ,
113
- '(focus)' : '_focusInitialTreeItem()' ,
114
113
} ,
115
114
encapsulation : ViewEncapsulation . None ,
116
115
@@ -259,22 +258,26 @@ export class CdkTree<T, K = T>
259
258
private _keyManagerFactory = inject ( TREE_KEY_MANAGER ) as TreeKeyManagerFactory < CdkTreeNode < T , K > > ;
260
259
261
260
/** The key manager for this tree. Handles focus and activation based on user keyboard input. */
262
- _keyManager : TreeKeyManagerStrategy < CdkTreeNode < T , K > > ;
261
+ _keyManager : TreeKeyManagerStrategy < CdkTreeNode < T , K > > | undefined ;
263
262
264
263
constructor (
265
264
private _differs : IterableDiffers ,
266
265
private _changeDetectorRef : ChangeDetectorRef ,
267
266
private _dir : Directionality ,
268
267
private _elementRef : ElementRef < HTMLElement > ,
269
- ) { }
268
+ ) {
269
+ console . log ( 'CdkTree' , 'constructor' ) ;
270
+ }
270
271
271
272
ngAfterContentInit ( ) {
272
- this . _initializeKeyManager ( ) ;
273
+ console . log ( 'CdkTree' , 'ngAfterContentInit' ) ;
273
274
}
274
275
275
276
ngAfterContentChecked ( ) {
277
+ console . log ( 'CdkTree' , 'ngAfterContentChecked' ) ;
276
278
this . _updateDefaultNodeDefinition ( ) ;
277
279
this . _subscribeToDataChanges ( ) ;
280
+ this . _initializeKeyManager ( ) ;
278
281
}
279
282
280
283
ngOnDestroy ( ) {
@@ -295,6 +298,7 @@ export class CdkTree<T, K = T>
295
298
}
296
299
297
300
ngOnInit ( ) {
301
+ console . log ( 'CdkTree' , 'ngOnInit' ) ;
298
302
this . _checkTreeControlUsage ( ) ;
299
303
this . _initializeDataDiffer ( ) ;
300
304
}
@@ -319,23 +323,6 @@ export class CdkTree<T, K = T>
319
323
}
320
324
}
321
325
322
- /**
323
- * Sets the tabIndex on the host element.
324
- *
325
- * NB: we don't set this as a host binding since children being activated
326
- * (e.g. on user click) doesn't trigger this component's change detection.
327
- */
328
- _setTabIndex ( ) {
329
- // If the `TreeKeyManager` has no active item, then we know that we need to focus the initial
330
- // item when the tree is focused. We set the tabindex to be `0` so that we can capture
331
- // the focus event and redirect it. Otherwise, we unset it.
332
- if ( ! this . _keyManager . getActiveItem ( ) ) {
333
- this . _elementRef . nativeElement . setAttribute ( 'tabindex' , '0' ) ;
334
- } else {
335
- this . _elementRef . nativeElement . removeAttribute ( 'tabindex' ) ;
336
- }
337
- }
338
-
339
326
/**
340
327
* Switch to the provided data source by resetting the data and unsubscribing from the current
341
328
* render change subscription if one exists. If the data source is null, interpret this by
@@ -425,6 +412,9 @@ export class CdkTree<T, K = T>
425
412
}
426
413
427
414
private _renderDataChanges ( data : RenderingData < T > ) {
415
+ console . log (
416
+ `renderDataChanges nodeType:${ data . nodeType } renderNodes:${ data . renderNodes . length } ` ,
417
+ ) ;
428
418
if ( data . nodeType === null ) {
429
419
this . _renderNodeChanges ( data . renderNodes ) ;
430
420
return ;
@@ -454,6 +444,10 @@ export class CdkTree<T, K = T>
454
444
}
455
445
456
446
private _initializeKeyManager ( ) {
447
+ if ( this . _keyManager ) {
448
+ return ;
449
+ }
450
+
457
451
const items = combineLatest ( [ this . _keyManagerNodes , this . _nodes ] ) . pipe (
458
452
map ( ( [ keyManagerNodes , renderNodes ] ) =>
459
453
keyManagerNodes . reduce < CdkTreeNode < T , K > [ ] > ( ( items , data ) => {
@@ -478,14 +472,10 @@ export class CdkTree<T, K = T>
478
472
this . _keyManager . change
479
473
. pipe ( startWith ( null ) , pairwise ( ) , takeUntil ( this . _onDestroy ) )
480
474
. subscribe ( ( [ prev , next ] ) => {
475
+ console . log ( 'keyManage change subscription' , prev , next ) ;
481
476
prev ?. _setTabUnfocusable ( ) ;
482
477
next ?. _setTabFocusable ( ) ;
483
478
} ) ;
484
-
485
- this . _keyManager . change . pipe ( startWith ( null ) , takeUntil ( this . _onDestroy ) ) . subscribe ( ( ) => {
486
- // refresh the tabindex when the active item changes.
487
- this . _setTabIndex ( ) ;
488
- } ) ;
489
479
}
490
480
491
481
private _initializeDataDiffer ( ) {
@@ -861,15 +851,7 @@ export class CdkTree<T, K = T>
861
851
862
852
/** `keydown` event handler; this just passes the event to the `TreeKeyManager`. */
863
853
_sendKeydownToKeyManager ( event : KeyboardEvent ) {
864
- this . _keyManager . onKeydown ( event ) ;
865
- }
866
-
867
- /** `focus` event handler; this focuses the initial item if there isn't already one available. */
868
- _focusInitialTreeItem ( ) {
869
- if ( this . _keyManager . getActiveItem ( ) ) {
870
- return ;
871
- }
872
- this . _keyManager . onInitialFocus ( ) ;
854
+ this . _keyManager ?. onKeydown ( event ) ;
873
855
}
874
856
875
857
/** Gets all nested descendants of a given node. */
@@ -1140,7 +1122,7 @@ export class CdkTree<T, K = T>
1140
1122
'[attr.aria-level]' : 'level + 1' ,
1141
1123
'[attr.aria-posinset]' : '_getPositionInSet()' ,
1142
1124
'[attr.aria-setsize]' : '_getSetSize()' ,
1143
- 'tabindex' : '-1 ' ,
1125
+ '[ tabindex] ' : '_getTabindex() ' ,
1144
1126
'role' : 'treeitem' ,
1145
1127
'(click)' : '_focusItem()' ,
1146
1128
'(focus)' : '_focusItem()' ,
@@ -1282,6 +1264,17 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
1282
1264
return this . _tree . _getPositionInSet ( this . _data ) ;
1283
1265
}
1284
1266
1267
+ protected _getTabindex ( ) : number | null {
1268
+ if ( ! this . _tree . _keyManager ) {
1269
+ return null ;
1270
+ }
1271
+ // TODO: determine if this equailty check will work in SSR
1272
+ if ( this . _tree . _keyManager . getActiveItem ( ) === this ) {
1273
+ return 0 ;
1274
+ }
1275
+ return - 1 ;
1276
+ }
1277
+
1285
1278
constructor (
1286
1279
protected _elementRef : ElementRef < HTMLElement > ,
1287
1280
protected _tree : CdkTree < T , K > ,
@@ -1343,18 +1336,20 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
1343
1336
}
1344
1337
1345
1338
_setTabFocusable ( ) {
1339
+ console . log ( '_setTabFocusable' , this . _elementRef . nativeElement . textContent ) ;
1346
1340
this . _elementRef . nativeElement . setAttribute ( 'tabindex' , '0' ) ;
1347
1341
}
1348
1342
1349
1343
_setTabUnfocusable ( ) {
1344
+ console . log ( '_setTabUnfocusable' , this . _elementRef . nativeElement . textContent ) ;
1350
1345
this . _elementRef . nativeElement . setAttribute ( 'tabindex' , '-1' ) ;
1351
1346
}
1352
1347
1353
1348
_focusItem ( ) {
1354
1349
if ( this . isDisabled ) {
1355
1350
return ;
1356
1351
}
1357
- this . _tree . _keyManager . focusItem ( this ) ;
1352
+ this . _tree . _keyManager ? .focusItem ( this ) ;
1358
1353
}
1359
1354
1360
1355
_emitExpansionState ( expanded : boolean ) {
0 commit comments