@rific/scroll-view 0.8.3 → 0.9.1
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/LICENSE +21 -0
- package/README.md +199 -25
- package/dist/index.d.mts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +335 -156
- package/dist/index.mjs +311 -136
- package/package.json +4 -4
- package/src/CustomList.tsx +3 -3
- package/src/FlatList.tsx +4 -4
- package/src/PullSearch.tsx +1 -1
- package/src/ScrollView.tsx +4 -4
- package/src/ScrollViewChromeContext.ts +37 -0
- package/src/ScrollViewChromeProvider.tsx +65 -0
- package/src/ScrollViewContext.ts +17 -1
- package/src/ScrollViewFooter.tsx +56 -20
- package/src/ScrollViewHeader.tsx +31 -10
- package/src/ScrollViewProvider.tsx +100 -27
- package/src/SectionList.tsx +4 -4
- package/src/index.ts +3 -0
- package/src/internal/ChromeRegistrar.tsx +37 -0
- package/src/internal/HorizontalDots.tsx +1 -1
- package/src/internal/ScrollViewChip.tsx +3 -3
- package/src/internal/chrome.ts +19 -0
- package/src/internal/useScrollHandler.ts +26 -5
- package/src/internal/useScrollHandlerJS.ts +34 -10
- package/src/internal/useScrollList.ts +29 -12
- package/src/internal/useStickyHeaders.ts +3 -3
- package/src/redux/scrollViewSlice.ts +1 -1
- package/src/useKeyboardInset.ts +1 -1
- package/src/useScrollInit.ts +12 -12
- package/src/useScrollViewChrome.ts +41 -0
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ __export(index_exports, {
|
|
|
34
34
|
FlatList: () => FlatList,
|
|
35
35
|
PullSearch: () => PullSearch,
|
|
36
36
|
ScrollView: () => ScrollView,
|
|
37
|
+
ScrollViewChromeProvider: () => ScrollViewChromeProvider,
|
|
37
38
|
ScrollViewContext: () => ScrollViewContext,
|
|
38
39
|
ScrollViewFooter: () => ScrollViewFooter,
|
|
39
40
|
ScrollViewHeader: () => ScrollViewHeader,
|
|
@@ -46,6 +47,9 @@ __export(index_exports, {
|
|
|
46
47
|
scrollViewReducer: () => scrollViewReducer,
|
|
47
48
|
useKeyboardInset: () => useKeyboardInset,
|
|
48
49
|
useScrollView: () => useScrollView,
|
|
50
|
+
useScrollViewChromePin: () => useScrollViewChromePin,
|
|
51
|
+
useScrollViewChromeReveal: () => useScrollViewChromeReveal,
|
|
52
|
+
useScrollViewChromeStyle: () => useScrollViewChromeStyle,
|
|
49
53
|
useScrollViewSettings: () => useScrollViewSettings
|
|
50
54
|
});
|
|
51
55
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -90,6 +94,9 @@ var import_react_native_reanimated3 = require("react-native-reanimated");
|
|
|
90
94
|
var import_react = require("react");
|
|
91
95
|
var ScrollViewContext = (0, import_react.createContext)({
|
|
92
96
|
blur: true,
|
|
97
|
+
chromeHosted: false,
|
|
98
|
+
chromeOverhang: 0,
|
|
99
|
+
chromeWritable: null,
|
|
93
100
|
footerAboveKeyboard: false,
|
|
94
101
|
footerHeight: null,
|
|
95
102
|
footerHeightShared: null,
|
|
@@ -120,6 +127,7 @@ var ScrollViewContext = (0, import_react.createContext)({
|
|
|
120
127
|
},
|
|
121
128
|
snapBackFooterShared: null,
|
|
122
129
|
snapBackHeaderShared: null,
|
|
130
|
+
stackHeightShared: null,
|
|
123
131
|
tabBarHeight: 0
|
|
124
132
|
});
|
|
125
133
|
|
|
@@ -311,9 +319,20 @@ function useScrollInit({ listHeaderComponent, onMomentumScrollEnd: externalMomen
|
|
|
311
319
|
return { activeListHeader, handleMomentumScrollEnd, handleScrollBeginDrag, handleScrollEndDrag, hiddenHeader, onRemountSyncRetry, onRemountSynced, pullSearchMinHeight: pullSearchHeight ?? 0, remountSyncTarget, remountTarget, scrollReady };
|
|
312
320
|
}
|
|
313
321
|
|
|
322
|
+
// src/internal/chrome.ts
|
|
323
|
+
var CHROME_SLACK = 2;
|
|
324
|
+
var chromeTravel = (maxScroll, headerHeight) => {
|
|
325
|
+
"worklet";
|
|
326
|
+
return usesContentInset ? maxScroll + headerHeight : maxScroll;
|
|
327
|
+
};
|
|
328
|
+
var chromeSettleTarget = (offset, stackHeight) => {
|
|
329
|
+
"worklet";
|
|
330
|
+
return offset > stackHeight / 2 ? stackHeight : 0;
|
|
331
|
+
};
|
|
332
|
+
|
|
314
333
|
// src/internal/useScrollHandler.ts
|
|
315
334
|
function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold = 100, footerFixed, headerFixed, isHorizontal, listGeneration, onRemountSyncRetry, onRemountSynced, remountSyncTarget }) {
|
|
316
|
-
const {
|
|
335
|
+
const { chromeHosted, chromeWritable, footerOffset, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackFooterShared, snapBackHeaderShared, stackHeightShared } = (0, import_react3.useContext)(ScrollViewContext);
|
|
317
336
|
const snapUpAccum = (0, import_react_native_reanimated3.useSharedValue)(0);
|
|
318
337
|
const fromBottomBounce = (0, import_react_native_reanimated3.useSharedValue)(false);
|
|
319
338
|
return (0, import_react_native_reanimated3.useAnimatedScrollHandler)(
|
|
@@ -348,7 +367,9 @@ function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold = 100,
|
|
|
348
367
|
fromBottomBounce.value = false;
|
|
349
368
|
}
|
|
350
369
|
const snapHeader = snapBackHeaderShared.value && !headerFixed;
|
|
351
|
-
const
|
|
370
|
+
const hideable = !chromeHosted || chromeTravel(maxScroll, headerHeightShared.value) >= stackHeightShared.value;
|
|
371
|
+
if (chromeHosted && !hideable && chromeWritable.value && footerOffset.value !== 0) footerOffset.value = 0;
|
|
372
|
+
const snapFooter = snapBackFooterShared.value && !footerFixed && chromeWritable.value && hideable;
|
|
352
373
|
if (snapHeader || snapFooter) {
|
|
353
374
|
if (yn <= -headerHeightShared.value) {
|
|
354
375
|
snapUpAccum.value = 0;
|
|
@@ -358,7 +379,7 @@ function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold = 100,
|
|
|
358
379
|
snapUpAccum.value = 0;
|
|
359
380
|
if (yn >= -headerHeightShared.value + pullSearchHeightShared.value) {
|
|
360
381
|
if (snapHeader) headerOffset.value = Math.max(-headerHeightShared.value, Math.min(0, headerOffset.value - delta));
|
|
361
|
-
if (snapFooter) footerOffset.value = Math.max(0, Math.min(
|
|
382
|
+
if (snapFooter) footerOffset.value = Math.max(0, Math.min(stackHeightShared.value, footerOffset.value + delta));
|
|
362
383
|
}
|
|
363
384
|
} else if (delta < 0 && !fromBottomBounce.value) {
|
|
364
385
|
if (yn >= -headerHeightShared.value + pullSearchHeightShared.value) snapUpAccum.value -= delta;
|
|
@@ -375,21 +396,29 @@ function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold = 100,
|
|
|
375
396
|
fromBottomBounce.value = false;
|
|
376
397
|
snapUpAccum.value = 0;
|
|
377
398
|
},
|
|
378
|
-
onEndDrag: ({ contentOffset: { y }, contentSize: { height: contentHeight }, layoutMeasurement: { height: layoutHeight } }) => {
|
|
399
|
+
onEndDrag: ({ contentOffset: { y }, contentSize: { height: contentHeight }, layoutMeasurement: { height: layoutHeight }, velocity }) => {
|
|
379
400
|
"worklet";
|
|
380
401
|
if (isHorizontal) return;
|
|
402
|
+
const revealing = snapUpAccum.value >= 10;
|
|
381
403
|
if (y >= contentHeight - layoutHeight - 10) {
|
|
382
404
|
fromBottomBounce.value = true;
|
|
383
405
|
snapUpAccum.value = 0;
|
|
384
406
|
}
|
|
407
|
+
if (chromeHosted && !footerFixed && chromeWritable.value && (velocity === void 0 || Math.abs(velocity.y) < 0.1)) {
|
|
408
|
+
footerOffset.value = (0, import_react_native_reanimated3.withTiming)(revealing ? 0 : chromeSettleTarget(footerOffset.value, stackHeightShared.value), { duration: 200 });
|
|
409
|
+
}
|
|
385
410
|
},
|
|
386
411
|
onMomentumEnd: () => {
|
|
387
412
|
"worklet";
|
|
413
|
+
const revealing = snapUpAccum.value >= 10;
|
|
388
414
|
fromBottomBounce.value = false;
|
|
389
415
|
snapUpAccum.value = 0;
|
|
416
|
+
if (chromeHosted && !isHorizontal && !footerFixed && chromeWritable.value) {
|
|
417
|
+
footerOffset.value = (0, import_react_native_reanimated3.withTiming)(revealing ? 0 : chromeSettleTarget(footerOffset.value, stackHeightShared.value), { duration: 200 });
|
|
418
|
+
}
|
|
390
419
|
}
|
|
391
420
|
},
|
|
392
|
-
[capturedGeneration, headerFixed, footerFixed, isHorizontal, chipThreshold, listGeneration, onRemountSyncRetry, onRemountSynced, remountSyncTarget]
|
|
421
|
+
[capturedGeneration, chromeHosted, headerFixed, footerFixed, isHorizontal, chipThreshold, listGeneration, onRemountSyncRetry, onRemountSynced, remountSyncTarget]
|
|
393
422
|
);
|
|
394
423
|
}
|
|
395
424
|
|
|
@@ -431,18 +460,20 @@ var CHIP_SLIDE = 48;
|
|
|
431
460
|
function useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, hideUntilMeasured, isHorizontal, keyboardAware, pullSearchHeight, style } = {}) {
|
|
432
461
|
const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
|
|
433
462
|
const keyboardHeight = useKeyboardInset();
|
|
434
|
-
const { footerAboveKeyboard, footerHeight, footerFixed: contextFooterFixed, headerHeight, headerHeightShared, headerFixed: contextHeaderFixed, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared, tabBarHeight } = (0, import_react5.useContext)(ScrollViewContext);
|
|
463
|
+
const { chromeHosted, chromeOverhang, footerAboveKeyboard, footerHeight, footerFixed: contextFooterFixed, headerHeight, headerHeightShared, headerFixed: contextHeaderFixed, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared, tabBarHeight } = (0, import_react5.useContext)(ScrollViewContext);
|
|
435
464
|
const headerFixed = isHorizontal ? true : headerFixedProp ?? contextHeaderFixed;
|
|
436
|
-
const footerFixed = isHorizontal ? true : footerFixedProp ?? contextFooterFixed;
|
|
465
|
+
const footerFixed = isHorizontal ? true : chromeHosted ? contextFooterFixed : footerFixedProp ?? contextFooterFixed;
|
|
437
466
|
(0, import_react5.useEffect)(() => {
|
|
438
467
|
pullSearchHeightShared.value = usesContentInset ? pullSearchHeight ?? 0 : 0;
|
|
439
468
|
}, [pullSearchHeight, pullSearchHeightShared]);
|
|
440
469
|
const containerStyle = (0, import_react5.useMemo)(() => headerHeight === null ? [{ flex: 1, opacity: hideUntilMeasured ? 0 : 1 }, style] : [import_react_native5.StyleSheet.absoluteFill, style], [headerHeight, hideUntilMeasured, style]);
|
|
441
470
|
const insetGeometry = (0, import_react5.useMemo)(() => {
|
|
442
|
-
const
|
|
443
|
-
const
|
|
471
|
+
const baseReserve = chromeHosted ? chromeOverhang : insets.bottom;
|
|
472
|
+
const footerReserve = chromeHosted ? Math.max(footerHeight ?? 0, baseReserve) : footerFixed ? footerHeight || baseReserve : baseReserve;
|
|
473
|
+
const barReserve = chromeHosted && footerFixed && footerAboveKeyboard ? Math.max(tabBarHeight - keyboardHeight, 0) : tabBarHeight;
|
|
474
|
+
const bottom = (!keyboardAware || footerFixed && footerAboveKeyboard ? footerReserve : Math.max(footerReserve, keyboardHeight)) + barReserve;
|
|
444
475
|
return { bottom, top: headerHeight ?? 0 };
|
|
445
|
-
}, [footerAboveKeyboard, footerFixed, footerHeight, insets.bottom, tabBarHeight, headerHeight, keyboardAware, keyboardHeight]);
|
|
476
|
+
}, [chromeHosted, chromeOverhang, footerAboveKeyboard, footerFixed, footerHeight, insets.bottom, tabBarHeight, headerHeight, keyboardAware, keyboardHeight]);
|
|
446
477
|
const contentInset = usesContentInset ? insetGeometry : ZERO_INSET;
|
|
447
478
|
const contentPadding = (0, import_react5.useMemo)(() => usesContentInset || isHorizontal ? null : { paddingBottom: insetGeometry.bottom, paddingTop: insetGeometry.top }, [insetGeometry, isHorizontal]);
|
|
448
479
|
const [startedWithHeader] = (0, import_react5.useState)(headerHeight !== null);
|
|
@@ -631,7 +662,7 @@ var import_react_native_reanimated8 = require("react-native-reanimated");
|
|
|
631
662
|
var REMOUNT_RETRY_TOLERANCE = 1;
|
|
632
663
|
var REMOUNT_RETRY_MAX_ATTEMPTS = 8;
|
|
633
664
|
function useScrollHandlerJS({ capturedGeneration, chipHidden, chipThreshold = 100, footerFixed, headerFixed, isHorizontal, jsListGeneration, remountTarget = null, scrollTo }) {
|
|
634
|
-
const {
|
|
665
|
+
const { chromeHosted, chromeWritable, footerOffset, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackFooterShared, snapBackHeaderShared, stackHeightShared } = (0, import_react8.useContext)(ScrollViewContext);
|
|
635
666
|
const snapUpAccum = (0, import_react8.useRef)(0);
|
|
636
667
|
const fromBottomBounce = (0, import_react8.useRef)(false);
|
|
637
668
|
const pendingRemountTarget = (0, import_react8.useRef)(remountTarget);
|
|
@@ -675,7 +706,9 @@ function useScrollHandlerJS({ capturedGeneration, chipHidden, chipThreshold = 10
|
|
|
675
706
|
fromBottomBounce.current = false;
|
|
676
707
|
}
|
|
677
708
|
const snapHeader = snapBackHeaderShared.value && !headerFixed;
|
|
678
|
-
const
|
|
709
|
+
const hideable = !chromeHosted || chromeTravel(maxScroll, headerHeightShared.value) >= stackHeightShared.value;
|
|
710
|
+
if (chromeHosted && !hideable && chromeWritable.value && footerOffset.value !== 0) footerOffset.value = 0;
|
|
711
|
+
const snapFooter = snapBackFooterShared.value && !footerFixed && chromeWritable.value && hideable;
|
|
679
712
|
if (snapHeader || snapFooter) {
|
|
680
713
|
if (yn <= -headerHeightShared.value) {
|
|
681
714
|
snapUpAccum.current = 0;
|
|
@@ -685,7 +718,7 @@ function useScrollHandlerJS({ capturedGeneration, chipHidden, chipThreshold = 10
|
|
|
685
718
|
snapUpAccum.current = 0;
|
|
686
719
|
if (yn >= -headerHeightShared.value + pullSearchHeightShared.value) {
|
|
687
720
|
if (snapHeader) headerOffset.value = Math.max(-headerHeightShared.value, Math.min(0, headerOffset.value - delta));
|
|
688
|
-
if (snapFooter) footerOffset.value = Math.max(0, Math.min(
|
|
721
|
+
if (snapFooter) footerOffset.value = Math.max(0, Math.min(stackHeightShared.value, footerOffset.value + delta));
|
|
689
722
|
}
|
|
690
723
|
} else if (delta < 0 && !fromBottomBounce.current) {
|
|
691
724
|
if (yn >= -headerHeightShared.value + pullSearchHeightShared.value) snapUpAccum.current -= delta;
|
|
@@ -697,7 +730,7 @@ function useScrollHandlerJS({ capturedGeneration, chipHidden, chipThreshold = 10
|
|
|
697
730
|
}
|
|
698
731
|
}
|
|
699
732
|
},
|
|
700
|
-
[capturedGeneration, chipHidden, chipThreshold,
|
|
733
|
+
[capturedGeneration, chipHidden, chipThreshold, chromeHosted, chromeWritable, footerFixed, footerOffset, headerFixed, headerHeightShared, headerOffset, isHorizontal, jsListGeneration, pullSearchHeightShared, scrollPosition, scrollTo, snapBackFooterShared, snapBackHeaderShared, stackHeightShared]
|
|
701
734
|
);
|
|
702
735
|
const onScrollBeginDrag = (0, import_react8.useCallback)(() => {
|
|
703
736
|
fromBottomBounce.current = false;
|
|
@@ -705,25 +738,37 @@ function useScrollHandlerJS({ capturedGeneration, chipHidden, chipThreshold = 10
|
|
|
705
738
|
}, []);
|
|
706
739
|
const onMomentumScrollBegin = (0, import_react8.useCallback)(() => {
|
|
707
740
|
}, []);
|
|
741
|
+
const settle = (0, import_react8.useCallback)(
|
|
742
|
+
(revealing) => {
|
|
743
|
+
if (!chromeHosted || footerFixed || !chromeWritable.value) return;
|
|
744
|
+
footerOffset.value = (0, import_react_native_reanimated8.withTiming)(revealing ? 0 : chromeSettleTarget(footerOffset.value, stackHeightShared.value), { duration: 200 });
|
|
745
|
+
},
|
|
746
|
+
[chromeHosted, chromeWritable, footerFixed, footerOffset, stackHeightShared]
|
|
747
|
+
);
|
|
708
748
|
const onScrollEndDrag = (0, import_react8.useCallback)(
|
|
709
749
|
(event) => {
|
|
710
750
|
if (isHorizontal) return;
|
|
711
751
|
const {
|
|
712
752
|
contentOffset: { y },
|
|
713
753
|
contentSize: { height: contentHeight },
|
|
714
|
-
layoutMeasurement: { height: layoutHeight }
|
|
754
|
+
layoutMeasurement: { height: layoutHeight },
|
|
755
|
+
velocity
|
|
715
756
|
} = event.nativeEvent;
|
|
757
|
+
const revealing = snapUpAccum.current >= 10;
|
|
716
758
|
if (y >= contentHeight - layoutHeight - 10) {
|
|
717
759
|
fromBottomBounce.current = true;
|
|
718
760
|
snapUpAccum.current = 0;
|
|
719
761
|
}
|
|
762
|
+
if (velocity === void 0 || Math.abs(velocity.y) < 0.1) settle(revealing);
|
|
720
763
|
},
|
|
721
|
-
[isHorizontal]
|
|
764
|
+
[isHorizontal, settle]
|
|
722
765
|
);
|
|
723
766
|
const onMomentumScrollEnd = (0, import_react8.useCallback)(() => {
|
|
767
|
+
const revealing = snapUpAccum.current >= 10;
|
|
724
768
|
fromBottomBounce.current = false;
|
|
725
769
|
snapUpAccum.current = 0;
|
|
726
|
-
|
|
770
|
+
if (!isHorizontal) settle(revealing);
|
|
771
|
+
}, [isHorizontal, settle]);
|
|
727
772
|
return { onMomentumScrollBegin, onMomentumScrollEnd, onScroll, onScrollBeginDrag, onScrollEndDrag };
|
|
728
773
|
}
|
|
729
774
|
|
|
@@ -911,7 +956,7 @@ var PullSearch = (0, import_react10.forwardRef)(function PullSearch2({ debounce,
|
|
|
911
956
|
(isHidden, wasHidden) => {
|
|
912
957
|
if (isHidden && !wasHidden) (0, import_react_native_reanimated9.runOnJS)(blurInput)();
|
|
913
958
|
},
|
|
914
|
-
// scrollPosition has to be listed too, not just read
|
|
959
|
+
// scrollPosition has to be listed too, not just read - see useStickyHeaders' useAnimatedReaction
|
|
915
960
|
// for why: on web, without reanimated's Babel plugin active, an unlisted SharedValue mutation
|
|
916
961
|
// never re-triggers this reaction (confirmed empirically elsewhere in this package).
|
|
917
962
|
[barHeight, headerHeight, blurInput, scrollPosition]
|
|
@@ -1052,13 +1097,47 @@ var ScrollViewInner = ({ chipProps, chipThreshold, children, contentContainerSty
|
|
|
1052
1097
|
};
|
|
1053
1098
|
var ScrollView = (0, import_react11.memo)(ScrollViewInner);
|
|
1054
1099
|
|
|
1100
|
+
// src/ScrollViewChromeProvider.tsx
|
|
1101
|
+
var import_react13 = require("react");
|
|
1102
|
+
var import_react_native_reanimated11 = require("react-native-reanimated");
|
|
1103
|
+
|
|
1104
|
+
// src/ScrollViewChromeContext.ts
|
|
1105
|
+
var import_react12 = require("react");
|
|
1106
|
+
var ScrollViewChromeHostContext = (0, import_react12.createContext)(null);
|
|
1107
|
+
var ScrollViewChromeContext = (0, import_react12.createContext)(null);
|
|
1108
|
+
|
|
1109
|
+
// src/ScrollViewChromeProvider.tsx
|
|
1110
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1111
|
+
var REVEAL_DURATION = 200;
|
|
1112
|
+
var alwaysActive = () => true;
|
|
1113
|
+
var ScrollViewChromeProvider = ({ children, footprint, overhang = 0, snapBack = true, useIsActive = alwaysActive }) => {
|
|
1114
|
+
const offset = (0, import_react_native_reanimated11.useSharedValue)(0);
|
|
1115
|
+
const [claims, setClaims] = (0, import_react13.useState)([]);
|
|
1116
|
+
const [pins, setPins] = (0, import_react13.useState)(0);
|
|
1117
|
+
const activeId = claims.length > 0 ? claims[claims.length - 1] : null;
|
|
1118
|
+
const pinned = pins > 0;
|
|
1119
|
+
const claim = (0, import_react13.useCallback)((id) => setClaims((current) => [...current.filter((c) => c !== id), id]), []);
|
|
1120
|
+
const release = (0, import_react13.useCallback)((id) => setClaims((current) => current.filter((c) => c !== id)), []);
|
|
1121
|
+
const addPin = (0, import_react13.useCallback)(() => setPins((current) => current + 1), []);
|
|
1122
|
+
const removePin = (0, import_react13.useCallback)(() => setPins((current) => Math.max(0, current - 1)), []);
|
|
1123
|
+
const reveal = (0, import_react13.useCallback)(() => {
|
|
1124
|
+
offset.value = (0, import_react_native_reanimated11.withTiming)(0, { duration: REVEAL_DURATION });
|
|
1125
|
+
}, [offset]);
|
|
1126
|
+
(0, import_react13.useEffect)(() => {
|
|
1127
|
+
reveal();
|
|
1128
|
+
}, [activeId, pinned, reveal]);
|
|
1129
|
+
const host = (0, import_react13.useMemo)(() => ({ activeId, claim, footprint, offset, overhang, pinned, release, reveal, snapBack, useIsActive }), [activeId, claim, footprint, offset, overhang, pinned, release, reveal, snapBack, useIsActive]);
|
|
1130
|
+
const chrome = (0, import_react13.useMemo)(() => ({ addPin, footprint, offset, overhang, removePin, reveal }), [addPin, footprint, offset, overhang, removePin, reveal]);
|
|
1131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ScrollViewChromeContext.Provider, { value: chrome, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ScrollViewChromeHostContext.Provider, { value: host, children }) });
|
|
1132
|
+
};
|
|
1133
|
+
|
|
1055
1134
|
// src/ScrollViewFooter.tsx
|
|
1056
1135
|
var import_auto_paper3 = require("@rific/auto-paper");
|
|
1057
|
-
var
|
|
1136
|
+
var import_react14 = require("react");
|
|
1058
1137
|
var import_react_native11 = require("react-native");
|
|
1059
|
-
var
|
|
1138
|
+
var import_react_native_reanimated12 = __toESM(require("react-native-reanimated"));
|
|
1060
1139
|
var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
|
|
1061
|
-
var
|
|
1140
|
+
var import_jsx_runtime9 = (
|
|
1062
1141
|
// bottom: tabBarHeight (not the styles.footer default of 0) - a consuming app's own persistent
|
|
1063
1142
|
// tab bar (a fixture outside this package's header/footer concepts entirely, same as
|
|
1064
1143
|
// useScrollList's content-inset reservation) sits below this at the true screen bottom, so this
|
|
@@ -1066,14 +1145,14 @@ var import_jsx_runtime8 = (
|
|
|
1066
1145
|
require("react/jsx-runtime")
|
|
1067
1146
|
);
|
|
1068
1147
|
var ScrollViewFooter = ({ children, style }) => {
|
|
1069
|
-
const { blur, footerAboveKeyboard, footerHeight, footerFixed, footerOffset, headerHeightShared, pullSearchHeightShared, scrollPosition, setFooterHeight, snapBackFooterShared, tabBarHeight } = (0,
|
|
1148
|
+
const { blur, chromeHosted, chromeOverhang, footerAboveKeyboard, footerHeight, footerFixed, footerOffset, headerHeightShared, pullSearchHeightShared, scrollPosition, setFooterHeight, snapBackFooterShared, stackHeightShared, tabBarHeight } = (0, import_react14.useContext)(ScrollViewContext);
|
|
1070
1149
|
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
1071
1150
|
const keyboardHeight = useKeyboardInset();
|
|
1072
|
-
const setFooterHeightRef = (0,
|
|
1073
|
-
(0,
|
|
1151
|
+
const setFooterHeightRef = (0, import_react14.useRef)(setFooterHeight);
|
|
1152
|
+
(0, import_react14.useEffect)(() => {
|
|
1074
1153
|
setFooterHeightRef.current = setFooterHeight;
|
|
1075
1154
|
});
|
|
1076
|
-
(0,
|
|
1155
|
+
(0, import_react14.useEffect)(
|
|
1077
1156
|
() => () => {
|
|
1078
1157
|
setFooterHeightRef.current(null);
|
|
1079
1158
|
},
|
|
@@ -1086,19 +1165,29 @@ var ScrollViewFooter = ({ children, style }) => {
|
|
|
1086
1165
|
}) => {
|
|
1087
1166
|
if (footerHeight !== height) setFooterHeight(height);
|
|
1088
1167
|
};
|
|
1089
|
-
const footerStyle = (0,
|
|
1168
|
+
const footerStyle = (0, import_react_native_reanimated12.useAnimatedStyle)(() => {
|
|
1169
|
+
if (chromeHosted) return { transform: [{ translateY: Math.min(Math.max(footerOffset.value, 0), stackHeightShared.value) }] };
|
|
1090
1170
|
if (footerFixed) return { transform: [{ translateY: 0 }] };
|
|
1091
1171
|
if (snapBackFooterShared.value) return { transform: [{ translateY: footerOffset.value }] };
|
|
1092
1172
|
const effective = scrollPosition.value + headerHeightShared.value - pullSearchHeightShared.value;
|
|
1093
1173
|
if (effective <= 0) return { transform: [{ translateY: 0 }] };
|
|
1094
1174
|
return { transform: [{ translateY: Math.min(effective, footerHeight ?? 0) }] };
|
|
1095
|
-
}, [footerHeight, footerFixed, headerHeightShared, pullSearchHeightShared, scrollPosition, snapBackFooterShared, footerOffset]);
|
|
1175
|
+
}, [chromeHosted, footerHeight, footerFixed, headerHeightShared, pullSearchHeightShared, scrollPosition, snapBackFooterShared, footerOffset, stackHeightShared]);
|
|
1096
1176
|
const containerPaddingBottom = footerFixed && footerAboveKeyboard ? keyboardHeight : 0;
|
|
1097
|
-
const
|
|
1177
|
+
const rowRef = (0, import_react14.useRef)(null);
|
|
1178
|
+
(0, import_react14.useLayoutEffect)(() => {
|
|
1179
|
+
if (import_react_native11.Platform.OS !== "web" || footerHeight) return;
|
|
1180
|
+
const height = rowRef.current?.offsetHeight;
|
|
1181
|
+
if (typeof height !== "number" || height <= 0) return;
|
|
1182
|
+
setFooterHeight(height + containerPaddingBottom);
|
|
1183
|
+
}, []);
|
|
1184
|
+
const bottomPadding = chromeHosted ? chromeOverhang : insets.bottom;
|
|
1185
|
+
const rowPaddingBottom = footerFixed && footerAboveKeyboard ? Math.max(bottomPadding - keyboardHeight, 0) : bottomPadding;
|
|
1186
|
+
const footerBottom = chromeHosted && footerFixed && footerAboveKeyboard ? Math.max(tabBarHeight - keyboardHeight, 0) : tabBarHeight;
|
|
1098
1187
|
const { paddingBottom: consumerPaddingBottom, ...restStyle } = style ?? {};
|
|
1099
|
-
return /* @__PURE__ */ (0,
|
|
1100
|
-
(footerHeight ?? 0) > 0 && /* @__PURE__ */ (0,
|
|
1101
|
-
/* @__PURE__ */ (0,
|
|
1188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_reanimated12.default.View, { onLayout: handleLayout, pointerEvents: "box-none", style: [styles6.footer, { bottom: footerBottom, paddingBottom: containerPaddingBottom }, footerStyle], children: [
|
|
1189
|
+
(footerHeight ?? 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper3.BlurView, { blur, style: import_react_native11.StyleSheet.absoluteFill }),
|
|
1190
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native11.View, { ref: rowRef, style: [styles6.row, restStyle, { paddingBottom: rowPaddingBottom + (typeof consumerPaddingBottom === "number" ? consumerPaddingBottom : 0) }], children })
|
|
1102
1191
|
] });
|
|
1103
1192
|
};
|
|
1104
1193
|
var styles6 = import_react_native11.StyleSheet.create({
|
|
@@ -1108,21 +1197,21 @@ var styles6 = import_react_native11.StyleSheet.create({
|
|
|
1108
1197
|
|
|
1109
1198
|
// src/ScrollViewHeader.tsx
|
|
1110
1199
|
var import_auto_paper4 = require("@rific/auto-paper");
|
|
1111
|
-
var
|
|
1200
|
+
var import_react15 = require("react");
|
|
1112
1201
|
var import_react_native12 = require("react-native");
|
|
1113
1202
|
var import_react_native_paper4 = require("react-native-paper");
|
|
1114
|
-
var
|
|
1203
|
+
var import_react_native_reanimated13 = __toESM(require("react-native-reanimated"));
|
|
1115
1204
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
1116
|
-
var
|
|
1117
|
-
var ActionBg = ({ blur, style }) => blur ? /* @__PURE__ */ (0,
|
|
1205
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1206
|
+
var ActionBg = ({ blur, style }) => blur ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: [import_react_native12.StyleSheet.absoluteFill, styles7.actionBg, style], children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_auto_paper4.BlurView, { blur: true, style: import_react_native12.StyleSheet.absoluteFill }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: [import_react_native12.StyleSheet.absoluteFill, styles7.actionBg, style], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper4.Surface, { style: import_react_native12.StyleSheet.absoluteFill, elevation: 1, children: null }) });
|
|
1118
1207
|
var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionAccessibilityLabel, backActionFixed, caption, centerContent, children, iconSize, style, title, topInset = true, trailingAction, trailingActionFixed = true }) => {
|
|
1119
|
-
const { blur, headerHeight, headerFixed, headerHeightShared, headerOffset, progress, progressing, pullSearchHeightShared, scrollPosition, setHeaderHeight, snapBackHeaderShared } = (0,
|
|
1120
|
-
const { settings } = (0,
|
|
1208
|
+
const { blur, headerHeight, headerFixed, headerHeightShared, headerOffset, progress, progressing, pullSearchHeightShared, scrollPosition, setHeaderHeight, snapBackHeaderShared } = (0, import_react15.useContext)(ScrollViewContext);
|
|
1209
|
+
const { settings } = (0, import_react15.useContext)(ScrollViewSettingsContext);
|
|
1121
1210
|
const effectiveBackActionFixed = backActionFixed ?? settings.backActionFixed;
|
|
1122
1211
|
const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
|
|
1123
1212
|
const theme = (0, import_react_native_paper4.useTheme)();
|
|
1124
1213
|
const top = topInset ? insets.top : 0;
|
|
1125
|
-
const measuredShared = (0,
|
|
1214
|
+
const measuredShared = (0, import_react_native_reanimated13.useSharedValue)(false);
|
|
1126
1215
|
const handleLayout = ({
|
|
1127
1216
|
nativeEvent: {
|
|
1128
1217
|
layout: { height }
|
|
@@ -1131,24 +1220,32 @@ var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionAc
|
|
|
1131
1220
|
measuredShared.value = true;
|
|
1132
1221
|
if (headerHeight !== height) setHeaderHeight(height);
|
|
1133
1222
|
};
|
|
1223
|
+
const contentRef = (0, import_react15.useRef)(null);
|
|
1224
|
+
(0, import_react15.useLayoutEffect)(() => {
|
|
1225
|
+
if (import_react_native12.Platform.OS !== "web" || headerHeight) return;
|
|
1226
|
+
const height = contentRef.current?.offsetHeight;
|
|
1227
|
+
if (typeof height !== "number" || height <= 0) return;
|
|
1228
|
+
measuredShared.value = true;
|
|
1229
|
+
setHeaderHeight(height);
|
|
1230
|
+
}, []);
|
|
1134
1231
|
const actionMargin = 4;
|
|
1135
1232
|
const contentMinHeight = actionSize + 2 * actionMargin;
|
|
1136
1233
|
const unmeasuredHeight = top + contentMinHeight;
|
|
1137
|
-
const translateStyle = (0,
|
|
1234
|
+
const translateStyle = (0, import_react_native_reanimated13.useAnimatedStyle)(() => {
|
|
1138
1235
|
if (headerFixed) return { transform: [{ translateY: 0 }] };
|
|
1139
1236
|
if (snapBackHeaderShared.value) return { transform: [{ translateY: headerOffset.value }] };
|
|
1140
1237
|
const effective = scrollPosition.value + headerHeightShared.value - pullSearchHeightShared.value;
|
|
1141
1238
|
if (effective <= 0) return { transform: [{ translateY: 0 }] };
|
|
1142
1239
|
return { transform: [{ translateY: -effective }] };
|
|
1143
1240
|
}, [headerFixed, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared]);
|
|
1144
|
-
const blurStyle = (0,
|
|
1241
|
+
const blurStyle = (0, import_react_native_reanimated13.useAnimatedStyle)(() => {
|
|
1145
1242
|
if (!measuredShared.value) return { height: unmeasuredHeight };
|
|
1146
1243
|
if (!headerHeightShared.value) return { height: 0 };
|
|
1147
1244
|
if (headerFixed) return { height: headerHeightShared.value };
|
|
1148
1245
|
const translateY = snapBackHeaderShared.value ? headerOffset.value : -Math.max(0, scrollPosition.value + headerHeightShared.value - pullSearchHeightShared.value);
|
|
1149
1246
|
return { height: Math.max(headerHeightShared.value + translateY, top) };
|
|
1150
1247
|
}, [headerFixed, top, unmeasuredHeight, measuredShared, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared]);
|
|
1151
|
-
const progressStyle = (0,
|
|
1248
|
+
const progressStyle = (0, import_react_native_reanimated13.useAnimatedStyle)(() => {
|
|
1152
1249
|
const h = headerHeightShared.value;
|
|
1153
1250
|
if (headerFixed) return { top: h };
|
|
1154
1251
|
const slide = snapBackHeaderShared.value ? -headerOffset.value : Math.max(0, scrollPosition.value + h - pullSearchHeightShared.value);
|
|
@@ -1159,32 +1256,32 @@ var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionAc
|
|
|
1159
1256
|
const actionShadow = { borderRadius: actionSize / 2, elevation: 2, shadowColor: "#000", shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.15, shadowRadius: 2 };
|
|
1160
1257
|
const leadingStyle = { alignItems: "center", height: actionSize, justifyContent: "center", left: actionMargin, position: "absolute", top: actionTop, width: actionSize, zIndex: 3, ...actionShadow };
|
|
1161
1258
|
const trailingStyle = { alignItems: "center", height: actionSize, justifyContent: "center", position: "absolute", right: actionMargin, top: actionTop, width: actionSize, zIndex: 3, ...actionShadow };
|
|
1162
|
-
return /* @__PURE__ */ (0,
|
|
1163
|
-
/* @__PURE__ */ (0,
|
|
1164
|
-
/* @__PURE__ */ (0,
|
|
1165
|
-
/* @__PURE__ */ (0,
|
|
1166
|
-
/* @__PURE__ */ (0,
|
|
1167
|
-
/* @__PURE__ */ (0,
|
|
1168
|
-
(centerContent || title || caption) && /* @__PURE__ */ (0,
|
|
1169
|
-
title && /* @__PURE__ */ (0,
|
|
1170
|
-
caption && /* @__PURE__ */ (0,
|
|
1259
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1260
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_reanimated13.default.View, { pointerEvents: "none", style: [styles7.blur, blurStyle], children: headerHeight !== 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_auto_paper4.BlurView, { blur, style: [styles7.blurInner, { height: headerHeight ?? unmeasuredHeight }] }) }),
|
|
1261
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native_reanimated13.default.View, { onLayout: handleLayout, pointerEvents: "box-none", style: [headerHeight === null ? styles7.headerInit : styles7.header, translateStyle], children: [
|
|
1262
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { ref: contentRef, style: [{ paddingTop: top }, style], children: children ?? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.View, { style: [styles7.content, { minHeight: contentMinHeight }], children: [
|
|
1263
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: styles7.side }),
|
|
1264
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: styles7.spacer }),
|
|
1265
|
+
(centerContent || title || caption) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: [import_react_native12.StyleSheet.absoluteFill, styles7.titleContainer], pointerEvents: centerContent ? "box-none" : "none", children: centerContent ?? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1266
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.Text, { numberOfLines: 1, style: [styles7.title, { color: theme.colors.onSurface }], children: title }),
|
|
1267
|
+
caption && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.Text, { numberOfLines: 1, style: [styles7.caption, { color: theme.colors.onSurfaceVariant }], children: caption })
|
|
1171
1268
|
] }) })
|
|
1172
1269
|
] }) }),
|
|
1173
|
-
!blur && /* @__PURE__ */ (0,
|
|
1270
|
+
!blur && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: [styles7.divider, { backgroundColor: theme.colors.outlineVariant }] })
|
|
1174
1271
|
] }),
|
|
1175
|
-
/* @__PURE__ */ (0,
|
|
1176
|
-
backAction && (effectiveBackActionFixed ? /* @__PURE__ */ (0,
|
|
1177
|
-
/* @__PURE__ */ (0,
|
|
1178
|
-
typeof backAction === "function" ? /* @__PURE__ */ (0,
|
|
1179
|
-
] }) : /* @__PURE__ */ (0,
|
|
1180
|
-
/* @__PURE__ */ (0,
|
|
1181
|
-
typeof backAction === "function" ? /* @__PURE__ */ (0,
|
|
1272
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_reanimated13.default.View, { pointerEvents: "none", style: [styles7.progress, progressStyle], children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper4.ProgressBar, { indeterminate: progress === null, visible: progressing, progress: progress ?? void 0 }) }),
|
|
1273
|
+
backAction && (effectiveBackActionFixed ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native_reanimated13.default.View, { style: leadingStyle, children: [
|
|
1274
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
1275
|
+
typeof backAction === "function" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper4.Appbar.BackAction, { accessibilityLabel: backActionAccessibilityLabel, onPress: backAction, size: iconSize ?? actionSize / 2, style: buttonStyle }) : backAction
|
|
1276
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native_reanimated13.default.View, { style: [leadingStyle, translateStyle], children: [
|
|
1277
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
1278
|
+
typeof backAction === "function" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper4.Appbar.BackAction, { accessibilityLabel: backActionAccessibilityLabel, onPress: backAction, size: iconSize ?? actionSize / 2, style: buttonStyle }) : backAction
|
|
1182
1279
|
] })),
|
|
1183
|
-
trailingAction && (trailingActionFixed ? /* @__PURE__ */ (0,
|
|
1184
|
-
/* @__PURE__ */ (0,
|
|
1280
|
+
trailingAction && (trailingActionFixed ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.View, { style: trailingStyle, children: [
|
|
1281
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
1185
1282
|
trailingAction
|
|
1186
|
-
] }) : /* @__PURE__ */ (0,
|
|
1187
|
-
/* @__PURE__ */ (0,
|
|
1283
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native_reanimated13.default.View, { style: [trailingStyle, translateStyle], children: [
|
|
1284
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
1188
1285
|
trailingAction
|
|
1189
1286
|
] }))
|
|
1190
1287
|
] });
|
|
@@ -1207,56 +1304,100 @@ var styles7 = import_react_native12.StyleSheet.create({
|
|
|
1207
1304
|
|
|
1208
1305
|
// src/ScrollViewProvider.tsx
|
|
1209
1306
|
var import_auto_paper5 = require("@rific/auto-paper");
|
|
1210
|
-
var
|
|
1307
|
+
var import_react17 = require("react");
|
|
1211
1308
|
var import_react_native13 = require("react-native");
|
|
1212
|
-
var
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1309
|
+
var import_react_native_reanimated14 = require("react-native-reanimated");
|
|
1310
|
+
|
|
1311
|
+
// src/internal/ChromeRegistrar.tsx
|
|
1312
|
+
var import_react16 = require("react");
|
|
1313
|
+
var ChromeRegistrar = ({ footerFixed, host, writable }) => {
|
|
1314
|
+
const id = (0, import_react16.useId)();
|
|
1315
|
+
const active = host.useIsActive();
|
|
1316
|
+
const { activeId, claim, pinned, release, reveal } = host;
|
|
1317
|
+
(0, import_react16.useEffect)(() => {
|
|
1318
|
+
if (!active) return void 0;
|
|
1319
|
+
claim(id);
|
|
1320
|
+
return () => release(id);
|
|
1321
|
+
}, [active, claim, id, release]);
|
|
1322
|
+
const owner = activeId === id;
|
|
1323
|
+
(0, import_react16.useEffect)(() => {
|
|
1324
|
+
writable.value = owner && !pinned;
|
|
1325
|
+
}, [owner, pinned, writable]);
|
|
1326
|
+
(0, import_react16.useEffect)(() => {
|
|
1327
|
+
if (owner && footerFixed) reveal();
|
|
1328
|
+
}, [footerFixed, owner, reveal]);
|
|
1329
|
+
return null;
|
|
1330
|
+
};
|
|
1331
|
+
|
|
1332
|
+
// src/ScrollViewProvider.tsx
|
|
1333
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1334
|
+
var ScrollViewProvider = ({ blur, chrome, children, fixed = false, footerAboveKeyboard = false, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight = 0 }) => {
|
|
1335
|
+
const { settings } = (0, import_react17.useContext)(ScrollViewSettingsContext);
|
|
1336
|
+
const enclosingHost = (0, import_react17.useContext)(ScrollViewChromeHostContext);
|
|
1337
|
+
const chromeHost = chrome === false ? null : enclosingHost;
|
|
1338
|
+
const chromeHosted = chromeHost !== null;
|
|
1339
|
+
const chromeFootprint = chromeHost?.footprint ?? 0;
|
|
1340
|
+
const chromeOverhang = chromeHost?.overhang ?? 0;
|
|
1341
|
+
const chromeSnapBack = chromeHost?.snapBack ?? false;
|
|
1216
1342
|
const effectiveBlur = (0, import_auto_paper5.useBlur)(blur);
|
|
1217
1343
|
const effectiveSnapBack = snapBack ?? settings.snapBack;
|
|
1218
1344
|
const effectiveSnapBackHeader = snapBackHeader ?? settings.snapBackHeader;
|
|
1219
1345
|
const effectiveSnapBackFooter = snapBackFooter ?? settings.snapBackFooter;
|
|
1220
|
-
const [headerHeight, setHeaderHeightState] = (0,
|
|
1221
|
-
const [footerHeight, setFooterHeightState] = (0,
|
|
1222
|
-
const [progress, setProgress] = (0,
|
|
1223
|
-
const [progressing, setProgressing] = (0,
|
|
1224
|
-
const scrollPosition = (0,
|
|
1225
|
-
const listGeneration = (0,
|
|
1226
|
-
const jsListGeneration = (0,
|
|
1227
|
-
const headerHeightShared = (0,
|
|
1228
|
-
const footerHeightShared = (0,
|
|
1229
|
-
const headerOffset = (0,
|
|
1230
|
-
const
|
|
1231
|
-
const
|
|
1232
|
-
const
|
|
1233
|
-
const
|
|
1234
|
-
(0,
|
|
1346
|
+
const [headerHeight, setHeaderHeightState] = (0, import_react17.useState)(null);
|
|
1347
|
+
const [footerHeight, setFooterHeightState] = (0, import_react17.useState)(null);
|
|
1348
|
+
const [progress, setProgress] = (0, import_react17.useState)(null);
|
|
1349
|
+
const [progressing, setProgressing] = (0, import_react17.useState)(false);
|
|
1350
|
+
const scrollPosition = (0, import_react_native_reanimated14.useSharedValue)(0);
|
|
1351
|
+
const listGeneration = (0, import_react_native_reanimated14.useSharedValue)(0);
|
|
1352
|
+
const jsListGeneration = (0, import_react17.useRef)(0);
|
|
1353
|
+
const headerHeightShared = (0, import_react_native_reanimated14.useSharedValue)(0);
|
|
1354
|
+
const footerHeightShared = (0, import_react_native_reanimated14.useSharedValue)(0);
|
|
1355
|
+
const headerOffset = (0, import_react_native_reanimated14.useSharedValue)(0);
|
|
1356
|
+
const ownFooterOffset = (0, import_react_native_reanimated14.useSharedValue)(0);
|
|
1357
|
+
const ownStackHeight = (0, import_react_native_reanimated14.useSharedValue)(0);
|
|
1358
|
+
const footerOffset = chromeHost ? chromeHost.offset : ownFooterOffset;
|
|
1359
|
+
const chromeWritable = (0, import_react_native_reanimated14.useSharedValue)(!chromeHosted);
|
|
1360
|
+
(0, import_react17.useEffect)(() => {
|
|
1361
|
+
if (!chromeHosted) chromeWritable.value = true;
|
|
1362
|
+
}, [chromeHosted, chromeWritable]);
|
|
1363
|
+
const revealChrome = chromeHost?.reveal;
|
|
1364
|
+
const stackHeightShared = chromeHosted ? ownStackHeight : footerHeightShared;
|
|
1365
|
+
const pullSearchHeightShared = (0, import_react_native_reanimated14.useSharedValue)(0);
|
|
1366
|
+
const snapBackHeaderShared = (0, import_react_native_reanimated14.useSharedValue)(false);
|
|
1367
|
+
const snapBackFooterShared = (0, import_react_native_reanimated14.useSharedValue)(false);
|
|
1368
|
+
(0, import_react17.useEffect)(() => {
|
|
1235
1369
|
snapBackHeaderShared.value = effectiveSnapBackHeader ?? effectiveSnapBack;
|
|
1236
|
-
snapBackFooterShared.value = effectiveSnapBackFooter ?? effectiveSnapBack;
|
|
1237
|
-
}, [effectiveSnapBack, effectiveSnapBackFooter, effectiveSnapBackHeader, snapBackFooterShared, snapBackHeaderShared]);
|
|
1238
|
-
|
|
1239
|
-
(
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1370
|
+
snapBackFooterShared.value = chromeHosted ? chromeSnapBack : effectiveSnapBackFooter ?? effectiveSnapBack;
|
|
1371
|
+
}, [chromeHosted, chromeSnapBack, effectiveSnapBack, effectiveSnapBackFooter, effectiveSnapBackHeader, snapBackFooterShared, snapBackHeaderShared]);
|
|
1372
|
+
(0, import_react17.useEffect)(() => {
|
|
1373
|
+
if (!chromeHosted) return;
|
|
1374
|
+
ownStackHeight.value = chromeFootprint + Math.max(footerHeight ?? 0, chromeOverhang) + CHROME_SLACK;
|
|
1375
|
+
}, [chromeFootprint, chromeHosted, chromeOverhang, footerHeight, ownStackHeight]);
|
|
1376
|
+
const headerHeightRef = (0, import_react17.useRef)(null);
|
|
1377
|
+
const footerHeightRef = (0, import_react17.useRef)(null);
|
|
1378
|
+
const setHeaderHeight = (0, import_react17.useCallback)((h) => {
|
|
1379
|
+
if (h === 0 && headerHeightRef.current) return;
|
|
1380
|
+
headerHeightRef.current = h;
|
|
1381
|
+
setHeaderHeightState(h);
|
|
1382
|
+
}, []);
|
|
1383
|
+
(0, import_react17.useLayoutEffect)(() => {
|
|
1384
|
+
headerHeightShared.value = headerHeight ?? 0;
|
|
1385
|
+
}, [headerHeight, headerHeightShared]);
|
|
1386
|
+
const onListUnmount = (0, import_react17.useCallback)(() => {
|
|
1247
1387
|
listGeneration.value += 1;
|
|
1248
|
-
|
|
1249
|
-
|
|
1388
|
+
if (revealChrome && chromeWritable.value) revealChrome();
|
|
1389
|
+
}, [chromeWritable, listGeneration, revealChrome]);
|
|
1390
|
+
const onJsListUnmount = (0, import_react17.useCallback)(() => {
|
|
1250
1391
|
jsListGeneration.current += 1;
|
|
1251
1392
|
}, []);
|
|
1252
|
-
(0,
|
|
1393
|
+
(0, import_react17.useEffect)(() => {
|
|
1253
1394
|
if (!__DEV__ || headerHeight !== null) return;
|
|
1254
1395
|
const timeout = setTimeout(() => {
|
|
1255
|
-
console.warn("[scroll-view] No ScrollViewHeader ever measured inside this ScrollViewProvider
|
|
1396
|
+
console.warn("[scroll-view] No ScrollViewHeader ever measured inside this ScrollViewProvider: scroll content stays hidden (opacity: 0) until one does. Render a <ScrollViewHeader> (it can be empty / zero height) inside this provider.");
|
|
1256
1397
|
}, 3e3);
|
|
1257
1398
|
return () => clearTimeout(timeout);
|
|
1258
1399
|
}, [headerHeight]);
|
|
1259
|
-
(0,
|
|
1400
|
+
(0, import_react17.useEffect)(() => {
|
|
1260
1401
|
if (import_react_native13.Platform.OS !== "web" || headerHeight !== null) return;
|
|
1261
1402
|
let raf2 = 0;
|
|
1262
1403
|
const raf1 = requestAnimationFrame(() => {
|
|
@@ -1267,47 +1408,55 @@ var ScrollViewProvider = ({ blur, children, fixed = false, footerAboveKeyboard =
|
|
|
1267
1408
|
cancelAnimationFrame(raf2);
|
|
1268
1409
|
};
|
|
1269
1410
|
}, [headerHeight, setHeaderHeight]);
|
|
1270
|
-
const setFooterHeight = (0,
|
|
1411
|
+
const setFooterHeight = (0, import_react17.useCallback)(
|
|
1271
1412
|
(h) => {
|
|
1272
|
-
if (h === 0 &&
|
|
1413
|
+
if (h === 0 && footerHeightRef.current) return;
|
|
1414
|
+
footerHeightRef.current = h;
|
|
1273
1415
|
setFooterHeightState(h);
|
|
1274
1416
|
footerHeightShared.value = h ?? 0;
|
|
1275
1417
|
},
|
|
1276
|
-
[
|
|
1418
|
+
[footerHeightShared]
|
|
1277
1419
|
);
|
|
1278
|
-
const scrollHeight = (0,
|
|
1420
|
+
const scrollHeight = (0, import_react17.useMemo)(() => import_react_native13.Dimensions.get("window").height - (headerHeight ?? 0) - (footerHeight ?? 0), [headerHeight, footerHeight]);
|
|
1279
1421
|
const effectiveHeaderFixed = fixed || (headerFixed ?? settings.headerFixed);
|
|
1280
1422
|
const effectiveFooterFixed = fixed || (footerFixed ?? settings.footerFixed);
|
|
1281
|
-
const
|
|
1282
|
-
|
|
1423
|
+
const effectiveTabBarHeight = chromeHosted ? chromeFootprint : tabBarHeight;
|
|
1424
|
+
const value = (0, import_react17.useMemo)(
|
|
1425
|
+
() => ({ blur: effectiveBlur, chromeHosted, chromeOverhang, chromeWritable, footerAboveKeyboard, 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, stackHeightShared, tabBarHeight: effectiveTabBarHeight }),
|
|
1426
|
+
[effectiveBlur, chromeHosted, chromeOverhang, chromeWritable, footerAboveKeyboard, effectiveFooterFixed, effectiveHeaderFixed, footerHeight, footerHeightShared, footerOffset, headerHeight, headerHeightShared, headerOffset, jsListGeneration, listGeneration, onJsListUnmount, onListUnmount, progress, pullSearchHeightShared, progressing, scrollHeight, scrollPosition, setFooterHeight, setHeaderHeight, snapBackFooterShared, snapBackHeaderShared, stackHeightShared, effectiveTabBarHeight]
|
|
1427
|
+
);
|
|
1428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScrollViewContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ScrollViewChromeHostContext.Provider, { value: null, children: [
|
|
1429
|
+
children,
|
|
1430
|
+
chromeHost ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChromeRegistrar, { footerFixed: effectiveFooterFixed, host: chromeHost, writable: chromeWritable }) : null
|
|
1431
|
+
] }) });
|
|
1283
1432
|
};
|
|
1284
1433
|
|
|
1285
1434
|
// src/ScrollViewSettingsProvider.tsx
|
|
1286
1435
|
var ScrollViewSettingsProvider = scrollViewSettingsProvider;
|
|
1287
1436
|
|
|
1288
1437
|
// src/SectionList.tsx
|
|
1289
|
-
var
|
|
1438
|
+
var import_react19 = require("react");
|
|
1290
1439
|
var import_react_native14 = require("react-native");
|
|
1291
1440
|
var import_react_native_gesture_handler4 = require("react-native-gesture-handler");
|
|
1292
|
-
var
|
|
1441
|
+
var import_react_native_reanimated16 = __toESM(require("react-native-reanimated"));
|
|
1293
1442
|
|
|
1294
1443
|
// src/internal/useStickyHeaders.ts
|
|
1295
|
-
var
|
|
1296
|
-
var
|
|
1444
|
+
var import_react18 = require("react");
|
|
1445
|
+
var import_react_native_reanimated15 = require("react-native-reanimated");
|
|
1297
1446
|
var import_react_native_safe_area_context5 = require("react-native-safe-area-context");
|
|
1298
1447
|
function useStickyHeaders(headerFixed, enabled) {
|
|
1299
|
-
const { headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared } = (0,
|
|
1448
|
+
const { headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared } = (0, import_react18.useContext)(ScrollViewContext);
|
|
1300
1449
|
const insetsTop = (0, import_react_native_safe_area_context5.useSafeAreaInsets)().top;
|
|
1301
|
-
const sectionYPositions = (0,
|
|
1302
|
-
const sectionHeights = (0,
|
|
1303
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
1304
|
-
const contentIndexShared = (0,
|
|
1305
|
-
(0,
|
|
1450
|
+
const sectionYPositions = (0, import_react_native_reanimated15.useSharedValue)([]);
|
|
1451
|
+
const sectionHeights = (0, import_react_native_reanimated15.useSharedValue)([]);
|
|
1452
|
+
const [activeIndex, setActiveIndex] = (0, import_react18.useState)(-1);
|
|
1453
|
+
const contentIndexShared = (0, import_react_native_reanimated15.useSharedValue)(-1);
|
|
1454
|
+
(0, import_react18.useLayoutEffect)(() => {
|
|
1306
1455
|
contentIndexShared.value = activeIndex;
|
|
1307
1456
|
}, [activeIndex, contentIndexShared]);
|
|
1308
|
-
const positionsCache = (0,
|
|
1309
|
-
const heightsCache = (0,
|
|
1310
|
-
(0,
|
|
1457
|
+
const positionsCache = (0, import_react18.useRef)([]);
|
|
1458
|
+
const heightsCache = (0, import_react18.useRef)([]);
|
|
1459
|
+
(0, import_react_native_reanimated15.useAnimatedReaction)(
|
|
1311
1460
|
() => {
|
|
1312
1461
|
if (!enabled) return -1;
|
|
1313
1462
|
const positions = sectionYPositions.value;
|
|
@@ -1332,16 +1481,16 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
1332
1481
|
return active;
|
|
1333
1482
|
},
|
|
1334
1483
|
(curr, prev) => {
|
|
1335
|
-
if (curr !== prev) (0,
|
|
1484
|
+
if (curr !== prev) (0, import_react_native_reanimated15.runOnJS)(setActiveIndex)(curr);
|
|
1336
1485
|
},
|
|
1337
1486
|
// Same web-only reanimated gap as useAnimatedStyle elsewhere in this file: this "prepare"
|
|
1338
1487
|
// function's own SharedValue reads (sectionYPositions, headerHeightShared, scrollPosition,
|
|
1339
1488
|
// snapBackHeaderShared, headerOffset, pullSearchHeightShared) need to be listed explicitly too
|
|
1340
|
-
//
|
|
1489
|
+
// - confirmed empirically that without them, useAnimatedReaction re-evaluates once on mount and
|
|
1341
1490
|
// then never again on web, permanently freezing activeIndex/the active sticky section.
|
|
1342
1491
|
[enabled, headerFixed, insetsTop, sectionYPositions, headerHeightShared, scrollPosition, snapBackHeaderShared, headerOffset, pullSearchHeightShared]
|
|
1343
1492
|
);
|
|
1344
|
-
const clipStyle = (0,
|
|
1493
|
+
const clipStyle = (0, import_react_native_reanimated15.useAnimatedStyle)(() => {
|
|
1345
1494
|
const hHeight = headerHeightShared.value;
|
|
1346
1495
|
const scrollPos = scrollPosition.value;
|
|
1347
1496
|
let stickyTop;
|
|
@@ -1355,7 +1504,7 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
1355
1504
|
}
|
|
1356
1505
|
return { top: stickyTop };
|
|
1357
1506
|
}, [enabled, headerFixed, insetsTop, headerHeightShared, scrollPosition, snapBackHeaderShared, headerOffset, pullSearchHeightShared]);
|
|
1358
|
-
const overlayStyle = (0,
|
|
1507
|
+
const overlayStyle = (0, import_react_native_reanimated15.useAnimatedStyle)(() => {
|
|
1359
1508
|
const hidden = { opacity: 0, top: 0, transform: [{ translateY: 0 }] };
|
|
1360
1509
|
if (!enabled) return hidden;
|
|
1361
1510
|
const index = contentIndexShared.value;
|
|
@@ -1383,7 +1532,7 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
1383
1532
|
}
|
|
1384
1533
|
return { opacity: 1, top: 0, transform: [{ translateY }] };
|
|
1385
1534
|
}, [enabled, headerFixed, insetsTop, contentIndexShared, sectionYPositions, headerHeightShared, scrollPosition, snapBackHeaderShared, headerOffset, pullSearchHeightShared, sectionHeights]);
|
|
1386
|
-
const measureHeader = (0,
|
|
1535
|
+
const measureHeader = (0, import_react18.useCallback)(
|
|
1387
1536
|
(index, pageY, height) => {
|
|
1388
1537
|
const contentY = pageY + scrollPosition.value;
|
|
1389
1538
|
positionsCache.current[index] = contentY;
|
|
@@ -1393,7 +1542,7 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
1393
1542
|
},
|
|
1394
1543
|
[scrollPosition, sectionHeights, sectionYPositions]
|
|
1395
1544
|
);
|
|
1396
|
-
const resetPositions = (0,
|
|
1545
|
+
const resetPositions = (0, import_react18.useCallback)(
|
|
1397
1546
|
(count) => {
|
|
1398
1547
|
positionsCache.current = Array.from({ length: count }, () => -1);
|
|
1399
1548
|
sectionYPositions.value = positionsCache.current.slice();
|
|
@@ -1406,36 +1555,36 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
1406
1555
|
}
|
|
1407
1556
|
|
|
1408
1557
|
// src/SectionList.tsx
|
|
1409
|
-
var
|
|
1410
|
-
var AnimatedSectionList =
|
|
1558
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1559
|
+
var AnimatedSectionList = import_react_native_reanimated16.default.createAnimatedComponent(import_react_native14.SectionList);
|
|
1411
1560
|
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 }) => {
|
|
1412
|
-
const scrollView = (0,
|
|
1561
|
+
const scrollView = (0, import_react19.useRef)(null);
|
|
1413
1562
|
const { stickySectionHeadersEnabled = true, renderSectionHeader, ...passThroughProps } = props;
|
|
1414
1563
|
const { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, contentPadding, footerFixed, headerFixed, headerHeight } = useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, hideUntilMeasured: true, keyboardAware, pullSearchHeight, style });
|
|
1415
|
-
const { listGeneration, onListUnmount } = (0,
|
|
1416
|
-
const capturedGeneration = (0,
|
|
1417
|
-
(0,
|
|
1564
|
+
const { listGeneration, onListUnmount } = (0, import_react19.useContext)(ScrollViewContext);
|
|
1565
|
+
const capturedGeneration = (0, import_react_native_reanimated16.useSharedValue)(-1);
|
|
1566
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
1418
1567
|
const generation = listGeneration.value;
|
|
1419
1568
|
if (import_react_native14.Platform.OS === "web") {
|
|
1420
1569
|
capturedGeneration.value = generation;
|
|
1421
1570
|
return;
|
|
1422
1571
|
}
|
|
1423
|
-
(0,
|
|
1572
|
+
(0, import_react_native_reanimated16.runOnUI)((gen) => {
|
|
1424
1573
|
"worklet";
|
|
1425
1574
|
capturedGeneration.value = gen;
|
|
1426
1575
|
})(generation);
|
|
1427
1576
|
}, [capturedGeneration, listGeneration]);
|
|
1428
1577
|
const usesCustomSticky = stickySectionHeadersEnabled && renderSectionHeader != null;
|
|
1429
1578
|
const { activeIndex, clipStyle, measureHeader, overlayStyle, resetPositions } = useStickyHeaders(headerFixed, usesCustomSticky);
|
|
1430
|
-
(0,
|
|
1579
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
1431
1580
|
if (usesCustomSticky) resetPositions(sections.length);
|
|
1432
1581
|
}, [sections, usesCustomSticky, resetPositions, headerHeight]);
|
|
1433
|
-
const sectionViewRefs = (0,
|
|
1434
|
-
const wrappedRenderSectionHeader = (0,
|
|
1582
|
+
const sectionViewRefs = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
|
|
1583
|
+
const wrappedRenderSectionHeader = (0, import_react19.useMemo)(() => {
|
|
1435
1584
|
if (!usesCustomSticky) return renderSectionHeader ?? void 0;
|
|
1436
1585
|
return (info) => {
|
|
1437
1586
|
const idx = sections.findIndex((s) => s === info.section);
|
|
1438
|
-
return /* @__PURE__ */ (0,
|
|
1587
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1439
1588
|
import_react_native14.View,
|
|
1440
1589
|
{
|
|
1441
1590
|
ref: (el) => {
|
|
@@ -1452,8 +1601,8 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
|
|
|
1452
1601
|
);
|
|
1453
1602
|
};
|
|
1454
1603
|
}, [usesCustomSticky, renderSectionHeader, sections, measureHeader]);
|
|
1455
|
-
(0,
|
|
1456
|
-
const scrollTo = (0,
|
|
1604
|
+
(0, import_react19.useLayoutEffect)(() => () => onListUnmount(), [onListUnmount]);
|
|
1605
|
+
const scrollTo = (0, import_react19.useCallback)((offset, animated) => {
|
|
1457
1606
|
scrollView.current?.getScrollResponder()?.scrollTo({ y: offset, animated });
|
|
1458
1607
|
}, []);
|
|
1459
1608
|
const {
|
|
@@ -1471,16 +1620,16 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
|
|
|
1471
1620
|
pullSearchHeight,
|
|
1472
1621
|
scrollTo
|
|
1473
1622
|
});
|
|
1474
|
-
const activeListHeader = (0,
|
|
1623
|
+
const activeListHeader = (0, import_react19.useMemo)(() => {
|
|
1475
1624
|
if (!renderFilters) return pullSearchHeader;
|
|
1476
1625
|
const Inner = pullSearchHeader;
|
|
1477
|
-
return () => /* @__PURE__ */ (0,
|
|
1478
|
-
Inner ? typeof Inner === "function" ? /* @__PURE__ */ (0,
|
|
1626
|
+
return () => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
1627
|
+
Inner ? typeof Inner === "function" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Inner, {}) : Inner : null,
|
|
1479
1628
|
renderFilters
|
|
1480
1629
|
] });
|
|
1481
1630
|
}, [pullSearchHeader, renderFilters]);
|
|
1482
|
-
const pullSearchSettled = (0,
|
|
1483
|
-
(0,
|
|
1631
|
+
const pullSearchSettled = (0, import_react19.useRef)(false);
|
|
1632
|
+
(0, import_react19.useEffect)(() => {
|
|
1484
1633
|
if (!usesCustomSticky || activeListHeader == null || pullSearchSettled.current) return;
|
|
1485
1634
|
pullSearchSettled.current = true;
|
|
1486
1635
|
const handle = requestAnimationFrame(() => {
|
|
@@ -1492,24 +1641,24 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
|
|
|
1492
1641
|
});
|
|
1493
1642
|
return () => cancelAnimationFrame(handle);
|
|
1494
1643
|
}, [activeListHeader, usesCustomSticky, measureHeader]);
|
|
1495
|
-
const contentContainerStyle = (0,
|
|
1644
|
+
const contentContainerStyle = (0, import_react19.useMemo)(() => [{ minHeight: import_react_native14.Dimensions.get("window").height - contentInset.top - contentInset.bottom + pullSearchMinHeight }, externalContentContainerStyle, contentPadding], [contentInset.bottom, contentInset.top, contentPadding, externalContentContainerStyle, pullSearchMinHeight]);
|
|
1496
1645
|
const handleScroll = useScrollHandler({ capturedGeneration, chipHidden, chipThreshold, footerFixed, headerFixed, listGeneration });
|
|
1497
|
-
const handleScrollToTop = (0,
|
|
1646
|
+
const handleScrollToTop = (0, import_react19.useCallback)(() => {
|
|
1498
1647
|
const offset = pullSearchHeight ? -contentInset.top + pullSearchHeight : -contentInset.top;
|
|
1499
1648
|
scrollView.current?.getScrollResponder()?.scrollTo({ y: offset, animated: true });
|
|
1500
1649
|
}, [contentInset.top, pullSearchHeight]);
|
|
1501
|
-
const handleContentSizeChange = (0,
|
|
1650
|
+
const handleContentSizeChange = (0, import_react19.useCallback)(
|
|
1502
1651
|
(w, h) => {
|
|
1503
1652
|
if (onContentSizeChange) onContentSizeChange(w, h);
|
|
1504
1653
|
},
|
|
1505
1654
|
[onContentSizeChange]
|
|
1506
1655
|
);
|
|
1507
|
-
const refreshControl = (0,
|
|
1508
|
-
const nativeGesture = (0,
|
|
1509
|
-
const combinedGesture = (0,
|
|
1656
|
+
const refreshControl = (0, import_react19.useMemo)(() => onRefresh ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefreshControl, { onRefresh, refreshing: refreshing ?? false }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(RefreshControl, {}), [onRefresh, refreshing]);
|
|
1657
|
+
const nativeGesture = (0, import_react19.useMemo)(() => import_react_native_gesture_handler4.Gesture.Native(), []);
|
|
1658
|
+
const combinedGesture = (0, import_react19.useMemo)(() => gesture !== void 0 ? import_react_native_gesture_handler4.Gesture.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
|
|
1510
1659
|
const detectorGesture = gesture !== void 0 ? combinedGesture : void 0;
|
|
1511
|
-
const content = /* @__PURE__ */ (0,
|
|
1512
|
-
/* @__PURE__ */ (0,
|
|
1660
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native14.View, { style: containerStyle, children: [
|
|
1661
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1513
1662
|
AnimatedSectionList,
|
|
1514
1663
|
{
|
|
1515
1664
|
...passThroughProps,
|
|
@@ -1539,26 +1688,52 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
|
|
|
1539
1688
|
},
|
|
1540
1689
|
headerHeight !== null && headerHeight > 0 ? 1 : 0
|
|
1541
1690
|
),
|
|
1542
|
-
hiddenHeader && /* @__PURE__ */ (0,
|
|
1543
|
-
/* @__PURE__ */ (0,
|
|
1544
|
-
usesCustomSticky && /* @__PURE__ */ (0,
|
|
1691
|
+
hiddenHeader && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native14.View, { pointerEvents: "none", style: styles8.measureContainer, children: hiddenHeader }),
|
|
1692
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollViewChip, { chipProps, onChipPress, onPress: handleScrollToTop, style: chipStyle }),
|
|
1693
|
+
usesCustomSticky && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_reanimated16.default.View, { pointerEvents: "none", style: [styles8.stickyClip, clipStyle], children: activeIndex >= 0 && activeIndex < sections.length && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_reanimated16.default.View, { style: [styles8.stickyOverlay, overlayStyle], children: renderSectionHeader({ section: sections[activeIndex] }) }) })
|
|
1545
1694
|
] });
|
|
1546
|
-
return detectorGesture ? /* @__PURE__ */ (0,
|
|
1695
|
+
return detectorGesture ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_gesture_handler4.GestureDetector, { gesture: detectorGesture, children: content }) : content;
|
|
1547
1696
|
};
|
|
1548
1697
|
var styles8 = {
|
|
1549
1698
|
measureContainer: { left: 0, opacity: 0, position: "absolute", right: 0, top: -9999 },
|
|
1550
1699
|
stickyClip: { bottom: 0, left: 0, overflow: "hidden", position: "absolute", right: 0, zIndex: 2 },
|
|
1551
1700
|
stickyOverlay: { left: 0, position: "absolute", right: 0 }
|
|
1552
1701
|
};
|
|
1553
|
-
var SectionList = (0,
|
|
1702
|
+
var SectionList = (0, import_react19.memo)(SectionListInner);
|
|
1554
1703
|
|
|
1555
1704
|
// src/useScrollView.ts
|
|
1556
|
-
var
|
|
1705
|
+
var import_react20 = require("react");
|
|
1557
1706
|
var useScrollView = () => {
|
|
1558
|
-
const { progress, progressing, scrollHeight, scrollPosition, setProgress, setProgressing } = (0,
|
|
1707
|
+
const { progress, progressing, scrollHeight, scrollPosition, setProgress, setProgressing } = (0, import_react20.useContext)(ScrollViewContext);
|
|
1559
1708
|
return { progress, progressing, scrollHeight, scrollPosition, setProgress, setProgressing };
|
|
1560
1709
|
};
|
|
1561
1710
|
|
|
1711
|
+
// src/useScrollViewChrome.ts
|
|
1712
|
+
var import_react21 = require("react");
|
|
1713
|
+
var import_react_native_reanimated17 = require("react-native-reanimated");
|
|
1714
|
+
var noop = () => {
|
|
1715
|
+
};
|
|
1716
|
+
var useScrollViewChromeStyle = () => {
|
|
1717
|
+
const chrome = (0, import_react21.useContext)(ScrollViewChromeContext);
|
|
1718
|
+
const fallback = (0, import_react_native_reanimated17.useSharedValue)(0);
|
|
1719
|
+
const offset = chrome?.offset ?? fallback;
|
|
1720
|
+
return (0, import_react_native_reanimated17.useAnimatedStyle)(() => ({ transform: [{ translateY: offset.value }] }), [offset]);
|
|
1721
|
+
};
|
|
1722
|
+
var useScrollViewChromePin = (active) => {
|
|
1723
|
+
const chrome = (0, import_react21.useContext)(ScrollViewChromeContext);
|
|
1724
|
+
const addPin = chrome?.addPin;
|
|
1725
|
+
const removePin = chrome?.removePin;
|
|
1726
|
+
(0, import_react21.useEffect)(() => {
|
|
1727
|
+
if (!active || !addPin || !removePin) return void 0;
|
|
1728
|
+
addPin();
|
|
1729
|
+
return removePin;
|
|
1730
|
+
}, [active, addPin, removePin]);
|
|
1731
|
+
};
|
|
1732
|
+
var useScrollViewChromeReveal = () => {
|
|
1733
|
+
const chrome = (0, import_react21.useContext)(ScrollViewChromeContext);
|
|
1734
|
+
return chrome?.reveal ?? noop;
|
|
1735
|
+
};
|
|
1736
|
+
|
|
1562
1737
|
// src/useScrollViewSettings.ts
|
|
1563
1738
|
var useScrollViewSettings = scrollViewUseSettings;
|
|
1564
1739
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1567,6 +1742,7 @@ var useScrollViewSettings = scrollViewUseSettings;
|
|
|
1567
1742
|
FlatList,
|
|
1568
1743
|
PullSearch,
|
|
1569
1744
|
ScrollView,
|
|
1745
|
+
ScrollViewChromeProvider,
|
|
1570
1746
|
ScrollViewContext,
|
|
1571
1747
|
ScrollViewFooter,
|
|
1572
1748
|
ScrollViewHeader,
|
|
@@ -1579,5 +1755,8 @@ var useScrollViewSettings = scrollViewUseSettings;
|
|
|
1579
1755
|
scrollViewReducer,
|
|
1580
1756
|
useKeyboardInset,
|
|
1581
1757
|
useScrollView,
|
|
1758
|
+
useScrollViewChromePin,
|
|
1759
|
+
useScrollViewChromeReveal,
|
|
1760
|
+
useScrollViewChromeStyle,
|
|
1582
1761
|
useScrollViewSettings
|
|
1583
1762
|
});
|