@vaadin/grid 25.0.0-alpha2 → 25.0.0-alpha21

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 -13
  3. package/src/array-data-provider.js +9 -2
  4. package/src/lit/column-renderer-directives.d.ts +0 -1
  5. package/src/styles/vaadin-grid-base-styles.d.ts +8 -0
  6. package/src/styles/vaadin-grid-base-styles.js +677 -0
  7. package/src/styles/vaadin-grid-filter-base-styles.d.ts +8 -0
  8. package/src/styles/vaadin-grid-filter-base-styles.js +18 -0
  9. package/src/styles/vaadin-grid-sorter-base-styles.d.ts +8 -0
  10. package/src/styles/vaadin-grid-sorter-base-styles.js +76 -0
  11. package/src/styles/vaadin-grid-tree-toggle-base-styles.d.ts +8 -0
  12. package/src/styles/vaadin-grid-tree-toggle-base-styles.js +76 -0
  13. package/src/vaadin-grid-a11y-mixin.js +26 -10
  14. package/src/vaadin-grid-column-auto-width-mixin.js +9 -6
  15. package/src/vaadin-grid-column-mixin.d.ts +1 -0
  16. package/src/vaadin-grid-column-mixin.js +1 -16
  17. package/src/vaadin-grid-column-reordering-mixin.js +2 -2
  18. package/src/vaadin-grid-data-provider-mixin.js +33 -85
  19. package/src/vaadin-grid-drag-and-drop-mixin.js +3 -0
  20. package/src/vaadin-grid-event-context-mixin.d.ts +2 -0
  21. package/src/vaadin-grid-event-context-mixin.js +1 -0
  22. package/src/vaadin-grid-filter-element-mixin.js +0 -17
  23. package/src/vaadin-grid-filter.js +7 -1
  24. package/src/vaadin-grid-helpers.js +9 -0
  25. package/src/vaadin-grid-keyboard-navigation-mixin.js +2 -6
  26. package/src/vaadin-grid-mixin.d.ts +1 -0
  27. package/src/vaadin-grid-mixin.js +64 -32
  28. package/src/vaadin-grid-row-details-mixin.js +5 -5
  29. package/src/vaadin-grid-scroll-mixin.js +57 -77
  30. package/src/vaadin-grid-selection-column-base-mixin.d.ts +1 -1
  31. package/src/vaadin-grid-selection-column-base-mixin.js +1 -1
  32. package/src/vaadin-grid-selection-column.d.ts +2 -0
  33. package/src/vaadin-grid-selection-column.js +2 -1
  34. package/src/vaadin-grid-sort-column.d.ts +2 -0
  35. package/src/vaadin-grid-sorter-mixin.js +0 -60
  36. package/src/vaadin-grid-sorter.d.ts +3 -3
  37. package/src/vaadin-grid-sorter.js +10 -4
  38. package/src/vaadin-grid-tree-column-mixin.js +2 -7
  39. package/src/vaadin-grid-tree-toggle-mixin.js +0 -77
  40. package/src/vaadin-grid-tree-toggle.d.ts +4 -4
  41. package/src/vaadin-grid-tree-toggle.js +13 -5
  42. package/src/vaadin-grid.d.ts +2 -1
  43. package/src/vaadin-grid.js +6 -3
  44. package/vaadin-grid-column-group.js +1 -1
  45. package/vaadin-grid-column.js +1 -1
  46. package/vaadin-grid-filter-column.js +1 -1
  47. package/vaadin-grid-filter.js +1 -1
  48. package/vaadin-grid-selection-column.js +1 -1
  49. package/vaadin-grid-sort-column.js +1 -1
  50. package/vaadin-grid-sorter.js +1 -1
  51. package/vaadin-grid-tree-column.js +1 -1
  52. package/vaadin-grid-tree-toggle.js +1 -1
  53. package/vaadin-grid.js +1 -1
  54. package/web-types.json +13 -13
  55. package/web-types.lit.json +12 -12
  56. package/src/vaadin-grid-styles.js +0 -389
  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
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2025 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import '@vaadin/component-base/src/styles/style-props.js';
7
+ import { css } from 'lit';
8
+
9
+ export const gridSorterStyles = css`
10
+ :host {
11
+ display: inline-flex;
12
+ align-items: center;
13
+ cursor: pointer;
14
+ max-width: 100%;
15
+ gap: var(--vaadin-gap-s);
16
+ -webkit-user-select: none;
17
+ user-select: none;
18
+ -webkit-tap-highlight-color: transparent;
19
+ }
20
+
21
+ [part='content'] {
22
+ flex: 1 1 auto;
23
+ overflow: hidden;
24
+ text-overflow: ellipsis;
25
+ }
26
+
27
+ [part='indicators'] {
28
+ position: relative;
29
+ flex: none;
30
+ height: 1lh;
31
+ color: var(--vaadin-text-color-disabled);
32
+ }
33
+
34
+ [part='order'] {
35
+ display: inline;
36
+ vertical-align: super;
37
+ font-size: 0.75em;
38
+ line-height: 1;
39
+ color: var(--vaadin-text-color-secondary);
40
+ }
41
+
42
+ [part='indicators']::before {
43
+ content: '';
44
+ display: inline-block;
45
+ height: 12px;
46
+ width: 8px;
47
+ mask-image: var(--_vaadin-icon-sort);
48
+ background: currentColor;
49
+ }
50
+
51
+ :host([direction]) [part='indicators']::before {
52
+ padding-bottom: 6px;
53
+ height: 6px;
54
+ mask-clip: content-box;
55
+ }
56
+
57
+ :host([direction='desc']) [part='indicators']::before {
58
+ padding-block: 6px 0;
59
+ }
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
+
71
+ @media (forced-colors: active) {
72
+ [part='indicators']::before {
73
+ background: CanvasText;
74
+ }
75
+ }
76
+ `;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2025 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import type { CSSResult } from 'lit';
7
+
8
+ export const gridTreeToggleStyles: CSSResult;
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2025 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import '@vaadin/component-base/src/styles/style-props.js';
7
+ import { css } from 'lit';
8
+
9
+ export const gridTreeToggleStyles = css`
10
+ :host {
11
+ display: flex;
12
+ max-width: 100%;
13
+ pointer-events: none;
14
+ }
15
+
16
+ /* Don't expand/collapse when clicking #level-spacer */
17
+ [part] {
18
+ pointer-events: auto;
19
+ }
20
+
21
+ :host([hidden]) {
22
+ display: none !important;
23
+ }
24
+
25
+ :host(:not([leaf])) {
26
+ cursor: var(--vaadin-clickable-cursor);
27
+ }
28
+
29
+ #level-spacer,
30
+ [part='toggle'] {
31
+ flex: none;
32
+ }
33
+
34
+ #level-spacer {
35
+ width: calc(var(--_level, 0) * var(--vaadin-grid-tree-toggle-level-offset, 16px));
36
+ }
37
+
38
+ [part='toggle'] {
39
+ margin-inline-end: var(--vaadin-gap-s);
40
+ }
41
+
42
+ [part='toggle']::before {
43
+ content: '';
44
+ display: block;
45
+ width: var(--vaadin-icon-size, 1lh);
46
+ height: var(--vaadin-icon-size, 1lh);
47
+ background: currentColor;
48
+ mask: var(--_vaadin-icon-chevron-down) 50% / var(--vaadin-icon-visual-size, 100%) no-repeat;
49
+ }
50
+
51
+ :host(:not([expanded])) [part='toggle']::before {
52
+ rotate: -90deg;
53
+ }
54
+
55
+ @media (prefers-reduced-motion: no-preference) {
56
+ [part='toggle']::before {
57
+ transition: rotate 120ms;
58
+ }
59
+ }
60
+
61
+ :host([leaf]) [part='toggle'] {
62
+ visibility: hidden;
63
+ }
64
+
65
+ slot {
66
+ display: block;
67
+ overflow: hidden;
68
+ text-overflow: ellipsis;
69
+ }
70
+
71
+ @media (forced-colors: active) {
72
+ [part='toggle']::before {
73
+ background: CanvasText;
74
+ }
75
+ }
76
+ `;
@@ -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 { iterateChildren, iterateRowCells } from './vaadin-grid-helpers.js';
6
+ import { findTreeToggleCell, iterateChildren, iterateRowCells } from './vaadin-grid-helpers.js';
7
7
 
