Skip to content

Commit

Permalink
Typescript for interpolation (software-mansion#2356)
Browse files Browse the repository at this point in the history
As the next step of the react-native-reanimated smooth transition to TypeScript, this PR updates types for the reanimated interpolation module.
  • Loading branch information
jmysliv authored Sep 6, 2021
1 parent 2d3af3a commit cb651ec
Show file tree
Hide file tree
Showing 23 changed files with 856 additions and 595 deletions.
4 changes: 3 additions & 1 deletion Example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
LogBox,
Platform,
UIManager,
ScrollView,
} from 'react-native';
import { RectButton, ScrollView } from 'react-native-gesture-handler';
import { RectButton } from 'react-native-gesture-handler';
import {
createStackNavigator,
StackNavigationProp,
Expand Down Expand Up @@ -36,6 +37,7 @@ import LightboxExample from './LightboxExample';
import LiquidSwipe from './LiquidSwipe';
import MeasureExample from './MeasureExample';
import { OlympicAnimation } from './LayoutReanimation/OlympicAnimation';
// @ts-ignore JS file
import Reanimated1 from '../reanimated1/App';
import ScrollEventExample from './ScrollEventExample';
import ScrollExample from './AnimatedScrollExample';
Expand Down
37 changes: 24 additions & 13 deletions Example/src/CustomHandler/AnimatedText.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
import React from 'react';
import { StyleProp, StyleSheet, TextInput, TextInputProps, TextStyle } from 'react-native';
import {
StyleProp,
StyleSheet,
TextInput,
TextInputProps,
TextStyle,
} from 'react-native';
import Animated, { useAnimatedProps } from 'react-native-reanimated';

Animated.addWhitelistedNativeProps({ text: true });

const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);

export function AnimatedText({ style, text }: {
style?: StyleProp<Animated.AnimateStyle<StyleProp<TextStyle>>>,
text: Animated.SharedValue<string>,
export function AnimatedText({
style,
text,
}: {
style?: StyleProp<Animated.AnimateStyle<StyleProp<TextStyle>>>;
text: Animated.SharedValue<string>;
}): React.ReactElement {
const animatedProps = useAnimatedProps(() => {
return { text: text.value } as unknown as TextInputProps;
return ({ text: text.value } as unknown) as TextInputProps;
});

return <AnimatedTextInput
underlineColorAndroid="transparent"
editable={false}
value={text.value}
style={[styles.text, style]}
animatedProps={animatedProps}
/>
return (
<AnimatedTextInput
underlineColorAndroid="transparent"
editable={false}
value={text.value}
style={[styles.text, style]}
animatedProps={animatedProps}
/>
);
}

const styles = StyleSheet.create({
text: {
color: 'black',
},
})
});
29 changes: 18 additions & 11 deletions Example/src/CustomHandler/PagerExample.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Animated, { useDerivedValue, useSharedValue } from 'react-native-reanimated';
import Animated, {
useDerivedValue,
useSharedValue,
} from 'react-native-reanimated';
import PagerView, { PageScrollState } from 'react-native-pager-view';

import { AnimatedText } from './AnimatedText';
Expand All @@ -19,7 +22,7 @@ const SLIDES = [
{ color: 'yellow', key: 3 },
{ color: 'green', key: 4 },
{ color: 'pink', key: 5 },
]
];

