@vaadin/grid 24.2.0-alpha4 → 24.2.0-dev.538d07bdf

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.2.0-alpha4",
3
+ "version": "24.2.0-dev.538d07bdf",
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/a11y-base": "24.2.0-alpha4",
50
- "@vaadin/checkbox": "24.2.0-alpha4",
51
- "@vaadin/component-base": "24.2.0-alpha4",
52
- "@vaadin/lit-renderer": "24.2.0-alpha4",
53
- "@vaadin/text-field": "24.2.0-alpha4",
54
- "@vaadin/vaadin-lumo-styles": "24.2.0-alpha4",
55
- "@vaadin/vaadin-material-styles": "24.2.0-alpha4",
56
- "@vaadin/vaadin-themable-mixin": "24.2.0-alpha4"
49
+ "@vaadin/a11y-base": "24.2.0-dev.538d07bdf",
50
+ "@vaadin/checkbox": "24.2.0-dev.538d07bdf",
51
+ "@vaadin/component-base": "24.2.0-dev.538d07bdf",
52
+ "@vaadin/lit-renderer": "24.2.0-dev.538d07bdf",
53
+ "@vaadin/text-field": "24.2.0-dev.538d07bdf",
54
+ "@vaadin/vaadin-lumo-styles": "24.2.0-dev.538d07bdf",
55
+ "@vaadin/vaadin-material-styles": "24.2.0-dev.538d07bdf",
56
+ "@vaadin/vaadin-themable-mixin": "24.2.0-dev.538d07bdf"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@esm-bundle/chai": "^4.3.4",
60
- "@vaadin/testing-helpers": "^0.4.2",
60
+ "@vaadin/testing-helpers": "^0.4.3",
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": "aaf7c5ebfea62628210eead4229be1718ac6b129"
68
+ "gitHead": "86c2fd5f37cf1240af98f7c7d752518c8d701db2"
69
69
  }
@@ -4,9 +4,8 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  /* eslint-disable max-classes-per-file */
7
- import type { TemplateResult } from 'lit';
8
7
  import type { DirectiveResult } from 'lit/directive';
9
- import type { LitRenderer } from '@vaadin/lit-renderer';
8
+ import type { LitRenderer, LitRendererResult } from '@vaadin/lit-renderer';
10
9
  import { LitRendererDirective } from '@vaadin/lit-renderer';
11
10
  import type { GridItemModel } from '../vaadin-grid.js';
12
11
  import type { GridColumn } from '../vaadin-grid-column.js';
@@ -15,10 +14,10 @@ export type GridColumnBodyLitRenderer<TItem> = (
15
14
  item: TItem,
16
15
  model: GridItemModel<TItem>,
17
16
  column: GridColumn,
18
- ) => TemplateResult;
17
+ ) => LitRendererResult;
19
18
 
20
- export type GridColumnHeaderLitRenderer = (column: GridColumn) => TemplateResult;
21
- export type GridColumnFooterLitRenderer = (column: GridColumn) => TemplateResult;
19
+ export type GridColumnHeaderLitRenderer = (column: GridColumn) => LitRendererResult;
20
+ export type GridColumnFooterLitRenderer = (column: GridColumn) => LitRendererResult;
22
21
 
23
22
  declare abstract class AbstractGridColumnRendererDirective<R extends LitRenderer> extends LitRendererDirective<
24
23
  GridColumn,
@@ -3,12 +3,16 @@
3
3
  * Copyright (c) 2017 - 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 type { TemplateResult } from 'lit';
7
6
  import type { DirectiveResult } from 'lit/directive';
7
+ import type { LitRendererResult } from '@vaadin/lit-renderer';
8
8
  import { LitRendererDirective } from '@vaadin/lit-renderer';
9
9
  import type { Grid, GridItemModel } from '../vaadin-grid.js';
10
10
 
