roiui
itemalert-dialogsource: ok · hit
Alert Dialog
A modal dialog that interrupts the user with important content.
npx shadcn add "https://roiui.com/r/alert-dialog.json"free
Interaction
modal
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lightui-primitives@base-ui/react@1.5.0
Files2 · source cached 10/9/2026, 4:23:03 AM
registry/brook/ui/alert-dialog/alert-dialog.tsx
"use client";
import { AlertDialog } from "@base-ui/react/alert-dialog";
import type React from "react";
import { cn } from "../../../lib/utils";
import styles from "./alert-dialog.module.css";
function AlertDialogRoot({ ...props }: AlertDialog.Root.Props) {
return <AlertDialog.Root {...props} />;
}
function AlertDialogTrigger({ ...props }: AlertDialog.Trigger.Props) {
return <AlertDialog.Trigger data-slot="alert-dialog-trigger" nativeButton {...props} />;
}
const AlertDialogPortal = AlertDialog.Portal;
function AlertDialogBackdrop({ className, ...props }: AlertDialog.Backdrop.Props) {
return (
<AlertDialog.Backdrop className={cn(styles.overlay, className)} data-slot="alert-dialog-backdrop" {...props} />
);
}
function AlertDialogPopup({ className, children, ...props }: AlertDialog.Popup.Props) {
return (
<AlertDialogPortal>
<AlertDialog.Popup className={cn(styles.content, className)} data-slot="alert-dialog-popup" {...props}>
{children}
</AlertDialog.Popup>
</AlertDialogPortal>
);
}
function AlertDialogContent({ className, children, ...props }: AlertDialog.Popup.Props) {
return (
<AlertDialogPortal>
<AlertDialogBackdrop />
<AlertDialog.Popup className={cn(styles.content, className)} data-slot="alert-dialog-popup" {...props}>
{children}
</AlertDialog.Popup>
</AlertDialogPortal>
);
}
function AlertDialogTitle({ className, ...props }: AlertDialog.Title.Props) {
return <AlertDialog.Title className={cn(styles.title, className)} data-slot="alert-dialog-title" {...props} />;
}
function AlertDialogDescription({ className, ...props }: AlertDialog.Description.Props) {
return (
<AlertDialog.Description
className={cn(styles.description, className)}
data-slot="alert-dialog-description"
{...props}
/>
);
}
function AlertDialogClose({ ...props }: AlertDialog.Close.Props) {
return <AlertDialog.Close data-slot="alert-dialog-close" nativeButton {...props} />;
}
const AlertDialogOverlay = AlertDialogBackdrop;
function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">) {
return <div className={cn(styles.header, className)} data-slot="alert-dialog-header" {...props} />;
}
function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">) {
return <div className={cn(styles.footer, className)} data-slot="alert-dialog-footer" {...props} />;
}
export {
AlertDialogRoot as AlertDialog,
AlertDialogClose,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogOverlay,
AlertDialogPopup,
AlertDialogPortal,
AlertDialogRoot,
AlertDialogTitle,
AlertDialogTrigger,
};
registry/brook/ui/alert-dialog/alert-dialog.module.css
.overlay {
position: fixed;
inset: 0;
z-index: var(--dialog-z);
background-color: var(--dialog-overlay);
transition: opacity 150ms;
&[data-starting-style],
&[data-ending-style] {
opacity: 0;
}
}
.content {
position: fixed;
left: 50%;
top: 50%;
z-index: 101;
display: grid;
width: 100%;
max-width: 32rem;
max-height: 85vh;
overflow-y: auto;
gap: 1rem;
border: none;
box-shadow:
0 0 0 1px oklch(from var(--border) l c h / 0.5),
var(--shadow-border-stack);
padding: 1.5rem;
border-radius: var(--radius);
background-color: var(--mix-card-5-bg);
transform: translate(-50%, -50%);
transition: all 150ms;
&[data-starting-style],
&[data-ending-style] {
opacity: 0;
transform: translate(-50%, -50%) scale(0.95);
}
@media (max-width: 640px) {
width: calc(100vw - 2rem);
max-width: none;
left: 1rem;
right: 1rem;
top: 50%;
transform: translateY(-50%);
&[data-starting-style],
&[data-ending-style] {
opacity: 0;
transform: translateY(-50%) scale(0.95);
}
}
}
.header {
display: flex;
flex-direction: column;
gap: 0.5rem;
text-align: left;
& h2 {
margin: 0;
}
& p {
margin: 0;
}
}
.footer {
display: flex;
flex-direction: column-reverse;
gap: 0.5rem;
@media (min-width: 640px) {
flex-direction: row;
justify-content: flex-end;
}
}
.title {
font-size: 1.125rem;
font-weight: 600;
line-height: 1;
letter-spacing: -0.025em;
color: var(--foreground);
margin: 0;
}
.description {
font-size: 0.875rem;
color: var(--secondary-foreground);
margin: 0;
line-height: 1.5;
}
.close {
appearance: none;
border: none;
background: transparent;
cursor: pointer;
padding: 0.5rem 1rem;
border-radius: var(--radius);
font-size: 0.875rem;
font-weight: 500;
transition: all 150ms ease-out;
&:hover {
background-color: var(--muted);
}
&:focus-visible {
outline: 2px solid var(--ring);
outline-offset: 2px;
}
}