Alert Dialog
Categorystyled
ArchitectureReact
Client
Component
Dependencies
Usage
import { useState } from "react";
import { Button } from "@/components/react/styled/button";
import { AlertDialog } from "@/components/react/styled/alertDialog";
import { DemoWrapper } from "@/demos/react/demoWrapper";
export const AlertDialogDemo = ({ code }: { code: string }) => {
const [wState, setWState] = useState(false);
const [eState, setEState] = useState(false);
const [cState, setCState] = useState(false);
return (
<DemoWrapper code={code}>
<Button onClick={setWState.bind(null, true)}>
Open warning alert dialog
</Button>
<AlertDialog
title="Alert Dialog Tittle"
subtitle="Alert Dialog Subtitle"
actions={{
accept: { action: () => {}, title: "dismiss", type: "dismiss" },
dismiss: {
action: () => {},
title: "second action",
type: "warn",
},
}}
state={wState}
setState={setWState}
/>
<Button onClick={setEState.bind(null, true)}>
Open error alert dialog
</Button>
<AlertDialog
title="Alert Dialog Tittle"
subtitle="Alert Dialog Subtitle"
actions={{
accept: { action: () => {}, title: "dismiss", type: "dismiss" },
dismiss: {
action: () => {},
title: "second action",
type: "error",
},
}}
state={eState}
setState={setEState}
/>
<Button onClick={setCState.bind(null, true)}>
Open warning confirm dialog
</Button>
<AlertDialog
title="Alert Dialog Tittle"
subtitle="Alert Dialog Subtitle"
actions={{
accept: { action: () => {}, title: "dismiss", type: "dismiss" },
dismiss: {
action: () => {},
title: "second action",
type: "confirm",
},
}}
state={cState}
setState={setCState}
/>
</DemoWrapper>
);
};
Install Instructions
Verifying dependencies
Make sure the following dependencies are satisfied:
- dialog
Copy and paste the code into that file
import { lazy, Suspense } from "react";
// Sub-Component
const Dialog = lazy(() =>
import("@/components/react/primitive/dialog").then((module) => ({
default: module.Dialog,
}))
);
// Types
import type { DialogProps } from "@/components/react/primitive/dialog";
// CVA
import { cva } from "class-variance-authority";
interface Action {
title: string;
action: () => void;
type: "warn" | "error" | "confirm" | "dismiss";
}
export interface AlertDialogProps
extends Omit<DialogProps, "className" | "closable" | "children" | "ref"> {
title: string;
subtitle?: string;
actions: {
accept?: Action;
dismiss?: Action;
};
}
const dialogClasses = cva([
"backdrop-blur-md",
"bg-neutral-100/75",
"dark:bg-neutral-900/75",
"rounded-3xl",
"p-0",
"not-prose",
"data-[display=true]:scale-100",
"data-[display=false]:scale-95",
"data-[display=true]:blur-0",
"data-[display=false]:blur-md",
]);
const buttonClasses = cva(
[
"whitespace-nowrap",
"text-sm",
"py-3",
"px-8",
"grow",
"dark:border-neutral-800",
"border-neutral-200",
"capitalize",
"border-t-2",
"first:border-r",
"last:border-l",
"only:last:border-r-0",
"only:last:border-l-0",
],
{
variants: {
actionType: {
dismiss: [],
warn: ["text-yellow-500"],
error: ["text-red-500"],
confirm: ["text-blue-500"],
},
},
}
);
/**
* AlertDialog provide an elegant way to display alerts
*/
export const AlertDialog = ({
title,
subtitle,
actions: { accept, dismiss },
setState,
...props
}: AlertDialogProps): JSX.Element => {
return (
<Suspense fallback={null}>
<Dialog
className={dialogClasses()}
setState={setState}
closable={false}
{...props}
>
<header className="py-6 flex flex-col justify-center align-middle items-center">
<p className="mb-1 last:mb-0 text-md font-semibold">{title}</p>
<p className="text-xs opacity-60">{subtitle}</p>
</header>
<div className="grid grid-cols-2">
{accept && (
<button
className={buttonClasses({ actionType: accept.type })}
onClick={() => {
setState && setState(false);
setState && accept.action();
}}
>
{accept.title}
</button>
)}
{dismiss && (
<button
className={buttonClasses({ actionType: dismiss.type })}
onClick={() => {
setState && setState(false);
setState && dismiss.action();
}}
>
{dismiss.title}
</button>
)}
</div>
</Dialog>
</Suspense>
);
};