Skip to content

Commit 12997c3

Browse files
committed
chore: add gesture sheet example
1 parent 6525dba commit 12997c3

File tree

5 files changed

+278
-4
lines changed

5 files changed

+278
-4
lines changed

example/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
"@react-native/virtualized-lists": "0.75.0-main",
1717
"expo": "~50.0.15",
1818
"react": "18.2.0",
19-
"react-native": "0.73.6"
19+
"react-native": "0.73.6",
20+
"react-native-gesture-handler": "~2.14.0",
21+
"react-native-reanimated": "~3.6.2"
2022
},
2123
"devDependencies": {
2224
"@babel/core": "^7.20.0",

example/src/App.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useRef } from 'react'
22
import { View, type ViewStyle } from 'react-native'
33
import { TrueSheet } from '@lodev09/react-native-true-sheet'
44

5-
import { BasicSheet, FlatListSheet, PromptSheet, ScrollViewSheet } from './sheets'
5+
import { BasicSheet, FlatListSheet, GestureSheet, PromptSheet, ScrollViewSheet } from './sheets'
66
import { Button } from './components'
77
import { BLUE } from './utils'
88

@@ -11,6 +11,7 @@ export default function App() {
1111
const promptSheet = useRef<TrueSheet>(null)
1212
const scrollViewSheet = useRef<TrueSheet>(null)
1313
const flatListSheet = useRef<TrueSheet>(null)
14+
const gestureSheet = useRef<TrueSheet>(null)
1415

1516
const presentBasicSheet = async (index = 0) => {
1617
await basicSheet.current?.present(index)
@@ -23,11 +24,13 @@ export default function App() {
2324
<Button text="TrueSheet Prompt" onPress={() => promptSheet.current?.present()} />
2425
<Button text="TrueSheet ScrollView" onPress={() => scrollViewSheet.current?.present()} />
2526
<Button text="TrueSheet FlatList" onPress={() => flatListSheet.current?.present()} />
27+
<Button text="TrueSheet Gestures" onPress={() => gestureSheet.current?.present()} />
2628

2729
<BasicSheet ref={basicSheet} />
2830
<PromptSheet ref={promptSheet} />
2931
<ScrollViewSheet ref={scrollViewSheet} />
3032
<FlatListSheet ref={flatListSheet} />
33+
<GestureSheet ref={gestureSheet} />
3134
</View>
3235
)
3336
}

example/src/sheets/GestureSheet.tsx

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import React, { forwardRef, useRef, type Ref, useImperativeHandle } from 'react'
2+
import { type ViewStyle, useWindowDimensions } from 'react-native'
3+
import { TrueSheet, type TrueSheetProps } from '@lodev09/react-native-true-sheet'
4+
import Animated, { useAnimatedStyle, useSharedValue, withDecay } from 'react-native-reanimated'
5+
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler'
6+
7+
import { DARK, DARK_GRAY, GRABBER_COLOR, SPACING, times } from '../utils'
8+
import { Button, DemoContent, Footer } from '../components'
9+
10+
const BOXES_COUNT = 20
11+
const CONTAINER_HEIGHT = 200
12+
const BOX_GAP = SPACING
13+
const BOX_SIZE = CONTAINER_HEIGHT - SPACING * 2
14+
15+
interface GestureSheetProps extends TrueSheetProps {}
16+
17+
export const GestureSheet = forwardRef((props: GestureSheetProps, ref: Ref<TrueSheet>) => {
18+
const sheetRef = useRef<TrueSheet>(null)
19+
20+
const scrollX = useSharedValue(0)
21+
const dimensions = useWindowDimensions()
22+
23+
const dismiss = async () => {
24+
await sheetRef.current?.dismiss()
25+
}
26+
27+
const $animatedContainer: ViewStyle = useAnimatedStyle(() => ({
28+
transform: [{ translateX: scrollX.value }],
29+
}))
30+
31+
const pan = Gesture.Pan()
32+
.onChange((e) => {
33+
scrollX.value += e.changeX
34+
})
35+
.onFinalize((e) => {
36+
scrollX.value = withDecay({
37+
velocity: e.velocityX,
38+
rubberBandEffect: true,
39+
clamp: [-((BOX_SIZE + BOX_GAP) * BOXES_COUNT) + dimensions.width - SPACING, 0],
40+
})
41+
})
42+
.activeOffsetX([-10, 10])
43+
44+
useImperativeHandle<TrueSheet | null, TrueSheet | null>(ref, () => sheetRef.current)
45+
46+
return (
47+
<TrueSheet
48+
sizes={['auto']}
49+
ref={sheetRef}
50+
contentContainerStyle={$content}
51+
blurTint="dark"
52+
backgroundColor={DARK}
53+
cornerRadius={12}
54+
grabberProps={{ color: GRABBER_COLOR }}
55+
onDismiss={() => console.log('Gesture sheet dismissed!')}
56+
onPresent={({ index, value }) =>
57+
console.log(`Gesture sheet presented with size of ${value} at index: ${index}`)
58+
}
59+
onSizeChange={({ index, value }) => console.log(`Resized to:`, value, 'at index:', index)}
60+
FooterComponent={<Footer />}
61+
{...props}
62+
>
63+
<GestureHandlerRootView>
64+
<GestureDetector gesture={pan}>
65+
<Animated.View style={[$panContainer, $animatedContainer]}>
66+
{times(BOXES_COUNT, (i) => (
67+
<DemoContent key={i} text={String(i + 1)} style={$box} />
68+
))}
69+
</Animated.View>
70+
</GestureDetector>
71+
<Button text="Dismis" onPress={dismiss} />
72+
</GestureHandlerRootView>
73+
</TrueSheet>
74+
)
75+
})
76+
77+
GestureSheet.displayName = 'GestureSheet'
78+
79+
const $content: ViewStyle = {
80+
padding: SPACING,
81+
}
82+
83+
const $panContainer: ViewStyle = {
84+
height: CONTAINER_HEIGHT,
85+
flexDirection: 'row',
86+
paddingVertical: SPACING,
87+
marginBottom: SPACING,
88+
gap: BOX_GAP,
89+
}
90+
91+
const $box: ViewStyle = {
92+
backgroundColor: DARK_GRAY,
93+
width: BOX_SIZE,
94+
height: BOX_SIZE,
95+
alignItems: 'center',
96+
justifyContent: 'center',
97+
}

example/src/sheets/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from './BasicSheet'
22
export * from './PromptSheet'
33
export * from './ScrollViewSheet'
44
export * from './FlatListSheet'
5+
export * from './GestureSheet'

0 commit comments

Comments
 (0)