Skip to content

Commit 1f992d0

Browse files
authoredJul 3, 2024··
fix(material/tree): aria-expanded attribute should not appear in the leaf node (#29273)
* fix(material/tree): fixed unit tests fixed unit tests Fixes #21922 * fix(material/tree): updated public api file updated public api file Fixes #21922
1 parent 0519174 commit 1f992d0

File tree

4 files changed

+38
-33
lines changed

4 files changed

+38
-33
lines changed
 

‎src/cdk/tree/tree.spec.ts

+8-16
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,14 @@ describe('CdkTree', () => {
145145
let data = dataSource.data;
146146
dataSource.addChild(data[2]);
147147
fixture.detectChanges();
148-
expect(
149-
getNodes(treeElement).every(node => {
150-
return node.getAttribute('aria-expanded') === 'false';
151-
}),
152-
).toBe(true);
148+
let ariaExpandedStates = getNodes(treeElement).map(n => n.getAttribute('aria-expanded'));
149+
expect(ariaExpandedStates).toEqual([null, null, 'false', null]);
153150

154151
component.treeControl.expandAll();
155152
fixture.detectChanges();
156153

157-
expect(
158-
getNodes(treeElement).every(node => {
159-
return node.getAttribute('aria-expanded') === 'true';
160-
}),
161-
).toBe(true);
154+
ariaExpandedStates = getNodes(treeElement).map(n => n.getAttribute('aria-expanded'));
155+
expect(ariaExpandedStates).toEqual([null, null, 'true', null]);
162156
});
163157

164158
it('with the right data', () => {
@@ -805,11 +799,8 @@ describe('CdkTree', () => {
805799
});
806800

807801
it('with the right aria-expanded attrs', () => {
808-
expect(
809-
getNodes(treeElement).every(node => {
810-
return node.getAttribute('aria-expanded') === 'false';
811-
}),
812-
).toBe(true);
802+
let ariaExpandedStates = getNodes(treeElement).map(n => n.getAttribute('aria-expanded'));
803+
expect(ariaExpandedStates).toEqual([null, null, null]);
813804

814805
component.toggleRecursively = false;
815806
fixture.changeDetectorRef.markForCheck();
@@ -822,7 +813,7 @@ describe('CdkTree', () => {
822813
fixture.detectChanges();
823814

824815
const ariaExpanded = getNodes(treeElement).map(n => n.getAttribute('aria-expanded'));
825-
expect(ariaExpanded).toEqual(['false', 'true', 'false', 'false']);
816+
expect(ariaExpanded).toEqual([null, 'true', 'false', null]);
826817
});
827818

828819
it('should expand/collapse the node multiple times', () => {
@@ -886,6 +877,7 @@ describe('CdkTree', () => {
886877
});
887878

888879
it('should expand/collapse the node recursively', () => {
880+
fixture.changeDetectorRef.markForCheck();
889881
let data = dataSource.data;
890882
const child = dataSource.addChild(data[1], false);
891883
dataSource.addChild(child, false);

‎src/cdk/tree/tree.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ export class CdkTree<T, K = T> implements AfterContentChecked, CollectionViewer,
324324
exportAs: 'cdkTreeNode',
325325
host: {
326326
'class': 'cdk-tree-node',
327-
'[attr.aria-expanded]': 'isExpanded',
327+
'[attr.aria-expanded]': 'isLeafNode ? null : isExpanded',
328328
},
329329
standalone: true,
330330
})
@@ -375,6 +375,26 @@ export class CdkTreeNode<T, K = T> implements FocusableOption, OnDestroy, OnInit
375375
return this._tree.treeControl.isExpanded(this._data);
376376
}
377377

378+
/* If leaf node, return true to not assign aria-expanded attribute */
379+
get isLeafNode(): boolean {
380+
// If flat tree node data returns false for expandable property, it's a leaf node
381+
if (
382+
this._tree.treeControl.isExpandable !== undefined &&
383+
!this._tree.treeControl.isExpandable(this._data)
384+
) {
385+
return true;
386+
387+
// If nested tree node data returns 0 descendants, it's a leaf node
388+
} else if (
389+
this._tree.treeControl.isExpandable === undefined &&
390+
this._tree.treeControl.getDescendants(this._data).length === 0
391+
) {
392+
return true;
393+
}
394+
395+
return false;
396+
}
397+
378398
get level(): number {
379399
// If the treeControl has a getLevel method, use it to get the level. Otherwise read the
380400
// aria-level off the parent node and use it as the level for this node (note aria-level is

‎src/material/tree/tree.spec.ts

+7-16
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,14 @@ describe('MatTree', () => {
7878
const data = underlyingDataSource.data;
7979
underlyingDataSource.addChild(data[2]);
8080
fixture.detectChanges();
81-
expect(
82-
getNodes(treeElement).every(node => {
83-
return node.getAttribute('aria-expanded') === 'false';
84-
}),
85-
).toBe(true);
81+
let ariaExpandedStates = getNodes(treeElement).map(n => n.getAttribute('aria-expanded'));
82+
expect(ariaExpandedStates).toEqual([null, null, 'false']);
8683

8784
component.treeControl.expandAll();
8885
fixture.detectChanges();
8986

90-
expect(
91-
getNodes(treeElement).every(node => {
92-
return node.getAttribute('aria-expanded') === 'true';
93-
}),
94-
).toBe(true);
87+
ariaExpandedStates = getNodes(treeElement).map(n => n.getAttribute('aria-expanded'));
88+
expect(ariaExpandedStates).toEqual([null, null, 'true', null]);
9589
});
9690

9791
it('with the right data', () => {
@@ -470,11 +464,8 @@ describe('MatTree', () => {
470464
});
471465

472466
it('with the right aria-expanded attrs', () => {
473-
expect(
474-
getNodes(treeElement).every(node => {
475-
return node.getAttribute('aria-expanded') === 'false';
476-
}),
477-
).toBe(true);
467+
let ariaExpandedStates = getNodes(treeElement).map(n => n.getAttribute('aria-expanded'));
468+
expect(ariaExpandedStates).toEqual([null, null, null]);
478469

479470
component.toggleRecursively = false;
480471
const data = underlyingDataSource.data;
@@ -486,7 +477,7 @@ describe('MatTree', () => {
486477
fixture.detectChanges();
487478

488479
const ariaExpanded = getNodes(treeElement).map(n => n.getAttribute('aria-expanded'));
489-
expect(ariaExpanded).toEqual(['false', 'true', 'false', 'false']);
480+
expect(ariaExpanded).toEqual([null, 'true', 'false', null]);
490481
});
491482

492483
it('should expand/collapse the node', () => {

‎tools/public_api_guard/cdk/tree.md

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ export class CdkTreeNode<T, K = T> implements FocusableOption, OnDestroy, OnInit
127127
// (undocumented)
128128
get isExpanded(): boolean;
129129
// (undocumented)
130+
get isLeafNode(): boolean;
131+
// (undocumented)
130132
get level(): number;
131133
static mostRecentTreeNode: CdkTreeNode<any> | null;
132134
// (undocumented)

0 commit comments

Comments
 (0)
Please sign in to comment.