g1t/apps/web/app/components/ui/alert-dialog.tsx
| 1 | import { AlertDialog as Primitive } from "radix-ui"; |
| 2 | import type { ComponentProps } from "react"; |
| 3 | |
| 4 | import { cn } from "../../lib/cn"; |
| 5 | import { DIALOG_PANEL } from "./dialog"; |
| 6 | |
| 7 | // shadcn/ui's alert dialog, for confirming what cannot be undone. It does |
| 8 | // not close on a click outside; the person has to choose. |
| 9 | |
| 10 | export const AlertDialog = Primitive.Root; |
| 11 | export const AlertDialogTrigger = Primitive.Trigger; |
| 12 | |
| 13 | export function AlertDialogContent({ className, ...props }: ComponentProps<typeof Primitive.Content>) { |
| 14 | return ( |
| 15 | <Primitive.Portal> |
| 16 | <Primitive.Overlay className="fixed inset-0 z-50 bg-black/60 backdrop-blur-[2px] data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out motion-reduce:animate-none" /> |
| 17 | <Primitive.Content className={cn(DIALOG_PANEL, "max-w-md", className)} {...props} /> |
| 18 | </Primitive.Portal> |
| 19 | ); |
| 20 | } |
| 21 | |
| 22 | export function AlertDialogHeader({ className, ...props }: ComponentProps<"div">) { |
| 23 | return <div className={cn("flex flex-col gap-1.5", className)} {...props} />; |
| 24 | } |
| 25 | |
| 26 | export function AlertDialogFooter({ className, ...props }: ComponentProps<"div">) { |
| 27 | return <div className={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)} {...props} />; |
| 28 | } |
| 29 | |
| 30 | export function AlertDialogTitle({ className, ...props }: ComponentProps<typeof Primitive.Title>) { |
| 31 | return <Primitive.Title className={cn("text-base font-semibold tracking-tight", className)} {...props} />; |
| 32 | } |
| 33 | |
| 34 | export function AlertDialogDescription({ className, ...props }: ComponentProps<typeof Primitive.Description>) { |
| 35 | return <Primitive.Description className={cn("text-sm text-muted", className)} {...props} />; |
| 36 | } |
| 37 | |
| 38 | const BUTTON = |
| 39 | "inline-flex items-center justify-center gap-2 rounded-md px-3.5 py-2 text-sm font-medium transition-colors disabled:opacity-50"; |
| 40 | |
| 41 | /** The destructive choice. Put a submit button inside with `asChild` to post a form. */ |
| 42 | export function AlertDialogAction({ className, ...props }: ComponentProps<typeof Primitive.Action>) { |
| 43 | return ( |
| 44 | <Primitive.Action |
| 45 | className={cn(BUTTON, "bg-danger text-bg hover:bg-danger/90", className)} |
| 46 | {...props} |
| 47 | /> |
| 48 | ); |
| 49 | } |
| 50 | |
| 51 | export function AlertDialogCancel({ className, ...props }: ComponentProps<typeof Primitive.Cancel>) { |
| 52 | return ( |
| 53 | <Primitive.Cancel |
| 54 | className={cn(BUTTON, "border border-line text-fg/80 hover:border-line-strong hover:bg-raised hover:text-fg", className)} |
| 55 | {...props} |
| 56 | /> |
| 57 | ); |
| 58 | } |