+
+ {renderRow({
+ node,
+ level,
+ isOpen,
+ hasChildren,
+ isSelected,
+ isDragging,
+ isReceivingDrop: receivingDrop,
+ rowRef,
+ tabIndex: activeId === node.id ? 0 : -1,
+ treeItemProps,
+ toggleOpen,
+ })}
+
+ {instruction && (
+
+ )}
+
+ );
+}
+
+// Custom memo comparator. The default shallow compare re-renders every row
+// when `openIds` (a Set) or `selectedId` (a string) on the parent changes,
+// because all rows receive the same reference via {...props} spread. With 1K
+// rows that's a perceptible stall on every expand and every navigate.
+//
+// Resolve openIds / selectedId per-row: only re-render if THIS row's own
+// open-state or selected-state actually flipped. Everything else uses
+// reference equality (callbacks are useCallback-stable from the parent).
+function arePropsEqual