react-stately 3.48.0 → 3.49.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/exports/index.cjs +6 -0
- package/dist/exports/index.cjs.map +1 -1
- package/dist/exports/index.js +5 -1
- package/dist/exports/index.js.map +1 -1
- package/dist/exports/index.mjs +5 -1
- package/dist/exports/index.mjs.map +1 -1
- package/dist/exports/useTokenFieldState.cjs +25 -0
- package/dist/exports/useTokenFieldState.cjs.map +1 -0
- package/dist/exports/useTokenFieldState.js +19 -0
- package/dist/exports/useTokenFieldState.js.map +1 -0
- package/dist/exports/useTokenFieldState.mjs +19 -0
- package/dist/exports/useTokenFieldState.mjs.map +1 -0
- package/dist/private/combobox/useComboBoxState.cjs +2 -1
- package/dist/private/combobox/useComboBoxState.cjs.map +1 -1
- package/dist/private/combobox/useComboBoxState.js +2 -1
- package/dist/private/combobox/useComboBoxState.js.map +1 -1
- package/dist/private/combobox/useComboBoxState.mjs +2 -1
- package/dist/private/combobox/useComboBoxState.mjs.map +1 -1
- package/dist/private/data/useTreeData.cjs +1 -0
- package/dist/private/data/useTreeData.cjs.map +1 -1
- package/dist/private/data/useTreeData.js +1 -0
- package/dist/private/data/useTreeData.js.map +1 -1
- package/dist/private/data/useTreeData.mjs +1 -0
- package/dist/private/data/useTreeData.mjs.map +1 -1
- package/dist/private/datepicker/useDateRangePickerState.cjs +1 -0
- package/dist/private/datepicker/useDateRangePickerState.cjs.map +1 -1
- package/dist/private/datepicker/useDateRangePickerState.js +1 -0
- package/dist/private/datepicker/useDateRangePickerState.js.map +1 -1
- package/dist/private/datepicker/useDateRangePickerState.mjs +1 -0
- package/dist/private/datepicker/useDateRangePickerState.mjs.map +1 -1
- package/dist/private/form/useFormValidationState.cjs +1 -1
- package/dist/private/form/useFormValidationState.cjs.map +1 -1
- package/dist/private/form/useFormValidationState.js +1 -1
- package/dist/private/form/useFormValidationState.js.map +1 -1
- package/dist/private/form/useFormValidationState.mjs +1 -1
- package/dist/private/form/useFormValidationState.mjs.map +1 -1
- package/dist/private/grid/useGridState.cjs +12 -10
- package/dist/private/grid/useGridState.cjs.map +1 -1
- package/dist/private/grid/useGridState.js +12 -10
- package/dist/private/grid/useGridState.js.map +1 -1
- package/dist/private/grid/useGridState.mjs +12 -10
- package/dist/private/grid/useGridState.mjs.map +1 -1
- package/dist/private/layout/ListLayout.cjs +0 -3
- package/dist/private/layout/ListLayout.cjs.map +1 -1
- package/dist/private/layout/ListLayout.js +0 -3
- package/dist/private/layout/ListLayout.js.map +1 -1
- package/dist/private/layout/ListLayout.mjs +0 -3
- package/dist/private/layout/ListLayout.mjs.map +1 -1
- package/dist/private/menu/useMenuTriggerState.cjs.map +1 -1
- package/dist/private/menu/useMenuTriggerState.js.map +1 -1
- package/dist/private/menu/useMenuTriggerState.mjs.map +1 -1
- package/dist/private/menu/useSubmenuTriggerState.cjs +3 -1
- package/dist/private/menu/useSubmenuTriggerState.cjs.map +1 -1
- package/dist/private/menu/useSubmenuTriggerState.js +3 -1
- package/dist/private/menu/useSubmenuTriggerState.js.map +1 -1
- package/dist/private/menu/useSubmenuTriggerState.mjs +3 -1
- package/dist/private/menu/useSubmenuTriggerState.mjs.map +1 -1
- package/dist/private/overlays/useOverlayTriggerState.cjs +4 -1
- package/dist/private/overlays/useOverlayTriggerState.cjs.map +1 -1
- package/dist/private/overlays/useOverlayTriggerState.js +5 -2
- package/dist/private/overlays/useOverlayTriggerState.js.map +1 -1
- package/dist/private/overlays/useOverlayTriggerState.mjs +5 -2
- package/dist/private/overlays/useOverlayTriggerState.mjs.map +1 -1
- package/dist/private/select/useSelectState.cjs +1 -0
- package/dist/private/select/useSelectState.cjs.map +1 -1
- package/dist/private/select/useSelectState.js +1 -0
- package/dist/private/select/useSelectState.js.map +1 -1
- package/dist/private/select/useSelectState.mjs +1 -0
- package/dist/private/select/useSelectState.mjs.map +1 -1
- package/dist/private/slider/useSliderState.cjs.map +1 -1
- package/dist/private/slider/useSliderState.js.map +1 -1
- package/dist/private/slider/useSliderState.mjs.map +1 -1
- package/dist/private/table/TableUtils.cjs +13 -1
- package/dist/private/table/TableUtils.cjs.map +1 -1
- package/dist/private/table/TableUtils.js +13 -1
- package/dist/private/table/TableUtils.js.map +1 -1
- package/dist/private/table/TableUtils.mjs +13 -1
- package/dist/private/table/TableUtils.mjs.map +1 -1
- package/dist/private/table/useTableState.cjs +1 -0
- package/dist/private/table/useTableState.cjs.map +1 -1
- package/dist/private/table/useTableState.js +1 -0
- package/dist/private/table/useTableState.js.map +1 -1
- package/dist/private/table/useTableState.mjs +1 -0
- package/dist/private/table/useTableState.mjs.map +1 -1
- package/dist/private/tokenfield/TokenFieldValue.cjs +287 -0
- package/dist/private/tokenfield/TokenFieldValue.cjs.map +1 -0
- package/dist/private/tokenfield/TokenFieldValue.js +285 -0
- package/dist/private/tokenfield/TokenFieldValue.js.map +1 -0
- package/dist/private/tokenfield/TokenFieldValue.mjs +282 -0
- package/dist/private/tokenfield/TokenFieldValue.mjs.map +1 -0
- package/dist/private/tokenfield/useTokenFieldState.cjs +37 -0
- package/dist/private/tokenfield/useTokenFieldState.cjs.map +1 -0
- package/dist/private/tokenfield/useTokenFieldState.js +32 -0
- package/dist/private/tokenfield/useTokenFieldState.js.map +1 -0
- package/dist/private/tokenfield/useTokenFieldState.mjs +32 -0
- package/dist/private/tokenfield/useTokenFieldState.mjs.map +1 -0
- package/dist/private/tooltip/useTooltipTriggerState.cjs +18 -6
- package/dist/private/tooltip/useTooltipTriggerState.cjs.map +1 -1
- package/dist/private/tooltip/useTooltipTriggerState.js +19 -7
- package/dist/private/tooltip/useTooltipTriggerState.js.map +1 -1
- package/dist/private/tooltip/useTooltipTriggerState.mjs +19 -7
- package/dist/private/tooltip/useTooltipTriggerState.mjs.map +1 -1
- package/dist/private/virtualizer/ScrollAnchor.cjs +136 -0
- package/dist/private/virtualizer/ScrollAnchor.cjs.map +1 -0
- package/dist/private/virtualizer/ScrollAnchor.js +132 -0
- package/dist/private/virtualizer/ScrollAnchor.js.map +1 -0
- package/dist/private/virtualizer/ScrollAnchor.mjs +131 -0
- package/dist/private/virtualizer/ScrollAnchor.mjs.map +1 -0
- package/dist/private/virtualizer/Virtualizer.cjs +50 -1
- package/dist/private/virtualizer/Virtualizer.cjs.map +1 -1
- package/dist/private/virtualizer/Virtualizer.js +54 -1
- package/dist/private/virtualizer/Virtualizer.js.map +1 -1
- package/dist/private/virtualizer/Virtualizer.mjs +50 -1
- package/dist/private/virtualizer/Virtualizer.mjs.map +1 -1
- package/dist/private/virtualizer/useVirtualizerState.cjs +2 -1
- package/dist/private/virtualizer/useVirtualizerState.cjs.map +1 -1
- package/dist/private/virtualizer/useVirtualizerState.js +2 -1
- package/dist/private/virtualizer/useVirtualizerState.js.map +1 -1
- package/dist/private/virtualizer/useVirtualizerState.mjs +2 -1
- package/dist/private/virtualizer/useVirtualizerState.mjs.map +1 -1
- package/dist/types/exports/index.d.ts +4 -0
- package/dist/types/exports/useTokenFieldState.d.ts +4 -0
- package/dist/types/src/combobox/useComboBoxState.d.ts +1 -1
- package/dist/types/src/menu/useMenuTriggerState.d.ts +1 -1
- package/dist/types/src/overlays/useOverlayTriggerState.d.ts +9 -0
- package/dist/types/src/table/useTableState.d.ts +7 -0
- package/dist/types/src/tokenfield/TokenFieldValue.d.ts +71 -0
- package/dist/types/src/tokenfield/useTokenFieldState.d.ts +19 -0
- package/dist/types/src/tooltip/useTooltipTriggerState.d.ts +5 -0
- package/dist/types/src/virtualizer/ScrollAnchor.d.ts +81 -0
- package/dist/types/src/virtualizer/Virtualizer.d.ts +1 -0
- package/dist/types/src/virtualizer/types.d.ts +2 -0
- package/package.json +5 -5
- package/useTokenFieldState/package.json +5 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import {Rect as $af827553fd3cf456$export$c79fc6492f3af13d} from "./Rect.mjs";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright 2026 Adobe. All rights reserved.
|
|
5
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
7
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
11
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Minimum overlap an item must have with the viewport, along the scroll axis,
|
|
16
|
+
* to be eligible as a scroll anchor. Without this, an item that only overlaps the viewport
|
|
17
|
+
* by a sliver (e.g. 1px, essentially scrolled out of view) can still "win" the anchor
|
|
18
|
+
* tie-break over a substantially visible item.
|
|
19
|
+
*/ const $78014f4785404d8e$var$MIN_ANCHOR_OVERLAP = 4;
|
|
20
|
+
function $78014f4785404d8e$var$dimensionForAxis(axis) {
|
|
21
|
+
return axis === 'x' ? 'width' : 'height';
|
|
22
|
+
}
|
|
23
|
+
function $78014f4785404d8e$export$413719533c5919c9(anchor, axis, getLayoutInfo, visibleRect, contentSize) {
|
|
24
|
+
let finalInfo = getLayoutInfo(anchor.key);
|
|
25
|
+
if (!finalInfo) return null;
|
|
26
|
+
let adjustment = finalInfo.rect[anchor.corner][axis] - visibleRect[axis] - anchor.offset;
|
|
27
|
+
if (adjustment === 0) return null;
|
|
28
|
+
let target = visibleRect[axis] + adjustment;
|
|
29
|
+
let dimension = $78014f4785404d8e$var$dimensionForAxis(axis);
|
|
30
|
+
let max = Math.max(0, contentSize[dimension] - visibleRect[dimension]);
|
|
31
|
+
let clamped = Math.max(0, Math.min(max, target));
|
|
32
|
+
return clamped !== visibleRect[axis] ? clamped : null;
|
|
33
|
+
}
|
|
34
|
+
function $78014f4785404d8e$export$69fb4c6de5f339b7(edge, axis, visibleRect, visibleLayoutInfos, isAnchorable = ()=>true) {
|
|
35
|
+
let dimension = $78014f4785404d8e$var$dimensionForAxis(axis);
|
|
36
|
+
let best = null;
|
|
37
|
+
for (let [key, layoutInfo] of visibleLayoutInfos){
|
|
38
|
+
if (!layoutInfo || !isAnchorable(layoutInfo)) continue;
|
|
39
|
+
let overlap = layoutInfo.rect.intersection(visibleRect)[dimension];
|
|
40
|
+
if (layoutInfo.rect.area > 0 && overlap >= $78014f4785404d8e$var$MIN_ANCHOR_OVERLAP) {
|
|
41
|
+
let corner = layoutInfo.rect.getCornerInRect(visibleRect) ?? 'topLeft';
|
|
42
|
+
let offset = layoutInfo.rect[corner][axis] - visibleRect[axis];
|
|
43
|
+
let isBetter = !best || (edge === 'end' ? offset < best.offset : offset > best.offset);
|
|
44
|
+
if (isBetter) best = {
|
|
45
|
+
key: key,
|
|
46
|
+
corner: corner,
|
|
47
|
+
offset: offset
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return best;
|
|
52
|
+
}
|
|
53
|
+
function $78014f4785404d8e$export$c74597e403428eac(edge, axis, contentSize, previousVisibleRect) {
|
|
54
|
+
if (edge === 'start') return 0;
|
|
55
|
+
let dimension = $78014f4785404d8e$var$dimensionForAxis(axis);
|
|
56
|
+
return Math.max(0, contentSize[dimension] - previousVisibleRect[dimension]);
|
|
57
|
+
}
|
|
58
|
+
function $78014f4785404d8e$export$f644bffd4937530e(visibleRect, contentSize, edge, axis, threshold) {
|
|
59
|
+
if (edge === 'start') return visibleRect[axis] <= threshold;
|
|
60
|
+
let dimension = $78014f4785404d8e$var$dimensionForAxis(axis);
|
|
61
|
+
let distanceFromEnd = contentSize[dimension] - (visibleRect[axis] + visibleRect[dimension]);
|
|
62
|
+
return distanceFromEnd <= threshold;
|
|
63
|
+
}
|
|
64
|
+
function $78014f4785404d8e$export$dcb80b718ca193d7(edge, axis, anchor, wasNearAnchorEdge, isScrolling, itemSizeChanged, contentSizeDelta, getLayoutInfo, previousVisibleRect, contentSize) {
|
|
65
|
+
let withTarget = (target)=>axis === 'x' ? new (0, $af827553fd3cf456$export$c79fc6492f3af13d)(target, previousVisibleRect.y, previousVisibleRect.width, previousVisibleRect.height) : new (0, $af827553fd3cf456$export$c79fc6492f3af13d)(previousVisibleRect.x, target, previousVisibleRect.width, previousVisibleRect.height);
|
|
66
|
+
if (anchor) {
|
|
67
|
+
let target = $78014f4785404d8e$export$413719533c5919c9(anchor, axis, getLayoutInfo, previousVisibleRect, contentSize);
|
|
68
|
+
if (target != null) return withTarget(target);
|
|
69
|
+
}
|
|
70
|
+
if (wasNearAnchorEdge && !isScrolling && (!itemSizeChanged || contentSizeDelta > 0)) {
|
|
71
|
+
let target = withTarget($78014f4785404d8e$export$c74597e403428eac(edge, axis, contentSize, previousVisibleRect));
|
|
72
|
+
return target.equals(previousVisibleRect) ? null : target;
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
class $78014f4785404d8e$export$8ce0fdedc36cb6b {
|
|
77
|
+
/** Resets all tracked state, e.g. when the virtualizer's layout instance changes. */ reset() {
|
|
78
|
+
this.hasSnappedToEdge = false;
|
|
79
|
+
this.hadEstimatedVisibleItems = false;
|
|
80
|
+
this.wasNearAnchorEdge = false;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Captures the anchor from pre-layout view positions.
|
|
84
|
+
*/ captureBeforeLayout(anchorInfo, preLayoutInfos, visibleRect) {
|
|
85
|
+
if (!anchorInfo) return null;
|
|
86
|
+
return $78014f4785404d8e$export$69fb4c6de5f339b7(anchorInfo.edge, anchorInfo.axis, visibleRect, preLayoutInfos, anchorInfo.isAnchorable);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Runs the full post-layout decision: updates the tracked state for the next pass, and
|
|
90
|
+
* returns the resolved scroll target, or null if nothing should change.
|
|
91
|
+
*/ resolveAfterLayout(options) {
|
|
92
|
+
let { anchorInfo: anchorInfo, anchor: anchor, postLayoutInfos: postLayoutInfos, previousVisibleRect: previousVisibleRect, previousContentSize: previousContentSize, contentSize: contentSize, itemSizeChanged: itemSizeChanged, isScrolling: isScrolling, getLayoutInfo: getLayoutInfo } = options;
|
|
93
|
+
if (!anchorInfo) return null;
|
|
94
|
+
// Read the previous pass's state into locals before any writes below overwrite it.
|
|
95
|
+
let wasSettlingLastPass = this.hadEstimatedVisibleItems;
|
|
96
|
+
let wasNearAnchorEdgeLastPass = this.wasNearAnchorEdge;
|
|
97
|
+
let hasEstimated = false;
|
|
98
|
+
for (let layoutInfo of postLayoutInfos.values())if (layoutInfo.estimatedSize) {
|
|
99
|
+
hasEstimated = true;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
this.hadEstimatedVisibleItems = hasEstimated;
|
|
103
|
+
// Don't recheck "near edge?" mid-resize because it could look like a scroll that never happened.
|
|
104
|
+
// Reuse the answer from before the resizing started.
|
|
105
|
+
if (!wasSettlingLastPass) this.wasNearAnchorEdge = $78014f4785404d8e$export$f644bffd4937530e(previousVisibleRect, previousContentSize, anchorInfo.edge, anchorInfo.axis, anchorInfo.threshold);
|
|
106
|
+
if (previousVisibleRect.area === 0) return null;
|
|
107
|
+
let dimension = anchorInfo.axis === 'x' ? 'width' : 'height';
|
|
108
|
+
let contentSizeDelta = contentSize[dimension] - previousContentSize[dimension];
|
|
109
|
+
let isFirstAnchoredLayout = !this.hasSnappedToEdge;
|
|
110
|
+
this.hasSnappedToEdge = true;
|
|
111
|
+
// Only modify scroll when content actually changed (or this is the first layout, which always snaps)
|
|
112
|
+
if (!(isFirstAnchoredLayout || contentSizeDelta !== 0 || itemSizeChanged)) return null;
|
|
113
|
+
let wasNearAnchorEdge = isFirstAnchoredLayout || wasSettlingLastPass && wasNearAnchorEdgeLastPass || $78014f4785404d8e$export$f644bffd4937530e(previousVisibleRect, previousContentSize, anchorInfo.edge, anchorInfo.axis, anchorInfo.threshold);
|
|
114
|
+
// A first-ever layout always snaps to the edge, even if the raw distance check says
|
|
115
|
+
// otherwise. Save that real decision here so later passes in this cascade reuse it.
|
|
116
|
+
if (!wasSettlingLastPass) this.wasNearAnchorEdge = wasNearAnchorEdge;
|
|
117
|
+
// Skip restoring to the captured anchor while still resizing because items above it are also still growing,
|
|
118
|
+
// and following it would fall short of the edge.
|
|
119
|
+
let effectiveAnchor = isFirstAnchoredLayout || wasSettlingLastPass && wasNearAnchorEdgeLastPass ? null : anchor;
|
|
120
|
+
return $78014f4785404d8e$export$dcb80b718ca193d7(anchorInfo.edge, anchorInfo.axis, effectiveAnchor, wasNearAnchorEdge, isScrolling, itemSizeChanged, contentSizeDelta, getLayoutInfo, previousVisibleRect, contentSize);
|
|
121
|
+
}
|
|
122
|
+
constructor(){
|
|
123
|
+
this.hasSnappedToEdge = false;
|
|
124
|
+
this.hadEstimatedVisibleItems = false;
|
|
125
|
+
this.wasNearAnchorEdge = false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
export {$78014f4785404d8e$export$413719533c5919c9 as computeScrollAnchorTarget, $78014f4785404d8e$export$69fb4c6de5f339b7 as captureScrollAnchor, $78014f4785404d8e$export$c74597e403428eac as getEdgeSnapTarget, $78014f4785404d8e$export$f644bffd4937530e as isNearEdge, $78014f4785404d8e$export$dcb80b718ca193d7 as resolveScrollAdjustment, $78014f4785404d8e$export$8ce0fdedc36cb6b as ScrollAnchorTracker};
|
|
131
|
+
//# sourceMappingURL=ScrollAnchor.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["packages/react-stately/src/virtualizer/ScrollAnchor.ts"],"sourcesContent":["/*\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Key} from '@react-types/shared';\nimport {LayoutInfo} from './LayoutInfo';\nimport {Rect, RectCorner} from './Rect';\nimport {Size} from './Size';\n\nexport type ScrollAnchorAxis = 'x' | 'y';\nexport type ScrollAnchorEdge = 'start' | 'end';\nexport interface ScrollAnchor {\n key: Key;\n corner: RectCorner;\n offset: number;\n}\n\nexport interface ScrollAnchorInfo {\n /** Which edge of the content the viewport should stay anchored to. */\n edge: 'start' | 'end';\n /** Which axis `edge` refers to — 'y' for vertical lists, 'x' for horizontal. */\n axis: 'x' | 'y';\n /** Distance (px) from `edge` within which the viewport is considered \"following\" it. */\n threshold: number;\n /**\n * Optional classifier excluding structural/ephemeral layout infos (e.g. loaders) from being\n * selected as the anchor. Defaults to allowing any layoutInfo.\n */\n isAnchorable?: (layoutInfo: LayoutInfo) => boolean;\n}\n\n/**\n * Minimum overlap an item must have with the viewport, along the scroll axis,\n * to be eligible as a scroll anchor. Without this, an item that only overlaps the viewport\n * by a sliver (e.g. 1px, essentially scrolled out of view) can still \"win\" the anchor\n * tie-break over a substantially visible item.\n */\nconst MIN_ANCHOR_OVERLAP = 4;\n\nfunction dimensionForAxis(axis: ScrollAnchorAxis): 'width' | 'height' {\n return axis === 'x' ? 'width' : 'height';\n}\n\n/**\n * Given a previously-captured anchor, computes the new viewport coordinate (along `axis`) needed\n * to keep it at the same offset from the viewport's start.\n */\nexport function computeScrollAnchorTarget(\n anchor: ScrollAnchor,\n axis: ScrollAnchorAxis,\n getLayoutInfo: (key: Key) => LayoutInfo | null,\n visibleRect: Rect,\n contentSize: Size\n): number | null {\n let finalInfo = getLayoutInfo(anchor.key);\n if (!finalInfo) {\n return null;\n }\n let adjustment = finalInfo.rect[anchor.corner][axis] - visibleRect[axis] - anchor.offset;\n if (adjustment === 0) {\n return null;\n }\n let target = visibleRect[axis] + adjustment;\n let dimension = dimensionForAxis(axis);\n let max = Math.max(0, contentSize[dimension] - visibleRect[dimension]);\n let clamped = Math.max(0, Math.min(max, target));\n return clamped !== visibleRect[axis] ? clamped : null;\n}\n\n/**\n * Picks the item to anchor scroll to: the one nearest the top of the viewport when\n * anchoring to 'end', or nearest the bottom when anchoring to 'start'. Callers can\n * exclude certain items (like loaders) with `isAnchorable`.\n */\nexport function captureScrollAnchor(\n edge: ScrollAnchorEdge,\n axis: ScrollAnchorAxis,\n visibleRect: Rect,\n visibleLayoutInfos: Iterable<[Key, LayoutInfo]>,\n isAnchorable: (layoutInfo: LayoutInfo) => boolean = () => true\n): ScrollAnchor | null {\n let dimension = dimensionForAxis(axis);\n let best: ScrollAnchor | null = null;\n for (let [key, layoutInfo] of visibleLayoutInfos) {\n if (!layoutInfo || !isAnchorable(layoutInfo)) {\n continue;\n }\n let overlap = layoutInfo.rect.intersection(visibleRect)[dimension];\n if (layoutInfo.rect.area > 0 && overlap >= MIN_ANCHOR_OVERLAP) {\n let corner = layoutInfo.rect.getCornerInRect(visibleRect) ?? 'topLeft';\n let offset = layoutInfo.rect[corner][axis] - visibleRect[axis];\n let isBetter = !best || (edge === 'end' ? offset < best.offset : offset > best.offset);\n if (isBetter) {\n best = {key, corner, offset};\n }\n }\n }\n return best;\n}\n\n/** Returns the viewport coordinate (along `axis`) that pins the viewport to `edge` of the content. */\nexport function getEdgeSnapTarget(\n edge: ScrollAnchorEdge,\n axis: ScrollAnchorAxis,\n contentSize: Size,\n previousVisibleRect: Rect\n): number {\n if (edge === 'start') {\n return 0;\n }\n let dimension = dimensionForAxis(axis);\n return Math.max(0, contentSize[dimension] - previousVisibleRect[dimension]);\n}\n\n/**\n * Whether the viewport is currently within `threshold` px of the anchored edge — used by\n * Virtualizer to compute wasNearAnchorEdge generically, without any layout-specific state.\n */\nexport function isNearEdge(\n visibleRect: Rect,\n contentSize: Size,\n edge: ScrollAnchorEdge,\n axis: ScrollAnchorAxis,\n threshold: number\n): boolean {\n if (edge === 'start') {\n return visibleRect[axis] <= threshold;\n }\n let dimension = dimensionForAxis(axis);\n let distanceFromEnd = contentSize[dimension] - (visibleRect[axis] + visibleRect[dimension]);\n return distanceFromEnd <= threshold;\n}\n\n/**\n * Works out the new scroll position after content changes. Tries to keep the anchor\n * item where it was. If that doesn't apply, sticks the view to the edge instead, but\n * only if the user was already near the edge and didn't just scroll away on their own.\n */\nexport function resolveScrollAdjustment(\n edge: ScrollAnchorEdge,\n axis: ScrollAnchorAxis,\n anchor: ScrollAnchor | null,\n wasNearAnchorEdge: boolean,\n isScrolling: boolean,\n itemSizeChanged: boolean,\n contentSizeDelta: number,\n getLayoutInfo: (key: Key) => LayoutInfo | null,\n previousVisibleRect: Rect,\n contentSize: Size\n): Rect | null {\n let withTarget = (target: number): Rect =>\n axis === 'x'\n ? new Rect(\n target,\n previousVisibleRect.y,\n previousVisibleRect.width,\n previousVisibleRect.height\n )\n : new Rect(\n previousVisibleRect.x,\n target,\n previousVisibleRect.width,\n previousVisibleRect.height\n );\n\n if (anchor) {\n let target = computeScrollAnchorTarget(\n anchor,\n axis,\n getLayoutInfo,\n previousVisibleRect,\n contentSize\n );\n if (target != null) {\n return withTarget(target);\n }\n }\n\n if (wasNearAnchorEdge && !isScrolling && (!itemSizeChanged || contentSizeDelta > 0)) {\n let target = withTarget(getEdgeSnapTarget(edge, axis, contentSize, previousVisibleRect));\n return target.equals(previousVisibleRect) ? null : target;\n }\n\n return null;\n}\n\nexport interface ResolveAfterLayoutOptions {\n anchorInfo: ScrollAnchorInfo | null;\n /** The anchor captured by `captureBeforeLayout` before this pass's `layout.update()` ran. */\n anchor: ScrollAnchor | null;\n /** The full post-layout visible layout infos, i.e. `virtualizer.getVisibleLayoutInfos()`. */\n postLayoutInfos: Map<Key, LayoutInfo>;\n previousVisibleRect: Rect;\n previousContentSize: Size;\n contentSize: Size;\n itemSizeChanged: boolean;\n isScrolling: boolean;\n getLayoutInfo: (key: Key) => LayoutInfo | null;\n}\n\n/**\n * Tracks the cross-pass state needed to keep the viewport anchored to a layout's edge across\n * relayouts.\n */\nexport class ScrollAnchorTracker {\n private hasSnappedToEdge = false;\n private hadEstimatedVisibleItems = false;\n private wasNearAnchorEdge = false;\n\n /** Resets all tracked state, e.g. when the virtualizer's layout instance changes. */\n reset(): void {\n this.hasSnappedToEdge = false;\n this.hadEstimatedVisibleItems = false;\n this.wasNearAnchorEdge = false;\n }\n\n /**\n * Captures the anchor from pre-layout view positions.\n */\n captureBeforeLayout(\n anchorInfo: ScrollAnchorInfo | null,\n preLayoutInfos: Iterable<[Key, LayoutInfo]>,\n visibleRect: Rect\n ): ScrollAnchor | null {\n if (!anchorInfo) {\n return null;\n }\n return captureScrollAnchor(\n anchorInfo.edge,\n anchorInfo.axis,\n visibleRect,\n preLayoutInfos,\n anchorInfo.isAnchorable\n );\n }\n\n /**\n * Runs the full post-layout decision: updates the tracked state for the next pass, and\n * returns the resolved scroll target, or null if nothing should change.\n */\n resolveAfterLayout(options: ResolveAfterLayoutOptions): Rect | null {\n let {\n anchorInfo,\n anchor,\n postLayoutInfos,\n previousVisibleRect,\n previousContentSize,\n contentSize,\n itemSizeChanged,\n isScrolling,\n getLayoutInfo\n } = options;\n\n if (!anchorInfo) {\n return null;\n }\n\n // Read the previous pass's state into locals before any writes below overwrite it.\n let wasSettlingLastPass = this.hadEstimatedVisibleItems;\n let wasNearAnchorEdgeLastPass = this.wasNearAnchorEdge;\n\n let hasEstimated = false;\n for (let layoutInfo of postLayoutInfos.values()) {\n if (layoutInfo.estimatedSize) {\n hasEstimated = true;\n break;\n }\n }\n this.hadEstimatedVisibleItems = hasEstimated;\n // Don't recheck \"near edge?\" mid-resize because it could look like a scroll that never happened.\n // Reuse the answer from before the resizing started.\n if (!wasSettlingLastPass) {\n this.wasNearAnchorEdge = isNearEdge(\n previousVisibleRect,\n previousContentSize,\n anchorInfo.edge,\n anchorInfo.axis,\n anchorInfo.threshold\n );\n }\n\n if (previousVisibleRect.area === 0) {\n return null;\n }\n\n let dimension = anchorInfo.axis === 'x' ? 'width' : 'height';\n let contentSizeDelta = contentSize[dimension] - previousContentSize[dimension];\n let isFirstAnchoredLayout = !this.hasSnappedToEdge;\n this.hasSnappedToEdge = true;\n\n // Only modify scroll when content actually changed (or this is the first layout, which always snaps)\n if (!(isFirstAnchoredLayout || contentSizeDelta !== 0 || itemSizeChanged)) {\n return null;\n }\n\n let wasNearAnchorEdge =\n isFirstAnchoredLayout ||\n (wasSettlingLastPass && wasNearAnchorEdgeLastPass) ||\n isNearEdge(\n previousVisibleRect,\n previousContentSize,\n anchorInfo.edge,\n anchorInfo.axis,\n anchorInfo.threshold\n );\n // A first-ever layout always snaps to the edge, even if the raw distance check says\n // otherwise. Save that real decision here so later passes in this cascade reuse it.\n if (!wasSettlingLastPass) {\n this.wasNearAnchorEdge = wasNearAnchorEdge;\n }\n // Skip restoring to the captured anchor while still resizing because items above it are also still growing,\n // and following it would fall short of the edge.\n let effectiveAnchor =\n isFirstAnchoredLayout || (wasSettlingLastPass && wasNearAnchorEdgeLastPass) ? null : anchor;\n return resolveScrollAdjustment(\n anchorInfo.edge,\n anchorInfo.axis,\n effectiveAnchor,\n wasNearAnchorEdge,\n isScrolling,\n itemSizeChanged,\n contentSizeDelta,\n getLayoutInfo,\n previousVisibleRect,\n contentSize\n );\n }\n}\n"],"names":[],"version":3,"file":"ScrollAnchor.mjs.map"}
|
|
@@ -2,6 +2,7 @@ var $c7afcf057887556c$exports = require("./ReusableView.cjs");
|
|
|
2
2
|
var $0ef96a3bce5c0b0e$exports = require("./utils.cjs");
|
|
3
3
|
var $2e81872088c084c8$exports = require("./OverscanManager.cjs");
|
|
4
4
|
var $2bdd626d0eea82c5$exports = require("./Rect.cjs");
|
|
5
|
+
var $e06c1e621ca9099b$exports = require("./ScrollAnchor.cjs");
|
|
5
6
|
var $f9c934dfa703bb0a$exports = require("./Size.cjs");
|
|
6
7
|
|
|
7
8
|
|
|
@@ -25,6 +26,7 @@ $parcel$export(module.exports, "Virtualizer", function () { return $c3448b396b9a
|
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
|
|
29
|
+
|
|
28
30
|
class $c3448b396b9ae7a2$export$89be5a243e59c4b2 {
|
|
29
31
|
constructor(options){
|
|
30
32
|
this.delegate = options.delegate;
|
|
@@ -40,6 +42,7 @@ class $c3448b396b9ae7a2$export$89be5a243e59c4b2 {
|
|
|
40
42
|
this._isScrolling = false;
|
|
41
43
|
this._invalidationContext = {};
|
|
42
44
|
this._overscanManager = new (0, $2e81872088c084c8$exports.OverscanManager)();
|
|
45
|
+
this._scrollAnchor = new (0, $e06c1e621ca9099b$exports.ScrollAnchorTracker)();
|
|
43
46
|
}
|
|
44
47
|
/** Returns whether the given key, or an ancestor, is persisted. */ isPersistedKey(key) {
|
|
45
48
|
// Quick check if the key is directly in the set of persisted keys.
|
|
@@ -90,9 +93,46 @@ class $c3448b396b9ae7a2$export$89be5a243e59c4b2 {
|
|
|
90
93
|
return null;
|
|
91
94
|
}
|
|
92
95
|
relayout(context = {}) {
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
let anchorInfo = this.layout.UNSTABLE_getScrollAnchorInfo?.(context.layoutOptions) ?? null;
|
|
98
|
+
// Capture scroll anchor from current (pre-layout) view positions.
|
|
99
|
+
// On first render _visibleViews is empty so no anchor will be found.
|
|
100
|
+
let anchor = null;
|
|
101
|
+
if (anchorInfo) {
|
|
102
|
+
let preLayoutInfos = [];
|
|
103
|
+
for (let [key, view] of this._visibleViews){
|
|
104
|
+
let layoutInfo = this.layout.getLayoutInfo(key) ?? view.layoutInfo;
|
|
105
|
+
if (layoutInfo) preLayoutInfos.push([
|
|
106
|
+
key,
|
|
107
|
+
layoutInfo
|
|
108
|
+
]);
|
|
109
|
+
}
|
|
110
|
+
anchor = this._scrollAnchor.captureBeforeLayout(anchorInfo, preLayoutInfos, this.visibleRect);
|
|
111
|
+
}
|
|
112
|
+
let previousContentSize = this.contentSize;
|
|
113
|
+
let previousVisibleRect = this.visibleRect;
|
|
93
114
|
// Update the layout
|
|
94
115
|
this.layout.update(context);
|
|
95
|
-
|
|
116
|
+
let rawContentSize = this.layout.getContentSize();
|
|
117
|
+
this.contentSize = new (0, $f9c934dfa703bb0a$exports.Size)(rawContentSize.width, rawContentSize.height);
|
|
118
|
+
let target = this._scrollAnchor.resolveAfterLayout({
|
|
119
|
+
anchorInfo: anchorInfo,
|
|
120
|
+
anchor: anchor,
|
|
121
|
+
postLayoutInfos: anchorInfo ? this.getVisibleLayoutInfos() : new Map(),
|
|
122
|
+
previousVisibleRect: previousVisibleRect,
|
|
123
|
+
previousContentSize: previousContentSize,
|
|
124
|
+
contentSize: this.contentSize,
|
|
125
|
+
itemSizeChanged: context.itemSizeChanged ?? false,
|
|
126
|
+
isScrolling: this._isScrolling,
|
|
127
|
+
getLayoutInfo: (key)=>this.layout.getLayoutInfo(key)
|
|
128
|
+
});
|
|
129
|
+
if (target) {
|
|
130
|
+
// Queues a new render cycle. Return early to skip updateSubviews — running it now
|
|
131
|
+
// would position views against the old visibleRect, causing a flash before the
|
|
132
|
+
// incoming relayout corrects them.
|
|
133
|
+
this.delegate.setVisibleRect(target);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
96
136
|
// Constrain scroll position.
|
|
97
137
|
// If the content changed, scroll to the top.
|
|
98
138
|
let visibleRect = this.visibleRect;
|
|
@@ -169,6 +209,8 @@ class $c3448b396b9ae7a2$export$89be5a243e59c4b2 {
|
|
|
169
209
|
let needsLayout = false;
|
|
170
210
|
let offsetChanged = false;
|
|
171
211
|
let sizeChanged = false;
|
|
212
|
+
let widthChanged = false;
|
|
213
|
+
let heightChanged = false;
|
|
172
214
|
let itemSizeChanged = false;
|
|
173
215
|
let layoutOptionsChanged = false;
|
|
174
216
|
let needsUpdate = false;
|
|
@@ -180,6 +222,7 @@ class $c3448b396b9ae7a2$export$89be5a243e59c4b2 {
|
|
|
180
222
|
if (this.layout) this.layout.virtualizer = null;
|
|
181
223
|
opts.layout.virtualizer = this;
|
|
182
224
|
mutableThis.layout = opts.layout;
|
|
225
|
+
this._scrollAnchor.reset();
|
|
183
226
|
needsLayout = true;
|
|
184
227
|
}
|
|
185
228
|
if (opts.persistedKeys && !(0, $0ef96a3bce5c0b0e$exports.isSetEqual)(opts.persistedKeys, this.persistedKeys)) {
|
|
@@ -196,6 +239,8 @@ class $c3448b396b9ae7a2$export$89be5a243e59c4b2 {
|
|
|
196
239
|
if (shouldInvalidate) {
|
|
197
240
|
offsetChanged = !opts.visibleRect.pointEquals(this.visibleRect);
|
|
198
241
|
sizeChanged = !this.size.equals(opts.size);
|
|
242
|
+
widthChanged = this.size.width !== opts.size.width;
|
|
243
|
+
heightChanged = this.size.height !== opts.size.height;
|
|
199
244
|
needsLayout = true;
|
|
200
245
|
} else needsUpdate = true;
|
|
201
246
|
mutableThis.visibleRect = opts.visibleRect;
|
|
@@ -204,6 +249,8 @@ class $c3448b396b9ae7a2$export$89be5a243e59c4b2 {
|
|
|
204
249
|
if (opts.invalidationContext !== this._invalidationContext) {
|
|
205
250
|
if (opts.invalidationContext) {
|
|
206
251
|
sizeChanged ||= opts.invalidationContext.sizeChanged || false;
|
|
252
|
+
widthChanged ||= opts.invalidationContext.widthChanged || false;
|
|
253
|
+
heightChanged ||= opts.invalidationContext.heightChanged || false;
|
|
207
254
|
offsetChanged ||= opts.invalidationContext.offsetChanged || false;
|
|
208
255
|
itemSizeChanged ||= opts.invalidationContext.itemSizeChanged || false;
|
|
209
256
|
layoutOptionsChanged ||= opts.invalidationContext.layoutOptions != null && this._invalidationContext.layoutOptions != null && opts.invalidationContext.layoutOptions !== this._invalidationContext.layoutOptions && this.layout.shouldInvalidateLayoutOptions(opts.invalidationContext.layoutOptions, this._invalidationContext.layoutOptions);
|
|
@@ -219,6 +266,8 @@ class $c3448b396b9ae7a2$export$89be5a243e59c4b2 {
|
|
|
219
266
|
if (needsLayout) this.relayout({
|
|
220
267
|
offsetChanged: offsetChanged,
|
|
221
268
|
sizeChanged: sizeChanged,
|
|
269
|
+
widthChanged: widthChanged,
|
|
270
|
+
heightChanged: heightChanged,
|
|
222
271
|
itemSizeChanged: itemSizeChanged,
|
|
223
272
|
layoutOptionsChanged: layoutOptionsChanged,
|
|
224
273
|
layoutOptions: this._invalidationContext.layoutOptions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["packages/react-stately/src/virtualizer/Virtualizer.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {ChildView, ReusableView, RootView} from './ReusableView';\nimport {Collection, Key} from '@react-types/shared';\nimport {InvalidationContext, Mutable, VirtualizerDelegate, VirtualizerRenderOptions} from './types';\nimport {isSetEqual} from './utils';\nimport {Layout} from './Layout';\nimport {LayoutInfo} from './LayoutInfo';\nimport {OverscanManager} from './OverscanManager';\nimport {Point} from './Point';\nimport {Rect} from './Rect';\nimport {Size} from './Size';\n\ninterface VirtualizerOptions<T extends object, V> {\n delegate: VirtualizerDelegate<T, V>;\n collection: Collection<T>;\n layout: Layout<T>;\n}\n\n/**\n * The Virtualizer class renders a scrollable collection of data using customizable layouts.\n * It supports very large collections by only rendering visible views to the DOM, reusing\n * them as you scroll. Virtualizer can present any type of view, including non-item views\n * such as section headers and footers.\n *\n * Virtualizer uses `Layout` objects to compute what views should be visible, and how\n * to position and style them. This means that virtualizer can have its items arranged in\n * a stack, a grid, a circle, or any other layout you can think of. The layout can be changed\n * dynamically at runtime as well.\n *\n * Layouts produce information on what views should appear in the virtualizer, but do not create the\n * views themselves directly. It is the responsibility of the `VirtualizerDelegate` object to render\n * elements for each layout info. The virtualizer manages a set of `ReusableView` objects, which are\n * reused as the user scrolls by swapping their content with cached elements returned by the\n * delegate.\n */\nexport class Virtualizer<T extends object, V> {\n /**\n * The virtualizer delegate. The delegate is used by the virtualizer\n * to create and configure views.\n */\n delegate: VirtualizerDelegate<T, V>;\n\n /** The current content of the virtualizer. */\n readonly collection: Collection<T>;\n /** The layout object that determines the visible views. */\n readonly layout: Layout<T>;\n /** The size of the scrollable content. */\n readonly contentSize: Size;\n /** The currently visible rectangle. */\n readonly visibleRect: Rect;\n /** The size of the virtualizer scroll view. */\n readonly size: Size;\n /** The set of persisted keys that are always present in the DOM, even if not currently in view. */\n readonly persistedKeys: Set<Key>;\n\n private _visibleViews: Map<Key, ChildView<T, V>>;\n private _renderedContent: WeakMap<T, V>;\n private _rootView: RootView<T, V>;\n private _isScrolling: boolean;\n private _invalidationContext: InvalidationContext;\n private _overscanManager: OverscanManager;\n\n constructor(options: VirtualizerOptions<T, V>) {\n this.delegate = options.delegate;\n this.collection = options.collection;\n this.layout = options.layout;\n this.contentSize = new Size();\n this.visibleRect = new Rect();\n this.size = new Size();\n this.persistedKeys = new Set();\n this._visibleViews = new Map();\n this._renderedContent = new WeakMap();\n this._rootView = new RootView(this);\n this._isScrolling = false;\n this._invalidationContext = {};\n this._overscanManager = new OverscanManager();\n }\n\n /** Returns whether the given key, or an ancestor, is persisted. */\n isPersistedKey(key: Key): boolean {\n // Quick check if the key is directly in the set of persisted keys.\n if (this.persistedKeys.has(key)) {\n return true;\n }\n\n // If not, check if the key is an ancestor of any of the persisted keys.\n for (let k of this.persistedKeys) {\n while (k != null) {\n let layoutInfo = this.layout.getLayoutInfo(k);\n if (!layoutInfo || layoutInfo.parentKey == null) {\n break;\n }\n\n k = layoutInfo.parentKey;\n\n if (k === key) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n private getParentView(layoutInfo: LayoutInfo): ReusableView<T, V> | undefined {\n return layoutInfo.parentKey != null\n ? this._visibleViews.get(layoutInfo.parentKey)\n : this._rootView;\n }\n\n private getReusableView(layoutInfo: LayoutInfo): ChildView<T, V> {\n let parentView = this.getParentView(layoutInfo)!;\n let view = parentView.getReusableView(layoutInfo.type);\n view.layoutInfo = layoutInfo;\n this._renderView(view);\n return view;\n }\n\n private _renderView(reusableView: ReusableView<T, V>) {\n if (reusableView.layoutInfo) {\n let {type, key, content} = reusableView.layoutInfo;\n reusableView.content = content || this.collection.getItem(key);\n reusableView.rendered = this._renderContent(type, reusableView.content);\n }\n }\n\n private _renderContent(type: string, content: T | null) {\n let cached = content != null ? this._renderedContent.get(content) : null;\n if (cached != null) {\n return cached;\n }\n\n let rendered = this.delegate.renderView(type, content);\n if (content) {\n this._renderedContent.set(content, rendered);\n }\n return rendered;\n }\n\n /**\n * Returns the key for the item view currently at the given point.\n */\n keyAtPoint(point: Point): Key | null {\n let rect = new Rect(point.x, point.y, 1, 1);\n let layoutInfos = rect.area === 0 ? [] : this.layout.getVisibleLayoutInfos(rect);\n\n // Layout may return multiple layout infos in the case of\n // persisted keys, so find the first one that actually intersects.\n for (let layoutInfo of layoutInfos) {\n if (layoutInfo.rect.intersects(rect)) {\n return layoutInfo.key;\n }\n }\n\n return null;\n }\n\n private relayout(context: InvalidationContext = {}) {\n // Update the layout\n this.layout.update(context);\n (this as Mutable<this>).contentSize = this.layout.getContentSize();\n\n // Constrain scroll position.\n // If the content changed, scroll to the top.\n let visibleRect = this.visibleRect;\n let contentOffsetX = context.contentChanged ? 0 : visibleRect.x;\n let contentOffsetY = context.contentChanged ? 0 : visibleRect.y;\n contentOffsetX = Math.max(\n 0,\n Math.min(this.contentSize.width - visibleRect.width, contentOffsetX)\n );\n contentOffsetY = Math.max(\n 0,\n Math.min(this.contentSize.height - visibleRect.height, contentOffsetY)\n );\n\n if (contentOffsetX !== visibleRect.x || contentOffsetY !== visibleRect.y) {\n // If the offset changed, trigger a new re-render.\n let rect = new Rect(contentOffsetX, contentOffsetY, visibleRect.width, visibleRect.height);\n this.delegate.setVisibleRect(rect);\n } else {\n this.updateSubviews();\n }\n }\n\n getVisibleLayoutInfos(): Map<Key, LayoutInfo> {\n let isTestEnv = process.env.NODE_ENV === 'test' && !process.env.VIRT_ON;\n let isClientWidthMocked =\n isTestEnv &&\n typeof HTMLElement !== 'undefined' &&\n Object.getOwnPropertyNames(HTMLElement.prototype).includes('clientWidth');\n let isClientHeightMocked =\n isTestEnv &&\n typeof HTMLElement !== 'undefined' &&\n Object.getOwnPropertyNames(HTMLElement.prototype).includes('clientHeight');\n\n let rect: Rect;\n if (isTestEnv && !(isClientWidthMocked && isClientHeightMocked)) {\n rect = new Rect(0, 0, this.contentSize.width, this.contentSize.height);\n } else {\n rect = this._overscanManager.getOverscannedRect();\n }\n let layoutInfos = this.layout.getVisibleLayoutInfos(rect);\n let map = new Map();\n for (let layoutInfo of layoutInfos) {\n map.set(layoutInfo.key, layoutInfo);\n }\n\n return map;\n }\n\n private updateSubviews() {\n let visibleLayoutInfos = this.getVisibleLayoutInfos();\n\n let removed = new Set<ChildView<T, V>>();\n for (let [key, view] of this._visibleViews) {\n let layoutInfo = visibleLayoutInfos.get(key);\n // If a view's parent changed, treat it as a delete and re-create in the new parent.\n if (!layoutInfo || view.parent !== this.getParentView(layoutInfo)) {\n this._visibleViews.delete(key);\n view.parent.reuseChild(view);\n removed.add(view); // Defer removing in case we reuse this view.\n }\n }\n\n for (let [key, layoutInfo] of visibleLayoutInfos) {\n let view = this._visibleViews.get(key);\n if (!view) {\n view = this.getReusableView(layoutInfo);\n view.parent.children.add(view);\n this._visibleViews.set(key, view);\n removed.delete(view);\n } else {\n view.layoutInfo = layoutInfo;\n\n let item = this.collection.getItem(layoutInfo.key);\n if (view.content !== item) {\n if (view.content != null) {\n this._renderedContent.delete(view.content);\n }\n this._renderView(view);\n }\n }\n }\n\n // The remaining views in `removed` were not reused to render new items.\n // They should be removed from the DOM. We also clear the reusable view queue\n // here since there's no point holding onto views that have been removed.\n // Doing so hurts performance in the future when reusing elements due to FIFO order.\n for (let view of removed) {\n view.parent.children.delete(view);\n view.parent.reusableViews.clear();\n }\n\n // Reordering DOM nodes is costly, so we defer this until scrolling stops.\n // DOM order does not affect visual order (due to absolute positioning),\n // but does matter for assistive technology users.\n if (!this._isScrolling) {\n // Layout infos must be in topological order (parents before children).\n for (let key of visibleLayoutInfos.keys()) {\n let view = this._visibleViews.get(key)!;\n view.parent.children.delete(view);\n view.parent.children.add(view);\n }\n }\n }\n\n /** Performs layout and updates visible views as needed. */\n render(opts: VirtualizerRenderOptions<T>): ReusableView<T, V>[] {\n let mutableThis: Mutable<this> = this;\n let needsLayout = false;\n let offsetChanged = false;\n let sizeChanged = false;\n let itemSizeChanged = false;\n let layoutOptionsChanged = false;\n let needsUpdate = false;\n\n if (opts.collection !== this.collection) {\n mutableThis.collection = opts.collection;\n needsLayout = true;\n }\n\n if (opts.layout !== this.layout || this.layout.virtualizer !== this) {\n if (this.layout) {\n this.layout.virtualizer = null;\n }\n\n opts.layout.virtualizer = this;\n mutableThis.layout = opts.layout;\n needsLayout = true;\n }\n\n if (opts.persistedKeys && !isSetEqual(opts.persistedKeys, this.persistedKeys)) {\n mutableThis.persistedKeys = opts.persistedKeys;\n needsUpdate = true;\n }\n\n if (!this.visibleRect.equals(opts.visibleRect) || !this.size.equals(opts.size)) {\n this._overscanManager.setVisibleRect(opts.visibleRect);\n\n // Create a rectangle using the scroll position and layout size of the scroll view. This is not the same\n // as the visibleRect, whose width and height may change during window scrolling.\n let oldRect = new Rect(\n this.visibleRect.x,\n this.visibleRect.y,\n this.size.width,\n this.size.height\n );\n let newRect = new Rect(\n opts.visibleRect.x,\n opts.visibleRect.y,\n opts.size.width,\n opts.size.height\n );\n let shouldInvalidate = this.layout.shouldInvalidate(newRect, oldRect);\n\n if (shouldInvalidate) {\n offsetChanged = !opts.visibleRect.pointEquals(this.visibleRect);\n sizeChanged = !this.size.equals(opts.size);\n needsLayout = true;\n } else {\n needsUpdate = true;\n }\n\n mutableThis.visibleRect = opts.visibleRect;\n mutableThis.size = opts.size;\n }\n\n if (opts.invalidationContext !== this._invalidationContext) {\n if (opts.invalidationContext) {\n sizeChanged ||= opts.invalidationContext.sizeChanged || false;\n offsetChanged ||= opts.invalidationContext.offsetChanged || false;\n itemSizeChanged ||= opts.invalidationContext.itemSizeChanged || false;\n layoutOptionsChanged ||=\n opts.invalidationContext.layoutOptions != null &&\n this._invalidationContext.layoutOptions != null &&\n opts.invalidationContext.layoutOptions !== this._invalidationContext.layoutOptions &&\n this.layout.shouldInvalidateLayoutOptions(\n opts.invalidationContext.layoutOptions,\n this._invalidationContext.layoutOptions\n );\n needsLayout ||= itemSizeChanged || sizeChanged || offsetChanged || layoutOptionsChanged;\n }\n this._invalidationContext = opts.invalidationContext;\n }\n\n if (opts.isScrolling !== this._isScrolling) {\n this._isScrolling = opts.isScrolling;\n if (!opts.isScrolling) {\n // Update to fix the DOM order after scrolling.\n needsUpdate = true;\n }\n }\n\n if (needsLayout) {\n this.relayout({\n offsetChanged,\n sizeChanged,\n itemSizeChanged,\n layoutOptionsChanged,\n layoutOptions: this._invalidationContext.layoutOptions\n });\n } else if (needsUpdate) {\n this.updateSubviews();\n }\n\n return Array.from(this._rootView.children);\n }\n\n getVisibleView(key: Key): ReusableView<T, V> | undefined {\n return this._visibleViews.get(key);\n }\n\n invalidate(context: InvalidationContext): void {\n this.delegate.invalidate(context);\n }\n\n updateItemSize(key: Key, size: Size): void {\n if (!this.layout.updateItemSize) {\n return;\n }\n\n let changed = this.layout.updateItemSize(key, size);\n if (changed) {\n this.invalidate({\n itemSizeChanged: true\n });\n }\n }\n}\n"],"names":[],"version":3,"file":"Virtualizer.cjs.map"}
|
|
1
|
+
{"mappings":"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","sources":["packages/react-stately/src/virtualizer/Virtualizer.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {ChildView, ReusableView, RootView} from './ReusableView';\nimport {Collection, Key} from '@react-types/shared';\nimport {InvalidationContext, Mutable, VirtualizerDelegate, VirtualizerRenderOptions} from './types';\nimport {isSetEqual} from './utils';\nimport {Layout} from './Layout';\nimport {LayoutInfo} from './LayoutInfo';\nimport {OverscanManager} from './OverscanManager';\nimport {Point} from './Point';\nimport {Rect} from './Rect';\nimport {ScrollAnchor, ScrollAnchorTracker} from './ScrollAnchor';\nimport {Size} from './Size';\n\ninterface VirtualizerOptions<T extends object, V> {\n delegate: VirtualizerDelegate<T, V>;\n collection: Collection<T>;\n layout: Layout<T>;\n}\n\n/**\n * The Virtualizer class renders a scrollable collection of data using customizable layouts.\n * It supports very large collections by only rendering visible views to the DOM, reusing\n * them as you scroll. Virtualizer can present any type of view, including non-item views\n * such as section headers and footers.\n *\n * Virtualizer uses `Layout` objects to compute what views should be visible, and how\n * to position and style them. This means that virtualizer can have its items arranged in\n * a stack, a grid, a circle, or any other layout you can think of. The layout can be changed\n * dynamically at runtime as well.\n *\n * Layouts produce information on what views should appear in the virtualizer, but do not create the\n * views themselves directly. It is the responsibility of the `VirtualizerDelegate` object to render\n * elements for each layout info. The virtualizer manages a set of `ReusableView` objects, which are\n * reused as the user scrolls by swapping their content with cached elements returned by the\n * delegate.\n */\nexport class Virtualizer<T extends object, V> {\n /**\n * The virtualizer delegate. The delegate is used by the virtualizer\n * to create and configure views.\n */\n delegate: VirtualizerDelegate<T, V>;\n\n /** The current content of the virtualizer. */\n readonly collection: Collection<T>;\n /** The layout object that determines the visible views. */\n readonly layout: Layout<T>;\n /** The size of the scrollable content. */\n readonly contentSize: Size;\n /** The currently visible rectangle. */\n readonly visibleRect: Rect;\n /** The size of the virtualizer scroll view. */\n readonly size: Size;\n /** The set of persisted keys that are always present in the DOM, even if not currently in view. */\n readonly persistedKeys: Set<Key>;\n\n private _visibleViews: Map<Key, ChildView<T, V>>;\n private _renderedContent: WeakMap<T, V>;\n private _rootView: RootView<T, V>;\n private _isScrolling: boolean;\n private _invalidationContext: InvalidationContext;\n private _overscanManager: OverscanManager;\n private _scrollAnchor: ScrollAnchorTracker;\n\n constructor(options: VirtualizerOptions<T, V>) {\n this.delegate = options.delegate;\n this.collection = options.collection;\n this.layout = options.layout;\n this.contentSize = new Size();\n this.visibleRect = new Rect();\n this.size = new Size();\n this.persistedKeys = new Set();\n this._visibleViews = new Map();\n this._renderedContent = new WeakMap();\n this._rootView = new RootView(this);\n this._isScrolling = false;\n this._invalidationContext = {};\n this._overscanManager = new OverscanManager();\n this._scrollAnchor = new ScrollAnchorTracker();\n }\n\n /** Returns whether the given key, or an ancestor, is persisted. */\n isPersistedKey(key: Key): boolean {\n // Quick check if the key is directly in the set of persisted keys.\n if (this.persistedKeys.has(key)) {\n return true;\n }\n\n // If not, check if the key is an ancestor of any of the persisted keys.\n for (let k of this.persistedKeys) {\n while (k != null) {\n let layoutInfo = this.layout.getLayoutInfo(k);\n if (!layoutInfo || layoutInfo.parentKey == null) {\n break;\n }\n\n k = layoutInfo.parentKey;\n\n if (k === key) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n private getParentView(layoutInfo: LayoutInfo): ReusableView<T, V> | undefined {\n return layoutInfo.parentKey != null\n ? this._visibleViews.get(layoutInfo.parentKey)\n : this._rootView;\n }\n\n private getReusableView(layoutInfo: LayoutInfo): ChildView<T, V> {\n let parentView = this.getParentView(layoutInfo)!;\n let view = parentView.getReusableView(layoutInfo.type);\n view.layoutInfo = layoutInfo;\n this._renderView(view);\n return view;\n }\n\n private _renderView(reusableView: ReusableView<T, V>) {\n if (reusableView.layoutInfo) {\n let {type, key, content} = reusableView.layoutInfo;\n reusableView.content = content || this.collection.getItem(key);\n reusableView.rendered = this._renderContent(type, reusableView.content);\n }\n }\n\n private _renderContent(type: string, content: T | null) {\n let cached = content != null ? this._renderedContent.get(content) : null;\n if (cached != null) {\n return cached;\n }\n\n let rendered = this.delegate.renderView(type, content);\n if (content) {\n this._renderedContent.set(content, rendered);\n }\n return rendered;\n }\n\n /**\n * Returns the key for the item view currently at the given point.\n */\n keyAtPoint(point: Point): Key | null {\n let rect = new Rect(point.x, point.y, 1, 1);\n let layoutInfos = rect.area === 0 ? [] : this.layout.getVisibleLayoutInfos(rect);\n\n // Layout may return multiple layout infos in the case of\n // persisted keys, so find the first one that actually intersects.\n for (let layoutInfo of layoutInfos) {\n if (layoutInfo.rect.intersects(rect)) {\n return layoutInfo.key;\n }\n }\n\n return null;\n }\n\n private relayout(context: InvalidationContext = {}) {\n // @ts-ignore\n let anchorInfo = this.layout.UNSTABLE_getScrollAnchorInfo?.(context.layoutOptions) ?? null;\n\n // Capture scroll anchor from current (pre-layout) view positions.\n // On first render _visibleViews is empty so no anchor will be found.\n let anchor: ScrollAnchor | null = null;\n if (anchorInfo) {\n let preLayoutInfos: [Key, LayoutInfo][] = [];\n for (let [key, view] of this._visibleViews) {\n let layoutInfo = this.layout.getLayoutInfo(key) ?? view.layoutInfo;\n if (layoutInfo) {\n preLayoutInfos.push([key, layoutInfo]);\n }\n }\n anchor = this._scrollAnchor.captureBeforeLayout(anchorInfo, preLayoutInfos, this.visibleRect);\n }\n\n let previousContentSize = this.contentSize;\n let previousVisibleRect = this.visibleRect;\n\n // Update the layout\n this.layout.update(context);\n\n let rawContentSize = this.layout.getContentSize();\n (this as Mutable<this>).contentSize = new Size(rawContentSize.width, rawContentSize.height);\n\n let target = this._scrollAnchor.resolveAfterLayout({\n anchorInfo,\n anchor,\n postLayoutInfos: anchorInfo ? this.getVisibleLayoutInfos() : new Map(),\n previousVisibleRect,\n previousContentSize,\n contentSize: this.contentSize,\n itemSizeChanged: context.itemSizeChanged ?? false,\n isScrolling: this._isScrolling,\n getLayoutInfo: (key: Key) => this.layout.getLayoutInfo(key)\n });\n\n if (target) {\n // Queues a new render cycle. Return early to skip updateSubviews — running it now\n // would position views against the old visibleRect, causing a flash before the\n // incoming relayout corrects them.\n this.delegate.setVisibleRect(target);\n return;\n }\n\n // Constrain scroll position.\n // If the content changed, scroll to the top.\n let visibleRect = this.visibleRect;\n let contentOffsetX = context.contentChanged ? 0 : visibleRect.x;\n let contentOffsetY = context.contentChanged ? 0 : visibleRect.y;\n contentOffsetX = Math.max(\n 0,\n Math.min(this.contentSize.width - visibleRect.width, contentOffsetX)\n );\n contentOffsetY = Math.max(\n 0,\n Math.min(this.contentSize.height - visibleRect.height, contentOffsetY)\n );\n\n if (contentOffsetX !== visibleRect.x || contentOffsetY !== visibleRect.y) {\n // If the offset changed, trigger a new re-render.\n let rect = new Rect(contentOffsetX, contentOffsetY, visibleRect.width, visibleRect.height);\n this.delegate.setVisibleRect(rect);\n } else {\n this.updateSubviews();\n }\n }\n\n getVisibleLayoutInfos(): Map<Key, LayoutInfo> {\n let isTestEnv = process.env.NODE_ENV === 'test' && !process.env.VIRT_ON;\n let isClientWidthMocked =\n isTestEnv &&\n typeof HTMLElement !== 'undefined' &&\n Object.getOwnPropertyNames(HTMLElement.prototype).includes('clientWidth');\n let isClientHeightMocked =\n isTestEnv &&\n typeof HTMLElement !== 'undefined' &&\n Object.getOwnPropertyNames(HTMLElement.prototype).includes('clientHeight');\n\n let rect: Rect;\n if (isTestEnv && !(isClientWidthMocked && isClientHeightMocked)) {\n rect = new Rect(0, 0, this.contentSize.width, this.contentSize.height);\n } else {\n rect = this._overscanManager.getOverscannedRect();\n }\n let layoutInfos = this.layout.getVisibleLayoutInfos(rect);\n let map = new Map();\n for (let layoutInfo of layoutInfos) {\n map.set(layoutInfo.key, layoutInfo);\n }\n\n return map;\n }\n\n private updateSubviews() {\n let visibleLayoutInfos = this.getVisibleLayoutInfos();\n\n let removed = new Set<ChildView<T, V>>();\n for (let [key, view] of this._visibleViews) {\n let layoutInfo = visibleLayoutInfos.get(key);\n // If a view's parent changed, treat it as a delete and re-create in the new parent.\n if (!layoutInfo || view.parent !== this.getParentView(layoutInfo)) {\n this._visibleViews.delete(key);\n view.parent.reuseChild(view);\n removed.add(view); // Defer removing in case we reuse this view.\n }\n }\n\n for (let [key, layoutInfo] of visibleLayoutInfos) {\n let view = this._visibleViews.get(key);\n if (!view) {\n view = this.getReusableView(layoutInfo);\n view.parent.children.add(view);\n this._visibleViews.set(key, view);\n removed.delete(view);\n } else {\n view.layoutInfo = layoutInfo;\n\n let item = this.collection.getItem(layoutInfo.key);\n if (view.content !== item) {\n if (view.content != null) {\n this._renderedContent.delete(view.content);\n }\n this._renderView(view);\n }\n }\n }\n\n // The remaining views in `removed` were not reused to render new items.\n // They should be removed from the DOM. We also clear the reusable view queue\n // here since there's no point holding onto views that have been removed.\n // Doing so hurts performance in the future when reusing elements due to FIFO order.\n for (let view of removed) {\n view.parent.children.delete(view);\n view.parent.reusableViews.clear();\n }\n\n // Reordering DOM nodes is costly, so we defer this until scrolling stops.\n // DOM order does not affect visual order (due to absolute positioning),\n // but does matter for assistive technology users.\n if (!this._isScrolling) {\n // Layout infos must be in topological order (parents before children).\n for (let key of visibleLayoutInfos.keys()) {\n let view = this._visibleViews.get(key)!;\n view.parent.children.delete(view);\n view.parent.children.add(view);\n }\n }\n }\n\n /** Performs layout and updates visible views as needed. */\n render(opts: VirtualizerRenderOptions<T>): ReusableView<T, V>[] {\n let mutableThis: Mutable<this> = this;\n let needsLayout = false;\n let offsetChanged = false;\n let sizeChanged = false;\n let widthChanged = false;\n let heightChanged = false;\n let itemSizeChanged = false;\n let layoutOptionsChanged = false;\n let needsUpdate = false;\n\n if (opts.collection !== this.collection) {\n mutableThis.collection = opts.collection;\n needsLayout = true;\n }\n\n if (opts.layout !== this.layout || this.layout.virtualizer !== this) {\n if (this.layout) {\n this.layout.virtualizer = null;\n }\n\n opts.layout.virtualizer = this;\n mutableThis.layout = opts.layout;\n this._scrollAnchor.reset();\n needsLayout = true;\n }\n\n if (opts.persistedKeys && !isSetEqual(opts.persistedKeys, this.persistedKeys)) {\n mutableThis.persistedKeys = opts.persistedKeys;\n needsUpdate = true;\n }\n\n if (!this.visibleRect.equals(opts.visibleRect) || !this.size.equals(opts.size)) {\n this._overscanManager.setVisibleRect(opts.visibleRect);\n\n // Create a rectangle using the scroll position and layout size of the scroll view. This is not the same\n // as the visibleRect, whose width and height may change during window scrolling.\n let oldRect = new Rect(\n this.visibleRect.x,\n this.visibleRect.y,\n this.size.width,\n this.size.height\n );\n let newRect = new Rect(\n opts.visibleRect.x,\n opts.visibleRect.y,\n opts.size.width,\n opts.size.height\n );\n let shouldInvalidate = this.layout.shouldInvalidate(newRect, oldRect);\n\n if (shouldInvalidate) {\n offsetChanged = !opts.visibleRect.pointEquals(this.visibleRect);\n sizeChanged = !this.size.equals(opts.size);\n widthChanged = this.size.width !== opts.size.width;\n heightChanged = this.size.height !== opts.size.height;\n needsLayout = true;\n } else {\n needsUpdate = true;\n }\n\n mutableThis.visibleRect = opts.visibleRect;\n mutableThis.size = opts.size;\n }\n\n if (opts.invalidationContext !== this._invalidationContext) {\n if (opts.invalidationContext) {\n sizeChanged ||= opts.invalidationContext.sizeChanged || false;\n widthChanged ||= opts.invalidationContext.widthChanged || false;\n heightChanged ||= opts.invalidationContext.heightChanged || false;\n offsetChanged ||= opts.invalidationContext.offsetChanged || false;\n itemSizeChanged ||= opts.invalidationContext.itemSizeChanged || false;\n layoutOptionsChanged ||=\n opts.invalidationContext.layoutOptions != null &&\n this._invalidationContext.layoutOptions != null &&\n opts.invalidationContext.layoutOptions !== this._invalidationContext.layoutOptions &&\n this.layout.shouldInvalidateLayoutOptions(\n opts.invalidationContext.layoutOptions,\n this._invalidationContext.layoutOptions\n );\n needsLayout ||= itemSizeChanged || sizeChanged || offsetChanged || layoutOptionsChanged;\n }\n this._invalidationContext = opts.invalidationContext;\n }\n\n if (opts.isScrolling !== this._isScrolling) {\n this._isScrolling = opts.isScrolling;\n if (!opts.isScrolling) {\n // Update to fix the DOM order after scrolling.\n needsUpdate = true;\n }\n }\n\n if (needsLayout) {\n this.relayout({\n offsetChanged,\n sizeChanged,\n widthChanged,\n heightChanged,\n itemSizeChanged,\n layoutOptionsChanged,\n layoutOptions: this._invalidationContext.layoutOptions\n });\n } else if (needsUpdate) {\n this.updateSubviews();\n }\n\n return Array.from(this._rootView.children);\n }\n\n getVisibleView(key: Key): ReusableView<T, V> | undefined {\n return this._visibleViews.get(key);\n }\n\n invalidate(context: InvalidationContext): void {\n this.delegate.invalidate(context);\n }\n\n updateItemSize(key: Key, size: Size): void {\n if (!this.layout.updateItemSize) {\n return;\n }\n\n let changed = this.layout.updateItemSize(key, size);\n if (changed) {\n this.invalidate({\n itemSizeChanged: true\n });\n }\n }\n}\n"],"names":[],"version":3,"file":"Virtualizer.cjs.map"}
|
|
@@ -2,6 +2,7 @@ import {RootView as $c7620442287ad52a$export$e21886a4eef6b29a} from "./ReusableV
|
|
|
2
2
|
import {isSetEqual as $94e3e3694aff09c6$export$a8d0d0c8d1c5df64} from "./utils.js";
|
|
3
3
|
import {OverscanManager as $44cbaca532f3db86$export$4455ee6afb38dcbb} from "./OverscanManager.js";
|
|
4
4
|
import {Rect as $546350db2c358941$export$c79fc6492f3af13d} from "./Rect.js";
|
|
5
|
+
import {ScrollAnchorTracker as $20fe89c1b1ab405a$export$8ce0fdedc36cb6b} from "./ScrollAnchor.js";
|
|
5
6
|
import {Size as $266cbd2785be3a2c$export$cb6da89c6af1a8ec} from "./Size.js";
|
|
6
7
|
|
|
7
8
|
/*
|
|
@@ -19,6 +20,7 @@ import {Size as $266cbd2785be3a2c$export$cb6da89c6af1a8ec} from "./Size.js";
|
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
|
|
22
24
|
class $55865ccb920012bc$export$89be5a243e59c4b2 {
|
|
23
25
|
/** Returns whether the given key, or an ancestor, is persisted. */ isPersistedKey(key) {
|
|
24
26
|
// Quick check if the key is directly in the set of persisted keys.
|
|
@@ -69,9 +71,50 @@ class $55865ccb920012bc$export$89be5a243e59c4b2 {
|
|
|
69
71
|
return null;
|
|
70
72
|
}
|
|
71
73
|
relayout(context = {}) {
|
|
74
|
+
var _this_layout_UNSTABLE_getScrollAnchorInfo, _this_layout;
|
|
75
|
+
var _this_layout_UNSTABLE_getScrollAnchorInfo1;
|
|
76
|
+
// @ts-ignore
|
|
77
|
+
let anchorInfo = (_this_layout_UNSTABLE_getScrollAnchorInfo1 = (_this_layout_UNSTABLE_getScrollAnchorInfo = (_this_layout = this.layout).UNSTABLE_getScrollAnchorInfo) === null || _this_layout_UNSTABLE_getScrollAnchorInfo === void 0 ? void 0 : _this_layout_UNSTABLE_getScrollAnchorInfo.call(_this_layout, context.layoutOptions)) !== null && _this_layout_UNSTABLE_getScrollAnchorInfo1 !== void 0 ? _this_layout_UNSTABLE_getScrollAnchorInfo1 : null;
|
|
78
|
+
// Capture scroll anchor from current (pre-layout) view positions.
|
|
79
|
+
// On first render _visibleViews is empty so no anchor will be found.
|
|
80
|
+
let anchor = null;
|
|
81
|
+
if (anchorInfo) {
|
|
82
|
+
let preLayoutInfos = [];
|
|
83
|
+
for (let [key, view] of this._visibleViews){
|
|
84
|
+
var _this_layout_getLayoutInfo;
|
|
85
|
+
let layoutInfo = (_this_layout_getLayoutInfo = this.layout.getLayoutInfo(key)) !== null && _this_layout_getLayoutInfo !== void 0 ? _this_layout_getLayoutInfo : view.layoutInfo;
|
|
86
|
+
if (layoutInfo) preLayoutInfos.push([
|
|
87
|
+
key,
|
|
88
|
+
layoutInfo
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
anchor = this._scrollAnchor.captureBeforeLayout(anchorInfo, preLayoutInfos, this.visibleRect);
|
|
92
|
+
}
|
|
93
|
+
let previousContentSize = this.contentSize;
|
|
94
|
+
let previousVisibleRect = this.visibleRect;
|
|
72
95
|
// Update the layout
|
|
73
96
|
this.layout.update(context);
|
|
74
|
-
|
|
97
|
+
let rawContentSize = this.layout.getContentSize();
|
|
98
|
+
this.contentSize = new (0, $266cbd2785be3a2c$export$cb6da89c6af1a8ec)(rawContentSize.width, rawContentSize.height);
|
|
99
|
+
var _context_itemSizeChanged;
|
|
100
|
+
let target = this._scrollAnchor.resolveAfterLayout({
|
|
101
|
+
anchorInfo: anchorInfo,
|
|
102
|
+
anchor: anchor,
|
|
103
|
+
postLayoutInfos: anchorInfo ? this.getVisibleLayoutInfos() : new Map(),
|
|
104
|
+
previousVisibleRect: previousVisibleRect,
|
|
105
|
+
previousContentSize: previousContentSize,
|
|
106
|
+
contentSize: this.contentSize,
|
|
107
|
+
itemSizeChanged: (_context_itemSizeChanged = context.itemSizeChanged) !== null && _context_itemSizeChanged !== void 0 ? _context_itemSizeChanged : false,
|
|
108
|
+
isScrolling: this._isScrolling,
|
|
109
|
+
getLayoutInfo: (key)=>this.layout.getLayoutInfo(key)
|
|
110
|
+
});
|
|
111
|
+
if (target) {
|
|
112
|
+
// Queues a new render cycle. Return early to skip updateSubviews — running it now
|
|
113
|
+
// would position views against the old visibleRect, causing a flash before the
|
|
114
|
+
// incoming relayout corrects them.
|
|
115
|
+
this.delegate.setVisibleRect(target);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
75
118
|
// Constrain scroll position.
|
|
76
119
|
// If the content changed, scroll to the top.
|
|
77
120
|
let visibleRect = this.visibleRect;
|
|
@@ -148,6 +191,8 @@ class $55865ccb920012bc$export$89be5a243e59c4b2 {
|
|
|
148
191
|
let needsLayout = false;
|
|
149
192
|
let offsetChanged = false;
|
|
150
193
|
let sizeChanged = false;
|
|
194
|
+
let widthChanged = false;
|
|
195
|
+
let heightChanged = false;
|
|
151
196
|
let itemSizeChanged = false;
|
|
152
197
|
let layoutOptionsChanged = false;
|
|
153
198
|
let needsUpdate = false;
|
|
@@ -159,6 +204,7 @@ class $55865ccb920012bc$export$89be5a243e59c4b2 {
|
|
|
159
204
|
if (this.layout) this.layout.virtualizer = null;
|
|
160
205
|
opts.layout.virtualizer = this;
|
|
161
206
|
mutableThis.layout = opts.layout;
|
|
207
|
+
this._scrollAnchor.reset();
|
|
162
208
|
needsLayout = true;
|
|
163
209
|
}
|
|
164
210
|
if (opts.persistedKeys && !(0, $94e3e3694aff09c6$export$a8d0d0c8d1c5df64)(opts.persistedKeys, this.persistedKeys)) {
|
|
@@ -175,6 +221,8 @@ class $55865ccb920012bc$export$89be5a243e59c4b2 {
|
|
|
175
221
|
if (shouldInvalidate) {
|
|
176
222
|
offsetChanged = !opts.visibleRect.pointEquals(this.visibleRect);
|
|
177
223
|
sizeChanged = !this.size.equals(opts.size);
|
|
224
|
+
widthChanged = this.size.width !== opts.size.width;
|
|
225
|
+
heightChanged = this.size.height !== opts.size.height;
|
|
178
226
|
needsLayout = true;
|
|
179
227
|
} else needsUpdate = true;
|
|
180
228
|
mutableThis.visibleRect = opts.visibleRect;
|
|
@@ -183,6 +231,8 @@ class $55865ccb920012bc$export$89be5a243e59c4b2 {
|
|
|
183
231
|
if (opts.invalidationContext !== this._invalidationContext) {
|
|
184
232
|
if (opts.invalidationContext) {
|
|
185
233
|
sizeChanged || (sizeChanged = opts.invalidationContext.sizeChanged || false);
|
|
234
|
+
widthChanged || (widthChanged = opts.invalidationContext.widthChanged || false);
|
|
235
|
+
heightChanged || (heightChanged = opts.invalidationContext.heightChanged || false);
|
|
186
236
|
offsetChanged || (offsetChanged = opts.invalidationContext.offsetChanged || false);
|
|
187
237
|
itemSizeChanged || (itemSizeChanged = opts.invalidationContext.itemSizeChanged || false);
|
|
188
238
|
layoutOptionsChanged || (layoutOptionsChanged = opts.invalidationContext.layoutOptions != null && this._invalidationContext.layoutOptions != null && opts.invalidationContext.layoutOptions !== this._invalidationContext.layoutOptions && this.layout.shouldInvalidateLayoutOptions(opts.invalidationContext.layoutOptions, this._invalidationContext.layoutOptions));
|
|
@@ -198,6 +248,8 @@ class $55865ccb920012bc$export$89be5a243e59c4b2 {
|
|
|
198
248
|
if (needsLayout) this.relayout({
|
|
199
249
|
offsetChanged: offsetChanged,
|
|
200
250
|
sizeChanged: sizeChanged,
|
|
251
|
+
widthChanged: widthChanged,
|
|
252
|
+
heightChanged: heightChanged,
|
|
201
253
|
itemSizeChanged: itemSizeChanged,
|
|
202
254
|
layoutOptionsChanged: layoutOptionsChanged,
|
|
203
255
|
layoutOptions: this._invalidationContext.layoutOptions
|
|
@@ -232,6 +284,7 @@ class $55865ccb920012bc$export$89be5a243e59c4b2 {
|
|
|
232
284
|
this._isScrolling = false;
|
|
233
285
|
this._invalidationContext = {};
|
|
234
286
|
this._overscanManager = new (0, $44cbaca532f3db86$export$4455ee6afb38dcbb)();
|
|
287
|
+
this._scrollAnchor = new (0, $20fe89c1b1ab405a$export$8ce0fdedc36cb6b)();
|
|
235
288
|
}
|
|
236
289
|
}
|
|
237
290
|
|