Skip to content

Commit

Permalink
chore: added useReactiveValue/s (#65)
Browse files Browse the repository at this point in the history
* chore: added useReactiveVlaue/s

* chore: updated basic example
  • Loading branch information
gorhom authored Nov 15, 2020
1 parent fd82d9f commit dbd6983
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 118 deletions.
2 changes: 1 addition & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -481,4 +481,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: aff15ad1e9bd5c910cdc2b575487ce8c56864ae7

COCOAPODS: 1.9.1
COCOAPODS: 1.9.3
133 changes: 19 additions & 114 deletions example/src/screens/static/BasicExample.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,32 @@
import React, { useCallback, useMemo, useRef, useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { useHeaderHeight } from '@react-navigation/stack';
import Animated, {
interpolate,
concat,
Extrapolate,
} from 'react-native-reanimated';
import { concat } from 'react-native-reanimated';
import { ReText, useValue } from 'react-native-redash';
import BottomSheet, { BottomSheetFlatList } from '@gorhom/bottom-sheet';
import Handle from '../../components/handle';
import BottomSheet from '@gorhom/bottom-sheet';
import Button from '../../components/button';
import ContactList from '../../components/contactList';
import { useSafeArea } from 'react-native-safe-area-context';

const BasicExample = () => {
// state
const [enabled, setEnabled] = useState(true);
const [dynamicSnapPoint, setDynamicSnapPoint] = useState(450);

// hooks
const bottomSheetRef = useRef<BottomSheet>(null);
const headerHeight = useHeaderHeight();
const { top: topSafeArea } = useSafeArea();

// variables
const snapPoints = useMemo(() => [150, 300, 450], []);
const snapPoints = useMemo(() => [150, dynamicSnapPoint], [dynamicSnapPoint]);
const position = useValue<number>(0);

// styles
const shadowOverlayStyle = useMemo(
const containerStyle = useMemo(
() => ({
...styles.shadowOverlay,
opacity: interpolate(position, {
inputRange: [300, 450],
outputRange: [0, 1],
extrapolate: Extrapolate.CLAMP,
}),
...styles.container,
paddingTop: topSafeArea,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
[topSafeArea]
);

// callbacks
Expand All @@ -44,31 +36,20 @@ const BasicExample = () => {
const handleSnapPress = useCallback(index => {
bottomSheetRef.current?.snapTo(index);
}, []);

const handleClosePress = useCallback(() => {
bottomSheetRef.current?.close();
}, []);
const handleIncreaseDynamicSnapPoint = useCallback(() => {
setDynamicSnapPoint(state => state + 50);
}, []);

// renders
// const renderHeader = useCallback(() => {
// return (
// <View style={styles.headerContainer}>
// <Text style={styles.title}>Basic Screen</Text>
// </View>
// );
// }, []);

return (
<View style={styles.container}>
<Button
label="Snap To 450"
style={styles.buttonContainer}
onPress={() => handleSnapPress(2)}
/>
<View style={containerStyle}>
<Button
label="Snap To 300"
label="Increase Dynamic Snap Point"
style={styles.buttonContainer}
onPress={() => handleSnapPress(1)}
onPress={handleIncreaseDynamicSnapPoint}
/>
<Button
label="Snap To 150"
Expand All @@ -87,92 +68,16 @@ const BasicExample = () => {
onPress={() => setEnabled(state => !state)}
/>
<ReText text={concat('Position from bottom: ', position)} />
<Animated.View pointerEvents="none" style={shadowOverlayStyle} />
<BottomSheet
ref={bottomSheetRef}
enabled={enabled}
snapPoints={snapPoints}
initialSnapIndex={1}
handleComponent={Handle}
topInset={headerHeight}
topInset={topSafeArea}
animatedPosition={position}
onChange={handleSheetChanges}
>
{/* <View
style={{
position: 'absolute',
left: 0,
right: 0,
height: (25 * sheetHeight) / 100,
backgroundColor: 'rgba(0,0,0,0.25)',
}}
/>
<View
style={{
position: 'absolute',
left: 0,
right: 0,
height: (50 * sheetHeight) / 100,
backgroundColor: 'rgba(0,0,0,0.50)',
}}
/>
<View
style={{
position: 'absolute',
left: windowWidth / 2 - 25,
width: 50,
height: 10,
backgroundColor: 'red',
}}
/>
<View
style={{
position: 'absolute',
left: windowWidth / 2 - 25,
bottom: 0,
width: 50,
height: 10,
backgroundColor: 'red',
}}
/>
<View
style={{
position: 'absolute',
bottom: sheetHeight / 2 - 25,
width: 10,
height: 50,
backgroundColor: 'red',
}}
/>
<View
style={{
position: 'absolute',
bottom: sheetHeight / 2 - 25,
right: 0,
width: 10,
height: 50,
backgroundColor: 'red',
}}
/> */}

{/* <Button
label="Open"
style={styles.buttonContainer}
onPress={() => handleSnapPress(1)}
/> */}
{/* <ContactList type="ScrollView" header={renderHeader} /> */}
<View style={{ height: 100, backgroundColor: 'blue' }} />
<BottomSheetFlatList
contentContainerStyle={{ flexGrow: 1, backgroundColor: '#fff' }}
data={[0, 1, 2, 3, 4, 5, 6, 7, 8]}
renderItem={() => (
<View
style={{ backgroundColor: 'red', height: 100, marginBottom: 20 }}
/>
)}
/>
<View style={{ height: 100, backgroundColor: 'green' }} />
<ContactList type="View" />
</BottomSheet>
</View>
);
Expand Down
10 changes: 7 additions & 3 deletions src/components/bottomSheet/useTransition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { State } from 'react-native-gesture-handler';
import { useClock, useValue, snapPoint } from 'react-native-redash';
import type { BottomSheetAnimationConfigs } from './types';
import { GESTURE } from '../../constants';
import { useReactiveValue, useReactiveValues } from '../../hooks';

interface TransitionProps extends Required<BottomSheetAnimationConfigs> {
contentPanGestureState: Animated.Value<State>;
Expand All @@ -48,11 +49,12 @@ export const useTransition = ({
handlePanGestureTranslationY,
handlePanGestureVelocityY,
scrollableContentOffsetY,
snapPoints,
snapPoints: _snapPoints,
initialPosition,
}: TransitionProps) => {
const currentGesture = useValue<GESTURE>(GESTURE.UNDETERMINED);
const currentPosition = useValue(initialPosition);
const currentPosition = useReactiveValue(initialPosition);
const snapPoints = useReactiveValues(_snapPoints);

const isPanningContent = useMemo(
() => eq(contentPanGestureState, State.ACTIVE),
Expand Down Expand Up @@ -86,11 +88,13 @@ export const useTransition = ({
frameTime: new Animated.Value(0),
time: new Animated.Value(0),
}),
[initialPosition]
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);

const finishTiming = useMemo(
() => [
// debug('finish timing', config.toValue),
set(currentGesture, GESTURE.UNDETERMINED),
set(shouldAnimate, 0),
set(currentPosition, config.toValue),
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export { useBottomSheetInternal } from './useBottomSheetInternal';
export { useScrollable } from './useScrollable';
export { useScrollableInternal } from './useScrollableInternal';
export { useStableCallback } from './useStableCallback';
export { useReactiveValue } from './useReactiveValue';
export { useReactiveValues } from './useReactiveValues';
20 changes: 20 additions & 0 deletions src/hooks/useReactiveValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useEffect, useRef } from 'react';
import Animated from 'react-native-reanimated';

export const useReactiveValue = (value: number) => {
// ref
const ref = useRef<Animated.Value<number>>(null);
if (ref.current === null) {
// @ts-ignore
ref.current = new Animated.Value(value);
}

// effects
useEffect(() => {
if (ref.current) {
ref.current.setValue(value);
}
}, [value]);

return ref.current;
};
47 changes: 47 additions & 0 deletions src/hooks/useReactiveValues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useEffect, useRef } from 'react';
import Animated from 'react-native-reanimated';

export const useReactiveValues = (values: number[]) => {
// ref
const ref = useRef<Animated.Value<number>[]>(null);
if (ref.current === null) {
// @ts-ignore
ref.current = [];
values.map(value => {
// @ts-ignore
ref.current.push(new Animated.Value(value));
});
}

// effects
useEffect(() => {
if (ref.current) {
values.map((value, index) => {
// @ts-ignore
if (ref.current[index]) {
// update current value
// @ts-ignore
ref.current[index].setValue(value);
} else {
// insert current value
// @ts-ignore
ref.current.push(new Animated.Value(value));
}
});

/**
* if previous animated array has more values than the updated
* array, we will need to set the extra values to the last
* value of the updated array.
*/
if (values.length < ref.current.length) {
const lastValue = values[values.length - 1];
for (let i = values.length - 1; i <= ref.current.length - 1; i++) {
ref.current[i].setValue(lastValue);
}
}
}
}, [values]);

return ref.current!;
};

0 comments on commit dbd6983

Please sign in to comment.