@legendapp/list 3.2.0 → 3.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/CHANGELOG.md +8 -0
- package/animated.d.ts +7 -1
- package/package.json +1 -1
- package/react-native.d.ts +8 -2
- package/react-native.js +126 -53
- package/react-native.mjs +126 -53
- package/react-native.web.d.ts +8 -2
- package/react-native.web.js +126 -53
- package/react-native.web.mjs +126 -53
- package/react.d.ts +8 -2
- package/react.js +126 -53
- package/react.mjs +126 -53
- package/reanimated.d.ts +7 -1
- package/section-list.d.ts +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 3.3.0
|
|
2
|
+
|
|
3
|
+
- Feat: Add `dataKey` so apps can tell the list when the current array represents a different dataset, such as switching conversations or feeds without remounting `LegendList`.
|
|
4
|
+
- Feat: `experimental_adaptiveRender.onChange` now receives a reason (`initial`, `ready`, or `scroll`) so item components can tell why the render mode changed.
|
|
5
|
+
- Fix: Large user scroll jumps render the visible rows first and fill the normal draw distance on the next frame, making long jumps less likely to land on a blank range.
|
|
6
|
+
- Fix: `maintainScrollAtEnd` reruns a pending keep-at-end request after the current one settles, so a footer resize and a new message arriving together keep chat-style lists pinned to the end.
|
|
7
|
+
- Fix: Replacing data after clearing the list, or changing `dataKey` for a non-empty replacement, resets layout readiness and uses the latest initial scroll target for the new dataset.
|
|
8
|
+
|
|
1
9
|
## 3.2.0
|
|
2
10
|
|
|
3
11
|
- Feat: Add `onFirstVisibleItemChanged` so apps can track the item at the top of the viewport without setting up full viewability callbacks.
|
package/animated.d.ts
CHANGED
|
@@ -92,6 +92,7 @@ interface NativeSyntheticEvent<T> {
|
|
|
92
92
|
type ViewStyle = Record<string, unknown>;
|
|
93
93
|
type StyleProp<T> = T | T[] | null | undefined | false;
|
|
94
94
|
type AdaptiveRender = "normal" | "light";
|
|
95
|
+
type AdaptiveRenderChangeReason = "initial" | "ready" | "scroll";
|
|
95
96
|
interface AdaptiveRenderConfig {
|
|
96
97
|
/**
|
|
97
98
|
* Mode to use before the list is ready to render.
|
|
@@ -116,7 +117,7 @@ interface AdaptiveRenderConfig {
|
|
|
116
117
|
/**
|
|
117
118
|
* Called when the list-level adaptive render changes.
|
|
118
119
|
*/
|
|
119
|
-
onChange?: (mode: AdaptiveRender) => void;
|
|
120
|
+
onChange?: (mode: AdaptiveRender, reason: AdaptiveRenderChangeReason) => void;
|
|
120
121
|
}
|
|
121
122
|
type BaseScrollViewProps<TScrollView> = Omit<TScrollView, "contentOffset" | "maintainVisibleContentPosition" | "stickyHeaderIndices" | "removeClippedSubviews" | "children" | "onScroll">;
|
|
122
123
|
interface DataModeProps<ItemT, TItemType extends string | undefined> {
|
|
@@ -158,6 +159,11 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
|
|
|
158
159
|
* Style applied to each column's wrapper view.
|
|
159
160
|
*/
|
|
160
161
|
columnWrapperStyle?: ColumnWrapperStyle;
|
|
162
|
+
/**
|
|
163
|
+
* Identity token for the dataset represented by `data`.
|
|
164
|
+
* Change this when replacing the current dataset with a different logical dataset.
|
|
165
|
+
*/
|
|
166
|
+
dataKey?: Key;
|
|
161
167
|
/**
|
|
162
168
|
* Version token that forces the list to treat data as updated even when the array reference is stable.
|
|
163
169
|
* Increment or change this when mutating the data array in place.
|
package/package.json
CHANGED
package/react-native.d.ts
CHANGED
|
@@ -92,6 +92,7 @@ interface NativeSyntheticEvent<T> {
|
|
|
92
92
|
type ViewStyle = Record<string, unknown>;
|
|
93
93
|
type StyleProp<T> = T | T[] | null | undefined | false;
|
|
94
94
|
type AdaptiveRender = "normal" | "light";
|
|
95
|
+
type AdaptiveRenderChangeReason = "initial" | "ready" | "scroll";
|
|
95
96
|
interface AdaptiveRenderConfig {
|
|
96
97
|
/**
|
|
97
98
|
* Mode to use before the list is ready to render.
|
|
@@ -116,7 +117,7 @@ interface AdaptiveRenderConfig {
|
|
|
116
117
|
/**
|
|
117
118
|
* Called when the list-level adaptive render changes.
|
|
118
119
|
*/
|
|
119
|
-
onChange?: (mode: AdaptiveRender) => void;
|
|
120
|
+
onChange?: (mode: AdaptiveRender, reason: AdaptiveRenderChangeReason) => void;
|
|
120
121
|
}
|
|
121
122
|
type BaseScrollViewProps<TScrollView> = Omit<TScrollView, "contentOffset" | "maintainVisibleContentPosition" | "stickyHeaderIndices" | "removeClippedSubviews" | "children" | "onScroll">;
|
|
122
123
|
interface DataModeProps<ItemT, TItemType extends string | undefined> {
|
|
@@ -158,6 +159,11 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
|
|
|
158
159
|
* Style applied to each column's wrapper view.
|
|
159
160
|
*/
|
|
160
161
|
columnWrapperStyle?: ColumnWrapperStyle;
|
|
162
|
+
/**
|
|
163
|
+
* Identity token for the dataset represented by `data`.
|
|
164
|
+
* Change this when replacing the current dataset with a different logical dataset.
|
|
165
|
+
*/
|
|
166
|
+
dataKey?: Key;
|
|
161
167
|
/**
|
|
162
168
|
* Version token that forces the list to treat data as updated even when the array reference is stable.
|
|
163
169
|
* Increment or change this when mutating the data array in place.
|
|
@@ -764,4 +770,4 @@ declare function useSyncLayout(): () => void;
|
|
|
764
770
|
|
|
765
771
|
declare const LegendList: LegendListComponent;
|
|
766
772
|
|
|
767
|
-
export { type AdaptiveRender, type AdaptiveRenderConfig, type AlwaysRenderConfig, type ColumnWrapperStyle, type Insets, type LayoutRectangle, LegendList, type LegendListAverageItemSize, type LegendListComponent, type LegendListMetrics, type LegendListProps, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type LegendListState, type MaintainScrollAtEndOnOptions, type MaintainScrollAtEndOptions, type MaintainVisibleContentPositionConfig, type NativeScrollEvent, type NativeSyntheticEvent, type OnViewableItemsChanged, type OnViewableItemsChangedInfo, type ScrollIndexWithOffset, type ScrollIndexWithOffsetAndContentOffset, type ScrollIndexWithOffsetPosition, type StickyHeaderConfig, type StyleProp, type ViewAmountToken, type ViewStyle, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, useAdaptiveRender, useAdaptiveRenderChange, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
|
|
773
|
+
export { type AdaptiveRender, type AdaptiveRenderChangeReason, type AdaptiveRenderConfig, type AlwaysRenderConfig, type ColumnWrapperStyle, type Insets, type LayoutRectangle, LegendList, type LegendListAverageItemSize, type LegendListComponent, type LegendListMetrics, type LegendListProps, type LegendListRecyclingState, type LegendListRef, type LegendListRenderItemProps, type LegendListState, type MaintainScrollAtEndOnOptions, type MaintainScrollAtEndOptions, type MaintainVisibleContentPositionConfig, type NativeScrollEvent, type NativeSyntheticEvent, type OnViewableItemsChanged, type OnViewableItemsChangedInfo, type ScrollIndexWithOffset, type ScrollIndexWithOffsetAndContentOffset, type ScrollIndexWithOffsetPosition, type StickyHeaderConfig, type StyleProp, type ViewAmountToken, type ViewStyle, type ViewToken, type ViewabilityAmountCallback, type ViewabilityCallback, type ViewabilityConfig, type ViewabilityConfigCallbackPair, type ViewabilityConfigCallbackPairs, useAdaptiveRender, useAdaptiveRenderChange, useIsLastItem, useListScrollSize, useRecyclingEffect, useRecyclingState, useSyncLayout, useViewability, useViewabilityAmount };
|
package/react-native.js
CHANGED
|
@@ -1116,32 +1116,34 @@ function scheduleAdaptiveRenderExit(ctx, exitDelay) {
|
|
|
1116
1116
|
const state = ctx.state;
|
|
1117
1117
|
clearAdaptiveRenderExitTimeout(ctx);
|
|
1118
1118
|
if (exitDelay <= 0) {
|
|
1119
|
-
setAdaptiveRender(ctx, "normal");
|
|
1119
|
+
setAdaptiveRender(ctx, "normal", "scroll");
|
|
1120
1120
|
} else {
|
|
1121
1121
|
const timeout = setTimeout(() => {
|
|
1122
1122
|
state.timeouts.delete(timeout);
|
|
1123
1123
|
state.timeoutAdaptiveRender = void 0;
|
|
1124
|
-
setAdaptiveRender(ctx, "normal");
|
|
1124
|
+
setAdaptiveRender(ctx, "normal", "scroll");
|
|
1125
1125
|
}, exitDelay);
|
|
1126
1126
|
state.timeoutAdaptiveRender = timeout;
|
|
1127
1127
|
state.timeouts.add(timeout);
|
|
1128
1128
|
}
|
|
1129
1129
|
}
|
|
1130
|
-
function setAdaptiveRender(ctx, mode) {
|
|
1130
|
+
function setAdaptiveRender(ctx, mode, reason) {
|
|
1131
1131
|
var _a3, _b;
|
|
1132
1132
|
const previousMode = peek$(ctx, "adaptiveRender");
|
|
1133
1133
|
if (previousMode !== mode) {
|
|
1134
1134
|
set$(ctx, "adaptiveRender", mode);
|
|
1135
|
-
(_b = (_a3 = ctx.state.props.adaptiveRender) == null ? void 0 : _a3.onChange) == null ? void 0 : _b.call(_a3, mode);
|
|
1135
|
+
(_b = (_a3 = ctx.state.props.adaptiveRender) == null ? void 0 : _a3.onChange) == null ? void 0 : _b.call(_a3, mode, reason);
|
|
1136
1136
|
}
|
|
1137
1137
|
}
|
|
1138
1138
|
function resetAdaptiveRender(ctx) {
|
|
1139
|
+
var _a3, _b;
|
|
1139
1140
|
clearAdaptiveRenderExitTimeout(ctx);
|
|
1140
|
-
|
|
1141
|
-
|
|
1141
|
+
const mode = (_b = (_a3 = ctx.state.props.adaptiveRender) == null ? void 0 : _a3.initialMode) != null ? _b : "normal";
|
|
1142
|
+
if (peek$(ctx, "adaptiveRender") !== mode) {
|
|
1143
|
+
setAdaptiveRender(ctx, mode, "initial");
|
|
1142
1144
|
}
|
|
1143
1145
|
}
|
|
1144
|
-
function updateAdaptiveRender(ctx, scrollVelocity) {
|
|
1146
|
+
function updateAdaptiveRender(ctx, scrollVelocity, options) {
|
|
1145
1147
|
var _a3, _b, _c;
|
|
1146
1148
|
const state = ctx.state;
|
|
1147
1149
|
const adaptiveRender = state.props.adaptiveRender;
|
|
@@ -1153,11 +1155,11 @@ function updateAdaptiveRender(ctx, scrollVelocity) {
|
|
|
1153
1155
|
const exitVelocity = (_b = adaptiveRender.exitVelocity) != null ? _b : isWeb ? DEFAULT_WEB_ADAPTIVE_RENDER_EXIT_VELOCITY : DEFAULT_ADAPTIVE_RENDER_EXIT_VELOCITY;
|
|
1154
1156
|
const exitDelay = (_c = adaptiveRender.exitDelay) != null ? _c : isWeb ? DEFAULT_WEB_ADAPTIVE_RENDER_EXIT_DELAY : DEFAULT_ADAPTIVE_RENDER_EXIT_DELAY;
|
|
1155
1157
|
const threshold = currentMode === "light" ? exitVelocity : enterVelocity;
|
|
1156
|
-
const nextMode = Math.abs(scrollVelocity) > threshold ? "light" : "normal";
|
|
1158
|
+
const nextMode = (options == null ? void 0 : options.forceLight) || Math.abs(scrollVelocity) > threshold ? "light" : "normal";
|
|
1157
1159
|
const previousMode = state.timeoutAdaptiveRender !== void 0 ? "normal" : currentMode;
|
|
1158
1160
|
if (nextMode !== previousMode) {
|
|
1159
1161
|
if (nextMode === "light") {
|
|
1160
|
-
setAdaptiveRender(ctx, "light");
|
|
1162
|
+
setAdaptiveRender(ctx, "light", "scroll");
|
|
1161
1163
|
scheduleAdaptiveRenderExit(ctx, exitDelay);
|
|
1162
1164
|
} else if (currentMode === "light") {
|
|
1163
1165
|
scheduleAdaptiveRenderExit(ctx, exitDelay);
|
|
@@ -1170,16 +1172,43 @@ function updateAdaptiveRender(ctx, scrollVelocity) {
|
|
|
1170
1172
|
}
|
|
1171
1173
|
|
|
1172
1174
|
// src/utils/getEffectiveDrawDistance.ts
|
|
1173
|
-
var INITIAL_DRAW_DISTANCE =
|
|
1174
|
-
function getEffectiveDrawDistance(ctx) {
|
|
1175
|
+
var INITIAL_DRAW_DISTANCE = 50;
|
|
1176
|
+
function getEffectiveDrawDistance(ctx, mode) {
|
|
1175
1177
|
var _a3;
|
|
1176
1178
|
const drawDistance = ctx.state.props.drawDistance;
|
|
1177
1179
|
const initialScroll = ctx.state.initialScroll;
|
|
1178
1180
|
const needsFullInitialDrawDistance = initialScroll !== void 0 && ((_a3 = initialScroll.viewPosition) != null ? _a3 : 0) > 0;
|
|
1179
|
-
|
|
1181
|
+
const shouldCapDrawDistance = mode === "visible-first" || mode !== "full" && !peek$(ctx, "readyToRender") && !needsFullInitialDrawDistance;
|
|
1182
|
+
return shouldCapDrawDistance ? Math.min(drawDistance, INITIAL_DRAW_DISTANCE) : drawDistance;
|
|
1183
|
+
}
|
|
1184
|
+
function scheduleFullDrawDistancePrewarm(ctx) {
|
|
1185
|
+
const { state } = ctx;
|
|
1186
|
+
if (state.props.drawDistance <= INITIAL_DRAW_DISTANCE || state.queuedFullDrawDistancePrewarm !== void 0) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
state.queuedFullDrawDistancePrewarm = requestAnimationFrame(() => {
|
|
1190
|
+
var _a3;
|
|
1191
|
+
state.queuedFullDrawDistancePrewarm = void 0;
|
|
1192
|
+
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state);
|
|
1193
|
+
});
|
|
1180
1194
|
}
|
|
1181
1195
|
|
|
1182
1196
|
// src/utils/setInitialRenderState.ts
|
|
1197
|
+
function resetInitialRenderState(ctx, {
|
|
1198
|
+
resetLayout,
|
|
1199
|
+
resetInitialScroll
|
|
1200
|
+
}) {
|
|
1201
|
+
const { state } = ctx;
|
|
1202
|
+
if (resetLayout) {
|
|
1203
|
+
state.didContainersLayout = false;
|
|
1204
|
+
state.queuedInitialLayout = false;
|
|
1205
|
+
}
|
|
1206
|
+
if (resetInitialScroll) {
|
|
1207
|
+
state.didFinishInitialScroll = false;
|
|
1208
|
+
}
|
|
1209
|
+
set$(ctx, "readyToRender", false);
|
|
1210
|
+
resetAdaptiveRender(ctx);
|
|
1211
|
+
}
|
|
1183
1212
|
function setInitialRenderState(ctx, {
|
|
1184
1213
|
didLayout,
|
|
1185
1214
|
didInitialScroll
|
|
@@ -1198,15 +1227,15 @@ function setInitialRenderState(ctx, {
|
|
|
1198
1227
|
const isReadyToRender = Boolean(state.didContainersLayout && state.didFinishInitialScroll);
|
|
1199
1228
|
if (isReadyToRender && !peek$(ctx, "readyToRender")) {
|
|
1200
1229
|
set$(ctx, "readyToRender", true);
|
|
1201
|
-
setAdaptiveRender(ctx, "normal");
|
|
1230
|
+
setAdaptiveRender(ctx, "normal", "ready");
|
|
1202
1231
|
if (state.props.drawDistance > INITIAL_DRAW_DISTANCE) {
|
|
1203
|
-
|
|
1204
|
-
var _a3;
|
|
1205
|
-
(_a3 = state.triggerCalculateItemsInView) == null ? void 0 : _a3.call(state);
|
|
1206
|
-
});
|
|
1232
|
+
scheduleFullDrawDistancePrewarm(ctx);
|
|
1207
1233
|
}
|
|
1208
|
-
if (
|
|
1209
|
-
|
|
1234
|
+
if (!state.didLoad) {
|
|
1235
|
+
state.didLoad = true;
|
|
1236
|
+
if (onLoad) {
|
|
1237
|
+
onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
|
|
1238
|
+
}
|
|
1210
1239
|
}
|
|
1211
1240
|
}
|
|
1212
1241
|
}
|
|
@@ -1735,8 +1764,8 @@ function doMaintainScrollAtEnd(ctx) {
|
|
|
1735
1764
|
state.pendingMaintainScrollAtEnd = shouldMaintainScrollAtEnd;
|
|
1736
1765
|
return false;
|
|
1737
1766
|
}
|
|
1738
|
-
state.pendingMaintainScrollAtEnd = false;
|
|
1739
1767
|
if (shouldMaintainScrollAtEnd) {
|
|
1768
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1740
1769
|
const contentSize = getContentSize(ctx);
|
|
1741
1770
|
if (contentSize < state.scrollLength) {
|
|
1742
1771
|
state.scroll = 0;
|
|
@@ -1767,6 +1796,9 @@ function doMaintainScrollAtEnd(ctx) {
|
|
|
1767
1796
|
() => {
|
|
1768
1797
|
if (state.maintainingScrollAtEnd === activeState) {
|
|
1769
1798
|
state.maintainingScrollAtEnd = void 0;
|
|
1799
|
+
if (state.pendingMaintainScrollAtEnd) {
|
|
1800
|
+
doMaintainScrollAtEnd(ctx);
|
|
1801
|
+
}
|
|
1770
1802
|
}
|
|
1771
1803
|
},
|
|
1772
1804
|
maintainScrollAtEnd.animated ? 500 : 0
|
|
@@ -1775,9 +1807,12 @@ function doMaintainScrollAtEnd(ctx) {
|
|
|
1775
1807
|
state.maintainingScrollAtEnd = void 0;
|
|
1776
1808
|
}
|
|
1777
1809
|
});
|
|
1810
|
+
} else {
|
|
1811
|
+
state.pendingMaintainScrollAtEnd = true;
|
|
1778
1812
|
}
|
|
1779
1813
|
return true;
|
|
1780
1814
|
}
|
|
1815
|
+
state.pendingMaintainScrollAtEnd = false;
|
|
1781
1816
|
return false;
|
|
1782
1817
|
}
|
|
1783
1818
|
|
|
@@ -2201,8 +2236,6 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
2201
2236
|
if (scrollHistory.length > 5) {
|
|
2202
2237
|
scrollHistory.shift();
|
|
2203
2238
|
}
|
|
2204
|
-
const scrollVelocity = getScrollVelocity(state);
|
|
2205
|
-
updateAdaptiveRender(ctx, scrollVelocity);
|
|
2206
2239
|
if (ignoreScrollFromMVCP && !scrollingTo) {
|
|
2207
2240
|
const { lt, gt } = ignoreScrollFromMVCP;
|
|
2208
2241
|
if (lt && newScroll < lt || gt && newScroll > gt) {
|
|
@@ -2217,6 +2250,9 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
2217
2250
|
const scrollDelta = Math.abs(newScroll - prevScroll);
|
|
2218
2251
|
const didResolvePendingNativeMVCPAdjust = resolvePendingNativeMVCPAdjust(ctx, newScroll);
|
|
2219
2252
|
const scrollLength = state.scrollLength;
|
|
2253
|
+
const isLargeUserScrollJump = scrollLength > 0 && scrollingTo === void 0 && scrollDelta > scrollLength && !state.pendingNativeMVCPAdjust;
|
|
2254
|
+
const scrollVelocity = getScrollVelocity(state);
|
|
2255
|
+
updateAdaptiveRender(ctx, scrollVelocity, { forceLight: isLargeUserScrollJump });
|
|
2220
2256
|
const lastCalculated = state.scrollLastCalculate;
|
|
2221
2257
|
const useAggressiveItemRecalculation = isInMVCPActiveMode(state);
|
|
2222
2258
|
const shouldUpdate = useAggressiveItemRecalculation || didResolvePendingNativeMVCPAdjust || forceUpdate || lastCalculated === void 0 || Math.abs(state.scroll - lastCalculated) > 2;
|
|
@@ -2226,10 +2262,17 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
2226
2262
|
state.lastScrollDelta = scrollDelta;
|
|
2227
2263
|
const runCalculateItems = () => {
|
|
2228
2264
|
var _a4;
|
|
2229
|
-
|
|
2265
|
+
const calculateItemsParams = {
|
|
2266
|
+
doMVCP: scrollingTo !== void 0,
|
|
2267
|
+
scrollVelocity
|
|
2268
|
+
};
|
|
2269
|
+
if (isLargeUserScrollJump) {
|
|
2270
|
+
calculateItemsParams.drawDistanceMode = "visible-first";
|
|
2271
|
+
}
|
|
2272
|
+
(_a4 = state.triggerCalculateItemsInView) == null ? void 0 : _a4.call(state, calculateItemsParams);
|
|
2230
2273
|
checkThresholds(ctx);
|
|
2231
2274
|
};
|
|
2232
|
-
if (
|
|
2275
|
+
if (isLargeUserScrollJump) {
|
|
2233
2276
|
state.mvcpAnchorLock = void 0;
|
|
2234
2277
|
state.pendingNativeMVCPAdjust = void 0;
|
|
2235
2278
|
state.userScrollAnchorReset = { keys: /* @__PURE__ */ new Set() };
|
|
@@ -2238,6 +2281,7 @@ function updateScroll(ctx, newScroll, forceUpdate, options) {
|
|
|
2238
2281
|
state.queuedMVCPRecalculate = void 0;
|
|
2239
2282
|
}
|
|
2240
2283
|
flushSync(runCalculateItems);
|
|
2284
|
+
scheduleFullDrawDistancePrewarm(ctx);
|
|
2241
2285
|
} else {
|
|
2242
2286
|
runCalculateItems();
|
|
2243
2287
|
}
|
|
@@ -2392,16 +2436,17 @@ function dispatchInitialScroll(ctx, params) {
|
|
|
2392
2436
|
waitForInitialScrollCompletionFrame: waitForCompletionFrame
|
|
2393
2437
|
});
|
|
2394
2438
|
}
|
|
2395
|
-
function setInitialScrollTarget(
|
|
2439
|
+
function setInitialScrollTarget(ctx, target, options) {
|
|
2396
2440
|
var _a3;
|
|
2441
|
+
const { state } = ctx;
|
|
2397
2442
|
state.clearPreservedInitialScrollOnNextFinish = void 0;
|
|
2398
2443
|
if (state.timeoutPreservedInitialScrollClear !== void 0) {
|
|
2399
2444
|
clearTimeout(state.timeoutPreservedInitialScrollClear);
|
|
2400
2445
|
state.timeoutPreservedInitialScrollClear = void 0;
|
|
2401
2446
|
}
|
|
2402
2447
|
state.initialScroll = target;
|
|
2403
|
-
if (
|
|
2404
|
-
|
|
2448
|
+
if (options == null ? void 0 : options.resetDidFinish) {
|
|
2449
|
+
resetInitialRenderState(ctx, { resetInitialScroll: true });
|
|
2405
2450
|
}
|
|
2406
2451
|
setInitialScrollSession(state, {
|
|
2407
2452
|
kind: ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" ? "offset" : "bootstrap"
|
|
@@ -2455,7 +2500,7 @@ function advanceMeasuredInitialScroll(ctx, options) {
|
|
|
2455
2500
|
return false;
|
|
2456
2501
|
}
|
|
2457
2502
|
if (didOffsetChange && ((_b = state.initialScrollSession) == null ? void 0 : _b.kind) !== "offset") {
|
|
2458
|
-
setInitialScrollTarget(
|
|
2503
|
+
setInitialScrollTarget(ctx, { ...initialScroll, contentOffset: resolvedOffset });
|
|
2459
2504
|
}
|
|
2460
2505
|
const forceScroll = (_c = options == null ? void 0 : options.forceScroll) != null ? _c : !!queuedInitialLayout || isInitialScrollInProgress && didOffsetChange;
|
|
2461
2506
|
dispatchInitialScroll(ctx, {
|
|
@@ -2728,7 +2773,6 @@ function areEquivalentBootstrapInitialScrollTargets(current, next) {
|
|
|
2728
2773
|
}
|
|
2729
2774
|
function clearPendingInitialScrollFooterLayout(ctx, options) {
|
|
2730
2775
|
const { dataLength, stylePaddingBottom, target } = options;
|
|
2731
|
-
const state = ctx.state;
|
|
2732
2776
|
if (!shouldPreserveInitialScrollForFooterLayout(target)) {
|
|
2733
2777
|
return;
|
|
2734
2778
|
}
|
|
@@ -2738,7 +2782,7 @@ function clearPendingInitialScrollFooterLayout(ctx, options) {
|
|
|
2738
2782
|
preserveForFooterLayout: void 0,
|
|
2739
2783
|
stylePaddingBottom
|
|
2740
2784
|
});
|
|
2741
|
-
setInitialScrollTarget(
|
|
2785
|
+
setInitialScrollTarget(ctx, clearedFooterTarget);
|
|
2742
2786
|
}
|
|
2743
2787
|
function clearFinishedViewportRetargetableInitialScroll(state) {
|
|
2744
2788
|
clearPreservedInitialScrollTarget(state);
|
|
@@ -2885,7 +2929,7 @@ function handleBootstrapInitialScrollDataChange(ctx, options) {
|
|
|
2885
2929
|
return;
|
|
2886
2930
|
}
|
|
2887
2931
|
if (!areEquivalentBootstrapInitialScrollTargets(initialScroll, updatedInitialScroll) || !!bootstrapInitialScroll || shouldResetDidFinish || didDataChange) {
|
|
2888
|
-
setInitialScrollTarget(
|
|
2932
|
+
setInitialScrollTarget(ctx, updatedInitialScroll, {
|
|
2889
2933
|
resetDidFinish: shouldResetDidFinish
|
|
2890
2934
|
});
|
|
2891
2935
|
rearmBootstrapInitialScroll(ctx, {
|
|
@@ -2900,7 +2944,7 @@ function handleBootstrapInitialScrollDataChange(ctx, options) {
|
|
|
2900
2944
|
return;
|
|
2901
2945
|
}
|
|
2902
2946
|
if (bootstrapInitialScroll || shouldResetDidFinish) {
|
|
2903
|
-
setInitialScrollTarget(
|
|
2947
|
+
setInitialScrollTarget(ctx, initialScroll, {
|
|
2904
2948
|
resetDidFinish: shouldResetDidFinish
|
|
2905
2949
|
});
|
|
2906
2950
|
rearmBootstrapInitialScroll(ctx, {
|
|
@@ -2946,7 +2990,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2946
2990
|
});
|
|
2947
2991
|
} else {
|
|
2948
2992
|
const didFinishInitialScroll = !!state.didFinishInitialScroll;
|
|
2949
|
-
setInitialScrollTarget(
|
|
2993
|
+
setInitialScrollTarget(ctx, updatedInitialScroll, {
|
|
2950
2994
|
resetDidFinish: didFinishInitialScroll
|
|
2951
2995
|
});
|
|
2952
2996
|
rearmBootstrapInitialScroll(ctx, {
|
|
@@ -3135,7 +3179,7 @@ function initializeInitialScrollOnMount(ctx, options) {
|
|
|
3135
3179
|
const resolvedInitialContentOffset = initialContentOffset != null ? initialContentOffset : 0;
|
|
3136
3180
|
const preserveForFooterLayout = useBootstrapInitialScroll && initialScrollAtEnd && hasFooterComponent;
|
|
3137
3181
|
if (initialScroll && (initialScroll.contentOffset === void 0 || !!initialScroll.preserveForFooterLayout !== preserveForFooterLayout && ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) !== "offset")) {
|
|
3138
|
-
setInitialScrollTarget(
|
|
3182
|
+
setInitialScrollTarget(ctx, {
|
|
3139
3183
|
...initialScroll,
|
|
3140
3184
|
contentOffset: resolvedInitialContentOffset,
|
|
3141
3185
|
preserveForFooterLayout
|
|
@@ -3164,6 +3208,7 @@ function handleInitialScrollDataChange(ctx, options) {
|
|
|
3164
3208
|
const {
|
|
3165
3209
|
dataLength,
|
|
3166
3210
|
didDataChange,
|
|
3211
|
+
didStartFreshData,
|
|
3167
3212
|
initialScrollAtEnd,
|
|
3168
3213
|
latestInitialScroll,
|
|
3169
3214
|
latestInitialScrollSessionKind,
|
|
@@ -3171,17 +3216,17 @@ function handleInitialScrollDataChange(ctx, options) {
|
|
|
3171
3216
|
useBootstrapInitialScroll
|
|
3172
3217
|
} = options;
|
|
3173
3218
|
const state = ctx.state;
|
|
3174
|
-
const
|
|
3175
|
-
const
|
|
3219
|
+
const previousInitialScrollDataLength = (_b = (_a3 = state.initialScrollSession) == null ? void 0 : _a3.previousDataLength) != null ? _b : 0;
|
|
3220
|
+
const shouldUseLatestInitialScroll = dataLength > 0 && (!state.hasHadNonEmptyData || didStartFreshData);
|
|
3176
3221
|
if (dataLength > 0) {
|
|
3177
3222
|
state.hasHadNonEmptyData = true;
|
|
3178
3223
|
}
|
|
3179
|
-
if (
|
|
3224
|
+
if (shouldUseLatestInitialScroll) {
|
|
3180
3225
|
if (latestInitialScroll) {
|
|
3181
|
-
setInitialScrollTarget(
|
|
3226
|
+
setInitialScrollTarget(ctx, latestInitialScroll);
|
|
3182
3227
|
setInitialScrollSession(state, {
|
|
3183
3228
|
kind: latestInitialScrollSessionKind,
|
|
3184
|
-
previousDataLength
|
|
3229
|
+
previousDataLength: previousInitialScrollDataLength
|
|
3185
3230
|
});
|
|
3186
3231
|
} else {
|
|
3187
3232
|
clearPreservedInitialScrollTarget(state);
|
|
@@ -3196,17 +3241,17 @@ function handleInitialScrollDataChange(ctx, options) {
|
|
|
3196
3241
|
dataLength,
|
|
3197
3242
|
didDataChange,
|
|
3198
3243
|
initialScrollAtEnd,
|
|
3199
|
-
previousDataLength,
|
|
3244
|
+
previousDataLength: previousInitialScrollDataLength,
|
|
3200
3245
|
stylePaddingBottom
|
|
3201
3246
|
});
|
|
3202
3247
|
return;
|
|
3203
3248
|
}
|
|
3204
|
-
const shouldReplayFinishedOffsetInitialScroll =
|
|
3205
|
-
if (
|
|
3249
|
+
const shouldReplayFinishedOffsetInitialScroll = previousInitialScrollDataLength === 0 && dataLength > 0 && !!state.initialScroll && ((_c = ctx.state.initialScrollSession) == null ? void 0 : _c.kind) === "offset" && !!state.didFinishInitialScroll;
|
|
3250
|
+
if (previousInitialScrollDataLength !== 0 || dataLength === 0 || !state.initialScroll || !state.queuedInitialLayout || state.didFinishInitialScroll && !shouldReplayFinishedOffsetInitialScroll) {
|
|
3206
3251
|
return;
|
|
3207
3252
|
}
|
|
3208
3253
|
if (shouldReplayFinishedOffsetInitialScroll) {
|
|
3209
|
-
|
|
3254
|
+
resetInitialRenderState(ctx, { resetInitialScroll: true });
|
|
3210
3255
|
}
|
|
3211
3256
|
advanceCurrentInitialScrollSession(ctx);
|
|
3212
3257
|
}
|
|
@@ -4205,7 +4250,7 @@ function calculateItemsInView(ctx, params = {}) {
|
|
|
4205
4250
|
const stickyHeaderIndicesSet = state.props.stickyHeaderIndicesSet || /* @__PURE__ */ new Set();
|
|
4206
4251
|
const alwaysRenderArr = alwaysRenderIndicesArr || [];
|
|
4207
4252
|
const alwaysRenderSet = alwaysRenderIndicesSet || /* @__PURE__ */ new Set();
|
|
4208
|
-
const drawDistance = getEffectiveDrawDistance(ctx);
|
|
4253
|
+
const drawDistance = getEffectiveDrawDistance(ctx, params.drawDistanceMode);
|
|
4209
4254
|
const { dataChanged, doMVCP, forceFullItemPositions } = params;
|
|
4210
4255
|
const bootstrapInitialScrollState = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
|
|
4211
4256
|
const suppressInitialScrollSideEffects = !!bootstrapInitialScrollState;
|
|
@@ -6442,7 +6487,7 @@ var LegendList = typedMemo(
|
|
|
6442
6487
|
})
|
|
6443
6488
|
);
|
|
6444
6489
|
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
6445
|
-
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
6490
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
|
|
6446
6491
|
const noopOnScroll = React2.useCallback((_event) => {
|
|
6447
6492
|
}, []);
|
|
6448
6493
|
if (props.recycleItems === void 0) {
|
|
@@ -6459,6 +6504,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6459
6504
|
contentContainerStyle: contentContainerStyleProp,
|
|
6460
6505
|
contentInset,
|
|
6461
6506
|
data: dataProp = [],
|
|
6507
|
+
dataKey,
|
|
6462
6508
|
dataVersion,
|
|
6463
6509
|
drawDistance = 250,
|
|
6464
6510
|
contentInsetEndAdjustment,
|
|
@@ -6589,6 +6635,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6589
6635
|
(_j = alwaysRender == null ? void 0 : alwaysRender.indices) == null ? void 0 : _j.join(","),
|
|
6590
6636
|
(_k = alwaysRender == null ? void 0 : alwaysRender.keys) == null ? void 0 : _k.join(","),
|
|
6591
6637
|
dataProp,
|
|
6638
|
+
dataKey,
|
|
6592
6639
|
dataVersion,
|
|
6593
6640
|
keyExtractor
|
|
6594
6641
|
]);
|
|
@@ -6611,6 +6658,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6611
6658
|
dataChangeNeedsScrollUpdate: false,
|
|
6612
6659
|
didColumnsChange: false,
|
|
6613
6660
|
didDataChange: false,
|
|
6661
|
+
didLoad: false,
|
|
6614
6662
|
enableScrollForNextCalculateItemsInView: true,
|
|
6615
6663
|
endBuffered: -1,
|
|
6616
6664
|
endNoBuffer: -1,
|
|
@@ -6640,6 +6688,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6640
6688
|
positions: [],
|
|
6641
6689
|
props: {},
|
|
6642
6690
|
queuedCalculateItemsInView: 0,
|
|
6691
|
+
queuedFullDrawDistancePrewarm: void 0,
|
|
6643
6692
|
refScroller: { current: null },
|
|
6644
6693
|
scroll: 0,
|
|
6645
6694
|
scrollAdjustHandler: new ScrollAdjustHandler(ctx),
|
|
@@ -6682,10 +6731,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6682
6731
|
const didScrollAxisGapChange = !isFirstLocal && ctx.scrollAxisGap !== nextScrollAxisGap;
|
|
6683
6732
|
ctx.scrollAxisGap = nextScrollAxisGap;
|
|
6684
6733
|
state.didColumnsChange = numColumnsProp !== previousNumColumnsProp || didScrollAxisGapChange;
|
|
6734
|
+
const previousDataLength = (_n = (_m = state.props.data) == null ? void 0 : _m.length) != null ? _n : 0;
|
|
6685
6735
|
const didDataReferenceChangeLocal = state.props.data !== dataProp;
|
|
6736
|
+
const didDataKeyChangeLocal = state.props.dataKey !== dataKey;
|
|
6686
6737
|
const didDataVersionChangeLocal = state.props.dataVersion !== dataVersion;
|
|
6687
|
-
const didDataChangeLocal = didDataVersionChangeLocal || didDataReferenceChangeLocal && checkStructuralDataChange(state, dataProp, state.props.data);
|
|
6688
|
-
|
|
6738
|
+
const didDataChangeLocal = didDataKeyChangeLocal || didDataVersionChangeLocal || didDataReferenceChangeLocal && checkStructuralDataChange(state, dataProp, state.props.data);
|
|
6739
|
+
const shouldResetFreshDataLayout = !isFirstLocal && didDataChangeLocal && state.hasHadNonEmptyData && (didDataKeyChangeLocal || previousDataLength === 0) && dataProp.length > 0;
|
|
6740
|
+
if (didDataChangeLocal && !initialScrollAtEnd && state.didFinishInitialScroll && ((_o = state.initialScroll) == null ? void 0 : _o.viewPosition) === 1 && state.props.data.length > 0) {
|
|
6689
6741
|
clearPreservedInitialScrollTarget(state);
|
|
6690
6742
|
}
|
|
6691
6743
|
if (didDataChangeLocal) {
|
|
@@ -6697,7 +6749,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6697
6749
|
const throttledOnScroll = useThrottledOnScroll(onScrollProp != null ? onScrollProp : noopOnScroll, scrollEventThrottle != null ? scrollEventThrottle : 0);
|
|
6698
6750
|
const throttleScrollFn = scrollEventThrottle && onScrollProp ? throttledOnScroll : onScrollProp;
|
|
6699
6751
|
const anchoredEndSpaceResolved = Platform.OS === "web" && anchoredEndSpace ? { ...anchoredEndSpace, includeInEndInset: true } : anchoredEndSpace;
|
|
6700
|
-
const didAnchoredEndSpaceAnchorIndexChange = !isFirstLocal && !didDataChangeLocal && ((
|
|
6752
|
+
const didAnchoredEndSpaceAnchorIndexChange = !isFirstLocal && !didDataChangeLocal && ((_p = state.props.anchoredEndSpace) == null ? void 0 : _p.anchorIndex) !== (anchoredEndSpaceResolved == null ? void 0 : anchoredEndSpaceResolved.anchorIndex);
|
|
6701
6753
|
state.props = {
|
|
6702
6754
|
adaptiveRender: experimental_adaptiveRender,
|
|
6703
6755
|
alignItemsAtEnd,
|
|
@@ -6711,6 +6763,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6711
6763
|
contentInset,
|
|
6712
6764
|
contentInsetEndAdjustment: contentInsetEndAdjustmentResolved,
|
|
6713
6765
|
data: dataProp,
|
|
6766
|
+
dataKey,
|
|
6714
6767
|
dataVersion,
|
|
6715
6768
|
drawDistance,
|
|
6716
6769
|
estimatedItemSize,
|
|
@@ -6751,13 +6804,19 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6751
6804
|
if (!isFirstLocal && previousAdaptiveRender && !experimental_adaptiveRender) {
|
|
6752
6805
|
resetAdaptiveRender(ctx);
|
|
6753
6806
|
}
|
|
6807
|
+
if (shouldResetFreshDataLayout) {
|
|
6808
|
+
resetInitialRenderState(ctx, {
|
|
6809
|
+
resetInitialScroll: !!initialScrollProp,
|
|
6810
|
+
resetLayout: true
|
|
6811
|
+
});
|
|
6812
|
+
}
|
|
6754
6813
|
const memoizedLastItemKeys = React2.useMemo(() => {
|
|
6755
6814
|
if (!dataProp.length) return [];
|
|
6756
6815
|
return Array.from(
|
|
6757
6816
|
{ length: Math.min(numColumnsProp, dataProp.length) },
|
|
6758
6817
|
(_, i) => getId(state, dataProp.length - 1 - i)
|
|
6759
6818
|
);
|
|
6760
|
-
}, [dataProp, dataVersion, numColumnsProp]);
|
|
6819
|
+
}, [dataProp, dataKey, dataVersion, numColumnsProp]);
|
|
6761
6820
|
const initializeStateVars = (shouldAdjustPadding) => {
|
|
6762
6821
|
set$(ctx, "lastItemKeys", memoizedLastItemKeys);
|
|
6763
6822
|
set$(ctx, "numColumns", numColumnsProp);
|
|
@@ -6817,13 +6876,22 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6817
6876
|
handleInitialScrollDataChange(ctx, {
|
|
6818
6877
|
dataLength: dataProp.length,
|
|
6819
6878
|
didDataChange: didDataChangeLocal,
|
|
6879
|
+
didStartFreshData: shouldResetFreshDataLayout,
|
|
6820
6880
|
initialScrollAtEnd,
|
|
6821
6881
|
latestInitialScroll: initialScrollProp,
|
|
6822
6882
|
latestInitialScrollSessionKind: initialScrollUsesOffsetOnly ? "offset" : "bootstrap",
|
|
6823
6883
|
stylePaddingBottom: stylePaddingBottomState,
|
|
6824
6884
|
useBootstrapInitialScroll: usesBootstrapInitialScroll
|
|
6825
6885
|
});
|
|
6826
|
-
}, [
|
|
6886
|
+
}, [
|
|
6887
|
+
dataProp.length,
|
|
6888
|
+
dataKey,
|
|
6889
|
+
didDataChangeLocal,
|
|
6890
|
+
shouldResetFreshDataLayout,
|
|
6891
|
+
initialScrollAtEnd,
|
|
6892
|
+
stylePaddingBottomState,
|
|
6893
|
+
usesBootstrapInitialScroll
|
|
6894
|
+
]);
|
|
6827
6895
|
React2.useLayoutEffect(() => {
|
|
6828
6896
|
var _a4;
|
|
6829
6897
|
if (didAnchoredEndSpaceAnchorIndexChange) {
|
|
@@ -6891,6 +6959,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6891
6959
|
React2.useLayoutEffect(
|
|
6892
6960
|
() => initializeStateVars(true),
|
|
6893
6961
|
[
|
|
6962
|
+
dataKey,
|
|
6894
6963
|
dataVersion,
|
|
6895
6964
|
memoizedLastItemKeys.join(","),
|
|
6896
6965
|
numColumnsProp,
|
|
@@ -6917,7 +6986,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6917
6986
|
state.didColumnsChange = false;
|
|
6918
6987
|
state.didDataChange = false;
|
|
6919
6988
|
state.isFirst = false;
|
|
6920
|
-
}, [dataProp, dataVersion, numColumnsProp, nextScrollAxisGap]);
|
|
6989
|
+
}, [dataProp, dataKey, dataVersion, numColumnsProp, nextScrollAxisGap]);
|
|
6921
6990
|
React2.useLayoutEffect(() => {
|
|
6922
6991
|
var _a4;
|
|
6923
6992
|
set$(ctx, "extraData", extraData);
|
|
@@ -6970,6 +7039,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
6970
7039
|
React2.useImperativeHandle(forwardedRef, () => createImperativeHandle(ctx, scheduleImperativeScrollCommit), []);
|
|
6971
7040
|
React2.useEffect(() => {
|
|
6972
7041
|
return () => {
|
|
7042
|
+
if (state.queuedFullDrawDistancePrewarm !== void 0) {
|
|
7043
|
+
cancelAnimationFrame(state.queuedFullDrawDistancePrewarm);
|
|
7044
|
+
state.queuedFullDrawDistancePrewarm = void 0;
|
|
7045
|
+
}
|
|
6973
7046
|
for (const timeout of state.timeouts) {
|
|
6974
7047
|
clearTimeout(timeout);
|
|
6975
7048
|
}
|
|
@@ -7022,7 +7095,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7022
7095
|
onScroll: onScrollHandler,
|
|
7023
7096
|
recycleItems,
|
|
7024
7097
|
refreshControl: refreshControlElement ? stylePaddingTopState > 0 ? React2__namespace.cloneElement(refreshControlElement, {
|
|
7025
|
-
progressViewOffset: ((
|
|
7098
|
+
progressViewOffset: ((_q = refreshControlElement.props.progressViewOffset) != null ? _q : 0) + stylePaddingTopState
|
|
7026
7099
|
}) : refreshControlElement : onRefresh && /* @__PURE__ */ React2__namespace.createElement(
|
|
7027
7100
|
ReactNative.RefreshControl,
|
|
7028
7101
|
{
|
|
@@ -7033,7 +7106,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
7033
7106
|
),
|
|
7034
7107
|
refScrollView: combinedRef,
|
|
7035
7108
|
renderScrollComponent,
|
|
7036
|
-
scrollAdjustHandler: (
|
|
7109
|
+
scrollAdjustHandler: (_r = refState.current) == null ? void 0 : _r.scrollAdjustHandler,
|
|
7037
7110
|
scrollEventThrottle: 0,
|
|
7038
7111
|
snapToIndices,
|
|
7039
7112
|
stickyHeaderIndices,
|