export function PagerExample(): React.ReactElement {
const scrollPosition = useSharedValue(0);
Expand Down Expand Up @@ -50,7 +53,10 @@ export function PagerExample(): React.ReactElement {
<View style={styles.container}>
<Pagination numberOfSlides={SLIDES.length} position={scrollPosition} />
<View style={styles.pagerDetails}>
<AnimatedText style={styles.pagerDetailsText} text={stringifiedCurrentPage} />
<AnimatedText
style={styles.pagerDetailsText}
text={stringifiedCurrentPage}
/>
<AnimatedText style={styles.pagerDetailsText} text={scrollState} />
</View>
<AnimatedPagerView
Expand All @@ -59,14 +65,15 @@ export function PagerExample(): React.ReactElement {
onPageScrollStateChanged={scrollStateHandler}
onPageSelected={selectedPageHandler}
orientation="horizontal"
style={styles.pager}
>
{SLIDES.map((slide) => <View
key={slide.key}
collapsable={false}
style={[styles.slide, { backgroundColor: slide.color }]}>
<Text style={styles.slideText}>{slide.key}</Text>
</View>)}
style={styles.pager}>
{SLIDES.map((slide) => (
<View
key={slide.key}
collapsable={false}
style={[styles.slide, { backgroundColor: slide.color }]}>
<Text style={styles.slideText}>{slide.key}</Text>
</View>
))}
</AnimatedPagerView>
</View>
);
Expand Down
42 changes: 25 additions & 17 deletions Example/src/CustomHandler/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import Animated, {
useAnimatedStyle,
} from 'react-native-reanimated';

function PaginationElement({ position, slideIndex }: {
position: Animated.SharedValue<number>,
slideIndex: number
function PaginationElement({
position,
slideIndex,
}: {
position: Animated.SharedValue<number>;
slideIndex: number;
}): React.ReactElement {
const inputRange = [slideIndex - 1, slideIndex, slideIndex + 1];
const dotAnimatedStyle = useAnimatedStyle(() => {
const width = interpolate(
position.value,
inputRange,
[4, 40, 4],
Extrapolate.CLAMP,
Extrapolate.CLAMP
);

return { width };
Expand All @@ -26,7 +29,7 @@ function PaginationElement({ position, slideIndex }: {
position.value,
inputRange,
[0.4, 1, 0.4],
Extrapolate.CLAMP,
Extrapolate.CLAMP
);

return { opacity };
Expand All @@ -40,21 +43,26 @@ function PaginationElement({ position, slideIndex }: {
);
}

export function Pagination({ numberOfSlides, position }: {
numberOfSlides: number,
position: Animated.SharedValue<number>
export function Pagination({
numberOfSlides,
position,
}: {
numberOfSlides: number;
position: Animated.SharedValue<number>;
}): React.ReactElement {
return (
<View style={styles.pagination}>
{Array(numberOfSlides).fill(1).map((_, slideIndex) => {
return (
<PaginationElement
key={slideIndex}
position={position}
slideIndex={slideIndex}
/>
);
})}
{Array(numberOfSlides)
.fill(1)
.map((_, slideIndex) => {
return (
<PaginationElement
key={slideIndex}
position={position}
slideIndex={slideIndex}
/>
);
})}
</View>
);
}
Expand Down
100 changes: 82 additions & 18 deletions Example/src/CustomHandler/useAnimatedPagerHandler.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,127 @@
import { NativeSyntheticEvent } from 'react-native';
import { PagerViewOnPageScrollEventData, PagerViewOnPageSelectedEventData, PageScrollStateChangedEvent } from 'react-native-pager-view';
import {
PagerViewOnPageScrollEventData,
PagerViewOnPageSelectedEventData,
PageScrollStateChangedEvent,
} from 'react-native-pager-view';
import { useEvent, useHandler } from 'react-native-reanimated';

export function useAnimatedPagerScrollHandler<TContext extends Record<string, unknown>>(
handlers: { onPageScroll: (e: PagerViewOnPageScrollEventData, context: TContext) => void },
interface CustomPagerViewOnPageScrollEventData
extends PagerViewOnPageScrollEventData {
eventName: string;
}

interface CustomPageScrollStateChangedEvent
extends PageScrollStateChangedEvent {
eventName: string;
}

interface CustomPagerViewOnPageSelectedEventData
extends PagerViewOnPageSelectedEventData {
eventName: string;
}

export function useAnimatedPagerScrollHandler<
TContext extends Record<string, unknown>
>(
handlers: {
onPageScroll: (
e: PagerViewOnPageScrollEventData,
context: TContext
) => void;
},
dependencies?: ReadonlyArray<unknown>
): (e: NativeSyntheticEvent<PagerViewOnPageScrollEventData>) => void {
const { context, doDependenciesDiffer } = useHandler<PagerViewOnPageScrollEventData, TContext>(handlers, dependencies);
const { context, doDependenciesDiffer } = useHandler<
PagerViewOnPageScrollEventData,
TContext
>(handlers, dependencies);

return useEvent<PagerViewOnPageScrollEventData>(
(event) => {
'worklet';
const { onPageScroll } = handlers;

if (onPageScroll && event.eventName.endsWith('onPageScroll')) {
if (
onPageScroll &&
(event as CustomPagerViewOnPageScrollEventData).eventName.endsWith(
'onPageScroll'
)
) {
onPageScroll(event, context);
}
},
['onPageScroll'],
doDependenciesDiffer,
doDependenciesDiffer
);
}

export function useAnimatedPagerScrollStateHandler<TContext extends Record<string, unknown>>(
handlers: { onPageScrollStateChanged: (e: PageScrollStateChangedEvent, context: TContext) => void },
dependencies?: ReadonlyArray<unknown>,
export function useAnimatedPagerScrollStateHandler<
TContext extends Record<string, unknown>
>(
handlers: {
onPageScrollStateChanged: (
e: PageScrollStateChangedEvent,
context: TContext
) => void;
},
dependencies?: ReadonlyArray<unknown>
): (e: NativeSyntheticEvent<PageScrollStateChangedEvent>) => void {
const { context, doDependenciesDiffer } = useHandler<PageScrollStateChangedEvent, TContext>(handlers, dependencies);
const { context, doDependenciesDiffer } = useHandler<
PageScrollStateChangedEvent,
TContext
>(handlers, dependencies);

return useEvent(
return useEvent<PageScrollStateChangedEvent>(
(event) => {
'worklet';
const { onPageScrollStateChanged } = handlers;

if (onPageScrollStateChanged && event.eventName.endsWith('onPageScrollStateChanged')) {
if (
onPageScrollStateChanged &&
(event as CustomPageScrollStateChangedEvent).eventName.endsWith(
'onPageScrollStateChanged'
)
) {
onPageScrollStateChanged(event, context);
}
},
['onPageScrollStateChanged'],
doDependenciesDiffer,
doDependenciesDiffer
);
}

export function useAnimatedPagerSelectedPageHandler<TContext extends Record<string, unknown>>(
handlers: { onPageSelected: (e: PagerViewOnPageSelectedEventData, context: TContext) => void },
export function useAnimatedPagerSelectedPageHandler<
TContext extends Record<string, unknown>
>(
handlers: {
onPageSelected: (
e: PagerViewOnPageSelectedEventData,
context: TContext
) => void;
},
dependencies?: ReadonlyArray<unknown>
): (e: NativeSyntheticEvent<PagerViewOnPageSelectedEventData>) => void {
const { context, doDependenciesDiffer } = useHandler<PagerViewOnPageSelectedEventData, TContext>(handlers, dependencies);
const { context, doDependenciesDiffer } = useHandler<
PagerViewOnPageSelectedEventData,
TContext
>(handlers, dependencies);

return useEvent<PagerViewOnPageSelectedEventData>(
(event) => {
'worklet';
const { onPageSelected } = handlers;

if (onPageSelected && event.eventName.endsWith('onPageSelected')) {
if (
onPageSelected &&
(event as CustomPagerViewOnPageSelectedEventData).eventName.endsWith(
'onPageSelected'
)
) {
onPageSelected(event, context);
}
},
['onPageSelected'],
doDependenciesDiffer,
doDependenciesDiffer
);
}
13 changes: 10 additions & 3 deletions Example/src/LayoutReanimation/AnimatedList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import React, { useState } from 'react';
import { Button, View, Text, ScrollView, TextInput } from 'react-native';
import {
Button,
View,
Text,
ScrollView,
TextInput,
StyleSheet,
} from 'react-native';
import Animated, {
Layout,
LightSpeedInLeft,
Expand All @@ -11,7 +18,7 @@ interface EventParticipant {
id: string;
}

const styles = {
const styles = StyleSheet.create({
participantView: {
borderBottomColor: 'black',
width: '100%',
Expand Down Expand Up @@ -44,7 +51,7 @@ const styles = {
flexDirection: 'row',
alignItems: 'center',
},
};
});

function Participant({
name,
Expand Down
Loading

0 comments on commit cb651ec

Please sign in to comment.