11
- export type GridRowDetailsLitRenderer<TItem> = (item: TItem, model: GridItemModel<TItem>, grid: Grid) => TemplateResult;
11
+ export type GridRowDetailsLitRenderer<TItem> = (
12
+ item: TItem,
13
+ model: GridItemModel<TItem>,
14
+ grid: Grid,
15
+ ) => LitRendererResult;
12
16
 
13
17
  export declare class GridRowDetailsRendererDirective<TItem> extends LitRendererDirective<
14
18
  Grid,
@@ -43,6 +43,17 @@ export declare class ColumnBaseMixinClass<TItem> {
43
43
  */
44
44
  frozenToEnd: boolean;
45
45
 
46
+ /**
47
+ * When true, the cells for this column will be rendered with the `role` attribute
48
+ * set as `rowheader`, instead of the `gridcell` role value used by default.
49
+ *
50
+ * When a column is set as row header, its cells will be announced by screen readers
51
+ * while navigating to help user identify the current row as uniquely as possible.
52
+ *
53
+ * @attr {boolean} row-header
54
+ */
55
+ rowHeader: boolean;
56
+
46
57
  /**
47
58
  * When set to true, the cells for this column are hidden.
48
59
  */
@@ -61,6 +61,21 @@ export const ColumnBaseMixin = (superClass) =>
61
61
  value: false,
62
62
  },
63
63
 
64
+ /**
65
+ * When true, the cells for this column will be rendered with the `role` attribute
66
+ * set as `rowheader`, instead of the `gridcell` role value used by default.
67
+ *
68
+ * When a column is set as row header, its cells will be announced by screen readers
69
+ * while navigating to help user identify the current row as uniquely as possible.
70
+ *
71
+ * @attr {boolean} row-header
72
+ * @type {boolean}
73
+ */
74
+ rowHeader: {
75
+ type: Boolean,
76
+ value: false,
77
+ },
78
+
64
79
  /**
65
80
  * When set to true, the cells for this column are hidden.
66
81
  */
@@ -222,6 +237,7 @@ export const ColumnBaseMixin = (superClass) =>
222
237
  '_resizableChanged(resizable, _headerCell)',
223
238
  '_reorderStatusChanged(_reorderStatus, _headerCell, _footerCell, _cells.*)',
224
239
  '_hiddenChanged(hidden, _headerCell, _footerCell, _cells.*)',
240
+ '_rowHeaderChanged(rowHeader, _cells.*)',
225
241
  ];
226
242
  }
227
243
 
@@ -407,6 +423,17 @@ export const ColumnBaseMixin = (superClass) =>
407
423
  }
408
424
  }
409
425
 
