Skip to content

Commit

Permalink
refactor: separate Screen native props and public API
Browse files Browse the repository at this point in the history
  • Loading branch information
maciekstosio committed Oct 21, 2024
1 parent 791cb10 commit 852c0a7
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 29 deletions.
51 changes: 35 additions & 16 deletions src/components/Screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,43 @@ import {
} from '../core';

// Native components
import ScreenNativeComponent from '../fabric/ScreenNativeComponent';
import ModalScreenNativeComponent from '../fabric/ModalScreenNativeComponent';
import NativeScreen, {
NativeProps as ScreenNativeProps,
} from '../fabric/ScreenNativeComponent';
import ModalScreenNative, {
NativeProps as ModalScreenNativeProps,
} from '../fabric/ModalScreenNativeComponent';
import { usePrevious } from './helpers/usePrevious';

type NativeScreenProps = Omit<
ScreenProps,
'sheetInitialDetentIndex' | 'sheetLargestUndimmedDetentIndex'
> & {
sheetInitialDetent: number;
sheetLargestUndimmedDetent: number;
};

export const NativeScreen: React.ComponentType<NativeScreenProps> =
ScreenNativeComponent as React.ComponentType<NativeScreenProps>;
const AnimatedNativeScreen = Animated.createAnimatedComponent(NativeScreen);
const AnimatedNativeModalScreen = Animated.createAnimatedComponent(
ModalScreenNativeComponent as React.ComponentType<NativeScreenProps>,
);
const AnimatedNativeModalScreen =
Animated.createAnimatedComponent(ModalScreenNative);

const AnimatedNativeModalScreenNormalized = React.forwardRef<
View,
ScreenNativeProps | ModalScreenNativeProps
>(function AnimatedNativeModalScreenNormalized(props, ref) {
const { stackAnimation } = props;

let resolvedStackAnimation: ModalScreenNativeProps['stackAnimation'];

if (
stackAnimation === 'ios_from_right' ||
stackAnimation === 'ios_from_left'
) {
resolvedStackAnimation = 'default';
} else {
resolvedStackAnimation = stackAnimation;
}

return (
<AnimatedNativeModalScreen
{...props}
ref={ref}
stackAnimation={resolvedStackAnimation}
/>
);
});

// Incomplete type, all accessible properties available at:
// react-native/Libraries/Components/View/ReactNativeViewViewConfig.js
Expand Down Expand Up @@ -218,7 +237,7 @@ export const InnerScreen = React.forwardRef<View, ScreenProps>(
stackPresentation === 'containedModal' ||
stackPresentation === 'containedTransparentModal'
? AnimatedNativeScreen
: AnimatedNativeModalScreen;
: AnimatedNativeModalScreenNormalized;

let {
// Filter out active prop in this case because it is unused and
Expand Down
12 changes: 8 additions & 4 deletions src/fabric/ModalScreenNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import type {
// eslint-disable-next-line @typescript-eslint/ban-types
type ScreenEvent = Readonly<{}>;

type ScreenTargetEvent = Readonly<{
target: Int32;
}>;

type ScreenDismissedEvent = Readonly<{
dismissCount: Int32;
}>;
Expand Down Expand Up @@ -60,12 +64,12 @@ type SwipeDirection = 'vertical' | 'horizontal';
type ReplaceAnimation = 'pop' | 'push';

export interface NativeProps extends ViewProps {
onAppear?: DirectEventHandler<ScreenEvent>;
onDisappear?: DirectEventHandler<ScreenEvent>;
onAppear?: DirectEventHandler<ScreenTargetEvent>;
onDisappear?: DirectEventHandler<ScreenTargetEvent>;
onDismissed?: DirectEventHandler<ScreenDismissedEvent>;
onNativeDismissCancelled?: DirectEventHandler<ScreenDismissedEvent>;
onWillAppear?: DirectEventHandler<ScreenEvent>;
onWillDisappear?: DirectEventHandler<ScreenEvent>;
onWillAppear?: DirectEventHandler<ScreenTargetEvent>;
onWillDisappear?: DirectEventHandler<ScreenTargetEvent>;
onHeaderHeightChange?: DirectEventHandler<HeaderHeightChangeEvent>;
onTransitionProgress?: DirectEventHandler<TransitionProgressEvent>;
onGestureCancel?: DirectEventHandler<ScreenEvent>;
Expand Down
12 changes: 8 additions & 4 deletions src/fabric/ScreenNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import type {
// eslint-disable-next-line @typescript-eslint/ban-types
type ScreenEvent = Readonly<{}>;

type ScreenTargetEvent = Readonly<{
target: Int32;
}>;

type ScreenDismissedEvent = Readonly<{
dismissCount: Int32;
}>;
Expand Down Expand Up @@ -66,12 +70,12 @@ type SwipeDirection = 'vertical' | 'horizontal';
type ReplaceAnimation = 'pop' | 'push';

export interface NativeProps extends ViewProps {
onAppear?: DirectEventHandler<ScreenEvent>;
onDisappear?: DirectEventHandler<ScreenEvent>;
onAppear?: DirectEventHandler<ScreenTargetEvent>;
onDisappear?: DirectEventHandler<ScreenTargetEvent>;
onDismissed?: DirectEventHandler<ScreenDismissedEvent>;
onNativeDismissCancelled?: DirectEventHandler<ScreenDismissedEvent>;
onWillAppear?: DirectEventHandler<ScreenEvent>;
onWillDisappear?: DirectEventHandler<ScreenEvent>;
onWillAppear?: DirectEventHandler<ScreenTargetEvent>;
onWillDisappear?: DirectEventHandler<ScreenTargetEvent>;
onHeaderHeightChange?: DirectEventHandler<HeaderHeightChangeEvent>;
onTransitionProgress?: DirectEventHandler<TransitionProgressEvent>;
onGestureCancel?: DirectEventHandler<ScreenEvent>;
Expand Down
1 change: 0 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export {
*/
export {
default as Screen,
NativeScreen,
InnerScreen,
ScreenContext,
} from './components/Screen';
Expand Down
9 changes: 5 additions & 4 deletions src/types.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import {
Animated,
NativeSyntheticEvent,
ViewProps,
View,
Expand Down Expand Up @@ -101,8 +100,8 @@ export type GestureResponseDistanceType = {
export type SearchBarPlacement = 'automatic' | 'inline' | 'stacked';

export interface ScreenProps extends ViewProps {
active?: 0 | 1 | Animated.AnimatedInterpolation<number>;
activityState?: 0 | 1 | 2 | Animated.AnimatedInterpolation<number>;
active?: 0 | 1;
activityState?: 0 | 1 | 2;
children?: React.ReactNode;
/**
* Boolean indicating that swipe dismissal should trigger animation provided by `stackAnimation`. Defaults to `false`.
Expand Down Expand Up @@ -218,7 +217,9 @@ export interface ScreenProps extends ViewProps {
/**
* A callback that gets called after swipe back is canceled.
*/
onGestureCancel?: (e: NativeSyntheticEvent<null>) => void;
onGestureCancel?: (
e: NativeSyntheticEvent<Readonly<Record<string, never>>>,
) => void;
/**
* An internal callback that gets called when the native header back button is clicked on Android and `enableNativeBackButtonDismissal` is set to `false`. It dismises the screen using `navigation.pop()`.
*
Expand Down

0 comments on commit 852c0a7

Please sign in to comment.