Components
- Accordion
- Alert
- Alert Dialog
- Autocomplete
- Avatar
- Badge
- Breadcrumb
- Button
- Card
- Checkbox
- Checkbox Group
- Collapsible
- Combobox
- Dialog
- Empty
- Field
- Fieldset
- Form
- Frame
- Group
- Input
- Label
- Menu
- Meter
- Number Field
- Pagination
- Popover
- Preview Card
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- Skeleton
- Slider
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Toolbar
- Tooltip
Toast
Generates toast notifications.
"use client"
import { Button } from "@/components/ui/button"
import { toastManager } from "@/components/ui/toast"
export default function ToastDemo() {
return (
<Button
variant="outline"
onClick={() => {
toastManager.add({
title: "Event has been created",
description: "Monday, January 3rd at 6:00pm",
})
}}
>
Default Toast
</Button>
)
}
Installation
npx love-ui@latest add toastAdd the ToastProvider to your app.
import { ToastProvider } from "@/components/ui/toast"
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<ToastProvider>
<main>{children}</main>
</ToastProvider>
</body>
</html>
)
}Usage
import { toastManager } from "@/components/ui/toast"toastManager.add({
title: "Event has been created",
description: "Monday, January 3rd at 6:00pm",
})By default, toasts appear in the bottom-right corner. You can change this by setting the position prop on the ToastProvider.
Allowed values: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right. For example:
<ToastProvider position="top-center">{children}</ToastProvider>Examples
With Status
"use client"
import { Button } from "@/components/ui/button"
import { toastManager } from "@/components/ui/toast"
export default function ToastWithStatus() {
return (
<div className="flex flex-wrap gap-2">
<Button
variant="outline"
onClick={() => {
toastManager.add({
title: "Success!",
description: "Your changes have been saved.",
type: "success",
})
}}
>
Success Toast
</Button>
<Button
variant="outline"
onClick={() => {
toastManager.add({
title: "Uh oh! Something went wrong.",
description: "There was a problem with your request.",
type: "error",
})
}}
>
Error Toast
</Button>
<Button
variant="outline"
onClick={() => {
toastManager.add({
title: "Heads up!",
description: "You can add components to your app using the cli.",
type: "info",
})
}}
>
Info Toast
</Button>
<Button
variant="outline"
onClick={() => {
toastManager.add({
title: "Warning!",
description: "Your session is about to expire.",
type: "warning",
})
}}
>
Warning Toast
</Button>
</div>
)
}
Loading
"use client"
import { Button } from "@/components/ui/button"
import { toastManager } from "@/components/ui/toast"
export default function ToastLoading() {
return (
<Button
variant="outline"
onClick={() => {
toastManager.add({
title: "Loading…",
description: "Please wait while we process your request.",
type: "loading",
})
}}
>
Loading Toast
</Button>
)
}
With Action
"use client"
import { Button } from "@/components/ui/button"
import { toastManager } from "@/components/ui/toast"
export default function ToastWithAction() {
return (
<Button
variant="outline"
onClick={() => {
const id = toastManager.add({
title: "Action performed",
description: "You can undo this action.",
type: "success",
actionProps: {
children: "Undo",
onClick: () => {
toastManager.close(id)
toastManager.add({
title: "Action undone",
description: "The action has been reverted.",
type: "info",
})
},
},
timeout: 1000000,
})
}}
>
Perform Action
</Button>
)
}
Promise
"use client"
import { Button } from "@/components/ui/button"
import { toastManager } from "@/components/ui/toast"
export default function ToastPromise() {
return (
<Button
variant="outline"
onClick={() => {
toastManager.promise(
new Promise<string>((resolve, reject) => {
const shouldSucceed = Math.random() > 0.3
setTimeout(() => {
if (shouldSucceed) {
resolve("Data loaded successfully")
} else {
reject(new Error("Failed to load data"))
}
}, 2000)
}),
{
loading: {
title: "Loading…",
description: "The promise is loading.",
},
success: (data: string) => ({
title: "This is a success toast!",
description: `Success: ${data}`,
}),
error: () => ({
title: "Something went wrong",
description: "Please try again.",
}),
}
)
}}
>
Run Promise
</Button>
)
}
With Varying Heights
"use client"
import * as React from "react"
import { Button } from "@/components/ui/button"
import { toastManager } from "@/components/ui/toast"
const TEXTS = [
"Short message.",
"A bit longer message that spans two lines.",
"This is a longer description that intentionally takes more vertical space to demonstrate stacking with varying heights.",
"An even longer description that should span multiple lines so we can verify the clamped collapsed height and smooth expansion animation when hovering or focusing the viewport.",
]
export default function ToastHeights() {
const [count, setCount] = React.useState(0)
function createToast() {
setCount((prev) => prev + 1)
const description = TEXTS[Math.floor(Math.random() * TEXTS.length)]
toastManager.add({
title: `Toast ${count + 1} created`,
description,
})
}
return (
<Button variant="outline" onClick={createToast}>
With Varying Heights
</Button>
)
}
Comparing with Sonner / shadcn
The API is significantly different from shadcn/ui (Sonner). Please review both docs before migrating: Sonner Docs and shadcn/ui Sonner, and our Base UI toast docs referenced at the top of this page.
Comparison Examples
shadcn/ui (Sonner)
import { Toaster } from "@/components/ui/sonner"
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<main>{children}</main>
<Toaster />
</body>
</html>
)
}toast("Event has been created", {
description: "Sunday, December 03, 2023 at 9:00 AM",
cancel: {
label: "Undo",
},
})loveui (Base UI)
import { ToastProvider } from "@/rcomponents/ui/toast"
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<ToastProvider>
<main>{children}</main>
</ToastProvider>
</body>
</html>
)
}onClick={() => {
const id = toastManager.add({
title: "Event has been created",
description: "Sunday, December 03, 2023 at 9:00 AM",
type: "success",
actionProps: {
children: "Undo",
onClick: () => toastManager.close(id),
},
})
}}