426
+ /** @private */
427
+ _rowHeaderChanged(rowHeader, cells) {
428
+ if (!cells.value) {
429
+ return;
430
+ }
431
+
432
+ cells.value.forEach((cell) => {
433
+ cell.setAttribute('role', rowHeader ? 'rowheader' : 'gridcell');
434
+ });
435
+ }
436
+
410
437
  /**
411
438
  * @param {string} path
412
439
  * @return {string}
@@ -33,31 +33,6 @@ export type GridDataProvider<TItem> = (
33
33
  callback: GridDataProviderCallback<TItem>,
34
34
  ) => void;
35
35
 
36
- export declare class ItemCache<TItem> {
37
- grid: HTMLElement;
38
- parentCache: ItemCache<TItem> | undefined;
39
- parentItem: TItem | undefined;
40
- itemCaches: object | null;
41
- items: object | null;
42
- effectiveSize: number;
43
- size: number;
44
- pendingRequests: object | null;
45
-
46
- constructor(grid: HTMLElement, parentCache: ItemCache<TItem> | undefined, parentItem: TItem | undefined);
47
-
48
- isLoading(): boolean;
49
-
50
- getItemForIndex(index: number): TItem | undefined;
51
-
52
- updateSize(): void;
53
-
54
- ensureSubCacheForScaledIndex(scaledIndex: number): void;
55
-
56
- getCacheAndIndex(index: number): { cache: ItemCache<TItem>; scaledIndex: number };
57
-
58
- getFlatIndex(scaledIndex: number): number;
59
- }
60
-
61
36
  export declare function DataProviderMixin<TItem, T extends Constructor<HTMLElement>>(
62
37
  base: T,
63
38
  ): Constructor<DataProviderMixinClass<TItem>> & T;
@@ -4,115 +4,10 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { timeOut } from '@vaadin/component-base/src/async.js';
7
+ import { DataProviderController } from '@vaadin/component-base/src/data-provider-controller.js';
7
8
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
8
9
  import { getBodyRowCells, updateCellsPart, updateState } from './vaadin-grid-helpers.js';
9
10
 
10
- /**
11
- * @private
12
- */
13
- export const ItemCache = class ItemCache {
14
- /**
15
- * @param {!HTMLElement} grid
16
- * @param {!ItemCache | undefined} parentCache
17
- * @param {!GridItem | undefined} parentItem
18
- */
19
- constructor(grid, parentCache, parentItem) {
20
- /** @type {!HTMLElement} */
21
- this.grid = grid;
22
- /** @type {!ItemCache | undefined} */
23
- this.parentCache = parentCache;
24
- /** @type {!GridItem | undefined} */
25
- this.parentItem = parentItem;
26
- /** @type {object} */
27
- this.itemCaches = {};
28
- /** @type {object[]} */
29
- this.items = [];
30
- /** @type {number} */
31
- this.effectiveSize = 0;
32
- /** @type {number} */
33
- this.size = 0;
34
- /** @type {object} */
35
- this.pendingRequests = {};
36
- }
37
-
38
- /**
39
- * @return {boolean}
40
- */
41
- isLoading() {
42
- return Boolean(
43
- Object.keys(this.pendingRequests).length ||
44
- Object.keys(this.itemCaches).filter((index) => {
45
- return this.itemCaches[index].isLoading();
46
- })[0],
47
- );
48
- }
49
-
50
- /**
51
- * @param {number} index
52
- * @return {!GridItem | undefined}
53
- */
54
- getItemForIndex(index) {
55
- const { cache, scaledIndex } = this.getCacheAndIndex(index);
56
- return cache.items[scaledIndex];
57
- }
58
-
59
- updateSize() {
60
- this.effectiveSize =
61
- !this.parentItem || this.grid._isExpanded(this.parentItem)
62
- ? this.size +
63
- Object.keys(this.itemCaches).reduce((prev, curr) => {
64
- const subCache = this.itemCaches[curr];
65
- subCache.updateSize();
66
- return prev + subCache.effectiveSize;
67
- }, 0)
68
- : 0;
69
- }
70
-
71
- /**
72
- * @param {number} scaledIndex
73
- */
74
- ensureSubCacheForScaledIndex(scaledIndex) {
75
- if (!this.itemCaches[scaledIndex]) {
76
- const subCache = new ItemCache(this.grid, this, this.items[scaledIndex]);
77
- this.itemCaches[scaledIndex] = subCache;
78
- this.grid._loadPage(0, subCache);
79
- }
80
- }
81
-
82
- /**
83
- * @param {number} index
84
- * @return {{cache: !ItemCache, scaledIndex: number}}
85
- */
86
- getCacheAndIndex(index) {
87
- let thisLevelIndex = index;
88
- for (const [index, subCache] of Object.entries(this.itemCaches)) {
89
- const numberIndex = Number(index);
90
- if (thisLevelIndex <= numberIndex) {
91
- return { cache: this, scaledIndex: thisLevelIndex };
92
- } else if (thisLevelIndex <= numberIndex + subCache.effectiveSize) {
93
- return subCache.getCacheAndIndex(thisLevelIndex - numberIndex - 1);
94
- }
95
- thisLevelIndex -= subCache.effectiveSize;
96
- }
97
- return { cache: this, scaledIndex: thisLevelIndex };
98
- }
99
-
100
- /**
101
- * Gets the scaled index as flattened index on this cache level.
102
- * In practice, this means that the effective size of any expanded
103
- * subcaches preceding the index are added to the value.
104
- * @param {number} scaledIndex
105
- * @return {number} The flat index on this cache level.
106
- */
107
- getFlatIndex(scaledIndex) {
108
- const clampedIndex = Math.max(0, Math.min(this.size - 1, scaledIndex));
109
-
110
- return Object.entries(this.itemCaches).reduce((prev, [index, subCache]) => {
111
- return clampedIndex > Number(index) ? prev + subCache.effectiveSize : prev;
112
- }, clampedIndex);
113
- }
114
- };
115
-
116
11
  /**
117
12
  * @polymerMixin
118
13
  */
