@vaadin/grid 25.0.0-alpha9 → 25.0.0-beta2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/all-imports.js +1 -1
  2. package/package.json +12 -15
  3. package/src/array-data-provider.js +3 -2
  4. package/src/styles/vaadin-grid-base-styles.js +256 -91
  5. package/src/styles/vaadin-grid-sorter-base-styles.js +15 -2
  6. package/src/styles/vaadin-grid-tree-toggle-base-styles.js +4 -4
  7. package/src/vaadin-grid-a11y-mixin.js +26 -10
  8. package/src/vaadin-grid-column-auto-width-mixin.js +6 -11
  9. package/src/vaadin-grid-column-mixin.d.ts +1 -0
  10. package/src/vaadin-grid-column-mixin.js +1 -16
  11. package/src/vaadin-grid-column-reordering-mixin.js +2 -2
  12. package/src/vaadin-grid-data-provider-mixin.js +15 -10
  13. package/src/vaadin-grid-drag-and-drop-mixin.js +1 -1
  14. package/src/vaadin-grid-event-context-mixin.d.ts +2 -0
  15. package/src/vaadin-grid-event-context-mixin.js +1 -0
  16. package/src/vaadin-grid-filter.js +1 -1
  17. package/src/vaadin-grid-helpers.js +9 -0
  18. package/src/vaadin-grid-keyboard-navigation-mixin.js +1 -5
  19. package/src/vaadin-grid-mixin.d.ts +1 -0
  20. package/src/vaadin-grid-mixin.js +36 -38
  21. package/src/vaadin-grid-resize-mixin.d.ts +10 -0
  22. package/src/vaadin-grid-resize-mixin.js +73 -0
  23. package/src/vaadin-grid-row-details-mixin.js +1 -5
  24. package/src/vaadin-grid-scroll-mixin.js +5 -87
  25. package/src/vaadin-grid-selection-column-base-mixin.d.ts +1 -1
  26. package/src/vaadin-grid-selection-column-base-mixin.js +1 -1
  27. package/src/vaadin-grid-selection-column.d.ts +2 -0
  28. package/src/vaadin-grid-selection-column.js +2 -1
  29. package/src/vaadin-grid-sort-column.d.ts +2 -0
  30. package/src/vaadin-grid-sorter.d.ts +3 -3
  31. package/src/vaadin-grid-sorter.js +4 -4
  32. package/src/vaadin-grid-tree-column-mixin.js +7 -8
  33. package/src/vaadin-grid-tree-toggle.d.ts +4 -4
  34. package/src/vaadin-grid-tree-toggle.js +5 -5
  35. package/src/vaadin-grid.d.ts +1 -0
  36. package/src/vaadin-grid.js +3 -1
  37. package/vaadin-grid-column-group.js +1 -1
  38. package/vaadin-grid-column.js +1 -1
  39. package/vaadin-grid-filter-column.js +1 -1
  40. package/vaadin-grid-filter.js +1 -1
  41. package/vaadin-grid-selection-column.js +1 -1
  42. package/vaadin-grid-sort-column.js +1 -1
  43. package/vaadin-grid-sorter.js +1 -1
  44. package/vaadin-grid-tree-column.js +1 -1
  45. package/vaadin-grid-tree-toggle.js +1 -1
  46. package/vaadin-grid.js +1 -1
  47. package/web-types.json +13 -13
  48. package/web-types.lit.json +12 -12
  49. package/src/styles/vaadin-grid-core-styles.d.ts +0 -8
  50. package/src/styles/vaadin-grid-core-styles.js +0 -388
  51. package/src/styles/vaadin-grid-filter-core-styles.d.ts +0 -8
  52. package/src/styles/vaadin-grid-filter-core-styles.js +0 -18
  53. package/src/styles/vaadin-grid-sorter-core-styles.d.ts +0 -8
  54. package/src/styles/vaadin-grid-sorter-core-styles.js +0 -61
  55. package/src/styles/vaadin-grid-tree-toggle-core-styles.d.ts +0 -8
  56. package/src/styles/vaadin-grid-tree-toggle-core-styles.js +0 -78
  57. package/theme/lumo/all-imports.d.ts +0 -11
  58. package/theme/lumo/all-imports.js +0 -11
  59. package/theme/lumo/vaadin-grid-column-group.d.ts +0 -1
  60. package/theme/lumo/vaadin-grid-column-group.js +0 -1
  61. package/theme/lumo/vaadin-grid-column.d.ts +0 -1
  62. package/theme/lumo/vaadin-grid-column.js +0 -1
  63. package/theme/lumo/vaadin-grid-filter-column.d.ts +0 -2
  64. package/theme/lumo/vaadin-grid-filter-column.js +0 -2
  65. package/theme/lumo/vaadin-grid-filter.d.ts +0 -2
  66. package/theme/lumo/vaadin-grid-filter.js +0 -2
  67. package/theme/lumo/vaadin-grid-selection-column.d.ts +0 -2
  68. package/theme/lumo/vaadin-grid-selection-column.js +0 -2
  69. package/theme/lumo/vaadin-grid-sort-column.d.ts +0 -2
  70. package/theme/lumo/vaadin-grid-sort-column.js +0 -2
  71. package/theme/lumo/vaadin-grid-sorter-styles.d.ts +0 -3
  72. package/theme/lumo/vaadin-grid-sorter-styles.js +0 -52
  73. package/theme/lumo/vaadin-grid-sorter.d.ts +0 -2
  74. package/theme/lumo/vaadin-grid-sorter.js +0 -2
  75. package/theme/lumo/vaadin-grid-styles.d.ts +0 -6
  76. package/theme/lumo/vaadin-grid-styles.js +0 -405
  77. package/theme/lumo/vaadin-grid-tree-column.d.ts +0 -2
  78. package/theme/lumo/vaadin-grid-tree-column.js +0 -2
  79. package/theme/lumo/vaadin-grid-tree-toggle-styles.d.ts +0 -3
  80. package/theme/lumo/vaadin-grid-tree-toggle-styles.js +0 -81
  81. package/theme/lumo/vaadin-grid-tree-toggle.d.ts +0 -2
  82. package/theme/lumo/vaadin-grid-tree-toggle.js +0 -2
  83. package/theme/lumo/vaadin-grid.d.ts +0 -2
  84. package/theme/lumo/vaadin-grid.js +0 -2
