Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit 151df47

Browse files
author
Burak Güner
authored
Merge pull request atlj#2 from atlj/feature/spring-animations
Support for spring animations
2 parents aa7c6e8 + 314a1b4 commit 151df47

3 files changed

Lines changed: 68 additions & 30 deletions

File tree

README.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ A fast bottom modal that works with React Native Reanimated 2!
77
## Prerequisites
88

99
This module needs
10+
1011
[React Native Reanimated 2](https://docs.swmansion.com/react-native-reanimated/docs/installation) &
12+
1113
[React Native Gesture Handler](https://docs.swmansion.com/react-native-gesture-handler/docs/) to work
1214

1315
## 🚀 Installation
@@ -17,45 +19,51 @@ First make sure that you have installed all the prerequisites.
1719
### Using npm
1820

1921
```sh
22+
2023
npm install react-native-lightning-modal
24+
2125
```
2226

2327
### Using Yarn
2428

2529
```sh
30+
2631
yarn add react-native-lightning-modal
32+
2733
```
2834

2935
## ⚙️ Usage
3036

3137
### Using the useBottomModal hook 🪝
3238

33-
>This hook declares the ref for you
39+
> This hook declares the ref for you
3440
3541
```js
3642
import React from 'react';
43+
3744
import { View } from 'react-native';
3845

3946
import { useBottomModal, BottomModal } from 'react-native-lightning-modal';
4047

4148
export default function App() {
4249
const { dismiss, show, modalProps } = useBottomModal();
50+
4351
return (
4452
<View>
45-
<BottomModal height={500} {...modalProps}>
53+
<BottomModal height={500} {...modalProps}>
4654
{/* Your Content */}
4755
</BottomModal>
4856
</View>
4957
);
5058
}
5159
```
5260

53-
>Bottom modal component needs to be below other elements.
61+
> Bottom modal component needs to be below other elements.
5462
5563
You can then use
5664

5765
```js
58-
show()
66+
show();
5967
```
6068

6169
to show the modal
@@ -66,12 +74,14 @@ to show the modal
6674

6775
```js
6876
import React from 'react';
77+
6978
import { View } from 'react-native';
7079

7180
import { BottomModal, BottomModalRef } from 'react-native-lightning-modal';
7281

7382
export default function App() {
74-
const bottomModalRef = React.useRef<BottomModalRef>(null);
83+
const bottomModalRef = React.useRef < BottomModalRef > null;
84+
7585
return (
7686
<View>
7787
<BottomModal height={500} ref={bottomModalRef}>
@@ -80,13 +90,12 @@ export default function App() {
8090
</View>
8191
);
8292
}
83-
8493
```
8594

8695
You can than use
8796

8897
```js
89-
bottomModalRef.show()
98+
bottomModalRef.show();
9099
```
91100

92101
to show the modal
@@ -95,13 +104,15 @@ to show the modal
95104

96105
### PROPS
97106

98-
|Prop name | Description| Type | Required
99-
| ----------- | ----------- | ----------- | ----------- |
100-
|height |Height of modal's presented state. This is required for animation to behave correctly | number ||
101-
| backdropColor | Basically the color of a fullscreen view displayed below modaL | string ||
102-
|style | Style of modal's container | ViewStyle ||
103-
| easing | Easing function which modal will be presented. | Animated.EasingFunction ||
104-
| duration | Modal animation's duration in milliseconds. | number ||
107+
| Prop Name | Description | Type | Required | Defaults to |
108+
| ----------------- | ------------------------------------------------------------------------------------- | :-------------------------: | :------: | -------------------------------------: |
109+
| **height** | Height of modal's presented state. This is required for animation to behave correctly | _number_ |||
110+
| **backdropColor** | Basically the color of a fullscreen view displayed below modaL | _string_ || `undefined` |
111+
| **style** | Style of modal's container | _ViewStyle_ || `undefined` |
112+
| **animation** | Animation type to use, can get spring and timing, defaults to timing animation | _'spring' \| 'timing'_ || `'timing'` |
113+
| **timingConfig** | Timing animation's config if animation prop is set to 'timing' | _Animated.WithTimingConfig_ || `{duration: 300, easing: Easing.quad}` |
114+
| **springConfig** | Spring animation's config if animation prop is set to 'spring' | _Animated.WithSpringConfig_ || `undefined` |
115+
| **backdropStyle** | Style of the backdrop component | _ViewStyle_ || `undefined` |
105116

106117
## ➕ Contributing
107118

package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@
4141
"react native bottom modal",
4242
"react native fast modal",
4343
"react native performant modal",
44+
"react native bottom sheet",
45+
"react native animated bottom sheet",
46+
"react native animated bottom modal",
47+
"react native gesture modal",
48+
"react native reanimated gesture modal",
49+
"react native easy modal",
50+
"react native easy animated modal",
4451
"react-native-reanimated-2",
4552
"react native reanimated modal",
4653
"react native reanimated bottom modal",

src/components/BottomModal.tsx

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Animated, {
1515
useAnimatedStyle,
1616
useDerivedValue,
1717
useSharedValue,
18+
withSpring,
1819
withTiming,
1920
} from 'react-native-reanimated';
2021
import { screen } from '../utils';
@@ -26,7 +27,7 @@ export type BottomModalProps = {
2627
height: number;
2728

2829
/**
29-
* Basically the color of a fullscreen view displayed below modal.
30+
* Color of the fullscreen view displayed behind modal.
3031
* You can also change this by using backdropStyle prop.
3132
* @example rgba(255,255,255,0.8)
3233
*/
@@ -38,18 +39,24 @@ export type BottomModalProps = {
3839
style?: ViewStyle;
3940

4041
/**
41-
* Easing function which modal will be presented.
42-
* Since this also affects the time between user pressing the button and seeing the effect, a faster kind of curve function is recommended.
43-
* @default Easing.quad
42+
* Type of animation
43+
* uses withTiming if set to 'timing'
44+
* uses withSpring if set to 'spring'
45+
* @default "timing"
46+
* @example <<BottomModal animation='timing' timingConfig={{duration: 300, easing: Easing.quad}} height={500} ref={bottomModalRef}>>
4447
*/
45-
easing?: Animated.EasingFunction;
48+
animation?: 'spring' | 'timing';
4649

4750
/**
48-
* Modal animation's duration in milliseconds.
49-
* Since this also affects the time between user pressing the button and seeing the effect, a smaler number is recommended.
50-
* @default 300
51+
* The configuration to use if animation prop is set to 'spring'
5152
*/
52-
duration?: number;
53+
springConfig?: Animated.WithSpringConfig;
54+
55+
/**
56+
* The configuration to use if animation prop is set to 'timing'
57+
* @default {duration: 300, easing: Easing.quad}
58+
*/
59+
timingConfig?: Animated.WithTimingConfig;
5360

5461
/**
5562
* Style of backdrop component
@@ -79,7 +86,16 @@ const BottomModal = React.forwardRef<
7986
PropsWithChildren<BottomModalProps>
8087
>(
8188
(
82-
{ height, backdropColor, style, easing, children, duration, backdropStyle },
89+
{
90+
height,
91+
backdropColor,
92+
style,
93+
children,
94+
backdropStyle,
95+
animation,
96+
springConfig,
97+
timingConfig,
98+
},
8399
ref
84100
) => {
85101
const top = useSharedValue(screen.height);
@@ -88,12 +104,13 @@ const BottomModal = React.forwardRef<
88104
const updateTop = useCallback(
89105
(value: number) => {
90106
'worklet';
91-
return withTiming(value, {
92-
easing,
93-
duration,
94-
});
107+
if (animation === 'spring') {
108+
return withSpring(value, springConfig);
109+
} else {
110+
return withTiming(value, timingConfig);
111+
}
95112
},
96-
[easing, duration]
113+
[timingConfig, animation, springConfig]
97114
);
98115

99116
const isActive = useDerivedValue<boolean>(() => {
@@ -179,7 +196,10 @@ const BottomModal = React.forwardRef<
179196
}
180197
);
181198

182-
BottomModal.defaultProps = { duration: 300, easing: Easing.quad };
199+
BottomModal.defaultProps = {
200+
timingConfig: { duration: 300, easing: Easing.quad },
201+
animation: 'timing',
202+
};
183203

184204
const styles = StyleSheet.create({
185205
fullScreen: {

0 commit comments

Comments
 (0)