Files
better-auth/demo/expo-example/src/components/ui/dialog.tsx
Bereket Engida 2f8a0e1168 chore: misc
2025-09-29 18:02:21 -07:00

167 lines
4.3 KiB
TypeScript

import * as DialogPrimitive from "@rn-primitives/dialog";
import * as React from "react";
import { Platform, StyleSheet, View, type ViewProps } from "react-native";
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
import { X } from "@/lib/icons/X";
import { cn } from "@/lib/utils";
const Dialog = DialogPrimitive.Root;
const DialogTrigger = DialogPrimitive.Trigger;
const DialogPortal = DialogPrimitive.Portal;
const DialogClose = DialogPrimitive.Close;
const DialogOverlayWeb = React.forwardRef<
DialogPrimitive.OverlayRef,
DialogPrimitive.OverlayProps
>(({ className, ...props }, ref) => {
const { open } = DialogPrimitive.useRootContext();
return (
<DialogPrimitive.Overlay
className={cn(
"bg-black/80 flex justify-center items-center p-2 absolute top-0 right-0 bottom-0 left-0",
open
? "web:animate-in web:fade-in-0"
: "web:animate-out web:fade-out-0",
className,
)}
{...props}
ref={ref}
/>
);
});
DialogOverlayWeb.displayName = "DialogOverlayWeb";
const DialogOverlayNative = React.forwardRef<
DialogPrimitive.OverlayRef,
DialogPrimitive.OverlayProps
>(({ className, children, ...props }, ref) => {
return (
<DialogPrimitive.Overlay
style={StyleSheet.absoluteFill}
className={cn(
"flex bg-black/80 justify-center items-center p-2",
className,
)}
{...props}
ref={ref}
>
<Animated.View
entering={FadeIn.duration(150)}
exiting={FadeOut.duration(150)}
>
<>{children}</>
</Animated.View>
</DialogPrimitive.Overlay>
);
});
DialogOverlayNative.displayName = "DialogOverlayNative";
const DialogOverlay = Platform.select({
web: DialogOverlayWeb,
default: DialogOverlayNative,
});
const DialogContent = React.forwardRef<
DialogPrimitive.ContentRef,
DialogPrimitive.ContentProps & { portalHost?: string }
>(({ className, children, portalHost, ...props }, ref) => {
const { open } = DialogPrimitive.useRootContext();
return (
<DialogPortal hostName={portalHost}>
<DialogOverlay>
<DialogPrimitive.Content
ref={ref}
className={cn(
"max-w-lg gap-4 border border-border web:cursor-default bg-background p-6 shadow-lg web:duration-200 rounded-lg",
open
? "web:animate-in web:fade-in-0 web:zoom-in-95"
: "web:animate-out web:fade-out-0 web:zoom-out-95",
className,
)}
{...props}
>
{children}
<DialogPrimitive.Close
className={
"absolute right-4 top-4 p-0.5 web:group rounded-sm opacity-70 web:ring-offset-background web:transition-opacity web:hover:opacity-100 web:focus:outline-none web:focus:ring-2 web:focus:ring-ring web:focus:ring-offset-2 web:disabled:pointer-events-none"
}
>
<X
size={Platform.OS === "web" ? 16 : 18}
className={cn(
"text-muted-foreground",
open && "text-accent-foreground",
)}
/>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogOverlay>
</DialogPortal>
);
});
DialogContent.displayName = DialogPrimitive.Content.displayName;
const DialogHeader = ({ className, ...props }: ViewProps) => (
<View
className={cn("flex flex-col gap-1.5 text-center sm:text-left", className)}
{...props}
/>
);
DialogHeader.displayName = "DialogHeader";
const DialogFooter = ({ className, ...props }: ViewProps) => (
<View
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end gap-2",
className,
)}
{...props}
/>
);
DialogFooter.displayName = "DialogFooter";
const DialogTitle = React.forwardRef<
DialogPrimitive.TitleRef,
DialogPrimitive.TitleProps
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn(
"text-lg native:text-xl text-foreground font-semibold leading-none tracking-tight",
className,
)}
{...props}
/>
));
DialogTitle.displayName = DialogPrimitive.Title.displayName;
const DialogDescription = React.forwardRef<
DialogPrimitive.DescriptionRef,
DialogPrimitive.DescriptionProps
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm native:text-base text-muted-foreground", className)}
{...props}
/>
));
DialogDescription.displayName = DialogPrimitive.Description.displayName;
export {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogOverlay,
DialogPortal,
DialogTitle,
DialogTrigger,
};