@rific/scroll-view 1.0.0 → 1.1.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 CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Blur-chrome scroll system for React Native. Drop-in replacements for `ScrollView`, `FlatList`, and `SectionList` with floating headers and footers, pull-to-search, keyboard awareness, horizontal paging, and frosted-glass chrome.
4
4
 
5
+ **[Live demo](https://rific.jaydeaton.com/demos/scroll-view)**
6
+
5
7
  ## Installation
6
8
 
7
9
  ```sh
package/dist/index.js CHANGED
@@ -90,6 +90,7 @@ var styles = import_react_native2.StyleSheet.create({
90
90
  });
91
91
 
92
92
  // src/internal/useScrollHandler.ts
93
+ var import_core = require("@rific/core");
93
94
  var import_react3 = require("react");
94
95
  var import_react_native_reanimated3 = require("react-native-reanimated");
95
96
 
@@ -338,6 +339,8 @@ function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold = 100,
338
339
  const { chromeHosted, chromeWritable, footerOffset, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackFooterShared, snapBackHeaderShared, stackHeightShared } = (0, import_react3.useContext)(ScrollViewContext);
339
340
  const snapUpAccum = (0, import_react_native_reanimated3.useSharedValue)(0);
340
341
  const fromBottomBounce = (0, import_react_native_reanimated3.useSharedValue)(false);
342
+ const remountSyncedKey = (0, import_core.useWorkletCallback)((y) => onRemountSynced?.(y));
343
+ const remountSyncRetryKey = (0, import_core.useWorkletCallback)((y) => onRemountSyncRetry?.(y));
341
344
  return (0, import_react_native_reanimated3.useAnimatedScrollHandler)(
342
345
  {
343
346
  onScroll: ({ contentOffset: { x, y }, contentSize: { height: contentHeight }, layoutMeasurement: { height: layoutHeight } }) => {
@@ -346,9 +349,9 @@ function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold = 100,
346
349
  const target = remountSyncTarget.value;
347
350
  if (Math.abs(y - target) < REMOUNT_SYNC_TOLERANCE) {
348
351
  remountSyncTarget.value = null;
349
- if (onRemountSynced) (0, import_react_native_reanimated3.runOnJS)(onRemountSynced)(y);
352
+ if (onRemountSynced) (0, import_react_native_reanimated3.runOnJS)(import_core.callWorkletCallback)(remountSyncedKey, y);
350
353
  } else if (onRemountSyncRetry) {
351
- (0, import_react_native_reanimated3.runOnJS)(onRemountSyncRetry)(y);
354
+ (0, import_react_native_reanimated3.runOnJS)(import_core.callWorkletCallback)(remountSyncRetryKey, y);
352
355
  }
353
356
  return;
354
357
  }
@@ -432,21 +435,23 @@ var import_react_native_reanimated5 = require("react-native-reanimated");
432
435
  var import_react_native_safe_area_context = require("react-native-safe-area-context");
433
436
 
434
437
  // src/useKeyboardInset.ts
438
+ var import_core2 = require("@rific/core");
435
439
  var import_react4 = require("react");
436
440
  var import_react_native4 = require("react-native");
437
441
  var import_react_native_keyboard_controller = require("react-native-keyboard-controller");
438
442
  var import_react_native_reanimated4 = require("react-native-reanimated");
439
443
  var useKeyboardInsetNative = () => {
440
444
  const [keyboardHeight, setKeyboardHeight] = (0, import_react4.useState)(0);
445
+ const keyboardHeightKey = (0, import_core2.useWorkletCallback)(setKeyboardHeight);
441
446
  (0, import_react_native_keyboard_controller.useKeyboardHandler)(
442
447
  {
443
448
  onMove: (e) => {
444
449
  "worklet";
445
- (0, import_react_native_reanimated4.runOnJS)(setKeyboardHeight)(e.height);
450
+ (0, import_react_native_reanimated4.runOnJS)(import_core2.callWorkletCallback)(keyboardHeightKey, e.height);
446
451
  },
447
452
  onEnd: (e) => {
448
453
  "worklet";
449
- (0, import_react_native_reanimated4.runOnJS)(setKeyboardHeight)(e.height);
454
+ (0, import_react_native_reanimated4.runOnJS)(import_core2.callWorkletCallback)(keyboardHeightKey, e.height);
450
455
  }
451
456
  },
452
457
  []
@@ -929,6 +934,7 @@ var styles4 = { measureContainer: { left: 0, opacity: 0, position: "absolute", r
929
934
  var FlatList = (0, import_react9.memo)(FlatListInner);
930
935
 
931
936
  // src/PullSearch.tsx
937
+ var import_core3 = require("@rific/core");
932
938
  var import_react10 = require("react");
933
939
  var import_react_native9 = require("react-native");
934
940
  var import_react_native_paper3 = require("react-native-paper");
@@ -951,13 +957,14 @@ var PullSearch = (0, import_react10.forwardRef)(function PullSearch2({ debounce,
951
957
  focus: () => inputRef.current?.focus()
952
958
  }));
953
959
  const blurInput = (0, import_react10.useCallback)(() => inputRef.current?.blur(), []);
960
+ const blurKey = (0, import_core3.useWorkletCallback)(blurInput);
954
961
  (0, import_react_native_reanimated9.useAnimatedReaction)(
955
962
  () => {
956
963
  if (barHeight === 0) return false;
957
964
  return scrollPosition.value >= -(headerHeight ?? 0) + barHeight;
958
965
  },
959
966
  (isHidden, wasHidden) => {
960
- if (isHidden && !wasHidden) (0, import_react_native_reanimated9.runOnJS)(blurInput)();
967
+ if (isHidden && !wasHidden) (0, import_react_native_reanimated9.runOnJS)(import_core3.callWorkletCallback)(blurKey);
961
968
  },
962
969
  // scrollPosition has to be listed too, not just read - see useStickyHeaders' useAnimatedReaction
963
970
  // for why: on web, without reanimated's Babel plugin active, an unlisted SharedValue mutation
@@ -1003,23 +1010,23 @@ var styles5 = import_react_native9.StyleSheet.create({
1003
1010
  });
1004
1011
 
1005
1012
  // src/redux/scrollViewSlice.ts
1006
- var import_core2 = require("@rific/core");
1013
+ var import_core5 = require("@rific/core");
1007
1014
 
1008
1015
  // src/ScrollViewSettingsContext.ts
1009
- var import_core = require("@rific/core");
1016
+ var import_core4 = require("@rific/core");
1010
1017
  var defaultScrollViewSettings = {
1011
1018
  backActionFixed: true,
1012
1019
  footerFixed: false,
1013
1020
  headerFixed: false,
1014
1021
  snapBack: false
1015
1022
  };
1016
- var settingsContext = (0, import_core.createSettingsContext)(defaultScrollViewSettings);
1023
+ var settingsContext = (0, import_core4.createSettingsContext)(defaultScrollViewSettings);
1017
1024
  var ScrollViewSettingsContext = settingsContext.Context;
1018
1025
  var scrollViewSettingsProvider = settingsContext.Provider;
1019
1026
  var scrollViewUseSettings = settingsContext.useSettings;
1020
1027
 
1021
1028
  // src/redux/scrollViewSlice.ts
1022
- var scrollViewSlice = (0, import_core2.createSettingsSlice)("scrollView", {
1029
+ var scrollViewSlice = (0, import_core5.createSettingsSlice)("scrollView", {
1023
1030
  initialState: defaultScrollViewSettings,
1024
1031
  fieldSetters: []
1025
1032
  });
@@ -1135,8 +1142,8 @@ var ScrollViewChromeProvider = ({ children, footprint, overhang = 0, snapBack =
1135
1142
  };
1136
1143
 
1137
1144
  // src/ScrollViewConfig.tsx
1138
- var import_core3 = require("@rific/core");
1139
- var scrollViewConfig = (0, import_core3.createModuleConfig)();
1145
+ var import_core6 = require("@rific/core");
1146
+ var scrollViewConfig = (0, import_core6.createModuleConfig)();
1140
1147
  var configureScrollView = scrollViewConfig.configure;
1141
1148
  var getScrollViewConfig = scrollViewConfig.getConfig;
1142
1149
  var ScrollViewConfigProvider = scrollViewConfig.Provider;
@@ -1453,6 +1460,7 @@ var import_react_native_gesture_handler4 = require("react-native-gesture-handler
1453
1460
  var import_react_native_reanimated16 = __toESM(require("react-native-reanimated"));
1454
1461
 
1455
1462
  // src/internal/useStickyHeaders.ts
1463
+ var import_core7 = require("@rific/core");
1456
1464
  var import_react18 = require("react");
1457
1465
  var import_react_native_reanimated15 = require("react-native-reanimated");
1458
1466
  var import_react_native_safe_area_context5 = require("react-native-safe-area-context");
@@ -1462,6 +1470,7 @@ function useStickyHeaders(headerFixed, enabled) {
1462
1470
  const sectionYPositions = (0, import_react_native_reanimated15.useSharedValue)([]);
1463
1471
  const sectionHeights = (0, import_react_native_reanimated15.useSharedValue)([]);
1464
1472
  const [activeIndex, setActiveIndex] = (0, import_react18.useState)(-1);
1473
+ const activeIndexKey = (0, import_core7.useWorkletCallback)(setActiveIndex);
1465
1474
  const contentIndexShared = (0, import_react_native_reanimated15.useSharedValue)(-1);
1466
1475
  (0, import_react18.useLayoutEffect)(() => {
1467
1476
  contentIndexShared.value = activeIndex;
@@ -1493,7 +1502,7 @@ function useStickyHeaders(headerFixed, enabled) {
1493
1502
  return active;
1494
1503
  },
1495
1504
  (curr, prev) => {
1496
- if (curr !== prev) (0, import_react_native_reanimated15.runOnJS)(setActiveIndex)(curr);
1505
+ if (curr !== prev) (0, import_react_native_reanimated15.runOnJS)(import_core7.callWorkletCallback)(activeIndexKey, curr);
1497
1506
  },
1498
1507
  // Same web-only reanimated gap as useAnimatedStyle elsewhere in this file: this "prepare"
1499
1508
  // function's own SharedValue reads (sectionYPositions, headerHeightShared, scrollPosition,
package/dist/index.mjs CHANGED
@@ -31,6 +31,7 @@ var styles = StyleSheet.create({
31
31
  });
32
32
 
33
33
  // src/internal/useScrollHandler.ts
34
+ import { callWorkletCallback, useWorkletCallback } from "@rific/core";
34
35
  import { useContext as useContext2 } from "react";
35
36
  import { runOnJS, useAnimatedScrollHandler, useSharedValue as useSharedValue2, withTiming } from "react-native-reanimated";
36
37
 
@@ -279,6 +280,8 @@ function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold = 100,
279
280
  const { chromeHosted, chromeWritable, footerOffset, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackFooterShared, snapBackHeaderShared, stackHeightShared } = useContext2(ScrollViewContext);
280
281
  const snapUpAccum = useSharedValue2(0);
281
282
  const fromBottomBounce = useSharedValue2(false);
283
+ const remountSyncedKey = useWorkletCallback((y) => onRemountSynced?.(y));
284
+ const remountSyncRetryKey = useWorkletCallback((y) => onRemountSyncRetry?.(y));
282
285
  return useAnimatedScrollHandler(
283
286
  {
284
287
  onScroll: ({ contentOffset: { x, y }, contentSize: { height: contentHeight }, layoutMeasurement: { height: layoutHeight } }) => {
@@ -287,9 +290,9 @@ function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold = 100,
287
290
  const target = remountSyncTarget.value;
288
291
  if (Math.abs(y - target) < REMOUNT_SYNC_TOLERANCE) {
289
292
  remountSyncTarget.value = null;
290
- if (onRemountSynced) runOnJS(onRemountSynced)(y);
293
+ if (onRemountSynced) runOnJS(callWorkletCallback)(remountSyncedKey, y);
291
294
  } else if (onRemountSyncRetry) {
292
- runOnJS(onRemountSyncRetry)(y);
295
+ runOnJS(callWorkletCallback)(remountSyncRetryKey, y);
293
296
  }
294
297
  return;
295
298
  }
@@ -373,21 +376,23 @@ import { useAnimatedStyle, useSharedValue as useSharedValue3, withTiming as with
373
376
  import { useSafeAreaInsets } from "react-native-safe-area-context";
374
377
 
375
378
  // src/useKeyboardInset.ts
379
+ import { callWorkletCallback as callWorkletCallback2, useWorkletCallback as useWorkletCallback2 } from "@rific/core";
376
380
  import { useState as useState2 } from "react";
377
381
  import { Platform as Platform2 } from "react-native";
378
382
  import { useKeyboardHandler } from "react-native-keyboard-controller";
379
383
  import { runOnJS as runOnJS2 } from "react-native-reanimated";
380
384
  var useKeyboardInsetNative = () => {
381
385
  const [keyboardHeight, setKeyboardHeight] = useState2(0);
386
+ const keyboardHeightKey = useWorkletCallback2(setKeyboardHeight);
382
387
  useKeyboardHandler(
383
388
  {
384
389
  onMove: (e) => {
385
390
  "worklet";
386
- runOnJS2(setKeyboardHeight)(e.height);
391
+ runOnJS2(callWorkletCallback2)(keyboardHeightKey, e.height);
387
392
  },
388
393
  onEnd: (e) => {
389
394
  "worklet";
390
- runOnJS2(setKeyboardHeight)(e.height);
395
+ runOnJS2(callWorkletCallback2)(keyboardHeightKey, e.height);
391
396
  }
392
397
  },
393
398
  []
@@ -870,6 +875,7 @@ var styles4 = { measureContainer: { left: 0, opacity: 0, position: "absolute", r
870
875
  var FlatList = memo2(FlatListInner);
871
876
 
872
877
  // src/PullSearch.tsx
878
+ import { callWorkletCallback as callWorkletCallback3, useWorkletCallback as useWorkletCallback3 } from "@rific/core";
873
879
  import { forwardRef, useCallback as useCallback5, useContext as useContext8, useEffect as useEffect3, useImperativeHandle, useRef as useRef5, useState as useState4 } from "react";
874
880
  import { StyleSheet as StyleSheet4 } from "react-native";
875
881
  import { Searchbar, useTheme as useTheme3 } from "react-native-paper";
@@ -892,13 +898,14 @@ var PullSearch = forwardRef(function PullSearch2({ debounce, onChangeText, onHei
892
898
  focus: () => inputRef.current?.focus()
893
899
  }));
894
900
  const blurInput = useCallback5(() => inputRef.current?.blur(), []);
901
+ const blurKey = useWorkletCallback3(blurInput);
895
902
  useAnimatedReaction(
896
903
  () => {
897
904
  if (barHeight === 0) return false;
898
905
  return scrollPosition.value >= -(headerHeight ?? 0) + barHeight;
899
906
  },
900
907
  (isHidden, wasHidden) => {
901
- if (isHidden && !wasHidden) runOnJS3(blurInput)();
908
+ if (isHidden && !wasHidden) runOnJS3(callWorkletCallback3)(blurKey);
902
909
  },
903
910
  // scrollPosition has to be listed too, not just read - see useStickyHeaders' useAnimatedReaction
904
911
  // for why: on web, without reanimated's Babel plugin active, an unlisted SharedValue mutation
@@ -1394,6 +1401,7 @@ import { Gesture as Gesture4, GestureDetector as GestureDetector4 } from "react-
1394
1401
  import Animated7, { runOnUI as runOnUI3, useSharedValue as useSharedValue10 } from "react-native-reanimated";
1395
1402
 
1396
1403
  // src/internal/useStickyHeaders.ts
1404
+ import { callWorkletCallback as callWorkletCallback4, useWorkletCallback as useWorkletCallback4 } from "@rific/core";
1397
1405
  import { useCallback as useCallback9, useContext as useContext13, useLayoutEffect as useLayoutEffect8, useRef as useRef10, useState as useState7 } from "react";
1398
1406
  import { runOnJS as runOnJS4, useAnimatedReaction as useAnimatedReaction2, useAnimatedStyle as useAnimatedStyle6, useSharedValue as useSharedValue9 } from "react-native-reanimated";
1399
1407
  import { useSafeAreaInsets as useSafeAreaInsets5 } from "react-native-safe-area-context";
@@ -1403,6 +1411,7 @@ function useStickyHeaders(headerFixed, enabled) {
1403
1411
  const sectionYPositions = useSharedValue9([]);
1404
1412
  const sectionHeights = useSharedValue9([]);
1405
1413
  const [activeIndex, setActiveIndex] = useState7(-1);
1414
+ const activeIndexKey = useWorkletCallback4(setActiveIndex);
1406
1415
  const contentIndexShared = useSharedValue9(-1);
1407
1416
  useLayoutEffect8(() => {
1408
1417
  contentIndexShared.value = activeIndex;
@@ -1434,7 +1443,7 @@ function useStickyHeaders(headerFixed, enabled) {
1434
1443
  return active;
1435
1444
  },
1436
1445
  (curr, prev) => {
1437
- if (curr !== prev) runOnJS4(setActiveIndex)(curr);
1446
+ if (curr !== prev) runOnJS4(callWorkletCallback4)(activeIndexKey, curr);
1438
1447
  },
1439
1448
  // Same web-only reanimated gap as useAnimatedStyle elsewhere in this file: this "prepare"
1440
1449
  // function's own SharedValue reads (sectionYPositions, headerHeightShared, scrollPosition,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rific/scroll-view",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
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",
@@ -66,7 +66,7 @@
66
66
  "@infinitetoken/tsconfig": "^0.6.0",
67
67
  "@reduxjs/toolkit": "^2.12.0",
68
68
  "@rific/auto-paper": "^0.13.3",
69
- "@rific/core": "^0.3.1",
69
+ "@rific/core": "^0.5.0",
70
70
  "@testing-library/dom": "^10.4.1",
71
71
  "@testing-library/react": "^16.3.2",
72
72
  "@types/jest": "^30.0.0",
@@ -92,7 +92,7 @@
92
92
  },
93
93
  "peerDependencies": {
94
94
  "@rific/auto-paper": ">=0.10.0",
95
- "@rific/core": ">=0.1.1",
95
+ "@rific/core": ">=0.5.0",
96
96
  "react": ">=19.0.0",
97
97
  "react-native": ">=0.83.0",
98
98
  "react-native-gesture-handler": ">=2.0.0 <4.0.0",
@@ -1,3 +1,4 @@
1
+ import { callWorkletCallback, useWorkletCallback } from '@rific/core'
1
2
  import { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react'
2
3
  import { type LayoutChangeEvent, StyleSheet, type TextInput } from 'react-native'
3
4
  import { Searchbar, useTheme } from 'react-native-paper'
@@ -38,6 +39,7 @@ export const PullSearch = forwardRef<PullSearchHandle, PullSearchProps>(function
38
39
  }))
39
40
 
40
41
  const blurInput = useCallback(() => inputRef.current?.blur(), [])
42
+ const blurKey = useWorkletCallback(blurInput)
41
43
 
42
44
  useAnimatedReaction(
43
45
  () => {
@@ -45,7 +47,7 @@ export const PullSearch = forwardRef<PullSearchHandle, PullSearchProps>(function
45
47
  return scrollPosition.value >= -(headerHeight ?? 0) + barHeight
46
48
  },
47
49
  (isHidden, wasHidden) => {
48
- if (isHidden && !wasHidden) runOnJS(blurInput)()
50
+ if (isHidden && !wasHidden) runOnJS(callWorkletCallback)(blurKey)
49
51
  },
50
52
  // scrollPosition has to be listed too, not just read - see useStickyHeaders' useAnimatedReaction
51
53
  // for why: on web, without reanimated's Babel plugin active, an unlisted SharedValue mutation
@@ -1,3 +1,4 @@
1
+ import { callWorkletCallback, useWorkletCallback } from '@rific/core'
1
2
  import { useContext } from 'react'
2
3
  import type { SharedValue } from 'react-native-reanimated'
3
4
  import { runOnJS, useAnimatedScrollHandler, useSharedValue, withTiming } from 'react-native-reanimated'
@@ -24,6 +25,10 @@ export function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold
24
25
  const { chromeHosted, chromeWritable, footerOffset, headerHeightShared, headerOffset, pullSearchHeightShared, scrollPosition, snapBackFooterShared, snapBackHeaderShared, stackHeightShared } = useContext(ScrollViewContext)
25
26
  const snapUpAccum = useSharedValue(0)
26
27
  const fromBottomBounce = useSharedValue(false)
28
+ // Worklets never get the consumer's callbacks themselves: react-native-worklets holds a runOnJS target natively for as
29
+ // long as the worklet lives, which pinned the list. They call the module-level callWorkletCallback by key.
30
+ const remountSyncedKey = useWorkletCallback((y: number) => onRemountSynced?.(y))
31
+ const remountSyncRetryKey = useWorkletCallback((y: number) => onRemountSyncRetry?.(y))
27
32
 
28
33
  return useAnimatedScrollHandler(
29
34
  {
@@ -33,9 +38,9 @@ export function useScrollHandler({ capturedGeneration, chipHidden, chipThreshold
33
38
  const target = remountSyncTarget.value
34
39
  if (Math.abs(y - target) < REMOUNT_SYNC_TOLERANCE) {
35
40
  remountSyncTarget.value = null
36
- if (onRemountSynced) runOnJS(onRemountSynced)(y)
41
+ if (onRemountSynced) runOnJS(callWorkletCallback)(remountSyncedKey, y)
37
42
  } else if (onRemountSyncRetry) {
38
- runOnJS(onRemountSyncRetry)(y)
43
+ runOnJS(callWorkletCallback)(remountSyncRetryKey, y)
39
44
  }
40
45
  return
41
46
  }
@@ -1,3 +1,4 @@
1
+ import { callWorkletCallback, useWorkletCallback } from '@rific/core'
1
2
  import { useCallback, useContext, useLayoutEffect, useRef, useState } from 'react'
2
3
  import { runOnJS, useAnimatedReaction, useAnimatedStyle, useSharedValue } from 'react-native-reanimated'
3
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
@@ -19,6 +20,7 @@ export function useStickyHeaders(headerFixed: boolean, enabled: boolean): Sticky
19
20
  const sectionYPositions = useSharedValue<number[]>([])
20
21
  const sectionHeights = useSharedValue<number[]>([])
21
22
  const [activeIndex, setActiveIndex] = useState(-1)
23
+ const activeIndexKey = useWorkletCallback(setActiveIndex)
22
24
  // Mirrors activeIndex React state but lives on the UI thread for overlayStyle.
23
25
  // Updated via useLayoutEffect so content and style always change together.
24
26
  const contentIndexShared = useSharedValue(-1)
@@ -60,7 +62,7 @@ export function useStickyHeaders(headerFixed: boolean, enabled: boolean): Sticky
60
62
  return active
61
63
  },
62
64
  (curr, prev) => {
63
- if (curr !== prev) runOnJS(setActiveIndex)(curr)
65
+ if (curr !== prev) runOnJS(callWorkletCallback)(activeIndexKey, curr)
64
66
  },
65
67
  // Same web-only reanimated gap as useAnimatedStyle elsewhere in this file: this "prepare"
66
68
  // function's own SharedValue reads (sectionYPositions, headerHeightShared, scrollPosition,
@@ -1,3 +1,4 @@
1
+ import { callWorkletCallback, useWorkletCallback } from '@rific/core'
1
2
  import { useState } from 'react'
2
3
  import { Platform } from 'react-native'
3
4
  import { useKeyboardHandler } from 'react-native-keyboard-controller'
@@ -5,15 +6,16 @@ import { runOnJS } from 'react-native-reanimated'
5
6
 
6
7
  const useKeyboardInsetNative = () => {
7
8
  const [keyboardHeight, setKeyboardHeight] = useState(0)
9
+ const keyboardHeightKey = useWorkletCallback(setKeyboardHeight)
8
10
  useKeyboardHandler(
9
11
  {
10
12
  onMove: (e) => {
11
13
  'worklet'
12
- runOnJS(setKeyboardHeight)(e.height)
14
+ runOnJS(callWorkletCallback)(keyboardHeightKey, e.height)
13
15
  },
14
16
  onEnd: (e) => {
15
17
  'worklet'
16
- runOnJS(setKeyboardHeight)(e.height)
18
+ runOnJS(callWorkletCallback)(keyboardHeightKey, e.height)
17
19
  }
18
20
  },
19
21
  []