package/all-imports.js CHANGED
@@ -1,4 +1,4 @@
1
- import './theme/lumo/all-imports.js';
1
+ import './src/all-imports.js';
2
2
 
3
3
  export * from './vaadin-grid-column-group.js';
4
4
  export * from './vaadin-grid-column.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/grid",
3
- "version": "25.0.0-alpha9",
3
+ "version": "25.0.0-beta2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -25,9 +25,6 @@
25
25
  "lit.d.ts",
26
26
  "lit.js",
27
27
  "src",
28
- "!src/styles/*-base-styles.d.ts",
29
- "!src/styles/*-base-styles.js",
30
- "theme",
31
28
  "vaadin-*.d.ts",
32
29
  "vaadin-*.js",
33
30
  "web-types.json",
@@ -47,24 +44,24 @@
47
44
  ],
48
45
  "dependencies": {
49
46
  "@open-wc/dedupe-mixin": "^1.3.0",
50
- "@vaadin/a11y-base": "25.0.0-alpha9",
51
- "@vaadin/checkbox": "25.0.0-alpha9",
52
- "@vaadin/component-base": "25.0.0-alpha9",
53
- "@vaadin/lit-renderer": "25.0.0-alpha9",
54
- "@vaadin/text-field": "25.0.0-alpha9",
55
- "@vaadin/vaadin-lumo-styles": "25.0.0-alpha9",
56
- "@vaadin/vaadin-themable-mixin": "25.0.0-alpha9",
47
+ "@vaadin/a11y-base": "25.0.0-beta2",
48
+ "@vaadin/checkbox": "25.0.0-beta2",
49
+ "@vaadin/component-base": "25.0.0-beta2",
50
+ "@vaadin/lit-renderer": "25.0.0-beta2",
51
+ "@vaadin/text-field": "25.0.0-beta2",
52
+ "@vaadin/vaadin-themable-mixin": "25.0.0-beta2",
57
53
  "lit": "^3.0.0"
58
54
  },
59
55
  "devDependencies": {
60
- "@vaadin/chai-plugins": "25.0.0-alpha9",
61
- "@vaadin/test-runner-commands": "25.0.0-alpha9",
56
+ "@vaadin/chai-plugins": "25.0.0-beta2",
57
+ "@vaadin/test-runner-commands": "25.0.0-beta2",
62
58
  "@vaadin/testing-helpers": "^2.0.0",
63
- "sinon": "^18.0.0"
59
+ "@vaadin/vaadin-lumo-styles": "25.0.0-beta2",
60
+ "sinon": "^21.0.0"
64
61
  },
65
62
  "web-types": [
66
63
  "web-types.json",
67
64
  "web-types.lit.json"
68
65
  ],
