@vaadin/component-base 24.2.0-dev.f254716fe → 24.3.0-alpha2

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/index.d.ts CHANGED
@@ -4,3 +4,4 @@ export { DirMixin } from './src/dir-mixin.js';
4
4
  export { ElementMixin } from './src/element-mixin.js';
5
5
  export { ResizeMixin } from './src/resize-mixin.js';
6
6
  export { SlotController } from './src/slot-controller.js';
7
+ export { SlotStylesMixin } from './src/slot-styles-mixin.js';
package/index.js CHANGED
@@ -4,3 +4,4 @@ export { DirMixin } from './src/dir-mixin.js';
4
4
  export { ElementMixin } from './src/element-mixin.js';
5
5
  export { ResizeMixin } from './src/resize-mixin.js';
6
6
  export { SlotController } from './src/slot-controller.js';
7
+ export { SlotStylesMixin } from './src/slot-styles-mixin.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/component-base",
3
- "version": "24.2.0-dev.f254716fe",
3
+ "version": "24.3.0-alpha2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -39,8 +39,8 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "@esm-bundle/chai": "^4.3.4",
42
- "@vaadin/testing-helpers": "^0.4.3",
42
+ "@vaadin/testing-helpers": "^0.5.0",
43
43
  "sinon": "^13.0.2"
44
44
  },
45
- "gitHead": "da54950b9f8c14c6451ede0d426e16a489c7fb9b"
45
+ "gitHead": "0fd437292fa2a2f65e29b424d2456909ad2d684b"
46
46
  }
