Migrate billing from Paddle to Lemon Squeezy
This commit is contained in:
94
resources/js/guest-v2/components/FabActionRing.tsx
Normal file
94
resources/js/guest-v2/components/FabActionRing.tsx
Normal file
@@ -0,0 +1,94 @@
|
||||
import React from 'react';
|
||||
import { YStack, XStack } from '@tamagui/stacks';
|
||||
import { Button } from '@tamagui/button';
|
||||
import { SizableText as Text } from '@tamagui/text';
|
||||
import { useAppearance } from '@/hooks/use-appearance';
|
||||
|
||||
type FabAction = {
|
||||
key: string;
|
||||
label: string;
|
||||
icon: React.ReactNode;
|
||||
onPress?: () => void;
|
||||
};
|
||||
|
||||
type FabActionRingProps = {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
actions: FabAction[];
|
||||
};
|
||||
|
||||
const positions = [
|
||||
{ x: 0, y: -120 },
|
||||
{ x: -70, y: -100 },
|
||||
{ x: -120, y: -24 },
|
||||
{ x: -92, y: 52 },
|
||||
];
|
||||
|
||||
export default function FabActionRing({ open, onOpenChange, actions }: FabActionRingProps) {
|
||||
const { resolved } = useAppearance();
|
||||
const isDark = resolved === 'dark';
|
||||
const borderColor = isDark ? 'rgba(255,255,255,0.18)' : 'rgba(15, 23, 42, 0.12)';
|
||||
const surfaceColor = isDark ? 'rgba(12, 16, 32, 0.92)' : 'rgba(255, 255, 255, 0.95)';
|
||||
const textColor = isDark ? '#F8FAFF' : '#0F172A';
|
||||
const shadow = isDark ? '0 16px 28px rgba(2, 6, 23, 0.55)' : '0 14px 24px rgba(15, 23, 42, 0.18)';
|
||||
const ringActions = actions.slice(0, positions.length);
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
return (
|
||||
<YStack position="fixed" inset={0} zIndex={1090} pointerEvents="box-none">
|
||||
<YStack
|
||||
position="absolute"
|
||||
inset={0}
|
||||
backgroundColor={isDark ? 'rgba(2,6,23,0.5)' : 'rgba(15,23,42,0.2)'}
|
||||
onPress={() => onOpenChange(false)}
|
||||
/>
|
||||
<YStack position="absolute" bottom={24} right={20} pointerEvents="box-none">
|
||||
{ringActions.map((action, index) => {
|
||||
const offset = positions[index];
|
||||
return (
|
||||
<XStack
|
||||
key={action.key}
|
||||
alignItems="center"
|
||||
gap="$2"
|
||||
position="absolute"
|
||||
style={{
|
||||
transform: `translate(${offset.x}px, ${offset.y}px)`,
|
||||
opacity: open ? 1 : 0,
|
||||
transition: 'transform 260ms ease, opacity 200ms ease',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
size="$3"
|
||||
circular
|
||||
backgroundColor={surfaceColor}
|
||||
borderWidth={1}
|
||||
borderColor={borderColor}
|
||||
onPress={() => {
|
||||
onOpenChange(false);
|
||||
action.onPress?.();
|
||||
}}
|
||||
style={{ boxShadow: shadow }}
|
||||
>
|
||||
{action.icon}
|
||||
</Button>
|
||||
<XStack
|
||||
paddingHorizontal="$3"
|
||||
paddingVertical="$2"
|
||||
borderRadius="$pill"
|
||||
backgroundColor={surfaceColor}
|
||||
borderWidth={1}
|
||||
borderColor={borderColor}
|
||||
style={{ boxShadow: shadow }}
|
||||
>
|
||||
<Text fontSize="$2" fontWeight="$6" color={textColor}>
|
||||
{action.label}
|
||||
</Text>
|
||||
</XStack>
|
||||
</XStack>
|
||||
);
|
||||
})}
|
||||
</YStack>
|
||||
</YStack>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user