Skip to content

Commit 44b7f25

Browse files
committed
feat: add share components
1 parent 3efb78a commit 44b7f25

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed

share/components/BottomSheet.tsx

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import React, {ReactNode, forwardRef, useCallback, useImperativeHandle, useRef} from 'react'
2+
import {
3+
BottomSheetBackdrop,
4+
BottomSheetBackdropProps,
5+
BottomSheetModal,
6+
BottomSheetProps as RNBottomSheetProps,
7+
} from '@gorhom/bottom-sheet'
8+
import {StyleSheet, View} from 'react-native'
9+
import {colors, metrics, responsiveWidth} from '../themes'
10+
11+
const SNAP_POINTS = ['50%']
12+
13+
export type BottomSheetMethods = {
14+
open: () => void
15+
close: () => void
16+
snapToIndex: (index: number) => void
17+
}
18+
19+
export interface BottomSheetProps extends RNBottomSheetProps {
20+
showSearchBox?: boolean
21+
searchValue?: string
22+
onSearchChange?: (text: string) => void
23+
children: ReactNode | React.JSX.Element
24+
snapPoints?: string[]
25+
onClose?: () => void
26+
}
27+
28+
export const BottomSheet = forwardRef<BottomSheetMethods, BottomSheetProps>(
29+
({children, snapPoints = SNAP_POINTS, onClose, ...rest}, ref) => {
30+
const sheetRef = useRef<BottomSheetModal>(null)
31+
32+
useImperativeHandle(ref, () => ({
33+
open: () => {
34+
sheetRef.current?.present()
35+
},
36+
close: () => {
37+
sheetRef.current?.close()
38+
},
39+
snapToIndex: (index: number) => {
40+
sheetRef.current?.snapToIndex(index)
41+
},
42+
}))
43+
44+
const handleDismiss = useCallback(() => {
45+
onClose?.()
46+
}, [onClose])
47+
48+
const renderBackdrop = useCallback(
49+
(props: BottomSheetBackdropProps) => <BottomSheetBackdrop {...props} pressBehavior="none" />,
50+
[],
51+
)
52+
53+
return (
54+
<BottomSheetModal
55+
ref={sheetRef}
56+
index={0}
57+
snapPoints={snapPoints}
58+
handleIndicatorStyle={styles.indicator}
59+
enablePanDownToClose
60+
onDismiss={handleDismiss}
61+
backdropComponent={renderBackdrop}
62+
stackBehavior="push"
63+
{...rest}>
64+
<View style={styles.container}>{children}</View>
65+
</BottomSheetModal>
66+
)
67+
},
68+
)
69+
70+
const styles = StyleSheet.create({
71+
container: {
72+
flex: 1,
73+
width: '100%',
74+
paddingHorizontal: metrics.marginHorizontal,
75+
backgroundColor: colors.white,
76+
},
77+
backdrop: {
78+
...StyleSheet.absoluteFillObject,
79+
zIndex: 0,
80+
},
81+
indicator: {
82+
backgroundColor: colors.gray700,
83+
width: responsiveWidth(36),
84+
borderRadius: metrics.tiny,
85+
height: metrics.tiny,
86+
},
87+
})
88+
89+
BottomSheet.displayName = 'BottomSheet'

share/components/FormInput.tsx

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react'
2+
import {Controller} from 'react-hook-form'
3+
import {UseControllerProps} from 'react-hook-form/dist/types/controller'
4+
import {TextInput} from './TextInput'
5+
import {TextInputProps} from 'rn-base-component'
6+
7+
interface IProps extends TextInputProps {
8+
control: UseControllerProps['control']
9+
id: string
10+
}
11+
12+
export const FormInput = ({control, id, ...rest}: IProps) => (
13+
<Controller
14+
control={control}
15+
render={({field: {onChange, onBlur, value}, fieldState: {error}}) => (
16+
<TextInput {...rest} value={value} onChangeText={onChange} onBlur={onBlur} errorText={error?.message} />
17+
)}
18+
name={id}
19+
/>
20+
)

share/components/Header.tsx

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import React from 'react'
2+
import {StyleProp, StyleSheet, TouchableOpacity, View, ViewStyle} from 'react-native'
3+
import {Text} from 'rn-base-component'
4+
import {useNavigation} from '@react-navigation/native'
5+
import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
6+
import {colors, fonts, fontSizes, metrics} from '../themes'
7+
8+
interface IHeaderProp {
9+
title?: string
10+
leftStyle?: StyleProp<ViewStyle>
11+
centerStyle?: StyleProp<ViewStyle>
12+
rightStyle?: StyleProp<ViewStyle>
13+
onGoBack?: () => void
14+
hasBackButton?: boolean
15+
leftView?: React.ReactNode
16+
centerView?: React.ReactNode
17+
rightView?: React.ReactNode
18+
containerStyle?: StyleProp<ViewStyle>
19+
}
20+
21+
export const Header: React.FC<IHeaderProp> = ({
22+
hasBackButton = true,
23+
title,
24+
leftStyle,
25+
rightStyle,
26+
centerStyle,
27+
onGoBack,
28+
leftView,
29+
centerView,
30+
rightView,
31+
containerStyle,
32+
}) => {
33+
const navigation = useNavigation()
34+
return (
35+
<View style={[styles.headerStyle, containerStyle]}>
36+
<View style={[styles.left, leftStyle]}>
37+
{hasBackButton && (
38+
<TouchableOpacity
39+
onPress={() => {
40+
if (onGoBack) {
41+
onGoBack()
42+
} else {
43+
navigation.goBack()
44+
}
45+
}}>
46+
<MaterialIcons name={'arrow-back'} color={colors.black} size={25} />
47+
</TouchableOpacity>
48+
)}
49+
{leftView}
50+
</View>
51+
<View style={[styles.center, centerStyle]}>
52+
{!!title && (
53+
<Text fontSize={fontSizes.label} fontFamily={fonts.bold} color={colors.black}>
54+
{title}
55+
</Text>
56+
)}
57+
{centerView}
58+
</View>
59+
<View style={[styles.right, rightStyle]}>{rightView}</View>
60+
</View>
61+
)
62+
}
63+
64+
const styles = StyleSheet.create({
65+
headerStyle: {
66+
flexDirection: 'row',
67+
justifyContent: 'space-between',
68+
alignItems: 'center',
69+
height: metrics.headerHeight,
70+
paddingHorizontal: metrics.marginTop,
71+
backgroundColor: colors.white,
72+
borderBottomWidth: metrics.borderWidth,
73+
borderColor: colors.gray1,
74+
},
75+
left: {
76+
flex: 1,
77+
},
78+
center: {
79+
flex: 4,
80+
justifyContent: 'center',
81+
alignItems: 'center',
82+
},
83+
right: {
84+
flex: 1,
85+
},
86+
})

0 commit comments

Comments
 (0)