@rific/scroll-view 0.4.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -1
- package/dist/index.d.mts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +69 -36
- package/dist/index.mjs +72 -39
- package/package.json +6 -5
- package/src/CustomList.tsx +9 -1
- package/src/PullSearch.tsx +5 -2
- package/src/ScrollView.tsx +16 -1
- package/src/ScrollViewContext.ts +3 -1
- package/src/ScrollViewFooter.tsx +35 -4
- package/src/ScrollViewHeader.tsx +25 -12
- package/src/ScrollViewProvider.tsx +10 -3
- package/src/SectionList.tsx +10 -2
- package/src/internal/HorizontalDots.tsx +13 -5
- package/src/internal/useScrollList.ts +37 -8
- package/src/internal/useStickyHeaders.ts +13 -3
- package/src/useScrollInit.ts +1 -0
package/README.md
CHANGED
|
@@ -71,12 +71,13 @@ Screen-level provider that owns header/footer state and scroll position. Must wr
|
|
|
71
71
|
|------|------|---------|-------------|
|
|
72
72
|
| `blur` | `boolean` | system | Enable frosted-glass backdrop on header/footer |
|
|
73
73
|
| `fixed` | `boolean` | `false` | Pin both header and footer (overrides `headerFixed`/`footerFixed`) |
|
|
74
|
+
| `footerAboveKeyboard` | `boolean` | `false` | With a fixed footer, float it above the keyboard instead of letting the keyboard cover it — see [Keyboard awareness](#keyboard-awareness) |
|
|
74
75
|
| `headerFixed` | `boolean` | `false` | Pin header; overrides settings default |
|
|
75
76
|
| `footerFixed` | `boolean` | `false` | Pin footer; overrides settings default |
|
|
76
77
|
| `snapBack` | `boolean` | `false` | Snap header and footer back when scrolling up |
|
|
77
78
|
| `snapBackHeader` | `boolean` | — | Override `snapBack` for header only |
|
|
78
79
|
| `snapBackFooter` | `boolean` | — | Override `snapBack` for footer only |
|
|
79
|
-
| `tabBarHeight` | `number` | `
|
|
80
|
+
| `tabBarHeight` | `number` | `0` | Extra bottom inset reserved for a host app's own persistent tab bar (added on top of the safe-area inset, independent of any `ScrollViewFooter`) |
|
|
80
81
|
|
|
81
82
|
---
|
|
82
83
|
|
|
@@ -269,6 +270,45 @@ export default function SearchScreen() {
|
|
|
269
270
|
|
|
270
271
|
---
|
|
271
272
|
|
|
273
|
+
## Keyboard awareness
|
|
274
|
+
|
|
275
|
+
Pass `keyboardAware` to any scroll component (`ScrollView`, `FlatList`, `SectionList`, `CustomList`) to add the keyboard's height to the bottom content inset, so a focused field near the bottom of the content stays above the keyboard instead of getting hidden behind it.
|
|
276
|
+
|
|
277
|
+
```tsx
|
|
278
|
+
<ScrollViewProvider>
|
|
279
|
+
<ScrollViewHeader title="Edit profile" />
|
|
280
|
+
<ScrollView keyboardAware>
|
|
281
|
+
<TextInput label="Name" />
|
|
282
|
+
<TextInput label="Bio" multiline />
|
|
283
|
+
</ScrollView>
|
|
284
|
+
</ScrollViewProvider>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
By default, a fixed `ScrollViewFooter` doesn't follow the keyboard — it stays pinned to the screen bottom and the keyboard simply covers it. If the footer holds something the user needs while typing (a submit button, say), set `footerAboveKeyboard` on `ScrollViewProvider` so the footer floats above the keyboard instead, reachable without dismissing it first:
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
<ScrollViewProvider footerFixed footerAboveKeyboard>
|
|
291
|
+
<ScrollViewHeader title="Edit profile" />
|
|
292
|
+
<ScrollView keyboardAware>
|
|
293
|
+
<TextInput label="Name" />
|
|
294
|
+
<TextInput label="Bio" multiline />
|
|
295
|
+
</ScrollView>
|
|
296
|
+
<ScrollViewFooter>
|
|
297
|
+
<Button mode="contained" onPress={handleSubmit}>Save</Button>
|
|
298
|
+
</ScrollViewFooter>
|
|
299
|
+
</ScrollViewProvider>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
`footerAboveKeyboard` only has an effect when the footer is fixed (`footerFixed`) — a footer that scrolls away with content has nothing to reserve keyboard space for. Always pair it with `keyboardAware: true` on any scroll component that could have a focused input while it's visible. Content always reserves space for the current footer height regardless of `keyboardAware` (so a fixed footer never overlaps it) — and while floating, that height already includes the keyboard, so a list with `keyboardAware: false` ends up reserving keyboard space anyway, just indirectly through the footer rather than directly. There's no useful configuration where you'd want the footer reachable above the keyboard but *not* want that same list's own content clear of it too, so don't rely on `keyboardAware: false` to opt a list out of this while `footerAboveKeyboard` is on — it won't.
|
|
303
|
+
|
|
304
|
+
Floating is done by growing the footer's own container rather than translating it, so its `BlurView` backdrop always stays sealed against the true physical screen bottom — nothing shows through beneath it, including at the keyboard's rounded top corners.
|
|
305
|
+
|
|
306
|
+
While floating above an open keyboard, the footer also drops its safe-area bottom inset — it's no longer sitting at the physical screen edge, so that padding would just be dead space under its content. As the keyboard closes, the inset ramps back in continuously over the last bit of its travel rather than snapping back once it's fully closed, so the content settles at the safe-area line smoothly instead of dropping to the physical bottom edge and correcting back up.
|
|
307
|
+
|
|
308
|
+
Keyboard awareness is native-only — `useKeyboardInset` (and therefore `keyboardAware`/`footerAboveKeyboard`) always resolves to `0` height on web.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
272
312
|
## Hooks
|
|
273
313
|
|
|
274
314
|
### `useScrollView`
|
package/dist/index.d.mts
CHANGED
|
@@ -121,6 +121,7 @@ declare const ScrollView: typeof ScrollViewInner;
|
|
|
121
121
|
|
|
122
122
|
type ScrollViewContextType = {
|
|
123
123
|
blur: boolean;
|
|
124
|
+
footerAboveKeyboard: boolean;
|
|
124
125
|
footerHeight: number;
|
|
125
126
|
footerHeightShared: SharedValue<number>;
|
|
126
127
|
footerFixed: boolean;
|
|
@@ -158,6 +159,7 @@ type ScrollViewHeaderProps = {
|
|
|
158
159
|
actionSize?: number;
|
|
159
160
|
actionStyle?: ViewStyle;
|
|
160
161
|
backAction?: () => void;
|
|
162
|
+
backActionAccessibilityLabel?: string;
|
|
161
163
|
backActionFixed?: boolean;
|
|
162
164
|
caption?: string;
|
|
163
165
|
centerContent?: ReactNode;
|
|
@@ -169,12 +171,13 @@ type ScrollViewHeaderProps = {
|
|
|
169
171
|
trailingAction?: ReactNode;
|
|
170
172
|
trailingActionFixed?: boolean;
|
|
171
173
|
};
|
|
172
|
-
declare const ScrollViewHeader: ({ actionSize, actionStyle, backAction, backActionFixed, caption, centerContent, children, iconSize, style, title, topInset, trailingAction, trailingActionFixed }: ScrollViewHeaderProps) => react.JSX.Element;
|
|
174
|
+
declare const ScrollViewHeader: ({ actionSize, actionStyle, backAction, backActionAccessibilityLabel, backActionFixed, caption, centerContent, children, iconSize, style, title, topInset, trailingAction, trailingActionFixed }: ScrollViewHeaderProps) => react.JSX.Element;
|
|
173
175
|
|
|
174
176
|
type ScrollViewProviderProps = {
|
|
175
177
|
blur?: boolean;
|
|
176
178
|
children: ReactNode;
|
|
177
179
|
fixed?: boolean;
|
|
180
|
+
footerAboveKeyboard?: boolean;
|
|
178
181
|
footerFixed?: boolean;
|
|
179
182
|
headerFixed?: boolean;
|
|
180
183
|
snapBack?: boolean;
|
|
@@ -182,7 +185,7 @@ type ScrollViewProviderProps = {
|
|
|
182
185
|
snapBackHeader?: boolean;
|
|
183
186
|
tabBarHeight?: number;
|
|
184
187
|
};
|
|
185
|
-
declare const ScrollViewProvider: ({ blur, children, fixed, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight }: ScrollViewProviderProps) => react.JSX.Element;
|
|
188
|
+
declare const ScrollViewProvider: ({ blur, children, fixed, footerAboveKeyboard, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight }: ScrollViewProviderProps) => react.JSX.Element;
|
|
186
189
|
|
|
187
190
|
type ScrollViewSettingsProviderProps = {
|
|
188
191
|
children: ReactNode;
|
package/dist/index.d.ts
CHANGED
|
@@ -121,6 +121,7 @@ declare const ScrollView: typeof ScrollViewInner;
|
|
|
121
121
|
|
|
122
122
|
type ScrollViewContextType = {
|
|
123
123
|
blur: boolean;
|
|
124
|
+
footerAboveKeyboard: boolean;
|
|
124
125
|
footerHeight: number;
|
|
125
126
|
footerHeightShared: SharedValue<number>;
|
|
126
127
|
footerFixed: boolean;
|
|
@@ -158,6 +159,7 @@ type ScrollViewHeaderProps = {
|
|
|
158
159
|
actionSize?: number;
|
|
159
160
|
actionStyle?: ViewStyle;
|
|
160
161
|
backAction?: () => void;
|
|
162
|
+
backActionAccessibilityLabel?: string;
|
|
161
163
|
backActionFixed?: boolean;
|
|
162
164
|
caption?: string;
|
|
163
165
|
centerContent?: ReactNode;
|
|
@@ -169,12 +171,13 @@ type ScrollViewHeaderProps = {
|
|
|
169
171
|
trailingAction?: ReactNode;
|
|
170
172
|
trailingActionFixed?: boolean;
|
|
171
173
|
};
|
|
172
|
-
declare const ScrollViewHeader: ({ actionSize, actionStyle, backAction, backActionFixed, caption, centerContent, children, iconSize, style, title, topInset, trailingAction, trailingActionFixed }: ScrollViewHeaderProps) => react.JSX.Element;
|
|
174
|
+
declare const ScrollViewHeader: ({ actionSize, actionStyle, backAction, backActionAccessibilityLabel, backActionFixed, caption, centerContent, children, iconSize, style, title, topInset, trailingAction, trailingActionFixed }: ScrollViewHeaderProps) => react.JSX.Element;
|
|
173
175
|
|
|
174
176
|
type ScrollViewProviderProps = {
|
|
175
177
|
blur?: boolean;
|
|
176
178
|
children: ReactNode;
|
|
177
179
|
fixed?: boolean;
|
|
180
|
+
footerAboveKeyboard?: boolean;
|
|
178
181
|
footerFixed?: boolean;
|
|
179
182
|
headerFixed?: boolean;
|
|
180
183
|
snapBack?: boolean;
|
|
@@ -182,7 +185,7 @@ type ScrollViewProviderProps = {
|
|
|
182
185
|
snapBackHeader?: boolean;
|
|
183
186
|
tabBarHeight?: number;
|
|
184
187
|
};
|
|
185
|
-
declare const ScrollViewProvider: ({ blur, children, fixed, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight }: ScrollViewProviderProps) => react.JSX.Element;
|
|
188
|
+
declare const ScrollViewProvider: ({ blur, children, fixed, footerAboveKeyboard, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight }: ScrollViewProviderProps) => react.JSX.Element;
|
|
186
189
|
|
|
187
190
|
type ScrollViewSettingsProviderProps = {
|
|
188
191
|
children: ReactNode;
|
package/dist/index.js
CHANGED
|
@@ -87,6 +87,7 @@ var import_react_native_reanimated3 = require("react-native-reanimated");
|
|
|
87
87
|
var import_react = require("react");
|
|
88
88
|
var ScrollViewContext = (0, import_react.createContext)({
|
|
89
89
|
blur: true,
|
|
90
|
+
footerAboveKeyboard: false,
|
|
90
91
|
footerHeight: 0,
|
|
91
92
|
footerHeightShared: null,
|
|
92
93
|
footerFixed: false,
|
|
@@ -116,7 +117,7 @@ var ScrollViewContext = (0, import_react.createContext)({
|
|
|
116
117
|
},
|
|
117
118
|
snapBackFooterShared: null,
|
|
118
119
|
snapBackHeaderShared: null,
|
|
119
|
-
tabBarHeight:
|
|
120
|
+
tabBarHeight: 0
|
|
120
121
|
});
|
|
121
122
|
|
|
122
123
|
// src/useScrollInit.ts
|
|
@@ -424,17 +425,21 @@ var useKeyboardInset = import_react_native4.Platform.OS === "web" ? useKeyboardI
|
|
|
424
425
|
var ZERO_INSET = { bottom: 0, top: 0 };
|
|
425
426
|
var ZERO_OFFSET = { x: 0, y: 0 };
|
|
426
427
|
var CHIP_SLIDE = 48;
|
|
427
|
-
function useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, isHorizontal, keyboardAware, pullSearchHeight, style } = {}) {
|
|
428
|
+
function useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, hideUntilMeasured, isHorizontal, keyboardAware, pullSearchHeight, style } = {}) {
|
|
428
429
|
const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
|
|
429
430
|
const keyboardHeight = useKeyboardInset();
|
|
430
|
-
const { footerHeight, footerFixed: contextFooterFixed, headerHeight, headerFixed: contextHeaderFixed, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared } = (0, import_react5.useContext)(ScrollViewContext);
|
|
431
|
+
const { footerAboveKeyboard, footerHeight, footerFixed: contextFooterFixed, headerHeight, headerFixed: contextHeaderFixed, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared, tabBarHeight } = (0, import_react5.useContext)(ScrollViewContext);
|
|
431
432
|
const headerFixed = isHorizontal ? true : headerFixedProp ?? contextHeaderFixed;
|
|
432
433
|
const footerFixed = isHorizontal ? true : footerFixedProp ?? contextFooterFixed;
|
|
433
434
|
(0, import_react5.useEffect)(() => {
|
|
434
435
|
pullSearchHeightShared.value = usesContentInset ? pullSearchHeight ?? 0 : 0;
|
|
435
436
|
}, [pullSearchHeight, pullSearchHeightShared]);
|
|
436
|
-
const containerStyle = (0, import_react5.useMemo)(() => headerHeight === null ? [{ flex: 1, opacity: 0 }, style] : [import_react_native5.StyleSheet.absoluteFill, style], [headerHeight, style]);
|
|
437
|
-
const insetGeometry = (0, import_react5.useMemo)(() =>
|
|
437
|
+
const containerStyle = (0, import_react5.useMemo)(() => headerHeight === null ? [{ flex: 1, opacity: hideUntilMeasured ? 0 : 1 }, style] : [import_react_native5.StyleSheet.absoluteFill, style], [headerHeight, hideUntilMeasured, style]);
|
|
438
|
+
const insetGeometry = (0, import_react5.useMemo)(() => {
|
|
439
|
+
const footerReserve = footerFixed ? footerHeight || insets.bottom : insets.bottom;
|
|
440
|
+
const bottom = (!keyboardAware || footerFixed && footerAboveKeyboard ? footerReserve : Math.max(footerReserve, keyboardHeight)) + tabBarHeight;
|
|
441
|
+
return { bottom, top: headerHeight ?? 0 };
|
|
442
|
+
}, [footerAboveKeyboard, footerFixed, footerHeight, insets.bottom, tabBarHeight, headerHeight, keyboardAware, keyboardHeight]);
|
|
438
443
|
const contentInset = usesContentInset ? insetGeometry : ZERO_INSET;
|
|
439
444
|
const contentPadding = (0, import_react5.useMemo)(() => usesContentInset || isHorizontal ? null : { paddingBottom: insetGeometry.bottom, paddingTop: insetGeometry.top }, [insetGeometry, isHorizontal]);
|
|
440
445
|
const [startedWithHeader] = (0, import_react5.useState)(headerHeight !== null);
|
|
@@ -460,7 +465,7 @@ function useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedP
|
|
|
460
465
|
top,
|
|
461
466
|
transform: [{ translateY: chipHidden.value ? (0, import_react_native_reanimated5.withTiming)(-CHIP_SLIDE) : (0, import_react_native_reanimated5.withTiming)(0) }]
|
|
462
467
|
};
|
|
463
|
-
}, [isHorizontal, headerFixed, headerHeight, insets.top]);
|
|
468
|
+
}, [isHorizontal, headerFixed, headerHeight, insets.top, chipHidden, snapBackHeaderShared, headerOffset, scrollPosition, pullSearchHeightShared]);
|
|
464
469
|
return { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, contentPadding, footerFixed, headerFixed, headerHeight, insets, isHorizontal: isHorizontal ?? false };
|
|
465
470
|
}
|
|
466
471
|
|
|
@@ -473,6 +478,10 @@ var CustomListInner = ({ chipProps, chipThreshold, component: List, renderFilter
|
|
|
473
478
|
const capturedGeneration = (0, import_react_native_reanimated6.useSharedValue)(-1);
|
|
474
479
|
(0, import_react6.useLayoutEffect)(() => {
|
|
475
480
|
const generation = listGeneration.value;
|
|
481
|
+
if (import_react_native6.Platform.OS === "web") {
|
|
482
|
+
capturedGeneration.value = generation;
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
476
485
|
(0, import_react_native_reanimated6.runOnUI)((gen) => {
|
|
477
486
|
"worklet";
|
|
478
487
|
capturedGeneration.value = gen;
|
|
@@ -570,7 +579,7 @@ var Dot = ({ activeColor, index, inactiveColor, pageWidth, scrollPosition }) =>
|
|
|
570
579
|
const size = DOT_FULL + (DOT_SMALL - DOT_FULL) * t;
|
|
571
580
|
const backgroundColor = (0, import_react_native_reanimated7.interpolateColor)(t, [0, 1], [activeColor, inactiveColor]);
|
|
572
581
|
return { backgroundColor, borderRadius: size / 2, height: size, width: size };
|
|
573
|
-
});
|
|
582
|
+
}, [scrollPosition, pageWidth, index, activeColor, inactiveColor]);
|
|
574
583
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles3.dotContainer, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_reanimated7.default.View, { style: circleStyle }) });
|
|
575
584
|
};
|
|
576
585
|
var HorizontalDots = ({ total }) => {
|
|
@@ -581,15 +590,18 @@ var HorizontalDots = ({ total }) => {
|
|
|
581
590
|
const insetsBottom = insets.bottom;
|
|
582
591
|
const activeColor = theme.colors.primary;
|
|
583
592
|
const inactiveColor = theme.colors.outlineVariant;
|
|
584
|
-
const pillContainerStyle = (0, import_react_native_reanimated7.useAnimatedStyle)(
|
|
585
|
-
|
|
586
|
-
|
|
593
|
+
const pillContainerStyle = (0, import_react_native_reanimated7.useAnimatedStyle)(
|
|
594
|
+
() => ({
|
|
595
|
+
bottom: Math.max(footerHeightShared.value, insetsBottom) + 8
|
|
596
|
+
}),
|
|
597
|
+
[footerHeightShared, insetsBottom]
|
|
598
|
+
);
|
|
587
599
|
const rowStyle = (0, import_react_native_reanimated7.useAnimatedStyle)(() => {
|
|
588
600
|
const page = scrollPosition.value / width;
|
|
589
601
|
const maxOffset = Math.max(0, (total - CLIP_COUNT) * DOT_STEP);
|
|
590
602
|
const offset = Math.max(0, Math.min((page - (CLIP_COUNT - 1) / 2) * DOT_STEP, maxOffset));
|
|
591
603
|
return { transform: [{ translateX: -offset }] };
|
|
592
|
-
});
|
|
604
|
+
}, [scrollPosition, width, total]);
|
|
593
605
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_reanimated7.default.View, { pointerEvents: "none", style: [styles3.pillContainer, pillContainerStyle], children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles3.pill, children: [
|
|
594
606
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_auto_paper2.BlurView, { blur, style: import_react_native7.StyleSheet.absoluteFill }),
|
|
595
607
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles3.dotsClip, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_reanimated7.default.View, { style: [styles3.dotsRow, rowStyle], children: Array.from({ length: total }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dot, { activeColor, index: i, inactiveColor, pageWidth: width, scrollPosition }, i)) }) })
|
|
@@ -896,7 +908,10 @@ var PullSearch = (0, import_react10.forwardRef)(function PullSearch2({ debounce,
|
|
|
896
908
|
(isHidden, wasHidden) => {
|
|
897
909
|
if (isHidden && !wasHidden) (0, import_react_native_reanimated9.runOnJS)(blurInput)();
|
|
898
910
|
},
|
|
899
|
-
|
|
911
|
+
// scrollPosition has to be listed too, not just read — see useStickyHeaders' useAnimatedReaction
|
|
912
|
+
// for why: on web, without reanimated's Babel plugin active, an unlisted SharedValue mutation
|
|
913
|
+
// never re-triggers this reaction (confirmed empirically elsewhere in this package).
|
|
914
|
+
[barHeight, headerHeight, blurInput, scrollPosition]
|
|
900
915
|
);
|
|
901
916
|
const handleClear = (0, import_react10.useCallback)(() => {
|
|
902
917
|
setValue("");
|
|
@@ -927,7 +942,7 @@ var PullSearch = (0, import_react10.forwardRef)(function PullSearch2({ debounce,
|
|
|
927
942
|
const showY = -h;
|
|
928
943
|
const hideY = -h + barHeight;
|
|
929
944
|
return { opacity: (0, import_react_native_reanimated9.interpolate)(scrollPosition.value, [showY, hideY], [1, 0], import_react_native_reanimated9.Extrapolation.CLAMP) };
|
|
930
|
-
}, [barHeight, headerHeight]);
|
|
945
|
+
}, [barHeight, headerHeight, scrollPosition]);
|
|
931
946
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_reanimated9.default.View, { onLayout: handleLayout, style: [styles5.container, animatedStyle], children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_paper2.Searchbar, { autoCorrect: false, onChangeText: (text) => setValue((text || "").trimStart()), onClearIconPress: handleClear, placeholder, placeholderTextColor: theme.colors.onSurfaceVariant, ref: inputRef, spellCheck: false, style: styles5.input, value }) });
|
|
932
947
|
});
|
|
933
948
|
var styles5 = import_react_native9.StyleSheet.create({
|
|
@@ -977,6 +992,10 @@ var ScrollViewInner = ({ chipProps, chipThreshold, children, contentContainerSty
|
|
|
977
992
|
const capturedGeneration = (0, import_react_native_reanimated10.useSharedValue)(-1);
|
|
978
993
|
(0, import_react12.useLayoutEffect)(() => {
|
|
979
994
|
const generation = listGeneration.value;
|
|
995
|
+
if (import_react_native10.Platform.OS === "web") {
|
|
996
|
+
capturedGeneration.value = generation;
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
980
999
|
(0, import_react_native_reanimated10.runOnUI)((gen) => {
|
|
981
1000
|
"worklet";
|
|
982
1001
|
capturedGeneration.value = gen;
|
|
@@ -1041,8 +1060,9 @@ var import_react_native_reanimated11 = __toESM(require("react-native-reanimated"
|
|
|
1041
1060
|
var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
|
|
1042
1061
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1043
1062
|
var ScrollViewFooter = ({ children, style }) => {
|
|
1044
|
-
const { blur, footerHeight, footerFixed, footerOffset, headerHeightShared, pullSearchHeightShared, scrollPosition, setFooterHeight, snapBackFooterShared } = (0, import_react13.useContext)(ScrollViewContext);
|
|
1063
|
+
const { blur, footerAboveKeyboard, footerHeight, footerFixed, footerOffset, headerHeightShared, pullSearchHeightShared, scrollPosition, setFooterHeight, snapBackFooterShared } = (0, import_react13.useContext)(ScrollViewContext);
|
|
1045
1064
|
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
1065
|
+
const keyboardHeight = useKeyboardInset();
|
|
1046
1066
|
(0, import_react13.useEffect)(
|
|
1047
1067
|
() => () => {
|
|
1048
1068
|
setFooterHeight(0);
|
|
@@ -1062,10 +1082,12 @@ var ScrollViewFooter = ({ children, style }) => {
|
|
|
1062
1082
|
const effective = scrollPosition.value + headerHeightShared.value - pullSearchHeightShared.value;
|
|
1063
1083
|
if (effective <= 0) return { transform: [{ translateY: 0 }] };
|
|
1064
1084
|
return { transform: [{ translateY: Math.min(effective, footerHeight) }] };
|
|
1065
|
-
}, [footerHeight, footerFixed]);
|
|
1066
|
-
|
|
1085
|
+
}, [footerHeight, footerFixed, headerHeightShared, pullSearchHeightShared, scrollPosition, snapBackFooterShared, footerOffset]);
|
|
1086
|
+
const containerPaddingBottom = footerFixed && footerAboveKeyboard ? keyboardHeight : 0;
|
|
1087
|
+
const rowPaddingBottom = footerFixed && footerAboveKeyboard ? Math.max(insets.bottom - keyboardHeight, 0) : insets.bottom;
|
|
1088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native_reanimated11.default.View, { onLayout: handleLayout, pointerEvents: "box-none", style: [styles6.footer, { paddingBottom: containerPaddingBottom }, footerStyle], children: [
|
|
1067
1089
|
footerHeight > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_auto_paper3.BlurView, { blur, style: import_react_native11.StyleSheet.absoluteFill }),
|
|
1068
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: [styles6.row, { paddingBottom:
|
|
1090
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: [styles6.row, { paddingBottom: rowPaddingBottom }, style], children })
|
|
1069
1091
|
] });
|
|
1070
1092
|
};
|
|
1071
1093
|
var styles6 = import_react_native11.StyleSheet.create({
|
|
@@ -1082,7 +1104,7 @@ var import_react_native_reanimated12 = __toESM(require("react-native-reanimated"
|
|
|
1082
1104
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
1083
1105
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1084
1106
|
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_paper3.Surface, { style: import_react_native12.StyleSheet.absoluteFill, elevation: 1, children: null }) });
|
|
1085
|
-
var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionFixed, caption, centerContent, children, iconSize, style, title, topInset = true, trailingAction, trailingActionFixed = true }) => {
|
|
1107
|
+
var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionAccessibilityLabel, backActionFixed, caption, centerContent, children, iconSize, style, title, topInset = true, trailingAction, trailingActionFixed = true }) => {
|
|
1086
1108
|
const { blur, headerHeight, headerFixed, headerOffset, progress, progressing, pullSearchHeightShared, scrollPosition, setHeaderHeight, snapBackHeaderShared } = (0, import_react14.useContext)(ScrollViewContext);
|
|
1087
1109
|
const { settings } = (0, import_react14.useContext)(ScrollViewSettingsContext);
|
|
1088
1110
|
const effectiveBackActionFixed = backActionFixed ?? settings.backActionFixed;
|
|
@@ -1096,35 +1118,36 @@ var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionFi
|
|
|
1096
1118
|
}) => {
|
|
1097
1119
|
if (headerHeight !== height) setHeaderHeight(height);
|
|
1098
1120
|
};
|
|
1121
|
+
const actionMargin = 4;
|
|
1122
|
+
const contentMinHeight = actionSize + 2 * actionMargin;
|
|
1123
|
+
const unmeasuredHeight = top + contentMinHeight;
|
|
1099
1124
|
const translateStyle = (0, import_react_native_reanimated12.useAnimatedStyle)(() => {
|
|
1100
1125
|
if (headerFixed) return { transform: [{ translateY: 0 }] };
|
|
1101
1126
|
if (snapBackHeaderShared.value) return { transform: [{ translateY: headerOffset.value }] };
|
|
1102
1127
|
const effective = scrollPosition.value + (headerHeight ?? 0) - pullSearchHeightShared.value;
|
|
1103
1128
|
if (effective <= 0) return { transform: [{ translateY: 0 }] };
|
|
1104
1129
|
return { transform: [{ translateY: -effective }] };
|
|
1105
|
-
}, [headerFixed, headerHeight]);
|
|
1130
|
+
}, [headerFixed, headerHeight, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared]);
|
|
1106
1131
|
const blurStyle = (0, import_react_native_reanimated12.useAnimatedStyle)(() => {
|
|
1132
|
+
if (headerHeight === null) return { height: unmeasuredHeight };
|
|
1107
1133
|
if (!headerHeight) return { height: 0 };
|
|
1108
1134
|
if (headerFixed) return { height: headerHeight };
|
|
1109
|
-
const
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
}, [headerFixed, headerHeight, top]);
|
|
1135
|
+
const translateY = snapBackHeaderShared.value ? headerOffset.value : -Math.max(0, scrollPosition.value + headerHeight - pullSearchHeightShared.value);
|
|
1136
|
+
return { height: Math.max(headerHeight + translateY, top) };
|
|
1137
|
+
}, [headerFixed, headerHeight, top, unmeasuredHeight, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared]);
|
|
1113
1138
|
const progressStyle = (0, import_react_native_reanimated12.useAnimatedStyle)(() => {
|
|
1114
1139
|
const h = headerHeight ?? 0;
|
|
1115
1140
|
if (headerFixed) return { top: h };
|
|
1116
1141
|
const slide = snapBackHeaderShared.value ? -headerOffset.value : Math.max(0, scrollPosition.value + h - pullSearchHeightShared.value);
|
|
1117
1142
|
return { top: Math.max(h - slide, top) };
|
|
1118
|
-
}, [headerFixed, headerHeight, top]);
|
|
1119
|
-
const actionMargin = 4;
|
|
1120
|
-
const contentMinHeight = actionSize + 2 * actionMargin;
|
|
1143
|
+
}, [headerFixed, headerHeight, top, headerOffset, pullSearchHeightShared, scrollPosition, snapBackHeaderShared]);
|
|
1121
1144
|
const actionTop = top + actionMargin;
|
|
1122
1145
|
const buttonStyle = { borderRadius: actionSize, height: actionSize, margin: 0, width: actionSize };
|
|
1123
1146
|
const actionShadow = { borderRadius: actionSize / 2, elevation: 2, shadowColor: "#000", shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.15, shadowRadius: 2 };
|
|
1124
1147
|
const leadingStyle = { alignItems: "center", height: actionSize, justifyContent: "center", left: actionMargin, position: "absolute", top: actionTop, width: actionSize, zIndex: 3, ...actionShadow };
|
|
1125
1148
|
const trailingStyle = { alignItems: "center", height: actionSize, justifyContent: "center", position: "absolute", right: actionMargin, top: actionTop, width: actionSize, zIndex: 3, ...actionShadow };
|
|
1126
1149
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1127
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_reanimated12.default.View, { pointerEvents: "none", style: [styles7.blur, blurStyle], children: headerHeight !==
|
|
1150
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_reanimated12.default.View, { pointerEvents: "none", style: [styles7.blur, blurStyle], children: headerHeight !== 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_auto_paper4.BlurView, { blur, style: [styles7.blurInner, { height: headerHeight ?? unmeasuredHeight }] }) }),
|
|
1128
1151
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_reanimated12.default.View, { onLayout: handleLayout, pointerEvents: "box-none", style: [headerHeight === null ? styles7.headerInit : styles7.header, translateStyle], children: [
|
|
1129
1152
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: [{ paddingTop: top }, style], children: children ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native12.View, { style: [styles7.content, { minHeight: contentMinHeight }], children: [
|
|
1130
1153
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: styles7.side }),
|
|
@@ -1139,10 +1162,10 @@ var ScrollViewHeader = ({ actionSize = 48, actionStyle, backAction, backActionFi
|
|
|
1139
1162
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_reanimated12.default.View, { pointerEvents: "none", style: [styles7.progress, progressStyle], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper3.ProgressBar, { indeterminate: progress === null, visible: progressing, progress: progress ?? void 0 }) }),
|
|
1140
1163
|
backAction && (effectiveBackActionFixed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_reanimated12.default.View, { style: leadingStyle, children: [
|
|
1141
1164
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
1142
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper3.Appbar.BackAction, { onPress: backAction, size: iconSize ?? actionSize / 2, style: buttonStyle })
|
|
1165
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper3.Appbar.BackAction, { accessibilityLabel: backActionAccessibilityLabel, onPress: backAction, size: iconSize ?? actionSize / 2, style: buttonStyle })
|
|
1143
1166
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_reanimated12.default.View, { style: [leadingStyle, translateStyle], children: [
|
|
1144
1167
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
1145
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper3.Appbar.BackAction, { onPress: backAction, size: iconSize ?? actionSize / 2, style: buttonStyle })
|
|
1168
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_paper3.Appbar.BackAction, { accessibilityLabel: backActionAccessibilityLabel, onPress: backAction, size: iconSize ?? actionSize / 2, style: buttonStyle })
|
|
1146
1169
|
] })),
|
|
1147
1170
|
trailingAction && (trailingActionFixed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native12.View, { style: trailingStyle, children: [
|
|
1148
1171
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ActionBg, { blur, style: actionStyle }),
|
|
@@ -1175,7 +1198,7 @@ var import_react15 = require("react");
|
|
|
1175
1198
|
var import_react_native13 = require("react-native");
|
|
1176
1199
|
var import_react_native_reanimated13 = require("react-native-reanimated");
|
|
1177
1200
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1178
|
-
var ScrollViewProvider = ({ blur, children, fixed = false, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight =
|
|
1201
|
+
var ScrollViewProvider = ({ blur, children, fixed = false, footerAboveKeyboard = false, footerFixed, headerFixed, snapBack, snapBackFooter, snapBackHeader, tabBarHeight = 0 }) => {
|
|
1179
1202
|
const { settings } = (0, import_react15.useContext)(ScrollViewSettingsContext);
|
|
1180
1203
|
const effectiveBlur = (0, import_auto_paper5.useBlur)(blur);
|
|
1181
1204
|
const effectiveSnapBack = snapBack ?? settings.snapBack;
|
|
@@ -1201,10 +1224,11 @@ var ScrollViewProvider = ({ blur, children, fixed = false, footerFixed, headerFi
|
|
|
1201
1224
|
}, [effectiveSnapBack, effectiveSnapBackFooter, effectiveSnapBackHeader, snapBackFooterShared, snapBackHeaderShared]);
|
|
1202
1225
|
const setHeaderHeight = (0, import_react15.useCallback)(
|
|
1203
1226
|
(h) => {
|
|
1227
|
+
if (h === 0 && headerHeight) return;
|
|
1204
1228
|
setHeaderHeightState(h);
|
|
1205
1229
|
headerHeightShared.value = h ?? 0;
|
|
1206
1230
|
},
|
|
1207
|
-
[headerHeightShared]
|
|
1231
|
+
[headerHeight, headerHeightShared]
|
|
1208
1232
|
);
|
|
1209
1233
|
const onListUnmount = (0, import_react15.useCallback)(() => {
|
|
1210
1234
|
listGeneration.value += 1;
|
|
@@ -1229,7 +1253,7 @@ var ScrollViewProvider = ({ blur, children, fixed = false, footerFixed, headerFi
|
|
|
1229
1253
|
const scrollHeight = (0, import_react15.useMemo)(() => import_react_native13.Dimensions.get("window").height - (headerHeight ?? 0) - footerHeight, [headerHeight, footerHeight]);
|
|
1230
1254
|
const effectiveHeaderFixed = fixed || (headerFixed ?? settings.headerFixed);
|
|
1231
1255
|
const effectiveFooterFixed = fixed || (footerFixed ?? settings.footerFixed);
|
|
1232
|
-
const value = (0, import_react15.useMemo)(() => ({ blur: effectiveBlur, footerHeight, footerHeightShared, footerFixed: effectiveFooterFixed, footerOffset, headerHeight, headerHeightShared, headerFixed: effectiveHeaderFixed, headerOffset, jsListGeneration, listGeneration, onJsListUnmount, onListUnmount, progress, pullSearchHeightShared, progressing, scrollHeight, scrollPosition, setFooterHeight, setHeaderHeight, setProgress, setProgressing, snapBackFooterShared, snapBackHeaderShared, tabBarHeight }), [effectiveBlur, effectiveFooterFixed, effectiveHeaderFixed, footerHeight, footerHeightShared, footerOffset, headerHeight, headerHeightShared, headerOffset, jsListGeneration, listGeneration, onJsListUnmount, onListUnmount, progress, pullSearchHeightShared, progressing, scrollHeight, scrollPosition, setFooterHeight, setHeaderHeight, snapBackFooterShared, snapBackHeaderShared, tabBarHeight]);
|
|
1256
|
+
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]);
|
|
1233
1257
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ScrollViewContext.Provider, { value, children });
|
|
1234
1258
|
};
|
|
1235
1259
|
|
|
@@ -1304,7 +1328,12 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
1304
1328
|
(curr, prev) => {
|
|
1305
1329
|
if (curr !== prev) (0, import_react_native_reanimated14.runOnJS)(setActiveIndex)(curr);
|
|
1306
1330
|
},
|
|
1307
|
-
|
|
1331
|
+
// Same web-only reanimated gap as useAnimatedStyle elsewhere in this file: this "prepare"
|
|
1332
|
+
// function's own SharedValue reads (sectionYPositions, headerHeightShared, scrollPosition,
|
|
1333
|
+
// snapBackHeaderShared, headerOffset, pullSearchHeightShared) need to be listed explicitly too
|
|
1334
|
+
// — confirmed empirically that without them, useAnimatedReaction re-evaluates once on mount and
|
|
1335
|
+
// then never again on web, permanently freezing activeIndex/the active sticky section.
|
|
1336
|
+
[enabled, headerFixed, insetsTop, sectionYPositions, headerHeightShared, scrollPosition, snapBackHeaderShared, headerOffset, pullSearchHeightShared]
|
|
1308
1337
|
);
|
|
1309
1338
|
const clipStyle = (0, import_react_native_reanimated14.useAnimatedStyle)(() => {
|
|
1310
1339
|
const hHeight = headerHeightShared.value;
|
|
@@ -1319,7 +1348,7 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
1319
1348
|
stickyTop = effective <= 0 ? hHeight : Math.max(insetsTop, hHeight - effective);
|
|
1320
1349
|
}
|
|
1321
1350
|
return { top: stickyTop };
|
|
1322
|
-
}, [enabled, headerFixed, insetsTop]);
|
|
1351
|
+
}, [enabled, headerFixed, insetsTop, headerHeightShared, scrollPosition, snapBackHeaderShared, headerOffset, pullSearchHeightShared]);
|
|
1323
1352
|
const overlayStyle = (0, import_react_native_reanimated14.useAnimatedStyle)(() => {
|
|
1324
1353
|
const hidden = { opacity: 0, top: 0, transform: [{ translateY: 0 }] };
|
|
1325
1354
|
if (!enabled) return hidden;
|
|
@@ -1347,7 +1376,7 @@ function useStickyHeaders(headerFixed, enabled) {
|
|
|
1347
1376
|
if (nextScreenY < pushThreshold) translateY = nextScreenY - pushThreshold;
|
|
1348
1377
|
}
|
|
1349
1378
|
return { opacity: 1, top: 0, transform: [{ translateY }] };
|
|
1350
|
-
}, [enabled, headerFixed, insetsTop]);
|
|
1379
|
+
}, [enabled, headerFixed, insetsTop, contentIndexShared, sectionYPositions, headerHeightShared, scrollPosition, snapBackHeaderShared, headerOffset, pullSearchHeightShared, sectionHeights]);
|
|
1351
1380
|
const measureHeader = (0, import_react17.useCallback)(
|
|
1352
1381
|
(index, pageY, height) => {
|
|
1353
1382
|
const contentY = pageY + scrollPosition.value;
|
|
@@ -1376,11 +1405,15 @@ var AnimatedSectionList = import_react_native_reanimated15.default.createAnimate
|
|
|
1376
1405
|
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 }) => {
|
|
1377
1406
|
const scrollView = (0, import_react18.useRef)(null);
|
|
1378
1407
|
const { stickySectionHeadersEnabled = true, renderSectionHeader, ...passThroughProps } = props;
|
|
1379
|
-
const { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, contentPadding, footerFixed, headerFixed, headerHeight } = useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, keyboardAware, pullSearchHeight, style });
|
|
1408
|
+
const { chipHidden, chipStyle, containerStyle, contentInset, contentOffset, contentPadding, footerFixed, headerFixed, headerHeight } = useScrollList({ footerFixed: footerFixedProp, headerFixed: headerFixedProp, hideUntilMeasured: true, keyboardAware, pullSearchHeight, style });
|
|
1380
1409
|
const { listGeneration, onListUnmount } = (0, import_react18.useContext)(ScrollViewContext);
|
|
1381
1410
|
const capturedGeneration = (0, import_react_native_reanimated15.useSharedValue)(-1);
|
|
1382
1411
|
(0, import_react18.useLayoutEffect)(() => {
|
|
1383
1412
|
const generation = listGeneration.value;
|
|
1413
|
+
if (import_react_native14.Platform.OS === "web") {
|
|
1414
|
+
capturedGeneration.value = generation;
|
|
1415
|
+
return;
|
|
1416
|
+
}
|
|
1384
1417
|
(0, import_react_native_reanimated15.runOnUI)((gen) => {
|
|
1385
1418
|
"worklet";
|
|
1386
1419
|
capturedGeneration.value = gen;
|