@vaadin/grid 25.0.0-alpha9 → 25.0.0-beta1

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 (83) 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 +251 -91
  5. package/src/styles/vaadin-grid-sorter-base-styles.js +15 -2
  6. package/src/styles/vaadin-grid-tree-toggle-base-styles.js +3 -3
  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-event-context-mixin.d.ts +2 -0
  14. package/src/vaadin-grid-event-context-mixin.js +1 -0
  15. package/src/vaadin-grid-filter.js +1 -1
  16. package/src/vaadin-grid-helpers.js +9 -0
  17. package/src/vaadin-grid-keyboard-navigation-mixin.js +1 -5
  18. package/src/vaadin-grid-mixin.d.ts +1 -0
  19. package/src/vaadin-grid-mixin.js +36 -38
  20. package/src/vaadin-grid-resize-mixin.d.ts +10 -0
  21. package/src/vaadin-grid-resize-mixin.js +73 -0
  22. package/src/vaadin-grid-row-details-mixin.js +1 -1
  23. package/src/vaadin-grid-scroll-mixin.js +5 -87
  24. package/src/vaadin-grid-selection-column-base-mixin.d.ts +1 -1
  25. package/src/vaadin-grid-selection-column-base-mixin.js +1 -1
  26. package/src/vaadin-grid-selection-column.d.ts +2 -0
  27. package/src/vaadin-grid-selection-column.js +2 -1
  28. package/src/vaadin-grid-sort-column.d.ts +2 -0
  29. package/src/vaadin-grid-sorter.d.ts +3 -3
  30. package/src/vaadin-grid-sorter.js +4 -4
  31. package/src/vaadin-grid-tree-column-mixin.js +2 -7
  32. package/src/vaadin-grid-tree-toggle.d.ts +4 -4
  33. package/src/vaadin-grid-tree-toggle.js +5 -5
  34. package/src/vaadin-grid.d.ts +1 -0
  35. package/src/vaadin-grid.js +3 -1
  36. package/vaadin-grid-column-group.js +1 -1
  37. package/vaadin-grid-column.js +1 -1
  38. package/vaadin-grid-filter-column.js +1 -1
  39. package/vaadin-grid-filter.js +1 -1
  40. package/vaadin-grid-selection-column.js +1 -1
  41. package/vaadin-grid-sort-column.js +1 -1
  42. package/vaadin-grid-sorter.js +1 -1
  43. package/vaadin-grid-tree-column.js +1 -1
  44. package/vaadin-grid-tree-toggle.js +1 -1
  45. package/vaadin-grid.js +1 -1
  46. package/web-types.json +13 -13
  47. package/web-types.lit.json +12 -12
  48. package/src/styles/vaadin-grid-core-styles.d.ts +0 -8
  49. package/src/styles/vaadin-grid-core-styles.js +0 -388
  50. package/src/styles/vaadin-grid-filter-core-styles.d.ts +0 -8
  51. package/src/styles/vaadin-grid-filter-core-styles.js +0 -18
  52. package/src/styles/vaadin-grid-sorter-core-styles.d.ts +0 -8
  53. package/src/styles/vaadin-grid-sorter-core-styles.js +0 -61
  54. package/src/styles/vaadin-grid-tree-toggle-core-styles.d.ts +0 -8
  55. package/src/styles/vaadin-grid-tree-toggle-core-styles.js +0 -78
  56. package/theme/lumo/all-imports.d.ts +0 -11
  57. package/theme/lumo/all-imports.js +0 -11
  58. package/theme/lumo/vaadin-grid-column-group.d.ts +0 -1
  59. package/theme/lumo/vaadin-grid-column-group.js +0 -1
  60. package/theme/lumo/vaadin-grid-column.d.ts +0 -1
  61. package/theme/lumo/vaadin-grid-column.js +0 -1
  62. package/theme/lumo/vaadin-grid-filter-column.d.ts +0 -2
  63. package/theme/lumo/vaadin-grid-filter-column.js +0 -2
  64. package/theme/lumo/vaadin-grid-filter.d.ts +0 -2
  65. package/theme/lumo/vaadin-grid-filter.js +0 -2
  66. package/theme/lumo/vaadin-grid-selection-column.d.ts +0 -2
  67. package/theme/lumo/vaadin-grid-selection-column.js +0 -2
  68. package/theme/lumo/vaadin-grid-sort-column.d.ts +0 -2
  69. package/theme/lumo/vaadin-grid-sort-column.js +0 -2
  70. package/theme/lumo/vaadin-grid-sorter-styles.d.ts +0 -3
  71. package/theme/lumo/vaadin-grid-sorter-styles.js +0 -52
  72. package/theme/lumo/vaadin-grid-sorter.d.ts +0 -2
  73. package/theme/lumo/vaadin-grid-sorter.js +0 -2
  74. package/theme/lumo/vaadin-grid-styles.d.ts +0 -6
  75. package/theme/lumo/vaadin-grid-styles.js +0 -405
  76. package/theme/lumo/vaadin-grid-tree-column.d.ts +0 -2
  77. package/theme/lumo/vaadin-grid-tree-column.js +0 -2
  78. package/theme/lumo/vaadin-grid-tree-toggle-styles.d.ts +0 -3
  79. package/theme/lumo/vaadin-grid-tree-toggle-styles.js +0 -81
  80. package/theme/lumo/vaadin-grid-tree-toggle.d.ts +0 -2
  81. package/theme/lumo/vaadin-grid-tree-toggle.js +0 -2
  82. package/theme/lumo/vaadin-grid.d.ts +0 -2
  83. 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-beta1",
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-beta1",
48
+ "@vaadin/checkbox": "25.0.0-beta1",
49
+ "@vaadin/component-base": "25.0.0-beta1",
50
+ "@vaadin/lit-renderer": "25.0.0-beta1",
51
+ "@vaadin/text-field": "25.0.0-beta1",
52
+ "@vaadin/vaadin-themable-mixin": "25.0.0-beta1",
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-beta1",
57
+ "@vaadin/test-runner-commands": "25.0.0-beta1",
62
58
  "@vaadin/testing-helpers": "^2.0.0",
