Primitives
Alert
Five tones, four looks; the icon carries the tone too. Danger and warning are announced.
soft
Rates change on 1 November
Payout sent
Gate 2 camera is slow
Payout on hold
outline
Rates change on 1 November
Payout sent
Gate 2 camera is slow
Payout on hold
accent
Rates change on 1 November
Payout sent
Gate 2 camera is slow
Payout on hold
solid
Rates change on 1 November
Payout sent
Gate 2 camera is slow
Payout on hold
Payout on hold
Read-only
"use client";
import { Alert, Button, type AlertTone, type AlertVariant } from "@waveinno/ui";
import * as React from "react";
const COPY: Record<AlertTone, [string, string]> = {
info: ["Rates change on 1 November", "Cars pay ৳35 for the first hour from then. Monthly passes keep their price."],
success: ["Payout sent", "৳1,24,500 reached your bank account ending 4410."],
warning: ["Gate 2 camera is slow", "Plates are read in 4 s instead of 1 s. Attendants may need to type some."],
danger: ["Payout on hold", "Your bank rejected the transfer. Check the account number in Billing."],
neutral: ["Read-only", "You are viewing Gulshan as an auditor. Changes are turned off."],
};
export default function AlertDemo() {
const [shown, setShown] = React.useState(true);
return (
<div className="space-y-6">
{(["soft", "outline", "accent", "solid"] as AlertVariant[]).map((variant) => (
<div key={variant} className="space-y-2">
<p className="text-[12px] text-muted">{variant}</p>
<div className="grid gap-2.5 md:grid-cols-2">
{(["info", "success", "warning", "danger"] as AlertTone[]).map((tone) => (
<Alert key={tone} tone={tone} variant={variant} title={COPY[tone][0]}>
{COPY[tone][1]}
</Alert>
))}
</div>
</div>
))}
<div className="grid gap-2.5 md:grid-cols-2">
{shown ? (
<Alert
tone="danger"
title={COPY.danger[0]}
onDismiss={() => setShown(false)}
action={
<>
<Button size="sm">Fix in Billing</Button>
<Button size="sm" variant="ghost">
Contact support
</Button>
</>
}
>
{COPY.danger[1]}
</Alert>
) : (
<Button variant="secondary" onClick={() => setShown(true)} className="justify-self-start">
Show the dismissed alert again
</Button>
)}
<Alert tone="neutral" variant="outline" title={COPY.neutral[0]}>
{COPY.neutral[1]}
</Alert>
</div>
</div>
);
}Import#
Everything comes from the package root. The example above uses:
import { Alert, Button, type AlertTone, type AlertVariant } from "@waveinno/ui";Props#
Read from the source of this version, so they match the code exactly.
<Alert>
src/components/ui/alert.tsx| Prop | Type | Default | Description |
|---|---|---|---|
tone | "info" | "success" | "warning" | "danger" | "neutral" | "info" | |
variant | "soft" | "outline" | "solid" | "accent" | "soft" | |
title | React.ReactNode | — | |
icon | React.ReactNode | false | — | Replace the tone's icon, or `false` for none. |
action | React.ReactNode | — | Buttons under the text: "Retry", "Review". |
onDismiss | () => void | — | Shows a close button; called when it is pressed. |
Also takes Omit<React.HTMLAttributes<HTMLDivElement>, "title">.
<Button>
src/components/ui/button.tsx| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | |
loading | boolean | — |
Also takes ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>.
Install#
If the project does not have the package yet, add it, then follow the setup for Next.js or Vite once.
$ npm install @waveinno/ui