@react-stately/layout 4.2.2 → 4.3.0
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/dist/GridLayout.main.js +17 -4
- package/dist/GridLayout.main.js.map +1 -1
- package/dist/GridLayout.mjs +17 -4
- package/dist/GridLayout.module.js +17 -4
- package/dist/GridLayout.module.js.map +1 -1
- package/dist/ListLayout.main.js +24 -5
- package/dist/ListLayout.main.js.map +1 -1
- package/dist/ListLayout.mjs +24 -5
- package/dist/ListLayout.module.js +24 -5
- package/dist/ListLayout.module.js.map +1 -1
- package/dist/TableLayout.main.js +26 -4
- package/dist/TableLayout.main.js.map +1 -1
- package/dist/TableLayout.mjs +27 -5
- package/dist/TableLayout.module.js +27 -5
- package/dist/TableLayout.module.js.map +1 -1
- package/dist/WaterfallLayout.main.js +30 -18
- package/dist/WaterfallLayout.main.js.map +1 -1
- package/dist/WaterfallLayout.mjs +30 -18
- package/dist/WaterfallLayout.module.js +30 -18
- package/dist/WaterfallLayout.module.js.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/GridLayout.ts +21 -4
- package/src/ListLayout.ts +30 -8
- package/src/TableLayout.ts +35 -5
- package/src/WaterfallLayout.ts +16 -5
package/src/TableLayout.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import {DropTarget, ItemDropTarget, Key} from '@react-types/shared';
|
|
14
|
-
import {getChildNodes} from '@react-stately/collections';
|
|
14
|
+
import {getChildNodes, getLastItem} from '@react-stately/collections';
|
|
15
15
|
import {GridNode} from '@react-types/grid';
|
|
16
16
|
import {InvalidationContext, LayoutInfo, Point, Rect, Size} from '@react-stately/virtualizer';
|
|
17
17
|
import {LayoutNode, ListLayout, ListLayoutOptions} from './ListLayout';
|
|
@@ -85,6 +85,10 @@ export class TableLayout<T, O extends TableLayoutProps = TableLayoutProps> exten
|
|
|
85
85
|
this.stickyColumnIndices = [];
|
|
86
86
|
|
|
87
87
|
let collection = this.virtualizer!.collection as TableCollection<T>;
|
|
88
|
+
if (collection.head?.key === -1) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
|
|
88
92
|
for (let column of collection.columns) {
|
|
89
93
|
// The selection cell and any other sticky columns always need to be visible.
|
|
90
94
|
// In addition, row headers need to be in the DOM for accessibility labeling.
|
|
@@ -251,7 +255,8 @@ export class TableLayout<T, O extends TableLayoutProps = TableLayoutProps> exten
|
|
|
251
255
|
let width = 0;
|
|
252
256
|
let children: LayoutNode[] = [];
|
|
253
257
|
let rowHeight = this.getEstimatedRowHeight() + this.gap;
|
|
254
|
-
|
|
258
|
+
let childNodes = getChildNodes(collection.body, collection);
|
|
259
|
+
for (let node of childNodes) {
|
|
255
260
|
// Skip rows before the valid rectangle unless they are already cached.
|
|
256
261
|
if (y + rowHeight < this.requestedRect.y && !this.isValid(node, y)) {
|
|
257
262
|
y += rowHeight;
|
|
@@ -267,13 +272,32 @@ export class TableLayout<T, O extends TableLayoutProps = TableLayoutProps> exten
|
|
|
267
272
|
children.push(layoutNode);
|
|
268
273
|
|
|
269
274
|
if (y > this.requestedRect.maxY) {
|
|
275
|
+
let rowsAfterRect = collection.size - (children.length + skipped);
|
|
276
|
+
let lastNode = getLastItem(childNodes);
|
|
277
|
+
if (lastNode?.type === 'loader') {
|
|
278
|
+
rowsAfterRect--;
|
|
279
|
+
}
|
|
280
|
+
|
|
270
281
|
// Estimate the remaining height for rows that we don't need to layout right now.
|
|
271
|
-
y +=
|
|
282
|
+
y += rowsAfterRect * rowHeight;
|
|
283
|
+
|
|
284
|
+
// Always add the loader sentinel if present. This assumes the loader is the last row in the body,
|
|
285
|
+
// will need to refactor when handling multi section loading
|
|
286
|
+
if (lastNode?.type === 'loader' && children.at(-1)?.layoutInfo.type !== 'loader') {
|
|
287
|
+
let loader = this.buildChild(lastNode, this.padding, y, layoutInfo.key);
|
|
288
|
+
loader.layoutInfo.parentKey = layoutInfo.key;
|
|
289
|
+
loader.index = collection.size;
|
|
290
|
+
width = Math.max(width, loader.layoutInfo.rect.width);
|
|
291
|
+
children.push(loader);
|
|
292
|
+
y = loader.layoutInfo.rect.maxY;
|
|
293
|
+
}
|
|
272
294
|
break;
|
|
273
295
|
}
|
|
274
296
|
}
|
|
275
297
|
|
|
276
|
-
if
|
|
298
|
+
// Make sure that the table body gets a height if empty or performing initial load
|
|
299
|
+
let isEmptyOrLoading = collection?.size === 0 || (collection.size === 1 && collection.getItem(collection.getFirstKey()!)!.type === 'loader');
|
|
300
|
+
if (isEmptyOrLoading) {
|
|
277
301
|
y = this.virtualizer!.visibleRect.maxY;
|
|
278
302
|
} else {
|
|
279
303
|
y -= this.gap;
|
|
@@ -442,6 +466,12 @@ export class TableLayout<T, O extends TableLayoutProps = TableLayoutProps> exten
|
|
|
442
466
|
this.addVisibleLayoutInfos(res, node.children[idx], rect);
|
|
443
467
|
}
|
|
444
468
|
}
|
|
469
|
+
|
|
470
|
+
// Always include loading sentinel even when virtualized, we assume it is always the last child for now
|
|
471
|
+
let lastRow = node.children.at(-1);
|
|
472
|
+
if (lastRow?.layoutInfo.type === 'loader') {
|
|
473
|
+
res.push(lastRow.layoutInfo);
|
|
474
|
+
}
|
|
445
475
|
break;
|
|
446
476
|
}
|
|
447
477
|
case 'headerrow':
|
|
@@ -543,7 +573,7 @@ export class TableLayout<T, O extends TableLayoutProps = TableLayoutProps> exten
|
|
|
543
573
|
y += this.virtualizer!.visibleRect.y;
|
|
544
574
|
|
|
545
575
|
// Find the closest item within on either side of the point using the gap width.
|
|
546
|
-
let searchRect = new Rect(x, Math.max(0, y - this.gap), 1, this.gap * 2);
|
|
576
|
+
let searchRect = new Rect(x, Math.max(0, y - this.gap), 1, Math.max(1, this.gap * 2));
|
|
547
577
|
let candidates = this.getVisibleLayoutInfos(searchRect);
|
|
548
578
|
let key: Key | null = null;
|
|
549
579
|
let minDistance = Infinity;
|
package/src/WaterfallLayout.ts
CHANGED
|
@@ -140,8 +140,9 @@ export class WaterfallLayout<T extends object, O extends WaterfallLayoutOptions
|
|
|
140
140
|
columnHeights[column] += layoutInfo.rect.height + minSpace.height;
|
|
141
141
|
};
|
|
142
142
|
|
|
143
|
+
let collection = this.virtualizer!.collection;
|
|
143
144
|
let skeletonCount = 0;
|
|
144
|
-
for (let node of
|
|
145
|
+
for (let node of collection) {
|
|
145
146
|
if (node.type === 'skeleton') {
|
|
146
147
|
// Add skeleton cards until every column has at least one, and we fill the viewport.
|
|
147
148
|
let startingHeights = [...columnHeights];
|
|
@@ -154,13 +155,23 @@ export class WaterfallLayout<T extends object, O extends WaterfallLayoutOptions
|
|
|
154
155
|
addNode(key, content);
|
|
155
156
|
}
|
|
156
157
|
break;
|
|
157
|
-
} else {
|
|
158
|
+
} else if (node.type !== 'loader') {
|
|
158
159
|
addNode(node.key, node);
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
//
|
|
163
|
-
|
|
163
|
+
// Always add the loader sentinel if present in the collection so we can make sure it is never virtualized out.
|
|
164
|
+
// Add it under the first column for simplicity
|
|
165
|
+
let lastNode = collection.getItem(collection.getLastKey()!);
|
|
166
|
+
if (lastNode?.type === 'loader') {
|
|
167
|
+
let rect = new Rect(horizontalSpacing, columnHeights[0], itemWidth, 0);
|
|
168
|
+
let layoutInfo = new LayoutInfo('loader', lastNode.key, rect);
|
|
169
|
+
newLayoutInfos.set(lastNode.key, layoutInfo);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Reset all columns to the maximum for the next section. If loading, set to 0 so virtualizer doesn't render its body since there aren't items to render
|
|
173
|
+
let isEmptyOrLoading = collection?.size === 0 || (collection.size === 1 && collection.getItem(collection.getFirstKey()!)!.type === 'loader');
|
|
174
|
+
let maxHeight = isEmptyOrLoading ? 0 : Math.max(...columnHeights);
|
|
164
175
|
this.contentSize = new Size(this.virtualizer!.visibleRect.width, maxHeight);
|
|
165
176
|
this.layoutInfos = newLayoutInfos;
|
|
166
177
|
this.numColumns = numColumns;
|
|
@@ -177,7 +188,7 @@ export class WaterfallLayout<T extends object, O extends WaterfallLayoutOptions
|
|
|
177
188
|
getVisibleLayoutInfos(rect: Rect): LayoutInfo[] {
|
|
178
189
|
let layoutInfos: LayoutInfo[] = [];
|
|
179
190
|
for (let layoutInfo of this.layoutInfos.values()) {
|
|
180
|
-
if (layoutInfo.rect.intersects(rect) || this.virtualizer!.isPersistedKey(layoutInfo.key)) {
|
|
191
|
+
if (layoutInfo.rect.intersects(rect) || this.virtualizer!.isPersistedKey(layoutInfo.key) || layoutInfo.type === 'loader') {
|
|
181
192
|
layoutInfos.push(layoutInfo);
|
|
182
193
|
}
|
|
183
194
|
}
|