diff --git a/src/Ui/Widget/Container.php b/src/Ui/Widget/Container.php index a3b6b3f..d473055 100644 --- a/src/Ui/Widget/Container.php +++ b/src/Ui/Widget/Container.php @@ -522,6 +522,26 @@ class Container extends Component ]; } + /** + * Get current scroll position. + */ + public function getScrollPosition(): array + { + return [ + 'x' => $this->scrollX, + 'y' => $this->scrollY, + ]; + } + + /** + * Restore scroll position (used e.g. after re-rendering children). + */ + public function setScrollPosition(float $x, float $y): void + { + $this->scrollX = max(0, $x); + $this->scrollY = max(0, $y); + } + private function renderScrollbars(&$renderer, array $overflow): void { $scrollbarColor = [120, 120, 120, 230]; diff --git a/src/Ui/Widget/Table.php b/src/Ui/Widget/Table.php index 67dc4b5..878573c 100644 --- a/src/Ui/Widget/Table.php +++ b/src/Ui/Widget/Table.php @@ -202,6 +202,10 @@ class Table extends Container */ public function selectRow(int $rowIndex): void { + // Remember current scroll position of the body so that selection + // does not reset scrolling back to the top. + $scrollPosition = $this->bodyContainer->getScrollPosition(); + $this->selectedRowIndex = $rowIndex; // Trigger callback @@ -211,6 +215,9 @@ class Table extends Container // Re-render rows to update selection $this->setData($this->rows); + + // Restore scroll position + $this->bodyContainer->setScrollPosition($scrollPosition['x'], $scrollPosition['y']); } /**