mirror of
https://github.com/hanzo-io/team.git
synced 2026-10-30 18:56:23 +00:00
121 lines
4.3 KiB
TypeScript
121 lines
4.3 KiB
TypeScript
import * as AlertDialogPrimitive from '@rn-primitives/alert-dialog';
|
|
import { useAugmentedRef } from '@rn-primitives/hooks';
|
|
import * as React from 'react';
|
|
import { View } from 'react-native';
|
|
import Animated, {
|
|
FadeIn,
|
|
FadeInDown,
|
|
FadeOut,
|
|
FadeOutDown,
|
|
} from 'react-native-reanimated';
|
|
|
|
import { AlertProps, AlertRef } from './types';
|
|
import { Text } from '@components/nativewindui/Text';
|
|
import { Button } from '@components/nativewindui/Button';
|
|
import { cn } from '@lib/cn';
|
|
|
|
const Alert = React.forwardRef<AlertRef, AlertProps>((_, ref) => {
|
|
const [open, setOpen] = React.useState(false);
|
|
const [props, setProps] = React.useState<AlertProps | null>(null);
|
|
|
|
const augmentedRef = useAugmentedRef({
|
|
ref,
|
|
methods: {
|
|
show: (args: AlertProps) => {
|
|
setProps(args);
|
|
setOpen(true);
|
|
},
|
|
},
|
|
});
|
|
|
|
const onOpenChange = (isOpen: boolean) => {
|
|
setOpen(isOpen);
|
|
};
|
|
|
|
return (
|
|
<AlertDialogPrimitive.Root ref={augmentedRef} open={open} onOpenChange={onOpenChange}>
|
|
<AlertDialogPrimitive.Portal hostName={props?.materialPortalHost}>
|
|
<AlertDialogPrimitive.Overlay asChild>
|
|
<Animated.View
|
|
entering={FadeIn}
|
|
exiting={FadeOut}
|
|
className={cn(
|
|
'bg-popover/80 absolute bottom-0 left-0 right-0 top-0 items-center justify-center px-3'
|
|
)}>
|
|
<AlertDialogPrimitive.Content>
|
|
<Animated.View
|
|
entering={FadeInDown}
|
|
exiting={FadeOutDown}
|
|
className="bg-card min-w-72 max-w-xl rounded-3xl p-6 pt-7 shadow-xl">
|
|
{/* Title */}
|
|
<AlertDialogPrimitive.Title asChild>
|
|
<Text variant="title2" className="text-center pb-4">
|
|
{props?.title}
|
|
</Text>
|
|
</AlertDialogPrimitive.Title>
|
|
|
|
{/* Message */}
|
|
{props?.message && (
|
|
<AlertDialogPrimitive.Description asChild>
|
|
<Text variant="subhead" className="pb-4 opacity-90 text-center">
|
|
{props.message}
|
|
</Text>
|
|
</AlertDialogPrimitive.Description>
|
|
)}
|
|
|
|
{/* Buttons */}
|
|
<View
|
|
className={cn(
|
|
'flex-row items-center justify-end gap-0.5',
|
|
props?.buttons.length && props?.buttons.length > 2 && 'justify-between'
|
|
)}>
|
|
{props?.buttons.map((button, index) => (
|
|
<View
|
|
key={`${button.text}-${index}`}
|
|
className={cn(
|
|
props.buttons.length > 2 && index === 0 && 'flex-1 items-start'
|
|
)}>
|
|
<AlertDialogPrimitive.Action asChild>
|
|
<Button
|
|
variant={
|
|
button.style === 'destructive'
|
|
? 'tonal'
|
|
: button.style === 'cancel'
|
|
? 'plain'
|
|
: 'plain'
|
|
}
|
|
onPress={() => {
|
|
button.onPress?.('');
|
|
setOpen(false);
|
|
}}
|
|
className={cn(
|
|
button.style === 'destructive' &&
|
|
'bg-destructive/10 dark:bg-destructive/25'
|
|
)}>
|
|
<Text
|
|
className={cn(
|
|
'text-[14px] font-medium',
|
|
button.style === 'destructive'
|
|
? 'text-foreground'
|
|
: 'text-primary dark:text-secondary'
|
|
)}>
|
|
{button.text}
|
|
</Text>
|
|
</Button>
|
|
</AlertDialogPrimitive.Action>
|
|
</View>
|
|
))}
|
|
</View>
|
|
</Animated.View>
|
|
</AlertDialogPrimitive.Content>
|
|
</Animated.View>
|
|
</AlertDialogPrimitive.Overlay>
|
|
</AlertDialogPrimitive.Portal>
|
|
</AlertDialogPrimitive.Root>
|
|
);
|
|
});
|
|
|
|
Alert.displayName = 'Alert';
|
|
|
|
export { Alert };
|