Grid rows of variable height are overlapping when using scrollTo
Description
When using the example snippet below, clicking one of the rendered buttons will cause the taller Grid rows to overlap with the surrounding ones so that either the contents of the taller row, or the row below it, are only partially visible. This behaviour is very reliably reproduced on Firefox and Safari, a bit less so on Chrome, but is also happening there most of the time.
As a workaround, adding a call to grid.recalculateColumnWidths(); as the last thing in the button's click listener seems to help.
Expected outcome
The row heights should be properly managed even when scrollTo is used right after populating the Grid.
Minimal reproducible example
public class MainView extends FlexLayout {
private class GridItem {
int idx;
NativeButton btnGrid;
Span spnGrid;
GridItem(int idx) {
this.idx = idx;
btnGrid = new NativeButton("" + idx, ev -> {
Random r = new Random();
int i = r.nextInt(items.size() - 1);
grid.setItems(items);
grid.scrollToIndex(i);
grid.select(items.get(i + 1));
});
spnGrid = new Span("Text " + idx);
}
}
private class GridItemRenderer extends Div {
public GridItemRenderer(GridItem gridItem) {
FlexLayout flex = new FlexLayout();
flex.add(gridItem.btnGrid, gridItem.spnGrid);
flex.setFlexGrow(1, gridItem.spnGrid);
if(gridItem.idx % 5 == 0) flex.getStyle().set("padding-top", "1.5em").set("color", "red");
add(flex);
}
}
private List<GridItem> items;
private final Grid<GridItem> grid = new Grid<>();
public MainView() {
items = new ArrayList<>();
for(int i = 0; i < 35; i++) {
GridItem item = new GridItem(i);
items.add(item);
}
grid.addColumn(new ComponentRenderer<>(GridItemRenderer::new));
grid.setItems(items);
grid.setHeightFull();
setHeightFull();
expand(grid);
add(grid);
}
}
Steps to reproduce
- add the view described in the snippet to the project
- navigate to the added view
- press any of the rendered buttons on any row
- see how things get broken around the taller rows
Environment
Vaadin version(s): 24.6.6 OS: macOS, but doesn't seem to be OS dependent. Or browser.
Browsers
Issue is not browser related
Hello @mlindfors! The issue in you example seems related to the fact that some element instances come from the bean instead of being created by the renderer class. Typically, all elements should be instantiated within the renderer class. When I do so, the issue doesn't happen:
public class MainView extends FlexLayout {
private class GridItem {
int idx;
GridItem(int idx) {
this.idx = idx;
}
}
private class GridItemRenderer extends Div {
public GridItemRenderer(GridItem gridItem) {
FlexLayout flex = new FlexLayout();
NativeButton btnGrid = new NativeButton("" + gridItem.idx); // <------
Span spnGrid = new Span("Text " + gridItem.idx); // <------
flex.add(btnGrid, spnGrid);
flex.setFlexGrow(1, spnGrid);
if (gridItem.idx % 5 == 0) {
flex.getStyle().set("padding-top", "1.5em").set("color", "red");
}
add(flex);
}
}
private List<GridItem> items;
private final Grid<GridItem> grid = new Grid<>();
public MainView() {
items = new ArrayList<>();
for (int i = 0; i < 35; i++) {
GridItem item = new GridItem(i);
items.add(item);
}
grid.addColumn(new ComponentRenderer<>(GridItemRenderer::new));
grid.setItems(items);
grid.setHeightFull();
setHeightFull();
expand(grid);
NativeButton btnGrid = new NativeButton("Scroll to item", ev -> {
Random r = new Random();
int i = r.nextInt(items.size() - 1);
grid.setItems(items);
grid.scrollToIndex(i);
grid.select(items.get(i));
});
add(grid, btnGrid);
}
}
Closing due to inactivity. Feel free to reopen if you have any additional context to share.