8
8
  /**
9
9
  * @polymerMixin
@@ -22,7 +22,7 @@ export const A11yMixin = (superClass) =>
22
22
  };
23
23
  }
24
24
  static get observers() {
25
- return ['_a11yUpdateGridSize(size, _columnTree)'];
25
+ return ['_a11yUpdateGridSize(size, _columnTree, __emptyState)'];
26
26
  }
27
27
 
28
28
  /** @private */
@@ -34,21 +34,27 @@ export const A11yMixin = (superClass) =>
34
34
 
35
35
  /** @private */
36
36
  _a11yGetFooterRowCount(_columnTree) {
37
- return _columnTree.filter((level) => level.some((col) => col.headerRenderer)).length;
37
+ return _columnTree.filter((level) => level.some((col) => col.footerRenderer)).length;
38
38
  }
39
39
 
40
40
  /** @private */
41
- _a11yUpdateGridSize(size, _columnTree) {
41
+ _a11yUpdateGridSize(size, _columnTree, emptyState) {
42
42
  if (size === undefined || _columnTree === undefined) {
43
43
  return;
44
44
  }
45
45
 
46
+ const headerRowsCount = this._a11yGetHeaderRowCount(_columnTree);
47
+ const footerRowsCount = this._a11yGetFooterRowCount(_columnTree);
48
+ const bodyRowsCount = emptyState ? 1 : size;
49
+ const rowsCount = bodyRowsCount + headerRowsCount + footerRowsCount;
50
+
51
+ this.$.table.setAttribute('aria-rowcount', rowsCount);
52
+
46
53
  const bodyColumns = _columnTree[_columnTree.length - 1];
47
- this.$.table.setAttribute(
48
- 'aria-rowcount',
49
- size + this._a11yGetHeaderRowCount(_columnTree) + this._a11yGetFooterRowCount(_columnTree),
50
- );
51
- this.$.table.setAttribute('aria-colcount', (bodyColumns && bodyColumns.length) || 0);
54
+ // If no header and footer rows while the empty state is active, count as one column
55
+ // Otherwise, use the number of body columns, if present
56
+ const columnsCount = emptyState ? 1 : (rowsCount && bodyColumns && bodyColumns.length) || 0;
57
+ this.$.table.setAttribute('aria-colcount', columnsCount);
52
58
 
53
59
  this._a11yUpdateHeaderRows();
54
60
  this._a11yUpdateFooterRows();
@@ -95,12 +101,22 @@ export const A11yMixin = (superClass) =>
95
101
  * @protected
96
102
  */
97
103
  _a11yUpdateRowExpanded(row) {
104
+ const toggleCell = findTreeToggleCell(row);
98
105
  if (this.__isRowExpandable(row)) {
99
106
  row.setAttribute('aria-expanded', 'false');
107
+ if (toggleCell) {
108
+ toggleCell.setAttribute('aria-expanded', 'false');
109
+ }
100
110
  } else if (this.__isRowCollapsible(row)) {
101
111
  row.setAttribute('aria-expanded', 'true');
112
+ if (toggleCell) {
113
+ toggleCell.setAttribute('aria-expanded', 'true');
114
+ }
102
115
  } else {
103
116
  row.removeAttribute('aria-expanded');
117
+ if (toggleCell) {
118
+ toggleCell.removeAttribute('aria-expanded');
119
+ }
104
120
  }
105
121
  }
106
122
 
@@ -132,7 +148,7 @@ export const A11yMixin = (superClass) =>
132
148
  }
133
149
 
134
150
  /**
135
- * @param {!HTMLElement} row
151
+ * @param {!HTMLElement} cell
136
152
  * @param {number} colspan
137
153
  * @protected
138
154
  */
@@ -59,9 +59,15 @@ export const ColumnAutoWidthMixin = (superClass) =>
59
59
  }