63
- "sinon": "^18.0.0"
59
+ "@vaadin/vaadin-lumo-styles": "25.0.0-beta1",
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": "1d20cf54e582d1f2e209126d4586f8b4c01c50e0"
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'] {
@@ -153,109 +153,185 @@ export const gridStyles = css`
153
153
  [part~='cell'] {
154
154
  padding: 0;
155
155
  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']) {
156
+ background: var(--vaadin-grid-cell-background, var(--vaadin-background-color));
157
+ border-block: var(--_row-border-width) solid var(--_border-color);
158
+ margin-top: calc(var(--_row-border-width) * -1);
159
+
160
+ /*
161
+ Box-shadows are used to create a "fake" border at the end of the cell/row, which is visible when a row/cell ends
162
+ before the edge of the grid viewport, as well as frozen columns and rows (header and footer).
163
+ If there are frozen columns, we'll make the "fake box-shadow border" on the header and footer opaque by rendering
164
+ both the border color and cell background color, so that a semi-transparent border color doesn't "stack" when
165
+ scrolling horizontally.
166
+ */
167
+ --_fake-border:
168
+ 0 calc(var(--_top, 0) * var(--_row-border-width) * -1) 0 0 var(--_border-color),
169
+ 0 calc(var(--_top-opaque, 0) * var(--_row-border-width) * -1) 0 0
170
+ var(--vaadin-grid-cell-background-color, var(--vaadin-background-color)),
171
+ 0 calc(var(--_bottom, 0) * var(--_row-border-width)) 0 0 var(--_border-color),
172
+ 0 calc(var(--_bottom-opaque, 0) * var(--_row-border-width)) 0 0
173
+ var(--vaadin-grid-cell-background-color, var(--vaadin-background-color)),
174
+ calc(var(--_start, 0) * var(--_column-border-width) * -1) 0 0 0 var(--_border-color),
175
+ calc(var(--_end, 0) * var(--_column-border-width)) 0 0 0 var(--_border-color),
176
+ calc(var(--_end-opaque, 0) * var(--_column-border-width)) 0 0 0
177
+ var(--vaadin-grid-cell-background-color, var(--vaadin-background-color));
178
+ box-shadow: var(--_fake-border);
179
+ }
180
+
181
+ [part~='cell']:where(:not([part~='details-cell'])) {
167
182
  flex-shrink: 0;
168
183
  flex-grow: 1;
169
- box-sizing: border-box;
170
184
  display: flex;
171
185
  width: 100%;
172
186
  position: relative;
173
187
  align-items: center;
174
188
  white-space: nowrap;
189
+ border-inline-start: var(--_column-border-width) solid var(--_border-color);
175
190
  }
176
191
 
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);
192
+ [part~='first-column-cell'] {
193
+ border-inline-start: 0;
181
194
  }
182
195
 
183
- [part~='row']:focus-visible {
184
- z-index: 1;
196
+ [part~='first-header-row-cell'],
197
+ [part~='first-footer-row-cell'],
198
+ [part~='first-row-cell'] {
199
+ margin-top: 0;
200
+ border-top: 0;
185
201
  }
186
202
 
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;
203
+ table:has(#header > tr:not([hidden])) [part~='first-row-cell'] {
204
+ border-top: var(--_row-border-width) solid var(--_border-color);
196
205
  }
197
206
 
198
- [part~='row']:focus-visible::after {
199
- visibility: visible;
207
+ [part~='last-column-cell'] {
208
+ --_end: 1;
200
209
  }
201
210
 
202
- /* Variant: wrap cell contents */
211
+ [part~='last-column-cell']:is([part~='header-cell'], [part~='footer-cell']) {
212
+ --_end-opaque: 1;
213
+ }
203
214
 
204
- :host([theme~='wrap-cell-content']) [part~='cell']:not([part~='details-cell']) {
205
- white-space: normal;
215
+ [part~='last-row-cell']:where(:not([part~='details-opened-row-cell'])),
216
+ [part~='last-footer-row-cell'] {
217
+ border-bottom: 0;
218
+ --_bottom: 1;
206
219
  }
207
220
 
208
- /* Variant: row & column borders */
221
+ [part~='last-frozen-cell'] {
222
+ --_end: 1;
223
+ }
209
224
 
210
- :host([theme~='no-row-borders']) {
211
- --_row-border-width: 0;
225
+ [part~='last-frozen-cell'] + [part~='cell'] {
226
+ border-inline-start-color: transparent;
212
227
  }
213
228
 
214
- :host([theme~='column-borders']) {
215
- --_column-border-width: var(--vaadin-grid-cell-border-width, 1px);
229
+ [part~='first-frozen-to-end-cell'] {
230
+ border-inline-start: 0;
231
+ --_start: 1;
216
232
  }
217
233
 
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));
234
+ [part~='last-header-row-cell'] {
235
+ border-bottom: 0;
221
236
  }
222
237
 
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));
238
+ :host([overflow~='top']) [part~='last-header-row-cell'],
239
+ [empty-state] [part~='last-header-row-cell'] {
240
+ --_bottom: 1;
225
241
  }
226
242
 
227
- [part~='first-header-row-cell'] {
228
- border-top: 0;
243
+ #header:has(:is([frozen], [frozen-to-end])) [part~='last-header-row-cell'] {
244
+ --_bottom-opaque: 1;
229
245
  }
230
246
 
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));
247
+ :host([overflow~='bottom']) [part~='first-footer-row-cell'],
248
+ [empty-state] [part~='first-footer-row-cell'] {
249
+ --_top: 1;
250
+ }
251
+
252
+ #footer:has(:is([frozen], [frozen-to-end])) [part~='first-footer-row-cell'] {
253
+ --_top-opaque: 1;
254
+ }
255
+
256
+ table:has(#footer > tr:not([hidden])) [part~='last-row-cell']:not([part~='details-opened-row-cell']) {
257
+ border-bottom: var(--_row-border-width) solid var(--_border-color);
258
+ --_bottom: 0;
259
+ }
260
+
261
+ [part~='body-cell']:where(:not([part~='details-cell'])) {
262
+ --_highlight-background-color: var(--vaadin-grid-row-highlight-background-color, transparent);
263
+ --_highlight-background-image: linear-gradient(
264
+ var(--_highlight-background-color),
265
+ var(--_highlight-background-color)
266
+ );
267
+ background:
268
+ var(--_hover-background-image, none), var(--_selected-background-image, none), var(--_highlight-background-image),
269
+ var(--vaadin-grid-cell-background-color, var(--vaadin-background-color));
233
270
  }
234
271
 
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));
272
+ /* Variant: wrap cell contents */
273
+
274
+ :host([theme~='wrap-cell-content']) [part~='cell']:not([part~='details-cell']) {
275
+ white-space: normal;
237
276
  }
238
277
 
239
278
  /* 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))
279
+ [part~='odd-row'] {
280
+ --vaadin-grid-cell-background-color: var(--vaadin-grid-row-odd-background-color, var(--vaadin-background-color));
281
+ }
282
+
283
+ :host([theme~='row-stripes']) [part~='odd-row'] {
284
+ --vaadin-grid-cell-background-color: var(
285
+ --vaadin-grid-row-odd-background-color,
286
+ color-mix(in srgb, var(--vaadin-text-color) 4%, var(--vaadin-background-color))
245
287
  );
246
288
  }
247
289
 
290
+ /* Raise highlighted rows above others */
291
+
292
+ [part~='row']:focus,
293
+ [part~='row']:focus-within,
294
+ [part~='body-row']:where([selected]) {
295
+ z-index: 3;
296
+ }
297
+
298
+ @container style(--vaadin-grid-row-odd-background-color) {
299
+ [part~='odd-row'] {
300
+ z-index: 1;
301
+ }
302
+ }
303
+
304
+ /* Row hover */
305
+ @media (any-hover: hover) {
306
+ @container style(--vaadin-grid-row-hover-background-color) {
307
+ [part~='body-row']:hover {
308
+ z-index: 2;
309
+ }
310
+ }
311
+
312
+ [part~='body-row']:hover [part~='cell']:where(:not([part~='details-cell'])) {
313
+ --_hover-background-color: var(--vaadin-grid-row-hover-background-color, transparent);
314
+ --_hover-background-image: linear-gradient(var(--_hover-background-color), var(--_hover-background-color));
315
+ }
316
+ }
317
+
248
318
  [part~='details-cell'] {
249
319
  position: absolute;
250
320
  bottom: 0;
251
321
  width: 100%;
322
+ margin-top: 0;
323
+ border-top: 0;
324
+ }
325
+
326
+ [part~='last-row-cell'] + [part~='details-cell'] {
327
+ border-bottom: 0;
252
328
  }
253
329
 
254
330
  [part~='cell'] ::slotted(vaadin-grid-cell-content) {
255
331
  display: block;
256
332
  overflow: hidden;
257
333
  text-overflow: ellipsis;
258
- padding: var(--_cell-padding);
334
+ padding: var(--vaadin-grid-cell-padding, var(--vaadin-padding-container));
259
335
  flex: 1;
260
336
  min-width: 0;
261
337
  }
@@ -267,12 +343,12 @@ export const gridStyles = css`
267
343
  }
