Browse docs
Browse docs
Surface a persistent status. Flag a warning. Confirm a save.
import { Alert } from '@dashforge/tw';
<Alert severity="success">Customer saved.</Alert><Alert severity="info">Heads up: build will take ~3 minutes.</Alert>
<Alert severity="warning" onClose={() => dismiss()}>
Your trial ends in 5 days.
</Alert>
<Alert severity="danger" variant="filled">
<AlertTitle>Failed to save</AlertTitle>
Check the network and retry.
</Alert>Four tones, all token-driven through dashforgePreset(). Use danger, not error — the prop value aligns with the danger.* token palette name (see Design decisions).
import { Alert, Stack } from '@dashforge/tw';
<Stack gap={2}>
<Alert severity="info">Informational message.</Alert>
<Alert severity="success">Operation completed.</Alert>
<Alert severity="warning">Check the field above.</Alert>
<Alert severity="danger">Something went wrong.</Alert>
</Stack>The same 3-variant axis as <Snackbar> (which is the transient-toast sibling of Alert):
import { Alert, Stack } from '@dashforge/tw';
<Stack gap={2}>
<Alert severity="info" variant="standard">Standard (soft tinted, default).</Alert>
<Alert severity="info" variant="filled">Filled (solid bg + light text).</Alert>
<Alert severity="info" variant="outlined">Outlined (border only).</Alert>
</Stack>standard is the default — softly tinted background with same-color text. Suitable for non-urgent persistent messaging inside dashboards. Use filled for high-prominence callouts, outlined for low-visual-weight notices on busy backgrounds.
<AlertTitle> ships as a sub-component for the heading row. It renders as a semantically appropriate element with the right typography.
import { Alert, AlertTitle } from '@dashforge/tw';
<Alert severity="warning">
<AlertTitle>Heads up</AlertTitle>
Your subscription expires in 7 days. Renew to keep access to premium features.
</Alert>The icon prop is tristate:
undefined (omitted) → default SVG icon for the severity, from _shared/severity/ReactNode → custom icon (any React element)false → no icon at all<Alert severity="info" icon={<MyCustomInfoIcon />}>Custom icon.</Alert>
<Alert severity="info" icon={false}>No icon at all.</Alert>Pass onClose to render a close button on the right. The button has accessible aria-label="Close" by default; override with closeText.
import { useState } from 'react';
import { Alert, AlertTitle, Button } from '@dashforge/tw';
function DismissibleAlert() {
const [open, setOpen] = useState(true);
if (!open) return <Button variant="outline" onClick={() => setOpen(true)}>Show alert again</Button>;
return (
<Alert severity="warning" onClose={() => setOpen(false)}>
<AlertTitle>Heads up</AlertTitle>
Your trial ends in 5 days. Click X to dismiss.
</Alert>
);
}Custom right-side action (e.g. a CTA button). When action is set and onClose is also set, both render — action left of the close button.
<Alert
severity="warning"
action={<Button size="sm" variant="outlined">Renew now</Button>}
>
Your trial ends in 5 days.
</Alert>By default role resolves to 'alert' for danger and 'status' for everything else. Override when needed (e.g. 'alert' for a critical warning to interrupt screen-reader flow):
<Alert severity="warning" role="alert">
Unsaved changes will be lost.
</Alert>Alert ships the universal bridge contract from day one — same as <Button>, <TextField>, and the other interactive components (Sprint 4.4 alignment).
// RBAC gating
<Alert severity="danger" access={{ requires: 'workspace.delete', when: 'denied:hide' }}>
Workspace will be permanently deleted.
</Alert>
// Engine-reactive visibility
<Alert severity="warning" visibleWhen={(engine) => engine.getValue('hasUnsavedChanges') === true}>
Unsaved changes will be lost on navigation.
</Alert><Alert> props| Prop | Type | Default | Description |
|---|---|---|---|
severity | 'info' | 'success' | 'warning' | 'danger' | (required) | Semantic tone. Drives bg/fg/border and default icon. Uses danger (token-aligned), not error. |
variant | 'standard' | 'filled' | 'outlined' | 'standard' | Visual treatment. Standard = soft tinted, filled = solid, outlined = border only. |
icon | ReactNode | false | — | Tristate. undefined → default per-severity SVG. ReactNode → custom. false → suppress. |
onClose | () => void | — | When set, renders a close button on the right with aria-label="Close". |
closeText | string | 'Close' | Override the close button accessible label. |
action | ReactNode | — | Custom right-side action slot (rendered left of close button if both set). |
role | 'alert' | 'status' | derived from severity | Override ARIA role. Defaults: 'alert' for danger, 'status' for others. |
access | AccessSpec | — | RBAC gating. See Access Control. |
visibleWhen | (engine: Engine) => boolean | — | Engine-reactive predicate. Component returns null when false. |
className | string | — | Merged via tailwind-merge. |
sx | string | — | String-form Tailwind override applied last. |
slotProps | { root?, icon?, content?, action?, closeButton?, titleSlot? } | — | Per-slot overrides. |
<AlertTitle> props| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | The heading text. |
className | string | — | Merged via tailwind-merge. |
root · icon · titleSlot · content · action · closeButton
severity="danger" vs MUI's "error" is intentional — the prop value aligns with the danger.* token palette. See Design decisions → severity rename._shared/severity/, shared with <Snackbar>. A future <Banner> will plug into the same foundation.<Snackbar>. Alert is for persistent inline status.@dashforge/forms engine + @dashforge/rbac package as the form fields, so visibleWhen predicates and access declarations are portable across components and across MUI/TW flavors.