Toast
A message that appears on the screen to provide feedback on an action.
Anatomy
To set up the toast correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-part
attribute to help identify them in the DOM.
Setup
To use the Toast component, create the toast engine using the createToaster
function.
This function manages the placement and grouping of toasts, and provides a toast
object needed
to create toast notification.
const toaster = createToaster({
placement: 'bottom-end',
overlap: true,
gap: 24,
})
Examples
Here's an example of creating a toast using the toast.create
method.
import { Toast, Toaster, createToaster } from '@ark-ui/react/toast'
import { XIcon } from 'lucide-react'
const toaster = createToaster({
placement: 'bottom-end',
overlap: true,
gap: 24,
})
export const Basic = () => {
return (
<div>
<button
type="button"
onClick={() =>
toaster.create({
title: 'Toast Title',
description: 'Toast Description',
type: 'info',
})
}
>
Add Toast
</button>
<Toaster toaster={toaster}>
{(toast) => (
<Toast.Root key={toast.id}>
<Toast.Title>{toast.title}</Toast.Title>
<Toast.Description>{toast.description}</Toast.Description>
<Toast.CloseTrigger>
<XIcon />
</Toast.CloseTrigger>
</Toast.Root>
)}
</Toaster>
</div>
)
}
import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast'
import { XIcon } from 'lucide-solid'
export const Basic = () => {
const toaster = createToaster({
placement: 'bottom-end',
gap: 24,
})
return (
<div>
<button
type="button"
onClick={() =>
toaster.create({
title: 'Loading!',
description: 'We are loading something for you. Please wait.',
type: 'info',
})
}
>
Add Toast
</button>
<Toaster toaster={toaster}>
{(toast) => (
<Toast.Root>
<Toast.Title>{toast().title}</Toast.Title>
<Toast.Description>{toast().description}</Toast.Description>
<Toast.CloseTrigger>
<XIcon />
</Toast.CloseTrigger>
</Toast.Root>
)}
</Toaster>
</div>
)
}
<script setup lang="tsx">
import { Toast, Toaster, createToaster } from '@ark-ui/vue/toast'
const toaster = createToaster({ placement: 'bottom-end', overlap: true, gap: 24 })
const createToast = () => {
toaster.create({
title: 'Title',
description: 'Description',
type: 'info',
})
}
</script>
<template>
<button @click="createToast">Create Toast</button>
<Toaster :toaster="toaster" v-slot="toast">
<Toast.Root>
<Toast.Title>{{ toast.title }}</Toast.Title>
<Toast.Description>{{ toast.description }}</Toast.Description>
<Toast.ActionTrigger>Action</Toast.ActionTrigger>
<Toast.CloseTrigger>Close</Toast.CloseTrigger>
</Toast.Root>
</Toaster>
</template>
Update Toast
To update a toast, use the toast.update
method.
import { Toast, Toaster, createToaster } from '@ark-ui/react/toast'
import { useRef } from 'react'
const toaster = createToaster({
placement: 'bottom-end',
overlap: true,
gap: 24,
})
export const Update = () => {
const id = useRef<string>()
const createToast = () => {
id.current = toaster.create({
title: 'Loading',
description: 'Loading ...',
type: 'info',
})
}
const updateToast = () => {
if (!id.current) {
return
}
toaster.update(id.current, {
title: 'Success',
description: 'Success!',
})
}
return (
<div>
<button type="button" onClick={createToast}>
Create Toast
</button>
<button type="button" onClick={updateToast}>
Update Toast
</button>
<Toaster toaster={toaster}>
{(toast) => (
<Toast.Root key={toast.id}>
<Toast.Title>{toast.title}</Toast.Title>
<Toast.Description>{toast.description}</Toast.Description>
</Toast.Root>
)}
</Toaster>
</div>
)
}
import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast'
import { createSignal } from 'solid-js'
const toaster = createToaster({
placement: 'bottom-end',
overlap: true,
gap: 24,
})
export const Update = () => {
const [id, setId] = createSignal<string | undefined>(undefined)
const createToast = () => {
const newId = toaster.create({
title: 'Loading',
description: 'Loading ...',
type: 'info',
})
setId(newId)
}
const updateToast = () => {
const currentId = id()
if (!currentId) {
return
}
toaster.update(currentId, {
title: 'Success',
description: 'Success!',
})
}
return (
<div>
<button type="button" onClick={createToast}>
Create Toast
</button>
<button type="button" onClick={updateToast}>
Update Toast
</button>
<Toaster toaster={toaster}>
{(toast) => (
<Toast.Root>
<Toast.Title>{toast().title}</Toast.Title>
<Toast.Description>{toast().description}</Toast.Description>
</Toast.Root>
)}
</Toaster>
</div>
)
}
<script setup lang="ts">
import { Toast, Toaster, createToaster } from '@ark-ui/vue/toast'
import { ref } from 'vue'
const toaster = createToaster({
placement: 'bottom-end',
overlap: true,
gap: 24,
})
const id = ref<string | undefined>(undefined)
const createToast = () => {
id.value = toaster.create({
title: 'Loading',
description: 'Loading ...',
type: 'info',
})
}
const updateToast = () => {
if (!id.value) {
return
}
toaster.update(id.value, {
title: 'Success',
description: 'Success!',
})
}
</script>
<template>
<div>
<button type="button" @click="createToast">Create Toast</button>
<button type="button" @click="updateToast">Update Toast</button>
<Toaster :toaster="toaster" v-slot="toast">
<Toast.Root>
<Toast.Title>{{ toast.title }}</Toast.Title>
<Toast.Description>{{ toast.description }}</Toast.Description>
</Toast.Root>
</Toaster>
</div>
</template>
Action
To add an action to a toast, use the toast.action
property.
import { Toast, Toaster, createToaster } from '@ark-ui/react/toast'
const toaster = createToaster({
placement: 'bottom-end',
gap: 24,
})
export const Action = () => {
return (
<div>
<button
type="button"
onClick={() =>
toaster.create({
title: 'Toast Title',
description: 'Toast Description',
type: 'info',
action: {
label: 'Subscribe',
onClick: () => {
console.log('Subscribe')
},
},
})
}
>
Add Toast
</button>
<Toaster toaster={toaster}>
{(toast) => (
<Toast.Root key={toast.id}>
<Toast.Title>{toast.title}</Toast.Title>
<Toast.Description>{toast.description}</Toast.Description>
{toast.action && <Toast.ActionTrigger>{toast.action?.label}</Toast.ActionTrigger>}
</Toast.Root>
)}
</Toaster>
</div>
)
}
import { Toast, Toaster, createToaster } from '@ark-ui/solid/toast'
const toaster = createToaster({
placement: 'bottom-end',
gap: 24,
})
export const Action = () => {
return (
<div>
<button
type="button"
onClick={() =>
toaster.create({
title: 'Toast Title',
description: 'Toast Description',
type: 'info',
action: {
label: 'Subscribe',
onClick: () => {
console.log('Subscribe')
},
},
})
}
>
Add Toast
</button>
<Toaster toaster={toaster}>
{(toast) => (
<Toast.Root>
<Toast.Title>{toast().title}</Toast.Title>
<Toast.Description>{toast().description}</Toast.Description>
{toast().action && <Toast.ActionTrigger>{toast().action?.label}</Toast.ActionTrigger>}
</Toast.Root>
)}
</Toaster>
</div>
)
}
<script setup lang="ts">
import { Toast, Toaster, createToaster } from '@ark-ui/vue/toast'
const toaster = createToaster({
placement: 'bottom-end',
gap: 24,
})
const addToast = () => {
toaster.create({
title: 'Toast Title',
description: 'Toast Description',
type: 'info',
action: {
label: 'Subscribe',
onClick: () => {
console.log('Subscribe')
},
},
})
}
</script>
<template>
<div>
<button type="button" @click="addToast">Add Toast</button>
<Toaster :toaster="toaster" v-slot="toast">
<ToastRoot :key="toast.id">
<Toast.Title>{{ toast.title }}</Toast.Title>
<Toast.Description>{{ toast.description }}</Toast.Description>
<Toast.ActionTrigger v-if="toast.action">{{ toast.action?.label }}</Toast.ActionTrigger>
</ToastRoot>
</Toaster>
</div>
</template>
API Reference
Root
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Data Attribute | Value |
---|---|
[data-scope] | toast |
[data-part] | root |
[data-state] | "open" | "closed" |
[data-type] | The type of the item |
[data-placement] | The placement of the toast |
[data-align] | |
[data-side] | |
[data-mounted] | Present when mounted |
[data-paused] | Present when paused |
[data-first] | |
[data-sibling] | |
[data-stack] | |
[data-overlap] | Present when overlapping |
ActionTrigger
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'button'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
CloseTrigger
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'button'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Description
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Title
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Toaster
Prop | Default | Type |
---|---|---|
toaster | CreateToasterReturn | |
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |