remove method
Removes a node and all its descendants from the tree.
If animate is true, the nodes will animate out.
Implementation
void remove({required TKey key, bool animate = true}) {
if (animationDuration == Duration.zero) animate = false;
if (!_hasKey(key)) {
return;
}
final descendants = _getDescendants(key);
final nodesToRemove = [key, ...descendants];
// Capture the parent BEFORE mutation; _removeNodesImmediate purges the
// node and releases its nid, after which _parentKeyOfKey returns null.
final parentKey = _parentKeyOfKey(key);
final affected = <TKey>{};
if (animate && _order.contains(key)) {
// Mark nodes as pending deletion so _finalizeAnimation knows to
// fully remove them (vs just hiding due to parent collapse)
for (final nodeId in nodesToRemove) {
_markPendingDeletion(nodeId);
}
// Mark all visible nodes as exiting
for (final nodeId in nodesToRemove) {
if (_order.contains(nodeId)) {
_startStandaloneExitAnimation(nodeId);
}
}
// Animated path: parent's child list is not mutated until exit
// animations complete; the hasChildren-flip refresh is fired from
// the standalone-tick / group-dismissed sites at completion time.
} else {
_removeNodesImmediate(nodesToRemove);
_structureGeneration++;
// Immediate path: if [key] was the last child under its parent, the
// parent's hasChildren just flipped true → false.
if (parentKey != null) {
final siblings = _childListOf(parentKey);
if (siblings == null || siblings.isEmpty) {
affected.add(parentKey);
}
}
}
_notifyStructural(affectedKeys: affected);
}