@rific/scroll-view 0.7.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -3,6 +3,8 @@ import { ReactNode, ComponentType, RefObject } from 'react';
3
3
  import { NativeSyntheticEvent, NativeScrollEvent, StyleProp, ViewStyle, FlatListProps as FlatListProps$1, FlatList as FlatList$1, ScrollViewProps as ScrollViewProps$1, ScrollView as ScrollView$1, SectionListProps as SectionListProps$1, SectionList as SectionList$1 } from 'react-native';
4
4
  import { GestureType } from 'react-native-gesture-handler';
5
5
  import { ChipProps as ChipProps$1 } from '@rific/auto-paper';
6
+ import * as _rific_core from '@rific/core';
7
+ import { SettingsContextValue, SettingsProviderProps } from '@rific/core';
6
8
  import * as react_native_reanimated from 'react-native-reanimated';
7
9
  import { SharedValue } from 'react-native-reanimated';
8
10
 
@@ -80,28 +82,62 @@ type ScrollViewSettings = {
80
82
  snapBackHeader?: boolean;
81
83
  };
82
84
  declare const defaultScrollViewSettings: ScrollViewSettings;
83
- type ScrollViewSettingsContextType = {
84
- settings: ScrollViewSettings;
85
- set: (patch: Partial<ScrollViewSettings>) => void;
86
- };
87
- declare const ScrollViewSettingsContext: react.Context<ScrollViewSettingsContextType>;
85
+ type ScrollViewSettingsContextType = SettingsContextValue<ScrollViewSettings>;
86
+ declare const ScrollViewSettingsContext: react.Context<SettingsContextValue<ScrollViewSettings>>;
88
87
 
89
- type PayloadAction<P> = {
90
- payload: P;
91
- type: string;
92
- };
93
88
  declare const scrollViewActions: {
94
89
  initialize: {
95
- (payload: ScrollViewSettings): PayloadAction<ScrollViewSettings>;
90
+ (payload: ScrollViewSettings): _rific_core.SettingsAction<ScrollViewSettings>;
91
+ type: string;
92
+ match: (action: {
93
+ type: string;
94
+ }) => action is _rific_core.SettingsAction<ScrollViewSettings>;
95
+ };
96
+ } & {
97
+ setFooterFixed: {
98
+ (payload: boolean): _rific_core.SettingsAction<boolean>;
99
+ type: string;
100
+ match: (action: {
101
+ type: string;
102
+ }) => action is _rific_core.SettingsAction<boolean>;
103
+ };
104
+ setHeaderFixed: {
105
+ (payload: boolean): _rific_core.SettingsAction<boolean>;
106
+ type: string;
107
+ match: (action: {
108
+ type: string;
109
+ }) => action is _rific_core.SettingsAction<boolean>;
110
+ };
111
+ setBackActionFixed: {
112
+ (payload: boolean): _rific_core.SettingsAction<boolean>;
96
113
  type: string;
97
- match(action: {
114
+ match: (action: {
98
115
  type: string;
99
- }): action is PayloadAction<ScrollViewSettings>;
116
+ }) => action is _rific_core.SettingsAction<boolean>;
100
117
  };
118
+ setSnapBack: {
119
+ (payload: boolean): _rific_core.SettingsAction<boolean>;
120
+ type: string;
121
+ match: (action: {
122
+ type: string;
123
+ }) => action is _rific_core.SettingsAction<boolean>;
124
+ };
125
+ setSnapBackFooter?: {
126
+ (payload: boolean | undefined): _rific_core.SettingsAction<boolean | undefined>;
127
+ type: string;
128
+ match: (action: {
129
+ type: string;
130
+ }) => action is _rific_core.SettingsAction<boolean | undefined>;
131
+ } | undefined;
132
+ setSnapBackHeader?: {
133
+ (payload: boolean | undefined): _rific_core.SettingsAction<boolean | undefined>;
134
+ type: string;
135
+ match: (action: {
136
+ type: string;
137
+ }) => action is _rific_core.SettingsAction<boolean | undefined>;
138
+ } | undefined;
101
139
  };
102
- declare const scrollViewReducer: (state: ScrollViewSettings | undefined, action: {
103
- type: string;
104
- }) => ScrollViewSettings;
140
+ declare const scrollViewReducer: _rific_core.SettingsReducer<ScrollViewSettings>;
105
141
 
