@rific/scroll-view 0.1.1 → 0.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/README.md +46 -7
- package/dist/index.d.mts +31 -10
- package/dist/index.d.ts +31 -10
- package/dist/index.js +663 -335
- package/dist/index.mjs +600 -272
- package/package.json +3 -3
- package/src/CustomList.tsx +38 -11
- package/src/FlatList.tsx +107 -22
- package/src/PullSearch.tsx +4 -3
- package/src/ScrollView.tsx +34 -11
- package/src/ScrollViewContext.ts +17 -4
- package/src/ScrollViewHeader.tsx +34 -31
- package/src/ScrollViewProvider.tsx +22 -6
- package/src/ScrollViewSettingsProvider.tsx +3 -3
- package/src/SectionList.tsx +37 -13
- package/src/__mocks__/auto-paper.ts +1 -0
- package/src/__mocks__/react-native-reanimated.ts +32 -1
- package/src/__tests__/FlatList.test.tsx +83 -0
- package/src/__tests__/ScrollViewProvider.test.tsx +2 -2
- package/src/__tests__/useScrollHandlerJS.test.ts +119 -0
- package/src/__tests__/useScrollInit.test.ts +251 -0
- package/src/index.ts +1 -0
- package/src/internal/ScrollViewChip.tsx +24 -8
- package/src/internal/useScrollHandler.ts +22 -23
- package/src/internal/useScrollHandlerJS.ts +141 -0
- package/src/internal/useScrollList.ts +16 -11
- package/src/useScrollInit.ts +200 -19
- package/src/out.txt +0 -61
package/dist/index.js
CHANGED
|
@@ -56,6 +56,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
56
56
|
var import_react6 = require("react");
|
|
57
57
|
var import_react_native4 = require("react-native");
|
|
58
58
|
var import_react_native_gesture_handler = require("react-native-gesture-handler");
|
|
59
|
+
var import_react_native_reanimated6 = require("react-native-reanimated");
|
|
59
60
|
|
|
60
61
|
// src/internal/RefreshControl.tsx
|
|
61
62
|
var import_react_native = require("react-native");
|
|
@@ -63,19 +64,26 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
63
64
|
var RefreshControl = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.RefreshControl, { refreshing: false, ...props });
|
|
64
65
|
|
|
65
66
|
// src/internal/ScrollViewChip.tsx
|
|
67
|
+
var import_auto_paper = require("@rific/auto-paper");
|
|
66
68
|
var import_react_native2 = require("react-native");
|
|
67
|
-
var import_react_native_paper = require("react-native-paper");
|
|
68
69
|
var import_react_native_reanimated = __toESM(require("react-native-reanimated"));
|
|
69
70
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
70
|
-
var ScrollViewChip = ({ isHorizontal, onPress, style }) =>
|
|
71
|
+
var ScrollViewChip = ({ chipProps, isHorizontal, onChipPress, onPress, style }) => {
|
|
72
|
+
const { label, style: chipStyle, ...restChipProps } = chipProps ?? {};
|
|
73
|
+
const handlePress = onChipPress ? () => {
|
|
74
|
+
onPress();
|
|
75
|
+
onChipPress();
|
|
76
|
+
} : onPress;
|
|
77
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_reanimated.default.View, { style: [styles.chip, style], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_auto_paper.Chip, { compact: true, ...restChipProps, icon: isHorizontal ? "chevron-left" : "chevron-up", onPress: handlePress, style: [styles.chipInner, chipStyle], children: label ?? (isHorizontal ? "Start" : "Top") }) });
|
|
78
|
+
};
|
|
71
79
|
var styles = import_react_native2.StyleSheet.create({
|
|
72
80
|
chip: { alignItems: "center", left: 0, position: "absolute", right: 0, zIndex: 3 },
|
|
73
81
|
chipInner: { elevation: 2, shadowColor: "#000", shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.15, shadowRadius: 2 }
|
|
74
82
|
});
|
|
75
83
|
|
|
76
84
|
// src/internal/useScrollHandler.ts
|
|
77
|
-
var
|
|
78
|
-
var
|
|
85
|
+
var import_react3 = require("react");
|
|
86
|
+
var import_react_native_reanimated3 = require("react-native-reanimated");
|
|
79
87
|
|
|
80
88
|
// src/ScrollViewContext.ts
|
|
81
89
|
var import_react = require("react");
|
|
@@ -85,10 +93,16 @@ var ScrollViewContext = (0, import_react.createContext)({
|
|
|
85
93
|
footerHeightShared: null,
|
|
86
94
|
footerFixed: false,
|
|
87
95
|
footerOffset: null,
|
|
88
|
-
headerHeight:
|
|
96
|
+
headerHeight: null,
|
|
89
97
|
headerHeightShared: null,
|
|
90
98
|
headerFixed: false,
|
|
91
99
|
headerOffset: null,
|
|
100
|
+
jsListGeneration: { current: 0 },
|
|
101
|
+
listGeneration: null,
|
|
102
|
+
onJsListUnmount: () => {
|
|
103
|
+
},
|
|
104
|
+
onListUnmount: () => {
|
|
105
|
+
},
|
|
92
106
|
progress: null,
|
|
93
107
|
progressing: false,
|
|
94
108
|
pullSearchHeightShared: null,
|
|
@@ -107,25 +121,215 @@ var ScrollViewContext = (0, import_react.createContext)({
|
|
|
107
121
|
tabBarHeight: 60
|
|
108
122
|
});
|
|
109
123
|
|
|
124
|
+
// src/useScrollInit.ts
|
|
125
|
+
var import_react2 = require("react");
|
|
126
|
+
var import_react_native_reanimated2 = require("react-native-reanimated");
|
|
127
|
+
var REMOUNT_SYNC_MAX_ATTEMPTS = 8;
|
|
128
|
+
var REMOUNT_SYNC_TOLERANCE = 1;
|
|
129
|
+
var REMOUNT_SYNC_FALLBACK_MS = 500;
|
|
130
|
+
var REMOUNT_PRIME_FRAMES = 40;
|
|
131
|
+
var SNAP_VERIFY_TOLERANCE = 1;
|
|
132
|
+
var SNAP_VERIFY_MAX_ATTEMPTS = 5;
|
|
133
|
+
var SNAP_VERIFY_INITIAL_DELAY_MS = 400;
|
|
134
|
+
var SNAP_VERIFY_RETRY_DELAY_MS = 150;
|
|
135
|
+
function useScrollInit({ listHeaderComponent, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pullSearchHeight, scrollTo }) {
|
|
136
|
+
const { headerHeight, scrollPosition, setProgressing } = (0, import_react2.useContext)(ScrollViewContext);
|
|
137
|
+
const hasPullSearch = pullSearchHeight !== void 0;
|
|
138
|
+
const [phase, setPhase] = (0, import_react2.useState)(hasPullSearch && !headerHeight ? "measuring" : "ready");
|
|
139
|
+
const [refreshing, setRefreshing] = (0, import_react2.useState)(false);
|
|
140
|
+
const refreshingRef = (0, import_react2.useRef)(refreshing);
|
|
141
|
+
(0, import_react2.useEffect)(() => {
|
|
142
|
+
refreshingRef.current = refreshing;
|
|
143
|
+
}, [refreshing]);
|
|
144
|
+
const dragStartY = (0, import_react2.useRef)(null);
|
|
145
|
+
const pendingSnapTarget = (0, import_react2.useRef)(null);
|
|
146
|
+
const snapVerifyTimeout = (0, import_react2.useRef)(null);
|
|
147
|
+
const snapVerifyAttempts = (0, import_react2.useRef)(0);
|
|
148
|
+
const scheduleSnapVerification = (0, import_react2.useCallback)(
|
|
149
|
+
(target, delay) => {
|
|
150
|
+
if (snapVerifyTimeout.current !== null) clearTimeout(snapVerifyTimeout.current);
|
|
151
|
+
pendingSnapTarget.current = target;
|
|
152
|
+
snapVerifyAttempts.current = 0;
|
|
153
|
+
const check = () => {
|
|
154
|
+
snapVerifyTimeout.current = null;
|
|
155
|
+
if (pendingSnapTarget.current !== target) return;
|
|
156
|
+
if (Math.abs(scrollPosition.value - target) <= SNAP_VERIFY_TOLERANCE) {
|
|
157
|
+
pendingSnapTarget.current = null;
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
snapVerifyAttempts.current += 1;
|
|
161
|
+
if (snapVerifyAttempts.current > SNAP_VERIFY_MAX_ATTEMPTS || refreshingRef.current) {
|
|
162
|
+
pendingSnapTarget.current = null;
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
scrollTo(target, false);
|
|
166
|
+
snapVerifyTimeout.current = setTimeout(check, SNAP_VERIFY_RETRY_DELAY_MS);
|
|
167
|
+
};
|
|
168
|
+
snapVerifyTimeout.current = setTimeout(check, delay);
|
|
169
|
+
},
|
|
170
|
+
[scrollPosition, scrollTo]
|
|
171
|
+
);
|
|
172
|
+
(0, import_react2.useEffect)(
|
|
173
|
+
() => () => {
|
|
174
|
+
if (snapVerifyTimeout.current !== null) clearTimeout(snapVerifyTimeout.current);
|
|
175
|
+
},
|
|
176
|
+
[]
|
|
177
|
+
);
|
|
178
|
+
const [remountTarget] = (0, import_react2.useState)(() => headerHeight !== null ? -headerHeight + (pullSearchHeight ?? 0) : null);
|
|
179
|
+
const remountSyncTarget = (0, import_react_native_reanimated2.useSharedValue)(remountTarget);
|
|
180
|
+
const [scrollReady, setScrollReady] = (0, import_react2.useState)(remountTarget === null);
|
|
181
|
+
const remountAttempts = (0, import_react2.useRef)(0);
|
|
182
|
+
const onRemountSynced = (0, import_react2.useCallback)(
|
|
183
|
+
(y) => {
|
|
184
|
+
scrollPosition.value = y;
|
|
185
|
+
setScrollReady(true);
|
|
186
|
+
},
|
|
187
|
+
[scrollPosition]
|
|
188
|
+
);
|
|
189
|
+
const onRemountSyncRetry = (0, import_react2.useCallback)(
|
|
190
|
+
(currentY) => {
|
|
191
|
+
if (remountTarget === null) return;
|
|
192
|
+
remountAttempts.current += 1;
|
|
193
|
+
if (remountAttempts.current > REMOUNT_SYNC_MAX_ATTEMPTS) {
|
|
194
|
+
remountSyncTarget.value = null;
|
|
195
|
+
onRemountSynced(currentY);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
scrollTo(remountTarget, false);
|
|
199
|
+
},
|
|
200
|
+
[onRemountSynced, remountSyncTarget, remountTarget, scrollTo]
|
|
201
|
+
);
|
|
202
|
+
(0, import_react2.useEffect)(() => {
|
|
203
|
+
if (remountTarget === null) return;
|
|
204
|
+
scrollTo(remountTarget, false);
|
|
205
|
+
const fallback = setTimeout(() => {
|
|
206
|
+
if (remountSyncTarget.value === null) return;
|
|
207
|
+
remountSyncTarget.value = null;
|
|
208
|
+
onRemountSynced(remountTarget);
|
|
209
|
+
}, REMOUNT_SYNC_FALLBACK_MS);
|
|
210
|
+
return () => clearTimeout(fallback);
|
|
211
|
+
}, []);
|
|
212
|
+
(0, import_react2.useEffect)(() => {
|
|
213
|
+
if (phase === "ready" || !headerHeight || !pullSearchHeight) return;
|
|
214
|
+
scrollPosition.value = -headerHeight + pullSearchHeight;
|
|
215
|
+
setPhase("ready");
|
|
216
|
+
}, [phase, headerHeight, pullSearchHeight, scrollPosition]);
|
|
217
|
+
const headerInitialized = (0, import_react2.useRef)(false);
|
|
218
|
+
(0, import_react2.useLayoutEffect)(() => {
|
|
219
|
+
if (!headerHeight || headerInitialized.current) return;
|
|
220
|
+
headerInitialized.current = true;
|
|
221
|
+
const target = remountTarget ?? -headerHeight;
|
|
222
|
+
scrollPosition.value = target;
|
|
223
|
+
scrollTo(target, false);
|
|
224
|
+
if (remountTarget === null) return;
|
|
225
|
+
let framesLeft = REMOUNT_PRIME_FRAMES;
|
|
226
|
+
let handle = null;
|
|
227
|
+
const tick = () => {
|
|
228
|
+
const offset = framesLeft === 1 ? target : framesLeft % 2 === 0 ? target + 30 : target - 30;
|
|
229
|
+
scrollTo(offset, false);
|
|
230
|
+
framesLeft -= 1;
|
|
231
|
+
if (framesLeft > 0) handle = requestAnimationFrame(tick);
|
|
232
|
+
};
|
|
233
|
+
handle = requestAnimationFrame(tick);
|
|
234
|
+
return () => {
|
|
235
|
+
if (handle !== null) cancelAnimationFrame(handle);
|
|
236
|
+
};
|
|
237
|
+
}, [remountTarget, headerHeight, scrollPosition, scrollTo]);
|
|
238
|
+
const pullSearchInitialized = (0, import_react2.useRef)(false);
|
|
239
|
+
(0, import_react2.useLayoutEffect)(() => {
|
|
240
|
+
if (remountTarget !== null || !hasPullSearch || phase !== "ready" || pullSearchInitialized.current || !headerHeight || !pullSearchHeight || !scrollReady) return;
|
|
241
|
+
pullSearchInitialized.current = true;
|
|
242
|
+
scrollPosition.value = -headerHeight + pullSearchHeight;
|
|
243
|
+
scrollTo(-headerHeight + pullSearchHeight, false);
|
|
244
|
+
}, [remountTarget, hasPullSearch, phase, headerHeight, pullSearchHeight, scrollPosition, scrollReady, scrollTo]);
|
|
245
|
+
(0, import_react2.useEffect)(() => {
|
|
246
|
+
if (pullSearchHeight) setProgressing(refreshing);
|
|
247
|
+
}, [pullSearchHeight, refreshing, setProgressing]);
|
|
248
|
+
const handleScrollBeginDrag = (0, import_react2.useCallback)(
|
|
249
|
+
(e) => {
|
|
250
|
+
if (snapVerifyTimeout.current !== null) {
|
|
251
|
+
clearTimeout(snapVerifyTimeout.current);
|
|
252
|
+
snapVerifyTimeout.current = null;
|
|
253
|
+
}
|
|
254
|
+
pendingSnapTarget.current = null;
|
|
255
|
+
if (pullSearchHeight) dragStartY.current = e.nativeEvent.contentOffset.y;
|
|
256
|
+
externalScrollBeginDrag?.(e);
|
|
257
|
+
},
|
|
258
|
+
[externalScrollBeginDrag, pullSearchHeight]
|
|
259
|
+
);
|
|
260
|
+
const handleScrollEndDrag = (0, import_react2.useCallback)(
|
|
261
|
+
(e) => {
|
|
262
|
+
if (pullSearchHeight && headerHeight) {
|
|
263
|
+
const y = e.nativeEvent.contentOffset.y;
|
|
264
|
+
const showY = -headerHeight;
|
|
265
|
+
const hideY = -headerHeight + pullSearchHeight;
|
|
266
|
+
const startY = dragStartY.current;
|
|
267
|
+
dragStartY.current = null;
|
|
268
|
+
const pulledDown = (startY ?? hideY) <= hideY;
|
|
269
|
+
const dragDistance = startY !== null ? startY - y : 0;
|
|
270
|
+
if (pulledDown && dragDistance >= pullSearchHeight * 0.5) {
|
|
271
|
+
if (y <= showY && !refreshing && onRefresh) {
|
|
272
|
+
setRefreshing(true);
|
|
273
|
+
Promise.resolve(onRefresh()).finally(() => setRefreshing(false));
|
|
274
|
+
}
|
|
275
|
+
scrollTo(showY, true);
|
|
276
|
+
scheduleSnapVerification(showY, SNAP_VERIFY_INITIAL_DELAY_MS);
|
|
277
|
+
} else if (y < hideY) {
|
|
278
|
+
scrollTo(hideY, true);
|
|
279
|
+
scheduleSnapVerification(hideY, SNAP_VERIFY_INITIAL_DELAY_MS);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
externalScrollEndDrag?.(e);
|
|
283
|
+
},
|
|
284
|
+
[externalScrollEndDrag, headerHeight, onRefresh, pullSearchHeight, refreshing, scheduleSnapVerification, scrollTo]
|
|
285
|
+
);
|
|
286
|
+
const handleMomentumScrollEnd = (0, import_react2.useCallback)(
|
|
287
|
+
(e) => {
|
|
288
|
+
if (pullSearchHeight && headerHeight && !refreshing && pendingSnapTarget.current === null) {
|
|
289
|
+
const y = e.nativeEvent.contentOffset.y;
|
|
290
|
+
const hideY = -headerHeight + pullSearchHeight;
|
|
291
|
+
if (y < hideY - 1) {
|
|
292
|
+
scrollTo(hideY, true);
|
|
293
|
+
scheduleSnapVerification(hideY, SNAP_VERIFY_INITIAL_DELAY_MS);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
externalMomentumScrollEnd?.(e);
|
|
297
|
+
},
|
|
298
|
+
[externalMomentumScrollEnd, headerHeight, pullSearchHeight, refreshing, scheduleSnapVerification, scrollTo]
|
|
299
|
+
);
|
|
300
|
+
const activeListHeader = hasPullSearch && phase === "measuring" ? null : listHeaderComponent;
|
|
301
|
+
const hiddenHeader = phase === "measuring" && listHeaderComponent != null ? typeof listHeaderComponent === "function" ? (0, import_react2.createElement)(listHeaderComponent) : listHeaderComponent : null;
|
|
302
|
+
return { activeListHeader, handleMomentumScrollEnd, handleScrollBeginDrag, handleScrollEndDrag, hiddenHeader, onRemountSyncRetry, onRemountSynced, pullSearchMinHeight: pullSearchHeight ?? 0, remountSyncTarget, remountTarget, scrollReady };
|
|
303
|
+
}
|
|
304
|
+
|
|
110
305
|
// src/internal/useScrollHandler.ts
|
|
111
|
-
function useScrollHandler({ chipHidden, footerFixed, headerFixed, isHorizontal,
|
|
112
|
-
const { footerHeightShared, footerOffset, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackFooterShared, snapBackHeaderShared } = (0,
|
|
113
|
-
const snapUpAccum = (0,
|
|
114
|
-
const fromBottomBounce = (0,
|
|
115
|
-
|
|
116
|
-
const momentumPullSearchFired = (0, import_react_native_reanimated2.useSharedValue)(false);
|
|
117
|
-
return (0, import_react_native_reanimated2.useAnimatedScrollHandler)(
|
|
306
|
+
function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold = 100, footerFixed, headerFixed, isHorizontal, listGeneration, onRemountSyncRetry, onRemountSynced, remountSyncTarget }) {
|
|
307
|
+
const { footerHeightShared, footerOffset, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackFooterShared, snapBackHeaderShared } = (0, import_react3.useContext)(ScrollViewContext);
|
|
308
|
+
const snapUpAccum = (0, import_react_native_reanimated3.useSharedValue)(0);
|
|
309
|
+
const fromBottomBounce = (0, import_react_native_reanimated3.useSharedValue)(false);
|
|
310
|
+
return (0, import_react_native_reanimated3.useAnimatedScrollHandler)(
|
|
118
311
|
{
|
|
119
312
|
onScroll: ({ contentOffset: { x, y }, contentSize: { height: contentHeight }, layoutMeasurement: { height: layoutHeight } }) => {
|
|
120
313
|
"worklet";
|
|
314
|
+
if (remountSyncTarget && remountSyncTarget.value !== null) {
|
|
315
|
+
const target = remountSyncTarget.value;
|
|
316
|
+
if (Math.abs(y - target) < REMOUNT_SYNC_TOLERANCE) {
|
|
317
|
+
remountSyncTarget.value = null;
|
|
318
|
+
if (onRemountSynced) (0, import_react_native_reanimated3.runOnJS)(onRemountSynced)(y);
|
|
319
|
+
} else if (onRemountSyncRetry) {
|
|
320
|
+
(0, import_react_native_reanimated3.runOnJS)(onRemountSyncRetry)(y);
|
|
321
|
+
}
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (listGeneration.value !== capturedGeneration.value) return;
|
|
121
325
|
if (isHorizontal) {
|
|
122
326
|
scrollPosition.value = x;
|
|
123
|
-
chipHidden.value = x <
|
|
327
|
+
chipHidden.value = x < chipThreshold ? 1 : 0;
|
|
124
328
|
return;
|
|
125
329
|
}
|
|
126
330
|
const delta = y - scrollPosition.value;
|
|
127
331
|
scrollPosition.value = y;
|
|
128
|
-
chipHidden.value = y <
|
|
332
|
+
chipHidden.value = y < chipThreshold ? 1 : 0;
|
|
129
333
|
const maxScroll = contentHeight - layoutHeight;
|
|
130
334
|
if (maxScroll > 0 && y >= maxScroll) {
|
|
131
335
|
fromBottomBounce.value = true;
|
|
@@ -133,13 +337,6 @@ function useScrollHandler({ chipHidden, footerFixed, headerFixed, isHorizontal,
|
|
|
133
337
|
} else if (fromBottomBounce.value) {
|
|
134
338
|
fromBottomBounce.value = false;
|
|
135
339
|
}
|
|
136
|
-
if (isMomentum.value && pullSearchHeightShared.value > 0 && !momentumPullSearchFired.value) {
|
|
137
|
-
const hideY = -headerHeightShared.value + pullSearchHeightShared.value;
|
|
138
|
-
if (y < hideY) {
|
|
139
|
-
momentumPullSearchFired.value = true;
|
|
140
|
-
if (onPullSearchZoneEnter) (0, import_react_native_reanimated2.runOnJS)(onPullSearchZoneEnter)();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
340
|
const snapHeader = snapBackHeaderShared.value && !headerFixed;
|
|
144
341
|
const snapFooter = snapBackFooterShared.value && !footerFixed;
|
|
145
342
|
if (snapHeader || snapFooter) {
|
|
@@ -157,24 +354,17 @@ function useScrollHandler({ chipHidden, footerFixed, headerFixed, isHorizontal,
|
|
|
157
354
|
if (y >= -headerHeightShared.value + pullSearchHeightShared.value) snapUpAccum.value -= delta;
|
|
158
355
|
if (snapUpAccum.value >= 10) {
|
|
159
356
|
snapUpAccum.value = 999;
|
|
160
|
-
if (snapHeader) headerOffset.value = (0,
|
|
161
|
-
if (snapFooter) footerOffset.value = (0,
|
|
357
|
+
if (snapHeader) headerOffset.value = (0, import_react_native_reanimated3.withTiming)(0, { duration: 200 });
|
|
358
|
+
if (snapFooter) footerOffset.value = (0, import_react_native_reanimated3.withTiming)(0, { duration: 200 });
|
|
162
359
|
}
|
|
163
360
|
}
|
|
164
361
|
}
|
|
165
362
|
},
|
|
166
363
|
onBeginDrag: () => {
|
|
167
364
|
"worklet";
|
|
168
|
-
isMomentum.value = false;
|
|
169
|
-
momentumPullSearchFired.value = false;
|
|
170
365
|
fromBottomBounce.value = false;
|
|
171
366
|
snapUpAccum.value = 0;
|
|
172
367
|
},
|
|
173
|
-
onMomentumBegin: () => {
|
|
174
|
-
"worklet";
|
|
175
|
-
isMomentum.value = true;
|
|
176
|
-
momentumPullSearchFired.value = false;
|
|
177
|
-
},
|
|
178
368
|
onEndDrag: ({ contentOffset: { y }, contentSize: { height: contentHeight }, layoutMeasurement: { height: layoutHeight } }) => {
|
|
179
369
|
"worklet";
|
|
180
370
|
if (isHorizontal) return;
|
|
@@ -185,37 +375,35 @@ function useScrollHandler({ chipHidden, footerFixed, headerFixed, isHorizontal,
|
|
|
185
375
|
},
|
|
186
376
|
onMomentumEnd: () => {
|
|
187
377
|
"worklet";
|
|
188
|
-
isMomentum.value = false;
|
|
189
|
-
momentumPullSearchFired.value = false;
|
|
190
378
|
fromBottomBounce.value = false;
|
|
191
379
|
snapUpAccum.value = 0;
|
|
192
380
|
}
|
|
193
381
|
},
|
|
194
|
-
[headerFixed, footerFixed, isHorizontal,
|
|
382
|
+
[capturedGeneration, headerFixed, footerFixed, isHorizontal, chipThreshold, listGeneration, onRemountSyncRetry, onRemountSynced, remountSyncTarget]
|
|
195
383
|
);
|
|
196
384
|
}
|
|
197
385
|
|
|
198
386
|
// src/internal/useScrollList.ts
|
|
199
|
-
var
|
|
387
|
+
var import_react5 = require("react");
|
|
200
388
|
var import_react_native3 = require("react-native");
|
|
201
|
-
var
|
|
389
|
+
var import_react_native_reanimated5 = require("react-native-reanimated");
|
|
202
390
|
var import_react_native_safe_area_context = require("react-native-safe-area-context");
|
|
203
391
|
|
|
204
392
|
// src/useKeyboardInset.ts
|
|
205
|
-
var
|
|
393
|
+
var import_react4 = require("react");
|
|
206
394
|
var import_react_native_keyboard_controller = require("react-native-keyboard-controller");
|
|
207
|
-
var
|
|
395
|
+
var import_react_native_reanimated4 = require("react-native-reanimated");
|
|
208
396
|
var useKeyboardInset = () => {
|
|
209
|
-
const [keyboardHeight, setKeyboardHeight] = (0,
|
|
397
|
+
const [keyboardHeight, setKeyboardHeight] = (0, import_react4.useState)(0);
|
|
210
398
|
(0, import_react_native_keyboard_controller.useKeyboardHandler)(
|
|
211
399
|
{
|
|
212
400
|
onMove: (e) => {
|
|
213
401
|
"worklet";
|
|
214
|
-
(0,
|
|
402
|
+
(0, import_react_native_reanimated4.runOnJS)(setKeyboardHeight)(e.height);
|
|
215
403
|
},
|
|
216
404
|
onEnd: (e) => {
|
|
217
405
|
"worklet";
|
|
218
|
-
(0,
|
|
406
|
+
(0, import_react_native_reanimated4.runOnJS)(setKeyboardHeight)(e.height);
|
|
219
407
|
}
|
|
220
408
|
},
|
|
221
409
|
[]
|
|
@@ -228,122 +416,55 @@ var CHIP_SLIDE = 48;
|
|
|
228
416
|
function useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, isHorizontal, keyboardAware, pullSearchHeight, style } = {}) {
|
|
229
417
|
const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
|
|
230
418
|
const keyboardHeight = useKeyboardInset();
|
|
231
|
-
const { footerHeight, footerFixed: contextFooterFixed, headerHeight, headerFixed: contextHeaderFixed, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared } = (0,
|
|
419
|
+
const { footerHeight, footerFixed: contextFooterFixed, headerHeight, headerFixed: contextHeaderFixed, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared } = (0, import_react5.useContext)(ScrollViewContext);
|
|
232
420
|
const headerFixed = isHorizontal ? true : headerFixedProp ?? contextHeaderFixed;
|
|
233
421
|
const footerFixed = isHorizontal ? true : footerFixedProp ?? contextFooterFixed;
|
|
234
|
-
(0,
|
|
422
|
+
(0, import_react5.useEffect)(() => {
|
|
235
423
|
pullSearchHeightShared.value = pullSearchHeight ?? 0;
|
|
236
424
|
}, [pullSearchHeight, pullSearchHeightShared]);
|
|
237
|
-
const containerStyle = (0,
|
|
238
|
-
const contentInset = (0,
|
|
239
|
-
const
|
|
240
|
-
const
|
|
241
|
-
const
|
|
425
|
+
const containerStyle = (0, import_react5.useMemo)(() => headerHeight === null ? [{ flex: 1, opacity: 0 }, style] : [import_react_native3.StyleSheet.absoluteFill, style], [headerHeight, style]);
|
|
426
|
+
const contentInset = (0, import_react5.useMemo)(() => ({ bottom: (footerFixed ? footerHeight || insets.bottom : insets.bottom) + (keyboardAware ? keyboardHeight : 0), top: headerHeight ?? 0 }), [footerFixed, footerHeight, insets.bottom, headerHeight, keyboardAware, keyboardHeight]);
|
|
427
|
+
const [startedWithHeader] = (0, import_react5.useState)(headerHeight !== null);
|
|
428
|
+
const contentOffset = (0, import_react5.useMemo)(() => ({ x: 0, y: headerHeight !== null ? -headerHeight + (startedWithHeader && !isHorizontal && pullSearchHeight ? pullSearchHeight : 0) : 0 }), [headerHeight, isHorizontal, pullSearchHeight, startedWithHeader]);
|
|
429
|
+
const chipHidden = (0, import_react_native_reanimated5.useSharedValue)(1);
|
|
430
|
+
const chipStyle = (0, import_react_native_reanimated5.useAnimatedStyle)(() => {
|
|
242
431
|
const pointerEvents = chipHidden.value ? "none" : "box-none";
|
|
243
432
|
if (isHorizontal) {
|
|
244
433
|
return {
|
|
245
|
-
opacity: chipHidden.value ? (0,
|
|
434
|
+
opacity: chipHidden.value ? (0, import_react_native_reanimated5.withTiming)(0) : (0, import_react_native_reanimated5.withTiming)(1),
|
|
246
435
|
pointerEvents,
|
|
247
|
-
top: Math.max(headerHeight, insets.top) + 4,
|
|
248
|
-
transform: [{ translateX: chipHidden.value ? (0,
|
|
436
|
+
top: Math.max(headerHeight ?? 0, insets.top) + 4,
|
|
437
|
+
transform: [{ translateX: chipHidden.value ? (0, import_react_native_reanimated5.withTiming)(-CHIP_SLIDE) : (0, import_react_native_reanimated5.withTiming)(0) }]
|
|
249
438
|
};
|
|
250
439
|
}
|
|
251
|
-
const
|
|
252
|
-
const
|
|
440
|
+
const h = headerHeight ?? 0;
|
|
441
|
+
const slide = headerFixed ? 0 : snapBackHeaderShared.value ? -headerOffset.value : Math.max(0, scrollPosition.value + h - pullSearchHeightShared.value);
|
|
442
|
+
const top = Math.max(h - slide, insets.top) + 4;
|
|
253
443
|
return {
|
|
254
|
-
opacity: chipHidden.value ? (0,
|
|
444
|
+
opacity: chipHidden.value ? (0, import_react_native_reanimated5.withTiming)(0) : (0, import_react_native_reanimated5.withTiming)(1),
|
|
255
445
|
pointerEvents,
|
|
256
446
|
top,
|
|
257
|
-
transform: [{ translateY: chipHidden.value ? (0,
|
|
447
|
+
transform: [{ translateY: chipHidden.value ? (0, import_react_native_reanimated5.withTiming)(-CHIP_SLIDE) : (0, import_react_native_reanimated5.withTiming)(0) }]
|
|
258
448
|
};
|
|
259
449
|
}, [isHorizontal, headerFixed, headerHeight, insets.top]);
|
|
260
450
|
return { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, footerFixed, headerFixed, headerHeight, insets, isHorizontal: isHorizontal ?? false };
|
|
261
451
|
}
|
|
262
452
|
|
|
263
|
-
// src/useScrollInit.ts
|
|
264
|
-
var import_react5 = require("react");
|
|
265
|
-
function useScrollInit({ listHeaderComponent, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pullSearchHeight, scrollTo }) {
|
|
266
|
-
const { headerHeight, scrollPosition, setProgressing } = (0, import_react5.useContext)(ScrollViewContext);
|
|
267
|
-
const hasPullSearch = pullSearchHeight !== void 0;
|
|
268
|
-
const [phase, setPhase] = (0, import_react5.useState)(hasPullSearch ? "measuring" : "ready");
|
|
269
|
-
const [refreshing, setRefreshing] = (0, import_react5.useState)(false);
|
|
270
|
-
const dragStartY = (0, import_react5.useRef)(null);
|
|
271
|
-
const deliberatelyOpened = (0, import_react5.useRef)(false);
|
|
272
|
-
(0, import_react5.useEffect)(() => {
|
|
273
|
-
if (phase === "ready" || !headerHeight || !pullSearchHeight) return;
|
|
274
|
-
scrollPosition.value = -headerHeight + pullSearchHeight;
|
|
275
|
-
setPhase("ready");
|
|
276
|
-
}, [phase, headerHeight, pullSearchHeight, scrollPosition]);
|
|
277
|
-
const headerInitialized = (0, import_react5.useRef)(false);
|
|
278
|
-
(0, import_react5.useLayoutEffect)(() => {
|
|
279
|
-
if (!headerHeight || headerInitialized.current) return;
|
|
280
|
-
headerInitialized.current = true;
|
|
281
|
-
scrollPosition.value = -headerHeight;
|
|
282
|
-
scrollTo(-headerHeight, false);
|
|
283
|
-
}, [headerHeight, scrollPosition, scrollTo]);
|
|
284
|
-
const pullSearchInitialized = (0, import_react5.useRef)(false);
|
|
285
|
-
(0, import_react5.useLayoutEffect)(() => {
|
|
286
|
-
if (!hasPullSearch || phase !== "ready" || pullSearchInitialized.current || !headerHeight || !pullSearchHeight) return;
|
|
287
|
-
pullSearchInitialized.current = true;
|
|
288
|
-
scrollPosition.value = -headerHeight + pullSearchHeight;
|
|
289
|
-
scrollTo(-headerHeight + pullSearchHeight, false);
|
|
290
|
-
}, [hasPullSearch, phase, headerHeight, pullSearchHeight, scrollPosition, scrollTo]);
|
|
291
|
-
(0, import_react5.useEffect)(() => {
|
|
292
|
-
if (pullSearchHeight) setProgressing(refreshing);
|
|
293
|
-
}, [pullSearchHeight, refreshing, setProgressing]);
|
|
294
|
-
const handleScrollBeginDrag = (0, import_react5.useCallback)(
|
|
295
|
-
(e) => {
|
|
296
|
-
deliberatelyOpened.current = false;
|
|
297
|
-
if (pullSearchHeight) dragStartY.current = e.nativeEvent.contentOffset.y;
|
|
298
|
-
externalScrollBeginDrag?.(e);
|
|
299
|
-
},
|
|
300
|
-
[externalScrollBeginDrag, pullSearchHeight]
|
|
301
|
-
);
|
|
302
|
-
const handleScrollEndDrag = (0, import_react5.useCallback)(
|
|
303
|
-
(e) => {
|
|
304
|
-
if (pullSearchHeight && headerHeight) {
|
|
305
|
-
const y = e.nativeEvent.contentOffset.y;
|
|
306
|
-
const showY = -headerHeight;
|
|
307
|
-
const hideY = -headerHeight + pullSearchHeight;
|
|
308
|
-
const pulledDown = (dragStartY.current ?? hideY) <= hideY;
|
|
309
|
-
dragStartY.current = null;
|
|
310
|
-
if (pulledDown && y <= showY + pullSearchHeight * 0.5) {
|
|
311
|
-
deliberatelyOpened.current = true;
|
|
312
|
-
if (y <= showY && !refreshing && onRefresh) {
|
|
313
|
-
setRefreshing(true);
|
|
314
|
-
Promise.resolve(onRefresh()).finally(() => setRefreshing(false));
|
|
315
|
-
}
|
|
316
|
-
scrollTo(showY, true);
|
|
317
|
-
} else if (y < hideY) {
|
|
318
|
-
scrollTo(hideY, true);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
externalScrollEndDrag?.(e);
|
|
322
|
-
},
|
|
323
|
-
[externalScrollEndDrag, headerHeight, onRefresh, pullSearchHeight, refreshing, scrollTo]
|
|
324
|
-
);
|
|
325
|
-
const handleMomentumScrollEnd = (0, import_react5.useCallback)(
|
|
326
|
-
(e) => {
|
|
327
|
-
if (pullSearchHeight && headerHeight && !deliberatelyOpened.current && !refreshing) {
|
|
328
|
-
const y = e.nativeEvent.contentOffset.y;
|
|
329
|
-
const hideY = -headerHeight + pullSearchHeight;
|
|
330
|
-
if (y < hideY - 1) scrollTo(hideY, true);
|
|
331
|
-
}
|
|
332
|
-
deliberatelyOpened.current = false;
|
|
333
|
-
externalMomentumScrollEnd?.(e);
|
|
334
|
-
},
|
|
335
|
-
[externalMomentumScrollEnd, headerHeight, pullSearchHeight, refreshing, scrollTo]
|
|
336
|
-
);
|
|
337
|
-
const activeListHeader = hasPullSearch && phase === "measuring" ? null : listHeaderComponent;
|
|
338
|
-
const hiddenHeader = phase === "measuring" && listHeaderComponent != null ? typeof listHeaderComponent === "function" ? (0, import_react5.createElement)(listHeaderComponent) : listHeaderComponent : null;
|
|
339
|
-
return { activeListHeader, handleMomentumScrollEnd, handleScrollBeginDrag, handleScrollEndDrag, hiddenHeader, pullSearchMinHeight: pullSearchHeight ?? 0 };
|
|
340
|
-
}
|
|
341
|
-
|
|
342
453
|
// src/CustomList.tsx
|
|
343
454
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
344
|
-
var CustomListInner = ({ component: List, renderFilters, footerFixed: footerFixedProp, gesture, headerFixed: headerFixedProp, keyboardAware, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pullSearchHeight, scrollRef, style, ...props }) => {
|
|
455
|
+
var CustomListInner = ({ chipProps, chipThreshold, component: List, renderFilters, footerFixed: footerFixedProp, gesture, headerFixed: headerFixedProp, keyboardAware, onChipPress, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pullSearchHeight, scrollRef, style, ...props }) => {
|
|
345
456
|
const { ListHeaderComponent: listHeaderComponent, contentContainerStyle: externalContentContainerStyle, ...restProps } = props;
|
|
346
457
|
const { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, footerFixed, headerFixed } = useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, keyboardAware, pullSearchHeight, style });
|
|
458
|
+
const { listGeneration, onListUnmount } = (0, import_react6.useContext)(ScrollViewContext);
|
|
459
|
+
const capturedGeneration = (0, import_react_native_reanimated6.useSharedValue)(-1);
|
|
460
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
461
|
+
const generation = listGeneration.value;
|
|
462
|
+
(0, import_react_native_reanimated6.runOnUI)((gen) => {
|
|
463
|
+
"worklet";
|
|
464
|
+
capturedGeneration.value = gen;
|
|
465
|
+
})(generation);
|
|
466
|
+
}, [capturedGeneration, listGeneration]);
|
|
467
|
+
(0, import_react6.useLayoutEffect)(() => () => onListUnmount(), [onListUnmount]);
|
|
347
468
|
const scrollViewInternal = (0, import_react6.useRef)(null);
|
|
348
469
|
const handleRef = (0, import_react6.useCallback)(
|
|
349
470
|
(el) => {
|
|
@@ -361,7 +482,10 @@ var CustomListInner = ({ component: List, renderFilters, footerFixed: footerFixe
|
|
|
361
482
|
handleScrollBeginDrag,
|
|
362
483
|
handleScrollEndDrag,
|
|
363
484
|
hiddenHeader,
|
|
364
|
-
|
|
485
|
+
onRemountSyncRetry,
|
|
486
|
+
onRemountSynced,
|
|
487
|
+
pullSearchMinHeight,
|
|
488
|
+
remountSyncTarget
|
|
365
489
|
} = useScrollInit({
|
|
366
490
|
listHeaderComponent,
|
|
367
491
|
onMomentumScrollEnd: externalMomentumScrollEnd,
|
|
@@ -380,11 +504,7 @@ var CustomListInner = ({ component: List, renderFilters, footerFixed: footerFixe
|
|
|
380
504
|
] });
|
|
381
505
|
}, [pullSearchHeader, renderFilters]);
|
|
382
506
|
const contentContainerStyle = (0, import_react6.useMemo)(() => [{ minHeight: import_react_native4.Dimensions.get("window").height - contentInset.top - contentInset.bottom + pullSearchMinHeight }, externalContentContainerStyle], [contentInset.bottom, contentInset.top, externalContentContainerStyle, pullSearchMinHeight]);
|
|
383
|
-
const
|
|
384
|
-
if (!pullSearchHeight) return;
|
|
385
|
-
scrollViewInternal.current?.scrollToOffset({ offset: -contentInset.top + pullSearchHeight, animated: true });
|
|
386
|
-
}, [contentInset.top, pullSearchHeight]);
|
|
387
|
-
const onScroll = useScrollHandler({ chipHidden, footerFixed, headerFixed, onPullSearchZoneEnter: pullSearchHeight ? onPullSearchZoneEnter : void 0 });
|
|
507
|
+
const onScroll = useScrollHandler({ capturedGeneration, chipHidden, chipThreshold, footerFixed, headerFixed, listGeneration, onRemountSyncRetry, onRemountSynced, remountSyncTarget });
|
|
388
508
|
const handleScrollToTop = (0, import_react6.useCallback)(() => {
|
|
389
509
|
const offset = pullSearchHeight ? -contentInset.top + pullSearchHeight : -contentInset.top;
|
|
390
510
|
scrollViewInternal.current?.scrollToOffset({ offset, animated: true });
|
|
@@ -397,7 +517,7 @@ var CustomListInner = ({ component: List, renderFilters, footerFixed: footerFixe
|
|
|
397
517
|
const content = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: containerStyle, children: [
|
|
398
518
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TypedList, { ...restProps, contentContainerStyle, contentInset, contentOffset, ListHeaderComponent: activeListHeader, onMomentumScrollEnd: handleMomentumScrollEnd, onScroll, onScrollBeginDrag: handleScrollBeginDrag, onScrollEndDrag: handleScrollEndDrag, ref: handleRef, refreshControl, scrollEventThrottle: 16 }),
|
|
399
519
|
hiddenHeader && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native4.View, { pointerEvents: "none", style: styles2.measureContainer, children: hiddenHeader }),
|
|
400
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ScrollViewChip, { onPress: handleScrollToTop, style: chipStyle })
|
|
520
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ScrollViewChip, { chipProps, onChipPress, onPress: handleScrollToTop, style: chipStyle })
|
|
401
521
|
] });
|
|
402
522
|
return detectorGesture ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_gesture_handler.GestureDetector, { gesture: detectorGesture, children: content }) : content;
|
|
403
523
|
};
|
|
@@ -405,17 +525,16 @@ var styles2 = { measureContainer: { left: 0, opacity: 0, position: "absolute", r
|
|
|
405
525
|
var CustomList = (0, import_react6.memo)(CustomListInner);
|
|
406
526
|
|
|
407
527
|
// src/FlatList.tsx
|
|
408
|
-
var
|
|
528
|
+
var import_react9 = require("react");
|
|
409
529
|
var import_react_native6 = require("react-native");
|
|
410
530
|
var import_react_native_gesture_handler2 = require("react-native-gesture-handler");
|
|
411
|
-
var import_react_native_reanimated6 = __toESM(require("react-native-reanimated"));
|
|
412
531
|
|
|
413
532
|
// src/internal/HorizontalDots.tsx
|
|
414
|
-
var
|
|
533
|
+
var import_auto_paper2 = require("@rific/auto-paper");
|
|
415
534
|
var import_react7 = require("react");
|
|
416
535
|
var import_react_native5 = require("react-native");
|
|
417
|
-
var
|
|
418
|
-
var
|
|
536
|
+
var import_react_native_paper = require("react-native-paper");
|
|
537
|
+
var import_react_native_reanimated7 = __toESM(require("react-native-reanimated"));
|
|
419
538
|
var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
|
|
420
539
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
421
540
|
var DOT_FULL = 8;
|
|
@@ -430,36 +549,36 @@ var PILL_HEIGHT = DOT_FULL + PILL_PAD_V * 2;
|
|
|
430
549
|
var PILL_RADIUS = PILL_HEIGHT / 2;
|
|
431
550
|
var PILL_WIDTH = CLIP_WIDTH + PILL_PAD_H * 2;
|
|
432
551
|
var Dot = ({ activeColor, index, inactiveColor, pageWidth, scrollPosition }) => {
|
|
433
|
-
const circleStyle = (0,
|
|
552
|
+
const circleStyle = (0, import_react_native_reanimated7.useAnimatedStyle)(() => {
|
|
434
553
|
const page = scrollPosition.value / pageWidth;
|
|
435
554
|
const distance = Math.abs(index - page);
|
|
436
555
|
const t = Math.max(0, Math.min((distance - 0.5) / 2, 1));
|
|
437
556
|
const size = DOT_FULL + (DOT_SMALL - DOT_FULL) * t;
|
|
438
|
-
const backgroundColor = (0,
|
|
557
|
+
const backgroundColor = (0, import_react_native_reanimated7.interpolateColor)(t, [0, 1], [activeColor, inactiveColor]);
|
|
439
558
|
return { backgroundColor, borderRadius: size / 2, height: size, width: size };
|
|
440
559
|
});
|
|
441
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native5.View, { style: styles3.dotContainer, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
560
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native5.View, { style: styles3.dotContainer, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_reanimated7.default.View, { style: circleStyle }) });
|
|
442
561
|
};
|
|
443
562
|
var HorizontalDots = ({ total }) => {
|
|
444
563
|
const { blur, footerHeightShared, scrollPosition } = (0, import_react7.useContext)(ScrollViewContext);
|
|
445
564
|
const { width } = (0, import_react_native5.useWindowDimensions)();
|
|
446
565
|
const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
|
|
447
|
-
const theme = (0,
|
|
566
|
+
const theme = (0, import_react_native_paper.useTheme)();
|
|
448
567
|
const insetsBottom = insets.bottom;
|
|
449
568
|
const activeColor = theme.colors.primary;
|
|
450
569
|
const inactiveColor = theme.colors.outlineVariant;
|
|
451
|
-
const pillContainerStyle = (0,
|
|
570
|
+
const pillContainerStyle = (0, import_react_native_reanimated7.useAnimatedStyle)(() => ({
|
|
452
571
|
bottom: Math.max(footerHeightShared.value, insetsBottom) + 8
|
|
453
572
|
}));
|
|
454
|
-
const rowStyle = (0,
|
|
573
|
+
const rowStyle = (0, import_react_native_reanimated7.useAnimatedStyle)(() => {
|
|
455
574
|
const page = scrollPosition.value / width;
|
|
456
575
|
const maxOffset = Math.max(0, (total - CLIP_COUNT) * DOT_STEP);
|
|
457
576
|
const offset = Math.max(0, Math.min((page - (CLIP_COUNT - 1) / 2) * DOT_STEP, maxOffset));
|
|
458
577
|
return { transform: [{ translateX: -offset }] };
|
|
459
578
|
});
|
|
460
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
461
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
462
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native5.View, { style: styles3.dotsClip, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_reanimated7.default.View, { pointerEvents: "none", style: [styles3.pillContainer, pillContainerStyle], children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.View, { style: styles3.pill, children: [
|
|
580
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_auto_paper2.BlurView, { blur, style: import_react_native5.StyleSheet.absoluteFill }),
|
|
581
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native5.View, { style: styles3.dotsClip, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_reanimated7.default.View, { style: [styles3.dotsRow, rowStyle], children: Array.from({ length: total }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dot, { activeColor, index: i, inactiveColor, pageWidth: width, scrollPosition }, i)) }) })
|
|
463
582
|
] }) });
|
|
464
583
|
};
|
|
465
584
|
var styles3 = import_react_native5.StyleSheet.create({
|
|
@@ -477,14 +596,144 @@ var styles3 = import_react_native5.StyleSheet.create({
|
|
|
477
596
|
pillContainer: { alignItems: "center", left: 0, position: "absolute", right: 0, zIndex: 3 }
|
|
478
597
|
});
|
|
479
598
|
|
|
599
|
+
// src/internal/useScrollHandlerJS.ts
|
|
600
|
+
var import_react8 = require("react");
|
|
601
|
+
var import_react_native_reanimated8 = require("react-native-reanimated");
|
|
602
|
+
var REMOUNT_RETRY_TOLERANCE = 1;
|
|
603
|
+
var REMOUNT_RETRY_MAX_ATTEMPTS = 8;
|
|
604
|
+
function useScrollHandlerJS({ capturedGeneration, chipHidden, chipThreshold = 100, footerFixed, headerFixed, isHorizontal, jsListGeneration, remountTarget = null, scrollTo }) {
|
|
605
|
+
const { footerHeightShared, footerOffset, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackFooterShared, snapBackHeaderShared } = (0, import_react8.useContext)(ScrollViewContext);
|
|
606
|
+
const snapUpAccum = (0, import_react8.useRef)(0);
|
|
607
|
+
const fromBottomBounce = (0, import_react8.useRef)(false);
|
|
608
|
+
const pendingRemountTarget = (0, import_react8.useRef)(remountTarget);
|
|
609
|
+
const remountAttempts = (0, import_react8.useRef)(0);
|
|
610
|
+
const onScroll = (0, import_react8.useCallback)(
|
|
611
|
+
(event) => {
|
|
612
|
+
if (jsListGeneration.current !== capturedGeneration.current) return;
|
|
613
|
+
const {
|
|
614
|
+
contentOffset: { x, y },
|
|
615
|
+
contentSize: { height: contentHeight },
|
|
616
|
+
layoutMeasurement: { height: layoutHeight }
|
|
617
|
+
} = event.nativeEvent;
|
|
618
|
+
if (pendingRemountTarget.current !== null) {
|
|
619
|
+
const target = pendingRemountTarget.current;
|
|
620
|
+
if (Math.abs(y - target) < REMOUNT_RETRY_TOLERANCE) {
|
|
621
|
+
pendingRemountTarget.current = null;
|
|
622
|
+
} else {
|
|
623
|
+
remountAttempts.current += 1;
|
|
624
|
+
if (remountAttempts.current > REMOUNT_RETRY_MAX_ATTEMPTS) {
|
|
625
|
+
pendingRemountTarget.current = null;
|
|
626
|
+
} else {
|
|
627
|
+
scrollTo?.(target, false);
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
if (isHorizontal) {
|
|
633
|
+
scrollPosition.value = x;
|
|
634
|
+
chipHidden.value = x < chipThreshold ? 1 : 0;
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
const delta = y - scrollPosition.value;
|
|
638
|
+
scrollPosition.value = y;
|
|
639
|
+
chipHidden.value = y < chipThreshold ? 1 : 0;
|
|
640
|
+
const maxScroll = contentHeight - layoutHeight;
|
|
641
|
+
if (maxScroll > 0 && y >= maxScroll) {
|
|
642
|
+
fromBottomBounce.current = true;
|
|
643
|
+
snapUpAccum.current = 0;
|
|
644
|
+
} else if (fromBottomBounce.current) {
|
|
645
|
+
fromBottomBounce.current = false;
|
|
646
|
+
}
|
|
647
|
+
const snapHeader = snapBackHeaderShared.value && !headerFixed;
|
|
648
|
+
const snapFooter = snapBackFooterShared.value && !footerFixed;
|
|
649
|
+
if (snapHeader || snapFooter) {
|
|
650
|
+
if (y <= -headerHeightShared.value) {
|
|
651
|
+
snapUpAccum.current = 0;
|
|
652
|
+
if (snapHeader) headerOffset.value = 0;
|
|
653
|
+
if (snapFooter) footerOffset.value = 0;
|
|
654
|
+
} else if (delta > 0) {
|
|
655
|
+
snapUpAccum.current = 0;
|
|
656
|
+
if (y >= -headerHeightShared.value + pullSearchHeightShared.value) {
|
|
657
|
+
if (snapHeader) headerOffset.value = Math.max(-headerHeightShared.value, Math.min(0, headerOffset.value - delta));
|
|
658
|
+
if (snapFooter) footerOffset.value = Math.max(0, Math.min(footerHeightShared.value, footerOffset.value + delta));
|
|
659
|
+
}
|
|
660
|
+
} else if (delta < 0 && !fromBottomBounce.current) {
|
|
661
|
+
if (y >= -headerHeightShared.value + pullSearchHeightShared.value) snapUpAccum.current -= delta;
|
|
662
|
+
if (snapUpAccum.current >= 10) {
|
|
663
|
+
snapUpAccum.current = 999;
|
|
664
|
+
if (snapHeader) headerOffset.value = (0, import_react_native_reanimated8.withTiming)(0, { duration: 200 });
|
|
665
|
+
if (snapFooter) footerOffset.value = (0, import_react_native_reanimated8.withTiming)(0, { duration: 200 });
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
},
|
|
670
|
+
[capturedGeneration, chipHidden, chipThreshold, footerFixed, footerHeightShared, footerOffset, headerFixed, headerHeightShared, headerOffset, isHorizontal, jsListGeneration, pullSearchHeightShared, scrollPosition, scrollTo, snapBackFooterShared, snapBackHeaderShared]
|
|
671
|
+
);
|
|
672
|
+
const onScrollBeginDrag = (0, import_react8.useCallback)(() => {
|
|
673
|
+
fromBottomBounce.current = false;
|
|
674
|
+
snapUpAccum.current = 0;
|
|
675
|
+
}, []);
|
|
676
|
+
const onMomentumScrollBegin = (0, import_react8.useCallback)(() => {
|
|
677
|
+
}, []);
|
|
678
|
+
const onScrollEndDrag = (0, import_react8.useCallback)(
|
|
679
|
+
(event) => {
|
|
680
|
+
if (isHorizontal) return;
|
|
681
|
+
const {
|
|
682
|
+
contentOffset: { y },
|
|
683
|
+
contentSize: { height: contentHeight },
|
|
684
|
+
layoutMeasurement: { height: layoutHeight }
|
|
685
|
+
} = event.nativeEvent;
|
|
686
|
+
if (y >= contentHeight - layoutHeight - 10) {
|
|
687
|
+
fromBottomBounce.current = true;
|
|
688
|
+
snapUpAccum.current = 0;
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
[isHorizontal]
|
|
692
|
+
);
|
|
693
|
+
const onMomentumScrollEnd = (0, import_react8.useCallback)(() => {
|
|
694
|
+
fromBottomBounce.current = false;
|
|
695
|
+
snapUpAccum.current = 0;
|
|
696
|
+
}, []);
|
|
697
|
+
return { onMomentumScrollBegin, onMomentumScrollEnd, onScroll, onScrollBeginDrag, onScrollEndDrag };
|
|
698
|
+
}
|
|
699
|
+
|
|
480
700
|
// src/FlatList.tsx
|
|
481
701
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
482
|
-
var FlatListInner = ({ contentContainerStyle: externalContentContainerStyle, data, initialNumToRender = 20, maxToRenderPerBatch = 50, renderFilters, footerFixed: footerFixedProp, gesture, headerFixed: headerFixedProp, horizontal, keyboardAware, ListHeaderComponent: externalListHeaderComponent, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pagingEnabled, pullSearchHeight, removeClippedSubviews = false, showsHorizontalScrollIndicator, showsVerticalScrollIndicator, style, onContentSizeChange, ref: externalRef, windowSize = 100, ...props }) => {
|
|
483
|
-
const scrollView = (0,
|
|
702
|
+
var FlatListInner = ({ chipProps, chipThreshold, columnWrapperStyle, contentContainerStyle: externalContentContainerStyle, data, initialNumToRender = 20, keyExtractor, maxToRenderPerBatch = 50, numColumns, renderFilters, renderItem, footerFixed: footerFixedProp, gesture, headerFixed: headerFixedProp, horizontal, keyboardAware, ListHeaderComponent: externalListHeaderComponent, onChipPress, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pagingEnabled, pullSearchHeight, removeClippedSubviews = false, showsHorizontalScrollIndicator, showsVerticalScrollIndicator, style, onContentSizeChange, ref: externalRef, windowSize = 100, ...props }) => {
|
|
703
|
+
const scrollView = (0, import_react9.useRef)(null);
|
|
484
704
|
const isHorizontal = horizontal === true;
|
|
485
705
|
const showDots = isHorizontal && pagingEnabled === true && (data?.length ?? 0) > 1;
|
|
706
|
+
const cols = numColumns && numColumns > 1 ? numColumns : 1;
|
|
707
|
+
const rowData = (0, import_react9.useMemo)(() => {
|
|
708
|
+
if (cols <= 1 || !data) return data;
|
|
709
|
+
const items = Array.from(data);
|
|
710
|
+
const rows = [];
|
|
711
|
+
for (let i = 0; i < items.length; i += cols) rows.push(items.slice(i, i + cols));
|
|
712
|
+
return rows;
|
|
713
|
+
}, [cols, data]);
|
|
714
|
+
const rowKeyExtractor = (0, import_react9.useCallback)(
|
|
715
|
+
(row, rowIndex) => {
|
|
716
|
+
if (cols <= 1) return keyExtractor ? keyExtractor(row, rowIndex) : defaultKeyExtractor(row, rowIndex);
|
|
717
|
+
return row.map((item, kk) => keyExtractor ? keyExtractor(item, rowIndex * cols + kk) : defaultKeyExtractor(item, rowIndex * cols + kk)).join(":");
|
|
718
|
+
},
|
|
719
|
+
[cols, keyExtractor]
|
|
720
|
+
);
|
|
721
|
+
const rowRenderItem = (0, import_react9.useCallback)(
|
|
722
|
+
(info) => {
|
|
723
|
+
if (cols <= 1) return renderItem ? renderItem(info) : null;
|
|
724
|
+
const row = info.item;
|
|
725
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { style: [styles4.row, columnWrapperStyle], children: row.map((item, kk) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react9.Fragment, { children: renderItem ? renderItem({ index: info.index * cols + kk, item, separators: info.separators }) : null }, kk)) });
|
|
726
|
+
},
|
|
727
|
+
[cols, columnWrapperStyle, renderItem]
|
|
728
|
+
);
|
|
486
729
|
const { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, footerFixed, headerFixed } = useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, isHorizontal, keyboardAware, pullSearchHeight, style });
|
|
487
|
-
const
|
|
730
|
+
const { jsListGeneration, onJsListUnmount } = (0, import_react9.useContext)(ScrollViewContext);
|
|
731
|
+
const capturedGeneration = (0, import_react9.useRef)(jsListGeneration.current);
|
|
732
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
733
|
+
capturedGeneration.current = jsListGeneration.current;
|
|
734
|
+
}, [jsListGeneration]);
|
|
735
|
+
(0, import_react9.useLayoutEffect)(() => () => onJsListUnmount(), [onJsListUnmount]);
|
|
736
|
+
const scrollTo = (0, import_react9.useCallback)((offset, animated) => {
|
|
488
737
|
scrollView.current?.scrollToOffset({ offset, animated });
|
|
489
738
|
}, []);
|
|
490
739
|
const {
|
|
@@ -493,7 +742,8 @@ var FlatListInner = ({ contentContainerStyle: externalContentContainerStyle, dat
|
|
|
493
742
|
handleScrollBeginDrag,
|
|
494
743
|
handleScrollEndDrag,
|
|
495
744
|
hiddenHeader,
|
|
496
|
-
pullSearchMinHeight
|
|
745
|
+
pullSearchMinHeight,
|
|
746
|
+
remountTarget
|
|
497
747
|
} = useScrollInit({
|
|
498
748
|
listHeaderComponent: externalListHeaderComponent,
|
|
499
749
|
onMomentumScrollEnd: externalMomentumScrollEnd,
|
|
@@ -503,7 +753,7 @@ var FlatListInner = ({ contentContainerStyle: externalContentContainerStyle, dat
|
|
|
503
753
|
pullSearchHeight,
|
|
504
754
|
scrollTo
|
|
505
755
|
});
|
|
506
|
-
const activeListHeader = (0,
|
|
756
|
+
const activeListHeader = (0, import_react9.useMemo)(() => {
|
|
507
757
|
if (!renderFilters) return pullSearchHeader;
|
|
508
758
|
const Inner = pullSearchHeader;
|
|
509
759
|
return () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
@@ -511,13 +761,30 @@ var FlatListInner = ({ contentContainerStyle: externalContentContainerStyle, dat
|
|
|
511
761
|
renderFilters
|
|
512
762
|
] });
|
|
513
763
|
}, [pullSearchHeader, renderFilters]);
|
|
514
|
-
const contentContainerStyle = (0,
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
764
|
+
const contentContainerStyle = (0, import_react9.useMemo)(() => isHorizontal ? externalContentContainerStyle : [{ minHeight: import_react_native6.Dimensions.get("window").height - contentInset.top - contentInset.bottom + pullSearchMinHeight }, externalContentContainerStyle], [isHorizontal, contentInset.bottom, contentInset.top, externalContentContainerStyle, pullSearchMinHeight]);
|
|
765
|
+
const scrollHandler = useScrollHandlerJS({ capturedGeneration, chipHidden, chipThreshold, footerFixed, headerFixed, isHorizontal, jsListGeneration, remountTarget, scrollTo });
|
|
766
|
+
const onScrollBeginDrag = (0, import_react9.useCallback)(
|
|
767
|
+
(e) => {
|
|
768
|
+
scrollHandler.onScrollBeginDrag(e);
|
|
769
|
+
handleScrollBeginDrag(e);
|
|
770
|
+
},
|
|
771
|
+
[scrollHandler, handleScrollBeginDrag]
|
|
772
|
+
);
|
|
773
|
+
const onScrollEndDrag = (0, import_react9.useCallback)(
|
|
774
|
+
(e) => {
|
|
775
|
+
scrollHandler.onScrollEndDrag(e);
|
|
776
|
+
handleScrollEndDrag(e);
|
|
777
|
+
},
|
|
778
|
+
[scrollHandler, handleScrollEndDrag]
|
|
779
|
+
);
|
|
780
|
+
const onMomentumScrollEnd = (0, import_react9.useCallback)(
|
|
781
|
+
(e) => {
|
|
782
|
+
scrollHandler.onMomentumScrollEnd(e);
|
|
783
|
+
handleMomentumScrollEnd(e);
|
|
784
|
+
},
|
|
785
|
+
[scrollHandler, handleMomentumScrollEnd]
|
|
786
|
+
);
|
|
787
|
+
const handleScrollToTop = (0, import_react9.useCallback)(() => {
|
|
521
788
|
if (isHorizontal) {
|
|
522
789
|
scrollView.current?.scrollToOffset({ offset: 0, animated: true });
|
|
523
790
|
return;
|
|
@@ -525,35 +792,39 @@ var FlatListInner = ({ contentContainerStyle: externalContentContainerStyle, dat
|
|
|
525
792
|
const offset = pullSearchHeight ? -contentInset.top + pullSearchHeight : -contentInset.top;
|
|
526
793
|
scrollView.current?.scrollToOffset({ offset, animated: true });
|
|
527
794
|
}, [isHorizontal, contentInset.top, pullSearchHeight]);
|
|
528
|
-
const handleContentSizeChange = (0,
|
|
795
|
+
const handleContentSizeChange = (0, import_react9.useCallback)(
|
|
529
796
|
(w, h) => {
|
|
530
797
|
if (onContentSizeChange) onContentSizeChange(w, h);
|
|
531
798
|
},
|
|
532
799
|
[onContentSizeChange]
|
|
533
800
|
);
|
|
534
|
-
const refreshControl = (0,
|
|
535
|
-
const nativeGesture = (0,
|
|
536
|
-
const combinedGesture = (0,
|
|
801
|
+
const refreshControl = (0, import_react9.useMemo)(() => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RefreshControl, {}), []);
|
|
802
|
+
const nativeGesture = (0, import_react9.useMemo)(() => import_react_native_gesture_handler2.Gesture.Native(), []);
|
|
803
|
+
const combinedGesture = (0, import_react9.useMemo)(() => gesture !== void 0 ? import_react_native_gesture_handler2.Gesture.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
|
|
537
804
|
const detectorGesture = gesture !== void 0 ? combinedGesture : void 0;
|
|
538
805
|
const content = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native6.View, { style: containerStyle, children: [
|
|
539
806
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
540
|
-
|
|
807
|
+
import_react_native6.FlatList,
|
|
541
808
|
{
|
|
542
809
|
...props,
|
|
543
810
|
contentContainerStyle,
|
|
544
811
|
contentInset,
|
|
812
|
+
contentInsetAdjustmentBehavior: "never",
|
|
545
813
|
contentOffset,
|
|
546
|
-
data,
|
|
814
|
+
data: cols > 1 ? rowData : data,
|
|
547
815
|
horizontal: isHorizontal,
|
|
548
816
|
initialNumToRender,
|
|
817
|
+
keyExtractor: cols > 1 ? rowKeyExtractor : keyExtractor,
|
|
549
818
|
ListHeaderComponent: activeListHeader,
|
|
550
819
|
maxToRenderPerBatch,
|
|
551
820
|
onContentSizeChange: handleContentSizeChange,
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
821
|
+
onMomentumScrollBegin: scrollHandler.onMomentumScrollBegin,
|
|
822
|
+
onMomentumScrollEnd,
|
|
823
|
+
onScroll: scrollHandler.onScroll,
|
|
824
|
+
onScrollBeginDrag,
|
|
825
|
+
onScrollEndDrag,
|
|
556
826
|
pagingEnabled,
|
|
827
|
+
renderItem: cols > 1 ? rowRenderItem : renderItem,
|
|
557
828
|
ref: (el) => {
|
|
558
829
|
if (externalRef) externalRef.current = el;
|
|
559
830
|
scrollView.current = el;
|
|
@@ -567,52 +838,56 @@ var FlatListInner = ({ contentContainerStyle: externalContentContainerStyle, dat
|
|
|
567
838
|
}
|
|
568
839
|
),
|
|
569
840
|
hiddenHeader && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { pointerEvents: "none", style: styles4.measureContainer, children: hiddenHeader }),
|
|
570
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScrollViewChip, { isHorizontal, onPress: handleScrollToTop, style: chipStyle }),
|
|
841
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScrollViewChip, { chipProps, isHorizontal, onChipPress, onPress: handleScrollToTop, style: chipStyle }),
|
|
571
842
|
showDots && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HorizontalDots, { total: data?.length ?? 0 })
|
|
572
843
|
] });
|
|
573
844
|
return detectorGesture ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native_gesture_handler2.GestureDetector, { gesture: detectorGesture, children: content }) : content;
|
|
574
845
|
};
|
|
575
|
-
var
|
|
576
|
-
|
|
846
|
+
var defaultKeyExtractor = (item, index) => {
|
|
847
|
+
const key = item?.key ?? item?.id;
|
|
848
|
+
return key != null ? String(key) : String(index);
|
|
849
|
+
};
|
|
850
|
+
var styles4 = { measureContainer: { left: 0, opacity: 0, position: "absolute", right: 0, top: -9999 }, row: { flexDirection: "row" } };
|
|
851
|
+
var FlatList = (0, import_react9.memo)(FlatListInner);
|
|
577
852
|
|
|
578
853
|
// src/PullSearch.tsx
|
|
579
|
-
var
|
|
854
|
+
var import_react10 = require("react");
|
|
580
855
|
var import_react_native7 = require("react-native");
|
|
581
|
-
var
|
|
582
|
-
var
|
|
856
|
+
var import_react_native_paper2 = require("react-native-paper");
|
|
857
|
+
var import_react_native_reanimated9 = __toESM(require("react-native-reanimated"));
|
|
583
858
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
584
|
-
var PullSearch = (0,
|
|
585
|
-
const { headerHeight, scrollPosition } = (0,
|
|
586
|
-
const theme = (0,
|
|
587
|
-
const inputRef = (0,
|
|
588
|
-
const [barHeight, setBarHeight] = (0,
|
|
589
|
-
const [value, setValue] = (0,
|
|
590
|
-
const prevPropValueRef = (0,
|
|
591
|
-
(0,
|
|
859
|
+
var PullSearch = (0, import_react10.forwardRef)(function PullSearch2({ debounce, onChangeText, onHeightChange, placeholder, value: propValue }, ref) {
|
|
860
|
+
const { headerHeight, scrollPosition } = (0, import_react10.useContext)(ScrollViewContext);
|
|
861
|
+
const theme = (0, import_react_native_paper2.useTheme)();
|
|
862
|
+
const inputRef = (0, import_react10.useRef)(null);
|
|
863
|
+
const [barHeight, setBarHeight] = (0, import_react10.useState)(0);
|
|
864
|
+
const [value, setValue] = (0, import_react10.useState)(propValue ?? "");
|
|
865
|
+
const prevPropValueRef = (0, import_react10.useRef)(propValue);
|
|
866
|
+
(0, import_react10.useEffect)(() => {
|
|
592
867
|
if (prevPropValueRef.current === propValue) return;
|
|
593
868
|
prevPropValueRef.current = propValue;
|
|
594
869
|
setValue(propValue ?? "");
|
|
595
870
|
}, [propValue]);
|
|
596
|
-
(0,
|
|
871
|
+
(0, import_react10.useImperativeHandle)(ref, () => ({
|
|
597
872
|
blur: () => inputRef.current?.blur(),
|
|
598
873
|
focus: () => inputRef.current?.focus()
|
|
599
874
|
}));
|
|
600
|
-
const blurInput = (0,
|
|
601
|
-
(0,
|
|
875
|
+
const blurInput = (0, import_react10.useCallback)(() => inputRef.current?.blur(), []);
|
|
876
|
+
(0, import_react_native_reanimated9.useAnimatedReaction)(
|
|
602
877
|
() => {
|
|
603
878
|
if (barHeight === 0) return false;
|
|
604
|
-
return scrollPosition.value >= -headerHeight + barHeight;
|
|
879
|
+
return scrollPosition.value >= -(headerHeight ?? 0) + barHeight;
|
|
605
880
|
},
|
|
606
881
|
(isHidden, wasHidden) => {
|
|
607
|
-
if (isHidden && !wasHidden) (0,
|
|
882
|
+
if (isHidden && !wasHidden) (0, import_react_native_reanimated9.runOnJS)(blurInput)();
|
|
608
883
|
},
|
|
609
884
|
[barHeight, headerHeight, blurInput]
|
|
610
885
|
);
|
|
611
|
-
const handleClear = (0,
|
|
886
|
+
const handleClear = (0, import_react10.useCallback)(() => {
|
|
612
887
|
setValue("");
|
|
613
888
|
onChangeText("");
|
|
614
889
|
}, [onChangeText]);
|
|
615
|
-
const handleLayout = (0,
|
|
890
|
+
const handleLayout = (0, import_react10.useCallback)(
|
|
616
891
|
({
|
|
617
892
|
nativeEvent: {
|
|
618
893
|
layout: { height }
|
|
@@ -623,7 +898,7 @@ var PullSearch = (0, import_react9.forwardRef)(function PullSearch2({ debounce,
|
|
|
623
898
|
},
|
|
624
899
|
[onHeightChange]
|
|
625
900
|
);
|
|
626
|
-
(0,
|
|
901
|
+
(0, import_react10.useEffect)(() => {
|
|
627
902
|
const normalizedValue = value.trim();
|
|
628
903
|
if (debounce) {
|
|
629
904
|
const timeout = setTimeout(() => onChangeText(normalizedValue), 500);
|
|
@@ -631,13 +906,14 @@ var PullSearch = (0, import_react9.forwardRef)(function PullSearch2({ debounce,
|
|
|
631
906
|
}
|
|
632
907
|
onChangeText(normalizedValue);
|
|
633
908
|
}, [debounce, onChangeText, value]);
|
|
634
|
-
const animatedStyle = (0,
|
|
909
|
+
const animatedStyle = (0, import_react_native_reanimated9.useAnimatedStyle)(() => {
|
|
635
910
|
if (barHeight === 0) return { opacity: 0 };
|
|
636
|
-
const
|
|
637
|
-
const
|
|
638
|
-
|
|
911
|
+
const h = headerHeight ?? 0;
|
|
912
|
+
const showY = -h;
|
|
913
|
+
const hideY = -h + barHeight;
|
|
914
|
+
return { opacity: (0, import_react_native_reanimated9.interpolate)(scrollPosition.value, [showY, hideY], [1, 0], import_react_native_reanimated9.Extrapolation.CLAMP) };
|
|
639
915
|
}, [barHeight, headerHeight]);
|
|
640
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_reanimated9.default.View, { onLayout: handleLayout, style: [styles5.container, animatedStyle], children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_paper2.Searchbar, { autoCorrect: false, onChangeText: (text) => setValue((text || "").trimStart()), onClearIconPress: handleClear, placeholder, placeholderTextColor: theme.colors.onSurfaceVariant, ref: inputRef, spellCheck: false, style: styles5.input, value }) });
|
|
641
917
|
});
|
|
642
918
|
var styles5 = import_react_native7.StyleSheet.create({
|
|
643
919
|
container: { paddingVertical: 8 },
|
|
@@ -1138,6 +1414,24 @@ var objectTraps = {
|
|
|
1138
1414
|
get(state, prop) {
|
|
1139
1415
|
if (prop === DRAFT_STATE)
|
|
1140
1416
|
return state;
|
|
1417
|
+
if (prop === "constructor" || prop === "__proto__") {
|
|
1418
|
+
const source2 = latest(state);
|
|
1419
|
+
const value2 = source2[prop];
|
|
1420
|
+
return new Proxy(value2 || {}, {
|
|
1421
|
+
get: (target, key) => {
|
|
1422
|
+
if (key === "__proto__" || key === "prototype") {
|
|
1423
|
+
return Object.freeze(/* @__PURE__ */ Object.create(null));
|
|
1424
|
+
}
|
|
1425
|
+
return Reflect.get(target, key);
|
|
1426
|
+
},
|
|
1427
|
+
set: () => {
|
|
1428
|
+
return true;
|
|
1429
|
+
},
|
|
1430
|
+
apply: (target, thisArg, args) => {
|
|
1431
|
+
return Reflect.apply(target, thisArg, args);
|
|
1432
|
+
}
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1141
1435
|
let arrayPlugin = state.scope_.arrayMethodsPlugin_;
|
|
1142
1436
|
const isArrayWithStringProp = state.type_ === 1 && typeof prop === "string";
|
|
1143
1437
|
if (isArrayWithStringProp) {
|
|
@@ -1167,12 +1461,18 @@ var objectTraps = {
|
|
|
1167
1461
|
return value;
|
|
1168
1462
|
},
|
|
1169
1463
|
has(state, prop) {
|
|
1464
|
+
if (prop === "constructor" || prop === "__proto__" || prop === "prototype") {
|
|
1465
|
+
return false;
|
|
1466
|
+
}
|
|
1170
1467
|
return prop in latest(state);
|
|
1171
1468
|
},
|
|
1172
1469
|
ownKeys(state) {
|
|
1173
1470
|
return Reflect.ownKeys(latest(state));
|
|
1174
1471
|
},
|
|
1175
1472
|
set(state, prop, value) {
|
|
1473
|
+
if (prop === "constructor" || prop === "__proto__" || prop === "prototype") {
|
|
1474
|
+
return true;
|
|
1475
|
+
}
|
|
1176
1476
|
const desc = getDescriptorFromProto(latest(state), prop);
|
|
1177
1477
|
if (desc?.set) {
|
|
1178
1478
|
desc.set.call(state.draft_, value);
|
|
@@ -1192,7 +1492,7 @@ var objectTraps = {
|
|
|
1192
1492
|
markChanged(state);
|
|
1193
1493
|
}
|
|
1194
1494
|
if (state.copy_[prop] === value && // special case: handle new props with value 'undefined'
|
|
1195
|
-
(value !== void 0 || prop
|
|
1495
|
+
(value !== void 0 || has(state.copy_, prop, state.type_)) || // special case: NaN
|
|
1196
1496
|
Number.isNaN(value) && Number.isNaN(state.copy_[prop]))
|
|
1197
1497
|
return true;
|
|
1198
1498
|
state.copy_[prop] = value;
|
|
@@ -2183,14 +2483,14 @@ function formatProdErrorMessage(code) {
|
|
|
2183
2483
|
}
|
|
2184
2484
|
|
|
2185
2485
|
// src/ScrollViewSettingsContext.ts
|
|
2186
|
-
var
|
|
2486
|
+
var import_react11 = require("react");
|
|
2187
2487
|
var defaultScrollViewSettings = {
|
|
2188
2488
|
backActionFixed: true,
|
|
2189
2489
|
footerFixed: false,
|
|
2190
2490
|
headerFixed: false,
|
|
2191
2491
|
snapBack: false
|
|
2192
2492
|
};
|
|
2193
|
-
var ScrollViewSettingsContext = (0,
|
|
2493
|
+
var ScrollViewSettingsContext = (0, import_react11.createContext)({
|
|
2194
2494
|
settings: defaultScrollViewSettings,
|
|
2195
2495
|
set: () => {
|
|
2196
2496
|
}
|
|
@@ -2208,16 +2508,26 @@ var scrollViewActions = slice.actions;
|
|
|
2208
2508
|
var scrollViewReducer = slice.reducer;
|
|
2209
2509
|
|
|
2210
2510
|
// src/ScrollView.tsx
|
|
2211
|
-
var
|
|
2511
|
+
var import_react12 = require("react");
|
|
2212
2512
|
var import_react_native8 = require("react-native");
|
|
2213
2513
|
var import_react_native_gesture_handler3 = require("react-native-gesture-handler");
|
|
2214
|
-
var
|
|
2514
|
+
var import_react_native_reanimated10 = __toESM(require("react-native-reanimated"));
|
|
2215
2515
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2216
|
-
var ScrollViewInner = ({ children, footerFixed: footerFixedProp, gesture, headerFixed: headerFixedProp, horizontal, keyboardAware, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pullSearchHeight, refreshing, style, ...props }) => {
|
|
2217
|
-
const scrollView = (0,
|
|
2516
|
+
var ScrollViewInner = ({ chipProps, chipThreshold, children, footerFixed: footerFixedProp, gesture, headerFixed: headerFixedProp, horizontal, keyboardAware, onChipPress, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pullSearchHeight, refreshing, style, ...props }) => {
|
|
2517
|
+
const scrollView = (0, import_react12.useRef)(null);
|
|
2218
2518
|
const isHorizontal = horizontal === true;
|
|
2219
2519
|
const { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, footerFixed, headerFixed } = useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, isHorizontal, keyboardAware, pullSearchHeight, style });
|
|
2220
|
-
const
|
|
2520
|
+
const { listGeneration, onListUnmount } = (0, import_react12.useContext)(ScrollViewContext);
|
|
2521
|
+
const capturedGeneration = (0, import_react_native_reanimated10.useSharedValue)(-1);
|
|
2522
|
+
(0, import_react12.useLayoutEffect)(() => {
|
|
2523
|
+
const generation = listGeneration.value;
|
|
2524
|
+
(0, import_react_native_reanimated10.runOnUI)((gen) => {
|
|
2525
|
+
"worklet";
|
|
2526
|
+
capturedGeneration.value = gen;
|
|
2527
|
+
})(generation);
|
|
2528
|
+
}, [capturedGeneration, listGeneration]);
|
|
2529
|
+
(0, import_react12.useLayoutEffect)(() => () => onListUnmount(), [onListUnmount]);
|
|
2530
|
+
const scrollTo = (0, import_react12.useCallback)((offset, animated) => {
|
|
2221
2531
|
scrollView.current?.scrollTo({ y: offset, animated });
|
|
2222
2532
|
}, []);
|
|
2223
2533
|
const { handleMomentumScrollEnd, handleScrollBeginDrag, handleScrollEndDrag } = useScrollInit({
|
|
@@ -2227,12 +2537,8 @@ var ScrollViewInner = ({ children, footerFixed: footerFixedProp, gesture, header
|
|
|
2227
2537
|
pullSearchHeight,
|
|
2228
2538
|
scrollTo
|
|
2229
2539
|
});
|
|
2230
|
-
const
|
|
2231
|
-
|
|
2232
|
-
scrollTo(-contentInset.top + pullSearchHeight, true);
|
|
2233
|
-
}, [contentInset.top, pullSearchHeight, scrollTo]);
|
|
2234
|
-
const handleScroll = useScrollHandler({ chipHidden, footerFixed, headerFixed, isHorizontal, onPullSearchZoneEnter: pullSearchHeight ? onPullSearchZoneEnter : void 0 });
|
|
2235
|
-
const handleScrollToTop = (0, import_react11.useCallback)(() => {
|
|
2540
|
+
const handleScroll = useScrollHandler({ capturedGeneration, chipHidden, chipThreshold, footerFixed, headerFixed, isHorizontal, listGeneration });
|
|
2541
|
+
const handleScrollToTop = (0, import_react12.useCallback)(() => {
|
|
2236
2542
|
if (isHorizontal) {
|
|
2237
2543
|
scrollView.current?.scrollTo({ x: 0, animated: true });
|
|
2238
2544
|
return;
|
|
@@ -2240,13 +2546,13 @@ var ScrollViewInner = ({ children, footerFixed: footerFixedProp, gesture, header
|
|
|
2240
2546
|
const offset = pullSearchHeight ? -contentInset.top + pullSearchHeight : -contentInset.top;
|
|
2241
2547
|
scrollView.current?.scrollTo({ y: offset, animated: true });
|
|
2242
2548
|
}, [isHorizontal, contentInset.top, pullSearchHeight]);
|
|
2243
|
-
const refreshControl = (0,
|
|
2244
|
-
const nativeGesture = (0,
|
|
2245
|
-
const combinedGesture = (0,
|
|
2549
|
+
const refreshControl = (0, import_react12.useMemo)(() => onRefresh ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RefreshControl, { onRefresh, refreshing: refreshing ?? false }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RefreshControl, {}), [onRefresh, refreshing]);
|
|
2550
|
+
const nativeGesture = (0, import_react12.useMemo)(() => import_react_native_gesture_handler3.Gesture.Native(), []);
|
|
2551
|
+
const combinedGesture = (0, import_react12.useMemo)(() => gesture !== void 0 ? import_react_native_gesture_handler3.Gesture.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
|
|
2246
2552
|
const detectorGesture = gesture !== void 0 ? combinedGesture : void 0;
|
|
2247
2553
|
const content = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native8.View, { style: containerStyle, children: [
|
|
2248
2554
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2249
|
-
|
|
2555
|
+
import_react_native_reanimated10.default.ScrollView,
|
|
2250
2556
|
{
|
|
2251
2557
|
...props,
|
|
2252
2558
|
contentInset,
|
|
@@ -2264,23 +2570,23 @@ var ScrollViewInner = ({ children, footerFixed: footerFixedProp, gesture, header
|
|
|
2264
2570
|
children
|
|
2265
2571
|
}
|
|
2266
2572
|
),
|
|
2267
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ScrollViewChip, { isHorizontal, onPress: handleScrollToTop, style: chipStyle })
|
|
2573
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ScrollViewChip, { chipProps, isHorizontal, onChipPress, onPress: handleScrollToTop, style: chipStyle })
|
|
2268
2574
|
] });
|
|
2269
2575
|
return detectorGesture ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_gesture_handler3.GestureDetector, { gesture: detectorGesture, children: content }) : content;
|
|
2270
2576
|
};
|
|
2271
|
-
var ScrollView = (0,
|
|
2577
|
+
var ScrollView = (0, import_react12.memo)(ScrollViewInner);
|
|
2272
2578
|
|
|
2273
2579
|
// src/ScrollViewFooter.tsx
|
|
2274
|
-
var
|
|
2275
|
-
var
|
|
2580
|
+
var import_auto_paper3 = require("@rific/auto-paper");
|
|
2581
|
+
var import_react13 = require("react");
|
|
2276
2582
|
var import_react_native9 = require("react-native");
|
|
2277
|
-
var
|
|
2583
|
+
var import_react_native_reanimated11 = __toESM(require("react-native-reanimated"));
|
|
2278
2584
|
var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
|
|
2279
2585
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2280
2586
|
var ScrollViewFooter = ({ children, style }) => {
|
|
2281
|
-
const { blur, footerHeight, footerFixed, footerOffset, headerHeightShared, pullSearchHeightShared, scrollPosition, setFooterHeight, snapBackFooterShared } = (0,
|
|
2587
|
+
const { blur, footerHeight, footerFixed, footerOffset, headerHeightShared, pullSearchHeightShared, scrollPosition, setFooterHeight, snapBackFooterShared } = (0, import_react13.useContext)(ScrollViewContext);
|
|
2282
2588
|
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
2283
|
-
(0,
|
|
2589
|
+
(0, import_react13.useEffect)(
|
|
2284
2590
|
() => () => {
|
|
2285
2591
|
setFooterHeight(0);
|
|
2286
2592
|
},
|
|
@@ -2293,15 +2599,15 @@ var ScrollViewFooter = ({ children, style }) => {
|
|
|
2293
2599
|
}) => {
|
|
2294
2600
|
if (footerHeight !== height) setFooterHeight(height);
|
|
2295
2601
|
};
|
|
2296
|
-
const footerStyle = (0,
|
|
2602
|
+
const footerStyle = (0, import_react_native_reanimated11.useAnimatedStyle)(() => {
|
|
2297
2603
|
if (footerFixed) return { transform: [{ translateY: 0 }] };
|
|
2298
2604
|
if (snapBackFooterShared.value) return { transform: [{ translateY: footerOffset.value }] };
|
|
2299
2605
|
const effective = scrollPosition.value + headerHeightShared.value - pullSearchHeightShared.value;
|
|
2300
2606
|
if (effective <= 0) return { transform: [{ translateY: 0 }] };
|
|
2301
2607
|
return { transform: [{ translateY: Math.min(effective, footerHeight) }] };
|
|
2302
2608
|
}, [footerHeight, footerFixed]);
|
|
2303
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2304
|
-
footerHeight > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2609
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native_reanimated11.default.View, { onLayout: handleLayout, pointerEvents: "box-none", style: [styles6.footer, footerStyle], children: [
|
|
2610
|
+
footerHeight > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_auto_paper3.BlurView, { blur, style: import_react_native9.StyleSheet.absoluteFill }),
|
|
2305
2611
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.View, { style: [styles6.row, { paddingBottom: insets.bottom }, style], children })
|
|
2306
2612
|
] });
|
|
2307
2613
|
};
|
|
@@ -2311,20 +2617,20 @@ var styles6 = import_react_native9.StyleSheet.create({
|
|
|
2311
2617
|
});
|
|
2312
2618
|
|
|
2313
2619
|
// src/ScrollViewHeader.tsx
|
|
2314
|
-
var
|
|
2315
|
-
var
|
|
2620
|
+
var import_auto_paper4 = require("@rific/auto-paper");
|
|
2621
|
+
var import_react14 = require("react");
|
|
2316
2622
|
var import_react_native10 = require("react-native");
|
|
2317
|
-
var
|
|
2318
|
-
var
|
|
2623
|
+
var import_react_native_paper3 = require("react-native-paper");
|
|
2624
|
+
var import_react_native_reanimated12 = __toESM(require("react-native-reanimated"));
|
|
2319
2625
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
2320
2626
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2321
|
-
var ActionBg = ({ blur, style }) => blur ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [import_react_native10.StyleSheet.absoluteFill, styles7.actionBg, style], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2627
|
+
var ActionBg = ({ blur, style }) => blur ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [import_react_native10.StyleSheet.absoluteFill, styles7.actionBg, style], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper4.BlurView, { blur: true, style: import_react_native10.StyleSheet.absoluteFill }) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [import_react_native10.StyleSheet.absoluteFill, styles7.actionBg, style], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper3.Surface, { style: import_react_native10.StyleSheet.absoluteFill, elevation: 1, children: null }) });
|
|
2322
2628
|
var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionFixed, caption, centerContent, children, iconSize, style, title, topInset = true, trailingAction, trailingActionFixed = true }) => {
|
|
2323
|
-
const { blur, headerHeight, headerFixed, headerOffset, progress, progressing, pullSearchHeightShared, scrollPosition, setHeaderHeight, snapBackHeaderShared } = (0,
|
|
2324
|
-
const { settings } = (0,
|
|
2629
|
+
const { blur, headerHeight, headerFixed, headerOffset, progress, progressing, pullSearchHeightShared, scrollPosition, setHeaderHeight, snapBackHeaderShared } = (0, import_react14.useContext)(ScrollViewContext);
|
|
2630
|
+
const { settings } = (0, import_react14.useContext)(ScrollViewSettingsContext);
|
|
2325
2631
|
const effectiveBackActionFixed = backActionFixed ?? settings.backActionFixed;
|
|
2326
2632
|
const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
|
|
2327
|
-
const theme = (0,
|
|
2633
|
+
const theme = (0, import_react_native_paper3.useTheme)();
|
|
2328
2634
|
const top = topInset ? insets.top : 0;
|
|
2329
2635
|
const handleLayout = ({
|
|
2330
2636
|
nativeEvent: {
|
|
@@ -2333,23 +2639,25 @@ var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionFi
|
|
|
2333
2639
|
}) => {
|
|
2334
2640
|
if (headerHeight !== height) setHeaderHeight(height);
|
|
2335
2641
|
};
|
|
2336
|
-
const translateStyle = (0,
|
|
2642
|
+
const translateStyle = (0, import_react_native_reanimated12.useAnimatedStyle)(() => {
|
|
2337
2643
|
if (headerFixed) return { transform: [{ translateY: 0 }] };
|
|
2338
2644
|
if (snapBackHeaderShared.value) return { transform: [{ translateY: headerOffset.value }] };
|
|
2339
|
-
const effective = scrollPosition.value + headerHeight - pullSearchHeightShared.value;
|
|
2645
|
+
const effective = scrollPosition.value + (headerHeight ?? 0) - pullSearchHeightShared.value;
|
|
2340
2646
|
if (effective <= 0) return { transform: [{ translateY: 0 }] };
|
|
2341
2647
|
return { transform: [{ translateY: -effective }] };
|
|
2342
2648
|
}, [headerFixed, headerHeight]);
|
|
2343
|
-
const blurStyle = (0,
|
|
2649
|
+
const blurStyle = (0, import_react_native_reanimated12.useAnimatedStyle)(() => {
|
|
2344
2650
|
if (!headerHeight) return { height: 0 };
|
|
2345
2651
|
if (headerFixed) return { height: headerHeight };
|
|
2346
|
-
const
|
|
2347
|
-
|
|
2652
|
+
const h = headerHeight ?? 0;
|
|
2653
|
+
const translateY = snapBackHeaderShared.value ? headerOffset.value : -Math.max(0, scrollPosition.value + h - pullSearchHeightShared.value);
|
|
2654
|
+
return { height: Math.max(h + translateY, top) };
|
|
2348
2655
|
}, [headerFixed, headerHeight, top]);
|
|
2349
|
-
const progressStyle = (0,
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2656
|
+
const progressStyle = (0, import_react_native_reanimated12.useAnimatedStyle)(() => {
|
|
2657
|
+
const h = headerHeight ?? 0;
|
|
2658
|
+
if (headerFixed) return { top: h };
|
|
2659
|
+
const slide = snapBackHeaderShared.value ? -headerOffset.value : Math.max(0, scrollPosition.value + h - pullSearchHeightShared.value);
|
|
2660
|
+
return { top: Math.max(h - slide, top) };
|
|
2353
2661
|
}, [headerFixed, headerHeight, top]);
|
|
2354
2662
|
const actionMargin = 4;
|
|
2355
2663
|
const contentMinHeight = actionSize + 2 * actionMargin;
|
|
@@ -2359,12 +2667,11 @@ var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionFi
|
|
|
2359
2667
|
const leadingStyle = { alignItems: "center", height: actionSize, justifyContent: "center", left: actionMargin, position: "absolute", top: actionTop, width: actionSize, zIndex: 3, ...actionShadow };
|
|
2360
2668
|
const trailingStyle = { alignItems: "center", height: actionSize, justifyContent: "center", position: "absolute", right: actionMargin, top: actionTop, width: actionSize, zIndex: 3, ...actionShadow };
|
|
2361
2669
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2362
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2363
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2364
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [{ paddingTop: top }, style], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: [styles7.content, { minHeight: contentMinHeight }], children: [
|
|
2670
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_reanimated12.default.View, { pointerEvents: "none", style: [styles7.blur, blurStyle], children: headerHeight !== null && headerHeight > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper4.BlurView, { blur, style: [styles7.blurInner, { height: headerHeight }] }) }),
|
|
2671
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_reanimated12.default.View, { onLayout: handleLayout, pointerEvents: "box-none", style: [headerHeight === null ? styles7.headerInit : styles7.header, translateStyle], children: [
|
|
2672
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [{ paddingTop: top }, style], children: children ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: [styles7.content, { minHeight: contentMinHeight }], children: [
|
|
2365
2673
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: styles7.side }),
|
|
2366
2674
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: styles7.spacer }),
|
|
2367
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: styles7.side, children }),
|
|
2368
2675
|
(centerContent || title || caption) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [import_react_native10.StyleSheet.absoluteFill, styles7.titleContainer], pointerEvents: centerContent ? "box-none" : "none", children: centerContent ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2369
2676
|
title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.Text, { numberOfLines: 1, style: [styles7.title, { color: theme.colors.onSurface }], children: title }),
|
|
2370
2677
|
caption && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.Text, { numberOfLines: 1, style: [styles7.caption, { color: theme.colors.onSurfaceVariant }], children: caption })
|
|
@@ -2372,18 +2679,18 @@ var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionFi
|
|
|
2372
2679
|
] }) }),
|
|
2373
2680
|
!blur && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native10.View, { style: [styles7.divider, { backgroundColor: theme.colors.outlineVariant }] })
|
|
2374
2681
|
] }),
|
|
2375
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2376
|
-
backAction && (effectiveBackActionFixed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2682
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_reanimated12.default.View, { pointerEvents: "none", style: [styles7.progress, progressStyle], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper3.ProgressBar, { indeterminate: progress === null, visible: progressing, progress: progress ?? void 0 }) }),
|
|
2683
|
+
backAction && (effectiveBackActionFixed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_reanimated12.default.View, { style: leadingStyle, children: [
|
|
2377
2684
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
2378
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2379
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2685
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper3.Appbar.BackAction, { onPress: backAction, size: iconSize ?? actionSize / 2, style: buttonStyle })
|
|
2686
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_reanimated12.default.View, { style: [leadingStyle, translateStyle], children: [
|
|
2380
2687
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
2381
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2688
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper3.Appbar.BackAction, { onPress: backAction, size: iconSize ?? actionSize / 2, style: buttonStyle })
|
|
2382
2689
|
] })),
|
|
2383
2690
|
trailingAction && (trailingActionFixed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native10.View, { style: trailingStyle, children: [
|
|
2384
2691
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
2385
2692
|
trailingAction
|
|
2386
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2693
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_reanimated12.default.View, { style: [trailingStyle, translateStyle], children: [
|
|
2387
2694
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
2388
2695
|
trailingAction
|
|
2389
2696
|
] }))
|
|
@@ -2406,63 +2713,78 @@ var styles7 = import_react_native10.StyleSheet.create({
|
|
|
2406
2713
|
});
|
|
2407
2714
|
|
|
2408
2715
|
// src/ScrollViewProvider.tsx
|
|
2409
|
-
var
|
|
2410
|
-
var
|
|
2716
|
+
var import_auto_paper5 = require("@rific/auto-paper");
|
|
2717
|
+
var import_react15 = require("react");
|
|
2411
2718
|
var import_react_native11 = require("react-native");
|
|
2412
|
-
var
|
|
2719
|
+
var import_react_native_reanimated13 = require("react-native-reanimated");
|
|
2413
2720
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2414
2721
|
var ScrollViewProvider = ({ blur, children, fixed = false, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight = 60 }) => {
|
|
2415
|
-
const { settings } = (0,
|
|
2416
|
-
const effectiveBlur = (0,
|
|
2722
|
+
const { settings } = (0, import_react15.useContext)(ScrollViewSettingsContext);
|
|
2723
|
+
const effectiveBlur = (0, import_auto_paper5.useBlur)(blur);
|
|
2417
2724
|
const effectiveSnapBack = snapBack ?? settings.snapBack;
|
|
2418
2725
|
const effectiveSnapBackHeader = snapBackHeader ?? settings.snapBackHeader;
|
|
2419
2726
|
const effectiveSnapBackFooter = snapBackFooter ?? settings.snapBackFooter;
|
|
2420
|
-
const [headerHeight, setHeaderHeightState] = (0,
|
|
2421
|
-
const [footerHeight, setFooterHeightState] = (0,
|
|
2422
|
-
const [progress, setProgress] = (0,
|
|
2423
|
-
const [progressing, setProgressing] = (0,
|
|
2424
|
-
const scrollPosition = (0,
|
|
2425
|
-
const
|
|
2426
|
-
const
|
|
2427
|
-
const
|
|
2428
|
-
const
|
|
2429
|
-
const
|
|
2430
|
-
const
|
|
2431
|
-
const
|
|
2432
|
-
(0,
|
|
2727
|
+
const [headerHeight, setHeaderHeightState] = (0, import_react15.useState)(null);
|
|
2728
|
+
const [footerHeight, setFooterHeightState] = (0, import_react15.useState)(0);
|
|
2729
|
+
const [progress, setProgress] = (0, import_react15.useState)(null);
|
|
2730
|
+
const [progressing, setProgressing] = (0, import_react15.useState)(false);
|
|
2731
|
+
const scrollPosition = (0, import_react_native_reanimated13.useSharedValue)(0);
|
|
2732
|
+
const listGeneration = (0, import_react_native_reanimated13.useSharedValue)(0);
|
|
2733
|
+
const jsListGeneration = (0, import_react15.useRef)(0);
|
|
2734
|
+
const headerHeightShared = (0, import_react_native_reanimated13.useSharedValue)(0);
|
|
2735
|
+
const footerHeightShared = (0, import_react_native_reanimated13.useSharedValue)(0);
|
|
2736
|
+
const headerOffset = (0, import_react_native_reanimated13.useSharedValue)(0);
|
|
2737
|
+
const footerOffset = (0, import_react_native_reanimated13.useSharedValue)(0);
|
|
2738
|
+
const pullSearchHeightShared = (0, import_react_native_reanimated13.useSharedValue)(0);
|
|
2739
|
+
const snapBackHeaderShared = (0, import_react_native_reanimated13.useSharedValue)(false);
|
|
2740
|
+
const snapBackFooterShared = (0, import_react_native_reanimated13.useSharedValue)(false);
|
|
2741
|
+
(0, import_react15.useEffect)(() => {
|
|
2433
2742
|
snapBackHeaderShared.value = effectiveSnapBackHeader ?? effectiveSnapBack;
|
|
2434
2743
|
snapBackFooterShared.value = effectiveSnapBackFooter ?? effectiveSnapBack;
|
|
2435
2744
|
}, [effectiveSnapBack, effectiveSnapBackFooter, effectiveSnapBackHeader, snapBackFooterShared, snapBackHeaderShared]);
|
|
2436
|
-
const setHeaderHeight = (0,
|
|
2745
|
+
const setHeaderHeight = (0, import_react15.useCallback)(
|
|
2437
2746
|
(h) => {
|
|
2438
2747
|
setHeaderHeightState(h);
|
|
2439
|
-
headerHeightShared.value = h;
|
|
2748
|
+
headerHeightShared.value = h ?? 0;
|
|
2440
2749
|
},
|
|
2441
2750
|
[headerHeightShared]
|
|
2442
2751
|
);
|
|
2443
|
-
const
|
|
2752
|
+
const onListUnmount = (0, import_react15.useCallback)(() => {
|
|
2753
|
+
listGeneration.value += 1;
|
|
2754
|
+
}, [listGeneration]);
|
|
2755
|
+
const onJsListUnmount = (0, import_react15.useCallback)(() => {
|
|
2756
|
+
jsListGeneration.current += 1;
|
|
2757
|
+
}, []);
|
|
2758
|
+
(0, import_react15.useEffect)(() => {
|
|
2759
|
+
if (!__DEV__ || headerHeight !== null) return;
|
|
2760
|
+
const timeout = setTimeout(() => {
|
|
2761
|
+
console.warn("[scroll-view] No ScrollViewHeader ever measured inside this ScrollViewProvider \u2014 scroll content stays hidden (opacity: 0) until one does. Render a <ScrollViewHeader> (it can be empty / zero height) inside this provider.");
|
|
2762
|
+
}, 3e3);
|
|
2763
|
+
return () => clearTimeout(timeout);
|
|
2764
|
+
}, [headerHeight]);
|
|
2765
|
+
const setFooterHeight = (0, import_react15.useCallback)(
|
|
2444
2766
|
(h) => {
|
|
2445
2767
|
setFooterHeightState(h);
|
|
2446
2768
|
footerHeightShared.value = h;
|
|
2447
2769
|
},
|
|
2448
2770
|
[footerHeightShared]
|
|
2449
2771
|
);
|
|
2450
|
-
const scrollHeight = (0,
|
|
2772
|
+
const scrollHeight = (0, import_react15.useMemo)(() => import_react_native11.Dimensions.get("window").height - (headerHeight ?? 0) - footerHeight, [headerHeight, footerHeight]);
|
|
2451
2773
|
const effectiveHeaderFixed = fixed || (headerFixed ?? settings.headerFixed);
|
|
2452
2774
|
const effectiveFooterFixed = fixed || (footerFixed ?? settings.footerFixed);
|
|
2453
|
-
const value = (0,
|
|
2775
|
+
const value = (0, import_react15.useMemo)(() => ({ blur: effectiveBlur, footerHeight, footerHeightShared, footerFixed: effectiveFooterFixed, footerOffset, headerHeight, headerHeightShared, headerFixed: effectiveHeaderFixed, headerOffset, jsListGeneration, listGeneration, onJsListUnmount, onListUnmount, progress, pullSearchHeightShared, progressing, scrollHeight, scrollPosition, setFooterHeight, setHeaderHeight, setProgress, setProgressing, snapBackFooterShared, snapBackHeaderShared, tabBarHeight }), [effectiveBlur, effectiveFooterFixed, effectiveHeaderFixed, footerHeight, footerHeightShared, footerOffset, headerHeight, headerHeightShared, headerOffset, jsListGeneration, listGeneration, onJsListUnmount, onListUnmount, progress, pullSearchHeightShared, progressing, scrollHeight, scrollPosition, setFooterHeight, setHeaderHeight, snapBackFooterShared, snapBackHeaderShared, tabBarHeight]);
|
|
2454
2776
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ScrollViewContext.Provider, { value, children });
|
|
2455
2777
|
};
|
|
2456
2778
|
|
|
2457
2779
|
// src/ScrollViewSettingsProvider.tsx
|
|
2458
|
-
var
|
|
2780
|
+
var import_react16 = require("react");
|
|
2459
2781
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2460
|
-
var ScrollViewSettingsProvider = ({ children, onChange,
|
|
2461
|
-
const [settings, setSettings] = (0,
|
|
2782
|
+
var ScrollViewSettingsProvider = ({ children, onChange, initialValue }) => {
|
|
2783
|
+
const [settings, setSettings] = (0, import_react16.useState)(() => ({
|
|
2462
2784
|
...defaultScrollViewSettings,
|
|
2463
|
-
...
|
|
2785
|
+
...initialValue
|
|
2464
2786
|
}));
|
|
2465
|
-
const set2 = (0,
|
|
2787
|
+
const set2 = (0, import_react16.useCallback)(
|
|
2466
2788
|
(patch) => {
|
|
2467
2789
|
setSettings((prev) => {
|
|
2468
2790
|
const next = { ...prev, ...patch };
|
|
@@ -2472,33 +2794,33 @@ var ScrollViewSettingsProvider = ({ children, onChange, value }) => {
|
|
|
2472
2794
|
},
|
|
2473
2795
|
[onChange]
|
|
2474
2796
|
);
|
|
2475
|
-
const ctx = (0,
|
|
2797
|
+
const ctx = (0, import_react16.useMemo)(() => ({ settings, set: set2 }), [settings, set2]);
|
|
2476
2798
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScrollViewSettingsContext.Provider, { value: ctx, children });
|
|
2477
2799
|
};
|
|
2478
2800
|
|
|
2479
2801
|
// src/SectionList.tsx
|
|
2480
|
-
var
|
|
2802
|
+
var import_react18 = require("react");
|
|
2481
2803
|
var import_react_native12 = require("react-native");
|
|
2482
2804
|
var import_react_native_gesture_handler4 = require("react-native-gesture-handler");
|
|
2483
|
-
var
|
|
2805
|
+
var import_react_native_reanimated15 = __toESM(require("react-native-reanimated"));
|
|
2484
2806
|
|
|
2485
2807
|
// src/internal/useStickyHeaders.ts
|
|
2486
|
-
var
|
|
2487
|
-
var
|
|
2808
|
+
var import_react17 = require("react");
|
|
2809
|
+
var import_react_native_reanimated14 = require("react-native-reanimated");
|
|
2488
2810
|
var import_react_native_safe_area_context5 = require("react-native-safe-area-context");
|
|
2489
2811
|
function useStickyHeaders(headerFixed, enabled) {
|
|
2490
|
-
const { headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared } = (0,
|
|
2812
|
+
const { headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared } = (0, import_react17.useContext)(ScrollViewContext);
|
|
2491
2813
|
const insetsTop = (0, import_react_native_safe_area_context5.useSafeAreaInsets)().top;
|
|
2492
|
-
const sectionYPositions = (0,
|
|
2493
|
-
const sectionHeights = (0,
|
|
2494
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
2495
|
-
const contentIndexShared = (0,
|
|
2496
|
-
(0,
|
|
2814
|
+
const sectionYPositions = (0, import_react_native_reanimated14.useSharedValue)([]);
|
|
2815
|
+
const sectionHeights = (0, import_react_native_reanimated14.useSharedValue)([]);
|
|
2816
|
+
const [activeIndex, setActiveIndex] = (0, import_react17.useState)(-1);
|
|
2817
|
+
const contentIndexShared = (0, import_react_native_reanimated14.useSharedValue)(-1);
|
|
2818
|
+
(0, import_react17.useLayoutEffect)(() => {
|
|
2497
2819
|
contentIndexShared.value = activeIndex;
|
|
2498
2820
|
}, [activeIndex, contentIndexShared]);
|
|
2499
|
-
const positionsCache = (0,
|
|
2500
|
-
const heightsCache = (0,
|
|
2501
|
-
(0,
|
|
2821
|
+
const positionsCache = (0, import_react17.useRef)([]);
|
|
2822
|
+
const heightsCache = (0, import_react17.useRef)([]);
|
|
2823
|
+
(0, import_react_native_reanimated14.useAnimatedReaction)(
|
|
2502
2824
|
() => {
|
|
2503
2825
|
if (!enabled) return -1;
|
|
2504
2826
|
const positions = sectionYPositions.value;
|
|
@@ -2523,11 +2845,11 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
2523
2845
|
return active;
|
|
2524
2846
|
},
|
|
2525
2847
|
(curr, prev) => {
|
|
2526
|
-
if (curr !== prev) (0,
|
|
2848
|
+
if (curr !== prev) (0, import_react_native_reanimated14.runOnJS)(setActiveIndex)(curr);
|
|
2527
2849
|
},
|
|
2528
2850
|
[enabled, headerFixed, insetsTop]
|
|
2529
2851
|
);
|
|
2530
|
-
const clipStyle = (0,
|
|
2852
|
+
const clipStyle = (0, import_react_native_reanimated14.useAnimatedStyle)(() => {
|
|
2531
2853
|
const hHeight = headerHeightShared.value;
|
|
2532
2854
|
const scrollPos = scrollPosition.value;
|
|
2533
2855
|
let stickyTop;
|
|
@@ -2541,7 +2863,7 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
2541
2863
|
}
|
|
2542
2864
|
return { top: stickyTop };
|
|
2543
2865
|
}, [enabled, headerFixed, insetsTop]);
|
|
2544
|
-
const overlayStyle = (0,
|
|
2866
|
+
const overlayStyle = (0, import_react_native_reanimated14.useAnimatedStyle)(() => {
|
|
2545
2867
|
const hidden = { opacity: 0, top: 0, transform: [{ translateY: 0 }] };
|
|
2546
2868
|
if (!enabled) return hidden;
|
|
2547
2869
|
const index = contentIndexShared.value;
|
|
@@ -2569,7 +2891,7 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
2569
2891
|
}
|
|
2570
2892
|
return { opacity: 1, top: 0, transform: [{ translateY }] };
|
|
2571
2893
|
}, [enabled, headerFixed, insetsTop]);
|
|
2572
|
-
const measureHeader = (0,
|
|
2894
|
+
const measureHeader = (0, import_react17.useCallback)(
|
|
2573
2895
|
(index, pageY, height) => {
|
|
2574
2896
|
const contentY = pageY + scrollPosition.value;
|
|
2575
2897
|
positionsCache.current[index] = contentY;
|
|
@@ -2579,7 +2901,7 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
2579
2901
|
},
|
|
2580
2902
|
[scrollPosition, sectionHeights, sectionYPositions]
|
|
2581
2903
|
);
|
|
2582
|
-
const resetPositions = (0,
|
|
2904
|
+
const resetPositions = (0, import_react17.useCallback)(
|
|
2583
2905
|
(count) => {
|
|
2584
2906
|
positionsCache.current = Array.from({ length: count }, () => -1);
|
|
2585
2907
|
sectionYPositions.value = positionsCache.current.slice();
|
|
@@ -2593,18 +2915,27 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
2593
2915
|
|
|
2594
2916
|
// src/SectionList.tsx
|
|
2595
2917
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2596
|
-
var AnimatedSectionList =
|
|
2597
|
-
var SectionListInner = ({ contentContainerStyle: externalContentContainerStyle, initialNumToRender = 20, maxToRenderPerBatch = 50, renderFilters, footerFixed: footerFixedProp, gesture, headerFixed: headerFixedProp, keyboardAware, ListHeaderComponent: externalListHeaderComponent, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onContentSizeChange, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pullSearchHeight, refreshing, removeClippedSubviews = false, sections, showsVerticalScrollIndicator, style, ref: externalRef, windowSize = 100, ...props }) => {
|
|
2598
|
-
const scrollView = (0,
|
|
2918
|
+
var AnimatedSectionList = import_react_native_reanimated15.default.createAnimatedComponent(import_react_native12.SectionList);
|
|
2919
|
+
var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: externalContentContainerStyle, initialNumToRender = 20, maxToRenderPerBatch = 50, renderFilters, footerFixed: footerFixedProp, gesture, headerFixed: headerFixedProp, keyboardAware, ListHeaderComponent: externalListHeaderComponent, onChipPress, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onContentSizeChange, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pullSearchHeight, refreshing, removeClippedSubviews = false, sections, showsVerticalScrollIndicator, style, ref: externalRef, windowSize = 100, ...props }) => {
|
|
2920
|
+
const scrollView = (0, import_react18.useRef)(null);
|
|
2599
2921
|
const { stickySectionHeadersEnabled = true, renderSectionHeader, ...passThroughProps } = props;
|
|
2600
2922
|
const { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, footerFixed, headerFixed, headerHeight } = useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, keyboardAware, pullSearchHeight, style });
|
|
2923
|
+
const { listGeneration, onListUnmount } = (0, import_react18.useContext)(ScrollViewContext);
|
|
2924
|
+
const capturedGeneration = (0, import_react_native_reanimated15.useSharedValue)(-1);
|
|
2925
|
+
(0, import_react18.useLayoutEffect)(() => {
|
|
2926
|
+
const generation = listGeneration.value;
|
|
2927
|
+
(0, import_react_native_reanimated15.runOnUI)((gen) => {
|
|
2928
|
+
"worklet";
|
|
2929
|
+
capturedGeneration.value = gen;
|
|
2930
|
+
})(generation);
|
|
2931
|
+
}, [capturedGeneration, listGeneration]);
|
|
2601
2932
|
const usesCustomSticky = stickySectionHeadersEnabled && renderSectionHeader != null;
|
|
2602
2933
|
const { activeIndex, clipStyle, measureHeader, overlayStyle, resetPositions } = useStickyHeaders(headerFixed, usesCustomSticky);
|
|
2603
|
-
(0,
|
|
2934
|
+
(0, import_react18.useLayoutEffect)(() => {
|
|
2604
2935
|
if (usesCustomSticky) resetPositions(sections.length);
|
|
2605
2936
|
}, [sections, usesCustomSticky, resetPositions, headerHeight]);
|
|
2606
|
-
const sectionViewRefs = (0,
|
|
2607
|
-
const wrappedRenderSectionHeader = (0,
|
|
2937
|
+
const sectionViewRefs = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
|
|
2938
|
+
const wrappedRenderSectionHeader = (0, import_react18.useMemo)(() => {
|
|
2608
2939
|
if (!usesCustomSticky) return renderSectionHeader ?? void 0;
|
|
2609
2940
|
return (info) => {
|
|
2610
2941
|
const idx = sections.findIndex((s) => s === info.section);
|
|
@@ -2625,7 +2956,8 @@ var SectionListInner = ({ contentContainerStyle: externalContentContainerStyle,
|
|
|
2625
2956
|
);
|
|
2626
2957
|
};
|
|
2627
2958
|
}, [usesCustomSticky, renderSectionHeader, sections, measureHeader]);
|
|
2628
|
-
|
|
2959
|
+
(0, import_react18.useLayoutEffect)(() => () => onListUnmount(), [onListUnmount]);
|
|
2960
|
+
const scrollTo = (0, import_react18.useCallback)((offset, animated) => {
|
|
2629
2961
|
scrollView.current?.getScrollResponder()?.scrollTo({ y: offset, animated });
|
|
2630
2962
|
}, []);
|
|
2631
2963
|
const {
|
|
@@ -2643,7 +2975,7 @@ var SectionListInner = ({ contentContainerStyle: externalContentContainerStyle,
|
|
|
2643
2975
|
pullSearchHeight,
|
|
2644
2976
|
scrollTo
|
|
2645
2977
|
});
|
|
2646
|
-
const activeListHeader = (0,
|
|
2978
|
+
const activeListHeader = (0, import_react18.useMemo)(() => {
|
|
2647
2979
|
if (!renderFilters) return pullSearchHeader;
|
|
2648
2980
|
const Inner = pullSearchHeader;
|
|
2649
2981
|
return () => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
@@ -2651,8 +2983,8 @@ var SectionListInner = ({ contentContainerStyle: externalContentContainerStyle,
|
|
|
2651
2983
|
renderFilters
|
|
2652
2984
|
] });
|
|
2653
2985
|
}, [pullSearchHeader, renderFilters]);
|
|
2654
|
-
const pullSearchSettled = (0,
|
|
2655
|
-
(0,
|
|
2986
|
+
const pullSearchSettled = (0, import_react18.useRef)(false);
|
|
2987
|
+
(0, import_react18.useEffect)(() => {
|
|
2656
2988
|
if (!usesCustomSticky || activeListHeader == null || pullSearchSettled.current) return;
|
|
2657
2989
|
pullSearchSettled.current = true;
|
|
2658
2990
|
const handle = requestAnimationFrame(() => {
|
|
@@ -2664,25 +2996,21 @@ var SectionListInner = ({ contentContainerStyle: externalContentContainerStyle,
|
|
|
2664
2996
|
});
|
|
2665
2997
|
return () => cancelAnimationFrame(handle);
|
|
2666
2998
|
}, [activeListHeader, usesCustomSticky, measureHeader]);
|
|
2667
|
-
const contentContainerStyle = (0,
|
|
2668
|
-
const
|
|
2669
|
-
|
|
2670
|
-
scrollTo(-contentInset.top + pullSearchHeight, true);
|
|
2671
|
-
}, [contentInset.top, pullSearchHeight, scrollTo]);
|
|
2672
|
-
const handleScroll = useScrollHandler({ chipHidden, footerFixed, headerFixed, onPullSearchZoneEnter: pullSearchHeight ? onPullSearchZoneEnter : void 0 });
|
|
2673
|
-
const handleScrollToTop = (0, import_react17.useCallback)(() => {
|
|
2999
|
+
const contentContainerStyle = (0, import_react18.useMemo)(() => [{ minHeight: import_react_native12.Dimensions.get("window").height - contentInset.top - contentInset.bottom + pullSearchMinHeight }, externalContentContainerStyle], [contentInset.bottom, contentInset.top, externalContentContainerStyle, pullSearchMinHeight]);
|
|
3000
|
+
const handleScroll = useScrollHandler({ capturedGeneration, chipHidden, chipThreshold, footerFixed, headerFixed, listGeneration });
|
|
3001
|
+
const handleScrollToTop = (0, import_react18.useCallback)(() => {
|
|
2674
3002
|
const offset = pullSearchHeight ? -contentInset.top + pullSearchHeight : -contentInset.top;
|
|
2675
3003
|
scrollView.current?.getScrollResponder()?.scrollTo({ y: offset, animated: true });
|
|
2676
3004
|
}, [contentInset.top, pullSearchHeight]);
|
|
2677
|
-
const handleContentSizeChange = (0,
|
|
3005
|
+
const handleContentSizeChange = (0, import_react18.useCallback)(
|
|
2678
3006
|
(w, h) => {
|
|
2679
3007
|
if (onContentSizeChange) onContentSizeChange(w, h);
|
|
2680
3008
|
},
|
|
2681
3009
|
[onContentSizeChange]
|
|
2682
3010
|
);
|
|
2683
|
-
const refreshControl = (0,
|
|
2684
|
-
const nativeGesture = (0,
|
|
2685
|
-
const combinedGesture = (0,
|
|
3011
|
+
const refreshControl = (0, import_react18.useMemo)(() => onRefresh ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefreshControl, { onRefresh, refreshing: refreshing ?? false }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefreshControl, {}), [onRefresh, refreshing]);
|
|
3012
|
+
const nativeGesture = (0, import_react18.useMemo)(() => import_react_native_gesture_handler4.Gesture.Native(), []);
|
|
3013
|
+
const combinedGesture = (0, import_react18.useMemo)(() => gesture !== void 0 ? import_react_native_gesture_handler4.Gesture.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
|
|
2686
3014
|
const detectorGesture = gesture !== void 0 ? combinedGesture : void 0;
|
|
2687
3015
|
const content = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native12.View, { style: containerStyle, children: [
|
|
2688
3016
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
@@ -2713,11 +3041,11 @@ var SectionListInner = ({ contentContainerStyle: externalContentContainerStyle,
|
|
|
2713
3041
|
stickySectionHeadersEnabled: false,
|
|
2714
3042
|
windowSize
|
|
2715
3043
|
},
|
|
2716
|
-
headerHeight > 0 ? 1 : 0
|
|
3044
|
+
headerHeight !== null && headerHeight > 0 ? 1 : 0
|
|
2717
3045
|
),
|
|
2718
3046
|
hiddenHeader && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native12.View, { pointerEvents: "none", style: styles8.measureContainer, children: hiddenHeader }),
|
|
2719
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollViewChip, { onPress: handleScrollToTop, style: chipStyle }),
|
|
2720
|
-
usesCustomSticky && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3047
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollViewChip, { chipProps, onChipPress, onPress: handleScrollToTop, style: chipStyle }),
|
|
3048
|
+
usesCustomSticky && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_reanimated15.default.View, { pointerEvents: "none", style: [styles8.stickyClip, clipStyle], children: activeIndex >= 0 && activeIndex < sections.length && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_reanimated15.default.View, { style: [styles8.stickyOverlay, overlayStyle], children: renderSectionHeader({ section: sections[activeIndex] }) }) })
|
|
2721
3049
|
] });
|
|
2722
3050
|
return detectorGesture ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_gesture_handler4.GestureDetector, { gesture: detectorGesture, children: content }) : content;
|
|
2723
3051
|
};
|
|
@@ -2726,18 +3054,18 @@ var styles8 = {
|
|
|
2726
3054
|
stickyClip: { bottom: 0, left: 0, overflow: "hidden", position: "absolute", right: 0, zIndex: 2 },
|
|
2727
3055
|
stickyOverlay: { left: 0, position: "absolute", right: 0 }
|
|
2728
3056
|
};
|
|
2729
|
-
var SectionList = (0,
|
|
3057
|
+
var SectionList = (0, import_react18.memo)(SectionListInner);
|
|
2730
3058
|
|
|
2731
3059
|
// src/useScrollView.ts
|
|
2732
|
-
var
|
|
3060
|
+
var import_react19 = require("react");
|
|
2733
3061
|
var useScrollView = () => {
|
|
2734
|
-
const { progress, progressing, scrollHeight, scrollPosition, setProgress, setProgressing } = (0,
|
|
3062
|
+
const { progress, progressing, scrollHeight, scrollPosition, setProgress, setProgressing } = (0, import_react19.useContext)(ScrollViewContext);
|
|
2735
3063
|
return { progress, progressing, scrollHeight, scrollPosition, setProgress, setProgressing };
|
|
2736
3064
|
};
|
|
2737
3065
|
|
|
2738
3066
|
// src/useScrollViewSettings.ts
|
|
2739
|
-
var
|
|
2740
|
-
var useScrollViewSettings = () => (0,
|
|
3067
|
+
var import_react20 = require("react");
|
|
3068
|
+
var useScrollViewSettings = () => (0, import_react20.useContext)(ScrollViewSettingsContext);
|
|
2741
3069
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2742
3070
|
0 && (module.exports = {
|
|
2743
3071
|
CustomList,
|