2026-10-03 16:23:38 +00:00
|
|
|
import { type ReactNode, createContext, useContext } from "react";
|
2026-10-03 10:36:03 +00:00
|
|
|
|
|
|
|
|
import { Button } from "./button";
|
|
|
|
|
import {
|
|
|
|
|
Dialog,
|
|
|
|
|
DialogClose,
|
|
|
|
|
DialogContent,
|
|
|
|
|
DialogFooter,
|
|
|
|
|
DialogHeader,
|
|
|
|
|
DialogTitle,
|
|
|
|
|
} from "./dialog";
|
|
|
|
|
|
2026-10-03 16:23:38 +00:00
|
|
|
const FormCancelContext = createContext<string | undefined>(undefined);
|
|
|
|
|
|
2026-10-03 10:36:03 +00:00
|
|
|
export function FormDialog({
|
|
|
|
|
open,
|
|
|
|
|
onOpenChange,
|
|
|
|
|
title,
|
|
|
|
|
cancelLabel,
|
|
|
|
|
children,
|
2026-10-03 16:23:38 +00:00
|
|
|
wide = false,
|
|
|
|
|
formActions = false,
|
2026-10-03 10:36:03 +00:00
|
|
|
}: {
|
|
|
|
|
open: boolean;
|
|
|
|
|
onOpenChange: (open: boolean) => void;
|
|
|
|
|
title: string;
|
|
|
|
|
cancelLabel: string;
|
|
|
|
|
children: ReactNode;
|
2026-10-03 16:23:38 +00:00
|
|
|
wide?: boolean;
|
|
|
|
|
formActions?: boolean;
|
2026-10-03 10:36:03 +00:00
|
|
|
}) {
|
|
|
|
|
return (
|
|
|
|
|
<Dialog onOpenChange={onOpenChange} open={open}>
|
|
|
|
|
<DialogContent
|
2026-10-03 16:23:38 +00:00
|
|
|
className={`max-h-[calc(100dvh-2rem)] overflow-y-auto ${wide ? "sm:max-w-3xl" : "sm:max-w-xl"}`}
|
2026-10-03 10:36:03 +00:00
|
|
|
showCloseButton={false}
|
|
|
|
|
>
|
|
|
|
|
<DialogHeader>
|
2026-10-09 10:36:05 +00:00
|
|
|
<DialogTitle className="text-xl">{title}</DialogTitle>
|
2026-10-03 10:36:03 +00:00
|
|
|
</DialogHeader>
|
2026-10-03 16:23:38 +00:00
|
|
|
<FormCancelContext.Provider value={formActions ? cancelLabel : undefined}>
|
|
|
|
|
{children}
|
|
|
|
|
</FormCancelContext.Provider>
|
|
|
|
|
{!formActions && (
|
|
|
|
|
<DialogFooter>
|
|
|
|
|
<DialogClose render={<Button type="button" variant="outline" />}>
|
|
|
|
|
{cancelLabel}
|
|
|
|
|
</DialogClose>
|
|
|
|
|
</DialogFooter>
|
|
|
|
|
)}
|
2026-10-03 10:36:03 +00:00
|
|
|
</DialogContent>
|
|
|
|
|
</Dialog>
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-10-03 16:23:38 +00:00
|
|
|
|
|
|
|
|
export function FormActions({ children }: { children: ReactNode }) {
|
|
|
|
|
const cancelLabel = useContext(FormCancelContext);
|
|
|
|
|
return (
|
|
|
|
|
<DialogFooter className="border-t pt-4">
|
|
|
|
|
{children}
|
|
|
|
|
{cancelLabel && (
|
|
|
|
|
<DialogClose render={<Button type="button" variant="outline" />}>{cancelLabel}</DialogClose>
|
|
|
|
|
)}
|
|
|
|
|
</DialogFooter>
|
|
|
|
|
);
|
|
|
|
|
}
|