-
Notifications
You must be signed in to change notification settings - Fork 0
/
BottomSheet.tsx
107 lines (102 loc) · 3.08 KB
/
BottomSheet.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import * as React from 'react';
import {
StyleProp,
TextStyle,
TouchableOpacity,
useWindowDimensions,
View,
ViewStyle,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useHeaderContext } from '../contexts/HeaderContext';
import { useThemeContext } from '../contexts/ThemeContext';
import DialogSheet from './DialogSheet';
import type { LocalIconName } from './Icon';
import Modal from './Modal';
type ButtonItemType = {
icon?: LocalIconName;
iconColor?: string;
title: string;
titleColor?: string;
onPress?: () => void;
containerStyle?: StyleProp<ViewStyle>;
titleStyle?: StyleProp<TextStyle>;
};
type CustomItemType<Props extends {} = {}> = {
key: string;
Custom: React.ComponentType<Props>;
CustomProps: Props;
// Custom: React.ReactElement<Props>; // !!! Cannot display dynamically.
};
type ItemType = ButtonItemType | CustomItemType;
export type BottomSheetItem = {
sheetItems: ItemType[];
};
type BottomSheetProps = {
visible: boolean;
onHide: () => Promise<void>;
onError?: (error: unknown) => void;
onDismiss?: () => void;
} & BottomSheetItem;
export default function BottomSheet({
onDismiss,
onHide,
visible,
sheetItems,
}: BottomSheetProps): JSX.Element {
const { defaultStatusBarTranslucent } = useHeaderContext();
const { colors } = useThemeContext();
const { width } = useWindowDimensions();
const { bottom, left, right } = useSafeAreaInsets();
const transparent = true;
return (
<Modal
type="slide"
onRequestClose={onHide}
onDismiss={onDismiss}
statusBarTranslucent={defaultStatusBarTranslucent}
visible={visible}
backgroundStyle={{ alignItems: 'center', justifyContent: 'flex-end' }}
transparent={transparent}
backdropColor={colors.backdrop}
>
<DialogSheet style={{ width, paddingBottom: bottom }}>
{sheetItems.map((value, idx) => {
if (Object.getOwnPropertyNames(value).includes('title')) {
const { onPress, ...props } = value as ButtonItemType;
return (
<TouchableOpacity
activeOpacity={0.75}
key={props.title + idx.toString}
style={{ paddingLeft: left, paddingRight: right }}
onPress={async () => {
await onHide();
try {
onPress?.();
} catch (e) {
console.warn(e);
}
}}
>
<DialogSheet.ButtonItem {...props} />
</TouchableOpacity>
);
} else if (Object.getOwnPropertyNames(value).includes('key')) {
const { Custom, CustomProps, key } = value as CustomItemType;
return (
<View
key={key}
style={{ paddingLeft: left, paddingRight: right }}
>
{/* {Custom} */}
<Custom {...CustomProps} />
</View>
);
} else {
return null;
}
})}
</DialogSheet>
</Modal>
);
}