@vaadin/grid 22.0.0-alpha7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +79 -0
  3. package/all-imports.js +1 -0
  4. package/package.json +58 -0
  5. package/src/all-imports.js +14 -0
  6. package/src/array-data-provider.js +145 -0
  7. package/src/interfaces.d.ts +75 -0
  8. package/src/vaadin-grid-a11y-mixin.js +158 -0
  9. package/src/vaadin-grid-active-item-mixin.d.ts +19 -0
  10. package/src/vaadin-grid-active-item-mixin.js +117 -0
  11. package/src/vaadin-grid-array-data-provider-mixin.d.ts +16 -0
  12. package/src/vaadin-grid-array-data-provider-mixin.js +75 -0
  13. package/src/vaadin-grid-column-group.d.ts +54 -0
  14. package/src/vaadin-grid-column-group.js +320 -0
  15. package/src/vaadin-grid-column-reordering-mixin.d.ts +19 -0
  16. package/src/vaadin-grid-column-reordering-mixin.js +387 -0
  17. package/src/vaadin-grid-column-resizing-mixin.js +111 -0
  18. package/src/vaadin-grid-column.d.ts +133 -0
  19. package/src/vaadin-grid-column.js +745 -0
  20. package/src/vaadin-grid-data-provider-mixin.d.ts +108 -0
  21. package/src/vaadin-grid-data-provider-mixin.js +520 -0
  22. package/src/vaadin-grid-drag-and-drop-mixin.d.ts +69 -0
  23. package/src/vaadin-grid-drag-and-drop-mixin.js +433 -0
  24. package/src/vaadin-grid-dynamic-columns-mixin.js +180 -0
  25. package/src/vaadin-grid-event-context-mixin.d.ts +33 -0
  26. package/src/vaadin-grid-event-context-mixin.js +57 -0
  27. package/src/vaadin-grid-filter-column.d.ts +35 -0
  28. package/src/vaadin-grid-filter-column.js +120 -0
  29. package/src/vaadin-grid-filter-mixin.js +76 -0
  30. package/src/vaadin-grid-filter.d.ts +67 -0
  31. package/src/vaadin-grid-filter.js +125 -0
  32. package/src/vaadin-grid-helpers.js +23 -0
  33. package/src/vaadin-grid-keyboard-navigation-mixin.js +891 -0
  34. package/src/vaadin-grid-row-details-mixin.d.ts +44 -0
  35. package/src/vaadin-grid-row-details-mixin.js +200 -0
  36. package/src/vaadin-grid-scroll-mixin.d.ts +18 -0
  37. package/src/vaadin-grid-scroll-mixin.js +202 -0
  38. package/src/vaadin-grid-selection-column.d.ts +71 -0
  39. package/src/vaadin-grid-selection-column.js +285 -0
  40. package/src/vaadin-grid-selection-mixin.d.ts +30 -0
  41. package/src/vaadin-grid-selection-mixin.js +93 -0
  42. package/src/vaadin-grid-sort-column.d.ts +63 -0
  43. package/src/vaadin-grid-sort-column.js +118 -0
  44. package/src/vaadin-grid-sort-mixin.d.ts +15 -0
  45. package/src/vaadin-grid-sort-mixin.js +139 -0
  46. package/src/vaadin-grid-sorter.d.ts +94 -0
  47. package/src/vaadin-grid-sorter.js +230 -0
  48. package/src/vaadin-grid-styles.js +297 -0
  49. package/src/vaadin-grid-styling-mixin.d.ts +37 -0
  50. package/src/vaadin-grid-styling-mixin.js +71 -0
  51. package/src/vaadin-grid-tree-column.d.ts +36 -0
  52. package/src/vaadin-grid-tree-column.js +119 -0
  53. package/src/vaadin-grid-tree-toggle.d.ts +104 -0
  54. package/src/vaadin-grid-tree-toggle.js +205 -0
  55. package/src/vaadin-grid.d.ts +397 -0
  56. package/src/vaadin-grid.js +1004 -0
  57. package/theme/lumo/all-imports.js +11 -0
  58. package/theme/lumo/vaadin-grid-column-group.js +1 -0
  59. package/theme/lumo/vaadin-grid-column.js +1 -0
  60. package/theme/lumo/vaadin-grid-filter-column.js +2 -0
  61. package/theme/lumo/vaadin-grid-filter.js +2 -0
  62. package/theme/lumo/vaadin-grid-selection-column.js +2 -0
  63. package/theme/lumo/vaadin-grid-sort-column.js +2 -0
  64. package/theme/lumo/vaadin-grid-sorter-styles.js +53 -0
  65. package/theme/lumo/vaadin-grid-sorter.js +2 -0
  66. package/theme/lumo/vaadin-grid-styles.js +378 -0
  67. package/theme/lumo/vaadin-grid-tree-column.js +2 -0
  68. package/theme/lumo/vaadin-grid-tree-toggle-styles.js +112 -0
  69. package/theme/lumo/vaadin-grid-tree-toggle.js +2 -0
  70. package/theme/lumo/vaadin-grid.js +9 -0
  71. package/theme/material/all-imports.js +11 -0
  72. package/theme/material/vaadin-grid-column-group.js +1 -0
  73. package/theme/material/vaadin-grid-column.js +1 -0
  74. package/theme/material/vaadin-grid-filter-column.js +2 -0
  75. package/theme/material/vaadin-grid-filter.js +2 -0
  76. package/theme/material/vaadin-grid-selection-column.js +2 -0
  77. package/theme/material/vaadin-grid-sort-column.js +2 -0
  78. package/theme/material/vaadin-grid-sorter-styles.js +72 -0
  79. package/theme/material/vaadin-grid-sorter.js +2 -0
  80. package/theme/material/vaadin-grid-styles.js +252 -0
  81. package/theme/material/vaadin-grid-tree-column.js +2 -0
  82. package/theme/material/vaadin-grid-tree-toggle-styles.js +42 -0
  83. package/theme/material/vaadin-grid-tree-toggle.js +2 -0
  84. package/theme/material/vaadin-grid.js +2 -0
  85. package/vaadin-grid-column-group.d.ts +1 -0
  86. package/vaadin-grid-column-group.js +3 -0
  87. package/vaadin-grid-column.d.ts +1 -0
  88. package/vaadin-grid-column.js +3 -0
  89. package/vaadin-grid-filter-column.d.ts +1 -0
  90. package/vaadin-grid-filter-column.js +3 -0
  91. package/vaadin-grid-filter.d.ts +1 -0
  92. package/vaadin-grid-filter.js +3 -0
  93. package/vaadin-grid-selection-column.d.ts +1 -0
  94. package/vaadin-grid-selection-column.js +3 -0
  95. package/vaadin-grid-sort-column.d.ts +1 -0
  96. package/vaadin-grid-sort-column.js +3 -0
  97. package/vaadin-grid-sorter.d.ts +1 -0
  98. package/vaadin-grid-sorter.js +3 -0
  99. package/vaadin-grid-tree-column.d.ts +1 -0
  100. package/vaadin-grid-tree-column.js +3 -0
  101. package/vaadin-grid-tree-toggle.d.ts +1 -0
  102. package/vaadin-grid-tree-toggle.js +3 -0
  103. package/vaadin-grid.d.ts +3 -0
  104. package/vaadin-grid.js +4 -0
