feat: expose stack transition values via context (#265)

This commit is contained in:
Samuel Chamberland
2019-10-24 07:34:15 -04:00
parent 20351e760b
commit 82c732a638
7 changed files with 147 additions and 2 deletions

View File

@@ -29,6 +29,7 @@ import {
HeaderBackgroundFade,
} from './src/HeaderBackgrounds';
import DragLimitedToModal from './src/DragLimitedToModal';
import StackAnimationConsumerStack from './src/StackAnimationConsumerStack';
// Comment the following two lines to stop using react-native-screens
// eslint-disable-next-line import/no-unresolved
@@ -109,6 +110,11 @@ const data: Item[] = [
title: 'Drag limited to modal',
routeName: 'DragLimitedToModal',
},
{
component: StackAnimationConsumerStack,
title: 'Stack animation consumer stack',
routeName: 'StackAnimationConsumerStack',
},
];
// Cache images

View File

@@ -0,0 +1,104 @@
import * as React from 'react';
import { Button, View } from 'react-native';
import Animated from 'react-native-reanimated';
import {
createStackNavigator,
NavigationStackScreenProps,
StackAnimationProgressContext,
StackAnimationIsSwipingContext,
StackAnimationIsClosingContext,
} from 'react-navigation-stack';
const ListScreen = (props: NavigationStackScreenProps) => (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button
title="Push to another screen"
onPress={() => props.navigation.push('Another')}
/>
<Button
title="Push to yet another screen"
onPress={() => props.navigation.push('YetAnother')}
/>
<Button
title="Go back to all examples"
onPress={() => props.navigation.navigate('Home')}
/>
</View>
);
const AnotherScreen = () => (
<StackAnimationProgressContext.Consumer>
{progress => {
const fontSize = Animated.interpolate(progress, {
inputRange: [0, 1],
outputRange: [8, 32],
});
return (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'honeydew',
}}
>
<Animated.Text style={{ fontSize, opacity: progress }}>
Animates on progress
</Animated.Text>
</View>
);
}}
</StackAnimationProgressContext.Consumer>
);
const YetAnotherScreen = () => (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'papayawhip',
}}
>
<StackAnimationIsSwipingContext.Consumer>
{isSwiping => (
<Animated.Text
style={{
fontSize: 24,
opacity: Animated.interpolate(isSwiping, {
inputRange: [0, 1],
outputRange: [1, 0],
}),
}}
>
Disappears when swiping
</Animated.Text>
)}
</StackAnimationIsSwipingContext.Consumer>
<StackAnimationIsClosingContext.Consumer>
{isClosing => (
<Animated.Text
style={{
fontSize: 24,
opacity: Animated.interpolate(isClosing, {
inputRange: [0, 1],
outputRange: [1, 0],
}),
}}
>
Disappears only when closing
</Animated.Text>
)}
</StackAnimationIsClosingContext.Consumer>
</View>
);
export default createStackNavigator(
{
List: ListScreen,
Another: AnotherScreen,
YetAnother: YetAnotherScreen,
},
{ initialRouteName: 'List' }
);

View File

@@ -35,8 +35,16 @@ export {
/**
* Utilities
*/
export { default as StackGestureContext } from './utils/StackGestureContext';
export {
default as StackAnimationProgressContext,
} from './utils/StackAnimationProgressContext';
export {
default as StackAnimationIsSwipingContext,
} from './utils/StackAnimationIsSwipingContext';
export {
default as StackAnimationIsClosingContext,
} from './utils/StackAnimationIsClosingContext';
/**
* Types

View File

@@ -0,0 +1,4 @@
import * as React from 'react';
import Animated from 'react-native-reanimated';
export default React.createContext<Animated.Node<0 | 1>>(new Animated.Value(0));

View File

@@ -0,0 +1,4 @@
import * as React from 'react';
import Animated from 'react-native-reanimated';
export default React.createContext<Animated.Node<0 | 1>>(new Animated.Value(0));

View File

@@ -0,0 +1,6 @@
import * as React from 'react';
import Animated from 'react-native-reanimated';
export default React.createContext<Animated.Value<number>>(
new Animated.Value(0)
);

View File

@@ -25,6 +25,9 @@ import {
import memoize from '../../utils/memoize';
import StackGestureContext from '../../utils/StackGestureContext';
import PointerEventsView from './PointerEventsView';
import StackAnimationProgressContext from '../../utils/StackAnimationProgressContext';
import StackAnimationIsSwipingContext from '../../utils/StackAnimationIsSwipingContext';
import StackAnimationIsClosingContext from '../../utils/StackAnimationIsClosingContext';
type Props = ViewProps & {
index: number;
@@ -910,7 +913,17 @@ export default class Card extends React.Component<Props> {
contentStyle,
]}
>
{children}
<StackAnimationProgressContext.Provider value={current}>
<StackAnimationIsSwipingContext.Provider
value={this.isSwiping}
>
<StackAnimationIsClosingContext.Provider
value={this.isClosing}
>
{children}
</StackAnimationIsClosingContext.Provider>
</StackAnimationIsSwipingContext.Provider>
</StackAnimationProgressContext.Provider>
</PointerEventsView>
</Animated.View>
</PanGestureHandler>