mirror of
https://github.com/hanzo-io/chat.git
synced 2026-10-30 18:57:58 +00:00
142 lines
3.9 KiB
TypeScript
142 lines
3.9 KiB
TypeScript
import type { DrawerContentComponentProps } from '@react-navigation/drawer';
|
|
import * as React from 'react';
|
|
import { Platform, Pressable, ScrollView, View } from 'react-native';
|
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
|
import { Text } from '@components/nativewindui/Text';
|
|
import { Button } from '@components/nativewindui/Button';
|
|
import { cn } from '@lib/cn';
|
|
import { useColorScheme } from '@hooks/useColorScheme';
|
|
import { COLORS } from '@theme/colors';
|
|
import CrossIcon from '@assets/icons/CrossIcon.svg';
|
|
import { SvgProps } from 'react-native-svg';
|
|
|
|
const ANDROID_ACTION_BAR_HEIGHT = 60;
|
|
|
|
type DrawerContentRootProps = React.ComponentPropsWithoutRef<typeof View> & {
|
|
navigation: DrawerContentComponentProps['navigation'];
|
|
actions?: React.ReactNode;
|
|
};
|
|
function DrawerContentRoot({
|
|
actions,
|
|
children,
|
|
className,
|
|
navigation,
|
|
...props
|
|
}: DrawerContentRootProps) {
|
|
const insets = useSafeAreaInsets();
|
|
const { colors } = useColorScheme();
|
|
|
|
return (
|
|
<View className={cn('flex-1', className)} {...props}>
|
|
{Platform.OS === 'ios' ? (
|
|
<View
|
|
style={{ paddingTop: insets.top }}
|
|
className="flex-row items-center justify-between px-4 pb-1.5">
|
|
<Pressable className="active:opacity-70" onPress={navigation.toggleDrawer}>
|
|
<CrossIcon
|
|
color={colors.primary}
|
|
/>
|
|
</Pressable>
|
|
{actions}
|
|
</View>
|
|
) : (
|
|
<View style={{ height: insets.top }} />
|
|
)}
|
|
<ScrollView
|
|
contentContainerStyle={{
|
|
paddingBottom:
|
|
insets.bottom + (Platform.OS !== 'ios' && !!actions ? ANDROID_ACTION_BAR_HEIGHT : 0),
|
|
}}>
|
|
{children}
|
|
</ScrollView>
|
|
{Platform.OS === 'android' && !!actions && (
|
|
<View
|
|
style={{ height: insets.bottom + ANDROID_ACTION_BAR_HEIGHT }}
|
|
className="bg-card px-4 pt-1">
|
|
<View className="flex-row items-center justify-between p-3.5">{actions}</View>
|
|
</View>
|
|
)}
|
|
</View>
|
|
);
|
|
}
|
|
|
|
function DrawerContentSectionTitle({
|
|
type = 'default',
|
|
className,
|
|
...props
|
|
}: React.ComponentPropsWithoutRef<typeof Text> & {
|
|
type?: 'large' | 'default';
|
|
}) {
|
|
return (
|
|
<Text
|
|
variant={Platform.OS === 'ios' ? (type === 'large' ? 'largeTitle' : 'title3') : 'footnote'}
|
|
className={cn(
|
|
'ios:font-bold ios:px-4 text-card-foreground px-6 pb-2.5 pt-4 font-medium',
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
|
|
function DrawerContentSection({
|
|
className,
|
|
...props
|
|
}: React.ComponentPropsWithoutRef<typeof View>) {
|
|
return <View className={cn('gap-1 px-2', className)} {...props} />;
|
|
}
|
|
|
|
function DrawerContentSectionItem<T extends 'sfSymbol' | 'material'>({
|
|
label,
|
|
icon,
|
|
onPress,
|
|
isActive,
|
|
rightView,
|
|
}: {
|
|
label: string;
|
|
icon: SvgProps;
|
|
onPress?: () => void;
|
|
isActive?: boolean;
|
|
rightView?: React.ReactNode;
|
|
}) {
|
|
const { colors } = useColorScheme();
|
|
return (
|
|
<Button
|
|
variant={isActive ? Platform.select({ default: 'tonal', ios: 'primary' }) : 'plain'}
|
|
onPress={onPress}
|
|
className="ios:gap-2 ios:px-2 justify-start gap-3 rounded-lg px-4 py-3.5">
|
|
<CrossIcon
|
|
color={
|
|
isActive
|
|
? Platform.select({ default: colors.foreground, ios: COLORS.white })
|
|
: Platform.select({ default: colors.grey, ios: colors.primary })
|
|
}
|
|
{...icon}
|
|
/>
|
|
<View className="flex-1">
|
|
<Text
|
|
className={cn(
|
|
isActive ? 'ios:text-white dark:text-white' : 'text-card-foreground',
|
|
'android:text-[14px] font-normal'
|
|
)}>
|
|
{label}
|
|
</Text>
|
|
</View>
|
|
{rightView}
|
|
</Button>
|
|
);
|
|
}
|
|
|
|
function getActiveDrawerContentScreen(props: DrawerContentComponentProps) {
|
|
return props.state.routes[props.state.index].name;
|
|
}
|
|
|
|
export {
|
|
DrawerContentRoot,
|
|
DrawerContentSection,
|
|
DrawerContentSectionItem,
|
|
DrawerContentSectionTitle,
|
|
getActiveDrawerContentScreen,
|
|
};
|