From 2ca35ba5934d5cc50f9d05cfc39ace9163ca03a3 Mon Sep 17 00:00:00 2001 From: Andre Marques Date: Tue, 21 Oct 2025 14:26:50 +0100 Subject: [PATCH 1/2] feat(reanimated): useAnimatedScrollHandler, withDelay --- .changeset/tall-sloths-fix.md | 5 +++ .../plugin-reanimated/src/animation/spring.ts | 2 +- .../plugin-reanimated/src/animation/timing.ts | 2 +- .../src/exports/useAnimatedScrollHandler.tsx | 42 +++++++++++++++++++ .../src/exports/withDelay.tsx | 19 +++++++++ packages/plugin-reanimated/src/index.ts | 2 + .../src/types/reanimated-extended.d.ts | 19 +++++++++ 7 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 .changeset/tall-sloths-fix.md create mode 100644 packages/plugin-reanimated/src/exports/useAnimatedScrollHandler.tsx create mode 100644 packages/plugin-reanimated/src/exports/withDelay.tsx create mode 100644 packages/plugin-reanimated/src/types/reanimated-extended.d.ts diff --git a/.changeset/tall-sloths-fix.md b/.changeset/tall-sloths-fix.md new file mode 100644 index 0000000..225b22d --- /dev/null +++ b/.changeset/tall-sloths-fix.md @@ -0,0 +1,5 @@ +--- +"@plextv/react-lightning-plugin-reanimated": minor +--- + +Added useAnimatedScrollHandler, withDelay implementations. diff --git a/packages/plugin-reanimated/src/animation/spring.ts b/packages/plugin-reanimated/src/animation/spring.ts index c703a03..35ac84e 100644 --- a/packages/plugin-reanimated/src/animation/spring.ts +++ b/packages/plugin-reanimated/src/animation/spring.ts @@ -139,7 +139,7 @@ export function createSpringAnimation( const animation = { duration: 350, easing: `cubic-bezier(${1 / 3}, ${p1_y}, ${2 / 3}, ${p2_y})`, - delay: 0, + delay: config?.delay ?? 0, loop: false, repeat: 0, repeatDelay: 0, diff --git a/packages/plugin-reanimated/src/animation/timing.ts b/packages/plugin-reanimated/src/animation/timing.ts index aa49c8a..a58d0f8 100644 --- a/packages/plugin-reanimated/src/animation/timing.ts +++ b/packages/plugin-reanimated/src/animation/timing.ts @@ -14,7 +14,7 @@ export function createTimingAnimation( return { duration: config?.duration ?? DefaultTimingConfig.duration, easing: 'linear', - delay: 0, + delay: config?.delay ?? 0, loop: false, repeat: 0, repeatDelay: 0, diff --git a/packages/plugin-reanimated/src/exports/useAnimatedScrollHandler.tsx b/packages/plugin-reanimated/src/exports/useAnimatedScrollHandler.tsx new file mode 100644 index 0000000..accf188 --- /dev/null +++ b/packages/plugin-reanimated/src/exports/useAnimatedScrollHandler.tsx @@ -0,0 +1,42 @@ +import { type DependencyList, useCallback, useRef } from 'react'; +import type { + ScrollHandlerProcessed, + useAnimatedScrollHandler as useAnimatedScrollHandlerRN, +} from 'react-native-reanimated-original'; + +type UseAnimatedScrollHandlerFn = ( + ...args: Parameters +) => ScrollHandlerProcessed; + +export const useAnimatedScrollHandler: UseAnimatedScrollHandlerFn = ( + scrollHandlers, + dependencies, +) => { + const inputs: DependencyList = dependencies ?? []; + // We want to persist context between scroll events + // The caller should use it, we won't do any assignment in + // this function. + const contextRef = useRef({}); + + return useCallback( + (event) => { + const context = contextRef.current; + // Only allow onScroll event + const reanimatedEvent = { + eventName: 'onScroll', + ...event.nativeEvent, + }; + + if (typeof scrollHandlers === 'function') { + scrollHandlers(reanimatedEvent, context); + return; + } + + if (scrollHandlers && typeof scrollHandlers.onScroll === 'function') { + scrollHandlers.onScroll(reanimatedEvent, context); + } + }, + // biome-ignore lint/correctness/useExhaustiveDependencies: We're passing a dependencies array from the props + inputs, + ); +}; diff --git a/packages/plugin-reanimated/src/exports/withDelay.tsx b/packages/plugin-reanimated/src/exports/withDelay.tsx new file mode 100644 index 0000000..cdcb376 --- /dev/null +++ b/packages/plugin-reanimated/src/exports/withDelay.tsx @@ -0,0 +1,19 @@ +import type { + AnimationObject, + withDelay as withDelayRN, +} from 'react-native-reanimated-original'; + +export type WithDelayFn = ( + ...args: Parameters +) => AnimationObject; + +export const withDelay: WithDelayFn = ( + _delayMs, + _nextAnimation, + _reduceMotion, +): AnimationObject => { + // withTiming and withSpring supports `delay`. The client should pass it directly + return typeof _nextAnimation === 'function' + ? (_nextAnimation as () => AnimationObject)() + : (_nextAnimation as AnimationObject); +}; diff --git a/packages/plugin-reanimated/src/index.ts b/packages/plugin-reanimated/src/index.ts index b8b33da..13d75be 100644 --- a/packages/plugin-reanimated/src/index.ts +++ b/packages/plugin-reanimated/src/index.ts @@ -46,8 +46,10 @@ export { SlideOutUp, } from './builders/Slide'; +export { useAnimatedScrollHandler } from './exports/useAnimatedScrollHandler'; export { useAnimatedStyle } from './exports/useAnimatedStyle'; export { useComposedEventHandler } from './exports/useComposedEventHandler'; +export { withDelay } from './exports/withDelay'; export { withRepeat } from './exports/withRepeat'; export { withSpring } from './exports/withSpring'; export { withTiming } from './exports/withTiming'; diff --git a/packages/plugin-reanimated/src/types/reanimated-extended.d.ts b/packages/plugin-reanimated/src/types/reanimated-extended.d.ts new file mode 100644 index 0000000..d361bcc --- /dev/null +++ b/packages/plugin-reanimated/src/types/reanimated-extended.d.ts @@ -0,0 +1,19 @@ +import type { + WithSpringConfig as BaseSpringConfig, + WithTimingConfig as BaseTimingConfig, +} from 'react-native-reanimated'; + +declare module 'react-native-reanimated' { + interface WithTimingConfig extends BaseTimingConfig { + delay?: number; + } + + interface WithSpringConfig extends BaseSpringConfig { + delay?: number; + } +} + +export type { + WithSpringConfig as SpringConfig, + WithTimingConfig as TimingConfig, +} from 'react-native-reanimated'; From 71c62b58ae0b6ea4ccd9c6981ef9c1319a59e075 Mon Sep 17 00:00:00 2001 From: Andre Marques Date: Thu, 23 Oct 2025 20:43:14 +0100 Subject: [PATCH 2/2] remove _ for used prop --- packages/plugin-reanimated/src/exports/withDelay.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/plugin-reanimated/src/exports/withDelay.tsx b/packages/plugin-reanimated/src/exports/withDelay.tsx index cdcb376..674e907 100644 --- a/packages/plugin-reanimated/src/exports/withDelay.tsx +++ b/packages/plugin-reanimated/src/exports/withDelay.tsx @@ -9,11 +9,11 @@ export type WithDelayFn = ( export const withDelay: WithDelayFn = ( _delayMs, - _nextAnimation, + nextAnimation, _reduceMotion, ): AnimationObject => { // withTiming and withSpring supports `delay`. The client should pass it directly - return typeof _nextAnimation === 'function' - ? (_nextAnimation as () => AnimationObject)() - : (_nextAnimation as AnimationObject); + return typeof nextAnimation === 'function' + ? (nextAnimation as () => AnimationObject)() + : (nextAnimation as AnimationObject); };