@@ -0,0 +1,108 @@
1
+ import { GridDataProvider } from './interfaces';
2
+
3
+ declare class ItemCache<TItem> {
4
+ grid: HTMLElement;
5
+ parentCache: ItemCache<TItem> | undefined;
6
+ parentItem: TItem | undefined;
7
+ itemCaches: object | null;
8
+ items: object | null;
9
+ effectiveSize: number;
10
+ size: number;
11
+ pendingRequests: object | null;
12
+
13
+ constructor(grid: HTMLElement, parentCache: ItemCache<TItem> | undefined, parentItem: TItem | undefined);
14
+
15
+ isLoading(): boolean;
16
+
17
+ getItemForIndex(index: number): TItem | undefined;
18
+
19
+ updateSize(): void;
20
+
21
+ ensureSubCacheForScaledIndex(scaledIndex: number): void;
22
+
23
+ getCacheAndIndex(index: number): { cache: ItemCache<TItem>; scaledIndex: number };
24
+ }
25
+
26
+ declare function DataProviderMixin<TItem, T extends new (...args: any[]) => {}>(
27
+ base: T
28
+ ): T & DataProviderMixinConstructor<TItem>;
29
+
30
+ interface DataProviderMixinConstructor<TItem> {
31
+ new (...args: any[]): DataProviderMixin<TItem>;
32
+ }
33
+
34
+ interface DataProviderMixin<TItem> {
35
+ /**
36
+ * Number of items fetched at a time from the dataprovider.
37
+ * @attr {number} page-size
38
+ */
39
+ pageSize: number;
40
+
41
+ /**
42
+ * The number of root-level items in the grid.
43
+ * @attr {number} size
44
+ */
45
+ size: number;
46
+
47
+ /**
48
+ * Function that provides items lazily. Receives arguments `params`, `callback`
49
+ *
50
+ * `params.page` Requested page index
51
+ *
52
+ * `params.pageSize` Current page size
53
+ *
54
+ * `params.filters` Currently applied filters
55
+ *
56
+ * `params.sortOrders` Currently applied sorting orders
57
+ *
58
+ * `params.parentItem` When tree is used, and sublevel items
59
+ * are requested, reference to parent item of the requested sublevel.
60
+ * Otherwise `undefined`.
61
+ *
62
+ * `callback(items, size)` Callback function with arguments:
63
+ * - `items` Current page of items
64
+ * - `size` Total number of items. When tree sublevel items
65
+ * are requested, total number of items in the requested sublevel.
66
+ * Optional when tree is not used, required for tree.
67
+ */
68
+ dataProvider: GridDataProvider<TItem> | null | undefined;
69
+
70
+ /**
71
+ * `true` while data is being requested from the data provider.
72
+ */
73
+ readonly loading: boolean | null | undefined;
74
+
75
+ /**
76
+ * Path to an item sub-property that identifies the item.
77
+ * @attr {string} item-id-path
78
+ */
79
+ itemIdPath: string | null | undefined;
80
+
81
+ /**
82
+ * An array that contains the expanded items.
83
+ */
84
+ expandedItems: TItem[];
85
+
86
+ /**
87
+ * Returns a value that identifies the item. Uses `itemIdPath` if available.
88
+ * Can be customized by overriding.
89
+ */
90
+ getItemId(item: TItem): TItem | unknown;
91
+
92
+ /**
93
+ * Expands the given item tree.
94
+ */
95
+ expandItem(item: TItem): void;
96
+
97
+ /**
98
+ * Collapses the given item tree.
99
+ */
100
+ collapseItem(item: TItem): void;
101
+
102
+ /**
103
+ * Clears the cached pages and reloads data from dataprovider when needed.
104
+ */
105
+ clearCache(): void;
106
+ }
107
+
108
+ export { DataProviderMixin, DataProviderMixinConstructor, ItemCache };
@@ -0,0 +1,520 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { Debouncer } from '@vaadin/component-base/src/debounce.js';
7
+ import { timeOut } from '@vaadin/component-base/src/async.js';
8
+
9
+ /**
10
+ * @private
11
+ */
12
+ export const ItemCache = class ItemCache {
13
+ /**
14
+ * @param {!HTMLElement} grid
15
+ * @param {!ItemCache | undefined} parentCache
16
+ * @param {!GridItem | undefined} parentItem
17
+ */
18
+ constructor(grid, parentCache, parentItem) {
19
+ /** @type {!HTMLElement} */
20
+ this.grid = grid;
21
+ /** @type {!ItemCache | undefined} */
22
+ this.parentCache = parentCache;
23
+ /** @type {!GridItem | undefined} */
24
+ this.parentItem = parentItem;
25
+ /** @type {object} */
26
+ this.itemCaches = {};
27
+ /** @type {object} */
28
+ this.items = {};
29
+ /** @type {number} */
30
+ this.effectiveSize = 0;
31
+ /** @type {number} */
32
+ this.size = 0;
33
+ /** @type {object} */
34
+ this.pendingRequests = {};
35
+ }
36
+
37
+ /**
38
+ * @return {boolean}
39
+ */
40
+ isLoading() {
41
+ return Boolean(
42
+ Object.keys(this.pendingRequests).length ||
43
+ Object.keys(this.itemCaches).filter((index) => {
44
+ return this.itemCaches[index].isLoading();
45
+ })[0]
46
+ );
47
+ }
48
+
49
+ /**
50
+ * @param {number} index
51
+ * @return {!GridItem | undefined}
52
+ */
53
+ getItemForIndex(index) {
54
+ const { cache, scaledIndex } = this.getCacheAndIndex(index);
55
+ return cache.items[scaledIndex];
56
+ }
57
+
58
+ updateSize() {
59
+ this.effectiveSize =
60
+ !this.parentItem || this.grid._isExpanded(this.parentItem)
61
+ ? this.size +
62
+ Object.keys(this.itemCaches).reduce((prev, curr) => {
63
+ const subCache = this.itemCaches[curr];
64
+ subCache.updateSize();
65
+ return prev + subCache.effectiveSize;
66
+ }, 0)
67
+ : 0;
68
+ }
69
+
70
+ /**
71
+ * @param {number} scaledIndex
72
+ */
73
+ ensureSubCacheForScaledIndex(scaledIndex) {
74
+ if (!this.itemCaches[scaledIndex]) {
75
+ const subCache = new ItemCache(this.grid, this, this.items[scaledIndex]);
76
+ this.itemCaches[scaledIndex] = subCache;
77
+ this.grid._loadPage(0, subCache);
78
+ }
79
+ }
80
+
81
+ /**
82
+ * @param {number} index
83
+ * @return {{cache: !ItemCache, scaledIndex: number}}
84
+ */
85
+ getCacheAndIndex(index) {
86
+ let thisLevelIndex = index;
87
+ const keys = Object.keys(this.itemCaches);
88
+ for (let i = 0; i < keys.length; i++) {
89
+ const expandedIndex = Number(keys[i]);
90
+ const subCache = this.itemCaches[expandedIndex];
91
+ if (thisLevelIndex <= expandedIndex) {
92
+ return { cache: this, scaledIndex: thisLevelIndex };
93
+ } else if (thisLevelIndex <= expandedIndex + subCache.effectiveSize) {
94
+ return subCache.getCacheAndIndex(thisLevelIndex - expandedIndex - 1);
95
+ }
96
+ thisLevelIndex -= subCache.effectiveSize;
97
+ }
98
+ return { cache: this, scaledIndex: thisLevelIndex };
99
+ }
100
+ };
101
+
102
+ /**
103
+ * @polymerMixin
104
+ */
105
+ export const DataProviderMixin = (superClass) =>
106
+ class DataProviderMixin extends superClass {
107
+ static get properties() {
108
+ return {
109
+ /**
110
+ * The number of root-level items in the grid.
111
+ * @attr {number} size
112
+ * @type {number}
113
+ */
114
+ size: {
115
+ type: Number,
116
+ notify: true
117
+ },
118
+
119
+ /**
120
+ * Number of items fetched at a time from the dataprovider.
121
+ * @attr {number} page-size
122
+ * @type {number}
123
+ */
124
+ pageSize: {
125
+ type: Number,
126
+ value: 50,
127
+ observer: '_pageSizeChanged'
128
+ },
129
+
130
+ /**
131
+ * Function that provides items lazily. Receives arguments `params`, `callback`
132
+ *
133
+ * `params.page` Requested page index
134
+ *
135
+ * `params.pageSize` Current page size
136
+ *
137
+ * `params.filters` Currently applied filters
138
+ *
139
+ * `params.sortOrders` Currently applied sorting orders
140
+ *
141
+ * `params.parentItem` When tree is used, and sublevel items
142
+ * are requested, reference to parent item of the requested sublevel.
143
+ * Otherwise `undefined`.
144
+ *
145
+ * `callback(items, size)` Callback function with arguments:
146
+ * - `items` Current page of items
147
+ * - `size` Total number of items. When tree sublevel items
148
+ * are requested, total number of items in the requested sublevel.
149
+ * Optional when tree is not used, required for tree.
150
+ *
151
+ * @type {GridDataProvider | null | undefined}
152
+ */
153
+ dataProvider: {
154
+ type: Object,
155
+ notify: true,
156
+ observer: '_dataProviderChanged'
157
+ },
158
+
159
+ /**
160
+ * `true` while data is being requested from the data provider.
161
+ */
162
+ loading: {
163
+ type: Boolean,
164
+ notify: true,
165
+ readOnly: true,
166
+ reflectToAttribute: true
167
+ },
168
+
169
+ /**
170
+ * @type {!ItemCache}
171
+ * @protected
172
+ */
173
+ _cache: {
174
+ type: Object,
175
+ value: function () {
176
+ const cache = new ItemCache(this);
177
+ return cache;
178
+ }
179
+ },
180
+
181
+ /**
182
+ * @protected
183
+ */
184
+ _hasData: {
185
+ type: Boolean,
186
+ value: false
187
+ },
188
+
189
+ /**
190
+ * Path to an item sub-property that identifies the item.
191
+ * @attr {string} item-id-path
192
+ */
193
+ itemIdPath: {
194
+ type: String,
195
+ value: null
196
+ },
197
+
198
+ /**
199
+ * An array that contains the expanded items.
200
+ * @type {!Array<!GridItem>}
201
+ */
202
+ expandedItems: {
203
+ type: Object,
204
+ notify: true,
205
+ value: () => []
206
+ },
207
+
208
+ /**
209
+ * @private
210
+ */
211
+ __expandedKeys: {
212
+ type: Object,
213
+ value: () => new Set()
214
+ }
215
+ };
216
+ }
217
+
218
+ static get observers() {
219
+ return ['_sizeChanged(size)', '_itemIdPathChanged(itemIdPath)', '_expandedItemsChanged(expandedItems.*)'];
220
+ }
221
+
222
+ /** @private */
223
+ _sizeChanged(size) {
224
+ const delta = size - this._cache.size;
225
+ this._cache.size += delta;
226
+ this._cache.effectiveSize += delta;
227
+ this._effectiveSize = this._cache.effectiveSize;
228
+ }
229
+
230
+ /**
231
+ * @param {number} index
232
+ * @param {HTMLElement} el
233
+ * @protected
234
+ */
235
+ _getItem(index, el) {
236
+ if (index >= this._effectiveSize) {
237
+ return;
238
+ }
239
+
240
+ el.index = index;
241
+ const { cache, scaledIndex } = this._cache.getCacheAndIndex(index);
242
+ const item = cache.items[scaledIndex];
243
+ if (item) {
244
+ el.toggleAttribute('loading', false);
245
+ this._updateItem(el, item);
246
+ if (this._isExpanded(item)) {
247
+ cache.ensureSubCacheForScaledIndex(scaledIndex);
248
+ }
249
+ } else {
250
+ el.toggleAttribute('loading', true);
251
+ this._loadPage(this._getPageForIndex(scaledIndex), cache);
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Returns a value that identifies the item. Uses `itemIdPath` if available.
257
+ * Can be customized by overriding.
258
+ * @param {!GridItem} item
259
+ * @return {!GridItem | !unknown}
260
+ */
261
+ getItemId(item) {
262
+ return this.itemIdPath ? this.get(this.itemIdPath, item) : item;
263
+ }
264
+
265
+ /**
266
+ * @param {!GridItem} item
267
+ * @return {boolean}
268
+ * @protected
269
+ */
270
+ _isExpanded(item) {
271
+ return this.__expandedKeys.has(this.getItemId(item));
272
+ }
273
+
274
+ /** @private */
275
+ _expandedItemsChanged() {
276
+ this.__cacheExpandedKeys();
277
+ this._cache.updateSize();
278
+ this._effectiveSize = this._cache.effectiveSize;
279
+ this.__updateVisibleRows();
280
+ }
281
+
282
+ /** @private */
283
+ _itemIdPathChanged() {
284
+ this.__cacheExpandedKeys();
285
+ }
286
+
287
+ /** @private */
288
+ __cacheExpandedKeys() {
289
+ if (this.expandedItems) {
290
+ this.__expandedKeys = new Set();
291
+ this.expandedItems.forEach((item) => {
292
+ this.__expandedKeys.add(this.getItemId(item));
293
+ });
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Expands the given item tree.
299
+ * @param {!GridItem} item
300
+ */
301
+ expandItem(item) {
302
+ if (!this._isExpanded(item)) {
303
+ this.expandedItems = [...this.expandedItems, item];
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Collapses the given item tree.
309
+ * @param {!GridItem} item
310
+ */
311
+ collapseItem(item) {
312
+ if (this._isExpanded(item)) {
313
+ this.expandedItems = this.expandedItems.filter((i) => !this._itemsEqual(i, item));
314
+ }
315
+ }
316
+
317
+ /**
318
+ * @param {number} index
319
+ * @return {number}
320
+ * @protected
321
+ */
322
+ _getIndexLevel(index) {
323
+ let { cache } = this._cache.getCacheAndIndex(index);
324
+ let level = 0;
325
+ while (cache.parentCache) {
326
+ cache = cache.parentCache;
327
+ level++;
328
+ }
329
+ return level;
330
+ }
331
+
332
+ /**
333
+ * @param {number} page
334
+ * @param {ItemCache} cache
335
+ * @protected
336
+ */
337
+ _loadPage(page, cache) {
338
+ // make sure same page isn't requested multiple times.
339
+ if (!cache.pendingRequests[page] && this.dataProvider) {
340
+ this._setLoading(true);
341
+ cache.pendingRequests[page] = true;
342
+ const params = {
343
+ page,
344
+ pageSize: this.pageSize,
345
+ sortOrders: this._mapSorters(),
346
+ filters: this._mapFilters(),
347
+ parentItem: cache.parentItem
348
+ };
349
+
350
+ this.dataProvider(params, (items, size) => {
351
+ if (size !== undefined) {
352
+ cache.size = size;
353
+ } else {
354
+ if (params.parentItem) {
355
+ cache.size = items.length;
356
+ }
357
+ }
358
+
359
+ const currentItems = Array.from(this.$.items.children).map((row) => row._item);
360
+
361
+ // Populate the cache with new items
362
+ items.forEach((item, itemsIndex) => {
363
+ const itemIndex = page * this.pageSize + itemsIndex;
364
+ cache.items[itemIndex] = item;
365
+ if (this._isExpanded(item) && currentItems.indexOf(item) > -1) {
366
+ // Force synchronous data request for expanded item sub-cache
367
+ cache.ensureSubCacheForScaledIndex(itemIndex);
368
+ }
369
+ });
370
+
371
+ this._hasData = true;
372
+
373
+ delete cache.pendingRequests[page];
374
+
375
+ this._debouncerApplyCachedData = Debouncer.debounce(this._debouncerApplyCachedData, timeOut.after(0), () => {
376
+ this._setLoading(false);
377
+ this._cache.updateSize();
378
+ this._effectiveSize = this._cache.effectiveSize;
379
+
380
+ Array.from(this.$.items.children)
381
+ .filter((row) => !row.hidden)
382
+ .forEach((row) => {
383
+ const cachedItem = this._cache.getItemForIndex(row.index);
384
+ if (cachedItem) {
385
+ this._getItem(row.index, row);
386
+ }
387
+ });
388
+
389
+ this.__scrollToPendingIndex();
390
+ });
391
+
392
+ if (!this._cache.isLoading()) {
393
+ this._debouncerApplyCachedData.flush();
394
+ }
395
+
396
+ this.__itemsReceived();
397
+ });
398
+ }
399
+ }
400
+
401
+ /**
402
+ * @param {number} index
403
+ * @return {number}
404
+ * @private
405
+ */
406
+ _getPageForIndex(index) {
407
+ return Math.floor(index / this.pageSize);
408
+ }
409
+
410
+ /**
411
+ * Clears the cached pages and reloads data from dataprovider when needed.
412
+ */
413
+ clearCache() {
414
+ this._cache = new ItemCache(this);
415
+ this._cache.size = this.size || 0;
416
+ this._cache.updateSize();
417
+ this._hasData = false;
418
+ this.__updateVisibleRows();
419
+
420
+ if (!this._effectiveSize) {
421
+ this._loadPage(0, this._cache);
422
+ }
423
+ }
424
+
425
+ /** @private */
426
+ _pageSizeChanged(pageSize, oldPageSize) {
427
+ if (oldPageSize !== undefined && pageSize !== oldPageSize) {
428
+ this.clearCache();
429
+ }
430
+ }
431
+
432
+ /** @protected */
433
+ _checkSize() {
434
+ if (this.size === undefined && this._effectiveSize === 0) {
435
+ console.warn(
436
+ 'The <vaadin-grid> needs the total number of items' +
437
+ ' in order to display rows. Set the total number of items' +
438
+ ' to the `size` property, or provide the total number of items' +
439
+ ' in the second argument of the `dataProvider`’s `callback` call.'
440
+ );
441
+ }
442
+ }
443
+
444
+ /** @private */
445
+ _dataProviderChanged(dataProvider, oldDataProvider) {
446
+ if (oldDataProvider !== undefined) {
447
+ this.clearCache();
448
+ }
449
+
450
+ this._ensureFirstPageLoaded();
451
+
452
+ this._debouncerCheckSize = Debouncer.debounce(
453
+ this._debouncerCheckSize,
454
+ timeOut.after(2000),
455
+ this._checkSize.bind(this)
456
+ );
457
+ }
458
+
459
+ /** @protected */
460
+ _ensureFirstPageLoaded() {
461
+ if (!this._hasData) {
462
+ // load data before adding rows to make sure they have content when
463
+ // rendered for the first time.
464
+ this._loadPage(0, this._cache);
465
+ }
466
+ }
467
+
468
+ /**
469
+ * @param {!GridItem} item1
470
+ * @param {!GridItem} item2
471
+ * @return {boolean}
472
+ * @protected
473
+ */
474
+ _itemsEqual(item1, item2) {
475
+ return this.getItemId(item1) === this.getItemId(item2);
476
+ }
477
+
478
+ /**
479
+ * @param {!GridItem} item
480
+ * @param {!Array<!GridItem>} array
481
+ * @return {number}
482
+ * @protected
483
+ */
484
+ _getItemIndexInArray(item, array) {
485
+ let result = -1;
486
+ array.forEach((i, idx) => {
487
+ if (this._itemsEqual(i, item)) {
488
+ result = idx;
489
+ }
490
+ });
491
+ return result;
492
+ }
493
+
494
+ scrollToIndex(index) {
495
+ super.scrollToIndex(index);
496
+ if (!isNaN(index) && (this._cache.isLoading() || !this.clientHeight)) {
497
+ this.__pendingScrollToIndex = index;
498
+ }
499
+ }
500
+
501
+ __scrollToPendingIndex() {
502
+ if (this.__pendingScrollToIndex && this.$.items.children.length) {
503
+ const index = this.__pendingScrollToIndex;
504
+ delete this.__pendingScrollToIndex;
505
+ this.scrollToIndex(index);
506
+ }
507
+ }
508
+
509
+ /**
510
+ * Fired when the `expandedItems` property changes.
511
+ *
512
+ * @event expanded-items-changed
513
+ */
514
+
515
+ /**
516
+ * Fired when the `loading` property changes.
517
+ *
518
+ * @event loading-changed
519
+ */
520
+ };
@@ -0,0 +1,69 @@
1
+ import { GridDragAndDropFilter, GridDropMode } from './interfaces';
2
+
3
+ declare function DragAndDropMixin<TItem, T extends new (...args: any[]) => {}>(
4
+ base: T
5
+ ): T & DragAndDropMixinConstructor<TItem>;
6
+
7
+ interface DragAndDropMixinConstructor<TItem> {
8
+ new (...args: any[]): DragAndDropMixin<TItem>;
9
+ }
10
+
11
+ interface DragAndDropMixin<TItem> {
12
+ /**
13
+ * Defines the locations within the Grid row where an element can be dropped.
14
+ *
15
+ * Possible values are:
16
+ * - `between`: The drop event can happen between Grid rows.
17
+ * - `on-top`: The drop event can happen on top of Grid rows.
18
+ * - `on-top-or-between`: The drop event can happen either on top of or between Grid rows.
19
+ * - `on-grid`: The drop event will not happen on any specific row, it will show the drop target outline around the whole grid.
20
+ * @attr {between|on-top|on-top-or-between|on-grid} drop-mode
21
+ */
22
+ dropMode: GridDropMode | null | undefined;
23
+
24
+ /**
25
+ * Marks the grid's rows to be available for dragging.
26
+ * @attr {boolean} rows-draggable
27
+ */
28
+ rowsDraggable: boolean | null | undefined;
29
+
30
+ /**
31
+ * A function that filters dragging of specific grid rows. The return value should be false
32
+ * if dragging of the row should be disabled.
33
+ *
34
+ * Receives one argument:
35
+ * - `model` The object with the properties related with
36
+ * the rendered item, contains:
37
+ * - `model.index` The index of the item.
38
+ * - `model.item` The item.
39
+ * - `model.expanded` Sublevel toggle state.
40
+ * - `model.level` Level of the tree represented with a horizontal offset of the toggle button.
41
+ * - `model.selected` Selected state.
42
+ */
43
+ dragFilter: GridDragAndDropFilter<TItem> | null | undefined;
44
+
45
+ /**
46
+ * A function that filters dropping on specific grid rows. The return value should be false
47
+ * if dropping on the row should be disabled.
48
+ *
49
+ * Receives one argument:
50
+ * - `model` The object with the properties related with
51
+ * the rendered item, contains:
52
+ * - `model.index` The index of the item.
53
+ * - `model.item` The item.
54
+ * - `model.expanded` Sublevel toggle state.
55
+ * - `model.level` Level of the tree represented with a horizontal offset of the toggle button.
56
+ * - `model.selected` Selected state.
57
+ */
58
+ dropFilter: GridDragAndDropFilter<TItem> | null | undefined;
59
+
60
+ /**
61
+ * Runs the `dragFilter` and `dropFilter` hooks for the visible cells.
62
+ * If the filter depends on varying conditions, you may need to
63
+ * call this function manually in order to update the draggability when
64
+ * the conditions change.
65
+ */
66
+ filterDragAndDrop(): void;
67
+ }
68
+
69
+ export { DragAndDropMixin, DragAndDropMixinConstructor };