@vaadin/grid 24.0.0-alpha9 → 24.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/grid",
3
- "version": "24.0.0-alpha9",
3
+ "version": "24.0.0-beta2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -46,18 +46,18 @@
46
46
  "dependencies": {
47
47
  "@open-wc/dedupe-mixin": "^1.3.0",
48
48
  "@polymer/polymer": "^3.0.0",
49
- "@vaadin/checkbox": "24.0.0-alpha9",
50
- "@vaadin/component-base": "24.0.0-alpha9",
51
- "@vaadin/lit-renderer": "24.0.0-alpha9",
52
- "@vaadin/text-field": "24.0.0-alpha9",
53
- "@vaadin/vaadin-lumo-styles": "24.0.0-alpha9",
54
- "@vaadin/vaadin-material-styles": "24.0.0-alpha9",
55
- "@vaadin/vaadin-themable-mixin": "24.0.0-alpha9"
49
+ "@vaadin/checkbox": "24.0.0-beta2",
50
+ "@vaadin/component-base": "24.0.0-beta2",
51
+ "@vaadin/lit-renderer": "24.0.0-beta2",
52
+ "@vaadin/text-field": "24.0.0-beta2",
53
+ "@vaadin/vaadin-lumo-styles": "24.0.0-beta2",
54
+ "@vaadin/vaadin-material-styles": "24.0.0-beta2",
55
+ "@vaadin/vaadin-themable-mixin": "24.0.0-beta2"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@esm-bundle/chai": "^4.3.4",
59
- "@vaadin/polymer-legacy-adapter": "24.0.0-alpha9",
60
- "@vaadin/testing-helpers": "^0.3.2",
59
+ "@vaadin/polymer-legacy-adapter": "24.0.0-beta2",
60
+ "@vaadin/testing-helpers": "^0.4.0",
61
61
  "lit": "^2.0.0",
62
62
  "sinon": "^13.0.2"
63
63
  },
@@ -65,5 +65,5 @@
65
65
  "web-types.json",
66
66
  "web-types.lit.json"
67
67
  ],
68
- "gitHead": "cc3f747164041566b300bde4b105d2475649e93f"
68
+ "gitHead": "00086f1f6d487f042f189c9b9ecd7ba736960888"
69
69
  }
@@ -38,30 +38,6 @@ function checkPaths(arrayToCheck, action, items) {
38
38
  return result;
39
39
  }
40
40
 
41
- /**
42
- * Sorts the given array of items based on the sorting rules and returns the result.
43
- *
44
- * @param {Array<any>} items
45
- * @param {Array<GridSorterDefinition>} items
46
- * @return {Array<any>}
47
- */
48
- function multiSort(items, sortOrders) {
49
- return items.sort((a, b) => {
50
- return sortOrders
51
- .map((sortOrder) => {
52
- if (sortOrder.direction === 'asc') {
53
- return compare(get(sortOrder.path, a), get(sortOrder.path, b));
54
- } else if (sortOrder.direction === 'desc') {
55
- return compare(get(sortOrder.path, b), get(sortOrder.path, a));
56
- }
57
- return 0;
58
- })
59
- .reduce((p, n) => {
60
- return p !== 0 ? p : n;
61
- }, 0);
62
- });
63
- }
64
-
65
41
  /**
66
42
  * @param {unknown} value
67
43
  * @return {string}
@@ -93,6 +69,30 @@ function compare(a, b) {
93
69
  return 0;
94
70
  }
95
71
 
72
+ /**
73
+ * Sorts the given array of items based on the sorting rules and returns the result.
74
+ *
75
+ * @param {Array<any>} items
76
+ * @param {Array<GridSorterDefinition>} items
77
+ * @return {Array<any>}
78
+ */
79
+ function multiSort(items, sortOrders) {
80
+ return items.sort((a, b) => {
81
+ return sortOrders
82
+ .map((sortOrder) => {
83
+ if (sortOrder.direction === 'asc') {
84
+ return compare(get(sortOrder.path, a), get(sortOrder.path, b));
85
+ } else if (sortOrder.direction === 'desc') {
86
+ return compare(get(sortOrder.path, b), get(sortOrder.path, a));
87
+ }
88
+ return 0;
89
+ })
90
+ .reduce((p, n) => {
91
+ return p !== 0 ? p : n;
92
+ }, 0);
93
+ });
94
+ }
95
+
96
96
  /**
97
97
  * @param {!Array<!GridItem>} items
98
98
  * @return {!Array<!GridItem>}
@@ -14,7 +14,7 @@ export declare class ActiveItemMixinClass<TItem> {
14
14
  * The item user has last interacted with. Turns to `null` after user deactivates
15
15
  * the item by re-interacting with the currently active item.
16
16
  */
17
- activeItem: TItem | null;
17
+ activeItem: TItem | null | undefined;
18
18
  }
19
19
 
20
20
  export declare function isFocusable(target: Element): boolean;
@@ -4,6 +4,30 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
 
7
+ /**
8
+ * @param {!Element} target
9
+ * @return {boolean}
10
+ * @protected
11
+ */
12
+ export const isFocusable = (target) => {
13
+ if (!target.parentNode) {
14
+ return false;
15
+ }
16
+ const focusables = Array.from(
17
+ target.parentNode.querySelectorAll(
18
+ '[tabindex], button, input, select, textarea, object, iframe, a[href], area[href]',
19
+ ),
20
+ ).filter((element) => {
21
+ const part = element.getAttribute('part');
22
+ return !(part && part.includes('body-cell'));
23
+ });
24
+
25
+ const isFocusableElement = focusables.includes(target);
26
+ return (
27
+ !target.disabled && isFocusableElement && target.offsetParent && getComputedStyle(target).visibility !== 'hidden'
28
+ );
29
+ };
30
+
7
31
  /**
8
32
  * @polymerMixin
9
33
  */
@@ -65,7 +89,7 @@ export const ActiveItemMixin = (superClass) =>
65
89
 
66
90
  const activeElement = this.getRootNode().activeElement;
67
91
  const cellContentHasFocus = cellContent.contains(activeElement);
