Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading