Skip to content

Commit 3a325f9

Browse files
feat: add onTransitionEnd callback with finished/interrupted status
1 parent 2784cb8 commit 3a325f9

4 files changed

Lines changed: 24 additions & 1 deletion

File tree

src/EaseView.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { StyleSheet, type ViewProps, type ViewStyle } from 'react-native';
22
import NativeEaseView from './EaseViewNativeComponent';
3-
import type { AnimateProps, Transition } from './types';
3+
import type { AnimateProps, Transition, TransitionEndEvent } from './types';
44

55
export type EaseViewStyle = Omit<ViewStyle, 'opacity' | 'transform'>;
66

@@ -19,6 +19,8 @@ export type EaseViewProps = Omit<ViewProps, 'style'> & {
1919
initialAnimate?: AnimateProps;
2020
/** Animation configuration (timing or spring). */
2121
transition?: Transition;
22+
/** Called when a property's animation ends. Reports which property and whether it finished naturally or was interrupted. */
23+
onTransitionEnd?: (event: TransitionEndEvent) => void;
2224
/**
2325
* Use a hardware layer during animations on Android for smoother rendering.
2426
* The view is rasterized to a GPU texture while animating so property changes
@@ -35,6 +37,7 @@ export function EaseView({
3537
animate,
3638
initialAnimate,
3739
transition,
40+
onTransitionEnd,
3841
useHardwareLayer = true,
3942
style,
4043
...rest
@@ -77,9 +80,15 @@ export function EaseView({
7780
const transitionLoop =
7881
transition?.type === 'timing' ? transition.loop ?? 'none' : 'none';
7982

83+
const handleTransitionEnd = onTransitionEnd
84+
? (event: { nativeEvent: { property: string; finished: boolean } }) =>
85+
onTransitionEnd(event.nativeEvent as TransitionEndEvent)
86+
: undefined;
87+
8088
return (
8189
<NativeEaseView
8290
style={cleanStyle}
91+
onTransitionEnd={handleTransitionEnd}
8392
animateOpacity={resolved.opacity}
8493
animateTranslateX={resolved.translateX}
8594
animateTranslateY={resolved.translateY}

src/EaseViewNativeComponent.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ export interface NativeProps extends ViewProps {
3535
'none'
3636
>;
3737

38+
// Events
39+
onTransitionEnd?: CodegenTypes.DirectEventHandler<
40+
Readonly<{ property: string; finished: boolean }>
41+
>;
42+
3843
// Android hardware layer optimization (no-op on iOS)
3944
useHardwareLayer?: CodegenTypes.WithDefault<boolean, true>;
4045
}

src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ export type {
66
TimingTransition,
77
SpringTransition,
88
EasingType,
9+
TransitionEndEvent,
910
} from './types';

src/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ export type SpringTransition = {
2626
/** Animation transition configuration. */
2727
export type Transition = TimingTransition | SpringTransition;
2828

29+
/** Event fired when a property animation ends. */
30+
export type TransitionEndEvent = {
31+
/** Which property finished animating. */
32+
property: 'opacity' | 'translateX' | 'translateY' | 'scale' | 'rotate';
33+
/** True if the animation completed naturally, false if interrupted. */
34+
finished: boolean;
35+
};
36+
2937
/** Animatable view properties. Unspecified properties default to their identity values. */
3038
export type AnimateProps = {
3139
/** View opacity (0–1). @default 1 */

0 commit comments

Comments
 (0)