60
60
 
61
61
  /** @private */
62
- __flatSizeChangedAutoWidth() {
62
+ __flatSizeChangedAutoWidth(flatSize) {
63
63
  // Flat size changed, recalculate column widths if pending (asynchronously, to allow grid to render row elements first)
64
- requestAnimationFrame(() => this.__tryToRecalculateColumnWidthsIfPending());
64
+ requestAnimationFrame(() => {
65
+ if (!!flatSize && !this.__hasHadRenderedRowsForColumnWidthCalculation) {
66
+ this.recalculateColumnWidths();
67
+ } else {
68
+ this.__tryToRecalculateColumnWidthsIfPending();
69
+ }
70
+ });
65
71
  }
66
72
 
67
73
  /**
@@ -131,10 +137,7 @@ export const ColumnAutoWidthMixin = (superClass) =>
131
137
  return this.__getIntrinsicWidth(innerColumn) + shareOfInnerColumnFromNecessaryExtraSpace;
132
138
  }
133
139
 
134
- /**
135
- * @param {!Array<!GridColumn>} cols the columns to auto size based on their content width
136
- * @private
137
- */
140
+ /** @private */
138
141
  _recalculateColumnWidths() {
139
142
  // Flush to make sure DOM is up-to-date when measuring the column widths
140
143
  this.__virtualizer.flush();
@@ -147,6 +147,7 @@ export declare class GridColumnMixinClass<
147
147
  * - `model.level` Level of the tree represented with a horizontal offset of the toggle button.
148
148
  * - `model.selected` Selected state.
149
149
  * - `model.detailsOpened` Details opened state.
150
+ * - `model.hasChildren` Whether the item has children.
150
151
  */
151
152
  renderer: GridBodyRenderer<TItem, Column> | null | undefined;
152
153
 
@@ -536,24 +536,8 @@ export const ColumnBaseMixin = (superClass) =>
536
536
  return;
537
537
  }
538
538
 
539
- let textAlignFallback;
540
- if (getComputedStyle(this._grid).direction === 'ltr') {
541
- if (textAlign === 'start') {
542
- textAlignFallback = 'left';
543
- } else if (textAlign === 'end') {
544
- textAlignFallback = 'right';
545
- }
546
- } else if (textAlign === 'start') {
547
- textAlignFallback = 'right';
548
- } else if (textAlign === 'end') {
549
- textAlignFallback = 'left';
550
- }
551
-
552
539
  this._allCells.forEach((cell) => {
553
540
  cell._content.style.textAlign = textAlign;
554
- if (getComputedStyle(cell._content).textAlign !== textAlign) {
555
- cell._content.style.textAlign = textAlignFallback;
556
- }
557
541
  });
558
542
  }
