Files
openmonetis/components/confirm-action-dialog.tsx
Felipe Coutinho 96118d85e4 style: padronizar dialogs e aplicar formatação Biome
DialogContent: padding p-6→p-10, max-w-lg→max-w-xl.
DialogFooter/AlertDialogFooter: botões com flex-1 (largura igual).
Remove gap-3/w-full redundantes de 12+ dialogs.

Reformatação Biome: line wrapping, import ordering.
Error component renomeado para evitar shadowing do global Error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:22:59 +00:00

104 lines
2.5 KiB
TypeScript

"use client";
import type { VariantProps } from "class-variance-authority";
import { useState, useTransition } from "react";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { buttonVariants } from "@/components/ui/button";
interface ConfirmActionDialogProps {
trigger?: React.ReactNode;
title: string;
description?: string;
confirmLabel?: string;
cancelLabel?: string;
pendingLabel?: string;
confirmVariant?: VariantProps<typeof buttonVariants>["variant"];
open?: boolean;
onOpenChange?: (open: boolean) => void;
onConfirm?: () => Promise<void> | void;
disabled?: boolean;
className?: string;
}
export function ConfirmActionDialog({
trigger,
title,
description,
confirmLabel = "Confirmar",
cancelLabel = "Cancelar",
pendingLabel,
confirmVariant = "default",
open,
onOpenChange,
onConfirm,
disabled = false,
className,
}: ConfirmActionDialogProps) {
const [internalOpen, setInternalOpen] = useState(false);
const [isPending, startTransition] = useTransition();
const dialogOpen = open ?? internalOpen;
const setDialogOpen = (value: boolean) => {
if (open === undefined) {
setInternalOpen(value);
}
onOpenChange?.(value);
};
const resolvedPendingLabel = pendingLabel ?? confirmLabel;
const handleConfirm = () => {
if (!onConfirm) {
setDialogOpen(false);
return;
}
startTransition(async () => {
try {
await onConfirm();
setDialogOpen(false);
} catch {
// Mantém o diálogo aberto para que o chamador trate o erro.
}
});
};
return (
<AlertDialog open={dialogOpen} onOpenChange={setDialogOpen}>
{trigger ? (
<AlertDialogTrigger asChild>{trigger}</AlertDialogTrigger>
) : null}
<AlertDialogContent className={className}>
<AlertDialogHeader>
<AlertDialogTitle>{title}</AlertDialogTitle>
{description ? (
<AlertDialogDescription>{description}</AlertDialogDescription>
) : null}
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel disabled={isPending || disabled}>
{cancelLabel}
</AlertDialogCancel>
<AlertDialogAction
onClick={handleConfirm}
disabled={isPending || disabled}
className={buttonVariants({ variant: confirmVariant })}
>
{isPending ? resolvedPendingLabel : confirmLabel}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}