Files
fotospiel-app/resources/js/guest-v2/components/FabActionSheet.tsx
2026-02-03 15:18:44 +01:00

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>
);
}