268
344
 
269
345
  /* 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))
346
+ [part~='body-row'][selected] {
347
+ --_selected-background-color: var(
348
+ --vaadin-grid-row-selected-background-color,
349
+ color-mix(in srgb, currentColor 8%, transparent)
275
350
  );
351
+ --_selected-background-image: linear-gradient(var(--_selected-background-color), var(--_selected-background-color));
276
352
  }
277
353
 
278
354
  /* Empty state */
@@ -287,6 +363,7 @@ export const gridStyles = css`
287
363
  inset: 0;
288
364
  flex: 1;
289
365
  overflow: hidden;
366
+ margin-top: calc(var(--_row-border-width) * -1);
290
367
  }
291
368
 
292
369
  #emptystaterow {
@@ -298,7 +375,14 @@ export const gridStyles = css`
298
375
  display: block;
299
376
  flex: 1;
300
377
  overflow: auto;
301
- padding: var(--_cell-padding);
378
+ padding: var(--vaadin-grid-cell-padding, var(--vaadin-padding-container));
379
+ border-top: var(--_row-border-width) solid transparent;
380
+ outline: none;
381
+ }
382
+
383
+ #emptystatecell:focus-visible {
384
+ outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
385
+ outline-offset: calc(var(--vaadin-focus-ring-width) * -1);
302
386
  }
