Skip to content

Commit 64addca

Browse files
committed
fix tslint comments, fix class inheritance for mat tree
1 parent f5f489b commit 64addca

File tree

5 files changed

+42
-35
lines changed

5 files changed

+42
-35
lines changed

src/cdk/tree/nested-node.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export class CdkNestedTreeNode<T> extends CdkTreeNode<T> implements AfterContent
4141
// tslint:disable:no-host-decorator-in-concrete
4242
@HostBinding('attr.aria-expanded') _expanded = this.isExpanded;
4343
@HostBinding('attr.role') _role = this.role;
44+
// tslint:enable:no-host-decorator-in-concrete
4445

4546
/** Differ used to find the changes in the data provided by the data source. */
4647
private _dataDiffer: IterableDiffer<T>;

src/cdk/tree/tree.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ describe('CdkTree', () => {
596596
[`topping_3 - cheese_3 + base_3`]);
597597
});
598598

599-
it('with correct aria-level', () => {
599+
it('with correct aria-level on nodes', () => {
600600
expect(getNodes(treeElement).every(node => {
601601
return node.getAttribute('aria-level') === '1';
602602
})).toBe(true);

src/cdk/tree/tree.ts

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
ElementRef,
1818
HostBinding,
1919
Input,
20+
isDevMode,
2021
IterableChangeRecord,
2122
IterableDiffer,
2223
IterableDiffers,
@@ -56,6 +57,10 @@ import {
5657
selector: 'cdk-tree',
5758
exportAs: 'cdkTree',
5859
template: `<ng-container cdkTreeNodeOutlet></ng-container>`,
60+
host: {
61+
'class': 'cdk-tree',
62+
'role': 'tree',
63+
},
5964
encapsulation: ViewEncapsulation.None,
6065

6166
// The "OnPush" status for the `CdkTree` component is effectively a noop, so we are removing it.
@@ -65,9 +70,6 @@ import {
6570
changeDetection: ChangeDetectionStrategy.Default
6671
})
6772
export class CdkTree<T> implements AfterContentChecked, CollectionViewer, OnDestroy, OnInit {
68-
// tslint:disable:no-host-decorator-in-concrete
69-
@HostBinding('attr.role') _role = 'tree';
70-
7173
/** Subject that emits when the component has been destroyed. */
7274
private _onDestroy = new Subject<void>();
7375

@@ -128,10 +130,7 @@ export class CdkTree<T> implements AfterContentChecked, CollectionViewer, OnDest
128130
new BehaviorSubject<{start: number, end: number}>({start: 0, end: Number.MAX_VALUE});
129131

130132
constructor(private _differs: IterableDiffers,
131-
private _changeDetectorRef: ChangeDetectorRef,
132-
private _elementRef: ElementRef<HTMLElement>) {
133-
this._elementRef.nativeElement.classList.add('cdk-tree');
134-
}
133+
private _changeDetectorRef: ChangeDetectorRef) {}
135134

136135
ngOnInit() {
137136
this._dataDiffer = this._differs.find([]).create(this.trackBy);
@@ -302,12 +301,13 @@ export class CdkTree<T> implements AfterContentChecked, CollectionViewer, OnDest
302301
exportAs: 'cdkTreeNode',
303302
})
304303
export class CdkTreeNode<T> implements FocusableOption, OnDestroy, OnInit {
304+
// TODO: mark as deprecated
305+
// tslint:disable:no-host-decorator-in-concrete
305306
/**
306-
* The role of the node should always be 'treeitem'.
307+
* The role of the tree node.
307308
*/
308-
// TODO: mark as deprecated
309-
// tslint:disable:no-host-decorator-in-concrete
310309
@HostBinding('attr.role') @Input() role: 'treeitem' | 'group' = 'treeitem';
310+
// tslint:enable:no-host-decorator-in-concrete
311311

312312
/**
313313
* The most recently created `CdkTreeNode`. We save it in static variable so we can retrieve it
@@ -334,7 +334,7 @@ export class CdkTreeNode<T> implements FocusableOption, OnDestroy, OnInit {
334334
}
335335
protected _data: T;
336336

337-
// tslint:disable:no-host-decorator-in-concrete
337+
// tslint:disable-next-line:no-host-decorator-in-concrete
338338
@HostBinding('attr.aria-expanded') get isExpanded(): boolean {
339339
return this._tree.treeControl.isExpanded(this._data);
340340
}
@@ -354,7 +354,7 @@ export class CdkTreeNode<T> implements FocusableOption, OnDestroy, OnInit {
354354
}
355355

356356
ngOnInit(): void {
357-
this._parentNodeAriaLevel = this._getParentNodeAriaLevel();
357+
this._parentNodeAriaLevel = getParentNodeAriaLevel(this._elementRef.nativeElement);
358358
this._elementRef.nativeElement.setAttribute('aria-level', String(this.level + 1));
359359
}
360360

@@ -382,20 +382,29 @@ export class CdkTreeNode<T> implements FocusableOption, OnDestroy, OnInit {
382382
}
383383
this.role = 'treeitem';
384384
}
385+
}
385386

386-
private _getParentNodeAriaLevel(): number {
387-
let parent = this._elementRef.nativeElement.parentElement;
388-
while (parent &&
389-
!(parent.classList.contains('cdk-nested-tree-node') || parent.classList.contains('cdk-tree'))) {
390-
parent = parent.parentElement;
391-
}
392-
if (!parent) {
387+
function getParentNodeAriaLevel(nodeElement: HTMLElement): number {
388+
debugger;
389+
let parent = nodeElement.parentElement;
390+
while (parent && isNodeElement(parent)) {
391+
parent = parent.parentElement;
392+
}
393+
if (!parent) {
394+
if (isDevMode()) {
393395
throw Error('Incorrect tree structure containing detached node.');
394-
} else if (parent.classList.contains('cdk-nested-tree-node')) {
395-
return parseInt(parent.getAttribute('aria-level')!);
396396
} else {
397-
// parent.classList.contains('cdk-tree')
398-
return 0;
397+
return -1;
399398
}
399+
} else if (parent.classList.contains('cdk-nested-tree-node')) {
400+
return Number(parent.getAttribute('aria-level')!);
401+
} else {
402+
// The ancestor element is the cdk-tree itself
403+
return 0;
400404
}
401405
}
406+
407+
function isNodeElement(element: HTMLElement) {
408+
const classList = element?.classList;
409+
return !(classList?.contains('cdk-nested-tree-node') || classList?.contains('cdk-tree'));
410+
}

src/material/tree/tree.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ describe('MatTree', () => {
350350
[`topping_3 - cheese_3 + base_3`]);
351351
});
352352

353-
it('with correct aria-level', () => {
353+
it('with correct aria-level on nodes', () => {
354354
expect(getNodes(treeElement).every(node => {
355355
return node.getAttribute('aria-level') === '1';
356356
})).toBe(true);

src/material/tree/tree.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@
99
import {CdkTree} from '@angular/cdk/tree';
1010
import {
1111
ChangeDetectionStrategy,
12-
ChangeDetectorRef,
1312
Component,
14-
ElementRef,
15-
IterableDiffers,
1613
ViewChild,
1714
ViewEncapsulation
1815
} from '@angular/core';
@@ -26,6 +23,13 @@ import {MatTreeNodeOutlet} from './outlet';
2623
exportAs: 'matTree',
2724
template: `<ng-container matTreeNodeOutlet></ng-container>`,
2825
host: {
26+
// The 'cdk-tree' class needs to be included here because classes set in the host in the
27+
// parent class are not inherited with View Engine. The 'cdk-tree' class in CdkTreeNode has
28+
// to be set in the host because:
29+
// if it is set as a @HostBinding it is not set by the time the tree nodes try to read the
30+
// class from it.
31+
// the ElementRef is not available in the constructor so the class can't be applied directly.
32+
'class': 'mat-tree cdk-tree',
2933
'role': 'tree',
3034
},
3135
styleUrls: ['tree.css'],
@@ -38,11 +42,4 @@ import {MatTreeNodeOutlet} from './outlet';
3842
export class MatTree<T> extends CdkTree<T> {
3943
// Outlets within the tree's template where the dataNodes will be inserted.
4044
@ViewChild(MatTreeNodeOutlet, {static: true}) _nodeOutlet: MatTreeNodeOutlet;
41-
42-
constructor(_differs: IterableDiffers,
43-
_changeDetectorRef: ChangeDetectorRef,
44-
_elementRef: ElementRef<HTMLElement>) {
45-
super(_differs, _changeDetectorRef, _elementRef);
46-
_elementRef.nativeElement.classList.add('mat-tree');
47-
}
4845
}

0 commit comments

Comments
 (0)