Skip to content

Commit

Permalink
fix: TreeViewItem.from should set parent properly (#1043)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdlukaa authored Mar 20, 2024
2 parents 9c0840d + 72efefa commit ed77764
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 20 deletions.
45 changes: 25 additions & 20 deletions lib/src/controls/navigation/tree_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -227,25 +227,30 @@ class TreeViewItem with Diagnosticable {
/// its child items. Useful if you want to have multiple trees with the
/// same items, but with different UX states (e.g., selection, visibility,
/// etc.).
TreeViewItem.from(TreeViewItem source)
: this(
key: source.key,
leading: source.leading,
content: source.content,
value: source.value,
children: source.children.map(TreeViewItem.from).toList(),
collapsable: source.collapsable,
expanded: source.expanded,
selected: source.selected,
onInvoked: source.onInvoked,
onExpandToggle: source.onExpandToggle,
backgroundColor: source.backgroundColor,
autofocus: source.autofocus,
focusNode: source.focusNode,
semanticLabel: source.semanticLabel,
loadingWidget: source.loadingWidget,
lazy: source.lazy,
);
factory TreeViewItem.from(TreeViewItem source) {
final newItem = TreeViewItem(
key: source.key,
leading: source.leading,
content: source.content,
value: source.value,
children: source.children.map(TreeViewItem.from).toList(),
collapsable: source.collapsable,
expanded: source.expanded,
selected: source.selected,
onInvoked: source.onInvoked,
onExpandToggle: source.onExpandToggle,
backgroundColor: source.backgroundColor,
autofocus: source.autofocus,
focusNode: source.focusNode,
semanticLabel: source.semanticLabel,
loadingWidget: source.loadingWidget,
lazy: source.lazy,
);
for (final c in newItem.children) {
c._parent = newItem;
}
return newItem;
}

/// Whether this node is expandable
bool get isExpandable {
Expand Down Expand Up @@ -428,7 +433,7 @@ extension TreeViewItemCollection on List<TreeViewItem> {
if (isNotEmpty) {
final list = <TreeViewItem>[];
final anyExpandableSiblings = any((i) => i.isExpandable);
for (final item in [...this]) {
for (final item in this) {
item
.._parent = parent
.._anyExpandableSiblings = anyExpandableSiblings;
Expand Down
47 changes: 47 additions & 0 deletions test/tree_view_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,53 @@ void main() {
await tester.pumpWidget(wrapApp(child: TreeView(items: items)));

expect(itemOne.parent, isNotNull);
expect(itemOne.parent, items[0]);
expect(itemOne.parent?.selected, null);
});

testWidgets('TreeViewItem deep copy rebuilds parent linkage',
(WidgetTester tester) async {
final items = [
TreeViewItem(
content: const Text('Parent item'),
children: [
TreeViewItem(
content: const Text('Item 1'),
children: [
TreeViewItem(
content: const Text('Subitem 1'),
),
TreeViewItem(
content: const Text('Subitem 2'),
),
],
),
TreeViewItem(
content: const Text('Item 2'),
),
TreeViewItem(
content: const Text('Item 3'),
),
],
),
];

await tester.pumpWidget(wrapApp(child: TreeView(items: items)));
expect(items[0].parent, isNull);
expect(items[0].children[0].parent, items[0]);
expect(items[0].children[1].parent, items[0]);
expect(items[0].children[2].parent, items[0]);
expect(items[0].children[0].children[0].parent, items[0].children[0]);
expect(items[0].children[0].children[1].parent, items[0].children[0]);

final itemsCopy = items.map(TreeViewItem.from).toList();
expect(itemsCopy[0].parent, isNull);
expect(itemsCopy[0].children[0].parent, itemsCopy[0]);
expect(itemsCopy[0].children[1].parent, itemsCopy[0]);
expect(itemsCopy[0].children[2].parent, itemsCopy[0]);
expect(
itemsCopy[0].children[0].children[0].parent, itemsCopy[0].children[0]);
expect(
itemsCopy[0].children[0].children[1].parent, itemsCopy[0].children[0]);
});
}

0 comments on commit ed77764

Please sign in to comment.