"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
const Demo = () => {
return (
<Button
variant="outline"
size="sm"
onClick={() =>
toaster.create({
description: "File saved successfully",
type: "info",
})
}
>
Show Toast
</Button>
)
}
Setup
If you don't already have the snippet, run the following command to add the
toaster
snippet
chakra snippet add toaster
The snippet includes a closed component composition for the Toast
component.
Usage
import { Toaster, toaster } from "@/components/ui/toaster"
First, render the Toaster
component in your app.
<Toaster />
Then, create a toast by calling the toaster
function.
toaster.create({
title: "Toast Title",
description: "Toast Description",
})
Examples
Persistent Toast
Set the type
prop to "loading"
to create a persistent toast.
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
const Demo = () => {
return (
<Button
variant="outline"
size="sm"
onClick={() =>
toaster.create({
description: "File saved successfully",
type: "loading",
})
}
>
Show Toast
</Button>
)
}
Types
Here's an example of each type of toast.
"use client"
import { Button, For, HStack } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
const Demo = () => {
return (
<HStack>
<For each={["success", "error", "warning", "info"]}>
{(type) => (
<Button
size="sm"
variant="outline"
key={type}
onClick={() =>
toaster.create({
title: `Toast status is ${type}`,
type: type,
})
}
>
{type}
</Button>
)}
</For>
</HStack>
)
}
With Action
Use the action
and actionLabel
prop to add an action to the toast.
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
const Demo = () => {
return (
<Button
variant="outline"
size="sm"
onClick={() =>
toaster.success({
title: "Update successful",
description: "File saved successfully to the server",
action: {
label: "Undo",
onClick: () => console.log("Undo"),
},
})
}
>
Click me
</Button>
)
}
Promise
Use the toaster.promise
to create a toast that resolves when the promise is
resolved.
Next, you can define the toast options (title, description, etc.) for each state of the promise.
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
const Demo = () => {
return (
<Button
variant="outline"
size="sm"
onClick={() => {
const promise = new Promise<void>((resolve) => {
setTimeout(() => resolve(), 5000)
})
toaster.promise(promise, {
success: {
title: "Successfully uploaded!",
description: "Looks great",
},
error: {
title: "Upload failed",
description: "Something wrong with the upload",
},
loading: { title: "Uploading...", description: "Please wait" },
})
}}
>
Show Toast
</Button>
)
}
Custom Duration
Use the duration
prop to set the duration of the toast.
"use client"
import { Button } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
const Demo = () => {
return (
<Button
variant="outline"
size="sm"
onClick={() =>
toaster.create({
description: "File saved successfully",
duration: 6000,
})
}
>
Show Toast
</Button>
)
}
Pause and Play
Use the pause
and resume
methods on the toaster
object to pause and play
the toast.
"use client"
import { Button, HStack } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
import { useId, useState } from "react"
import { HiPause, HiPlay } from "react-icons/hi"
const Demo = () => {
const id = useId()
const [paused, setPaused] = useState(false)
const show = () => {
toaster.success({ id, title: "This is a success toast" })
}
const pause = () => {
toaster.pause(id)
setPaused(true)
}
const play = () => {
toaster.resume(id)
setPaused(false)
}
return (
<HStack>
<Button variant="outline" size="sm" onClick={show}>
Show Toast
</Button>
<Button variant="outline" size="sm" onClick={pause} disabled={!paused}>
<HiPause />
Pause Toast
</Button>
<Button variant="outline" size="sm" onClick={play} disabled={paused}>
<HiPlay />
Play Toast
</Button>
</HStack>
)
}
Lifecycle
Use the onStatusChange
prop on the toaster
function to listen for changes to
the toast's status.
"use client"
import { Button, HStack, Stack, Text } from "@chakra-ui/react"
import { toaster } from "@/components/ui/toaster"
import { useState } from "react"
const Demo = () => {
const [statusLog, setStatusLog] = useState<[number, string][]>([])
const [dismissed, setDismissed] = useState(true)
return (
<Stack align="flex-start">
<Button
disabled={!dismissed}
variant="outline"
size="sm"
onClick={() =>
toaster.create({
description: "This is a toast",
type: "info",
onStatusChange({ status }) {
setDismissed(status === "unmounted")
setStatusLog((prev) => [[Date.now(), status], ...prev])
},
})
}
>
Show Toast
</Button>
<Stack padding="2" width="full" role="log" borderWidth="1px" minH="100px">
{statusLog.map(([time, toastStatus], i) => {
const date = new Date(time)
return (
<HStack as="pre" fontFamily="mono" textStyle="sm" key={i}>
{date.toLocaleTimeString()}{" "}
<Text fontWeight="bold">{toastStatus}</Text>
</HStack>
)
})}
</Stack>
</Stack>
)
}
Maximum Visible Toasts
Set the max
prop on the createToaster
function to define the maximum number
of toasts that can be rendered at any one time. Any extra toasts will be queued
and rendered when a toast has been dismissed.
@/components/ui/toaster.tsx
const toaster = createToaster({
max: 3,
})
Placement
Toasts can be displayed on all four corners of a page. We recommend picking one
desired position and configure it in the createToaster
function.
@/components/ui/toaster.tsx
const toaster = createToaster({
placement: "top-end",
})
Overlapping Toasts
By default, toasts are stacked on top of each other. To make the toasts overlap
each other, set the overlap
prop to true
in the createToaster
function.
@/components/ui/toaster.tsx
const toaster = createToaster({
placement: "top-end",
overlap: true,
})
Offset
Set the offset
prop in the createToaster
function to offset the toasts from
the edges of the screen.
@/components/ui/toaster.tsx
const toaster = createToaster({
offset: "20px",
})
Alternatively, you can use the offset
prop to set the offset for each edge of
the screen.
@/components/ui/toaster.tsx
const toaster = createToaster({
offset: { left: "20px", top: "20px", right: "20px", bottom: "20px" },
})