Sonner
An opinionated toast component powered by Sonner, styled with Hummingbird's design tokens.
Usage
The Toaster is rendered once at the application root; toasts are then fired from anywhere with the toast function.
import { Toaster } from "@hummingbirdui/react";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Toaster />
</body>
</html>
);
}import { toast } from "@hummingbirdui/react";
toast("Event has been created");Default
The default toast displays a message, with optional description and action.
tsx
import { Button, toast } from "@hummingbirdui/react";
export default function SonnerDefault() {
return (
<div className="text-center">
<Button
variant="outline"
onClick={() =>
toast("Event has been created", {
description: "Sunday, December 03, 2023 at 9:00 AM",
action: {
label: "Undo",
onClick: () => console.log("Undo"),
},
})
}
>
Show Toast
</Button>
</div>
);
}Types
toast.success, toast.info, toast.warning, and toast.error render typed toasts with a matching icon. toast.promise tracks a promise through loading, success, and error states.
tsx
import { Button, toast } from "@hummingbirdui/react";
export default function SonnerTypes() {
const promise = () =>
new Promise<{ name: string }>((resolve) =>
setTimeout(() => resolve({ name: "Sonner" }), 2000)
);
return (
<div className="flex flex-wrap justify-center gap-2">
<Button variant="outline" onClick={() => toast("Event has been created")}>
Default
</Button>
<Button
variant="outline"
onClick={() => toast.success("Event has been created")}
>
Success
</Button>
<Button
variant="outline"
onClick={() =>
toast.info("Be at the area 10 minutes before the event time")
}
>
Info
</Button>
<Button
variant="outline"
onClick={() =>
toast.warning("Event start time cannot be earlier than 8am")
}
>
Warning
</Button>
<Button
variant="outline"
onClick={() => toast.error("Event has not been created")}
>
Error
</Button>
<Button
variant="outline"
onClick={() =>
toast("Event has been created", {
action: {
label: "Undo",
onClick: () => console.log("Undo"),
},
})
}
>
Action
</Button>
<Button
variant="outline"
onClick={() =>
toast.promise(promise, {
loading: "Loading...",
success: (data) => `${data.name} toast has been added`,
error: "Error",
})
}
>
Promise
</Button>
</div>
);
}Description
toast.message renders a message with a supporting description underneath.
tsx
import { Button, toast } from "@hummingbirdui/react";
export default function SonnerDescription() {
return (
<div className="text-center">
<Button
variant="outline"
onClick={() =>
toast.message("Event has been created", {
description: "Monday, January 3rd at 6:00pm",
})
}
>
Show Toast
</Button>
</div>
);
}Position
tsx
import { Button, toast } from "@hummingbirdui/react";
const positions = [
"top-left",
"top-center",
"top-right",
"bottom-left",
"bottom-center",
"bottom-right",
] as const;
export default function SonnerPosition() {
return (
<div className="flex flex-wrap justify-center gap-2">
{positions.map((position) => (
<Button
key={position}
variant="outline"
onClick={() =>
toast("Event has been created", { position })
}
>
{position}
</Button>
))}
</div>
);
}Custom
toast.custom renders fully custom JSX - including Hummingbird's own toast classes while Sonner keeps handling stacking, timing, and dismissal.
tsx
import { Button, CloseButton, toast } from "@hummingbirdui/react";
export default function SonnerCustom() {
return (
<div className="text-center">
<Button
variant="outline"
onClick={() =>
toast.custom((t) => (
<div className="toast show">
<div className="toast-header">
<strong className="me-auto">Hummingbird</strong>
<small>just now</small>
<CloseButton onClick={() => toast.dismiss(t)} />
</div>
<div className="toast-body">
A fully custom toast built with Hummingbird classes.
</div>
</div>
))
}
>
Show Custom Toast
</Button>
</div>
);
}API Reference
Built on sonner.
Toaster
| Prop | Type | Default |
|---|---|---|
theme | enum | "light" |
position | enum | "bottom-right" |
richColors | boolean | false |
expand | boolean | false |
visibleToasts | number | 3 |
closeButton | boolean | false |
duration | number | 4000 |
offset | number | "24px" |
dir | enum | "auto" |
hotkey | string[] | ["altKey", "KeyT"] |
invert | boolean | false |
gap | number | 14 |
icons | object | — |
toastOptions | object | — |
style | object | — |
className | string | — |
toast
The toast function shows a toast and returns its id.
toast.success/toast.info/toast.warning/toast.error— typed toasts with an icontoast.message— message with a descriptiontoast.promise— loading, success, and error states of a promisetoast.loading— toast with a spinnertoast.custom— custom JSXtoast.dismiss— removes a toast by id, or all toasts without one
Every call accepts options like description, duration, position, and action — see the Sonner API reference.
Styling
The Toaster maps Sonner's CSS variables to Hummingbird tokens, so toasts follow the active theme automatically.
--normal-bg: var(--background-color-subtle);
--normal-text: var(--text-color-default);
--normal-border: var(--border-color-default);
--border-radius: var(--radius-lg);- Individual variables are overridden through the
styleprop on theToaster. - Per-part classes are applied through
toastOptions.classNames; fully custom markup usestoast.customwith Hummingbird's toast classes.