303
387
 
304
388
  /* Reordering styles */
@@ -315,7 +399,7 @@ export const gridStyles = css`
315
399
  box-shadow:
316
400
  0 0 0 1px hsla(0deg, 0%, 0%, 0.2),
317
401
  0 8px 24px -2px hsla(0deg, 0%, 0%, 0.2);
318
- padding: var(--_cell-padding) !important;
402
+ padding: var(--vaadin-grid-cell-padding, var(--vaadin-padding-container)) !important;
319
403
  border-radius: 3px;
320
404
 
321
405
  /* Prevent overflowing the grid in Firefox */
@@ -340,6 +424,7 @@ export const gridStyles = css`
340
424
  z-index: 1;
341
425
  -webkit-backdrop-filter: var(--_reorder-curtain-filter);
342
426
  backdrop-filter: var(--_reorder-curtain-filter);
427
+ outline: 0;
343
428
  }
344
429
 
345
430
  :host([reordering]) [part~='cell'][reorder-status='allowed'] {
@@ -402,13 +487,12 @@ export const gridStyles = css`
402
487
  inset-inline: 0 auto;
403
488
  }
404
489
 
405
- [first-frozen-to-end] {
406
- margin-inline-start: auto;
490
+ [frozen-to-end] [part~='resize-handle'] {
491
+ translate: calc(var(--_column-border-width) * -1);
407
492
  }
408
493
 
409
- /* Hide resize handle if scrolled to end */
410
- :host(:not([overflow~='end'])) [first-frozen-to-end] [part~='resize-handle'] {
411
- display: none;
494
+ [first-frozen-to-end] {
495
+ margin-inline-start: auto;
412
496
  }
413
497
 
414
498
  #scroller:is([column-resizing], [range-selecting]) {
@@ -416,6 +500,69 @@ export const gridStyles = css`
416
500
  user-select: none;
417
501
  }
