Components
- Accordion
- Alert
- Alert Dialog
- Autocomplete
- Avatar
- Badge
- Breadcrumb
- Button
- Card
- Checkbox
- Checkbox Group
- Collapsible
- Combobox
- Dialog
- Field
- Fieldset
- Form
- Frame
- Group
- Input
- Label
- Menu
- Meter
- Number Field
- Pagination
- Popover
- Preview Card
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- Slider
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Toolbar
- Tooltip
Resources
Toast
Generates toast notifications.
"use client"
import { Button } from "@/components/ui/button"
import { toastManager } from "@/components/ui/toast"
export 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
pnpm dlx shadcn@latest add https://coss.com/ui/r/toast.json
Add the ToastProvider
to your app.
import { ToastProvider } from "@/rcomponents/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 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 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 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 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 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",
},
})
coss.com ui (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),
},
})
}}