559
543
 
@@ -885,6 +869,7 @@ export const GridColumnMixin = (superClass) =>
885
869
  * - `model.level` Level of the tree represented with a horizontal offset of the toggle button.
886
870
  * - `model.selected` Selected state.
887
871
  * - `model.detailsOpened` Details opened state.
872
+ * - `model.hasChildren` Whether the item has children.
888
873
  *
889
874
  * @type {GridBodyRenderer | null | undefined}
890
875
  */
@@ -127,9 +127,9 @@ export const ColumnReorderingMixin = (superClass) =>
127
127
  return;
128
128
  }
129
129
 
130
- // Cancel reordering if there are draggable nodes on the event path
130
+ // Cancel reordering if there are draggable nodes on the event path following this element
131
131
  const path = e.composedPath && e.composedPath();
132
- if (path && path.some((node) => node.hasAttribute && node.hasAttribute('draggable'))) {
132
+ if (path && path.slice(0, Math.max(0, path.indexOf(this))).some((node) => node.draggable)) {
133
133
  return;
134
134
  }
135
135
 
@@ -7,7 +7,6 @@ import { microTask, timeOut } from '@vaadin/component-base/src/async.js';
7
7
  import { DataProviderController } from '@vaadin/component-base/src/data-provider-controller/data-provider-controller.js';
8
8
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
9
9
  import { get } from '@vaadin/component-base/src/path-utils.js';
10
- import { getBodyRowCells, updateCellsPart, updateState } from './vaadin-grid-helpers.js';
11
10
 
12
11
  /**
13
12
  * @polymerMixin
@@ -166,24 +165,6 @@ export const DataProviderMixin = (superClass) =>
166
165
  this._dataProviderController.addEventListener('page-loaded', this._onDataProviderPageLoaded.bind(this));
167
166
  }
168
167
 
169
- /**
170
- * @protected
171
- * @deprecated since 24.3 and will be removed in Vaadin 25.
172
- */
173
- get _cache() {
174
- console.warn('<vaadin-grid> The `_cache` property is deprecated and will be removed in Vaadin 25.');
175
- return this._dataProviderController.rootCache;
176
- }
177
-
178
- /**
179
- * @protected
180
- * @deprecated since 24.3 and will be removed in Vaadin 25.
181
- */
182
- get _effectiveSize() {
183
- console.warn('<vaadin-grid> The `_effectiveSize` property is deprecated and will be removed in Vaadin 25.');
184
- return this._flatSize;
185
- }
186
-
187
168
  /** @private */
188
169
  _sizeChanged(size) {
189
170
  this._dataProviderController.rootCache.size = size;
@@ -200,46 +181,26 @@ export const DataProviderMixin = (superClass) =>
200
181
  this.requestContentUpdate();
201
182
  }
202
183
 
203
- /**
204
- * @param {number} index
205
- * @param {HTMLElement} el
206
- * @protected
207
- */
208
- _getItem(index, el) {
209
- el.index = index;
210
-
211
- const { item } = this._dataProviderController.getFlatIndexContext(index);
212
- if (item) {
213
- this.__updateLoading(el, false);
214
- this._updateItem(el, item);
215
- if (this._isExpanded(item)) {
216
- this._dataProviderController.ensureFlatIndexHierarchy(index);
217
- }
218
- } else {
219
- this.__updateLoading(el, true);
220
- this._dataProviderController.ensureFlatIndexLoaded(index);
221
- }
184
+ /** @private */
185
+ __getRowLevel(row) {
186
+ const { level } = this._dataProviderController.getFlatIndexContext(row.index);
187
+ return level;
222
188
  }
223
189
 
224
- /**
225
- * @param {!HTMLElement} row
226
- * @param {boolean} loading
227
- * @private
228
- */
229
- __updateLoading(row, loading) {
230
- const cells = getBodyRowCells(row);
231
-
232
- // Row state attribute
233
- updateState(row, 'loading', loading);
190
+ /** @private */
191
+ __getRowItem(row) {
192
+ const { item } = this._dataProviderController.getFlatIndexContext(row.index);
193
+ return item;
194
+ }
234
195
 
235
- // Cells part attribute
236
- updateCellsPart(cells, 'loading-row-cell', loading);
196
+ /** @private */
197
+ __ensureRowItem(row) {
198
+ this._dataProviderController.ensureFlatIndexLoaded(row.index);
199
+ }
237
200
 
238
- if (loading) {
239
- // Run style generators for the loading row to have custom names cleared
240
- this._generateCellClassNames(row);
241
- this._generateCellPartNames(row);
242
- }
201
+ /** @private */
202
+ __ensureRowHierarchy(row) {
203
+ this._dataProviderController.ensureFlatIndexHierarchy(row.index);
243
204
  }
244
205
 
245
206
  /**
@@ -261,6 +222,15 @@ export const DataProviderMixin = (superClass) =>
261
222
  return this.__expandedKeys && this.__expandedKeys.has(this.getItemId(item));
262
223
  }
263
224
 
225
+ /**
226
+ * @param {!GridItem} item
227
+ * @return {boolean}
228
+ * @protected
229
+ */
230
+ _hasChildren(item) {
231
+ return this.itemHasChildrenPath && item && !!get(this.itemHasChildrenPath, item);
232
+ }
233
+
264
234
  /** @private */
265
235
  _expandedItemsChanged() {
266
236
  this._dataProviderController.recalculateFlatSize();
@@ -299,27 +269,6 @@ export const DataProviderMixin = (superClass) =>
299
269
  }
300
270
  }
301
271
 
302
- /**
303
- * @param {number} index
304
- * @return {number}
305
- * @protected
306
- */
307
- _getIndexLevel(index = 0) {
308
- const { level } = this._dataProviderController.getFlatIndexContext(index);
309
- return level;
310
- }
311
-
312
- /**
313
- * @param {number} page
314
- * @param {ItemCache} cache
315
- * @protected
316
- * @deprecated since 24.3 and will be removed in Vaadin 25.
317
- */
318
- _loadPage(page, cache) {
319
- console.warn('<vaadin-grid> The `_loadPage` method is deprecated and will be removed in Vaadin 25.');
320
- this._dataProviderController.__loadCachePage(cache, page);
321
- }
322
-
323
272
  /** @protected */
324
273
  _onDataProviderPageRequested() {
325
274
  this._setLoading(true);
@@ -331,7 +280,7 @@ export const DataProviderMixin = (superClass) =>
331
280
  if (this._flatSize !== this._dataProviderController.flatSize) {
332
281
  // Schedule an update of all rendered rows by _debouncerApplyCachedData,
333
282
  // to ensure that all pages associated with the rendered rows are loaded.
334
- this._shouldUpdateAllRenderedRowsAfterPageLoad = true;
283
+ this._shouldLoadAllRenderedRowsAfterPageLoad = true;
335
284
 
336
285
  // TODO: Updating the flat size property can still result in a synchonous virtualizer update
337
286
  // if the size change requires the virtualizer to increase the amount of physical elements
@@ -341,9 +290,7 @@ export const DataProviderMixin = (superClass) =>
341
290
  }
342
291
 
343
292
  // After updating the cache, check if some of the expanded items should have sub-caches loaded
344
- this._getRenderedRows().forEach((row) => {
345
- this._dataProviderController.ensureFlatIndexHierarchy(row.index);
346
- });
293
+ this._getRenderedRows().forEach((row) => this.__ensureRowHierarchy(row));
347
294
 
348
295
  this._hasData = true;
349
296
  }
@@ -354,13 +301,14 @@ export const DataProviderMixin = (superClass) =>
354
301
  this._debouncerApplyCachedData = Debouncer.debounce(this._debouncerApplyCachedData, timeOut.after(0), () => {
355
302
  this._setLoading(false);
356
303
 
357
- const shouldUpdateAllRenderedRowsAfterPageLoad = this._shouldUpdateAllRenderedRowsAfterPageLoad;
358
- this._shouldUpdateAllRenderedRowsAfterPageLoad = false;
304
+ const shouldLoadAllRenderedRowsAfterPageLoad = this._shouldLoadAllRenderedRowsAfterPageLoad;
305
+ this._shouldLoadAllRenderedRowsAfterPageLoad = false;
359
306
 
360
307
  this._getRenderedRows().forEach((row) => {
361
- const { item } = this._dataProviderController.getFlatIndexContext(row.index);
362
- if (item || shouldUpdateAllRenderedRowsAfterPageLoad) {
363
- this._getItem(row.index, row);
308
+ this.__updateRow(row);
309
+
310
+ if (shouldLoadAllRenderedRowsAfterPageLoad) {
311
+ this.__ensureRowItem(row);
364
312
  }
365
313
  });
366
314
 
@@ -247,6 +247,9 @@ export const DragAndDropMixin = (superClass) =>
247
247
 
248
248
  let row = e.composedPath().find((node) => node.localName === 'tr');
249
249
 
250
+ // Update the horizontal scroll position property of the row being dragged over
251
+ this.__updateRowScrollPositionProperty(row);
252
+
250
253
  if (!this._flatSize || this.dropMode === DropMode.ON_GRID) {
251
254
  // The grid is empty or "on-grid" drop mode was used, always default to "empty"
252
255
  this._dropLocation = DropLocation.EMPTY;
@@ -13,6 +13,7 @@ export interface GridEventContext<TItem> {
13
13
  index?: number;
14
14
  selected?: boolean;
15
15
  detailsOpened?: boolean;
16
+ hasChildren?: boolean;
16
17
  expanded?: boolean;
17
18
  level?: number;
18
19
  }
@@ -34,6 +35,7 @@ export declare class EventContextMixinClass<TItem> {
34
35
  * - `detailsOpened`: whether the row details are open for the item
35
36
  * - `expanded`: the expanded state of the tree toggle
36
37
  * - `level`: the tree hierarchy level
38
+ * - `hasChildren`: whether the item has children
37
39
  *
38
40
  * The returned object is populated only when a grid cell, header, footer or row details is found in `event.composedPath()`.
39
41
  * This means mostly mouse and keyboard events. If such a grid part is not found in the path, an empty object is returned.
@@ -21,6 +21,7 @@ export const EventContextMixin = (superClass) =>
21
21
  * - `detailsOpened`: whether the row details are open for the item
22
22
  * - `expanded`: the expanded state of the tree toggle
23
23
  * - `level`: the tree hierarchy level
24
+ * - `hasChildren`: whether the item has children
24
25
  *
25
26
  * The returned object is populated only when a grid cell, header, footer or row details is found in `event.composedPath()`.
26
27
  * This means mostly mouse and keyboard events. If such a grid part is not found in the path, an empty object is returned.
@@ -6,23 +6,6 @@
6
6
  import { timeOut } from '@vaadin/component-base/src/async.js';
7
7
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
8
8
  import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
9
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin';
10
-
11
- registerStyles(
12
- 'vaadin-grid-filter',
13
- css`
14
- :host {
15
- display: inline-flex;
16
- max-width: 100%;
17
- }
18
-
19
- ::slotted(*) {
20
- width: 100%;
21
- box-sizing: border-box;
22
- }
23
- `,
24
- { moduleId: 'vaadin-grid-filter-styles' },
25
- );
26
9
 
27
10
  /**
28
11
  * @polymerMixin
@@ -8,6 +8,8 @@ import { html, LitElement } from 'lit';
8
8
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
9
9
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
10
10
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin';
11
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
12
+ import { gridFilterStyles } from './styles/vaadin-grid-filter-base-styles.js';
11
13
  import { GridFilterElementMixin } from './vaadin-grid-filter-element-mixin.js';
12
14
 
13
15
  /**
@@ -39,11 +41,15 @@ import { GridFilterElementMixin } from './vaadin-grid-filter-element-mixin.js';
39
41
  * @extends HTMLElement
40
42
  * @mixes GridFilterElementMixin
41
43
  */
42
- class GridFilter extends GridFilterElementMixin(ThemableMixin(PolylitMixin(LitElement))) {
44
+ class GridFilter extends GridFilterElementMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement)))) {
43
45
  static get is() {
44
46
  return 'vaadin-grid-filter';
45
47
  }
46
48
 
49
+ static get styles() {
50
+ return gridFilterStyles;
51
+ }
52
+
47
53
  /** @protected */
48
54
  render() {
49
55
  return html`<slot></slot>`;
@@ -173,6 +173,15 @@ export function updateCellState(cell, attribute, value, part, oldPart) {
173
173
  updatePart(cell, value, part || `${attribute}-cell`);
174
174
  }
175
175
 
176
+ /**
177
+ * Finds the cell containing the tree toggle element
178
+ * @param {!HTMLElement} row
179
+ * @return {HTMLElement | null}
180
+ */
181
+ export function findTreeToggleCell(row) {
182
+ return getBodyRowCells(row).find((cell) => cell._content.querySelector('vaadin-grid-tree-toggle'));
183
+ }
184
+
176
185
  /**
177
186
  * A helper for observing flattened child column list of an element.
178
187
  */
@@ -7,7 +7,6 @@ import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
7
7
  import { animationFrame } from '@vaadin/component-base/src/async.js';
8
8
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
9
9
  import { addValueToAttribute, removeValueFromAttribute } from '@vaadin/component-base/src/dom-utils.js';
10
- import { get } from '@vaadin/component-base/src/path-utils.js';
11
10
 
12
11
  function isRow(element) {
13
12
  return element instanceof HTMLTableRowElement;
@@ -280,16 +279,13 @@ export const KeyboardNavigationMixin = (superClass) =>
280
279
  if (!targetRowInDom) {
281
280
  this._scrollToFlatIndex(index);
282
281
  } else {
283
- this.__scrollIntoViewport(index);
282
+ this.__scrollIntoViewport(targetRowInDom);
284
283
  }
285
284
  }
286
285
 
287
286
  /** @private */
288
287
  __isRowExpandable(row) {
289
- if (this.itemHasChildrenPath) {
290
- const item = row._item;
291
- return !!(item && get(this.itemHasChildrenPath, item) && !this._isExpanded(item));
292
- }
288
+ return this._hasChildren(row._item) && !this._isExpanded(row._item);
293
289
  }
294
290
 
295
291
  /** @private */
@@ -62,6 +62,7 @@ export interface GridItemModel<TItem> {
62
62
  expanded?: boolean;
63
63
  level?: number;
64
64
  detailsOpened?: boolean;
65
+ hasChildren?: boolean;
65
66
  }
66
67
 
67
68
  /**