418
502
 
503
+ /* Focus outline element, also used for d'n'd indication */
504
+ :is([part~='row'], [part~='cell'])::after {
505
+ position: absolute;
506
+ inset: calc(var(--_row-border-width) * -1) calc(var(--_column-border-width) * -1);
507
+ z-index: 3;
508
+ pointer-events: none;
509
+ outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
510
+ outline-offset: calc(var(--vaadin-focus-ring-width) * -1);
511
+ }
512
+
513
+ [part~='first-column-cell']::after {
514
+ inset-inline-start: 0;
515
+ }
516
+
517
+ [part~='last-column-cell']::after {
518
+ inset-inline-end: 0;
519
+ }
520
+
521
+ #header [part~='row']:first-child::after,
522
+ [part~='first-header-row-cell']::after,
523
+ [part*='first-row']::after {
524
+ top: 0;
525
+ }
526
+
527
+ table:has(#header > tr:not([hidden])) [part~='first-row-cell']::after {
528
+ top: calc(var(--_row-border-width) * -1);
529
+ }
530
+
531
+ #footer [part~='row']:last-child::after,
532
+ [part~='last-footer-row-cell']::after,
533
+ [part~='last-row']::after,
534
+ [part~='last-row-cell']::after {
535
+ bottom: 0;
536
+ }
537
+
538
+ #header [part~='row']:last-child::after,
539
+ table:has(#footer > tr:not([hidden])) [part*='last-row']::after {
540
+ bottom: calc(var(--_row-border-width) * -1);
541
+ }
542
+
543
+ :host([navigating]) [part~='row']:focus,
544
+ :host([navigating]) [part~='cell']:focus {
545
+ outline: 0;
546
+ }
547
+
548
+ [part~='row']::after {
549
+ transform: translateX(var(--_grid-horizontal-scroll-position));
550
+ inset-inline: 0;
551
+ bottom: 0;
552
+ }
553
+
554
+ [part~='row']:focus-visible,
555
+ [part~='cell']:focus-visible {
556
+ outline: 0;
557
+ }
558
+
559
+ [part~='row']:focus-visible::after,
560
+ [part~='cell']:focus-visible::after,
561
+ :host([navigating]) [part~='row']:focus::after,
562
+ :host([navigating]) [part~='cell']:focus::after {
563
+ content: '';
564
+ }
565
+
419
566
  /* Drag'n'drop styles */
