@legendapp/list 3.0.0-beta.55 → 3.0.0-beta.56
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/animated.d.ts +3 -5
- package/index.d.ts +9 -6
- package/index.js +83 -23
- package/index.mjs +84 -24
- package/index.native.js +86 -21
- package/index.native.mjs +87 -22
- package/package.json +1 -1
- package/react-native.d.ts +3 -5
- package/react-native.js +88 -21
- package/react-native.mjs +89 -22
- package/react-native.web.d.ts +3 -5
- package/react-native.web.js +85 -23
- package/react-native.web.mjs +86 -24
- package/react.d.ts +3 -5
- package/react.js +85 -23
- package/react.mjs +86 -24
- package/reanimated.d.ts +3 -5
- package/reanimated.js +9 -8
- package/reanimated.mjs +9 -8
- package/section-list.d.ts +3 -5
package/index.native.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React2 from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useLayoutEffect, useImperativeHandle, useContext } from 'react';
|
|
3
3
|
import * as ReactNative from 'react-native';
|
|
4
4
|
import { Animated, Platform as Platform$1, View as View$1, Text as Text$1, StyleSheet as StyleSheet$1, RefreshControl, Dimensions, I18nManager } from 'react-native';
|
|
5
5
|
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
@@ -1120,6 +1120,26 @@ function WebAnchoredEndSpace({ horizontal }) {
|
|
|
1120
1120
|
const style = horizontal ? { height: "100%", width: anchoredEndSpaceSize || 0 } : { height: anchoredEndSpaceSize || 0 };
|
|
1121
1121
|
return /* @__PURE__ */ React2.createElement("div", { style }, null);
|
|
1122
1122
|
}
|
|
1123
|
+
function useLatestRef(value) {
|
|
1124
|
+
const ref = React2.useRef(value);
|
|
1125
|
+
ref.current = value;
|
|
1126
|
+
return ref;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// src/hooks/useStableRenderComponent.tsx
|
|
1130
|
+
function useStableRenderComponent(renderComponent, mapProps) {
|
|
1131
|
+
const renderComponentRef = useLatestRef(renderComponent);
|
|
1132
|
+
const mapPropsRef = useLatestRef(mapProps);
|
|
1133
|
+
return React2.useMemo(
|
|
1134
|
+
() => React2.forwardRef(
|
|
1135
|
+
(props, ref) => {
|
|
1136
|
+
var _a3, _b;
|
|
1137
|
+
return (_b = (_a3 = renderComponentRef.current) == null ? void 0 : _a3.call(renderComponentRef, mapPropsRef.current(props, ref))) != null ? _b : null;
|
|
1138
|
+
}
|
|
1139
|
+
),
|
|
1140
|
+
[mapPropsRef, renderComponentRef]
|
|
1141
|
+
);
|
|
1142
|
+
}
|
|
1123
1143
|
var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
|
|
1124
1144
|
const localRef = useRef(null);
|
|
1125
1145
|
const ref = refView != null ? refView : localRef;
|
|
@@ -1164,14 +1184,11 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1164
1184
|
needsOtherAxisSize: ctx.state.needsOtherAxisSize,
|
|
1165
1185
|
otherAxisSize
|
|
1166
1186
|
});
|
|
1167
|
-
const
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
(props, ref) => renderScrollComponent({ ...props, ref })
|
|
1173
|
-
);
|
|
1174
|
-
}, [renderScrollComponent]);
|
|
1187
|
+
const CustomScrollComponent = useStableRenderComponent(
|
|
1188
|
+
renderScrollComponent,
|
|
1189
|
+
(props, ref) => ({ ...props, ref })
|
|
1190
|
+
);
|
|
1191
|
+
const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
|
|
1175
1192
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
1176
1193
|
useLayoutEffect(() => {
|
|
1177
1194
|
if (!ListHeaderComponent) {
|
|
@@ -2652,11 +2669,51 @@ function getObservedBootstrapInitialScrollOffset(state) {
|
|
|
2652
2669
|
const observedOffset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getCurrentScrollOffset) == null ? void 0 : _b.call(_a3);
|
|
2653
2670
|
return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
|
|
2654
2671
|
}
|
|
2672
|
+
function getPreservedEndAnchorOffsetDiff(ctx) {
|
|
2673
|
+
var _a3;
|
|
2674
|
+
const state = ctx.state;
|
|
2675
|
+
const initialScroll = state.initialScroll;
|
|
2676
|
+
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
|
|
2677
|
+
return;
|
|
2678
|
+
}
|
|
2679
|
+
const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
|
|
2680
|
+
return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
|
|
2681
|
+
}
|
|
2682
|
+
function schedulePreservedEndAnchorCorrection(ctx) {
|
|
2683
|
+
if (getPreservedEndAnchorOffsetDiff(ctx) === void 0) {
|
|
2684
|
+
return false;
|
|
2685
|
+
}
|
|
2686
|
+
const correction = {};
|
|
2687
|
+
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
2688
|
+
return true;
|
|
2689
|
+
}
|
|
2690
|
+
function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
|
|
2691
|
+
const state = ctx.state;
|
|
2692
|
+
state.preservedEndAnchorCorrection = correction;
|
|
2693
|
+
requestAnimationFrame(() => {
|
|
2694
|
+
var _a3;
|
|
2695
|
+
const activeCorrection = state.preservedEndAnchorCorrection;
|
|
2696
|
+
if (activeCorrection !== correction) {
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
const offsetDiff = getPreservedEndAnchorOffsetDiff(ctx);
|
|
2700
|
+
if (offsetDiff === void 0 || Math.abs(offsetDiff) <= DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
|
|
2701
|
+
state.preservedEndAnchorCorrection = void 0;
|
|
2702
|
+
return;
|
|
2703
|
+
}
|
|
2704
|
+
const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
|
|
2705
|
+
if (hasObservedNativeScrollAfterRequest) {
|
|
2706
|
+
activeCorrection.lastRequestTime = Date.now();
|
|
2707
|
+
requestAdjust(ctx, offsetDiff);
|
|
2708
|
+
}
|
|
2709
|
+
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
2710
|
+
});
|
|
2711
|
+
}
|
|
2655
2712
|
function clearFinishedBootstrapInitialScrollTargetIfMovedAway(ctx) {
|
|
2656
2713
|
var _a3, _b;
|
|
2657
2714
|
const state = ctx.state;
|
|
2658
2715
|
const initialScroll = state.initialScroll;
|
|
2659
|
-
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1) {
|
|
2716
|
+
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1 || state.preservedEndAnchorCorrection) {
|
|
2660
2717
|
return;
|
|
2661
2718
|
}
|
|
2662
2719
|
if (didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
|
|
@@ -2813,7 +2870,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2813
2870
|
}
|
|
2814
2871
|
}
|
|
2815
2872
|
function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
2816
|
-
var _a3, _b, _c
|
|
2873
|
+
var _a3, _b, _c;
|
|
2817
2874
|
const state = ctx.state;
|
|
2818
2875
|
const initialScroll = state.initialScroll;
|
|
2819
2876
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
@@ -2824,7 +2881,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2824
2881
|
const currentOffset = scrollingTo ? (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset : getObservedBootstrapInitialScrollOffset(state);
|
|
2825
2882
|
const offsetDiff = resolvedOffset - currentOffset;
|
|
2826
2883
|
if (Math.abs(offsetDiff) > DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
|
|
2827
|
-
if (
|
|
2884
|
+
if (state.didFinishInitialScroll) {
|
|
2885
|
+
schedulePreservedEndAnchorCorrection(ctx);
|
|
2886
|
+
} else if (scrollingTo) {
|
|
2828
2887
|
const existingWatchdog = initialScrollWatchdog.get(state);
|
|
2829
2888
|
scrollingTo.offset = resolvedOffset;
|
|
2830
2889
|
scrollingTo.targetOffset = resolvedOffset;
|
|
@@ -2837,14 +2896,8 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2837
2896
|
startScroll: (_c = existingWatchdog == null ? void 0 : existingWatchdog.startScroll) != null ? _c : state.scroll,
|
|
2838
2897
|
targetOffset: resolvedOffset
|
|
2839
2898
|
});
|
|
2899
|
+
requestAdjust(ctx, offsetDiff);
|
|
2840
2900
|
}
|
|
2841
|
-
requestAdjust(ctx, offsetDiff);
|
|
2842
|
-
if (state.didFinishInitialScroll) {
|
|
2843
|
-
(_d = state.triggerCalculateItemsInView) == null ? void 0 : _d.call(state, { forceFullItemPositions: true });
|
|
2844
|
-
}
|
|
2845
|
-
}
|
|
2846
|
-
if (state.didFinishInitialScroll) {
|
|
2847
|
-
clearFinishedViewportRetargetableInitialScroll(state);
|
|
2848
2901
|
}
|
|
2849
2902
|
} else {
|
|
2850
2903
|
rearmBootstrapInitialScroll(ctx, {
|
|
@@ -2961,7 +3014,10 @@ function retargetActiveInitialScrollAtEnd(ctx) {
|
|
|
2961
3014
|
var _a3;
|
|
2962
3015
|
const state = ctx.state;
|
|
2963
3016
|
const initialScroll = state.initialScroll;
|
|
2964
|
-
if (
|
|
3017
|
+
if (state.didFinishInitialScroll) {
|
|
3018
|
+
return schedulePreservedEndAnchorCorrection(ctx);
|
|
3019
|
+
}
|
|
3020
|
+
if (!initialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
|
|
2965
3021
|
return false;
|
|
2966
3022
|
}
|
|
2967
3023
|
return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
|
|
@@ -4975,7 +5031,7 @@ function cloneScrollEvent(event) {
|
|
|
4975
5031
|
};
|
|
4976
5032
|
}
|
|
4977
5033
|
function onScroll(ctx, event) {
|
|
4978
|
-
var _a3, _b, _c, _d, _e;
|
|
5034
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4979
5035
|
const state = ctx.state;
|
|
4980
5036
|
const { scrollProcessingEnabled } = state;
|
|
4981
5037
|
if (scrollProcessingEnabled === false) {
|
|
@@ -4997,6 +5053,13 @@ function onScroll(ctx, event) {
|
|
|
4997
5053
|
if (state.props.horizontal) {
|
|
4998
5054
|
newScroll = toLogicalHorizontalOffset(state, newScroll, (_e = event.nativeEvent.contentSize) == null ? void 0 : _e.width);
|
|
4999
5055
|
}
|
|
5056
|
+
const isFinishedEndInitialScroll = state.didFinishInitialScroll && ((_f = state.initialScroll) == null ? void 0 : _f.viewPosition) === 1 && state.scroll > state.scrollLength;
|
|
5057
|
+
const shouldIgnoreNegativeInsetChange = Platform.OS !== "web" && insetChanged && newScroll < 0 && isFinishedEndInitialScroll;
|
|
5058
|
+
if (shouldIgnoreNegativeInsetChange) {
|
|
5059
|
+
return;
|
|
5060
|
+
}
|
|
5061
|
+
state.lastNativeScroll = newScroll;
|
|
5062
|
+
state.lastNativeScrollTime = Date.now();
|
|
5000
5063
|
if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
|
|
5001
5064
|
const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
|
|
5002
5065
|
if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
|
|
@@ -5637,6 +5700,8 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
|
|
|
5637
5700
|
indices.sort(sortAsc);
|
|
5638
5701
|
return indices;
|
|
5639
5702
|
}
|
|
5703
|
+
|
|
5704
|
+
// src/utils/getRenderedItem.ts
|
|
5640
5705
|
function getRenderedItem(ctx, key) {
|
|
5641
5706
|
var _a3;
|
|
5642
5707
|
const state = ctx.state;
|
|
@@ -5662,7 +5727,7 @@ function getRenderedItem(ctx, key) {
|
|
|
5662
5727
|
item,
|
|
5663
5728
|
type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
|
|
5664
5729
|
};
|
|
5665
|
-
renderedItem =
|
|
5730
|
+
renderedItem = renderItem(itemProps);
|
|
5666
5731
|
}
|
|
5667
5732
|
return { index, item: data[index], renderedItem };
|
|
5668
5733
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legendapp/list",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.56",
|
|
4
4
|
"description": "Legend List is a drop-in replacement for FlatList with much better performance and supporting dynamically sized items.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"private": false,
|
package/react-native.d.ts
CHANGED
|
@@ -97,13 +97,11 @@ interface DataModeProps<ItemT, TItemType extends string | undefined> {
|
|
|
97
97
|
*/
|
|
98
98
|
data: ReadonlyArray<ItemT>;
|
|
99
99
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* - A function: (props: LegendListRenderItemProps<ItemT>) => ReactNode
|
|
103
|
-
* - A React component: React.ComponentType<LegendListRenderItemProps<ItemT>>
|
|
100
|
+
* Callback to render each item in the list.
|
|
101
|
+
* To use hooks in an item component, return that component from this callback.
|
|
104
102
|
* @required when using data mode
|
|
105
103
|
*/
|
|
106
|
-
renderItem: (
|
|
104
|
+
renderItem: (props: LegendListRenderItemProps<ItemT, TItemType>) => React.ReactNode;
|
|
107
105
|
children?: never;
|
|
108
106
|
}
|
|
109
107
|
interface ChildrenModeProps {
|
package/react-native.js
CHANGED
|
@@ -1141,6 +1141,26 @@ function WebAnchoredEndSpace({ horizontal }) {
|
|
|
1141
1141
|
const style = horizontal ? { height: "100%", width: anchoredEndSpaceSize || 0 } : { height: anchoredEndSpaceSize || 0 };
|
|
1142
1142
|
return /* @__PURE__ */ React2__namespace.createElement("div", { style }, null);
|
|
1143
1143
|
}
|
|
1144
|
+
function useLatestRef(value) {
|
|
1145
|
+
const ref = React2__namespace.useRef(value);
|
|
1146
|
+
ref.current = value;
|
|
1147
|
+
return ref;
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
// src/hooks/useStableRenderComponent.tsx
|
|
1151
|
+
function useStableRenderComponent(renderComponent, mapProps) {
|
|
1152
|
+
const renderComponentRef = useLatestRef(renderComponent);
|
|
1153
|
+
const mapPropsRef = useLatestRef(mapProps);
|
|
1154
|
+
return React2__namespace.useMemo(
|
|
1155
|
+
() => React2__namespace.forwardRef(
|
|
1156
|
+
(props, ref) => {
|
|
1157
|
+
var _a3, _b;
|
|
1158
|
+
return (_b = (_a3 = renderComponentRef.current) == null ? void 0 : _a3.call(renderComponentRef, mapPropsRef.current(props, ref))) != null ? _b : null;
|
|
1159
|
+
}
|
|
1160
|
+
),
|
|
1161
|
+
[mapPropsRef, renderComponentRef]
|
|
1162
|
+
);
|
|
1163
|
+
}
|
|
1144
1164
|
var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
|
|
1145
1165
|
const localRef = React2.useRef(null);
|
|
1146
1166
|
const ref = refView != null ? refView : localRef;
|
|
@@ -1185,14 +1205,11 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1185
1205
|
needsOtherAxisSize: ctx.state.needsOtherAxisSize,
|
|
1186
1206
|
otherAxisSize
|
|
1187
1207
|
});
|
|
1188
|
-
const
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
(props, ref) => renderScrollComponent({ ...props, ref })
|
|
1194
|
-
);
|
|
1195
|
-
}, [renderScrollComponent]);
|
|
1208
|
+
const CustomScrollComponent = useStableRenderComponent(
|
|
1209
|
+
renderScrollComponent,
|
|
1210
|
+
(props, ref) => ({ ...props, ref })
|
|
1211
|
+
);
|
|
1212
|
+
const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
|
|
1196
1213
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
1197
1214
|
React2.useLayoutEffect(() => {
|
|
1198
1215
|
if (!ListHeaderComponent) {
|
|
@@ -2673,11 +2690,51 @@ function getObservedBootstrapInitialScrollOffset(state) {
|
|
|
2673
2690
|
const observedOffset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getCurrentScrollOffset) == null ? void 0 : _b.call(_a3);
|
|
2674
2691
|
return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
|
|
2675
2692
|
}
|
|
2693
|
+
function getPreservedEndAnchorOffsetDiff(ctx) {
|
|
2694
|
+
var _a3;
|
|
2695
|
+
const state = ctx.state;
|
|
2696
|
+
const initialScroll = state.initialScroll;
|
|
2697
|
+
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
|
|
2698
|
+
return;
|
|
2699
|
+
}
|
|
2700
|
+
const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
|
|
2701
|
+
return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
|
|
2702
|
+
}
|
|
2703
|
+
function schedulePreservedEndAnchorCorrection(ctx) {
|
|
2704
|
+
if (getPreservedEndAnchorOffsetDiff(ctx) === void 0) {
|
|
2705
|
+
return false;
|
|
2706
|
+
}
|
|
2707
|
+
const correction = {};
|
|
2708
|
+
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
2709
|
+
return true;
|
|
2710
|
+
}
|
|
2711
|
+
function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
|
|
2712
|
+
const state = ctx.state;
|
|
2713
|
+
state.preservedEndAnchorCorrection = correction;
|
|
2714
|
+
requestAnimationFrame(() => {
|
|
2715
|
+
var _a3;
|
|
2716
|
+
const activeCorrection = state.preservedEndAnchorCorrection;
|
|
2717
|
+
if (activeCorrection !== correction) {
|
|
2718
|
+
return;
|
|
2719
|
+
}
|
|
2720
|
+
const offsetDiff = getPreservedEndAnchorOffsetDiff(ctx);
|
|
2721
|
+
if (offsetDiff === void 0 || Math.abs(offsetDiff) <= DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
|
|
2722
|
+
state.preservedEndAnchorCorrection = void 0;
|
|
2723
|
+
return;
|
|
2724
|
+
}
|
|
2725
|
+
const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
|
|
2726
|
+
if (hasObservedNativeScrollAfterRequest) {
|
|
2727
|
+
activeCorrection.lastRequestTime = Date.now();
|
|
2728
|
+
requestAdjust(ctx, offsetDiff);
|
|
2729
|
+
}
|
|
2730
|
+
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
2731
|
+
});
|
|
2732
|
+
}
|
|
2676
2733
|
function clearFinishedBootstrapInitialScrollTargetIfMovedAway(ctx) {
|
|
2677
2734
|
var _a3, _b;
|
|
2678
2735
|
const state = ctx.state;
|
|
2679
2736
|
const initialScroll = state.initialScroll;
|
|
2680
|
-
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1) {
|
|
2737
|
+
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1 || state.preservedEndAnchorCorrection) {
|
|
2681
2738
|
return;
|
|
2682
2739
|
}
|
|
2683
2740
|
if (didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
|
|
@@ -2834,7 +2891,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2834
2891
|
}
|
|
2835
2892
|
}
|
|
2836
2893
|
function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
2837
|
-
var _a3, _b, _c
|
|
2894
|
+
var _a3, _b, _c;
|
|
2838
2895
|
const state = ctx.state;
|
|
2839
2896
|
const initialScroll = state.initialScroll;
|
|
2840
2897
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
@@ -2845,7 +2902,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2845
2902
|
const currentOffset = scrollingTo ? (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset : getObservedBootstrapInitialScrollOffset(state);
|
|
2846
2903
|
const offsetDiff = resolvedOffset - currentOffset;
|
|
2847
2904
|
if (Math.abs(offsetDiff) > DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
|
|
2848
|
-
if (
|
|
2905
|
+
if (state.didFinishInitialScroll) {
|
|
2906
|
+
schedulePreservedEndAnchorCorrection(ctx);
|
|
2907
|
+
} else if (scrollingTo) {
|
|
2849
2908
|
const existingWatchdog = initialScrollWatchdog.get(state);
|
|
2850
2909
|
scrollingTo.offset = resolvedOffset;
|
|
2851
2910
|
scrollingTo.targetOffset = resolvedOffset;
|
|
@@ -2858,14 +2917,8 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2858
2917
|
startScroll: (_c = existingWatchdog == null ? void 0 : existingWatchdog.startScroll) != null ? _c : state.scroll,
|
|
2859
2918
|
targetOffset: resolvedOffset
|
|
2860
2919
|
});
|
|
2920
|
+
requestAdjust(ctx, offsetDiff);
|
|
2861
2921
|
}
|
|
2862
|
-
requestAdjust(ctx, offsetDiff);
|
|
2863
|
-
if (state.didFinishInitialScroll) {
|
|
2864
|
-
(_d = state.triggerCalculateItemsInView) == null ? void 0 : _d.call(state, { forceFullItemPositions: true });
|
|
2865
|
-
}
|
|
2866
|
-
}
|
|
2867
|
-
if (state.didFinishInitialScroll) {
|
|
2868
|
-
clearFinishedViewportRetargetableInitialScroll(state);
|
|
2869
2922
|
}
|
|
2870
2923
|
} else {
|
|
2871
2924
|
rearmBootstrapInitialScroll(ctx, {
|
|
@@ -2982,7 +3035,10 @@ function retargetActiveInitialScrollAtEnd(ctx) {
|
|
|
2982
3035
|
var _a3;
|
|
2983
3036
|
const state = ctx.state;
|
|
2984
3037
|
const initialScroll = state.initialScroll;
|
|
2985
|
-
if (
|
|
3038
|
+
if (state.didFinishInitialScroll) {
|
|
3039
|
+
return schedulePreservedEndAnchorCorrection(ctx);
|
|
3040
|
+
}
|
|
3041
|
+
if (!initialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
|
|
2986
3042
|
return false;
|
|
2987
3043
|
}
|
|
2988
3044
|
return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
|
|
@@ -4996,7 +5052,7 @@ function cloneScrollEvent(event) {
|
|
|
4996
5052
|
};
|
|
4997
5053
|
}
|
|
4998
5054
|
function onScroll(ctx, event) {
|
|
4999
|
-
var _a3, _b, _c, _d, _e;
|
|
5055
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
5000
5056
|
const state = ctx.state;
|
|
5001
5057
|
const { scrollProcessingEnabled } = state;
|
|
5002
5058
|
if (scrollProcessingEnabled === false) {
|
|
@@ -5018,6 +5074,13 @@ function onScroll(ctx, event) {
|
|
|
5018
5074
|
if (state.props.horizontal) {
|
|
5019
5075
|
newScroll = toLogicalHorizontalOffset(state, newScroll, (_e = event.nativeEvent.contentSize) == null ? void 0 : _e.width);
|
|
5020
5076
|
}
|
|
5077
|
+
const isFinishedEndInitialScroll = state.didFinishInitialScroll && ((_f = state.initialScroll) == null ? void 0 : _f.viewPosition) === 1 && state.scroll > state.scrollLength;
|
|
5078
|
+
const shouldIgnoreNegativeInsetChange = Platform.OS !== "web" && insetChanged && newScroll < 0 && isFinishedEndInitialScroll;
|
|
5079
|
+
if (shouldIgnoreNegativeInsetChange) {
|
|
5080
|
+
return;
|
|
5081
|
+
}
|
|
5082
|
+
state.lastNativeScroll = newScroll;
|
|
5083
|
+
state.lastNativeScrollTime = Date.now();
|
|
5021
5084
|
if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
|
|
5022
5085
|
const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
|
|
5023
5086
|
if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
|
|
@@ -5658,6 +5721,8 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
|
|
|
5658
5721
|
indices.sort(sortAsc);
|
|
5659
5722
|
return indices;
|
|
5660
5723
|
}
|
|
5724
|
+
|
|
5725
|
+
// src/utils/getRenderedItem.ts
|
|
5661
5726
|
function getRenderedItem(ctx, key) {
|
|
5662
5727
|
var _a3;
|
|
5663
5728
|
const state = ctx.state;
|
|
@@ -5683,7 +5748,7 @@ function getRenderedItem(ctx, key) {
|
|
|
5683
5748
|
item,
|
|
5684
5749
|
type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
|
|
5685
5750
|
};
|
|
5686
|
-
renderedItem =
|
|
5751
|
+
renderedItem = renderItem(itemProps);
|
|
5687
5752
|
}
|
|
5688
5753
|
return { index, item: data[index], renderedItem };
|
|
5689
5754
|
}
|
|
@@ -6393,6 +6458,8 @@ var internal = {
|
|
|
6393
6458
|
typedMemo,
|
|
6394
6459
|
useArr$,
|
|
6395
6460
|
useCombinedRef,
|
|
6461
|
+
useLatestRef,
|
|
6462
|
+
useStableRenderComponent,
|
|
6396
6463
|
useStateContext
|
|
6397
6464
|
};
|
|
6398
6465
|
|
package/react-native.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React2 from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { useReducer, useEffect, createContext, useRef, useState, useMemo, useCallback, useLayoutEffect, useImperativeHandle, useContext } from 'react';
|
|
3
3
|
import * as ReactNative from 'react-native';
|
|
4
4
|
import { Animated, Platform as Platform$1, View as View$1, Text as Text$1, StyleSheet as StyleSheet$1, RefreshControl, Dimensions, I18nManager } from 'react-native';
|
|
5
5
|
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
@@ -1120,6 +1120,26 @@ function WebAnchoredEndSpace({ horizontal }) {
|
|
|
1120
1120
|
const style = horizontal ? { height: "100%", width: anchoredEndSpaceSize || 0 } : { height: anchoredEndSpaceSize || 0 };
|
|
1121
1121
|
return /* @__PURE__ */ React2.createElement("div", { style }, null);
|
|
1122
1122
|
}
|
|
1123
|
+
function useLatestRef(value) {
|
|
1124
|
+
const ref = React2.useRef(value);
|
|
1125
|
+
ref.current = value;
|
|
1126
|
+
return ref;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// src/hooks/useStableRenderComponent.tsx
|
|
1130
|
+
function useStableRenderComponent(renderComponent, mapProps) {
|
|
1131
|
+
const renderComponentRef = useLatestRef(renderComponent);
|
|
1132
|
+
const mapPropsRef = useLatestRef(mapProps);
|
|
1133
|
+
return React2.useMemo(
|
|
1134
|
+
() => React2.forwardRef(
|
|
1135
|
+
(props, ref) => {
|
|
1136
|
+
var _a3, _b;
|
|
1137
|
+
return (_b = (_a3 = renderComponentRef.current) == null ? void 0 : _a3.call(renderComponentRef, mapPropsRef.current(props, ref))) != null ? _b : null;
|
|
1138
|
+
}
|
|
1139
|
+
),
|
|
1140
|
+
[mapPropsRef, renderComponentRef]
|
|
1141
|
+
);
|
|
1142
|
+
}
|
|
1123
1143
|
var LayoutView = ({ onLayoutChange, refView, ...rest }) => {
|
|
1124
1144
|
const localRef = useRef(null);
|
|
1125
1145
|
const ref = refView != null ? refView : localRef;
|
|
@@ -1164,14 +1184,11 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
1164
1184
|
needsOtherAxisSize: ctx.state.needsOtherAxisSize,
|
|
1165
1185
|
otherAxisSize
|
|
1166
1186
|
});
|
|
1167
|
-
const
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
(props, ref) => renderScrollComponent({ ...props, ref })
|
|
1173
|
-
);
|
|
1174
|
-
}, [renderScrollComponent]);
|
|
1187
|
+
const CustomScrollComponent = useStableRenderComponent(
|
|
1188
|
+
renderScrollComponent,
|
|
1189
|
+
(props, ref) => ({ ...props, ref })
|
|
1190
|
+
);
|
|
1191
|
+
const ScrollComponent = renderScrollComponent ? CustomScrollComponent : ListComponentScrollView;
|
|
1175
1192
|
const SnapOrScroll = snapToIndices ? SnapWrapper : ScrollComponent;
|
|
1176
1193
|
useLayoutEffect(() => {
|
|
1177
1194
|
if (!ListHeaderComponent) {
|
|
@@ -2652,11 +2669,51 @@ function getObservedBootstrapInitialScrollOffset(state) {
|
|
|
2652
2669
|
const observedOffset = (_b = (_a3 = state.refScroller.current) == null ? void 0 : _a3.getCurrentScrollOffset) == null ? void 0 : _b.call(_a3);
|
|
2653
2670
|
return typeof observedOffset === "number" && Number.isFinite(observedOffset) ? observedOffset : (_d = (_c = state.scrollPending) != null ? _c : state.scroll) != null ? _d : 0;
|
|
2654
2671
|
}
|
|
2672
|
+
function getPreservedEndAnchorOffsetDiff(ctx) {
|
|
2673
|
+
var _a3;
|
|
2674
|
+
const state = ctx.state;
|
|
2675
|
+
const initialScroll = state.initialScroll;
|
|
2676
|
+
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || !initialScroll || initialScroll.viewPosition !== 1 || state.props.data.length === 0 || isOffsetInitialScrollSession(state)) {
|
|
2677
|
+
return;
|
|
2678
|
+
}
|
|
2679
|
+
const currentOffset = typeof state.lastNativeScroll === "number" && Number.isFinite(state.lastNativeScroll) ? state.lastNativeScroll : getObservedBootstrapInitialScrollOffset(state);
|
|
2680
|
+
return resolveInitialScrollOffset(ctx, initialScroll) - currentOffset;
|
|
2681
|
+
}
|
|
2682
|
+
function schedulePreservedEndAnchorCorrection(ctx) {
|
|
2683
|
+
if (getPreservedEndAnchorOffsetDiff(ctx) === void 0) {
|
|
2684
|
+
return false;
|
|
2685
|
+
}
|
|
2686
|
+
const correction = {};
|
|
2687
|
+
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
2688
|
+
return true;
|
|
2689
|
+
}
|
|
2690
|
+
function schedulePreservedEndAnchorCorrectionFrame(ctx, correction) {
|
|
2691
|
+
const state = ctx.state;
|
|
2692
|
+
state.preservedEndAnchorCorrection = correction;
|
|
2693
|
+
requestAnimationFrame(() => {
|
|
2694
|
+
var _a3;
|
|
2695
|
+
const activeCorrection = state.preservedEndAnchorCorrection;
|
|
2696
|
+
if (activeCorrection !== correction) {
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
const offsetDiff = getPreservedEndAnchorOffsetDiff(ctx);
|
|
2700
|
+
if (offsetDiff === void 0 || Math.abs(offsetDiff) <= DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
|
|
2701
|
+
state.preservedEndAnchorCorrection = void 0;
|
|
2702
|
+
return;
|
|
2703
|
+
}
|
|
2704
|
+
const hasObservedNativeScrollAfterRequest = !activeCorrection.lastRequestTime || ((_a3 = state.lastNativeScrollTime) != null ? _a3 : 0) > activeCorrection.lastRequestTime;
|
|
2705
|
+
if (hasObservedNativeScrollAfterRequest) {
|
|
2706
|
+
activeCorrection.lastRequestTime = Date.now();
|
|
2707
|
+
requestAdjust(ctx, offsetDiff);
|
|
2708
|
+
}
|
|
2709
|
+
schedulePreservedEndAnchorCorrectionFrame(ctx, correction);
|
|
2710
|
+
});
|
|
2711
|
+
}
|
|
2655
2712
|
function clearFinishedBootstrapInitialScrollTargetIfMovedAway(ctx) {
|
|
2656
2713
|
var _a3, _b;
|
|
2657
2714
|
const state = ctx.state;
|
|
2658
2715
|
const initialScroll = state.initialScroll;
|
|
2659
|
-
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1) {
|
|
2716
|
+
if (!state.didFinishInitialScroll || ((_a3 = state.scrollingTo) == null ? void 0 : _a3.isInitialScroll) || (initialScroll == null ? void 0 : initialScroll.viewPosition) !== 1 || state.preservedEndAnchorCorrection) {
|
|
2660
2717
|
return;
|
|
2661
2718
|
}
|
|
2662
2719
|
if (didFinishedInitialScrollMoveAwayFromTarget(ctx, initialScroll)) {
|
|
@@ -2813,7 +2870,7 @@ function handleBootstrapInitialScrollFooterLayout(ctx, options) {
|
|
|
2813
2870
|
}
|
|
2814
2871
|
}
|
|
2815
2872
|
function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
2816
|
-
var _a3, _b, _c
|
|
2873
|
+
var _a3, _b, _c;
|
|
2817
2874
|
const state = ctx.state;
|
|
2818
2875
|
const initialScroll = state.initialScroll;
|
|
2819
2876
|
const bootstrapInitialScroll = getBootstrapInitialScrollSession(state);
|
|
@@ -2824,7 +2881,9 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2824
2881
|
const currentOffset = scrollingTo ? (_b = scrollingTo.targetOffset) != null ? _b : scrollingTo.offset : getObservedBootstrapInitialScrollOffset(state);
|
|
2825
2882
|
const offsetDiff = resolvedOffset - currentOffset;
|
|
2826
2883
|
if (Math.abs(offsetDiff) > DEFAULT_BOOTSTRAP_REVEAL_EPSILON) {
|
|
2827
|
-
if (
|
|
2884
|
+
if (state.didFinishInitialScroll) {
|
|
2885
|
+
schedulePreservedEndAnchorCorrection(ctx);
|
|
2886
|
+
} else if (scrollingTo) {
|
|
2828
2887
|
const existingWatchdog = initialScrollWatchdog.get(state);
|
|
2829
2888
|
scrollingTo.offset = resolvedOffset;
|
|
2830
2889
|
scrollingTo.targetOffset = resolvedOffset;
|
|
@@ -2837,14 +2896,8 @@ function handleBootstrapInitialScrollLayoutChange(ctx) {
|
|
|
2837
2896
|
startScroll: (_c = existingWatchdog == null ? void 0 : existingWatchdog.startScroll) != null ? _c : state.scroll,
|
|
2838
2897
|
targetOffset: resolvedOffset
|
|
2839
2898
|
});
|
|
2899
|
+
requestAdjust(ctx, offsetDiff);
|
|
2840
2900
|
}
|
|
2841
|
-
requestAdjust(ctx, offsetDiff);
|
|
2842
|
-
if (state.didFinishInitialScroll) {
|
|
2843
|
-
(_d = state.triggerCalculateItemsInView) == null ? void 0 : _d.call(state, { forceFullItemPositions: true });
|
|
2844
|
-
}
|
|
2845
|
-
}
|
|
2846
|
-
if (state.didFinishInitialScroll) {
|
|
2847
|
-
clearFinishedViewportRetargetableInitialScroll(state);
|
|
2848
2901
|
}
|
|
2849
2902
|
} else {
|
|
2850
2903
|
rearmBootstrapInitialScroll(ctx, {
|
|
@@ -2961,7 +3014,10 @@ function retargetActiveInitialScrollAtEnd(ctx) {
|
|
|
2961
3014
|
var _a3;
|
|
2962
3015
|
const state = ctx.state;
|
|
2963
3016
|
const initialScroll = state.initialScroll;
|
|
2964
|
-
if (
|
|
3017
|
+
if (state.didFinishInitialScroll) {
|
|
3018
|
+
return schedulePreservedEndAnchorCorrection(ctx);
|
|
3019
|
+
}
|
|
3020
|
+
if (!initialScroll || ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "offset" || initialScroll.viewPosition !== 1 || state.props.data.length === 0) {
|
|
2965
3021
|
return false;
|
|
2966
3022
|
}
|
|
2967
3023
|
return advanceCurrentInitialScrollSession(ctx, { forceScroll: true });
|
|
@@ -4975,7 +5031,7 @@ function cloneScrollEvent(event) {
|
|
|
4975
5031
|
};
|
|
4976
5032
|
}
|
|
4977
5033
|
function onScroll(ctx, event) {
|
|
4978
|
-
var _a3, _b, _c, _d, _e;
|
|
5034
|
+
var _a3, _b, _c, _d, _e, _f;
|
|
4979
5035
|
const state = ctx.state;
|
|
4980
5036
|
const { scrollProcessingEnabled } = state;
|
|
4981
5037
|
if (scrollProcessingEnabled === false) {
|
|
@@ -4997,6 +5053,13 @@ function onScroll(ctx, event) {
|
|
|
4997
5053
|
if (state.props.horizontal) {
|
|
4998
5054
|
newScroll = toLogicalHorizontalOffset(state, newScroll, (_e = event.nativeEvent.contentSize) == null ? void 0 : _e.width);
|
|
4999
5055
|
}
|
|
5056
|
+
const isFinishedEndInitialScroll = state.didFinishInitialScroll && ((_f = state.initialScroll) == null ? void 0 : _f.viewPosition) === 1 && state.scroll > state.scrollLength;
|
|
5057
|
+
const shouldIgnoreNegativeInsetChange = Platform.OS !== "web" && insetChanged && newScroll < 0 && isFinishedEndInitialScroll;
|
|
5058
|
+
if (shouldIgnoreNegativeInsetChange) {
|
|
5059
|
+
return;
|
|
5060
|
+
}
|
|
5061
|
+
state.lastNativeScroll = newScroll;
|
|
5062
|
+
state.lastNativeScrollTime = Date.now();
|
|
5000
5063
|
if (state.scrollingTo && state.scrollingTo.offset >= newScroll) {
|
|
5001
5064
|
const maxOffset = clampScrollOffset(ctx, newScroll, state.scrollingTo);
|
|
5002
5065
|
if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
|
|
@@ -5637,6 +5700,8 @@ function getAlwaysRenderIndices(config, data, keyExtractor, anchoredEndSpaceAnch
|
|
|
5637
5700
|
indices.sort(sortAsc);
|
|
5638
5701
|
return indices;
|
|
5639
5702
|
}
|
|
5703
|
+
|
|
5704
|
+
// src/utils/getRenderedItem.ts
|
|
5640
5705
|
function getRenderedItem(ctx, key) {
|
|
5641
5706
|
var _a3;
|
|
5642
5707
|
const state = ctx.state;
|
|
@@ -5662,7 +5727,7 @@ function getRenderedItem(ctx, key) {
|
|
|
5662
5727
|
item,
|
|
5663
5728
|
type: getItemType ? (_a3 = getItemType(item, index)) != null ? _a3 : "" : ""
|
|
5664
5729
|
};
|
|
5665
|
-
renderedItem =
|
|
5730
|
+
renderedItem = renderItem(itemProps);
|
|
5666
5731
|
}
|
|
5667
5732
|
return { index, item: data[index], renderedItem };
|
|
5668
5733
|
}
|
|
@@ -6372,6 +6437,8 @@ var internal = {
|
|
|
6372
6437
|
typedMemo,
|
|
6373
6438
|
useArr$,
|
|
6374
6439
|
useCombinedRef,
|
|
6440
|
+
useLatestRef,
|
|
6441
|
+
useStableRenderComponent,
|
|
6375
6442
|
useStateContext
|
|
6376
6443
|
};
|
|
6377
6444
|
|
package/react-native.web.d.ts
CHANGED
|
@@ -120,13 +120,11 @@ interface DataModeProps<ItemT, TItemType extends string | undefined> {
|
|
|
120
120
|
*/
|
|
121
121
|
data: ReadonlyArray<ItemT>;
|
|
122
122
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* - A function: (props: LegendListRenderItemProps<ItemT>) => ReactNode
|
|
126
|
-
* - A React component: React.ComponentType<LegendListRenderItemProps<ItemT>>
|
|
123
|
+
* Callback to render each item in the list.
|
|
124
|
+
* To use hooks in an item component, return that component from this callback.
|
|
127
125
|
* @required when using data mode
|
|
128
126
|
*/
|
|
129
|
-
renderItem: (
|
|
127
|
+
renderItem: (props: LegendListRenderItemProps<ItemT, TItemType>) => React.ReactNode;
|
|
130
128
|
children?: never;
|
|
131
129
|
}
|
|
132
130
|
interface ChildrenModeProps {
|