diff --git a/src/vaadin-grid.html b/src/vaadin-grid.html
index ebf3e4bb8..a447fcab0 100644
--- a/src/vaadin-grid.html
+++ b/src/vaadin-grid.html
@@ -266,7 +266,7 @@
* `reorder-status` | Reflects the status of a cell while columns are being reordered | cell
* `frozen` | Frozen cell | cell
* `last-frozen` | Last frozen cell | cell
- * * `first-column` | First visible cell on a row | cell
+ * `first-column` | First visible cell on a row | cell
* `last-column` | Last visible cell on a row | cell
* `selected` | Selected row | row
* `expanded` | Expanded row | row
@@ -274,6 +274,7 @@
* `loading` | Row that is waiting for data from data provider | row
* `odd` | Odd row | row
* `first` | The first body row | row
+ * `last` | The last body row | row
* `dragstart` | Set for one frame when drag of a row is starting. The value is a number when multiple rows are dragged | row
* `dragover` | Set when the row is dragged over | row
* `drag-disabled` | Set to a row that isn't available for dragging | row
@@ -770,6 +771,7 @@
}
this._toggleAttribute('first', index === 0, row);
+ this._toggleAttribute('last', index === this._effectiveSize - 1, row);
this._toggleAttribute('odd', index % 2, row);
this._a11yUpdateRowRowindex(row, index);
this._getItem(index, row);
diff --git a/test/basic.html b/test/basic.html
index 6bbf1c312..2917a465f 100644
--- a/test/basic.html
+++ b/test/basic.html
@@ -317,6 +317,20 @@
expect(window.getComputedStyle(grid).getPropertyValue('flex-basis')).to.equal('auto');
});
+ it('should have attribute last on the last body row', () => {
+ grid.scrollToIndex(grid.size - 1);
+ const lastRowCell = grid.shadowRoot.querySelector('[part~="row"][last] td');
+ const lastRowSlot = lastRowCell.firstElementChild;
+ expect(lastRowSlot.assignedNodes()[0].textContent).to.equal(String(grid.size - 1));
+ });
+
+ it('should have attribute last on the last body row after resize', () => {
+ grid.size = 2;
+ const lastRowCell = grid.shadowRoot.querySelector('[part~="row"][last] td');
+ const lastRowSlot = lastRowCell.firstElementChild;
+ expect(lastRowSlot.assignedNodes()[0].textContent).to.equal(String(grid.size - 1));
+ });
+
it('should keep row position after hiding/unhiding Grid', () => {
grid._scrollToIndex(100);
diff --git a/test/visual/screens/vaadin-grid/drag-and-drop-lumo/dragstart-below-last-row-all-rows-visible/chrome.png b/test/visual/screens/vaadin-grid/drag-and-drop-lumo/dragstart-below-last-row-all-rows-visible/chrome.png
new file mode 100644
index 000000000..a755030ec
Binary files /dev/null and b/test/visual/screens/vaadin-grid/drag-and-drop-lumo/dragstart-below-last-row-all-rows-visible/chrome.png differ
diff --git a/test/visual/screens/vaadin-grid/drag-and-drop-material/dragstart-below-last-row-all-rows-visible/chrome.png b/test/visual/screens/vaadin-grid/drag-and-drop-material/dragstart-below-last-row-all-rows-visible/chrome.png
new file mode 100644
index 000000000..9df39de9f
Binary files /dev/null and b/test/visual/screens/vaadin-grid/drag-and-drop-material/dragstart-below-last-row-all-rows-visible/chrome.png differ
diff --git a/test/visual/test.js b/test/visual/test.js
index c4fc52467..7a29cf3fd 100644
--- a/test/visual/test.js
+++ b/test/visual/test.js
@@ -128,6 +128,15 @@ gemini.suite('vaadin-grid', (rootSuite) => {
grid.$.items.children[1].removeAttribute('dragover');
grid.$.items.children[1].setAttribute('dragstart', '123');
});
+ })
+ .capture('dragstart-below-last-row-all-rows-visible', {}, (actions) => {
+ actions.executeJS(function(window) {
+ var grid = window.document.querySelector('vaadin-grid');
+ grid.allRowsVisible = true;
+ grid.items = grid.items.slice(0, 2);
+ grid.$.items.children[1].removeAttribute('dragstart');
+ grid.$.items.children[1].setAttribute('dragover', 'below');
+ });
});
});
});
diff --git a/theme/lumo/vaadin-grid-styles.html b/theme/lumo/vaadin-grid-styles.html
index 8c0dab63d..296ea111f 100644
--- a/theme/lumo/vaadin-grid-styles.html
+++ b/theme/lumo/vaadin-grid-styles.html
@@ -118,6 +118,10 @@
margin-top: -1px;
}
+ :host([all-rows-visible]) [part~="row"][last][dragover="below"] [part~="cell"]::after {
+ height: 1px;
+ }
+
[part~="row"][dragover="above"] [part~="cell"]::after {
top: auto;
bottom: 100%;
diff --git a/theme/material/vaadin-grid-styles.html b/theme/material/vaadin-grid-styles.html
index c968a2a14..43532f9e2 100644
--- a/theme/material/vaadin-grid-styles.html
+++ b/theme/material/vaadin-grid-styles.html
@@ -160,6 +160,10 @@
margin-top: -1px;
}
+ :host([all-rows-visible]) [part~="row"][last][dragover="below"] [part~="cell"]::after {
+ height: 1px;
+ }
+
[part~="row"][dragover="above"] [part~="cell"]::after {
top: auto;
bottom: 100%;