420
567
  :host([dragover]) {
421
568
  outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
@@ -427,31 +574,32 @@ export const gridStyles = css`
427
574
  }
428
575
 
429
576
  [part~='row'][dragover]::after {
430
- visibility: visible;
577
+ content: '';
431
578
  }
432
579
 
433
580
  [part~='row'][dragover='above']::after {
434
581
  outline: 0;
435
582
  border-top: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
583
+ }
584
+
585
+ [part~='row']:not([part*='first-row'])[dragover='above']::after,
586
+ table:has(#header > tr:not([hidden])) [part*='first-row'][dragover='above']::after {
436
587
  top: calc(var(--vaadin-focus-ring-width) / -2);
437
588
  }
438
589
 
439
590
  [part~='row'][dragover='below']::after {
440
591
  outline: 0;
441
592
  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
593
  }
448
594
 
449
- :is([part~='row']:last-child, [part~='last-row'])::after {
450
- bottom: 0;
595
+ [part~='row']:not([part*='last-row'])[dragover='below']::after,
596
+ table:has(#footer > tr:not([hidden])) [part*='last-row'][dragover='below']::after {
597
+ bottom: calc(var(--vaadin-focus-ring-width) / -2);
451
598
  }
452
599
 
453
600
  [part~='row'][dragstart] [part~='cell'] {
454
- border-top: 0 !important;
601
+ border-block-color: transparent !important;
602
+ box-shadow: none;
455
603
  }
456
604
 
457
605
  [part~='row'][dragstart] [part~='cell'][last-column] {
@@ -507,4 +655,16 @@ export const gridStyles = css`
507
655
  #sizer [part~='cell']::before {
508
656
  content: '-';
509
657
  }
658
+
659
+ @media (forced-colors: active) {
660
+ :host([overflow~='top']) [part~='last-header-row-cell'] {
661
+ border-bottom: var(--_row-border-width) solid;
662
+ margin-bottom: calc(var(--_row-border-width) * -1);
663
+ }
664
+
665
+ :host([overflow~='bottom']) [part~='first-footer-row-cell'] {
666
+ border-top: var(--_row-border-width) solid;
667
+ margin-top: calc(var(--_row-border-width) * -1);
668
+ }
669
+ }
510
670
  `;
@@ -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;