Alert dialog

Requires a decision before work continues. Native dialog with Escape and light dismiss disabled.

Delete this workspace?

All projects go with it. This needs an answer.

Kill

Pull a sheet from the run. The question needs an answer.

Delete this sheet?

The plate goes with it.

Use it for

  • Destructive or irreversible actions that need an explicit answer.
  • Exactly two actions: keep and proceed.

Not for

  • Anything the user may dismiss without answering; use Dialog.
  • Informational messages; use Alert or toast.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

npm install @noorddev/vlak-react

// once, next to your app's root
import "@noorddev/vlak-react/css";

import { AlertDialog, AlertDialogActions, AlertDialogBody, AlertDialogTitle, Button } from "@noorddev/vlak-react";

Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/alert-dialog.

2. Vendor the source

npx @noorddev/vlak-cli add alert-dialog

The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.

3. Through shadcn

npx shadcn add https://vlak.dev/r/alert-dialog.json

The same registry item, installed by shadcn's CLI.

CSS only

<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />

No React. Link vlak.css and use the markup and classes below.

import { useState } from "react";
import { AlertDialog, AlertDialogActions, AlertDialogBody, AlertDialogTitle, Button } from "@noorddev/vlak-react";

const [open, setOpen] = useState(false);

<AlertDialog open={open} onClose={() => setOpen(false)}>
  <AlertDialogTitle>Delete this workspace?</AlertDialogTitle>
  <AlertDialogBody>All projects go with it.</AlertDialogBody>
  <AlertDialogActions>
    <Button variant="ghost" size="sm" onClick={() => setOpen(false)}>Keep it</Button>
    <Button size="sm" onClick={remove}>Delete</Button>
  </AlertDialogActions>
</AlertDialog>

AlertDialog

A native <dialog> that requires an explicit answer. Escape and light dismiss are off (closedby="none"); the actions close it.

PropTypeDefaultDescription
openrequiredboolean
onClose() => void
extraStylesLeavesExtra StyleX leaves merged after the dialog frame (command palette).

Also accepts Omit<DialogHTMLAttributes<HTMLDialogElement>, "open" | "onClose">.

AlertDialogActions

Also accepts HTMLAttributes<HTMLDivElement>.

AlertDialogBody

Also accepts HTMLAttributes<HTMLParagraphElement>.

AlertDialogTitle

PropTypeDefaultDescription
as"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "div""h2"Heading level. The dialog is named by this element either way.

Also accepts HTMLAttributes<HTMLHeadingElement>.

KeysDoes
Tab, Shift + TabCycles focus between the actions
Enter, SpaceActivates the focused action
EscapeDoes nothing; the dialog must be answered
<dialog class="rs-dialog" role="alertdialog" closedby="none" aria-labelledby="delete-title" aria-describedby="delete-body" open><h2 class="rs-dialog-title" id="delete-title">Delete this workspace?</h2><p class="rs-dialog-body" id="delete-body">All projects go with it.</p><div class="rs-dialog-actions"><button class="rs-btn-ghost rs-btn-sm">Cancel</button><button class="rs-btn-primary rs-btn-sm">Delete</button></div></dialog>
.rs-alert-dialog