mirror of
https://github.com/zhigang1992/react-native-bottom-sheet.git
synced 2026-04-29 04:35:38 +08:00
docs: updated documents
This commit is contained in:
12
README.md
12
README.md
@@ -51,7 +51,7 @@ yarn add @gorhom/bottom-sheet
|
||||
npm install @gorhom/bottom-sheet
|
||||
```
|
||||
|
||||
> ⚠️ You need to install [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) & [react-native-gesture-handler](https://github.com/software-mansion/react-native-gesture-handler) and follow their installation instructions.
|
||||
> ⚠️ You need to install [react-native-reanimated v2](https://github.com/software-mansion/react-native-reanimated) & [react-native-gesture-handler](https://github.com/software-mansion/react-native-gesture-handler) and follow their installation instructions.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -131,15 +131,15 @@ Snapping animation easing function.
|
||||
|
||||
#### `animatedPosition`
|
||||
|
||||
Animated value to be used as a callback for the position node internally.
|
||||
Animated shared value to be used as a callback for the position node internally.
|
||||
|
||||
> `required:` NO | `type:` Animated.Value<number>
|
||||
> `required:` NO | `type:` Animated.SharedValue<number>
|
||||
|
||||
#### `animatedPositionIndex`
|
||||
|
||||
Animated value to be used as a callback for the position index node internally.
|
||||
Animated shared value to be used as a callback for the position index node internally.
|
||||
|
||||
> `required:` NO | `type:` Animated.Value<number>
|
||||
> `required:` NO | `type:` Animated.SharedValue<number>
|
||||
|
||||
#### `handleComponent`
|
||||
|
||||
@@ -163,7 +163,7 @@ Callback when sheet position changed to a provided point.
|
||||
|
||||
A scrollable node or normal view.
|
||||
|
||||
> `required:` YES | `type:` React.ReactNode[] | React.ReactNode
|
||||
> `required:` YES | `type:` () => React.ReactNode | React.ReactNode[] | React.ReactNode
|
||||
|
||||
## Methods
|
||||
|
||||
|
||||
@@ -10,8 +10,25 @@ Here is an example of a custom handle component:
|
||||
import React, { useMemo } from 'react';
|
||||
import { StyleProp, StyleSheet, ViewStyle } from 'react-native';
|
||||
import { BottomSheetHandleProps } from '@gorhom/bottom-sheet';
|
||||
import Animated, { interpolate, Extrapolate } from 'react-native-reanimated';
|
||||
import { transformOrigin, toRad } from 'react-native-redash';
|
||||
import Animated, {
|
||||
Extrapolate,
|
||||
interpolate,
|
||||
useAnimatedStyle,
|
||||
useDerivedValue,
|
||||
} from 'react-native-reanimated';
|
||||
import { toRad } from 'react-native-redash';
|
||||
|
||||
// @ts-ignore
|
||||
export const transformOrigin = ({ x, y }, ...transformations) => {
|
||||
'worklet';
|
||||
return [
|
||||
{ translateX: x },
|
||||
{ translateY: y },
|
||||
...transformations,
|
||||
{ translateX: x * -1 },
|
||||
{ translateY: y * -1 },
|
||||
];
|
||||
};
|
||||
|
||||
interface HandleProps extends BottomSheetHandleProps {
|
||||
style?: StyleProp<ViewStyle>;
|
||||
@@ -19,78 +36,86 @@ interface HandleProps extends BottomSheetHandleProps {
|
||||
|
||||
const Handle: React.FC<HandleProps> = ({ style, animatedPositionIndex }) => {
|
||||
//#region animations
|
||||
const borderTopRadius = interpolate(animatedPositionIndex, {
|
||||
inputRange: [1, 2],
|
||||
outputRange: [20, 0],
|
||||
extrapolate: Extrapolate.CLAMP,
|
||||
});
|
||||
const indicatorTransformOriginY = interpolate(animatedPositionIndex, {
|
||||
inputRange: [0, 1, 2],
|
||||
outputRange: [-1, 0, 1],
|
||||
extrapolate: Extrapolate.CLAMP,
|
||||
});
|
||||
const leftIndicatorRotate = interpolate(animatedPositionIndex, {
|
||||
inputRange: [0, 1, 2],
|
||||
outputRange: [toRad(-30), 0, toRad(30)],
|
||||
extrapolate: Extrapolate.CLAMP,
|
||||
});
|
||||
const rightIndicatorRotate = interpolate(animatedPositionIndex, {
|
||||
inputRange: [0, 1, 2],
|
||||
outputRange: [toRad(30), 0, toRad(-30)],
|
||||
extrapolate: Extrapolate.CLAMP,
|
||||
});
|
||||
const indicatorTransformOriginY = useDerivedValue(() =>
|
||||
interpolate(
|
||||
animatedPositionIndex.value,
|
||||
[0, 1, 2],
|
||||
[-1, 0, 1],
|
||||
Extrapolate.CLAMP
|
||||
)
|
||||
);
|
||||
//#endregion
|
||||
|
||||
//#region styles
|
||||
const containerStyle = useMemo(
|
||||
() => [
|
||||
styles.header,
|
||||
style,
|
||||
{
|
||||
borderTopLeftRadius: borderTopRadius,
|
||||
borderTopRightRadius: borderTopRadius,
|
||||
},
|
||||
],
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[style]
|
||||
);
|
||||
const leftIndicatorStyle = useMemo(
|
||||
() => ({
|
||||
...styles.indicator,
|
||||
...styles.leftIndicator,
|
||||
const containerStyle = useMemo(() => [styles.header, style], [style]);
|
||||
const containerAnimatedStyle = useAnimatedStyle(() => {
|
||||
const borderTopRadius = interpolate(
|
||||
animatedPositionIndex.value,
|
||||
[1, 2],
|
||||
[20, 0],
|
||||
Extrapolate.CLAMP
|
||||
);
|
||||
return {
|
||||
borderTopLeftRadius: borderTopRadius,
|
||||
borderTopRightRadius: borderTopRadius,
|
||||
};
|
||||
});
|
||||
const leftIndicatorAnimatedStyle = useAnimatedStyle(() => {
|
||||
const leftIndicatorRotate = interpolate(
|
||||
animatedPositionIndex.value,
|
||||
[0, 1, 2],
|
||||
[toRad(-30), 0, toRad(30)],
|
||||
Extrapolate.CLAMP
|
||||
);
|
||||
return {
|
||||
transform: transformOrigin(
|
||||
{ x: 0, y: indicatorTransformOriginY },
|
||||
{ x: 0, y: indicatorTransformOriginY.value },
|
||||
{
|
||||
rotate: `${leftIndicatorRotate}rad`,
|
||||
},
|
||||
{
|
||||
rotate: leftIndicatorRotate,
|
||||
translateX: -5,
|
||||
}
|
||||
),
|
||||
}),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
);
|
||||
};
|
||||
});
|
||||
const rightIndicatorStyle = useMemo(
|
||||
() => ({
|
||||
...styles.indicator,
|
||||
...styles.rightIndicator,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
const rightIndicatorAnimatedStyle = useAnimatedStyle(() => {
|
||||
const rightIndicatorRotate = interpolate(
|
||||
animatedPositionIndex.value,
|
||||
[0, 1, 2],
|
||||
[toRad(30), 0, toRad(-30)],
|
||||
Extrapolate.CLAMP
|
||||
);
|
||||
return {
|
||||
transform: transformOrigin(
|
||||
{ x: 0, y: indicatorTransformOriginY },
|
||||
{ x: 0, y: indicatorTransformOriginY.value },
|
||||
{
|
||||
rotate: `${rightIndicatorRotate}rad`,
|
||||
},
|
||||
{
|
||||
rotate: rightIndicatorRotate,
|
||||
translateX: 5,
|
||||
}
|
||||
),
|
||||
}),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
);
|
||||
};
|
||||
});
|
||||
//#endregion
|
||||
|
||||
// render
|
||||
return (
|
||||
<Animated.View style={containerStyle} renderToHardwareTextureAndroid={true}>
|
||||
<Animated.View style={leftIndicatorStyle} />
|
||||
<Animated.View style={rightIndicatorStyle} />
|
||||
<Animated.View
|
||||
style={[containerStyle, containerAnimatedStyle]} renderToHardwareTextureAndroid={true}
|
||||
>
|
||||
<Animated.View style={[leftIndicatorStyle, leftIndicatorAnimatedStyle]} />
|
||||
<Animated.View
|
||||
style={[rightIndicatorStyle, rightIndicatorAnimatedStyle]}
|
||||
/>
|
||||
</Animated.View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,7 +7,6 @@ import React, {
|
||||
} from 'react';
|
||||
import { SafeAreaView, StyleSheet, Text, View } from 'react-native';
|
||||
import BottomSheet from '@gorhom/bottom-sheet';
|
||||
import Button from '../components/button';
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
|
||||
const App = () => {
|
||||
|
||||
Reference in New Issue
Block a user