69
- "gitHead": "bbe4720721e0955ffc87a79b412bee38b1f0eb1e"
66
+ "gitHead": "e078f8371ae266f05c7ca1ec25686cc489c83f24"
70
67
  }
@@ -79,7 +79,7 @@ function compare(a, b) {
79
79
  * Sorts the given array of items based on the sorting rules and returns the result.
80
80
  *
81
81
  * @param {Array<any>} items
82
- * @param {Array<GridSorterDefinition>} items
82
+ * @param {Array<GridSorterDefinition>} sortOrders
83
83
  * @return {Array<any>}
84
84
  */
85
85
  function multiSort(items, sortOrders) {
@@ -101,6 +101,7 @@ function multiSort(items, sortOrders) {
101
101
 
102
102
  /**
103
103
  * @param {!Array<!GridItem>} items
104
+ * @param {Array<GridFilterDefinition>} filters
104
105
  * @return {!Array<!GridItem>}
105
106
  */
106
107
  function filter(items, filters) {
@@ -120,7 +121,7 @@ function filter(items, filters) {
120
121
  * Creates a new grid compatible data provider that serves the items
121
122
  * from the given array as data when requested by the grid.
122
123
  *
123
- * @param {Array<any>} items
124
+ * @param {Array<any>} allItems
124
125
  * @return {GridDataProvider<any>}
125
126
  */
126
127
  export const createArrayDataProvider = (allItems) => {
@@ -3,19 +3,12 @@
3
3
  * Copyright (c) 2016 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import '@vaadin/component-base/src/style-props.js';
6
+ import '@vaadin/component-base/src/styles/style-props.js';
7
7
  import { css } from 'lit';
8
8
 
9
9
  export const gridStyles = css`
10
- @keyframes vaadin-grid-appear {
11
- to {
12
- opacity: 1;
13
- }
14
- }
15
-
16
10
  :host {
17
11
  display: flex;
18
- animation: 1ms vaadin-grid-appear;
19
12
  max-width: 100%;
20
13
  height: 400px;
21
14
  min-height: var(--_grid-min-height, 0);
@@ -25,13 +18,12 @@ export const gridStyles = css`
25
18
  box-sizing: border-box;
26
19
  -webkit-tap-highlight-color: transparent;
27
20
  background: var(--vaadin-grid-background, var(--vaadin-background-color));
28
- border: var(--_border-width) solid var(--vaadin-grid-border-color, var(--vaadin-border-color));
21
+ border: var(--_border-width) solid var(--_border-color);
29
22
  cursor: default;
23
+ --_border-color: var(--vaadin-grid-border-color, var(--vaadin-border-color-secondary));
30
24
  --_border-width: 0;
31
- --_row-border-width: var(--vaadin-grid-cell-border-width, 1px);
32
- --_column-border-width: var(--vaadin-grid-cell-border-width, 0);
33
- --_cell-padding: var(--vaadin-grid-cell-padding, var(--vaadin-padding-container));
34
- --_selection-background-image: none;
25
+ --_row-border-width: var(--vaadin-grid-row-border-width, 1px);
26
+ --_column-border-width: var(--vaadin-grid-column-border-width, 0px);
35
27
  border-radius: var(--_border-radius);
36
28
  --_border-radius: 0;
37
29
  }
@@ -49,7 +41,7 @@ export const gridStyles = css`
49
41
  /* Variant: No outer border */
50
42
  :host(:not([theme~='no-border'])) {
51
43
  --_border-width: var(--vaadin-grid-border-width, 1px);
52
- --_border-radius: var(--vaadin-grid-border-radius, var(--vaadin-radius-l));
44
+ --_border-radius: var(--vaadin-grid-border-radius, var(--vaadin-radius-m));
53
45
  }
54
46
 
55
47
  :host([all-rows-visible]) {
@@ -79,6 +71,7 @@ export const gridStyles = css`
79
71
  width: 100%;
80
72
  left: 0;
81
73
  min-height: 1px;
74
+ z-index: 1;
82
75
  }
83
76
 
84
77
  #table {
@@ -102,7 +95,14 @@ export const gridStyles = css`
102
95
  position: sticky;
103
96
  left: 0;
104
97
  width: 100%;
105
- z-index: 1;
98
+ }
99
+
100
+ :host([overflow~='top']) #header,
101
+ :host([overflow~='bottom']) #footer,
102
+ :host([navigating]) #header:has(tr:last-child:focus-within),
103
+ :host([navigating]) #footer:has(tr:first-child:focus-within),
104
+ [empty-state] #header {
105
+ z-index: 2;
106
106
  }
107
107
 
108
108
  :host([dir='rtl']) #items,
@@ -127,7 +127,7 @@ export const gridStyles = css`
127
127
  [part~='reorder-ghost'] {
128
128
  font-size: var(--vaadin-grid-header-font-size, 1em);
129
129
  font-weight: var(--vaadin-grid-header-font-weight, 500);
130
- color: var(--vaadin-grid-header-color, var(--vaadin-color));
130
+ color: var(--vaadin-grid-header-text-color, var(--vaadin-text-color));
131
131
  }
132
132
 
133
133
  [part~='row'] {
@@ -138,6 +138,10 @@ export const gridStyles = css`
138
138
  position: relative;
139
139
  }
140
140
 
141
+ [part~='row']:not(:focus-within) {
142
+ --_non-focused-row-none: none;
143
+ }
144
+
141
145
  [part~='row'][loading] [part~='body-cell'] ::slotted(vaadin-grid-cell-content) {
142
146
  visibility: hidden;
143
147
  }
@@ -153,110 +157,187 @@ export const gridStyles = css`
153
157
  [part~='cell'] {
154
158
  padding: 0;
155
159
  box-sizing: border-box;
156
- }
157
-
158
- [part~='row'],
159
- [part~='cell'] {
160
- --_hover-background-image: var(--vaadin-grid-cell-background-hover, none);
161
- background:
162
- var(--_hover-background-image), var(--_selection-background-image),
163
- var(--vaadin-grid-cell-background, var(--vaadin-background-color));
164
- }
165
-
166
- [part~='cell']:not([part~='details-cell']) {
160
+ background: var(--vaadin-grid-cell-background, var(--vaadin-background-color));
161
+ border-block: var(--_row-border-width) solid var(--_border-color);
162
+ margin-top: calc(var(--_row-border-width) * -1);
163
+
164
+ /*
165
+ Box-shadows are used to create a "fake" border at the end of the cell/row, which is visible when a row/cell ends
166
+ before the edge of the grid viewport, as well as frozen columns and rows (header and footer).
167
+ If there are frozen columns, we'll make the "fake box-shadow border" on the header and footer opaque by rendering
168
+ both the border color and cell background color, so that a semi-transparent border color doesn't "stack" when
169
+ scrolling horizontally.
170
+ */
171
+ --_fake-border:
172
+ 0 calc(var(--_top, 0) * var(--_row-border-width) * -1) 0 0 var(--_border-color),
173
+ 0 calc(var(--_top-opaque, 0) * var(--_row-border-width) * -1) 0 0
174
+ var(--vaadin-grid-cell-background-color, var(--vaadin-background-color)),
175
+ 0 calc(var(--_bottom, 0) * var(--_row-border-width)) 0 0 var(--_border-color),
176
+ 0 calc(var(--_bottom-opaque, 0) * var(--_row-border-width)) 0 0
177
+ var(--vaadin-grid-cell-background-color, var(--vaadin-background-color)),
178
+ calc(var(--_start, 0) * var(--_column-border-width) * -1) 0 0 0 var(--_border-color),
179
+ calc(var(--_end, 0) * var(--_column-border-width)) 0 0 0 var(--_border-color),
180
+ calc(var(--_end-opaque, 0) * var(--_column-border-width)) 0 0 0
181
+ var(--vaadin-grid-cell-background-color, var(--vaadin-background-color));
182
+ box-shadow: var(--_fake-border);
183
+ }
184
+
185
+ [part~='cell']:where(:not([part~='details-cell'])) {
167
186
  flex-shrink: 0;
168
187
  flex-grow: 1;
169
- box-sizing: border-box;
170
188
  display: flex;
171
189
  width: 100%;
172
190
  position: relative;
173
191
  align-items: center;
174
192
  white-space: nowrap;
193
+ border-inline-start: var(--_column-border-width) solid var(--_border-color);
175
194
  }
176
195
 
177
- :focus-visible,
178
- [part~='row']::after {
179
- outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
180
- outline-offset: calc(var(--vaadin-focus-ring-width) * -1);
196
+ [part~='first-column-cell'] {
197
+ border-inline-start: 0;
181
198
  }
182
199
 
183
- [part~='row']:focus-visible {
184
- z-index: 1;
200
+ [part~='first-header-row-cell'],
201
+ [part~='first-footer-row-cell'],
202
+ [part~='first-row-cell'] {
203
+ margin-top: 0;
204
+ border-top: 0;
185
205
  }
186
206
 
187
- /* Used for focus outline and drag'n'drop target indication */
188
- [part~='row']::after {
189
- content: '';
190
- position: absolute;
191
- inset: calc(var(--_row-border-width) * -1) 0;
192
- z-index: 3;
193
- transform: translateX(var(--_grid-horizontal-scroll-position));
194
- pointer-events: none;
195
- visibility: hidden;
207
+ table:has(#header > tr:not([hidden])) [part~='first-row-cell'] {
208
+ border-top: var(--_row-border-width) solid var(--_border-color);
196
209
  }
197
210
 
198
- [part~='row']:focus-visible::after {
199
- visibility: visible;
211
+ [part~='last-column-cell'] {
212
+ --_end: 1;
200
213
  }
201
214
 
202
- /* Variant: wrap cell contents */
215
+ [part~='last-column-cell']:is([part~='header-cell'], [part~='footer-cell']) {
216
+ --_end-opaque: 1;
217
+ }
203
218
 
204
- :host([theme~='wrap-cell-content']) [part~='cell']:not([part~='details-cell']) {
205
- white-space: normal;
219
+ [part~='last-row-cell']:where(:not([part~='details-opened-row-cell'])),
220
+ [part~='last-footer-row-cell'] {
221
+ border-bottom: 0;
222
+ --_bottom: 1;
206
223
  }
207
224
 
208
- /* Variant: row & column borders */
225
+ [part~='last-frozen-cell'] {
226
+ --_end: 1;
227
+ }
209
228
 
210
- :host([theme~='no-row-borders']) {
211
- --_row-border-width: 0;
229
+ [part~='last-frozen-cell'] + [part~='cell'] {
230
+ border-inline-start-color: transparent;
212
231
  }
213
232
 
214
- :host([theme~='column-borders']) {
215
- --_column-border-width: var(--vaadin-grid-cell-border-width, 1px);
233
+ [part~='first-frozen-to-end-cell'] {
234
+ border-inline-start: 0;
235
+ --_start: 1;
216
236
  }
217
237
 
218
- [part~='cell']:not([part~='last-column-cell'], [part~='details-cell']) {
219
- border-inline-end: var(--_column-border-width, 0) solid
220
- var(--vaadin-grid-cell-border-color, var(--vaadin-border-color));
238
+ [part~='last-header-row-cell'] {
239
+ border-bottom: 0;
221
240
  }
222
241
 
223
- [part~='cell']:where(:not([part~='details-cell'], [part~='first-row-cell'])) {
224
- border-top: var(--_row-border-width) solid var(--vaadin-grid-cell-border-color, var(--vaadin-border-color));
242
+ :host([overflow~='top']) [part~='last-header-row-cell'],
243
+ [empty-state] [part~='last-header-row-cell'] {
244
+ --_bottom: 1;
225
245
  }
226
246
 
227
- [part~='first-header-row-cell'] {
228
- border-top: 0;
247
+ #header:has(:is([frozen], [frozen-to-end])) [part~='last-header-row-cell'] {
248
+ --_bottom-opaque: 1;
229
249
  }
230
250
 
231
- [part~='last-header-row-cell'] {
232
- border-bottom: var(--_row-border-width, 1px) solid var(--vaadin-grid-cell-border-color, var(--vaadin-border-color));
251
+ :host([overflow~='bottom']) [part~='first-footer-row-cell'],
252
+ [empty-state] [part~='first-footer-row-cell'] {
253
+ --_top: 1;
254
+ }
255
+
256
+ #footer:has(:is([frozen], [frozen-to-end])) [part~='first-footer-row-cell'] {
257
+ --_top-opaque: 1;
258
+ }
259
+
260
+ table:has(#footer > tr:not([hidden])) [part~='last-row-cell']:not([part~='details-opened-row-cell']) {
261
+ border-bottom: var(--_row-border-width) solid var(--_border-color);
262
+ --_bottom: 0;
263
+ }
264
+
265
+ [part~='body-cell']:where(:not([part~='details-cell'])) {
266
+ --_highlight-background-color: var(--vaadin-grid-row-highlight-background-color, transparent);
267
+ --_highlight-background-image: linear-gradient(
268
+ var(--_highlight-background-color),
269
+ var(--_highlight-background-color)
270
+ );
271
+ background:
272
+ var(--_hover-background-image, none), var(--_selected-background-image, none), var(--_highlight-background-image),
273
+ var(--vaadin-grid-cell-background-color, var(--vaadin-background-color));
233
274
  }
234
275
 
235
- [part~='first-footer-row-cell'] {
236
- border-top: var(--_row-border-width, 1px) solid var(--vaadin-grid-cell-border-color, var(--vaadin-border-color));
276
+ /* Variant: wrap cell contents */
277
+
278
+ :host([theme~='wrap-cell-content']) [part~='cell']:not([part~='details-cell']) {
279
+ white-space: normal;
237
280
  }
238
281
 
239
282
  /* Variant: row stripes */
240
- :host([theme~='row-stripes']) [part~='odd-row'],
241
- :host([theme~='row-stripes']) [part~='odd-row'] [part~='cell'] {
242
- --vaadin-grid-cell-background: var(
243
- --vaadin-grid-odd-row-cell-background,
244
- linear-gradient(var(--vaadin-background-container), var(--vaadin-background-container))
283
+ [part~='odd-row'] {
284
+ --vaadin-grid-cell-background-color: var(--vaadin-grid-row-odd-background-color, var(--vaadin-background-color));
285
+ }
286
+
287
+ :host([theme~='row-stripes']) [part~='odd-row'] {
288
+ --vaadin-grid-cell-background-color: var(
289
+ --vaadin-grid-row-odd-background-color,
290
+ color-mix(in srgb, var(--vaadin-text-color) 4%, var(--vaadin-background-color))
245
291
  );
246
292
  }
247
293
 
294
+ /* Raise highlighted rows above others */
295
+
296
+ [part~='row']:focus,
297
+ [part~='row']:focus-within,
298
+ [part~='body-row']:where([selected]) {
299
+ z-index: 3;
300
+ }
301
+
302
+ @container style(--vaadin-grid-row-odd-background-color) {
303
+ [part~='odd-row'] {
304
+ z-index: 1;
305
+ }
306
+ }
307
+
308
+ /* Row hover */
309
+ @media (any-hover: hover) {
310
+ @container style(--vaadin-grid-row-hover-background-color) {
311
+ [part~='body-row']:hover {
312
+ z-index: 2;
313
+ }
314
+ }
315
+
316
+ [part~='body-row']:hover [part~='cell']:where(:not([part~='details-cell'])) {
317
+ --_hover-background-color: var(--vaadin-grid-row-hover-background-color, transparent);
318
+ --_hover-background-image: linear-gradient(var(--_hover-background-color), var(--_hover-background-color));
319
+ }
320
+ }
321
+
248
322
  [part~='details-cell'] {
249
323
  position: absolute;
250
324
  bottom: 0;
251
325
  width: 100%;
326
+ margin-top: 0;
327
+ border-top: 0;
328
+ }
329
+
330
+ [part~='last-row-cell'] + [part~='details-cell'] {
331
+ border-bottom: 0;
252
332
  }
253
333
 
254
334
  [part~='cell'] ::slotted(vaadin-grid-cell-content) {
255
335
  display: block;
256
336
  overflow: hidden;
257
337
  text-overflow: ellipsis;
258
- padding: var(--_cell-padding);
338
+ padding: var(--vaadin-grid-cell-padding, var(--vaadin-padding-container));
259
339
  flex: 1;
340
+ min-height: 1lh;
260
341
  min-width: 0;
261
342
  }
262
343
 
@@ -267,12 +348,12 @@ export const gridStyles = css`
267
348
  }
268
349
 
269
350
  /* Selected row */
270
- [part~='row'][selected] [part~='body-cell']:not([part~='details-cell']) {
271
- --_color: color-mix(in srgb, currentColor 8%, transparent);
272
- --_selection-background-image: var(
273
- --vaadin-grid-row-selected-background,
274
- linear-gradient(var(--_color), var(--_color))
351
+ [part~='body-row'][selected] {
352
+ --_selected-background-color: var(
353
+ --vaadin-grid-row-selected-background-color,
354
+ color-mix(in srgb, currentColor 8%, transparent)
275
355
  );
356
+ --_selected-background-image: linear-gradient(var(--_selected-background-color), var(--_selected-background-color));
276
357
  }
277
358
 
278
359
  /* Empty state */
@@ -287,6 +368,7 @@ export const gridStyles = css`
287
368
  inset: 0;
288
369
  flex: 1;
289
370
  overflow: hidden;
371
+ margin-top: calc(var(--_row-border-width) * -1);
290
372
  }
291
373
 
292
374
  #emptystaterow {
@@ -298,7 +380,14 @@ export const gridStyles = css`
298
380
  display: block;
299
381
  flex: 1;
300
382
  overflow: auto;
301
- padding: var(--_cell-padding);
383
+ padding: var(--vaadin-grid-cell-padding, var(--vaadin-padding-container));
384
+ border-top: var(--_row-border-width) solid transparent;
385
+ outline: none;
386
+ }
387
+
388
+ #emptystatecell:focus-visible {
389
+ outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
390
+ outline-offset: calc(var(--vaadin-focus-ring-width) * -1);
302
391
  }
303
392
 
304
393
  /* Reordering styles */
@@ -315,7 +404,7 @@ export const gridStyles = css`
315
404
  box-shadow:
316
405
  0 0 0 1px hsla(0deg, 0%, 0%, 0.2),
317
406
  0 8px 24px -2px hsla(0deg, 0%, 0%, 0.2);
318
- padding: var(--_cell-padding) !important;
407
+ padding: var(--vaadin-grid-cell-padding, var(--vaadin-padding-container)) !important;
319
408
  border-radius: 3px;
320
409
 
321
410
  /* Prevent overflowing the grid in Firefox */
@@ -340,6 +429,7 @@ export const gridStyles = css`
340
429
  z-index: 1;
341
430
  -webkit-backdrop-filter: var(--_reorder-curtain-filter);
342
431
  backdrop-filter: var(--_reorder-curtain-filter);
432
+ outline: 0;
343
433
  }
344
434
 
345
435
  :host([reordering]) [part~='cell'][reorder-status='allowed'] {
@@ -402,13 +492,12 @@ export const gridStyles = css`
402
492
  inset-inline: 0 auto;
403
493
  }
404
494
 
405
- [first-frozen-to-end] {
406
- margin-inline-start: auto;
495
+ [frozen-to-end] [part~='resize-handle'] {
496
+ translate: calc(var(--_column-border-width) * -1);
407
497
  }
408
498
 
409
- /* Hide resize handle if scrolled to end */
410
- :host(:not([overflow~='end'])) [first-frozen-to-end] [part~='resize-handle'] {
411
- display: none;
499
+ [first-frozen-to-end] {
500
+ margin-inline-start: auto;
412
501
  }
413
502
 
414
503
  #scroller:is([column-resizing], [range-selecting]) {
@@ -416,6 +505,69 @@ export const gridStyles = css`
416
505
  user-select: none;
417
506
  }
418
507
 
508
+ /* Focus outline element, also used for d'n'd indication */
509
+ :is([part~='row'], [part~='cell'])::after {
510
+ position: absolute;
511
+ inset: calc(var(--_row-border-width) * -1) calc(var(--_column-border-width) * -1);
512
+ z-index: 3;
513
+ pointer-events: none;
514
+ outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
515
+ outline-offset: calc(var(--vaadin-focus-ring-width) * -1);
516
+ }
517
+
518
+ [part~='first-column-cell']::after {
519
+ inset-inline-start: 0;
520
+ }
521
+
522
+ [part~='last-column-cell']::after {
523
+ inset-inline-end: 0;
524
+ }
525
+
526
+ #header [part~='row']:first-child::after,
527
+ [part~='first-header-row-cell']::after,
528
+ [part*='first-row']::after {
529
+ top: 0;
530
+ }
531
+
532
+ table:has(#header > tr:not([hidden])) [part~='first-row-cell']::after {
533
+ top: calc(var(--_row-border-width) * -1);
534
+ }
535
+
536
+ #footer [part~='row']:last-child::after,
537
+ [part~='last-footer-row-cell']::after,
538
+ [part~='last-row']::after,
539
+ [part~='last-row-cell']::after {
540
+ bottom: 0;
541
+ }
542
+
543
+ #header [part~='row']:last-child::after,
544
+ table:has(#footer > tr:not([hidden])) [part*='last-row']::after {
545
+ bottom: calc(var(--_row-border-width) * -1);
546
+ }
547
+
548
+ :host([navigating]) [part~='row']:focus,
549
+ :host([navigating]) [part~='cell']:focus {
550
+ outline: 0;
551
+ }
552
+
553
+ [part~='row']::after {
554
+ transform: translateX(var(--_grid-horizontal-scroll-position));
555
+ inset-inline: 0;
556
+ bottom: 0;
557
+ }
558
+
559
+ [part~='row']:focus-visible,
560
+ [part~='cell']:focus-visible {
561
+ outline: 0;
562
+ }
563
+
564
+ [part~='row']:focus-visible::after,
565
+ [part~='cell']:focus-visible::after,
566
+ :host([navigating]) [part~='row']:focus::after,
567
+ :host([navigating]) [part~='cell']:focus::after {
568
+ content: '';
569
+ }
570
+
419
571
  /* Drag'n'drop styles */
420
572
  :host([dragover]) {
421
573
  outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
@@ -427,31 +579,32 @@ export const gridStyles = css`
427
579
  }
428
580
 
429
581
  [part~='row'][dragover]::after {
430
- visibility: visible;
582
+ content: '';
431
583
  }
432
584
 
433
585
  [part~='row'][dragover='above']::after {
434
586
  outline: 0;
435
587
  border-top: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
588
+ }
589
+
590
+ [part~='row']:not([part*='first-row'])[dragover='above']::after,
591
+ table:has(#header > tr:not([hidden])) [part*='first-row'][dragover='above']::after {
436
592
  top: calc(var(--vaadin-focus-ring-width) / -2);
437
593
  }
438
594
 
439
595
  [part~='row'][dragover='below']::after {
440
596
  outline: 0;
441
597
  border-bottom: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
442
- bottom: calc(var(--vaadin-focus-ring-width) / -2);
443
- }
444
-
445
- :is([part~='row']:first-child, [part~='first-row'])::after {
446
- top: 0;
447
598
  }
448
599
 
449
- :is([part~='row']:last-child, [part~='last-row'])::after {
450
- bottom: 0;
600
+ [part~='row']:not([part*='last-row'])[dragover='below']::after,
601
+ table:has(#footer > tr:not([hidden])) [part*='last-row'][dragover='below']::after {
602
+ bottom: calc(var(--vaadin-focus-ring-width) / -2);
451
603
  }
452
604
 
453
605
  [part~='row'][dragstart] [part~='cell'] {
454
- border-top: 0 !important;
606
+ border-block-color: transparent !important;
607
+ box-shadow: none;
455
608
  }
456
609
 
457
610
  [part~='row'][dragstart] [part~='cell'][last-column] {
@@ -507,4 +660,16 @@ export const gridStyles = css`
507
660
  #sizer [part~='cell']::before {
508
661
  content: '-';
509
662
  }
663
+
664
+ @media (forced-colors: active) {
665
+ :host([overflow~='top']) [part~='last-header-row-cell'] {
666
+ border-bottom: var(--_row-border-width) solid;
667
+ margin-bottom: calc(var(--_row-border-width) * -1);
668
+ }
669
+
670
+ :host([overflow~='bottom']) [part~='first-footer-row-cell'] {
671
+ border-top: var(--_row-border-width) solid;
672
+ margin-top: calc(var(--_row-border-width) * -1);
673
+ }
674
+ }
510
675
  `;
@@ -3,7 +3,7 @@
3
3
  * Copyright (c) 2016 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import '@vaadin/component-base/src/style-props.js';
6
+ import '@vaadin/component-base/src/styles/style-props.js';
7
7
  import { css } from 'lit';
8
8
 
9
9
  export const gridSorterStyles = css`
@@ -12,7 +12,7 @@ export const gridSorterStyles = css`
12
12
  align-items: center;
13
13
  cursor: pointer;
14
14
  max-width: 100%;
15
- gap: var(--vaadin-gap-container-inline);
15
+ gap: var(--vaadin-gap-s);
16
16
  -webkit-user-select: none;
17
17
  user-select: none;
18
18
  -webkit-tap-highlight-color: transparent;
@@ -27,6 +27,8 @@ export const gridSorterStyles = css`
27
27
  [part='indicators'] {
28
28
  position: relative;
29
29
  flex: none;
30
+ height: 1lh;
31
+ color: var(--vaadin-text-color-disabled);
30
32
  }
31
33
 
32
34
  [part='order'] {
@@ -34,6 +36,7 @@ export const gridSorterStyles = css`
34
36
  vertical-align: super;
35
37
  font-size: 0.75em;
36
38
  line-height: 1;
39
+ color: var(--vaadin-text-color-secondary);
37
40
  }
38
41
 
39
42
  [part='indicators']::before {
@@ -55,6 +58,16 @@ export const gridSorterStyles = css`
55
58
  padding-block: 6px 0;
56
59
  }
57
60
 
61
+ :host([direction]) [part='indicators'] {
62
+ color: var(--vaadin-text-color-secondary);
63
+ }
64
+
65
+ @media (any-hover: hover) {
66
+ :host(:hover) [part='indicators'] {
67
+ color: var(--vaadin-text-color);
68
+ }
69
+ }
70
+
58
71
  @media (forced-colors: active) {
59
72
  [part='indicators']::before {
60
73
  background: CanvasText;