106
142
  type ScrollViewProps = ScrollViewProps$1 & {
107
143
  chipProps?: ChipProps;
@@ -189,12 +225,8 @@ type ScrollViewProviderProps = {
189
225
  };
190
226
  declare const ScrollViewProvider: ({ blur, children, fixed, footerAboveKeyboard, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight }: ScrollViewProviderProps) => react.JSX.Element;
191
227
 
192
- type ScrollViewSettingsProviderProps = {
193
- children: ReactNode;
194
- onChange?: (settings: ScrollViewSettings) => void;
195
- initialValue?: Partial<ScrollViewSettings>;
196
- };
197
- declare const ScrollViewSettingsProvider: ({ children, onChange, initialValue }: ScrollViewSettingsProviderProps) => react.JSX.Element;
228
+ type ScrollViewSettingsProviderProps = SettingsProviderProps<ScrollViewSettings>;
229
+ declare const ScrollViewSettingsProvider: (props: SettingsProviderProps<ScrollViewSettings>) => React.JSX.Element;
198
230
 
199
231
  type SectionListProps<ItemT, SectionT extends {
200
232
  data: ReadonlyArray<ItemT>;
@@ -233,6 +265,6 @@ declare const useScrollView: () => {
233
265
  setProgressing: (b: boolean) => void;
234
266
  };
235
267
 
236
- declare const useScrollViewSettings: () => ScrollViewSettingsContextType;
268
+ declare const useScrollViewSettings: () => _rific_core.SettingsContextValue<ScrollViewSettings>;
237
269
 
238
270
  export { type ChipProps, CustomList, type CustomListProps, FlatList, type FlatListProps, PullSearch, type PullSearchHandle, type PullSearchProps, ScrollView, ScrollViewContext, type ScrollViewContextType, ScrollViewFooter, type ScrollViewFooterProps, ScrollViewHeader, type ScrollViewHeaderProps, type ScrollViewProps, ScrollViewProvider, type ScrollViewProviderProps, type ScrollViewSettings, ScrollViewSettingsContext, type ScrollViewSettingsContextType, ScrollViewSettingsProvider, type ScrollViewSettingsProviderProps, SectionList, type SectionListProps, defaultScrollViewSettings, scrollViewActions, scrollViewReducer, useKeyboardInset, useScrollView, useScrollViewSettings };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,8 @@ import { ReactNode, ComponentType, RefObject } from 'react';
3
3
  import { NativeSyntheticEvent, NativeScrollEvent, StyleProp, ViewStyle, FlatListProps as FlatListProps$1, FlatList as FlatList$1, ScrollViewProps as ScrollViewProps$1, ScrollView as ScrollView$1, SectionListProps as SectionListProps$1, SectionList as SectionList$1 } from 'react-native';
4
4
  import { GestureType } from 'react-native-gesture-handler';
5
5
  import { ChipProps as ChipProps$1 } from '@rific/auto-paper';
6
+ import * as _rific_core from '@rific/core';
7
+ import { SettingsContextValue, SettingsProviderProps } from '@rific/core';
6
8
  import * as react_native_reanimated from 'react-native-reanimated';
7
9
  import { SharedValue } from 'react-native-reanimated';
8
10
 
@@ -80,28 +82,62 @@ type ScrollViewSettings = {
80
82
  snapBackHeader?: boolean;
81
83
  };
82
84
  declare const defaultScrollViewSettings: ScrollViewSettings;
83
- type ScrollViewSettingsContextType = {
84
- settings: ScrollViewSettings;
85
- set: (patch: Partial<ScrollViewSettings>) => void;
86
- };
87
- declare const ScrollViewSettingsContext: react.Context<ScrollViewSettingsContextType>;
85
+ type ScrollViewSettingsContextType = SettingsContextValue<ScrollViewSettings>;
86
+ declare const ScrollViewSettingsContext: react.Context<SettingsContextValue<ScrollViewSettings>>;
88
87
 
89
- type PayloadAction<P> = {
90
- payload: P;
91
- type: string;
92
- };
93
88
  declare const scrollViewActions: {
94
89
  initialize: {
95
- (payload: ScrollViewSettings): PayloadAction<ScrollViewSettings>;
90
+ (payload: ScrollViewSettings): _rific_core.SettingsAction<ScrollViewSettings>;
91
+ type: string;
92
+ match: (action: {
93
+ type: string;
94
+ }) => action is _rific_core.SettingsAction<ScrollViewSettings>;
95
+ };
96
+ } & {
97
+ setFooterFixed: {
98
+ (payload: boolean): _rific_core.SettingsAction<boolean>;
99
+ type: string;
100
+ match: (action: {
101
+ type: string;
102
+ }) => action is _rific_core.SettingsAction<boolean>;
103
+ };
104
+ setHeaderFixed: {
105
+ (payload: boolean): _rific_core.SettingsAction<boolean>;
106
+ type: string;
107
+ match: (action: {
108
+ type: string;
109
+ }) => action is _rific_core.SettingsAction<boolean>;
110
+ };
111
+ setBackActionFixed: {
112
+ (payload: boolean): _rific_core.SettingsAction<boolean>;
96
113
  type: string;
97
- match(action: {
114
+ match: (action: {
98
115
  type: string;
99
- }): action is PayloadAction<ScrollViewSettings>;
116
+ }) => action is _rific_core.SettingsAction<boolean>;
100
117
  };
118
+ setSnapBack: {
119
+ (payload: boolean): _rific_core.SettingsAction<boolean>;
120
+ type: string;
121
+ match: (action: {
122
+ type: string;
123
+ }) => action is _rific_core.SettingsAction<boolean>;
124
+ };
125
+ setSnapBackFooter?: {
126
+ (payload: boolean | undefined): _rific_core.SettingsAction<boolean | undefined>;
127
+ type: string;
128
+ match: (action: {
129
+ type: string;
130
+ }) => action is _rific_core.SettingsAction<boolean | undefined>;
131
+ } | undefined;
132
+ setSnapBackHeader?: {
133
+ (payload: boolean | undefined): _rific_core.SettingsAction<boolean | undefined>;
134
+ type: string;
135
+ match: (action: {
136
+ type: string;
137
+ }) => action is _rific_core.SettingsAction<boolean | undefined>;
138
+ } | undefined;
101
139
  };
102
- declare const scrollViewReducer: (state: ScrollViewSettings | undefined, action: {
103
- type: string;
104
- }) => ScrollViewSettings;
140
+ declare const scrollViewReducer: _rific_core.SettingsReducer<ScrollViewSettings>;
105
141
 
106
142
  type ScrollViewProps = ScrollViewProps$1 & {
107
143
  chipProps?: ChipProps;
@@ -189,12 +225,8 @@ type ScrollViewProviderProps = {
189
225
  };
190
226
  declare const ScrollViewProvider: ({ blur, children, fixed, footerAboveKeyboard, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight }: ScrollViewProviderProps) => react.JSX.Element;
191
227
 
192
- type ScrollViewSettingsProviderProps = {
193
- children: ReactNode;
194
- onChange?: (settings: ScrollViewSettings) => void;
195
- initialValue?: Partial<ScrollViewSettings>;
196
- };
197
- declare const ScrollViewSettingsProvider: ({ children, onChange, initialValue }: ScrollViewSettingsProviderProps) => react.JSX.Element;
228
+ type ScrollViewSettingsProviderProps = SettingsProviderProps<ScrollViewSettings>;
229
+ declare const ScrollViewSettingsProvider: (props: SettingsProviderProps<ScrollViewSettings>) => React.JSX.Element;
198
230
 
199
231
  type SectionListProps<ItemT, SectionT extends {
200
232
  data: ReadonlyArray<ItemT>;
@@ -233,6 +265,6 @@ declare const useScrollView: () => {
233
265
  setProgressing: (b: boolean) => void;
234
266
  };
235
267
 
236
- declare const useScrollViewSettings: () => ScrollViewSettingsContextType;
268
+ declare const useScrollViewSettings: () => _rific_core.SettingsContextValue<ScrollViewSettings>;
237
269
 
238
270
  export { type ChipProps, CustomList, type CustomListProps, FlatList, type FlatListProps, PullSearch, type PullSearchHandle, type PullSearchProps, ScrollView, ScrollViewContext, type ScrollViewContextType, ScrollViewFooter, type ScrollViewFooterProps, ScrollViewHeader, type ScrollViewHeaderProps, type ScrollViewProps, ScrollViewProvider, type ScrollViewProviderProps, type ScrollViewSettings, ScrollViewSettingsContext, type ScrollViewSettingsContextType, ScrollViewSettingsProvider, type ScrollViewSettingsProviderProps, SectionList, type SectionListProps, defaultScrollViewSettings, scrollViewActions, scrollViewReducer, useKeyboardInset, useScrollView, useScrollViewSettings };
package/dist/index.js CHANGED
@@ -954,47 +954,43 @@ var styles5 = import_react_native9.StyleSheet.create({
954
954
  input: { margin: 0 }
955
955
  });
956
956
 
957
+ // src/redux/scrollViewSlice.ts
958
+ var import_core2 = require("@rific/core");
959
+
957
960
  // src/ScrollViewSettingsContext.ts
958
- var import_react11 = require("react");
961
+ var import_core = require("@rific/core");
959
962
  var defaultScrollViewSettings = {
960
963
  backActionFixed: true,
961
964
  footerFixed: false,
962
965
  headerFixed: false,
963
966
  snapBack: false
964
967
  };
965
- var ScrollViewSettingsContext = (0, import_react11.createContext)({
966
- settings: defaultScrollViewSettings,
967
- set: () => {
968
- }
969
- });
968
+ var settingsContext = (0, import_core.createSettingsContext)(defaultScrollViewSettings);
969
+ var ScrollViewSettingsContext = settingsContext.Context;
970
+ var scrollViewSettingsProvider = settingsContext.Provider;
971
+ var scrollViewUseSettings = settingsContext.useSettings;
970
972
 
971
973
  // src/redux/scrollViewSlice.ts
972
- var createAction = (type) => {
973
- const actionCreator = (payload) => ({ payload, type });
974
- actionCreator.type = type;
975
- actionCreator.match = (action) => action.type === type;
976
- return actionCreator;
977
- };
978
- var initialize = createAction("scrollView/initialize");
979
- var scrollViewActions = { initialize };
980
- var scrollViewReducer = (state = defaultScrollViewSettings, action) => {
981
- if (initialize.match(action)) return action.payload;
982
- return state;
983
- };
974
+ var scrollViewSlice = (0, import_core2.createSettingsSlice)("scrollView", {
975
+ initialState: defaultScrollViewSettings,
976
+ fieldSetters: []
977
+ });
978
+ var scrollViewActions = scrollViewSlice.actions;
979
+ var scrollViewReducer = scrollViewSlice.reducer;
984
980
 
985
981
  // src/ScrollView.tsx
986
- var import_react12 = require("react");
982
+ var import_react11 = require("react");
987
983
  var import_react_native10 = require("react-native");
988
984
  var import_react_native_gesture_handler3 = require("react-native-gesture-handler");
989
985
  var import_react_native_reanimated10 = __toESM(require("react-native-reanimated"));
990
986
  var import_jsx_runtime7 = require("react/jsx-runtime");
991
987
  var ScrollViewInner = ({ chipProps, chipThreshold, children, contentContainerStyle: externalContentContainerStyle, footerFixed: footerFixedProp, gesture, headerFixed: headerFixedProp, horizontal, keyboardAware, onChipPress, onMomentumScrollEnd: externalMomentumScrollEnd, onRefresh, onScrollBeginDrag: externalScrollBeginDrag, onScrollEndDrag: externalScrollEndDrag, pullSearchHeight, refreshing, style, ...props }) => {
992
- const scrollView = (0, import_react12.useRef)(null);
988
+ const scrollView = (0, import_react11.useRef)(null);
993
989
  const isHorizontal = horizontal === true;
994
990
  const { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, contentPadding, footerFixed, headerFixed } = useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, isHorizontal, keyboardAware, pullSearchHeight, style });
995
- const { listGeneration, onListUnmount } = (0, import_react12.useContext)(ScrollViewContext);
991
+ const { listGeneration, onListUnmount } = (0, import_react11.useContext)(ScrollViewContext);
996
992
  const capturedGeneration = (0, import_react_native_reanimated10.useSharedValue)(-1);
997
- (0, import_react12.useLayoutEffect)(() => {
993
+ (0, import_react11.useLayoutEffect)(() => {
998
994
  const generation = listGeneration.value;
999
995
  if (import_react_native10.Platform.OS === "web") {
1000
996
  capturedGeneration.value = generation;
@@ -1005,8 +1001,8 @@ var ScrollViewInner = ({ chipProps, chipThreshold, children, contentContainerSty
1005
1001
  capturedGeneration.value = gen;
1006
1002
  })(generation);
1007
1003
  }, [capturedGeneration, listGeneration]);
1008
- (0, import_react12.useLayoutEffect)(() => () => onListUnmount(), [onListUnmount]);
1009
- const scrollTo = (0, import_react12.useCallback)((offset, animated) => {
1004
+ (0, import_react11.useLayoutEffect)(() => () => onListUnmount(), [onListUnmount]);
1005
+ const scrollTo = (0, import_react11.useCallback)((offset, animated) => {
1010
1006
  scrollView.current?.scrollTo({ y: offset, animated });
1011
1007
  }, []);
1012
1008
  const { handleMomentumScrollEnd, handleScrollBeginDrag, handleScrollEndDrag } = useScrollInit({
@@ -1017,7 +1013,7 @@ var ScrollViewInner = ({ chipProps, chipThreshold, children, contentContainerSty
1017
1013
  scrollTo
1018
1014
  });
1019
1015
  const handleScroll = useScrollHandler({ capturedGeneration, chipHidden, chipThreshold, footerFixed, headerFixed, isHorizontal, listGeneration });
1020
- const handleScrollToTop = (0, import_react12.useCallback)(() => {
1016
+ const handleScrollToTop = (0, import_react11.useCallback)(() => {
1021
1017
  if (isHorizontal) {
1022
1018
  scrollView.current?.scrollTo({ x: 0, animated: true });
1023
1019
  return;
@@ -1025,9 +1021,9 @@ var ScrollViewInner = ({ chipProps, chipThreshold, children, contentContainerSty
1025
1021
  const offset = pullSearchHeight ? -contentInset.top + pullSearchHeight : -contentInset.top;
1026
1022
  scrollView.current?.scrollTo({ y: offset, animated: true });
1027
1023
  }, [isHorizontal, contentInset.top, pullSearchHeight]);
1028
- 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]);
1029
- const nativeGesture = (0, import_react12.useMemo)(() => import_react_native_gesture_handler3.Gesture.Native(), []);
1030
- const combinedGesture = (0, import_react12.useMemo)(() => gesture !== void 0 ? import_react_native_gesture_handler3.Gesture.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
1024
+ const refreshControl = (0, import_react11.useMemo)(() => onRefresh ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RefreshControl, { onRefresh, refreshing: refreshing ?? false }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RefreshControl, {}), [onRefresh, refreshing]);
1025
+ const nativeGesture = (0, import_react11.useMemo)(() => import_react_native_gesture_handler3.Gesture.Native(), []);
1026
+ const combinedGesture = (0, import_react11.useMemo)(() => gesture !== void 0 ? import_react_native_gesture_handler3.Gesture.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
1031
1027
  const detectorGesture = gesture !== void 0 ? combinedGesture : void 0;
1032
1028
  const content = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native10.View, { style: containerStyle, children: [
1033
1029
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
@@ -1054,11 +1050,11 @@ var ScrollViewInner = ({ chipProps, chipThreshold, children, contentContainerSty
1054
1050
  ] });
1055
1051
  return detectorGesture ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_gesture_handler3.GestureDetector, { gesture: detectorGesture, children: content }) : content;
1056
1052
  };
1057
- var ScrollView = (0, import_react12.memo)(ScrollViewInner);
1053
+ var ScrollView = (0, import_react11.memo)(ScrollViewInner);
1058
1054
 
1059
1055
  // src/ScrollViewFooter.tsx
1060
1056
  var import_auto_paper3 = require("@rific/auto-paper");
1061
- var import_react13 = require("react");
1057
+ var import_react12 = require("react");
1062
1058
  var import_react_native11 = require("react-native");
1063
1059
  var import_react_native_reanimated11 = __toESM(require("react-native-reanimated"));
1064
1060
  var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
@@ -1070,12 +1066,14 @@ var import_jsx_runtime8 = (
1070
1066
  require("react/jsx-runtime")
1071
1067
  );
1072
1068
  var ScrollViewFooter = ({ children, style }) => {
1073
- const { blur, footerAboveKeyboard, footerHeight, footerFixed, footerOffset, headerHeightShared, pullSearchHeightShared, scrollPosition, setFooterHeight, snapBackFooterShared, tabBarHeight } = (0, import_react13.useContext)(ScrollViewContext);
1069
+ const { blur, footerAboveKeyboard, footerHeight, footerFixed, footerOffset, headerHeightShared, pullSearchHeightShared, scrollPosition, setFooterHeight, snapBackFooterShared, tabBarHeight } = (0, import_react12.useContext)(ScrollViewContext);
1074
1070
  const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
1075
1071
  const keyboardHeight = useKeyboardInset();
1076
- const setFooterHeightRef = (0, import_react13.useRef)(setFooterHeight);
1077
- setFooterHeightRef.current = setFooterHeight;
1078
- (0, import_react13.useEffect)(
1072
+ const setFooterHeightRef = (0, import_react12.useRef)(setFooterHeight);
1073
+ (0, import_react12.useEffect)(() => {
1074
+ setFooterHeightRef.current = setFooterHeight;
1075
+ });
1076
+ (0, import_react12.useEffect)(
1079
1077
  () => () => {
1080
1078
  setFooterHeightRef.current(null);
1081
1079
  },
@@ -1110,7 +1108,7 @@ var styles6 = import_react_native11.StyleSheet.create({
1110
1108
 
1111
1109
  // src/ScrollViewHeader.tsx
1112
1110
  var import_auto_paper4 = require("@rific/auto-paper");
1113
- var import_react14 = require("react");
1111
+ var import_react13 = require("react");
1114
1112
  var import_react_native12 = require("react-native");
1115
1113
  var import_react_native_paper4 = require("react-native-paper");
1116
1114
  var import_react_native_reanimated12 = __toESM(require("react-native-reanimated"));
@@ -1118,8 +1116,8 @@ var import_react_native_safe_area_context4 = require("react-native-safe-area-con
1118
1116
  var import_jsx_runtime9 = require("react/jsx-runtime");
1119
1117
  var ActionBg = ({ blur, style }) => blur ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: [import_react_native12.StyleSheet.absoluteFill, styles7.actionBg, style], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper4.BlurView, { blur: true, style: import_react_native12.StyleSheet.absoluteFill }) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: [import_react_native12.StyleSheet.absoluteFill, styles7.actionBg, style], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper4.Surface, { style: import_react_native12.StyleSheet.absoluteFill, elevation: 1, children: null }) });
1120
1118
  var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionAccessibilityLabel, backActionFixed, caption, centerContent, children, iconSize, style, title, topInset = true, trailingAction, trailingActionFixed = true }) => {
1121
- const { blur, headerHeight, headerFixed, headerHeightShared, headerOffset, progress, progressing, pullSearchHeightShared, scrollPosition, setHeaderHeight, snapBackHeaderShared } = (0, import_react14.useContext)(ScrollViewContext);
1122
- const { settings } = (0, import_react14.useContext)(ScrollViewSettingsContext);
1119
+ const { blur, headerHeight, headerFixed, headerHeightShared, headerOffset, progress, progressing, pullSearchHeightShared, scrollPosition, setHeaderHeight, snapBackHeaderShared } = (0, import_react13.useContext)(ScrollViewContext);
1120
+ const { settings } = (0, import_react13.useContext)(ScrollViewSettingsContext);
1123
1121
  const effectiveBackActionFixed = backActionFixed ?? settings.backActionFixed;
1124
1122
  const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
1125
1123
  const theme = (0, import_react_native_paper4.useTheme)();
@@ -1209,23 +1207,23 @@ var styles7 = import_react_native12.StyleSheet.create({
1209
1207
 
1210
1208
  // src/ScrollViewProvider.tsx
1211
1209
  var import_auto_paper5 = require("@rific/auto-paper");
1212
- var import_react15 = require("react");
1210
+ var import_react14 = require("react");
1213
1211
  var import_react_native13 = require("react-native");
1214
1212
  var import_react_native_reanimated13 = require("react-native-reanimated");
1215
1213
  var import_jsx_runtime10 = require("react/jsx-runtime");
1216
1214
  var ScrollViewProvider = ({ blur, children, fixed = false, footerAboveKeyboard = false, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight = 0 }) => {
1217
- const { settings } = (0, import_react15.useContext)(ScrollViewSettingsContext);
1215
+ const { settings } = (0, import_react14.useContext)(ScrollViewSettingsContext);
1218
1216
  const effectiveBlur = (0, import_auto_paper5.useBlur)(blur);
1219
1217
  const effectiveSnapBack = snapBack ?? settings.snapBack;
1220
1218
  const effectiveSnapBackHeader = snapBackHeader ?? settings.snapBackHeader;
1221
1219
  const effectiveSnapBackFooter = snapBackFooter ?? settings.snapBackFooter;
1222
- const [headerHeight, setHeaderHeightState] = (0, import_react15.useState)(null);
1223
- const [footerHeight, setFooterHeightState] = (0, import_react15.useState)(null);
1224
- const [progress, setProgress] = (0, import_react15.useState)(null);
1225
- const [progressing, setProgressing] = (0, import_react15.useState)(false);
1220
+ const [headerHeight, setHeaderHeightState] = (0, import_react14.useState)(null);
1221
+ const [footerHeight, setFooterHeightState] = (0, import_react14.useState)(null);
1222
+ const [progress, setProgress] = (0, import_react14.useState)(null);
1223
+ const [progressing, setProgressing] = (0, import_react14.useState)(false);
1226
1224
  const scrollPosition = (0, import_react_native_reanimated13.useSharedValue)(0);
1227
1225
  const listGeneration = (0, import_react_native_reanimated13.useSharedValue)(0);
1228
- const jsListGeneration = (0, import_react15.useRef)(0);
1226
+ const jsListGeneration = (0, import_react14.useRef)(0);
1229
1227
  const headerHeightShared = (0, import_react_native_reanimated13.useSharedValue)(0);
1230
1228
  const footerHeightShared = (0, import_react_native_reanimated13.useSharedValue)(0);
1231
1229
  const headerOffset = (0, import_react_native_reanimated13.useSharedValue)(0);
@@ -1233,11 +1231,11 @@ var ScrollViewProvider = ({ blur, children, fixed = false, footerAboveKeyboard =
1233
1231
  const pullSearchHeightShared = (0, import_react_native_reanimated13.useSharedValue)(0);
1234
1232
  const snapBackHeaderShared = (0, import_react_native_reanimated13.useSharedValue)(false);
1235
1233
  const snapBackFooterShared = (0, import_react_native_reanimated13.useSharedValue)(false);
1236
- (0, import_react15.useEffect)(() => {
1234
+ (0, import_react14.useEffect)(() => {
1237
1235
  snapBackHeaderShared.value = effectiveSnapBackHeader ?? effectiveSnapBack;
1238
1236
  snapBackFooterShared.value = effectiveSnapBackFooter ?? effectiveSnapBack;
1239
1237
  }, [effectiveSnapBack, effectiveSnapBackFooter, effectiveSnapBackHeader, snapBackFooterShared, snapBackHeaderShared]);
1240
- const setHeaderHeight = (0, import_react15.useCallback)(
1238
+ const setHeaderHeight = (0, import_react14.useCallback)(
1241
1239
  (h) => {
1242
1240
  if (h === 0 && headerHeight) return;
1243
1241
  setHeaderHeightState(h);
@@ -1245,20 +1243,20 @@ var ScrollViewProvider = ({ blur, children, fixed = false, footerAboveKeyboard =
1245
1243
  },
1246
1244
  [headerHeight, headerHeightShared]
1247
1245
  );
1248
- const onListUnmount = (0, import_react15.useCallback)(() => {
1246
+ const onListUnmount = (0, import_react14.useCallback)(() => {
1249
1247
  listGeneration.value += 1;
1250
1248
  }, [listGeneration]);
1251
- const onJsListUnmount = (0, import_react15.useCallback)(() => {
1249
+ const onJsListUnmount = (0, import_react14.useCallback)(() => {
1252
1250
  jsListGeneration.current += 1;
1253
1251
  }, []);
1254
- (0, import_react15.useEffect)(() => {
1252
+ (0, import_react14.useEffect)(() => {
1255
1253
  if (!__DEV__ || headerHeight !== null) return;
1256
1254
  const timeout = setTimeout(() => {
1257
1255
  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.");
1258
1256
  }, 3e3);
1259
1257
  return () => clearTimeout(timeout);
1260
1258
  }, [headerHeight]);
1261
- (0, import_react15.useEffect)(() => {
1259
+ (0, import_react14.useEffect)(() => {
1262
1260
  if (import_react_native13.Platform.OS !== "web" || headerHeight !== null) return;
1263
1261
  let raf2 = 0;
1264
1262
  const raf1 = requestAnimationFrame(() => {
@@ -1269,7 +1267,7 @@ var ScrollViewProvider = ({ blur, children, fixed = false, footerAboveKeyboard =
1269
1267
  cancelAnimationFrame(raf2);
1270
1268
  };
1271
1269
  }, [headerHeight, setHeaderHeight]);
1272
- const setFooterHeight = (0, import_react15.useCallback)(
1270
+ const setFooterHeight = (0, import_react14.useCallback)(
1273
1271
  (h) => {
1274
1272
  if (h === 0 && footerHeight) return;
1275
1273
  setFooterHeightState(h);
@@ -1277,57 +1275,38 @@ var ScrollViewProvider = ({ blur, children, fixed = false, footerAboveKeyboard =
1277
1275
  },
1278
1276
  [footerHeight, footerHeightShared]
1279
1277
  );
1280
- const scrollHeight = (0, import_react15.useMemo)(() => import_react_native13.Dimensions.get("window").height - (headerHeight ?? 0) - (footerHeight ?? 0), [headerHeight, footerHeight]);
1278
+ const scrollHeight = (0, import_react14.useMemo)(() => import_react_native13.Dimensions.get("window").height - (headerHeight ?? 0) - (footerHeight ?? 0), [headerHeight, footerHeight]);
1281
1279
  const effectiveHeaderFixed = fixed || (headerFixed ?? settings.headerFixed);
1282
1280
  const effectiveFooterFixed = fixed || (footerFixed ?? settings.footerFixed);
1283
- const value = (0, import_react15.useMemo)(() => ({ blur: effectiveBlur, 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, tabBarHeight }), [effectiveBlur, footerAboveKeyboard, effectiveFooterFixed, effectiveHeaderFixed, footerHeight, footerHeightShared, footerOffset, headerHeight, headerHeightShared, headerOffset, jsListGeneration, listGeneration, onJsListUnmount, onListUnmount, progress, pullSearchHeightShared, progressing, scrollHeight, scrollPosition, setFooterHeight, setHeaderHeight, snapBackFooterShared, snapBackHeaderShared, tabBarHeight]);
1281
+ const value = (0, import_react14.useMemo)(() => ({ blur: effectiveBlur, 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, tabBarHeight }), [effectiveBlur, footerAboveKeyboard, effectiveFooterFixed, effectiveHeaderFixed, footerHeight, footerHeightShared, footerOffset, headerHeight, headerHeightShared, headerOffset, jsListGeneration, listGeneration, onJsListUnmount, onListUnmount, progress, pullSearchHeightShared, progressing, scrollHeight, scrollPosition, setFooterHeight, setHeaderHeight, snapBackFooterShared, snapBackHeaderShared, tabBarHeight]);
1284
1282
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ScrollViewContext.Provider, { value, children });
1285
1283
  };
1286
1284
 
1287
1285
  // src/ScrollViewSettingsProvider.tsx
1288
- var import_react16 = require("react");
1289
- var import_jsx_runtime11 = require("react/jsx-runtime");
1290
- var ScrollViewSettingsProvider = ({ children, onChange, initialValue }) => {
1291
- const [settings, setSettings] = (0, import_react16.useState)(() => ({
1292
- ...defaultScrollViewSettings,
1293
- ...initialValue
1294
- }));
1295
- const set = (0, import_react16.useCallback)(
1296
- (patch) => {
1297
- setSettings((prev) => {
1298
- const next = { ...prev, ...patch };
1299
- onChange?.(next);
1300
- return next;
1301
- });
1302
- },
1303
- [onChange]
1304
- );
1305
- const ctx = (0, import_react16.useMemo)(() => ({ settings, set }), [settings, set]);
1306
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScrollViewSettingsContext.Provider, { value: ctx, children });
1307
- };
1286
+ var ScrollViewSettingsProvider = scrollViewSettingsProvider;
1308
1287
 
1309
1288
  // src/SectionList.tsx
1310
- var import_react18 = require("react");
1289
+ var import_react16 = require("react");
1311
1290
  var import_react_native14 = require("react-native");
1312
1291
  var import_react_native_gesture_handler4 = require("react-native-gesture-handler");
1313
1292
  var import_react_native_reanimated15 = __toESM(require("react-native-reanimated"));
1314
1293
 
1315
1294
  // src/internal/useStickyHeaders.ts
1316
- var import_react17 = require("react");
1295
+ var import_react15 = require("react");
1317
1296
  var import_react_native_reanimated14 = require("react-native-reanimated");
1318
1297
  var import_react_native_safe_area_context5 = require("react-native-safe-area-context");
1319
1298
  function useStickyHeaders(headerFixed, enabled) {
1320
- const { headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared } = (0, import_react17.useContext)(ScrollViewContext);
1299
+ const { headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared } = (0, import_react15.useContext)(ScrollViewContext);
1321
1300
  const insetsTop = (0, import_react_native_safe_area_context5.useSafeAreaInsets)().top;
1322
1301
  const sectionYPositions = (0, import_react_native_reanimated14.useSharedValue)([]);
1323
1302
  const sectionHeights = (0, import_react_native_reanimated14.useSharedValue)([]);
1324
- const [activeIndex, setActiveIndex] = (0, import_react17.useState)(-1);
1303
+ const [activeIndex, setActiveIndex] = (0, import_react15.useState)(-1);
1325
1304
  const contentIndexShared = (0, import_react_native_reanimated14.useSharedValue)(-1);
1326
- (0, import_react17.useLayoutEffect)(() => {
1305
+ (0, import_react15.useLayoutEffect)(() => {
1327
1306
  contentIndexShared.value = activeIndex;
1328
1307
  }, [activeIndex, contentIndexShared]);
1329
- const positionsCache = (0, import_react17.useRef)([]);
1330
- const heightsCache = (0, import_react17.useRef)([]);
1308
+ const positionsCache = (0, import_react15.useRef)([]);
1309
+ const heightsCache = (0, import_react15.useRef)([]);
1331
1310
  (0, import_react_native_reanimated14.useAnimatedReaction)(
1332
1311
  () => {
1333
1312
  if (!enabled) return -1;
@@ -1404,7 +1383,7 @@ function useStickyHeaders(headerFixed, enabled) {
1404
1383
  }
1405
1384
  return { opacity: 1, top: 0, transform: [{ translateY }] };
1406
1385
  }, [enabled, headerFixed, insetsTop, contentIndexShared, sectionYPositions, headerHeightShared, scrollPosition, snapBackHeaderShared, headerOffset, pullSearchHeightShared, sectionHeights]);
1407
- const measureHeader = (0, import_react17.useCallback)(
1386
+ const measureHeader = (0, import_react15.useCallback)(
1408
1387
  (index, pageY, height) => {
1409
1388
  const contentY = pageY + scrollPosition.value;
1410
1389
  positionsCache.current[index] = contentY;
@@ -1414,7 +1393,7 @@ function useStickyHeaders(headerFixed, enabled) {
1414
1393
  },
1415
1394
  [scrollPosition, sectionHeights, sectionYPositions]
1416
1395
  );
1417
- const resetPositions = (0, import_react17.useCallback)(
1396
+ const resetPositions = (0, import_react15.useCallback)(
1418
1397
  (count) => {
1419
1398
  positionsCache.current = Array.from({ length: count }, () => -1);
1420
1399
  sectionYPositions.value = positionsCache.current.slice();
@@ -1427,15 +1406,15 @@ function useStickyHeaders(headerFixed, enabled) {
1427
1406
  }
1428
1407
 
1429
1408
  // src/SectionList.tsx
1430
- var import_jsx_runtime12 = require("react/jsx-runtime");
1409
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1431
1410
  var AnimatedSectionList = import_react_native_reanimated15.default.createAnimatedComponent(import_react_native14.SectionList);
1432
1411
  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 }) => {
1433
- const scrollView = (0, import_react18.useRef)(null);
1412
+ const scrollView = (0, import_react16.useRef)(null);
1434
1413
  const { stickySectionHeadersEnabled = true, renderSectionHeader, ...passThroughProps } = props;
1435
1414
  const { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, contentPadding, footerFixed, headerFixed, headerHeight } = useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, hideUntilMeasured: true, keyboardAware, pullSearchHeight, style });
1436
- const { listGeneration, onListUnmount } = (0, import_react18.useContext)(ScrollViewContext);
1415
+ const { listGeneration, onListUnmount } = (0, import_react16.useContext)(ScrollViewContext);
1437
1416
  const capturedGeneration = (0, import_react_native_reanimated15.useSharedValue)(-1);
1438
- (0, import_react18.useLayoutEffect)(() => {
1417
+ (0, import_react16.useLayoutEffect)(() => {
1439
1418
  const generation = listGeneration.value;
1440
1419
  if (import_react_native14.Platform.OS === "web") {
1441
1420
  capturedGeneration.value = generation;
@@ -1448,15 +1427,15 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1448
1427
  }, [capturedGeneration, listGeneration]);
1449
1428
  const usesCustomSticky = stickySectionHeadersEnabled && renderSectionHeader != null;
1450
1429
  const { activeIndex, clipStyle, measureHeader, overlayStyle, resetPositions } = useStickyHeaders(headerFixed, usesCustomSticky);
1451
- (0, import_react18.useLayoutEffect)(() => {
1430
+ (0, import_react16.useLayoutEffect)(() => {
1452
1431
  if (usesCustomSticky) resetPositions(sections.length);
1453
1432
  }, [sections, usesCustomSticky, resetPositions, headerHeight]);
1454
- const sectionViewRefs = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
1455
- const wrappedRenderSectionHeader = (0, import_react18.useMemo)(() => {
1433
+ const sectionViewRefs = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
1434
+ const wrappedRenderSectionHeader = (0, import_react16.useMemo)(() => {
1456
1435
  if (!usesCustomSticky) return renderSectionHeader ?? void 0;
1457
1436
  return (info) => {
1458
1437
  const idx = sections.findIndex((s) => s === info.section);
1459
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1438
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1460
1439
  import_react_native14.View,
1461
1440
  {
1462
1441
  ref: (el) => {
@@ -1473,8 +1452,8 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1473
1452
  );
1474
1453
  };
1475
1454
  }, [usesCustomSticky, renderSectionHeader, sections, measureHeader]);
1476
- (0, import_react18.useLayoutEffect)(() => () => onListUnmount(), [onListUnmount]);
1477
- const scrollTo = (0, import_react18.useCallback)((offset, animated) => {
1455
+ (0, import_react16.useLayoutEffect)(() => () => onListUnmount(), [onListUnmount]);
1456
+ const scrollTo = (0, import_react16.useCallback)((offset, animated) => {
1478
1457
  scrollView.current?.getScrollResponder()?.scrollTo({ y: offset, animated });
1479
1458
  }, []);
1480
1459
  const {
@@ -1492,16 +1471,16 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1492
1471
  pullSearchHeight,
1493
1472
  scrollTo
1494
1473
  });
1495
- const activeListHeader = (0, import_react18.useMemo)(() => {
1474
+ const activeListHeader = (0, import_react16.useMemo)(() => {
1496
1475
  if (!renderFilters) return pullSearchHeader;
1497
1476
  const Inner = pullSearchHeader;
1498
- return () => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1499
- Inner ? typeof Inner === "function" ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Inner, {}) : Inner : null,
1477
+ return () => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1478
+ Inner ? typeof Inner === "function" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Inner, {}) : Inner : null,
1500
1479
  renderFilters
1501
1480
  ] });
1502
1481
  }, [pullSearchHeader, renderFilters]);
1503
- const pullSearchSettled = (0, import_react18.useRef)(false);
1504
- (0, import_react18.useEffect)(() => {
1482
+ const pullSearchSettled = (0, import_react16.useRef)(false);
1483
+ (0, import_react16.useEffect)(() => {
1505
1484
  if (!usesCustomSticky || activeListHeader == null || pullSearchSettled.current) return;
1506
1485
  pullSearchSettled.current = true;
1507
1486
  const handle = requestAnimationFrame(() => {
@@ -1513,24 +1492,24 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1513
1492
  });
1514
1493
  return () => cancelAnimationFrame(handle);
1515
1494
  }, [activeListHeader, usesCustomSticky, measureHeader]);
1516
- const contentContainerStyle = (0, import_react18.useMemo)(() => [{ minHeight: import_react_native14.Dimensions.get("window").height - contentInset.top - contentInset.bottom + pullSearchMinHeight }, externalContentContainerStyle, contentPadding], [contentInset.bottom, contentInset.top, contentPadding, externalContentContainerStyle, pullSearchMinHeight]);
1495
+ const contentContainerStyle = (0, import_react16.useMemo)(() => [{ minHeight: import_react_native14.Dimensions.get("window").height - contentInset.top - contentInset.bottom + pullSearchMinHeight }, externalContentContainerStyle, contentPadding], [contentInset.bottom, contentInset.top, contentPadding, externalContentContainerStyle, pullSearchMinHeight]);
1517
1496
  const handleScroll = useScrollHandler({ capturedGeneration, chipHidden, chipThreshold, footerFixed, headerFixed, listGeneration });
1518
- const handleScrollToTop = (0, import_react18.useCallback)(() => {
1497
+ const handleScrollToTop = (0, import_react16.useCallback)(() => {
1519
1498
  const offset = pullSearchHeight ? -contentInset.top + pullSearchHeight : -contentInset.top;
1520
1499
  scrollView.current?.getScrollResponder()?.scrollTo({ y: offset, animated: true });
1521
1500
  }, [contentInset.top, pullSearchHeight]);
1522
- const handleContentSizeChange = (0, import_react18.useCallback)(
1501
+ const handleContentSizeChange = (0, import_react16.useCallback)(
1523
1502
  (w, h) => {
1524
1503
  if (onContentSizeChange) onContentSizeChange(w, h);
1525
1504
  },
1526
1505
  [onContentSizeChange]
1527
1506
  );
1528
- 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]);
1529
- const nativeGesture = (0, import_react18.useMemo)(() => import_react_native_gesture_handler4.Gesture.Native(), []);
1530
- const combinedGesture = (0, import_react18.useMemo)(() => gesture !== void 0 ? import_react_native_gesture_handler4.Gesture.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
1507
+ const refreshControl = (0, import_react16.useMemo)(() => onRefresh ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RefreshControl, { onRefresh, refreshing: refreshing ?? false }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RefreshControl, {}), [onRefresh, refreshing]);
1508
+ const nativeGesture = (0, import_react16.useMemo)(() => import_react_native_gesture_handler4.Gesture.Native(), []);
1509
+ const combinedGesture = (0, import_react16.useMemo)(() => gesture !== void 0 ? import_react_native_gesture_handler4.Gesture.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
1531
1510
  const detectorGesture = gesture !== void 0 ? combinedGesture : void 0;
1532
- const content = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native14.View, { style: containerStyle, children: [
1533
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1511
+ const content = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native14.View, { style: containerStyle, children: [
1512
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1534
1513
  AnimatedSectionList,
1535
1514
  {
1536
1515
  ...passThroughProps,
@@ -1560,29 +1539,28 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1560
1539
  },
1561
1540
  headerHeight !== null && headerHeight > 0 ? 1 : 0
1562
1541
  ),
1563
- hiddenHeader && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native14.View, { pointerEvents: "none", style: styles8.measureContainer, children: hiddenHeader }),
1564
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScrollViewChip, { chipProps, onChipPress, onPress: handleScrollToTop, style: chipStyle }),
1565
- 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] }) }) })
1542
+ hiddenHeader && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native14.View, { pointerEvents: "none", style: styles8.measureContainer, children: hiddenHeader }),
1543
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScrollViewChip, { chipProps, onChipPress, onPress: handleScrollToTop, style: chipStyle }),
1544
+ usesCustomSticky && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_reanimated15.default.View, { pointerEvents: "none", style: [styles8.stickyClip, clipStyle], children: activeIndex >= 0 && activeIndex < sections.length && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_reanimated15.default.View, { style: [styles8.stickyOverlay, overlayStyle], children: renderSectionHeader({ section: sections[activeIndex] }) }) })
1566
1545
  ] });
1567
- return detectorGesture ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native_gesture_handler4.GestureDetector, { gesture: detectorGesture, children: content }) : content;
1546
+ return detectorGesture ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_gesture_handler4.GestureDetector, { gesture: detectorGesture, children: content }) : content;
1568
1547
  };
1569
1548
  var styles8 = {
1570
1549
  measureContainer: { left: 0, opacity: 0, position: "absolute", right: 0, top: -9999 },
1571
1550
  stickyClip: { bottom: 0, left: 0, overflow: "hidden", position: "absolute", right: 0, zIndex: 2 },
1572
1551
  stickyOverlay: { left: 0, position: "absolute", right: 0 }
1573
1552
  };
1574
- var SectionList = (0, import_react18.memo)(SectionListInner);
1553
+ var SectionList = (0, import_react16.memo)(SectionListInner);
1575
1554
 
1576
1555
  // src/useScrollView.ts
1577
- var import_react19 = require("react");
1556
+ var import_react17 = require("react");
1578
1557
  var useScrollView = () => {
1579
- const { progress, progressing, scrollHeight, scrollPosition, setProgress, setProgressing } = (0, import_react19.useContext)(ScrollViewContext);
1558
+ const { progress, progressing, scrollHeight, scrollPosition, setProgress, setProgressing } = (0, import_react17.useContext)(ScrollViewContext);
1580
1559
  return { progress, progressing, scrollHeight, scrollPosition, setProgress, setProgressing };
1581
1560
  };
1582
1561
 
1583
1562
  // src/useScrollViewSettings.ts
1584
- var import_react20 = require("react");
1585
- var useScrollViewSettings = () => (0, import_react20.useContext)(ScrollViewSettingsContext);
1563
+ var useScrollViewSettings = scrollViewUseSettings;
1586
1564
  // Annotate the CommonJS export names for ESM import in node:
1587
1565
  0 && (module.exports = {
1588
1566
  CustomList,
package/dist/index.mjs CHANGED
@@ -902,33 +902,29 @@ var styles5 = StyleSheet4.create({
902
902
  input: { margin: 0 }
903
903
  });
904
904
 
905
+ // src/redux/scrollViewSlice.ts
906
+ import { createSettingsSlice } from "@rific/core";
907
+
905
908
  // src/ScrollViewSettingsContext.ts
906
- import { createContext as createContext2 } from "react";
909
+ import { createSettingsContext } from "@rific/core";
907
910
  var defaultScrollViewSettings = {
908
911
  backActionFixed: true,
909
912
  footerFixed: false,
910
913
  headerFixed: false,
911
914
  snapBack: false
912
915
  };
913
- var ScrollViewSettingsContext = createContext2({
914
- settings: defaultScrollViewSettings,
915
- set: () => {
916
- }
917
- });
916
+ var settingsContext = createSettingsContext(defaultScrollViewSettings);
917
+ var ScrollViewSettingsContext = settingsContext.Context;
918
+ var scrollViewSettingsProvider = settingsContext.Provider;
919
+ var scrollViewUseSettings = settingsContext.useSettings;
918
920
 
919
921
  // src/redux/scrollViewSlice.ts
920
- var createAction = (type) => {
921
- const actionCreator = (payload) => ({ payload, type });
922
- actionCreator.type = type;
923
- actionCreator.match = (action) => action.type === type;
924
- return actionCreator;
925
- };
926
- var initialize = createAction("scrollView/initialize");
927
- var scrollViewActions = { initialize };
928
- var scrollViewReducer = (state = defaultScrollViewSettings, action) => {
929
- if (initialize.match(action)) return action.payload;
930
- return state;
931
- };
922
+ var scrollViewSlice = createSettingsSlice("scrollView", {
923
+ initialState: defaultScrollViewSettings,
924
+ fieldSetters: []
925
+ });
926
+ var scrollViewActions = scrollViewSlice.actions;
927
+ var scrollViewReducer = scrollViewSlice.reducer;
932
928
 
933
929
  // src/ScrollView.tsx
934
930
  import { memo as memo3, useCallback as useCallback6, useContext as useContext9, useLayoutEffect as useLayoutEffect4, useMemo as useMemo4, useRef as useRef6 } from "react";
@@ -1016,7 +1012,9 @@ var ScrollViewFooter = ({ children, style }) => {
1016
1012
  const insets = useSafeAreaInsets3();
1017
1013
  const keyboardHeight = useKeyboardInset();
1018
1014
  const setFooterHeightRef = useRef7(setFooterHeight);
1019
- setFooterHeightRef.current = setFooterHeight;
1015
+ useEffect4(() => {
1016
+ setFooterHeightRef.current = setFooterHeight;
1017
+ });
1020
1018
  useEffect4(
1021
1019
  () => () => {
1022
1020
  setFooterHeightRef.current(null);
@@ -1233,35 +1231,16 @@ var ScrollViewProvider = ({ blur, children, fixed = false, footerAboveKeyboard =
1233
1231
  };
1234
1232
 
1235
1233
  // src/ScrollViewSettingsProvider.tsx
1236
- import { useCallback as useCallback8, useMemo as useMemo6, useState as useState6 } from "react";
1237
- import { jsx as jsx11 } from "react/jsx-runtime";
1238
- var ScrollViewSettingsProvider = ({ children, onChange, initialValue }) => {
1239
- const [settings, setSettings] = useState6(() => ({
1240
- ...defaultScrollViewSettings,
1241
- ...initialValue
1242
- }));
1243
- const set = useCallback8(
1244
- (patch) => {
1245
- setSettings((prev) => {
1246
- const next = { ...prev, ...patch };
1247
- onChange?.(next);
1248
- return next;
1249
- });
1250
- },
1251
- [onChange]
1252
- );
1253
- const ctx = useMemo6(() => ({ settings, set }), [settings, set]);
1254
- return /* @__PURE__ */ jsx11(ScrollViewSettingsContext.Provider, { value: ctx, children });
1255
- };
1234
+ var ScrollViewSettingsProvider = scrollViewSettingsProvider;
1256
1235
 
1257
1236
  // src/SectionList.tsx
1258
- import { memo as memo4, useCallback as useCallback10, useContext as useContext14, useEffect as useEffect6, useLayoutEffect as useLayoutEffect6, useMemo as useMemo7, useRef as useRef10 } from "react";
1237
+ import { memo as memo4, useCallback as useCallback9, useContext as useContext14, useEffect as useEffect6, useLayoutEffect as useLayoutEffect6, useMemo as useMemo6, useRef as useRef10 } from "react";
1259
1238
  import { Dimensions as Dimensions4, Platform as Platform6, SectionList as RNSectionList, View as View7 } from "react-native";
1260
1239
  import { Gesture as Gesture4, GestureDetector as GestureDetector4 } from "react-native-gesture-handler";
1261
1240
  import Animated7, { runOnUI as runOnUI3, useSharedValue as useSharedValue9 } from "react-native-reanimated";
1262
1241
 
1263
1242
  // src/internal/useStickyHeaders.ts
1264
- import { useCallback as useCallback9, useContext as useContext13, useLayoutEffect as useLayoutEffect5, useRef as useRef9, useState as useState7 } from "react";
1243
+ import { useCallback as useCallback8, useContext as useContext13, useLayoutEffect as useLayoutEffect5, useRef as useRef9, useState as useState6 } from "react";
1265
1244
  import { runOnJS as runOnJS4, useAnimatedReaction as useAnimatedReaction2, useAnimatedStyle as useAnimatedStyle6, useSharedValue as useSharedValue8 } from "react-native-reanimated";
1266
1245
  import { useSafeAreaInsets as useSafeAreaInsets5 } from "react-native-safe-area-context";
1267
1246
  function useStickyHeaders(headerFixed, enabled) {
@@ -1269,7 +1248,7 @@ function useStickyHeaders(headerFixed, enabled) {
1269
1248
  const insetsTop = useSafeAreaInsets5().top;
1270
1249
  const sectionYPositions = useSharedValue8([]);
1271
1250
  const sectionHeights = useSharedValue8([]);
1272
- const [activeIndex, setActiveIndex] = useState7(-1);
1251
+ const [activeIndex, setActiveIndex] = useState6(-1);
1273
1252
  const contentIndexShared = useSharedValue8(-1);
1274
1253
  useLayoutEffect5(() => {
1275
1254
  contentIndexShared.value = activeIndex;
@@ -1352,7 +1331,7 @@ function useStickyHeaders(headerFixed, enabled) {
1352
1331
  }
1353
1332
  return { opacity: 1, top: 0, transform: [{ translateY }] };
1354
1333
  }, [enabled, headerFixed, insetsTop, contentIndexShared, sectionYPositions, headerHeightShared, scrollPosition, snapBackHeaderShared, headerOffset, pullSearchHeightShared, sectionHeights]);
1355
- const measureHeader = useCallback9(
1334
+ const measureHeader = useCallback8(
1356
1335
  (index, pageY, height) => {
1357
1336
  const contentY = pageY + scrollPosition.value;
1358
1337
  positionsCache.current[index] = contentY;
@@ -1362,7 +1341,7 @@ function useStickyHeaders(headerFixed, enabled) {
1362
1341
  },
1363
1342
  [scrollPosition, sectionHeights, sectionYPositions]
1364
1343
  );
1365
- const resetPositions = useCallback9(
1344
+ const resetPositions = useCallback8(
1366
1345
  (count) => {
1367
1346
  positionsCache.current = Array.from({ length: count }, () => -1);
1368
1347
  sectionYPositions.value = positionsCache.current.slice();
@@ -1375,7 +1354,7 @@ function useStickyHeaders(headerFixed, enabled) {
1375
1354
  }
1376
1355
 
1377
1356
  // src/SectionList.tsx
1378
- import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
1357
+ import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
1379
1358
  var AnimatedSectionList = Animated7.createAnimatedComponent(RNSectionList);
1380
1359
  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 }) => {
1381
1360
  const scrollView = useRef10(null);
@@ -1400,11 +1379,11 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1400
1379
  if (usesCustomSticky) resetPositions(sections.length);
1401
1380
  }, [sections, usesCustomSticky, resetPositions, headerHeight]);
1402
1381
  const sectionViewRefs = useRef10(/* @__PURE__ */ new Map());
1403
- const wrappedRenderSectionHeader = useMemo7(() => {
1382
+ const wrappedRenderSectionHeader = useMemo6(() => {
1404
1383
  if (!usesCustomSticky) return renderSectionHeader ?? void 0;
1405
1384
  return (info) => {
1406
1385
  const idx = sections.findIndex((s) => s === info.section);
1407
- return /* @__PURE__ */ jsx12(
1386
+ return /* @__PURE__ */ jsx11(
1408
1387
  View7,
1409
1388
  {
1410
1389
  ref: (el) => {
@@ -1422,7 +1401,7 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1422
1401
  };
1423
1402
  }, [usesCustomSticky, renderSectionHeader, sections, measureHeader]);
1424
1403
  useLayoutEffect6(() => () => onListUnmount(), [onListUnmount]);
1425
- const scrollTo = useCallback10((offset, animated) => {
1404
+ const scrollTo = useCallback9((offset, animated) => {
1426
1405
  scrollView.current?.getScrollResponder()?.scrollTo({ y: offset, animated });
1427
1406
  }, []);
1428
1407
  const {
@@ -1440,11 +1419,11 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1440
1419
  pullSearchHeight,
1441
1420
  scrollTo
1442
1421
  });
1443
- const activeListHeader = useMemo7(() => {
1422
+ const activeListHeader = useMemo6(() => {
1444
1423
  if (!renderFilters) return pullSearchHeader;
1445
1424
  const Inner = pullSearchHeader;
1446
1425
  return () => /* @__PURE__ */ jsxs7(Fragment5, { children: [
1447
- Inner ? typeof Inner === "function" ? /* @__PURE__ */ jsx12(Inner, {}) : Inner : null,
1426
+ Inner ? typeof Inner === "function" ? /* @__PURE__ */ jsx11(Inner, {}) : Inner : null,
1448
1427
  renderFilters
1449
1428
  ] });
1450
1429
  }, [pullSearchHeader, renderFilters]);
@@ -1461,24 +1440,24 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1461
1440
  });
1462
1441
  return () => cancelAnimationFrame(handle);
1463
1442
  }, [activeListHeader, usesCustomSticky, measureHeader]);
1464
- const contentContainerStyle = useMemo7(() => [{ minHeight: Dimensions4.get("window").height - contentInset.top - contentInset.bottom + pullSearchMinHeight }, externalContentContainerStyle, contentPadding], [contentInset.bottom, contentInset.top, contentPadding, externalContentContainerStyle, pullSearchMinHeight]);
1443
+ const contentContainerStyle = useMemo6(() => [{ minHeight: Dimensions4.get("window").height - contentInset.top - contentInset.bottom + pullSearchMinHeight }, externalContentContainerStyle, contentPadding], [contentInset.bottom, contentInset.top, contentPadding, externalContentContainerStyle, pullSearchMinHeight]);
1465
1444
  const handleScroll = useScrollHandler({ capturedGeneration, chipHidden, chipThreshold, footerFixed, headerFixed, listGeneration });
1466
- const handleScrollToTop = useCallback10(() => {
1445
+ const handleScrollToTop = useCallback9(() => {
1467
1446
  const offset = pullSearchHeight ? -contentInset.top + pullSearchHeight : -contentInset.top;
1468
1447
  scrollView.current?.getScrollResponder()?.scrollTo({ y: offset, animated: true });
1469
1448
  }, [contentInset.top, pullSearchHeight]);
1470
- const handleContentSizeChange = useCallback10(
1449
+ const handleContentSizeChange = useCallback9(
1471
1450
  (w, h) => {
1472
1451
  if (onContentSizeChange) onContentSizeChange(w, h);
1473
1452
  },
1474
1453
  [onContentSizeChange]
1475
1454
  );
1476
- const refreshControl = useMemo7(() => onRefresh ? /* @__PURE__ */ jsx12(RefreshControl, { onRefresh, refreshing: refreshing ?? false }) : /* @__PURE__ */ jsx12(RefreshControl, {}), [onRefresh, refreshing]);
1477
- const nativeGesture = useMemo7(() => Gesture4.Native(), []);
1478
- const combinedGesture = useMemo7(() => gesture !== void 0 ? Gesture4.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
1455
+ const refreshControl = useMemo6(() => onRefresh ? /* @__PURE__ */ jsx11(RefreshControl, { onRefresh, refreshing: refreshing ?? false }) : /* @__PURE__ */ jsx11(RefreshControl, {}), [onRefresh, refreshing]);
1456
+ const nativeGesture = useMemo6(() => Gesture4.Native(), []);
1457
+ const combinedGesture = useMemo6(() => gesture !== void 0 ? Gesture4.Simultaneous(gesture, nativeGesture) : nativeGesture, [gesture, nativeGesture]);
1479
1458
  const detectorGesture = gesture !== void 0 ? combinedGesture : void 0;
1480
1459
  const content = /* @__PURE__ */ jsxs7(View7, { style: containerStyle, children: [
1481
- /* @__PURE__ */ jsx12(
1460
+ /* @__PURE__ */ jsx11(
1482
1461
  AnimatedSectionList,
1483
1462
  {
1484
1463
  ...passThroughProps,
@@ -1508,11 +1487,11 @@ var SectionListInner = ({ chipProps, chipThreshold, contentContainerStyle: exter
1508
1487
  },
1509
1488
  headerHeight !== null && headerHeight > 0 ? 1 : 0
1510
1489
  ),
1511
- hiddenHeader && /* @__PURE__ */ jsx12(View7, { pointerEvents: "none", style: styles8.measureContainer, children: hiddenHeader }),
1512
- /* @__PURE__ */ jsx12(ScrollViewChip, { chipProps, onChipPress, onPress: handleScrollToTop, style: chipStyle }),
1513
- usesCustomSticky && /* @__PURE__ */ jsx12(Animated7.View, { pointerEvents: "none", style: [styles8.stickyClip, clipStyle], children: activeIndex >= 0 && activeIndex < sections.length && /* @__PURE__ */ jsx12(Animated7.View, { style: [styles8.stickyOverlay, overlayStyle], children: renderSectionHeader({ section: sections[activeIndex] }) }) })
1490
+ hiddenHeader && /* @__PURE__ */ jsx11(View7, { pointerEvents: "none", style: styles8.measureContainer, children: hiddenHeader }),
1491
+ /* @__PURE__ */ jsx11(ScrollViewChip, { chipProps, onChipPress, onPress: handleScrollToTop, style: chipStyle }),
1492
+ usesCustomSticky && /* @__PURE__ */ jsx11(Animated7.View, { pointerEvents: "none", style: [styles8.stickyClip, clipStyle], children: activeIndex >= 0 && activeIndex < sections.length && /* @__PURE__ */ jsx11(Animated7.View, { style: [styles8.stickyOverlay, overlayStyle], children: renderSectionHeader({ section: sections[activeIndex] }) }) })
1514
1493
  ] });
1515
- return detectorGesture ? /* @__PURE__ */ jsx12(GestureDetector4, { gesture: detectorGesture, children: content }) : content;
1494
+ return detectorGesture ? /* @__PURE__ */ jsx11(GestureDetector4, { gesture: detectorGesture, children: content }) : content;
1516
1495
  };
1517
1496
  var styles8 = {
1518
1497
  measureContainer: { left: 0, opacity: 0, position: "absolute", right: 0, top: -9999 },
@@ -1529,8 +1508,7 @@ var useScrollView = () => {
1529
1508
  };
1530
1509
 
1531
1510
  // src/useScrollViewSettings.ts
1532
- import { useContext as useContext16 } from "react";
1533
- var useScrollViewSettings = () => useContext16(ScrollViewSettingsContext);
1511
+ var useScrollViewSettings = scrollViewUseSettings;
1534
1512
  export {
1535
1513
  CustomList,
1536
1514
  FlatList,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rific/scroll-view",
3
- "version": "0.7.1",
3
+ "version": "0.8.2",
4
4
  "description": "Blur styled scroll system for React Native. Floating headers/footers, keyboard awareness, and scroll-away chrome",
5
5
  "keywords": [
6
6
  "react-native",
@@ -62,10 +62,11 @@
62
62
  "prettier": "@infinitetoken/eslint-config/prettier",
63
63
  "devDependencies": {
64
64
  "@infinitetoken/eslint-config": "0.2.0",
65
- "@infinitetoken/jest-config": "^0.3.0",
66
- "@infinitetoken/tsconfig": "^0.4.1",
65
+ "@infinitetoken/jest-config": "^0.4.0",
66
+ "@infinitetoken/tsconfig": "^0.5.0",
67
67
  "@reduxjs/toolkit": "^2.12.0",
68
- "@rific/auto-paper": "^0.10.3",
68
+ "@rific/auto-paper": "^0.12.0",
69
+ "@rific/core": "^0.2.0",
69
70
  "@testing-library/dom": "^10.4.1",
70
71
  "@testing-library/react": "^16.3.2",
71
72
  "@types/jest": "^30.0.0",
@@ -90,7 +91,8 @@
90
91
  "typescript": "^6.0.3"
91
92
  },
92
93
  "peerDependencies": {
93
- "@rific/auto-paper": "^0.10.0",
94
+ "@rific/auto-paper": ">=0.10.0",
95
+ "@rific/core": "^0.2.0",
94
96
  "react": ">=19.0.0",
95
97
  "react-native": ">=0.83.0",
96
98
  "react-native-gesture-handler": ">=2.0.0 <3.0.0",
@@ -24,8 +24,13 @@ export const ScrollViewFooter = ({ children, style }: ScrollViewFooterProps) =>
24
24
  // recover it (the DOM node's true size never changed, so onLayout never fires again). Reading
25
25
  // through a ref sidesteps that: the effect itself only ever runs once, on mount/unmount, so its
26
26
  // cleanup fires exactly when it's meant to (a real unmount) rather than after every measurement.
27
+ // The mirror below has to be effect-based too, not a bare render-time assignment: writing to the
28
+ // ref during render is a React-render-purity violation (render can be discarded/replayed), so it's
29
+ // done in its own no-deps effect, which still re-runs on every commit and keeps the ref current.
27
30
  const setFooterHeightRef = useRef(setFooterHeight)
28
- setFooterHeightRef.current = setFooterHeight
31
+ useEffect(() => {
32
+ setFooterHeightRef.current = setFooterHeight
33
+ })
29
34
  useEffect(
30
35
  () => () => {
31
36
  setFooterHeightRef.current(null)
@@ -1,4 +1,4 @@
1
- import { createContext } from 'react'
1
+ import { createSettingsContext, type SettingsContextValue } from '@rific/core'
2
2
 
3
3
  export type ScrollViewSettings = {
4
4
  backActionFixed: boolean
@@ -16,12 +16,13 @@ export const defaultScrollViewSettings: ScrollViewSettings = {
16
16
  snapBack: false
17
17
  }
18
18
 
19
- export type ScrollViewSettingsContextType = {
20
- settings: ScrollViewSettings
21
- set: (patch: Partial<ScrollViewSettings>) => void
22
- }
19
+ export type ScrollViewSettingsContextType = SettingsContextValue<ScrollViewSettings>
20
+
21
+ // Single createSettingsContext() call, shared by ScrollViewSettingsProvider.tsx and
22
+ // useScrollViewSettings.ts (each just re-exports the relevant piece under its original name) so
23
+ // there's exactly one Context instance backing all three files, same as before this migration.
24
+ const settingsContext = createSettingsContext<ScrollViewSettings>(defaultScrollViewSettings)
23
25
 
24
- export const ScrollViewSettingsContext = createContext<ScrollViewSettingsContextType>({
25
- settings: defaultScrollViewSettings,
26
- set: () => {}
27
- })
26
+ export const ScrollViewSettingsContext = settingsContext.Context
27
+ export const scrollViewSettingsProvider = settingsContext.Provider
28
+ export const scrollViewUseSettings = settingsContext.useSettings
@@ -1,31 +1,7 @@
1
- import { type ReactNode, useCallback, useMemo, useState } from 'react'
1
+ import type { SettingsProviderProps } from '@rific/core'
2
2
 
3
- import { defaultScrollViewSettings, type ScrollViewSettings, ScrollViewSettingsContext } from './ScrollViewSettingsContext'
3
+ import { type ScrollViewSettings, scrollViewSettingsProvider } from './ScrollViewSettingsContext'
4
4
 
5
- export type ScrollViewSettingsProviderProps = {
6
- children: ReactNode
7
- onChange?: (settings: ScrollViewSettings) => void
8
- initialValue?: Partial<ScrollViewSettings>
9
- }
5
+ export type ScrollViewSettingsProviderProps = SettingsProviderProps<ScrollViewSettings>
10
6
 
11
- export const ScrollViewSettingsProvider = ({ children, onChange, initialValue }: ScrollViewSettingsProviderProps) => {
12
- const [settings, setSettings] = useState<ScrollViewSettings>(() => ({
13
- ...defaultScrollViewSettings,
14
- ...initialValue
15
- }))
16
-
17
- const set = useCallback(
18
- (patch: Partial<ScrollViewSettings>) => {
19
- setSettings((prev) => {
20
- const next = { ...prev, ...patch }
21
- onChange?.(next)
22
- return next
23
- })
24
- },
25
- [onChange]
26
- )
27
-
28
- const ctx = useMemo(() => ({ settings, set }), [settings, set])
29
-
30
- return <ScrollViewSettingsContext.Provider value={ctx}>{children}</ScrollViewSettingsContext.Provider>
31
- }
7
+ export const ScrollViewSettingsProvider = scrollViewSettingsProvider
@@ -1,22 +1,13 @@
1
- import { defaultScrollViewSettings, type ScrollViewSettings } from '../ScrollViewSettingsContext'
2
-
3
- // Hand-rolled slice — no @reduxjs/toolkit dependency. Action types and creator
4
- // behavior match the previous createSlice implementation exactly, so this works
5
- // with RTK stores, vanilla Redux, or any reducer-based state container.
6
- type PayloadAction<P> = { payload: P; type: string }
1
+ import { createSettingsSlice } from '@rific/core'
7
2
 
8
- const createAction = <P>(type: string) => {
9
- const actionCreator = (payload: P): PayloadAction<P> => ({ payload, type })
10
- actionCreator.type = type
11
- actionCreator.match = (action: { type: string }): action is PayloadAction<P> => action.type === type
12
- return actionCreator
13
- }
14
-
15
- const initialize = createAction<ScrollViewSettings>('scrollView/initialize')
3
+ import { defaultScrollViewSettings, type ScrollViewSettings } from '../ScrollViewSettingsContext'
16
4
 
17
- export const scrollViewActions = { initialize }
5
+ // scrollView has no per-field setters, just a full-replace initialize — matches the previous
6
+ // hand-rolled slice exactly (action type 'scrollView/initialize', full-state-replace behavior).
7
+ const scrollViewSlice = createSettingsSlice<ScrollViewSettings>('scrollView', {
8
+ initialState: defaultScrollViewSettings,
9
+ fieldSetters: []
10
+ })
18
11
 
19
- export const scrollViewReducer = (state: ScrollViewSettings = defaultScrollViewSettings, action: { type: string }): ScrollViewSettings => {
20
- if (initialize.match(action)) return action.payload
21
- return state
22
- }
12
+ export const scrollViewActions = scrollViewSlice.actions
13
+ export const scrollViewReducer = scrollViewSlice.reducer
@@ -1,5 +1,3 @@
1
- import { useContext } from 'react'
1
+ import { scrollViewUseSettings } from './ScrollViewSettingsContext'
2
2
 
3
- import { ScrollViewSettingsContext } from './ScrollViewSettingsContext'
4
-
5
- export const useScrollViewSettings = () => useContext(ScrollViewSettingsContext)
3
+ export const useScrollViewSettings = scrollViewUseSettings