66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
"use client";
|
||
|
||
import { useRef, useState, type ComponentProps } from "react";
|
||
import { useFormStatus } from "react-dom";
|
||
import { Loader2 } from "lucide-react";
|
||
import { Button } from "@/components/ui/button";
|
||
import {
|
||
AlertDialog,
|
||
AlertDialogContent,
|
||
AlertDialogHeader,
|
||
AlertDialogTitle,
|
||
AlertDialogDescription,
|
||
AlertDialogFooter,
|
||
AlertDialogCancel,
|
||
AlertDialogAction,
|
||
} from "@/components/ui/alert-dialog";
|
||
|
||
export function SubmitButton({
|
||
children,
|
||
confirm,
|
||
...props
|
||
}: ComponentProps<typeof Button> & { confirm?: string }) {
|
||
const { pending } = useFormStatus();
|
||
const [open, setOpen] = useState(false);
|
||
const ref = useRef<HTMLButtonElement>(null);
|
||
return (
|
||
<>
|
||
<Button
|
||
{...props}
|
||
ref={ref}
|
||
type="submit"
|
||
size="sm"
|
||
disabled={pending || props.disabled}
|
||
onClick={(event) => {
|
||
if (confirm) {
|
||
event.preventDefault();
|
||
setOpen(true);
|
||
}
|
||
}}
|
||
>
|
||
{pending && <Loader2 className="animate-spin" aria-hidden="true" />}
|
||
{pending ? "处理中…" : children}
|
||
</Button>
|
||
{confirm && (
|
||
<AlertDialog open={open} onOpenChange={setOpen}>
|
||
<AlertDialogContent>
|
||
<AlertDialogHeader>
|
||
<AlertDialogTitle>确认{children}?</AlertDialogTitle>
|
||
<AlertDialogDescription>{confirm}</AlertDialogDescription>
|
||
</AlertDialogHeader>
|
||
<AlertDialogFooter>
|
||
<AlertDialogCancel>取消</AlertDialogCancel>
|
||
<AlertDialogAction
|
||
variant="destructive"
|
||
onClick={() => ref.current?.form?.requestSubmit(ref.current)}
|
||
>
|
||
确认{children}
|
||
</AlertDialogAction>
|
||
</AlertDialogFooter>
|
||
</AlertDialogContent>
|
||
</AlertDialog>
|
||
)}
|
||
</>
|
||
);
|
||
}
|