forked from github/plane
20e7dc68e6
* style: update modals typography, alignment * style: made the modal separator full width * style: delete modals consistency * style: update the remaining delete modals * chore: delete modal secondary button text * style: update the remaining create modals * chore: update cancel button text * chore: created modal core * style: modals responsiveness
91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
import { AlertTriangle, LucideIcon } from "lucide-react";
|
|
// ui
|
|
import { Button, TButtonVariant } from "@plane/ui";
|
|
// components
|
|
import { EModalPosition, EModalWidth, ModalCore } from "@/components/core";
|
|
// helpers
|
|
import { cn } from "@/helpers/common.helper";
|
|
|
|
export type TModalVariant = "danger";
|
|
|
|
type Props = {
|
|
content: React.ReactNode | string;
|
|
handleClose: () => void;
|
|
handleSubmit: () => Promise<void>;
|
|
hideIcon?: boolean;
|
|
isDeleting: boolean;
|
|
isOpen: boolean;
|
|
position?: EModalPosition;
|
|
primaryButtonText?: {
|
|
loading: string;
|
|
default: string;
|
|
};
|
|
secondaryButtonText?: string;
|
|
title: string;
|
|
variant?: TModalVariant;
|
|
width?: EModalWidth;
|
|
};
|
|
|
|
const VARIANT_ICONS: Record<TModalVariant, LucideIcon> = {
|
|
danger: AlertTriangle,
|
|
};
|
|
|
|
const BUTTON_VARIANTS: Record<TModalVariant, TButtonVariant> = {
|
|
danger: "danger",
|
|
};
|
|
|
|
const VARIANT_CLASSES: Record<TModalVariant, string> = {
|
|
danger: "bg-red-500/20 text-red-500",
|
|
};
|
|
|
|
export const AlertModalCore: React.FC<Props> = (props) => {
|
|
const {
|
|
content,
|
|
handleClose,
|
|
handleSubmit,
|
|
hideIcon = false,
|
|
isDeleting,
|
|
isOpen,
|
|
position = EModalPosition.CENTER,
|
|
primaryButtonText = {
|
|
loading: "Deleting",
|
|
default: "Delete",
|
|
},
|
|
secondaryButtonText = "Cancel",
|
|
title,
|
|
variant = "danger",
|
|
width = EModalWidth.XL,
|
|
} = props;
|
|
|
|
const Icon = VARIANT_ICONS[variant];
|
|
|
|
return (
|
|
<ModalCore isOpen={isOpen} handleClose={handleClose} position={position} width={width}>
|
|
<div className="p-5 flex flex-col sm:flex-row items-center sm:items-start gap-4">
|
|
{!hideIcon && (
|
|
<span
|
|
className={cn(
|
|
"flex-shrink-0 grid place-items-center rounded-full size-12 sm:size-10",
|
|
VARIANT_CLASSES[variant]
|
|
)}
|
|
>
|
|
<Icon className="size-5" aria-hidden="true" />
|
|
</span>
|
|
)}
|
|
<div className="text-center sm:text-left">
|
|
<h3 className="text-lg font-medium">{title}</h3>
|
|
<p className="mt-1 text-sm text-custom-text-200">{content}</p>
|
|
</div>
|
|
</div>
|
|
<div className="px-5 py-4 flex flex-col-reverse sm:flex-row sm:justify-end gap-2 border-t-[0.5px] border-custom-border-200">
|
|
<Button variant="neutral-primary" size="sm" onClick={handleClose}>
|
|
{secondaryButtonText}
|
|
</Button>
|
|
<Button variant={BUTTON_VARIANTS[variant]} size="sm" tabIndex={1} onClick={handleSubmit} loading={isDeleting}>
|
|
{isDeleting ? primaryButtonText.loading : primaryButtonText.default}
|
|
</Button>
|
|
</div>
|
|
</ModalCore>
|
|
);
|
|
};
|