@@ -180,18 +75,6 @@ export const DataProviderMixin = (superClass) =>
180
75
  reflectToAttribute: true,
181
76
  },
182
77
 
183
- /**
184
- * @type {!ItemCache}
185
- * @protected
186
- */
187
- _cache: {
188
- type: Object,
189
- value() {
190
- const cache = new ItemCache(this);
191
- return cache;
192
- },
193
- },
194
-
195
78
  /**
196
79
  * @protected
197
80
  */
@@ -243,12 +126,32 @@ export const DataProviderMixin = (superClass) =>
243
126
  return ['_sizeChanged(size)', '_expandedItemsChanged(expandedItems.*)'];
244
127
  }
245
128
 
129
+ constructor() {
130
+ super();
131
+
132
+ /** @type {DataProviderController} */
133
+ this._dataProviderController = new DataProviderController(this, {
134
+ size: this.size,
135
+ pageSize: this.pageSize,
136
+ isExpanded: this._isExpanded.bind(this),
137
+ dataProvider: this.dataProvider ? this.dataProvider.bind(this) : null,
138
+ dataProviderParams: () => {
139
+ return {
140
+ sortOrders: this._mapSorters(),
141
+ filters: this._mapFilters(),
142
+ };
143
+ },
144
+ });
145
+
146
+ this._dataProviderController.addEventListener('page-requested', this._onDataProviderPageRequested.bind(this));
147
+ this._dataProviderController.addEventListener('page-received', this._onDataProviderPageReceived.bind(this));
148
+ this._dataProviderController.addEventListener('page-loaded', this._onDataProviderPageLoaded.bind(this));
149
+ }
150
+
246
151
  /** @private */
247
152
  _sizeChanged(size) {
248
- const delta = size - this._cache.size;
249
- this._cache.size += delta;
250
- this._cache.effectiveSize += delta;
251
- this._effectiveSize = this._cache.effectiveSize;
153
+ this._dataProviderController.setSize(size);
154
+ this._effectiveSize = this._dataProviderController.effectiveSize;
252
155
  }
253
156
 
254
157
  /** @private */
@@ -271,17 +174,17 @@ export const DataProviderMixin = (superClass) =>
271
174
  }
272
175
 
273
176
  el.index = index;
274
- const { cache, scaledIndex } = this._cache.getCacheAndIndex(index);
275
- const item = cache.items[scaledIndex];
177
+
178
+ const { item } = this._dataProviderController.getFlatIndexInfo(index);
276
179
  if (item) {
277
180
  this.__updateLoading(el, false);
278
181
  this._updateItem(el, item);
279
182
  if (this._isExpanded(item)) {
280
- cache.ensureSubCacheForScaledIndex(scaledIndex);
183
+ this._dataProviderController.ensureFlatIndexChildrenLoaded(index);
281
184
  }
282
185
  } else {
283
186
  this.__updateLoading(el, true);
284
- this._loadPage(this._getPageForIndex(scaledIndex), cache);
187
+ this._dataProviderController.ensureFlatIndexLoaded(index);
285
188
  }
286
189
  }
287
190
 
@@ -321,8 +224,8 @@ export const DataProviderMixin = (superClass) =>
321
224
 
322
225
  /** @private */
