105 lines
3.2 KiB
TypeScript
105 lines
3.2 KiB
TypeScript
import React from 'react';
|
|
import { YStack, XStack } from '@tamagui/stacks';
|
|
import { SizableText as Text } from '@tamagui/text';
|
|
import { Button } from '@tamagui/button';
|
|
import { Sheet } from '@tamagui/sheet';
|
|
import { useGuestThemeVariant } from '../lib/guestTheme';
|
|
|
|
export type FabAction = {
|
|
key: string;
|
|
label: string;
|
|
description?: string;
|
|
icon?: React.ReactNode;
|
|
onPress?: () => void;
|
|
};
|
|
|
|
type FabActionSheetProps = {
|
|
open: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
title: string;
|
|
actions: FabAction[];
|
|
};
|
|
|
|
export default function FabActionSheet({ open, onOpenChange, title, actions }: FabActionSheetProps) {
|
|
const { isDark } = useGuestThemeVariant();
|
|
|
|
if (!open) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Sheet
|
|
modal
|
|
open={open}
|
|
onOpenChange={onOpenChange}
|
|
snapPoints={[70]}
|
|
snapPointsMode="percent"
|
|
dismissOnOverlayPress
|
|
dismissOnSnapToBottom
|
|
zIndex={100000}
|
|
>
|
|
<Sheet.Overlay {...({ backgroundColor: isDark ? 'rgba(15, 23, 42, 0.45)' : 'rgba(15, 23, 42, 0.2)' } as any)} />
|
|
<Sheet.Frame
|
|
{...({
|
|
width: '100%',
|
|
maxWidth: 560,
|
|
alignSelf: 'center',
|
|
borderTopLeftRadius: 28,
|
|
borderTopRightRadius: 28,
|
|
backgroundColor: '$surface',
|
|
padding: 20,
|
|
shadowColor: isDark ? 'rgba(15, 23, 42, 0.25)' : 'rgba(15, 23, 42, 0.12)',
|
|
shadowOpacity: 0.2,
|
|
shadowRadius: 20,
|
|
shadowOffset: { width: 0, height: -6 },
|
|
} as any)}
|
|
style={{ marginBottom: 'calc(16px + env(safe-area-inset-bottom))' }}
|
|
>
|
|
<Sheet.Handle height={5} width={52} backgroundColor="#CBD5E1" borderRadius={999} marginBottom="$3" />
|
|
<YStack gap="$3">
|
|
<Text fontSize="$6" fontFamily="$display" fontWeight="$8">
|
|
{title}
|
|
</Text>
|
|
<YStack gap="$2">
|
|
{actions.map((action) => (
|
|
<Button
|
|
key={action.key}
|
|
onPress={action.onPress}
|
|
backgroundColor="$surface"
|
|
borderRadius="$card"
|
|
borderWidth={1}
|
|
borderColor="$borderColor"
|
|
padding="$3"
|
|
justifyContent="flex-start"
|
|
>
|
|
<XStack alignItems="center" gap="$3">
|
|
<YStack
|
|
width={40}
|
|
height={40}
|
|
alignItems="center"
|
|
justifyContent="center"
|
|
borderRadius={999}
|
|
backgroundColor="$accentSoft"
|
|
>
|
|
{action.icon ? action.icon : null}
|
|
</YStack>
|
|
<YStack gap="$1" flex={1}>
|
|
<Text fontSize="$4" fontWeight="$7">
|
|
{action.label}
|
|
</Text>
|
|
{action.description ? (
|
|
<Text fontSize="$2" color="$color" opacity={0.6}>
|
|
{action.description}
|
|
</Text>
|
|
) : null}
|
|
</YStack>
|
|
</XStack>
|
|
</Button>
|
|
))}
|
|
</YStack>
|
|
</YStack>
|
|
</Sheet.Frame>
|
|
</Sheet>
|
|
);
|
|
}
|