Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2000-2026 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.flow.component.grid.it;

import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.NativeButton;
import com.vaadin.flow.router.Route;

@Route("vaadin-grid/grid-scroll-to-column")
public class GridScrollToColumnPage extends Div {
public GridScrollToColumnPage() {
Grid<Integer> grid = new Grid<>();
grid.setWidth("400px");

var items = java.util.stream.IntStream.range(0, 10).boxed().toList();
grid.setItems(items);

final int columnCount = 20;
for (int i = 0; i < columnCount; i++) {
final int columnIndex = i;
grid.addColumn(item -> "Cell " + columnIndex)
.setHeader("Column " + columnIndex)
.setKey("column-" + columnIndex);
}

NativeButton scrollByIndex = new NativeButton(
"Scroll to column 10 by index", e -> grid.scrollToColumn(10));
scrollByIndex.setId("scroll-by-index");
add(scrollByIndex);

NativeButton scrollByReference = new NativeButton(
"Scroll to column 10 by reference", e -> {
var column = grid.getColumnByKey("column-10");
grid.scrollToColumn(column);
});
scrollByReference.setId("scroll-by-reference");
add(scrollByReference);

add(grid);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright 2000-2026 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.flow.component.grid.it;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.vaadin.flow.component.grid.testbench.GridElement;
import com.vaadin.flow.component.grid.testbench.GridTHTDElement;
import com.vaadin.flow.testutil.TestPath;
import com.vaadin.tests.AbstractComponentIT;

@TestPath("vaadin-grid/grid-scroll-to-column")
public class GridScrollToColumnIT extends AbstractComponentIT {
private GridElement grid;

@Before
public void setUp() {
open();
grid = $(GridElement.class).waitForFirst();
}

@Test
public void scrollToColumnByIndex_columnIsVisible() {
var headerCell = grid.getHeaderCell(0, 10);
isCellVisible(headerCell);

Assert.assertFalse(isCellVisible(headerCell));

clickElementWithJs("scroll-by-index");

Assert.assertTrue(isCellVisible(headerCell));
}

@Test
public void scrollToColumnByReference_columnIsVisible() {
var headerCell = grid.getHeaderCell(0, 10);
isCellVisible(headerCell);

Assert.assertFalse(isCellVisible(headerCell));

clickElementWithJs("scroll-by-reference");

Assert.assertTrue(isCellVisible(headerCell));
}

@Test
public void scrollToColumnByIndexWithTestbench_columnIsVisible() {
var headerCell = grid.getHeaderCell(0, 10);
isCellVisible(headerCell);

Assert.assertFalse(isCellVisible(headerCell));

grid.scrollToColumn(10);

Assert.assertTrue(isCellVisible(headerCell));
}

@Test
public void scrollToColumnByReferenceWithTestbench_columnIsVisible() {
var headerCell = grid.getHeaderCell(0, 10);
isCellVisible(headerCell);

Assert.assertFalse(isCellVisible(headerCell));

var column = grid.getColumn("Column 10");
grid.scrollToColumn(column);

Assert.assertTrue(isCellVisible(headerCell));
}

private Boolean isCellVisible(GridTHTDElement cell) {
return (Boolean) (cell.getCommandExecutor()).executeScript(
"""
const cell = arguments[0];
const bounds = cell.getBoundingClientRect();
const centerX = bounds.left + bounds.width / 2;
const centerY = bounds.top + bounds.height / 2;
const cellContent = document.elementFromPoint(centerX, centerY);
return cell.querySelector('slot').assignedElements().includes(cellContent);
""",
cell);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5054,6 +5054,27 @@ public void scrollToEnd() {
.executeJs("this.scrollToIndex(this._flatSize)")));
}

/**
* Scrolls the grid horizontally to make the column with the given index
* visible. The index refers to visible columns, in their visual order.
*
* @param columnIndex
* the index of the column to scroll to
*/
public void scrollToColumn(int columnIndex) {
getElement().callJsFunction("scrollToColumn", columnIndex);
}

/**
* Scrolls the grid horizontally to make the given column visible.
*
* @param column
* the column to scroll to
*/
public void scrollToColumn(Column<T> column) {
getElement().callJsFunction("scrollToColumn", column.getElement());
}

private void onDragStart(GridDragStartEvent<T> event) {
ComponentUtil.setData(this, DRAG_SOURCE_DATA_KEY,
event.getDraggedItems());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,36 @@ void scrollToRowByFlatIndex(int rowFlatIndex) {
waitUntilLoadingFinished();
}

/**
* Scrolls the grid horizontally to make the column with the given index
* visible. The index refers to visible columns, in their visual order.
*
* @param columnIndex
* the index of the column to scroll to
*/
public void scrollToColumn(int columnIndex) {
callFunction("scrollToColumn", columnIndex);
}

/**
* Scrolls the grid horizontally to make the given column visible.
*
* @param column
* the column to scroll to
*/
public void scrollToColumn(GridColumnElement column) {
executeScript("""
const grid = arguments[0];
const columnId = arguments[1];
const column = grid._getColumns().find((col) => {
return col.__generatedTbId === columnId;
});
if (column) {
grid.scrollToColumn(column);
}
""", this, column.get__generatedId());
}

/**
* Gets the page size used when fetching data.
*
Expand Down