323
226
  _expandedItemsChanged() {
324
- this._cache.updateSize();
325
- this._effectiveSize = this._cache.effectiveSize;
227
+ this._dataProviderController.recalculateEffectiveSize();
228
+ this._effectiveSize = this._dataProviderController.effectiveSize;
326
229
  this.__updateVisibleRows();
327
230
  }
328
231
 
@@ -362,121 +265,68 @@ export const DataProviderMixin = (superClass) =>
362
265
  * @return {number}
363
266
  * @protected
364
267
  */
365
- _getIndexLevel(index) {
366
- let { cache } = this._cache.getCacheAndIndex(index);
367
- let level = 0;
368
- while (cache.parentCache) {
369
- cache = cache.parentCache;
370
- level += 1;
371
- }
268
+ _getIndexLevel(index = 0) {
269
+ const { level } = this._dataProviderController.getFlatIndexInfo(index);
372
270
  return level;
373
271
  }
374
272
 
375
- /**
376
- * @param {number} page
377
- * @param {ItemCache} cache
378
- * @protected
379
- */
380
- _loadPage(page, cache) {
381
- // Make sure same page isn't requested multiple times.
382
- if (!cache.pendingRequests[page] && this.dataProvider) {
383
- this._setLoading(true);
384
- cache.pendingRequests[page] = true;
385
- const params = {
386
- page,
387
- pageSize: this.pageSize,
388
- sortOrders: this._mapSorters(),
389
- filters: this._mapFilters(),
390
- parentItem: cache.parentItem,
391
- };
392
-
393
- this.dataProvider(params, (items, size) => {
394
- if (size !== undefined) {
395
- cache.size = size;
396
- } else if (params.parentItem) {
397
- cache.size = items.length;
398
- }
273
+ /** @protected */
274
+ _onDataProviderPageRequested() {
275
+ this._setLoading(true);
276
+ }
399
277
 
400
- // Populate the cache with new items
401
- items.forEach((item, itemsIndex) => {
402
- const itemIndex = page * this.pageSize + itemsIndex;
403
- cache.items[itemIndex] = item;
404
- });
405
-
406
- // With the new items added, update the cache size and the grid's effective size
407
- this._cache.updateSize();
408
- this._effectiveSize = this._cache.effectiveSize;
409
-
410
- // After updating the cache, check if some of the expanded items should have sub-caches loaded
411
- this._getRenderedRows().forEach((row) => {
412
- const { cache, scaledIndex } = this._cache.getCacheAndIndex(row.index);
413
- const item = cache.items[scaledIndex];
414
- if (item && this._isExpanded(item)) {
415
- cache.ensureSubCacheForScaledIndex(scaledIndex);
416
- }
417
- });
418
-
419
- this._hasData = true;
420
-
421
- // Remove the pending request
422
- delete cache.pendingRequests[page];
423
-
424
- // Schedule a debouncer to update the visible rows
425
- this._debouncerApplyCachedData = Debouncer.debounce(this._debouncerApplyCachedData, timeOut.after(0), () => {
426
- this._setLoading(false);
427
-
428
- this._getRenderedRows().forEach((row) => {
429
- const cachedItem = this._cache.getItemForIndex(row.index);
430
- if (cachedItem) {
431
- this._getItem(row.index, row);
432
- }
433
- });
434
-
435
- this.__scrollToPendingIndexes();
436
- });
437
-
438
- // If the grid is not loading anything, flush the debouncer immediately
439
- if (!this._cache.isLoading()) {
440
- this._debouncerApplyCachedData.flush();
441
- }
278
+ /** @protected */
279
+ _onDataProviderPageReceived() {
280
+ // With the new items added, update the cache size and the grid's effective size
281
+ this._effectiveSize = this._dataProviderController.effectiveSize;
442
282
 
443
- // Notify that new data has been received
444
- this._onDataProviderPageLoaded();
445
- });
446
- }
283
+ // After updating the cache, check if some of the expanded items should have sub-caches loaded
284
+ this._getRenderedRows().forEach((row) => {
285
+ this._dataProviderController.ensureFlatIndexChildrenLoaded(row.index);
286
+ });
287
+
288
+ this._hasData = true;
447
289
  }
448
290
 
449
291
  /** @protected */
450
- _onDataProviderPageLoaded() {}
292
+ _onDataProviderPageLoaded() {
293
+ // Schedule a debouncer to update the visible rows
294
+ this._debouncerApplyCachedData = Debouncer.debounce(this._debouncerApplyCachedData, timeOut.after(0), () => {
295
+ this._setLoading(false);
296
+
297
+ this._getRenderedRows().forEach((row) => {
298
+ const { item } = this._dataProviderController.getFlatIndexInfo(row.index);
299
+ if (item) {
300
+ this._getItem(row.index, row);
301
+ }
302
+ });
451
303
 
452
- /**
453
- * @param {number} index
454
- * @return {number}
455
- * @private
456
- */
457
- _getPageForIndex(index) {
458
- return Math.floor(index / this.pageSize);
304
+ this.__scrollToPendingIndexes();
305
+ });
306
+
307
+ // If the grid is not loading anything, flush the debouncer immediately
308
+ if (!this._dataProviderController.isLoading) {
309
+ this._debouncerApplyCachedData.flush();
310
+ }
459
311
  }
460
312
 
461
313
  /**
462
314
  * Clears the cached pages and reloads data from dataprovider when needed.
463
315
  */
464
316
  clearCache() {
465
- this._cache = new ItemCache(this);
466
- this._cache.size = this.size || 0;
467
- this._cache.updateSize();
317
+ this._dataProviderController.clearCache();
468
318
  this._hasData = false;
469
319
  this.__updateVisibleRows();
470
-
471
- if (!this._effectiveSize) {
472
- this._loadPage(0, this._cache);
473
- }
320
+ this._ensureFirstPageLoaded();
474
321
  }
475
322
 
476
323
  /** @private */
477
324
  _pageSizeChanged(pageSize, oldPageSize) {
478
325
  if (oldPageSize !== undefined && pageSize !== oldPageSize) {
479
- this.clearCache();
326
+ this._dataProviderController.setPageSize(pageSize);
327
+ this._hasData = false;
328
+ this.__updateVisibleRows();
329
+ this._ensureFirstPageLoaded();
480
330
  }
481
331
  }
482
332
 
@@ -494,8 +344,11 @@ export const DataProviderMixin = (superClass) =>
494
344
 
495
345
  /** @private */
496
346
  _dataProviderChanged(dataProvider, oldDataProvider) {
347
+ this._dataProviderController.setDataProvider(dataProvider ? dataProvider.bind(this) : null);
348
+
497
349
  if (oldDataProvider !== undefined) {
498
- this.clearCache();
350
+ this._hasData = false;
351
+ this.__updateVisibleRows();
499
352
  }
500
353
 
501
354
  this._ensureFirstPageLoaded();
@@ -512,7 +365,7 @@ export const DataProviderMixin = (superClass) =>
512
365
  if (!this._hasData) {
513
366
  // Load data before adding rows to make sure they have content when
514
367
  // rendered for the first time.
515
- this._loadPage(0, this._cache);
368
+ this._dataProviderController.ensureFirstPageLoaded();
516
369
  }
517
370
  }
518
371
 
@@ -562,39 +415,15 @@ export const DataProviderMixin = (superClass) =>
562
415
  // ending up in a loading state. Try scrolling to the index until the target
563
416
  // index stabilizes.
564
417
  let targetIndex;
565
- while (targetIndex !== (targetIndex = this.__getGlobalFlatIndex(indexes))) {
418
+ while (targetIndex !== (targetIndex = this._dataProviderController.getFlatIndexByPath(indexes))) {
566
419
  this._scrollToFlatIndex(targetIndex);
567
420
  }
568
421
 
569
- if (this._cache.isLoading() || !this.clientHeight) {
422
+ if (this._dataProviderController.isLoading || !this.clientHeight) {
570
423
  this.__pendingScrollToIndexes = indexes;
571
424
  }
572
425
  }
573
426
 
574
- /**
575
- * Recursively returns the globally flat index of the item the given indexes point to.
576
- * Each index in the array points to a sub-item of the previous index.
577
- * Using `Infinity` as an index will point to the last item on the level.
578
- *
579
- * @param {!Array<number>} indexes
580
- * @param {!ItemCache} cache
581
- * @param {number} flatIndex
582
- * @return {number}
583
- * @private
584
- */
585
- __getGlobalFlatIndex([levelIndex, ...subIndexes], cache = this._cache, flatIndex = 0) {
586
- if (levelIndex === Infinity) {
587
- // Treat Infinity as the last index on the level
588
- levelIndex = cache.size - 1;
589
- }
590
- const flatIndexOnLevel = cache.getFlatIndex(levelIndex);
591
- const subCache = cache.itemCaches[levelIndex];
592
- if (subCache && subCache.effectiveSize && subIndexes.length) {
593
- return this.__getGlobalFlatIndex(subIndexes, subCache, flatIndex + flatIndexOnLevel + 1);
594
- }
595
- return flatIndex + flatIndexOnLevel;
596
- }
597
-
598
427
  /** @private */
599
428
  __scrollToPendingIndexes() {
600
429
  if (this.__pendingScrollToIndexes && this.$.items.children.length) {
@@ -475,7 +475,7 @@ export const KeyboardNavigationMixin = (superClass) =>
475
475
  // Row details navigation logic
476
476
  if (activeRowGroup === this.$.items) {
477
477
  const item = activeRow._item;
478
- const dstItem = this._cache.getItemForIndex(dstRowIndex);
478
+ const { item: dstItem } = this._dataProviderController.getFlatIndexInfo(dstRowIndex);
479
479
  // Should we navigate to row details?
480
480
  if (isRowDetails) {
481
481
  dstIsRowDetails = dy === 0;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import type { Constructor } from '@open-wc/dedupe-mixin';
7
+
8
+ export declare function GridSelectionColumnBaseMixin<TItem, T extends Constructor<HTMLElement>>(
9
+ base: T,
10
+ ): Constructor<GridSelectionColumnBaseMixinClass<TItem>> & T;
11
+
12
+ /**
13
+ * A mixin that provides basic functionality for the
14
+ * `<vaadin-grid-selection-column>`. This includes properties, cell rendering,
15
+ * and overridable methods for handling changes to the selection state.
16
+ *
17
+ * **NOTE**: This mixin is re-used by the Flow component, and as such must not
18
+ * implement any selection state updates for the column element or the grid.
19
+ * Web component-specific selection state updates must be implemented in the
20
+ * `<vaadin-grid-selection-column>` itself, by overriding the protected methods
21
+ * provided by this mixin.
22
+ *
23
+ * @polymerMixin
24
+ */
25
+ export declare class GridSelectionColumnBaseMixinClass<TItem> {
26
+ /**
27
+ * When true, all the items are selected.
28
+ * @attr {boolean} select-all
29
+ */
30
+ selectAll: boolean;
31
+
32
+ /**
33
+ * When true, the active gets automatically selected.
34
+ * @attr {boolean} auto-select
35
+ */
36
+ autoSelect: boolean;
37
+
38
+ /**
39
+ * Override to handle the user selecting all items.
40
+ */
41
+ protected _selectAll(): void;
42
+
43
+ /**
44
+ * Override to handle the user deselecting all items.
45
+ */
46
+ protected _deselectAll(): void;
47
+
48
+ /**
49
+ * Override to handle the user selecting an item.
50
+ */
51
+ protected _selectItem(item: TItem): void;
52
+
53
+ /**
54
+ * Override to handle the user deselecting an item.
55
+ */
56
+ protected _deselectItem(item: TItem): void;
57
+ }