@@ -0,0 +1,146 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import type { DataProviderCallback } from './data-provider-controller.js';
7
+
8
+ export type CacheContext<TItem> = { isExpanded(item: TItem): boolean };
9
+
10
+ /**
11
+ * A class that stores items with their associated sub-caches.
12
+ */
13
+ export class Cache<TItem> {
14
+ /**
15
+ * A context object.
16
+ */
17
+ context: CacheContext<TItem>;
18
+
19
+ /**
20
+ * The number of items.
21
+ */
22
+ size: number;
23
+
24
+ /**
25
+ * The number of items to display per page.
26
+ */
27
+ pageSize: number;
28
+
29
+ /**
30
+ * An array of cached items.
31
+ */
32
+ items: TItem[];
33
+
34
+ /**
35
+ * A map where the key is a requested page and the value is a callback
36
+ * that will be called with data once the request is complete.
37
+ */
38
+ pendingRequests: Record<number, DataProviderCallback<TItem>>;
39
+
40
+ /**
41
+ * An item in the parent cache that the current cache is associated with.
42
+ */
43
+ get parentItem(): TItem | undefined;
44
+
45
+ /**
46
+ * An array of sub-caches sorted in the same order as their associated items
47
+ * appear in the `items` array.
48
+ */
49
+ get subCaches(): Array<Cache<TItem>>;
50
+
51
+ /**
52
+ * Whether the cache or any of its descendant caches have pending requests.
53
+ */
54
+ get isLoading(): boolean;
55
+
56
+ /**
57
+ * The total number of items, including items from expanded sub-caches.
58
+ */
59
+ get flatSize(): number;
60
+
61
+ /**
62
+ * The total number of items, including items from expanded sub-caches.
63
+ *
64
+ * @protected
65
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
66
+ */
67
+ get effectiveSize(): number;
68
+
69
+ constructor(
70
+ context: CacheContext<TItem>,
71
+ pageSize: number,
72
+ size: number,
73
+ parentCache?: Cache<TItem>,
74
+ parentCacheIndex?: number,
75
+ );
76
+
77
+ /**
78
+ * Recalculates the flattened size for the cache and its descendant caches recursively.
79
+ */
80
+ recalculateFlatSize(): void;
81
+
82
+ /**
83
+ * Adds an array of items corresponding to the given page
84
+ * to the `items` array.
85
+ */
86
+ setPage(page: number, items: unknown[]): void;
87
+
88
+ /**
89
+ * Retrieves the sub-cache associated with the item at the given index
90
+ * in the `items` array.
91
+ */
92
+ getSubCache(index: number): Cache<TItem> | undefined;
93
+
94
+ /**
95
+ * Removes the sub-cache associated with the item at the given index
96
+ * in the `items` array.
97
+ */
98
+ removeSubCache(index: number): void;
99
+
100
+ /**
101
+ * Removes all sub-caches.
102
+ */
103
+ removeSubCaches(): void;
104
+
105
+ /**
106
+ * Creates and associates a sub-cache for the item at the given index
107
+ * in the `items` array.
108
+ */
109
+ createSubCache(index: number): Cache<TItem>;
110
+
111
+ /**
112
+ * Retrieves the flattened index corresponding to the given index
113
+ * of an item in the `items` array.
114
+ */
115
+ getFlatIndex(index: number): number;
116
+
117
+ /**
118
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
119
+ */
120
+ getItemForIndex(index: number): TItem | undefined;
121
+
122
+ /**
123
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
124
+ */
125
+ getCacheAndIndex(index: number): { cache: Cache<TItem>; scaledIndex: number };
126
+
127
+ /**
128
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
129
+ */
130
+ updateSize(): void;
131
+
132
+ /**
133
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
134
+ */
135
+ ensureSubCacheForScaledIndex(scaledIndex: number): void;
136
+
137
+ /**
138
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
139
+ */
140
+ get grid(): HTMLElement;
141
+
142
+ /**
143
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
144
+ */
145
+ get itemCaches(): object;
146
+ }
@@ -1,8 +1,20 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { getFlatIndexContext } from './helpers.js';
7
+
8
+ /**
9
+ * A class that stores items with their associated sub-caches.
10
+ */
1
11
  export class Cache {
2
12
  /**
3
- * @type {import('../data-provider-controller.js').DataProviderController}
13
+ * A context object.
14
+ *
15
+ * @type {{ isExpanded: (item: unknown) => boolean }}
4
16
  */
5
- controller;
17
+ context;
6
18
 
7
19
  /**
8
20
  * The number of items.
@@ -18,13 +30,6 @@ export class Cache {
18
30
  */
19
31
  pageSize;
20
32
 
21
- /**
22
- * The total number of items, including items from expanded sub-caches.
23
- *
24
- * @type {number}
25
- */
26
- effectiveSize = 0;
27
-
28
33
  /**
29
34
  * An array of cached items.
30
35
  *
@@ -36,9 +41,9 @@ export class Cache {
36
41
  * A map where the key is a requested page and the value is a callback
37
42
  * that will be called with data once the request is complete.
38
43
  *
39
- * @type {Map<number, Function>}
44
+ * @type {Record<number, Function>}
40
45
  */
41
- pendingRequests = new Map();
46
+ pendingRequests = {};
42
47
 
43
48
  /**
44
49
  * A map where the key is the index of an item in the `items` array
@@ -49,23 +54,32 @@ export class Cache {
49
54
  * in alphabetical order, rather than the order they were added.
50
55
  *
51
56
  * @type {Record<number, Cache>}
57
+ * @private
52
58
  */
53
- #subCacheByIndex = {};
59
+ __subCacheByIndex = {};
54
60
 
55
61
  /**
56
- * @param {Cache['controller']} controller
62
+ * The total number of items, including items from expanded sub-caches.
63
+ *
64
+ * @type {number}
65
+ * @private
66
+ */
67
+ __flatSize = 0;
68
+
69
+ /**
70
+ * @param {Cache['context']} context
57
71
  * @param {number} pageSize
58
72
  * @param {number | undefined} size
59
73
  * @param {Cache | undefined} parentCache
60
74
  * @param {number | undefined} parentCacheIndex
61
75
  */
62
- constructor(controller, pageSize, size, parentCache, parentCacheIndex) {
63
- this.controller = controller;
76
+ constructor(context, pageSize, size, parentCache, parentCacheIndex) {
77
+ this.context = context;
64
78
  this.pageSize = pageSize;
65
79
  this.size = size || 0;
66
- this.effectiveSize = size || 0;
67
80
  this.parentCache = parentCache;
68
81
  this.parentCacheIndex = parentCacheIndex;
82
+ this.__flatSize = size || 0;
69
83
  }
70
84
 
71
85
  /**
@@ -77,41 +91,61 @@ export class Cache {
77
91
  return this.parentCache && this.parentCache.items[this.parentCacheIndex];
78
92
  }
79
93
 
94
+ /**
95
+ * An array of sub-caches sorted in the same order as their associated items
96
+ * appear in the `items` array.
97
+ *
98
+ * @return {Cache[]}
99
+ */
100
+ get subCaches() {
101
+ return Object.values(this.__subCacheByIndex);
102
+ }
103
+
80
104
  /**
81
105
  * Whether the cache or any of its descendant caches have pending requests.
82
106
  *
83
107
  * @return {boolean}
84
108
  */
85
109
  get isLoading() {
86
- if (this.pendingRequests.size > 0) {
110
+ if (Object.keys(this.pendingRequests).length > 0) {
87
111
  return true;
88
112
  }
89
113
 
90
- return Object.values(this.#subCacheByIndex).some((subCache) => subCache.isLoading);
114
+ return this.subCaches.some((subCache) => subCache.isLoading);
91
115
  }
92
116
 
93
117
  /**
94
- * An array of sub-caches sorted in the same order as their associated items
95
- * appear in the `items` array.
118
+ * The total number of items, including items from expanded sub-caches.
96
119
  *
97
- * @return {Array<[number, Cache]>}
120
+ * @return {number}
98
121
  */
99
- get subCaches() {
100
- return Object.entries(this.#subCacheByIndex).map(([index, subCache]) => {
101
- return [parseInt(index), subCache];
102
- });
122
+ get flatSize() {
123
+ return this.__flatSize;
103
124
  }
104
125
 
105
126
  /**
106
- * Recalculates the effective size for the cache and its descendant caches recursively.
127
+ * The total number of items, including items from expanded sub-caches.
128
+ *
129
+ * @protected
130
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
107
131
  */
108
- recalculateEffectiveSize() {
109
- this.effectiveSize =
110
- !this.parentItem || this.controller.isExpanded(this.parentItem)
132
+ get effectiveSize() {
133
+ console.warn(
134
+ '<vaadin-grid> The `effectiveSize` property of ItemCache is deprecated and will be removed in Vaadin 25.',
135
+ );
136
+ return this.flatSize;
137
+ }
138
+
139
+ /**
140
+ * Recalculates the flattened size for the cache and its descendant caches recursively.
141
+ */
142
+ recalculateFlatSize() {
143
+ this.__flatSize =
144
+ !this.parentItem || this.context.isExpanded(this.parentItem)
111
145
  ? this.size +
112
- Object.values(this.#subCacheByIndex).reduce((total, subCache) => {
113
- subCache.recalculateEffectiveSize();
114
- return total + subCache.effectiveSize;
146
+ this.subCaches.reduce((total, subCache) => {
147
+ subCache.recalculateFlatSize();
148
+ return total + subCache.flatSize;
115
149
  }, 0)
116
150
  : 0;
117
151
  }
@@ -130,16 +164,6 @@ export class Cache {
130
164
  });
131
165
  }
132
166
 
133
- /**
134
- * Returns whether the given page has been loaded in the cache.
135
- *
136
- * @param {number} page
137
- * @return {boolean}
138
- */
139
- isPageLoaded(page) {
140
- return this.items[page * this.pageSize] !== undefined;
141
- }
142
-
143
167
  /**
144
168
  * Retrieves the sub-cache associated with the item at the given index
145
169
  * in the `items` array.
@@ -148,7 +172,7 @@ export class Cache {
148
172
  * @return {Cache | undefined}
149
173
  */
150
174
  getSubCache(index) {
151
- return this.#subCacheByIndex[index];
175
+ return this.__subCacheByIndex[index];
152
176
  }
153
177
 
154
178
  /**
@@ -158,32 +182,14 @@ export class Cache {
158
182
  * @param {number} index
159
183
  */
160
184
  removeSubCache(index) {
161
- const subCache = this.getSubCache(index);
162
- delete this.#subCacheByIndex[index];
163
-
164
- this.controller.dispatchEvent(
165
- new CustomEvent('sub-cache-removed', {
166
- detail: {
167
- cache: this,
168
- subCache,
169
- },
170
- }),
171
- );
185
+ delete this.__subCacheByIndex[index];
172
186
  }
173
187
 
174
188
  /**
175
189
  * Removes all sub-caches.
176
190
  */
177
191
  removeSubCaches() {
178
- this.#subCacheByIndex = {};
179
-
180
- this.controller.dispatchEvent(
181
- new CustomEvent('sub-caches-removed', {
182
- detail: {
183
- cache: this,
184
- },
185
- }),
186
- );
192
+ this.__subCacheByIndex = {};
187
193
  }
188
194
 
189
195
  /**
@@ -194,18 +200,8 @@ export class Cache {
194
200
  * @return {Cache}
195
201
  */
196
202
  createSubCache(index) {
197
- const subCache = new Cache(this.controller, this.pageSize, 0, this, index);
198
- this.#subCacheByIndex[index] = subCache;
199
-
200
- this.controller.dispatchEvent(
201
- new CustomEvent('sub-cache-created', {
202
- detail: {
203
- cache: this,
204
- subCache,
205
- },
206
- }),
207
- );
208
-
203
+ const subCache = new Cache(this.context, this.pageSize, 0, this, index);
204
+ this.__subCacheByIndex[index] = subCache;
209
205
  return subCache;
210
206
  }
211
207
 
@@ -219,8 +215,71 @@ export class Cache {
219
215
  getFlatIndex(index) {
220
216
  const clampedIndex = Math.max(0, Math.min(this.size - 1, index));
221
217
 
222
- return this.subCaches.reduce((prev, [index, subCache]) => {
223
- return clampedIndex > index ? prev + subCache.effectiveSize : prev;
218
+ return this.subCaches.reduce((prev, subCache) => {
219
+ const index = subCache.parentCacheIndex;
220
+ return clampedIndex > index ? prev + subCache.flatSize : prev;
224
221
  }, clampedIndex);
225
222
  }
223
+
224
+ /**
225
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
226
+ */
227
+ getItemForIndex(index) {
228
+ console.warn(
229
+ '<vaadin-grid> The `getItemForIndex` method of ItemCache is deprecated and will be removed in Vaadin 25.',
230
+ );
231
+ const { item } = getFlatIndexContext(this, index);
232
+ return item;
233
+ }
234
+
235
+ /**
236
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
237
+ */
238
+ getCacheAndIndex(index) {
239
+ console.warn(
240
+ '<vaadin-grid> The `getCacheAndIndex` method of ItemCache is deprecated and will be removed in Vaadin 25.',
241
+ );
242
+ const { cache, index: scaledIndex } = getFlatIndexContext(this, index);
243
+ return { cache, scaledIndex };
244
+ }
245
+
246
+ /**
247
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
248
+ */
249
+ updateSize() {
250
+ console.warn('<vaadin-grid> The `updateSize` method of ItemCache is deprecated and will be removed in Vaadin 25.');
251
+ this.recalculateFlatSize();
252
+ }
253
+
254
+ /**
255
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
256
+ */
257
+ ensureSubCacheForScaledIndex(scaledIndex) {
258
+ console.warn(
259
+ '<vaadin-grid> The `ensureSubCacheForScaledIndex` method of ItemCache is deprecated and will be removed in Vaadin 25.',
260
+ );
261
+
262
+ if (!this.getSubCache(scaledIndex)) {
263
+ const subCache = this.createSubCache(scaledIndex);
264
+ this.context.__controller.__loadCachePage(subCache, 0);
265
+ }
266
+ }
267
+
268
+ /**
269
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
270
+ */
271
+ get grid() {
272
+ console.warn('<vaadin-grid> The `grid` property of ItemCache is deprecated and will be removed in Vaadin 25.');
273
+ return this.context.__controller.host;
274
+ }
275
+
276
+ /**
277
+ * @deprecated since 24.3 and will be removed in Vaadin 25.
278
+ */
279
+ get itemCaches() {
280
+ console.warn(
281
+ '<vaadin-grid> The `itemCaches` property of ItemCache is deprecated and will be removed in Vaadin 25.',
282
+ );
283
+ return this.__subCacheByIndex;
284
+ }
226
285
  }
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2021 - 2023 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import type { ReactiveController } from 'lit';
7
+ import type { Cache } from './cache.js';
8
+
9
+ type DataProviderDefaultParams = {
10
+ page: number;
11
+ pageSize: number;
12
+ parentItem?: unknown;
13
+ };
14
+
15
+ export type DataProviderCallback<TItem> = (items: TItem[], size?: number) => void;
16
+
17
+ export type DataProvider<TItem, TDataProviderParams extends Record<string, unknown>> = (
18
+ params: DataProviderDefaultParams & TDataProviderParams,
19
+ callback: DataProviderCallback<TItem>,
20
+ ) => void;
21
+
22
+ /**
23
+ * A controller that stores and manages items loaded with a data provider.
24
+ */
25
+ export class DataProviderController<TItem, TDataProviderParams extends Record<string, unknown>>
26
+ implements ReactiveController
27
+ {
28
+ /**
29
+ * The controller host element.
30
+ */
31
+ host: HTMLElement;
32
+
33
+ /**
34
+ * A callback that returns data based on the passed params such as
35
+ * `page`, `pageSize`, `parentItem`, etc.
36
+ */
37
+ dataProvider: DataProvider<TItem, TDataProviderParams>;
38
+
39
+ /**
40
+ * A callback that returns additional params that need to be passed
41
+ * to the data provider callback with every request.
42
+ */
43
+ dataProviderParams: () => TDataProviderParams;
44
+
45
+ /**
46
+ * A number of items in the root cache.
47
+ */
48
+ size?: number;
49
+
50
+ /**
51
+ * A number of items to display per page.
52
+ */
53
+ pageSize: number;
54
+
55
+ /**
56
+ * A callback that returns whether the given item is expanded.
57
+ */
58
+ isExpanded: (item: TItem) => boolean;
59
+
60
+ /**
61
+ * A reference to the root cache instance.
62
+ */
63
+ rootCache: Cache<TItem>;
64
+
65
+ constructor(
66
+ host: HTMLElement,
67
+ config: {
68
+ size?: number;
69
+ pageSize: number;
70
+ isExpanded(item: TItem): boolean;
71
+ dataProvider: DataProvider<TItem, TDataProviderParams>;
72
+ dataProviderParams(): TDataProviderParams;
73
+ },
74
+ );
75
+
76
+ /**
77
+ * The total number of items, including items from expanded sub-caches.
78
+ */
79
+ get flatSize(): number;
80
+
81
+ hostConnected(): void;
82
+
83
+ hostDisconnected(): void;
84
+
85
+ /**
86
+ * Whether the root cache or any of its decendant caches have pending requests.
87
+ */
88
+ isLoading(): boolean;
89
+
90
+ /**
91
+ * Sets the size for the root cache and recalculates the flattened size.
92
+ */
93
+ setSize(size: number): void;
94
+
95
+ /**
96
+ * Sets the page size and clears the cache.
97
+ */
98
+ setPageSize(pageSize: number): void;
99
+
100
+ /**
101
+ * Sets the data provider callback and clears the cache.
102
+ */
103
+ setDataProvider(dataProvider: DataProvider<TItem, TDataProviderParams>): void;
104
+
105
+ /**
106
+ * Recalculates the flattened size.
107
+ */
108
+ recalculateFlatSize(): void;
109
+
110
+ /**
111
+ * Clears the cache.
112
+ */
113
+ clearCache(): void;
114
+
115
+ /**
116
+ * Returns context for the given flattened index, including:
117
+ * - the corresponding cache
118
+ * - the associated item (if loaded)
119
+ * - the corresponding index in the cache's items array.
120
+ * - the page containing the index.
121
+ * - the cache level
122
+ */
123
+ getFlatIndexContext(flatIndex: number): {
124
+ cache: Cache<TItem>;
125
+ item: TItem | undefined;
126
+ index: number;
127
+ page: number;
128
+ level: number;
129
+ };
130
+
131
+ /**
132
+ * Returns the flattened index for the item that the given indexes point to.
133
+ * Each index in the path array points to a sub-item of the previous index.
134
+ * Using `Infinity` as an index will point to the last item on the level.
135
+ */
136
+ getFlatIndexByPath(path: number[]): number;
137
+
138
+ /**
139
+ * Requests the data provider to load the page with the item corresponding
140
+ * to the given flattened index. If the item is already loaded, the method
141
+ * returns immediatelly.
142
+ */
143
+ ensureFlatIndexLoaded(flatIndex: number): void;
144
+
145
+ /**
146
+ * Creates a sub-cache for the item corresponding to the given flattened index and
147
+ * requests the data provider to load the first page into the created sub-cache.
148
+ * If the sub-cache already exists, the method returns immediatelly.
149
+ */
150
+ ensureFlatIndexHierarchy(flatIndex: number): void;
151
+
152
+ /**
153
+ * Loads the first page into the root cache.
154
+ */
155
+ loadFirstPage(): void;
156
+ }