Skip to content

Commit

Permalink
fix(cdk/tree): fix issue where isExpanded wouldn't be set if placed…
Browse files Browse the repository at this point in the history
… before `isExpandable` (#29565)

* fix(cdk/tree): fix issue where `isExpanded` wouldn't be set if placed before `isExpandable`

* fix(cdk/tree): actually fix the issue

* fix(cdk/tree): actually actually fix tests
  • Loading branch information
BobobUnicorn authored Aug 13, 2024
1 parent ec35e99 commit bd84c2a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
41 changes: 40 additions & 1 deletion src/cdk/tree/tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,17 @@ describe('CdkTree', () => {
});
});
});

it('sets a node as expanded if attribute is ordered before `isExpandable`', () => {
configureCdkTreeTestingModule([IsExpandableOrderingTest]);
const fixture = TestBed.createComponent(IsExpandableOrderingTest);
fixture.detectChanges();

const component = fixture.componentInstance;
expect(getExpandedNodes(component.dataSource, component.tree).length)
.withContext(`expect an expanded node`)
.toBe(1);
});
});

export class TestData {
Expand Down Expand Up @@ -1554,7 +1565,7 @@ function getNodes(treeElement: Element): HTMLElement[] {
return Array.from(treeElement.querySelectorAll('.cdk-tree-node'));
}

function getExpandedNodes(nodes: TestData[] | undefined, tree: CdkTree<TestData>): TestData[] {
function getExpandedNodes<T>(nodes: T[] | undefined, tree: CdkTree<T>): T[] {
return nodes?.filter(node => tree.isExpanded(node)) ?? [];
}

Expand Down Expand Up @@ -2100,3 +2111,31 @@ class FlatTreeWithThreeNodes {
@ViewChild('tree', {read: ElementRef}) tree: ElementRef<HTMLElement>;
@ViewChildren('node') treeNodes: QueryList<ElementRef<HTMLElement>>;
}

@Component({
template: `
<cdk-tree [dataSource]="dataSource" [childrenAccessor]="getChildren">
<cdk-tree-node
*cdkTreeNodeDef="let node"
[isExpanded]="true"
[isExpandable]="true">
{{node.name}}
</cdk-tree-node>
</cdk-tree>
`,
})
class IsExpandableOrderingTest {
getChildren = (node: MinimalTestData) => node.children;

@ViewChild(CdkTree) tree: CdkTree<MinimalTestData>;

dataSource: MinimalTestData[];

constructor() {
const children = [new MinimalTestData('child')];
const data = [new MinimalTestData('parent')];
data[0].children = children;

this.dataSource = data;
}
}
12 changes: 12 additions & 0 deletions src/cdk/tree/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1176,13 +1176,24 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
}
set isExpandable(isExpandable: boolean) {
this._inputIsExpandable = isExpandable;
if ((this.data && !this._isExpandable) || !this._inputIsExpandable) {
return;
}
// If the node is being set to expandable, ensure that the status of the
// node is propagated
if (this._inputIsExpanded) {
this.expand();
} else if (this._inputIsExpanded === false) {
this.collapse();
}
}

@Input()
get isExpanded(): boolean {
return this._tree.isExpanded(this._data);
}
set isExpanded(isExpanded: boolean) {
this._inputIsExpanded = isExpanded;
if (isExpanded) {
this.expand();
} else {
Expand Down Expand Up @@ -1227,6 +1238,7 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
readonly _dataChanges = new Subject<void>();

private _inputIsExpandable: boolean = false;
private _inputIsExpanded: boolean | undefined = undefined;
/**
* Flag used to determine whether or not we should be focusing the actual element based on
* some user interaction (click or focus). On click, we don't forcibly focus the element
Expand Down

0 comments on commit bd84c2a

Please sign in to comment.