moveItem method
Repositions itemKey, either across sections or within its own.
• toSection non-null → reparents the item under that section.
With index it lands at that position; without, it is
appended.
• toSection null, index non-null → reorders the item within
its current section to index.
• both null → no-op.
No animate parameter: the underlying TreeController.moveNode /
TreeController.reorderChildren are repositioning ops, not
insert/remove; nothing animates.
Implementation
void moveItem(K itemKey, {K? toSection, int? index}) {
_checkNotDisposed();
_requireItem(itemKey, "moveItem");
if (toSection != null) {
_requireSection(toSection, "moveItem(toSection)");
_tree.moveNode(
ItemKey<K>(itemKey),
SectionKey<K>(toSection),
index: index,
);
return;
}
if (index == null) {
// Neither a reparent target nor a reorder index — nothing to do.
return;
}
if (_tree.isPendingDeletion(ItemKey<K>(itemKey))) {
_throwMissing("moveItem", "item $itemKey is being removed");
}
final parentKey = sectionOf(itemKey);
if (parentKey == null) {
_throwMissing("moveItem", "item $itemKey has no parent section");
}
// Use the LIVE list — `reorderItems` → `_tree.reorderChildren`
// validates against the live child set (excludes pending-deletion).
final siblings = itemKeysOf(parentKey)..remove(itemKey);
final clamped = index.clamp(0, siblings.length);
siblings.insert(clamped, itemKey);
reorderItems(parentKey, siblings);
}