68
- if (!cellContentHasFocus && !this._isFocusable(e.target)) {
92
+ if (!cellContentHasFocus && !this._isFocusable(e.target) && !(e.target instanceof HTMLLabelElement)) {
69
93
  this.dispatchEvent(
70
94
  new CustomEvent('cell-activate', {
71
95
  detail: {
@@ -97,25 +121,3 @@ export const ActiveItemMixin = (superClass) =>
97
121
  * @event cell-activate
98
122
  */
99
123
  };
100
-
101
- /**
102
- * @param {!Element} target
103
- * @return {boolean}
104
- * @protected
105
- */
106
- export const isFocusable = (target) => {
107
- if (!target.parentNode) {
108
- return false;
109
- }
110
- const focusables = Array.from(
111
- target.parentNode.querySelectorAll(
112
- '[tabindex], button, input, select, textarea, object, iframe, label, a[href], area[href]',
113
- ),
114
- ).filter((element) => {
115
- const part = element.getAttribute('part');
116
- return !(part && part.includes('body-cell'));
117
- });
118
-
119
- const isFocusableElement = focusables.includes(target);
120
- return !target.disabled && isFocusableElement;
121
- };
@@ -130,22 +130,22 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
130
130
  this._updateFlexAndWidth();
131
131
  }
132
132
 
133
- // Dont unfreeze the frozen group because of a non-frozen child
133
+ // Don't unfreeze the frozen group because of a non-frozen child
134
134
  if (path === 'frozen' && !this.frozen) {
135
135
  this.frozen = value;
136
136
  }
137
137
 
138
- // Dont unfreeze the frozen group because of a non-frozen child
138
+ // Don't unfreeze the frozen group because of a non-frozen child
139
139
  if (path === 'lastFrozen' && !this._lastFrozen) {
140
140
  this._lastFrozen = value;
141
141
  }
142
142
 
143
- // Dont unfreeze the frozen group because of a non-frozen child
143
+ // Don't unfreeze the frozen group because of a non-frozen child
144
144
  if (path === 'frozenToEnd' && !this.frozenToEnd) {
145
145
  this.frozenToEnd = value;
146
146
  }
147
147
 
148
- // Dont unfreeze the frozen group because of a non-frozen child
148
+ // Don't unfreeze the frozen group because of a non-frozen child
149
149
  if (path === 'firstFrozenToEnd' && !this._firstFrozenToEnd) {
150
150
  this._firstFrozenToEnd = value;
151
151
  }
@@ -279,7 +279,7 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
279
279
  return;
280
280
  }
281
281
 
282
- // Dont propagate the default `false` value.
282
+ // Don't propagate the default `false` value.
283
283
  if (frozen !== false) {
284
284
  this.__scheduleAutoFreezeWarning(rootColumns, 'frozen');
285
285
 
@@ -295,7 +295,7 @@ class GridColumnGroup extends ColumnBaseMixin(PolymerElement) {
295
295
  return;
296
296
  }
297
297
 
298
- // Dont propagate the default `false` value.
298
+ // Don't propagate the default `false` value.
299
299
  if (frozenToEnd !== false) {
300
300
  this.__scheduleAutoFreezeWarning(rootColumns, 'frozenToEnd');
301
301
 
@@ -3,6 +3,7 @@
3
3
  * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
+ import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
6
7
  import { addListener } from '@vaadin/component-base/src/gestures.js';
7
8
  import { iterateChildren, updateColumnOrders } from './vaadin-grid-helpers.js';
8
9
 
@@ -51,6 +52,14 @@ export const ColumnReorderingMixin = (superClass) =>
51
52
  _onContextMenu(e) {
52
53
  if (this.hasAttribute('reordering')) {
53
54
  e.preventDefault();
55
+
56
+ // A contextmenu event is fired on mobile Chrome on long-press
57
+ // (which should start reordering). Don't end the reorder on touch devices.
58
+ if (!isTouch) {
59
+ // Context menu cancels the track gesture on desktop without firing an end event.
60
+ // End the reorder manually.
61
+ this._onTrackEnd();
62
+ }
54
63
  }
55
64
  }
56
65
 
@@ -147,7 +156,7 @@ export const ColumnReorderingMixin = (superClass) =>
147
156
  /** @private */
148
157
  _onTrack(e) {
149
158
  if (!this._draggedColumn) {
150
- // Reordering didnt start. Skip this event.
159
+ // Reordering didn't start. Skip this event.
151
160
  return;
152
161
  }
153
162
 
@@ -187,7 +196,7 @@ export const ColumnReorderingMixin = (superClass) =>
187
196
  /** @private */
188
197
  _onTrackEnd() {
189
198
  if (!this._draggedColumn) {
190
- // Reordering didnt start. Skip this event.
199
+ // Reordering didn't start. Skip this event.
191
200
  return;
192
201
  }
193
202
 
@@ -216,6 +216,30 @@ export const ColumnBaseMixin = (superClass) =>
216
216
  ];
217
217
  }
218
218
 
219
+ /**
220
+ * @return {!Grid | undefined}
221
+ * @protected
222
+ */
223
+ get _grid() {
224
+ if (!this._gridValue) {
225
+ this._gridValue = this._findHostGrid();
226
+ }
227
+ return this._gridValue;
228
+ }
229
+
230
+ /**
231
+ * @return {!Array<!HTMLElement>}
232
+ * @protected
233
+ */
234
+ get _allCells() {
235
+ return []
236
+ .concat(this._cells || [])
237
+ .concat(this._emptyCells || [])
238
+ .concat(this._headerCell)
239
+ .concat(this._footerCell)
240
+ .filter((cell) => cell);
241
+ }
242
+
219
243
  /** @protected */
220
244
  connectedCallback() {
221
245
  super.connectedCallback();
@@ -277,30 +301,6 @@ export const ColumnBaseMixin = (superClass) =>
277
301
  return el || undefined;
278
302
  }
279
303
 
280
- /**
281
- * @return {!Grid | undefined}
282
- * @protected
283
- */
284
- get _grid() {
285
- if (!this._gridValue) {
286
- this._gridValue = this._findHostGrid();
287
- }
288
- return this._gridValue;
289
- }
290
-
291
- /**
292
- * @return {!Array<!HTMLElement>}
293
- * @protected
294
- */
295
- get _allCells() {
296
- return []
297
- .concat(this._cells || [])
298
- .concat(this._emptyCells || [])
299
- .concat(this._headerCell)
300
- .concat(this._footerCell)
301
- .filter((cell) => cell);
302
- }
303
-
304
304
  /** @protected */
305
305
  _renderHeaderAndFooter() {
306
306
  this._renderHeaderCellContent(this._headerRenderer, this._headerCell);
@@ -85,14 +85,12 @@ export const ItemCache = class ItemCache {
85
85
  */
86
86
  getCacheAndIndex(index) {
87
87
  let thisLevelIndex = index;
88
- const keys = Object.keys(this.itemCaches);
89
- for (let i = 0; i < keys.length; i++) {
90
- const expandedIndex = Number(keys[i]);
91
- const subCache = this.itemCaches[expandedIndex];
92
- if (thisLevelIndex <= expandedIndex) {
88
+ for (const [index, subCache] of Object.entries(this.itemCaches)) {
89
+ const numberIndex = Number(index);
90
+ if (thisLevelIndex <= numberIndex) {
93
91
  return { cache: this, scaledIndex: thisLevelIndex };
94
- } else if (thisLevelIndex <= expandedIndex + subCache.effectiveSize) {
95
- return subCache.getCacheAndIndex(thisLevelIndex - expandedIndex - 1);
92
+ } else if (thisLevelIndex <= numberIndex + subCache.effectiveSize) {
93
+ return subCache.getCacheAndIndex(thisLevelIndex - numberIndex - 1);
96
94
  }
97
95
  thisLevelIndex -= subCache.effectiveSize;
98
96
  }
@@ -461,10 +459,10 @@ export const DataProviderMixin = (superClass) =>
461
459
  _checkSize() {
462
460
  if (this.size === undefined && this._effectiveSize === 0) {
463
461
  console.warn(
464
- 'The <vaadin-grid> needs the total number of items' +
465
- ' in order to display rows. Set the total number of items' +
466
- ' to the `size` property, or provide the total number of items' +
467
- ' in the second argument of the `dataProvider`’s `callback` call.',
462
+ 'The <vaadin-grid> needs the total number of items in' +
463
+ ' order to display rows, which you can specify either by setting' +
464
+ ' the `size` property, or by providing it to the second argument' +
465
+ ' of the `dataProvider` function `callback` call.',
468
466
  );
469
467
  }
470
468
  }
@@ -50,13 +50,7 @@ export const DynamicColumnsMixin = (superClass) =>
50
50
 
51
51
  /** @private */
52
52
  _hasColumnGroups(columns) {
53
- for (let i = 0; i < columns.length; i++) {
54
- if (columns[i].localName === 'vaadin-grid-column-group') {
55
- return true;
56
- }
57
- }
58
-
59
- return false;
53
+ return columns.some((column) => column.localName === 'vaadin-grid-column-group');
60
54
  }
61
55
 
62
56
  /**
@@ -77,6 +77,33 @@ export const KeyboardNavigationMixin = (superClass) =>
77
77
  };
78
78
  }
79
79
 
80
+ /** @private */
81
+ get __rowFocusMode() {
82
+ return (
83
+ this.__isRow(this._itemsFocusable) || this.__isRow(this._headerFocusable) || this.__isRow(this._footerFocusable)
84
+ );
85
+ }
86
+
87
+ set __rowFocusMode(value) {
88
+ ['_itemsFocusable', '_footerFocusable', '_headerFocusable'].forEach((prop) => {
89
+ const focusable = this[prop];
90
+ if (value) {
91
+ const parent = focusable && focusable.parentElement;
92
+ if (this.__isCell(focusable)) {
93
+ // Cell itself focusable (default)
94
+ this[prop] = parent;
95
+ } else if (this.__isCell(parent)) {
96
+ // Focus button mode is enabled for the column,
97
+ // button element inside the cell is focusable.
98
+ this[prop] = parent.parentElement;
99
+ }
100
+ } else if (!value && this.__isRow(focusable)) {
101
+ const cell = focusable.firstElementChild;
102
+ this[prop] = cell._focusButton || cell;
103
+ }
104
+ });
105
+ }
106
+
80
107
  /** @protected */
81
108
  ready() {
82
109
  super.ready();
@@ -93,7 +120,7 @@ export const KeyboardNavigationMixin = (superClass) =>
93
120
  this.addEventListener('focusout', this._onFocusOut);
94
121
 
95
122
  // When focus goes from cell to another cell, focusin/focusout events do
96
- // not escape the grids shadowRoot, thus listening inside the shadowRoot.
123
+ // not escape the grid's shadowRoot, thus listening inside the shadowRoot.
97
124
  this.$.table.addEventListener('focusin', this._onContentFocusIn.bind(this));
98
125
 
99
126
  this.addEventListener('mousedown', () => {
@@ -108,33 +135,6 @@ export const KeyboardNavigationMixin = (superClass) =>
108
135
  });
109
136
  }
110
137
 
111
- /** @private */
112
- get __rowFocusMode() {
113
- return (
114
- this.__isRow(this._itemsFocusable) || this.__isRow(this._headerFocusable) || this.__isRow(this._footerFocusable)
115
- );
116
- }
117
-
118
- set __rowFocusMode(value) {
119
- ['_itemsFocusable', '_footerFocusable', '_headerFocusable'].forEach((prop) => {
120
- const focusable = this[prop];
121
- if (value) {
122
- const parent = focusable && focusable.parentElement;
123
- if (this.__isCell(focusable)) {
124
- // Cell itself focusable (default)
125
- this[prop] = parent;
126
- } else if (this.__isCell(parent)) {
127
- // Focus button mode is enabled for the column,
128
- // button element inside the cell is focusable.
129
- this[prop] = parent.parentElement;
130
- }
131
- } else if (!value && this.__isRow(focusable)) {
132
- const cell = focusable.firstElementChild;
133
- this[prop] = cell._focusButton || cell;
134
- }
135
- });
136
- }
137
-
138
138
  /** @private */
139
139
  _focusableChanged(focusable, oldFocusable) {
140
140
  if (oldFocusable) {
@@ -243,7 +243,7 @@ export const KeyboardNavigationMixin = (superClass) =>
243
243
 
244
244
  this._detectInteracting(e);
245
245
  if (this.interacting && keyGroup !== 'Interaction') {
246
- // When in the interacting mode, only the Interaction keys are handled.
246
+ // When in the interacting mode, only the "Interaction" keys are handled.
247
247
  keyGroup = undefined;
248
248
  }
249
249
 
@@ -526,7 +526,7 @@ export const KeyboardNavigationMixin = (superClass) =>
526
526
  const activeRowGroup = activeRow.parentNode;
527
527
  const currentRowIndex = this.__getIndexInGroup(activeRow, this._focusedItemIndex);
528
528
 
529
- // _focusedColumnOrder is memoized this is to ensure predictable
529
+ // _focusedColumnOrder is memoized - this is to ensure predictable
530
530
  // navigation when entering and leaving detail and column group cells.
531
531
  if (this._focusedColumnOrder === undefined) {
532
532
  if (isCurrentCellRowDetails) {
@@ -545,7 +545,7 @@ export const KeyboardNavigationMixin = (superClass) =>
545
545
  } else {
546
546
  // Focusing a regular cell on the destination row
547
547
 
548
- // Find orderedColumnIndex the index of order closest matching the
548
+ // Find orderedColumnIndex - the index of order closest matching the
549
549
  // original _focusedColumnOrder in the sorted array of orders
550
550
  // of the visible columns on the destination row.
551
551
  const dstRowIndex = this.__getIndexInGroup(dstRow, this._focusedItemIndex);
@@ -91,7 +91,7 @@ export const RowDetailsMixin = (superClass) =>
91
91
 
92
92
  /** @private */
93
93
  _detailsOpenedItemsChanged(changeRecord, rowDetailsRenderer) {
94
- // Skip to avoid duplicate work of both “.splices and “.length updates.
94
+ // Skip to avoid duplicate work of both `.splices` and `.length` updates.
95
95
  if (changeRecord.path === 'detailsOpenedItems.length' || !changeRecord.value) {
96
96
  return;
97
97
  }
@@ -42,6 +42,11 @@ export const ScrollMixin = (superClass) =>
42
42
  };
43
43
  }
44
44
 
45
+ /** @private */
46
+ get _scrollLeft() {
47
+ return this.$.table.scrollLeft;
48
+ }
49
+
45
50
  /** @private */
46
51
  get _scrollTop() {
47
52
  return this.$.table.scrollTop;
@@ -55,11 +60,6 @@ export const ScrollMixin = (superClass) =>
55
60
  this.$.table.scrollTop = top;
56
61
  }
57
62
 
58
- /** @private */
59
- get _scrollLeft() {
60
- return this.$.table.scrollLeft;
61
- }
62
-
63
63
  /** @protected */
64
64
  ready() {
65
65
  super.ready();
@@ -147,6 +147,13 @@ export const ScrollMixin = (superClass) =>
147
147
 
148
148
  /** @private */
149
149
  _updateOverflow() {
150
+ this._debounceOverflow = Debouncer.debounce(this._debounceOverflow, animationFrame, () => {
151
+ this.__doUpdateOverflow();
152
+ });
153
+ }
154
+
155
+ /** @private */
156
+ __doUpdateOverflow() {
150
157
  // Set overflow styling attributes
151
158
  let overflow = '';
152
159
  const table = this.$.table;
@@ -182,14 +189,12 @@ export const ScrollMixin = (superClass) =>
182
189
  overflow += ' left';
183
190
  }
184
191
 
185
- this._debounceOverflow = Debouncer.debounce(this._debounceOverflow, animationFrame, () => {
186
- const value = overflow.trim();
187
- if (value.length > 0 && this.getAttribute('overflow') !== value) {
188
- this.setAttribute('overflow', value);
189
- } else if (value.length === 0 && this.hasAttribute('overflow')) {
190
- this.removeAttribute('overflow');
191
- }
192
- });
192
+ const value = overflow.trim();
193
+ if (value.length > 0 && this.getAttribute('overflow') !== value) {
194
+ this.setAttribute('overflow', value);
195
+ } else if (value.length === 0 && this.hasAttribute('overflow')) {
196
+ this.removeAttribute('overflow');
197
+ }
193
198
  }
194
199
 
195
200
  /** @protected */
@@ -267,16 +272,16 @@ export const ScrollMixin = (superClass) =>
267
272
  // Position frozen cells
268
273
  const x = this.__isRTL ? normalizedScrollLeft + clientWidth - scrollWidth : scrollLeft;
269
274
  const transformFrozen = `translate(${x}px, 0)`;
270
- for (let i = 0; i < this._frozenCells.length; i++) {
271
- this._frozenCells[i].style.transform = transformFrozen;
272
- }
275
+ this._frozenCells.forEach((cell) => {
276
+ cell.style.transform = transformFrozen;
277
+ });
273
278
 
274
279
  // Position cells frozen to end
275
280
  const remaining = this.__isRTL ? normalizedScrollLeft : scrollLeft + clientWidth - scrollWidth;
276
281
  const transformFrozenToEnd = `translate(${remaining}px, 0)`;
277
- for (let i = 0; i < this._frozenToEndCells.length; i++) {
278
- this._frozenToEndCells[i].style.transform = transformFrozenToEnd;
279
- }
282
+ this._frozenToEndCells.forEach((cell) => {
283
+ cell.style.transform = transformFrozenToEnd;
284
+ });
280
285
 
281
286
  // Only update the --_grid-horizontal-scroll-position custom property when navigating
282
287
  // on row focus mode to avoid performance issues.
@@ -94,7 +94,7 @@ export const SortMixin = (superClass) =>
94
94
  const sorter = e.target;
95
95
  e.stopPropagation();
96
96
  sorter._grid = this;
97
- this.__updateSorter(sorter, e.detail.shiftClick);
97
+ this.__updateSorter(sorter, e.detail.shiftClick, e.detail.fromSorterClick);
98
98
  this.__applySorters();
99
99
  }
100
100
 
@@ -139,14 +139,17 @@ export const SortMixin = (superClass) =>
139
139
  }
140
140
 
141
141
  /** @private */
142
- __updateSorter(sorter, shiftClick) {
142
+ __updateSorter(sorter, shiftClick, fromSorterClick) {
143
143
  if (!sorter.direction && this._sorters.indexOf(sorter) === -1) {
144
144
  return;
145
145
  }
146
146
 
147
147
  sorter._order = null;
148
148
 
149
- if ((this.multiSort && !this.multiSortOnShiftClick) || (this.multiSortOnShiftClick && shiftClick)) {
149
+ if (
150
+ (this.multiSort && (!this.multiSortOnShiftClick || !fromSorterClick)) ||
151
+ (this.multiSortOnShiftClick && shiftClick)
152
+ ) {
150
153
  if (this.multiSortPriority === 'append') {
151
154
  this.__appendSorter(sorter);
152
155
  } else {
@@ -11,7 +11,7 @@ export type GridSorterDirection = 'asc' | 'desc' | null;
11
11
  /**
12
12
  * Fired when the `path` or `direction` property changes.
13
13
  */
14
- export type GridSorterChangedEvent = CustomEvent<{ shiftClick: boolean }>;
14
+ export type GridSorterChangedEvent = CustomEvent<{ shiftClick: boolean; fromSorterClick: boolean }>;
15
15
 
16
16
  /**
17
17
  * Fired when the `direction` property changes.
@@ -153,12 +153,6 @@ class GridSorter extends ThemableMixin(DirMixin(PolymerElement)) {
153
153
  type: Boolean,
154
154
  observer: '__isConnectedChanged',
155
155
  },
156
-
157
- /** @private */
158
- _shiftClick: {
159
- type: Boolean,
160
- value: false,
161
- },
162
156
  };
163
157
  }
164
158
 
@@ -210,11 +204,14 @@ class GridSorter extends ThemableMixin(DirMixin(PolymerElement)) {
210
204
 
211
205
  this.dispatchEvent(
212
206
  new CustomEvent('sorter-changed', {
213
- detail: { shiftClick: this._shiftClick },
207
+ detail: { shiftClick: Boolean(this._shiftClick), fromSorterClick: Boolean(this._fromSorterClick) },
214
208
  bubbles: true,
215
209
  composed: true,
216
210
  }),
217
211
  );
212
+ // Cleaning up as a programatically sorting can be done after some user interaction
213
+ this._fromSorterClick = false;
214
+ this._shiftClick = false;
218
215
  }
219
216
 
220
217
  /** @private */
@@ -237,6 +234,7 @@ class GridSorter extends ThemableMixin(DirMixin(PolymerElement)) {
237
234
 
238
235
  e.preventDefault();
239
236
  this._shiftClick = e.shiftKey;
237
+ this._fromSorterClick = true;
240
238
  if (this.direction === 'asc') {
241
239
  this.direction = 'desc';
242
240
  } else if (this.direction === 'desc') {
@@ -192,7 +192,7 @@ class GridTreeToggle extends ThemableMixin(DirMixin(PolymerElement)) {
192
192
  if (this.leaf) {
193
193
  return;
194
194
  }
195
- if (isFocusable(e.target)) {
195
+ if (isFocusable(e.target) || e.target instanceof HTMLLabelElement) {
196
196
  return;
197
197
  }
198
198
 
@@ -68,7 +68,7 @@ export interface GridItemModel<TItem> {
68
68
  /**
69
69
  * Fired when the `activeItem` property changes.
70
70
  */
71
- export type GridActiveItemChangedEvent<TItem> = CustomEvent<{ value: TItem }>;
71
+ export type GridActiveItemChangedEvent<TItem> = CustomEvent<{ value: TItem | null | undefined }>;
72
72
 
73
73
  /**
74
74
  * Fired when the cell is activated with click or keyboard.
@@ -262,9 +262,8 @@ export interface GridEventMap<TItem> extends HTMLElementEventMap, GridCustomEven
262
262
  * The `<vaadin-grid>` calls this function lazily, only when it needs more data
263
263
  * to be displayed.
264
264
  *
265
- * See the [`dataProvider`](#/elements/vaadin-grid#property-dataProvider) in
266
- * the API reference below for the detailed data provider arguments description,
267
- * and the “Assigning Data” page in the demos.
265
+ * See the [`dataProvider`](#/elements/vaadin-grid#property-dataProvider) property
266
+ * documentation for the detailed data provider arguments description.
268
267
  *
269
268
  * __Note that expanding the tree grid's item will trigger a call to the `dataProvider`.__
270
269
  *
@@ -134,9 +134,8 @@ import { StylingMixin } from './vaadin-grid-styling-mixin.js';
134
134
  * The `<vaadin-grid>` calls this function lazily, only when it needs more data
135
135
  * to be displayed.
136
136
  *
137
- * See the [`dataProvider`](#/elements/vaadin-grid#property-dataProvider) in
138
- * the API reference below for the detailed data provider arguments description,
139
- * and the “Assigning Data” page in the demos.
137
+ * See the [`dataProvider`](#/elements/vaadin-grid#property-dataProvider) property
138
+ * documentation for the detailed data provider arguments description.
140
139
  *
141
140
  * __Note that expanding the tree grid's item will trigger a call to the `dataProvider`.__
142
141
  *
@@ -436,6 +435,18 @@ class Grid extends ElementMixin(
436
435
  this.addEventListener('animationend', this._onAnimationEnd);
437
436
  }
438
437
 
438
+ /** @private */
439
+ get _firstVisibleIndex() {
440
+ const firstVisibleItem = this.__getFirstVisibleItem();
441
+ return firstVisibleItem ? firstVisibleItem.index : undefined;
442
+ }
443
+
444
+ /** @private */
445
+ get _lastVisibleIndex() {
446
+ const lastVisibleItem = this.__getLastVisibleItem();
447
+ return lastVisibleItem ? lastVisibleItem.index : undefined;
448
+ }
449
+
439
450
  /** @protected */
440
451
  connectedCallback() {
441
452
  super.connectedCallback();
@@ -455,12 +466,6 @@ class Grid extends ElementMixin(
455
466
  return this._getVisibleRows().find((row) => this._isInViewport(row));
456
467
  }
457
468
 
458
- /** @private */
459
- get _firstVisibleIndex() {
460
- const firstVisibleItem = this.__getFirstVisibleItem();
461
- return firstVisibleItem ? firstVisibleItem.index : undefined;
462
- }
463
-
464
469
  /** @private */
465
470
  __getLastVisibleItem() {
466
471
  return this._getVisibleRows()
@@ -468,12 +473,6 @@ class Grid extends ElementMixin(
468
473
  .find((row) => this._isInViewport(row));
469
474
  }
470
475
 
471
- /** @private */
472
- get _lastVisibleIndex() {
473
- const lastVisibleItem = this.__getLastVisibleItem();
474
- return lastVisibleItem ? lastVisibleItem.index : undefined;
475
- }
476
-
477
476
  /** @private */
478
477
  _isInViewport(item) {
479
478
  const scrollTargetRect = this.$.table.getBoundingClientRect();
@@ -777,7 +776,7 @@ class Grid extends ElementMixin(
777
776
  if (isChrome) {
778
777
  // Chrome bug: focusing before mouseup prevents text selection, see http://crbug.com/771903
779
778
  const mouseUpListener = (event) => {
780
- // If focus is on element within the cell content respect it, do not change
779
+ // If focus is on element within the cell content - respect it, do not change
781
780
  const contentContainsFocusedElement = cellContent.contains(this.getRootNode().activeElement);
782
781
  // Only focus if mouse is released on cell content itself
783
782
  const mouseUpWithinCell = event.composedPath().includes(cellContent);
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/grid",
4
- "version": "24.0.0-alpha9",
4
+ "version": "24.0.0-beta2",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-grid-column",
11
- "description": "A `<vaadin-grid-column>` is used to configure how a column in `<vaadin-grid>`\nshould look like.\n\nSee [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid) documentation for instructions on how\nto configure the `<vaadin-grid-column>`.",
11
+ "description": "A `<vaadin-grid-column>` is used to configure how a column in `<vaadin-grid>`\nshould look like.\n\nSee [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid) documentation for instructions on how\nto configure the `<vaadin-grid-column>`.",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "resizable",
@@ -765,7 +765,7 @@
765
765
  },
766
766
  {
767
767
  "name": "vaadin-grid-selection-column",
768
- "description": "`<vaadin-grid-selection-column>` is a helper element for the `<vaadin-grid>`\nthat provides default renderers and functionality for item selection.\n\n#### Example:\n```html\n<vaadin-grid items=\"[[items]]\">\n <vaadin-grid-selection-column frozen auto-select></vaadin-grid-selection-column>\n\n <vaadin-grid-column>\n ...\n```\n\nBy default the selection column displays `<vaadin-checkbox>` elements in the\ncolumn cells. The checkboxes in the body rows toggle selection of the corresponding row items.\n\nWhen the grid data is provided as an array of [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid#property-items),\nthe column header gets an additional checkbox that can be used for toggling\nselection for all the items at once.\n\n__The default content can also be overridden__",
768
+ "description": "`<vaadin-grid-selection-column>` is a helper element for the `<vaadin-grid>`\nthat provides default renderers and functionality for item selection.\n\n#### Example:\n```html\n<vaadin-grid items=\"[[items]]\">\n <vaadin-grid-selection-column frozen auto-select></vaadin-grid-selection-column>\n\n <vaadin-grid-column>\n ...\n```\n\nBy default the selection column displays `<vaadin-checkbox>` elements in the\ncolumn cells. The checkboxes in the body rows toggle selection of the corresponding row items.\n\nWhen the grid data is provided as an array of [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid#property-items),\nthe column header gets an additional checkbox that can be used for toggling\nselection for all the items at once.\n\n__The default content can also be overridden__",
769
769
  "attributes": [
770
770
  {
771
771
  "name": "resizable",
@@ -1758,7 +1758,7 @@
1758
1758
  },
1759
1759
  {
1760
1760
  "name": "vaadin-grid",
1761
- "description": "`<vaadin-grid>` is a free, high quality data grid / data table Web Component. The content of the\nthe grid can be populated by using renderer callback function.\n\n### Quick Start\n\nStart with an assigning an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid#property-items) property to visualize your data.\n\nUse the [`<vaadin-grid-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-column) element to configure the grid columns. Set `path` and `header`\nshorthand properties for the columns to define what gets rendered in the cells of the column.\n\n#### Example:\n```html\n<vaadin-grid>\n <vaadin-grid-column path=\"name.first\" header=\"First name\"></vaadin-grid-column>\n <vaadin-grid-column path=\"name.last\" header=\"Last name\"></vaadin-grid-column>\n <vaadin-grid-column path=\"email\"></vaadin-grid-column>\n</vaadin-grid>\n```\n\nFor custom content `vaadin-grid-column` element provides you with three types of `renderer` callback functions: `headerRenderer`,\n`renderer` and `footerRenderer`.\n\nEach of those renderer functions provides `root`, `column`, `model` arguments when applicable.\nGenerate DOM content, append it to the `root` element and control the state\nof the host element by accessing `column`. Before generating new content,\nusers are able to check if there is already content in `root` for reusing it.\n\nRenderers are called on initialization of new column cells and each time the\nrelated row model is updated. DOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n#### Example:\n```html\n<vaadin-grid>\n <vaadin-grid-column></vaadin-grid-column>\n <vaadin-grid-column></vaadin-grid-column>\n <vaadin-grid-column></vaadin-grid-column>\n</vaadin-grid>\n```\n```js\nconst grid = document.querySelector('vaadin-grid');\ngrid.items = [{'name': 'John', 'surname': 'Lennon', 'role': 'singer'},\n {'name': 'Ringo', 'surname': 'Starr', 'role': 'drums'}];\n\nconst columns = grid.querySelectorAll('vaadin-grid-column');\n\ncolumns[0].headerRenderer = function(root) {\n root.textContent = 'Name';\n};\ncolumns[0].renderer = function(root, column, model) {\n root.textContent = model.item.name;\n};\n\ncolumns[1].headerRenderer = function(root) {\n root.textContent = 'Surname';\n};\ncolumns[1].renderer = function(root, column, model) {\n root.textContent = model.item.surname;\n};\n\ncolumns[2].headerRenderer = function(root) {\n root.textContent = 'Role';\n};\ncolumns[2].renderer = function(root, column, model) {\n root.textContent = model.item.role;\n};\n```\n\nThe following properties are available in the `model` argument:\n\nProperty name | Type | Description\n--------------|------|------------\n`index`| Number | The index of the item.\n`item` | String or Object | The item.\n`level` | Number | Number of the item's tree sublevel, starts from 0.\n`expanded` | Boolean | True if the item's tree sublevel is expanded.\n`selected` | Boolean | True if the item is selected.\n`detailsOpened` | Boolean | True if the item's row details are open.\n\nThe following helper elements can be used for further customization:\n- [`<vaadin-grid-column-group>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-column-group)\n- [`<vaadin-grid-filter>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-filter)\n- [`<vaadin-grid-sorter>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-sorter)\n- [`<vaadin-grid-selection-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-selection-column)\n- [`<vaadin-grid-tree-toggle>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-tree-toggle)\n\n__Note that the helper elements must be explicitly imported.__\nIf you want to import everything at once you can use the `all-imports.html` bundle.\n\n### Lazy Loading with Function Data Provider\n\nIn addition to assigning an array to the items property, you can alternatively\nprovide the `<vaadin-grid>` data through the\n[`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid#property-dataProvider) function property.\nThe `<vaadin-grid>` calls this function lazily, only when it needs more data\nto be displayed.\n\nSee the [`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid#property-dataProvider) in\nthe API reference below for the detailed data provider arguments description,\nand the “Assigning Data” page in the demos.\n\n__Note that expanding the tree grid's item will trigger a call to the `dataProvider`.__\n\n__Also, note that when using function data providers, the total number of items\nneeds to be set manually. The total number of items can be returned\nin the second argument of the data provider callback:__\n\n```javascript\ngrid.dataProvider = ({page, pageSize}, callback) => {\n // page: the requested page index\n // pageSize: number of items on one page\n const url = `https://api.example/data?page=${page}&per_page=${pageSize}`;\n\n fetch(url)\n .then((res) => res.json())\n .then(({ employees, totalSize }) => {\n callback(employees, totalSize);\n });\n};\n```\n\n__Alternatively, you can use the `size` property to set the total number of items:__\n\n```javascript\ngrid.size = 200; // The total number of items\ngrid.dataProvider = ({page, pageSize}, callback) => {\n const url = `https://api.example/data?page=${page}&per_page=${pageSize}`;\n\n fetch(url)\n .then((res) => res.json())\n .then((resJson) => callback(resJson.employees));\n};\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------------|----------------\n`row` | Row in the internal table\n`expanded-row` | Expanded row\n`selected-row` | Selected row\n`details-opened-row` | Row with details open\n`odd-row` | Odd row\n`even-row` | Even row\n`first-row` | The first body row\n`last-row` | The last body row\n`dragstart-row` | Set on the row for one frame when drag is starting.\n`dragover-above-row` | Set on the row when the a row is dragged over above\n`dragover-below-row` | Set on the row when the a row is dragged over below\n`dragover-on-top-row` | Set on the row when the a row is dragged over on top\n`drag-disabled-row` | Set to a row that isn't available for dragging\n`drop-disabled-row` | Set to a row that can't be dropped on top of\n`cell` | Cell in the internal table\n`header-cell` | Header cell in the internal table\n`body-cell` | Body cell in the internal table\n`footer-cell` | Footer cell in the internal table\n`details-cell` | Row details cell in the internal table\n`focused-cell` | Focused cell in the internal table\n`odd-row-cell` | Cell in an odd row\n`even-row-cell` | Cell in an even row\n`first-row-cell` | Cell in the first body row\n`last-row-cell` | Cell in the last body row\n`first-header-row-cell` | Cell in the first header row\n`first-footer-row-cell` | Cell in the first footer row\n`last-header-row-cell` | Cell in the last header row\n`last-footer-row-cell` | Cell in the last footer row\n`loading-row-cell` | Cell in a row that is waiting for data from data provider\n`selected-row-cell` | Cell in a selected row\n`expanded-row-cell` | Cell in an expanded row\n`details-opened-row-cell` | Cell in an row with details open\n`dragstart-row-cell` | Cell in a row that user started to drag (set for one frame)\n`dragover-above-row-cell` | Cell in a row that has another row dragged over above\n`dragover-below-row-cell` | Cell in a row that has another row dragged over below\n`dragover-on-top-row-cell` | Cell in a row that has another row dragged over on top\n`drag-disabled-row-cell` | Cell in a row that isn't available for dragging\n`drop-disabled-row-cell` | Cell in a row that can't be dropped on top of\n`frozen-cell` | Frozen cell in the internal table\n`frozen-to-end-cell` | Frozen to end cell in the internal table\n`last-frozen-cell` | Last frozen cell\n`first-frozen-to-end-cell` | First cell frozen to end\n`first-column-cell` | First visible cell on a row\n`last-column-cell` | Last visible cell on a row\n`reorder-allowed-cell` | Cell in a column where another column can be reordered\n`reorder-dragging-cell` | Cell in a column currently being reordered\n`resize-handle` | Handle for resizing the columns\n`reorder-ghost` | Ghost element of the header cell being dragged\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n----------------------|---------------------------------------------------------------------------------------------------|-----------\n`loading` | Set when the grid is loading data from data provider | :host\n`interacting` | Keyboard navigation in interaction mode | :host\n`navigating` | Keyboard navigation in navigation mode | :host\n`overflow` | Set when rows are overflowing the grid viewport. Possible values: `top`, `bottom`, `start`, `end` | :host\n`reordering` | Set when the grid's columns are being reordered | :host\n`dragover` | Set when the grid (not a specific row) is dragged over | :host\n`dragging-rows` | Set when grid rows are dragged | :host\n`reorder-status` | Reflects the status of a cell while columns are being reordered | cell\n`frozen` | Frozen cell | cell\n`frozen-to-end` | Cell frozen to end | cell\n`last-frozen` | Last frozen cell | cell\n`first-frozen-to-end` | First cell frozen to end | cell\n`first-column` | First visible cell on a row | cell\n`last-column` | Last visible cell on a row | cell\n`selected` | Selected row | row\n`expanded` | Expanded row | row\n`details-opened` | Row with details open | row\n`loading` | Row that is waiting for data from data provider | row\n`odd` | Odd row | row\n`first` | The first body row | row\n`last` | The last body row | row\n`dragstart` | Set for one frame when starting to drag a row. The value is a number when dragging multiple rows | row\n`dragover` | Set when the row is dragged over | row\n`drag-disabled` | Set to a row that isn't available for dragging | row\n`drop-disabled` | Set to a row that can't be dropped on top of | row\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
1761
+ "description": "`<vaadin-grid>` is a free, high quality data grid / data table Web Component. The content of the\nthe grid can be populated by using renderer callback function.\n\n### Quick Start\n\nStart with an assigning an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid#property-items) property to visualize your data.\n\nUse the [`<vaadin-grid-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-column) element to configure the grid columns. Set `path` and `header`\nshorthand properties for the columns to define what gets rendered in the cells of the column.\n\n#### Example:\n```html\n<vaadin-grid>\n <vaadin-grid-column path=\"name.first\" header=\"First name\"></vaadin-grid-column>\n <vaadin-grid-column path=\"name.last\" header=\"Last name\"></vaadin-grid-column>\n <vaadin-grid-column path=\"email\"></vaadin-grid-column>\n</vaadin-grid>\n```\n\nFor custom content `vaadin-grid-column` element provides you with three types of `renderer` callback functions: `headerRenderer`,\n`renderer` and `footerRenderer`.\n\nEach of those renderer functions provides `root`, `column`, `model` arguments when applicable.\nGenerate DOM content, append it to the `root` element and control the state\nof the host element by accessing `column`. Before generating new content,\nusers are able to check if there is already content in `root` for reusing it.\n\nRenderers are called on initialization of new column cells and each time the\nrelated row model is updated. DOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n#### Example:\n```html\n<vaadin-grid>\n <vaadin-grid-column></vaadin-grid-column>\n <vaadin-grid-column></vaadin-grid-column>\n <vaadin-grid-column></vaadin-grid-column>\n</vaadin-grid>\n```\n```js\nconst grid = document.querySelector('vaadin-grid');\ngrid.items = [{'name': 'John', 'surname': 'Lennon', 'role': 'singer'},\n {'name': 'Ringo', 'surname': 'Starr', 'role': 'drums'}];\n\nconst columns = grid.querySelectorAll('vaadin-grid-column');\n\ncolumns[0].headerRenderer = function(root) {\n root.textContent = 'Name';\n};\ncolumns[0].renderer = function(root, column, model) {\n root.textContent = model.item.name;\n};\n\ncolumns[1].headerRenderer = function(root) {\n root.textContent = 'Surname';\n};\ncolumns[1].renderer = function(root, column, model) {\n root.textContent = model.item.surname;\n};\n\ncolumns[2].headerRenderer = function(root) {\n root.textContent = 'Role';\n};\ncolumns[2].renderer = function(root, column, model) {\n root.textContent = model.item.role;\n};\n```\n\nThe following properties are available in the `model` argument:\n\nProperty name | Type | Description\n--------------|------|------------\n`index`| Number | The index of the item.\n`item` | String or Object | The item.\n`level` | Number | Number of the item's tree sublevel, starts from 0.\n`expanded` | Boolean | True if the item's tree sublevel is expanded.\n`selected` | Boolean | True if the item is selected.\n`detailsOpened` | Boolean | True if the item's row details are open.\n\nThe following helper elements can be used for further customization:\n- [`<vaadin-grid-column-group>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-column-group)\n- [`<vaadin-grid-filter>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-filter)\n- [`<vaadin-grid-sorter>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-sorter)\n- [`<vaadin-grid-selection-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-selection-column)\n- [`<vaadin-grid-tree-toggle>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-tree-toggle)\n\n__Note that the helper elements must be explicitly imported.__\nIf you want to import everything at once you can use the `all-imports.html` bundle.\n\n### Lazy Loading with Function Data Provider\n\nIn addition to assigning an array to the items property, you can alternatively\nprovide the `<vaadin-grid>` data through the\n[`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid#property-dataProvider) function property.\nThe `<vaadin-grid>` calls this function lazily, only when it needs more data\nto be displayed.\n\nSee the [`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid#property-dataProvider) property\ndocumentation for the detailed data provider arguments description.\n\n__Note that expanding the tree grid's item will trigger a call to the `dataProvider`.__\n\n__Also, note that when using function data providers, the total number of items\nneeds to be set manually. The total number of items can be returned\nin the second argument of the data provider callback:__\n\n```javascript\ngrid.dataProvider = ({page, pageSize}, callback) => {\n // page: the requested page index\n // pageSize: number of items on one page\n const url = `https://api.example/data?page=${page}&per_page=${pageSize}`;\n\n fetch(url)\n .then((res) => res.json())\n .then(({ employees, totalSize }) => {\n callback(employees, totalSize);\n });\n};\n```\n\n__Alternatively, you can use the `size` property to set the total number of items:__\n\n```javascript\ngrid.size = 200; // The total number of items\ngrid.dataProvider = ({page, pageSize}, callback) => {\n const url = `https://api.example/data?page=${page}&per_page=${pageSize}`;\n\n fetch(url)\n .then((res) => res.json())\n .then((resJson) => callback(resJson.employees));\n};\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------------|----------------\n`row` | Row in the internal table\n`expanded-row` | Expanded row\n`selected-row` | Selected row\n`details-opened-row` | Row with details open\n`odd-row` | Odd row\n`even-row` | Even row\n`first-row` | The first body row\n`last-row` | The last body row\n`dragstart-row` | Set on the row for one frame when drag is starting.\n`dragover-above-row` | Set on the row when the a row is dragged over above\n`dragover-below-row` | Set on the row when the a row is dragged over below\n`dragover-on-top-row` | Set on the row when the a row is dragged over on top\n`drag-disabled-row` | Set to a row that isn't available for dragging\n`drop-disabled-row` | Set to a row that can't be dropped on top of\n`cell` | Cell in the internal table\n`header-cell` | Header cell in the internal table\n`body-cell` | Body cell in the internal table\n`footer-cell` | Footer cell in the internal table\n`details-cell` | Row details cell in the internal table\n`focused-cell` | Focused cell in the internal table\n`odd-row-cell` | Cell in an odd row\n`even-row-cell` | Cell in an even row\n`first-row-cell` | Cell in the first body row\n`last-row-cell` | Cell in the last body row\n`first-header-row-cell` | Cell in the first header row\n`first-footer-row-cell` | Cell in the first footer row\n`last-header-row-cell` | Cell in the last header row\n`last-footer-row-cell` | Cell in the last footer row\n`loading-row-cell` | Cell in a row that is waiting for data from data provider\n`selected-row-cell` | Cell in a selected row\n`expanded-row-cell` | Cell in an expanded row\n`details-opened-row-cell` | Cell in an row with details open\n`dragstart-row-cell` | Cell in a row that user started to drag (set for one frame)\n`dragover-above-row-cell` | Cell in a row that has another row dragged over above\n`dragover-below-row-cell` | Cell in a row that has another row dragged over below\n`dragover-on-top-row-cell` | Cell in a row that has another row dragged over on top\n`drag-disabled-row-cell` | Cell in a row that isn't available for dragging\n`drop-disabled-row-cell` | Cell in a row that can't be dropped on top of\n`frozen-cell` | Frozen cell in the internal table\n`frozen-to-end-cell` | Frozen to end cell in the internal table\n`last-frozen-cell` | Last frozen cell\n`first-frozen-to-end-cell` | First cell frozen to end\n`first-column-cell` | First visible cell on a row\n`last-column-cell` | Last visible cell on a row\n`reorder-allowed-cell` | Cell in a column where another column can be reordered\n`reorder-dragging-cell` | Cell in a column currently being reordered\n`resize-handle` | Handle for resizing the columns\n`reorder-ghost` | Ghost element of the header cell being dragged\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n----------------------|---------------------------------------------------------------------------------------------------|-----------\n`loading` | Set when the grid is loading data from data provider | :host\n`interacting` | Keyboard navigation in interaction mode | :host\n`navigating` | Keyboard navigation in navigation mode | :host\n`overflow` | Set when rows are overflowing the grid viewport. Possible values: `top`, `bottom`, `start`, `end` | :host\n`reordering` | Set when the grid's columns are being reordered | :host\n`dragover` | Set when the grid (not a specific row) is dragged over | :host\n`dragging-rows` | Set when grid rows are dragged | :host\n`reorder-status` | Reflects the status of a cell while columns are being reordered | cell\n`frozen` | Frozen cell | cell\n`frozen-to-end` | Cell frozen to end | cell\n`last-frozen` | Last frozen cell | cell\n`first-frozen-to-end` | First cell frozen to end | cell\n`first-column` | First visible cell on a row | cell\n`last-column` | Last visible cell on a row | cell\n`selected` | Selected row | row\n`expanded` | Expanded row | row\n`details-opened` | Row with details open | row\n`loading` | Row that is waiting for data from data provider | row\n`odd` | Odd row | row\n`first` | The first body row | row\n`last` | The last body row | row\n`dragstart` | Set for one frame when starting to drag a row. The value is a number when dragging multiple rows | row\n`dragover` | Set when the row is dragged over | row\n`drag-disabled` | Set to a row that isn't available for dragging | row\n`drop-disabled` | Set to a row that can't be dropped on top of | row\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
1762
1762
  "attributes": [
1763
1763
  {
1764
1764
  "name": "size",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/grid",
4
- "version": "24.0.0-alpha9",
4
+ "version": "24.0.0-beta2",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -16,7 +16,7 @@
16
16
  "elements": [
17
17
  {
18
18
  "name": "vaadin-grid-column",
19
- "description": "A `<vaadin-grid-column>` is used to configure how a column in `<vaadin-grid>`\nshould look like.\n\nSee [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid) documentation for instructions on how\nto configure the `<vaadin-grid-column>`.",
19
+ "description": "A `<vaadin-grid-column>` is used to configure how a column in `<vaadin-grid>`\nshould look like.\n\nSee [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid) documentation for instructions on how\nto configure the `<vaadin-grid-column>`.",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {
@@ -303,7 +303,7 @@
303
303
  },
304
304
  {
305
305
  "name": "vaadin-grid-selection-column",
306
- "description": "`<vaadin-grid-selection-column>` is a helper element for the `<vaadin-grid>`\nthat provides default renderers and functionality for item selection.\n\n#### Example:\n```html\n<vaadin-grid items=\"[[items]]\">\n <vaadin-grid-selection-column frozen auto-select></vaadin-grid-selection-column>\n\n <vaadin-grid-column>\n ...\n```\n\nBy default the selection column displays `<vaadin-checkbox>` elements in the\ncolumn cells. The checkboxes in the body rows toggle selection of the corresponding row items.\n\nWhen the grid data is provided as an array of [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid#property-items),\nthe column header gets an additional checkbox that can be used for toggling\nselection for all the items at once.\n\n__The default content can also be overridden__",
306
+ "description": "`<vaadin-grid-selection-column>` is a helper element for the `<vaadin-grid>`\nthat provides default renderers and functionality for item selection.\n\n#### Example:\n```html\n<vaadin-grid items=\"[[items]]\">\n <vaadin-grid-selection-column frozen auto-select></vaadin-grid-selection-column>\n\n <vaadin-grid-column>\n ...\n```\n\nBy default the selection column displays `<vaadin-checkbox>` elements in the\ncolumn cells. The checkboxes in the body rows toggle selection of the corresponding row items.\n\nWhen the grid data is provided as an array of [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid#property-items),\nthe column header gets an additional checkbox that can be used for toggling\nselection for all the items at once.\n\n__The default content can also be overridden__",
307
307
  "extension": true,
308
308
  "attributes": [
309
309
  {
@@ -695,7 +695,7 @@
695
695
  },
696
696
  {
697
697
  "name": "vaadin-grid",
698
- "description": "`<vaadin-grid>` is a free, high quality data grid / data table Web Component. The content of the\nthe grid can be populated by using renderer callback function.\n\n### Quick Start\n\nStart with an assigning an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid#property-items) property to visualize your data.\n\nUse the [`<vaadin-grid-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-column) element to configure the grid columns. Set `path` and `header`\nshorthand properties for the columns to define what gets rendered in the cells of the column.\n\n#### Example:\n```html\n<vaadin-grid>\n <vaadin-grid-column path=\"name.first\" header=\"First name\"></vaadin-grid-column>\n <vaadin-grid-column path=\"name.last\" header=\"Last name\"></vaadin-grid-column>\n <vaadin-grid-column path=\"email\"></vaadin-grid-column>\n</vaadin-grid>\n```\n\nFor custom content `vaadin-grid-column` element provides you with three types of `renderer` callback functions: `headerRenderer`,\n`renderer` and `footerRenderer`.\n\nEach of those renderer functions provides `root`, `column`, `model` arguments when applicable.\nGenerate DOM content, append it to the `root` element and control the state\nof the host element by accessing `column`. Before generating new content,\nusers are able to check if there is already content in `root` for reusing it.\n\nRenderers are called on initialization of new column cells and each time the\nrelated row model is updated. DOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n#### Example:\n```html\n<vaadin-grid>\n <vaadin-grid-column></vaadin-grid-column>\n <vaadin-grid-column></vaadin-grid-column>\n <vaadin-grid-column></vaadin-grid-column>\n</vaadin-grid>\n```\n```js\nconst grid = document.querySelector('vaadin-grid');\ngrid.items = [{'name': 'John', 'surname': 'Lennon', 'role': 'singer'},\n {'name': 'Ringo', 'surname': 'Starr', 'role': 'drums'}];\n\nconst columns = grid.querySelectorAll('vaadin-grid-column');\n\ncolumns[0].headerRenderer = function(root) {\n root.textContent = 'Name';\n};\ncolumns[0].renderer = function(root, column, model) {\n root.textContent = model.item.name;\n};\n\ncolumns[1].headerRenderer = function(root) {\n root.textContent = 'Surname';\n};\ncolumns[1].renderer = function(root, column, model) {\n root.textContent = model.item.surname;\n};\n\ncolumns[2].headerRenderer = function(root) {\n root.textContent = 'Role';\n};\ncolumns[2].renderer = function(root, column, model) {\n root.textContent = model.item.role;\n};\n```\n\nThe following properties are available in the `model` argument:\n\nProperty name | Type | Description\n--------------|------|------------\n`index`| Number | The index of the item.\n`item` | String or Object | The item.\n`level` | Number | Number of the item's tree sublevel, starts from 0.\n`expanded` | Boolean | True if the item's tree sublevel is expanded.\n`selected` | Boolean | True if the item is selected.\n`detailsOpened` | Boolean | True if the item's row details are open.\n\nThe following helper elements can be used for further customization:\n- [`<vaadin-grid-column-group>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-column-group)\n- [`<vaadin-grid-filter>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-filter)\n- [`<vaadin-grid-sorter>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-sorter)\n- [`<vaadin-grid-selection-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-selection-column)\n- [`<vaadin-grid-tree-toggle>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid-tree-toggle)\n\n__Note that the helper elements must be explicitly imported.__\nIf you want to import everything at once you can use the `all-imports.html` bundle.\n\n### Lazy Loading with Function Data Provider\n\nIn addition to assigning an array to the items property, you can alternatively\nprovide the `<vaadin-grid>` data through the\n[`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid#property-dataProvider) function property.\nThe `<vaadin-grid>` calls this function lazily, only when it needs more data\nto be displayed.\n\nSee the [`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha9/#/elements/vaadin-grid#property-dataProvider) in\nthe API reference below for the detailed data provider arguments description,\nand the “Assigning Data” page in the demos.\n\n__Note that expanding the tree grid's item will trigger a call to the `dataProvider`.__\n\n__Also, note that when using function data providers, the total number of items\nneeds to be set manually. The total number of items can be returned\nin the second argument of the data provider callback:__\n\n```javascript\ngrid.dataProvider = ({page, pageSize}, callback) => {\n // page: the requested page index\n // pageSize: number of items on one page\n const url = `https://api.example/data?page=${page}&per_page=${pageSize}`;\n\n fetch(url)\n .then((res) => res.json())\n .then(({ employees, totalSize }) => {\n callback(employees, totalSize);\n });\n};\n```\n\n__Alternatively, you can use the `size` property to set the total number of items:__\n\n```javascript\ngrid.size = 200; // The total number of items\ngrid.dataProvider = ({page, pageSize}, callback) => {\n const url = `https://api.example/data?page=${page}&per_page=${pageSize}`;\n\n fetch(url)\n .then((res) => res.json())\n .then((resJson) => callback(resJson.employees));\n};\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------------|----------------\n`row` | Row in the internal table\n`expanded-row` | Expanded row\n`selected-row` | Selected row\n`details-opened-row` | Row with details open\n`odd-row` | Odd row\n`even-row` | Even row\n`first-row` | The first body row\n`last-row` | The last body row\n`dragstart-row` | Set on the row for one frame when drag is starting.\n`dragover-above-row` | Set on the row when the a row is dragged over above\n`dragover-below-row` | Set on the row when the a row is dragged over below\n`dragover-on-top-row` | Set on the row when the a row is dragged over on top\n`drag-disabled-row` | Set to a row that isn't available for dragging\n`drop-disabled-row` | Set to a row that can't be dropped on top of\n`cell` | Cell in the internal table\n`header-cell` | Header cell in the internal table\n`body-cell` | Body cell in the internal table\n`footer-cell` | Footer cell in the internal table\n`details-cell` | Row details cell in the internal table\n`focused-cell` | Focused cell in the internal table\n`odd-row-cell` | Cell in an odd row\n`even-row-cell` | Cell in an even row\n`first-row-cell` | Cell in the first body row\n`last-row-cell` | Cell in the last body row\n`first-header-row-cell` | Cell in the first header row\n`first-footer-row-cell` | Cell in the first footer row\n`last-header-row-cell` | Cell in the last header row\n`last-footer-row-cell` | Cell in the last footer row\n`loading-row-cell` | Cell in a row that is waiting for data from data provider\n`selected-row-cell` | Cell in a selected row\n`expanded-row-cell` | Cell in an expanded row\n`details-opened-row-cell` | Cell in an row with details open\n`dragstart-row-cell` | Cell in a row that user started to drag (set for one frame)\n`dragover-above-row-cell` | Cell in a row that has another row dragged over above\n`dragover-below-row-cell` | Cell in a row that has another row dragged over below\n`dragover-on-top-row-cell` | Cell in a row that has another row dragged over on top\n`drag-disabled-row-cell` | Cell in a row that isn't available for dragging\n`drop-disabled-row-cell` | Cell in a row that can't be dropped on top of\n`frozen-cell` | Frozen cell in the internal table\n`frozen-to-end-cell` | Frozen to end cell in the internal table\n`last-frozen-cell` | Last frozen cell\n`first-frozen-to-end-cell` | First cell frozen to end\n`first-column-cell` | First visible cell on a row\n`last-column-cell` | Last visible cell on a row\n`reorder-allowed-cell` | Cell in a column where another column can be reordered\n`reorder-dragging-cell` | Cell in a column currently being reordered\n`resize-handle` | Handle for resizing the columns\n`reorder-ghost` | Ghost element of the header cell being dragged\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n----------------------|---------------------------------------------------------------------------------------------------|-----------\n`loading` | Set when the grid is loading data from data provider | :host\n`interacting` | Keyboard navigation in interaction mode | :host\n`navigating` | Keyboard navigation in navigation mode | :host\n`overflow` | Set when rows are overflowing the grid viewport. Possible values: `top`, `bottom`, `start`, `end` | :host\n`reordering` | Set when the grid's columns are being reordered | :host\n`dragover` | Set when the grid (not a specific row) is dragged over | :host\n`dragging-rows` | Set when grid rows are dragged | :host\n`reorder-status` | Reflects the status of a cell while columns are being reordered | cell\n`frozen` | Frozen cell | cell\n`frozen-to-end` | Cell frozen to end | cell\n`last-frozen` | Last frozen cell | cell\n`first-frozen-to-end` | First cell frozen to end | cell\n`first-column` | First visible cell on a row | cell\n`last-column` | Last visible cell on a row | cell\n`selected` | Selected row | row\n`expanded` | Expanded row | row\n`details-opened` | Row with details open | row\n`loading` | Row that is waiting for data from data provider | row\n`odd` | Odd row | row\n`first` | The first body row | row\n`last` | The last body row | row\n`dragstart` | Set for one frame when starting to drag a row. The value is a number when dragging multiple rows | row\n`dragover` | Set when the row is dragged over | row\n`drag-disabled` | Set to a row that isn't available for dragging | row\n`drop-disabled` | Set to a row that can't be dropped on top of | row\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
698
+ "description": "`<vaadin-grid>` is a free, high quality data grid / data table Web Component. The content of the\nthe grid can be populated by using renderer callback function.\n\n### Quick Start\n\nStart with an assigning an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid#property-items) property to visualize your data.\n\nUse the [`<vaadin-grid-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-column) element to configure the grid columns. Set `path` and `header`\nshorthand properties for the columns to define what gets rendered in the cells of the column.\n\n#### Example:\n```html\n<vaadin-grid>\n <vaadin-grid-column path=\"name.first\" header=\"First name\"></vaadin-grid-column>\n <vaadin-grid-column path=\"name.last\" header=\"Last name\"></vaadin-grid-column>\n <vaadin-grid-column path=\"email\"></vaadin-grid-column>\n</vaadin-grid>\n```\n\nFor custom content `vaadin-grid-column` element provides you with three types of `renderer` callback functions: `headerRenderer`,\n`renderer` and `footerRenderer`.\n\nEach of those renderer functions provides `root`, `column`, `model` arguments when applicable.\nGenerate DOM content, append it to the `root` element and control the state\nof the host element by accessing `column`. Before generating new content,\nusers are able to check if there is already content in `root` for reusing it.\n\nRenderers are called on initialization of new column cells and each time the\nrelated row model is updated. DOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n#### Example:\n```html\n<vaadin-grid>\n <vaadin-grid-column></vaadin-grid-column>\n <vaadin-grid-column></vaadin-grid-column>\n <vaadin-grid-column></vaadin-grid-column>\n</vaadin-grid>\n```\n```js\nconst grid = document.querySelector('vaadin-grid');\ngrid.items = [{'name': 'John', 'surname': 'Lennon', 'role': 'singer'},\n {'name': 'Ringo', 'surname': 'Starr', 'role': 'drums'}];\n\nconst columns = grid.querySelectorAll('vaadin-grid-column');\n\ncolumns[0].headerRenderer = function(root) {\n root.textContent = 'Name';\n};\ncolumns[0].renderer = function(root, column, model) {\n root.textContent = model.item.name;\n};\n\ncolumns[1].headerRenderer = function(root) {\n root.textContent = 'Surname';\n};\ncolumns[1].renderer = function(root, column, model) {\n root.textContent = model.item.surname;\n};\n\ncolumns[2].headerRenderer = function(root) {\n root.textContent = 'Role';\n};\ncolumns[2].renderer = function(root, column, model) {\n root.textContent = model.item.role;\n};\n```\n\nThe following properties are available in the `model` argument:\n\nProperty name | Type | Description\n--------------|------|------------\n`index`| Number | The index of the item.\n`item` | String or Object | The item.\n`level` | Number | Number of the item's tree sublevel, starts from 0.\n`expanded` | Boolean | True if the item's tree sublevel is expanded.\n`selected` | Boolean | True if the item is selected.\n`detailsOpened` | Boolean | True if the item's row details are open.\n\nThe following helper elements can be used for further customization:\n- [`<vaadin-grid-column-group>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-column-group)\n- [`<vaadin-grid-filter>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-filter)\n- [`<vaadin-grid-sorter>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-sorter)\n- [`<vaadin-grid-selection-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-selection-column)\n- [`<vaadin-grid-tree-toggle>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid-tree-toggle)\n\n__Note that the helper elements must be explicitly imported.__\nIf you want to import everything at once you can use the `all-imports.html` bundle.\n\n### Lazy Loading with Function Data Provider\n\nIn addition to assigning an array to the items property, you can alternatively\nprovide the `<vaadin-grid>` data through the\n[`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid#property-dataProvider) function property.\nThe `<vaadin-grid>` calls this function lazily, only when it needs more data\nto be displayed.\n\nSee the [`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-beta2/#/elements/vaadin-grid#property-dataProvider) property\ndocumentation for the detailed data provider arguments description.\n\n__Note that expanding the tree grid's item will trigger a call to the `dataProvider`.__\n\n__Also, note that when using function data providers, the total number of items\nneeds to be set manually. The total number of items can be returned\nin the second argument of the data provider callback:__\n\n```javascript\ngrid.dataProvider = ({page, pageSize}, callback) => {\n // page: the requested page index\n // pageSize: number of items on one page\n const url = `https://api.example/data?page=${page}&per_page=${pageSize}`;\n\n fetch(url)\n .then((res) => res.json())\n .then(({ employees, totalSize }) => {\n callback(employees, totalSize);\n });\n};\n```\n\n__Alternatively, you can use the `size` property to set the total number of items:__\n\n```javascript\ngrid.size = 200; // The total number of items\ngrid.dataProvider = ({page, pageSize}, callback) => {\n const url = `https://api.example/data?page=${page}&per_page=${pageSize}`;\n\n fetch(url)\n .then((res) => res.json())\n .then((resJson) => callback(resJson.employees));\n};\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------------|----------------\n`row` | Row in the internal table\n`expanded-row` | Expanded row\n`selected-row` | Selected row\n`details-opened-row` | Row with details open\n`odd-row` | Odd row\n`even-row` | Even row\n`first-row` | The first body row\n`last-row` | The last body row\n`dragstart-row` | Set on the row for one frame when drag is starting.\n`dragover-above-row` | Set on the row when the a row is dragged over above\n`dragover-below-row` | Set on the row when the a row is dragged over below\n`dragover-on-top-row` | Set on the row when the a row is dragged over on top\n`drag-disabled-row` | Set to a row that isn't available for dragging\n`drop-disabled-row` | Set to a row that can't be dropped on top of\n`cell` | Cell in the internal table\n`header-cell` | Header cell in the internal table\n`body-cell` | Body cell in the internal table\n`footer-cell` | Footer cell in the internal table\n`details-cell` | Row details cell in the internal table\n`focused-cell` | Focused cell in the internal table\n`odd-row-cell` | Cell in an odd row\n`even-row-cell` | Cell in an even row\n`first-row-cell` | Cell in the first body row\n`last-row-cell` | Cell in the last body row\n`first-header-row-cell` | Cell in the first header row\n`first-footer-row-cell` | Cell in the first footer row\n`last-header-row-cell` | Cell in the last header row\n`last-footer-row-cell` | Cell in the last footer row\n`loading-row-cell` | Cell in a row that is waiting for data from data provider\n`selected-row-cell` | Cell in a selected row\n`expanded-row-cell` | Cell in an expanded row\n`details-opened-row-cell` | Cell in an row with details open\n`dragstart-row-cell` | Cell in a row that user started to drag (set for one frame)\n`dragover-above-row-cell` | Cell in a row that has another row dragged over above\n`dragover-below-row-cell` | Cell in a row that has another row dragged over below\n`dragover-on-top-row-cell` | Cell in a row that has another row dragged over on top\n`drag-disabled-row-cell` | Cell in a row that isn't available for dragging\n`drop-disabled-row-cell` | Cell in a row that can't be dropped on top of\n`frozen-cell` | Frozen cell in the internal table\n`frozen-to-end-cell` | Frozen to end cell in the internal table\n`last-frozen-cell` | Last frozen cell\n`first-frozen-to-end-cell` | First cell frozen to end\n`first-column-cell` | First visible cell on a row\n`last-column-cell` | Last visible cell on a row\n`reorder-allowed-cell` | Cell in a column where another column can be reordered\n`reorder-dragging-cell` | Cell in a column currently being reordered\n`resize-handle` | Handle for resizing the columns\n`reorder-ghost` | Ghost element of the header cell being dragged\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n----------------------|---------------------------------------------------------------------------------------------------|-----------\n`loading` | Set when the grid is loading data from data provider | :host\n`interacting` | Keyboard navigation in interaction mode | :host\n`navigating` | Keyboard navigation in navigation mode | :host\n`overflow` | Set when rows are overflowing the grid viewport. Possible values: `top`, `bottom`, `start`, `end` | :host\n`reordering` | Set when the grid's columns are being reordered | :host\n`dragover` | Set when the grid (not a specific row) is dragged over | :host\n`dragging-rows` | Set when grid rows are dragged | :host\n`reorder-status` | Reflects the status of a cell while columns are being reordered | cell\n`frozen` | Frozen cell | cell\n`frozen-to-end` | Cell frozen to end | cell\n`last-frozen` | Last frozen cell | cell\n`first-frozen-to-end` | First cell frozen to end | cell\n`first-column` | First visible cell on a row | cell\n`last-column` | Last visible cell on a row | cell\n`selected` | Selected row | row\n`expanded` | Expanded row | row\n`details-opened` | Row with details open | row\n`loading` | Row that is waiting for data from data provider | row\n`odd` | Odd row | row\n`first` | The first body row | row\n`last` | The last body row | row\n`dragstart` | Set for one frame when starting to drag a row. The value is a number when dragging multiple rows | row\n`dragover` | Set when the row is dragged over | row\n`drag-disabled` | Set to a row that isn't available for dragging | row\n`drop-disabled` | Set to a row that can't be dropped on top of | row\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
699
699
  "extension": true,
700
700
  "attributes": [
701
701
  {