Skip to content

Commit cd8db86

Browse files
committed
feat: implement reanimated (not yet working)
1 parent 40ae593 commit cd8db86

File tree

3 files changed

+83
-5
lines changed

3 files changed

+83
-5
lines changed

example/src/screens/MapScreen.tsx

+71-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { useRef } from 'react'
2-
import { Text, View, type TextStyle, type ViewStyle } from 'react-native'
3-
import { TrueSheet } from '@lodev09/react-native-true-sheet'
2+
import { Text, TouchableOpacity, View, type StyleProp, type TextStyle, type ViewStyle } from 'react-native'
3+
import { TrueSheet, type SizeInfo } from '@lodev09/react-native-true-sheet'
44
import MapView from 'react-native-maps'
5+
import { useSafeAreaInsets } from 'react-native-safe-area-context'
6+
import Animated, { useSharedValue, withSpring, useAnimatedStyle, useEvent, useHandler } from 'react-native-reanimated'
57

68
import {
79
BasicSheet,
@@ -12,7 +14,10 @@ import {
1214
ScrollViewSheet,
1315
} from '../components/sheets'
1416
import { Button, Spacer } from '../components'
15-
import { BLUE, DARK, GRAY, SPACING } from '../utils'
17+
import { BLUE, DARK, GRAY, SPACING, SPRING_CONFIG } from '../utils'
18+
19+
const AnimatedButton = Animated.createAnimatedComponent(TouchableOpacity)
20+
const AnimatedTrueSheet = Animated.createAnimatedComponent(TrueSheet)
1621

1722
export const MapScreen = () => {
1823
const sheetRef = useRef<TrueSheet>(null)
@@ -24,11 +29,54 @@ export const MapScreen = () => {
2429
const gestureSheet = useRef<TrueSheet>(null)
2530
const blankSheet = useRef<TrueSheet>(null)
2631

32+
const insets = useSafeAreaInsets()
33+
const buttonY = useSharedValue(0)
34+
35+
const handlers = {
36+
onDragChange: (e: SizeInfo, _: Record<string, unknown>) => {
37+
'worklet'
38+
buttonY.value = -e.value
39+
},
40+
}
41+
42+
const { context, doDependenciesDiffer } = useHandler(handlers, [])
43+
44+
const dragChangeHandler = useEvent<SizeInfo>(
45+
(event) => {
46+
'worklet'
47+
console.log(event)
48+
const { onDragChange } = handlers
49+
if (onDragChange && event.eventName.endsWith('onDragChange')) {
50+
onDragChange(event, context)
51+
}
52+
},
53+
['onDragChange'],
54+
doDependenciesDiffer,
55+
)
56+
2757
const presentBasicSheet = async (index = 0) => {
2858
await basicSheet.current?.present(index)
2959
console.log('Sheet 1 present async')
3060
}
3161

62+
const $mapStyleButtonStyles: StyleProp<ViewStyle> = [
63+
$mapStyle,
64+
{ bottom: insets.bottom + SPACING },
65+
useAnimatedStyle(() => ({
66+
transform: [
67+
{ translateY: buttonY.value }
68+
]
69+
}))
70+
]
71+
72+
const handlePresent = (sizeInfo: SizeInfo) => {
73+
buttonY.value = withSpring(-sizeInfo.value, SPRING_CONFIG)
74+
}
75+
76+
const handleOnDragEnd = (sizeInfo: SizeInfo) => {
77+
buttonY.value = withSpring(-sizeInfo.value, SPRING_CONFIG)
78+
}
79+
3280
return (
3381
<View style={$container}>
3482
<MapView
@@ -46,7 +94,8 @@ export const MapScreen = () => {
4694
userInterfaceStyle="dark"
4795
/>
4896

49-
<TrueSheet
97+
<AnimatedButton activeOpacity={0.6} style={$mapStyleButtonStyles} />
98+
<AnimatedTrueSheet
5099
sizes={['15%', 'auto', 'large']}
51100
ref={sheetRef}
52101
blurTint="dark"
@@ -57,6 +106,9 @@ export const MapScreen = () => {
57106
dismissible={false}
58107
cornerRadius={12}
59108
initialIndex={1}
109+
onPresent={handlePresent}
110+
onDragChange={dragChangeHandler}
111+
onDragEnd={handleOnDragEnd}
60112
// initialIndexAnimated={false}
61113
onMount={() => {
62114
// sheetRef.current?.present(1)
@@ -84,11 +136,25 @@ export const MapScreen = () => {
84136
<FlatListSheet ref={flatListSheet} />
85137
<GestureSheet ref={gestureSheet} />
86138
<BlankSheet ref={blankSheet} />
87-
</TrueSheet>
139+
</AnimatedTrueSheet>
88140
</View>
89141
)
90142
}
91143

144+
const $mapStyle: ViewStyle = {
145+
position: 'absolute',
146+
right: SPACING,
147+
height: SPACING * 3,
148+
width: SPACING * 3,
149+
borderRadius: (SPACING * 3) / 2,
150+
backgroundColor: BLUE,
151+
shadowColor: DARK,
152+
shadowOffset: { width: 0, height: 2 },
153+
shadowOpacity: 0.3,
154+
shadowRadius: 2,
155+
elevation: 4,
156+
}
157+
92158
const $container: ViewStyle = {
93159
backgroundColor: BLUE,
94160
justifyContent: 'center',

example/src/utils/constants.ts

+10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { TextStyle } from 'react-native'
2+
import type { WithSpringConfig } from 'react-native-reanimated'
23

34
export const SPACING = 16
45
export const INPUT_HEIGHT = SPACING * 3
@@ -14,3 +15,12 @@ export const BLUE = '#3784d7'
1415
export const DARK_BLUE = '#1f64ae'
1516

1617
export const $WHITE_TEXT: TextStyle = { color: 'white' }
18+
19+
export const SPRING_CONFIG: WithSpringConfig = {
20+
damping: 500,
21+
stiffness: 1000,
22+
mass: 3,
23+
overshootClamping: true,
24+
restDisplacementThreshold: 10,
25+
restSpeedThreshold: 10,
26+
}

ios/TrueSheetView.swift

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class TrueSheetView: UIView, RCTInvalidating, TrueSheetViewControllerDelegate {
1212

1313
// MARK: - Events
1414

15+
// TODO: migrate to RCTEventDispatcher
16+
// https://github.com/software-mansion/react-native-reanimated/issues/1229#issuecomment-735609106
1517
@objc var onMount: RCTDirectEventBlock?
1618
@objc var onDismiss: RCTDirectEventBlock?
1719
@objc var onPresent: RCTDirectEventBlock?

0 commit comments

Comments
 (0)