import clsx from "clsx";
import { X } from "lucide-react";
import type { ModalOverlayProps } from "react-aria-components";
import {
Dialog,
DialogTrigger,
Heading,
Modal,
ModalOverlay,
} from "react-aria-components";
import { useNavigate } from "react-router";
import * as R from "remeda";
import { SendouButton } from "~/components/elements/Button";
import styles from "./Dialog.module.css";
interface SendouDialogProps extends ModalOverlayProps {
trigger?: React.ReactNode;
children?: React.ReactNode;
heading?: string;
showHeading?: boolean;
onClose?: () => void;
/** When closing the modal which URL to navigate to */
onCloseTo?: string;
overlayClassName?: string;
"aria-label"?: string;
/** If true, the modal takes over the full screen with the content below hidden */
isFullScreen?: boolean;
/** If true, shows the close button even if onClose is not provided */
showCloseButton?: boolean;
}
/**
* This component allows you to create a dialog with a customizable trigger and content.
* It supports both controlled and uncontrolled modes for managing the dialog's open state.
*
* @example
* // Example usage with implicit isOpen
* return (
*
* This is the dialog content.
*
* );
*
* @example
* // Example usage with a SendouButton as the trigger
* return (
* Open Dialog}
* >
* This is the dialog content.
*
* );
*/
export function SendouDialog({
trigger,
children,
...rest
}: SendouDialogProps) {
if (!trigger) {
const props =
typeof rest.isOpen === "boolean" ? rest : { isOpen: true, ...rest };
return {children};
}
return (
{trigger}
{children}
);
}
function DialogModal({
children,
heading,
showHeading = true,
className,
showCloseButton: showCloseButtonProp,
isControlledByTrigger,
...rest
}: Omit & { isControlledByTrigger?: boolean }) {
const navigate = useNavigate();
const showCloseButton = showCloseButtonProp || rest.onClose || rest.onCloseTo;
const onClose = () => {
if (rest.onCloseTo) {
navigate(rest.onCloseTo);
} else if (rest.onClose) {
rest.onClose();
}
};
const defaultOnOpenChange = (isOpen: boolean) => {
if (!isOpen) {
if (rest.onCloseTo) {
navigate(rest.onCloseTo);
} else if (rest.onClose) {
rest.onClose();
}
}
};
const overlayProps = isControlledByTrigger
? R.omit(rest, ["onOpenChange"])
: { ...rest, onOpenChange: rest.onOpenChange ?? defaultOnOpenChange };
return (
);
}