Skip to content

Toast ​

A neo-brutalist notification toast system providing the useToast composable, 5 variants, and ToastContainer for rendering.

Demo ​

Preview

变体

尺寸

悬停暂停(pauseOnHover)

将鼠标悬停在提示上可暂停倒计时与进度条,移出后从剩余时间继续。点击下方按钮显示一条 10 秒提示进行体验,可切换开关对比行为。

Installation ​

pnpm dlx brutx-vue@latest add toast

Usage ​

vue
<script setup>
import { ToastContainer } from 'brutx-ui-vue'
</script>

<template>
    <router-view />
    <ToastContainer />
</template>

Using useToast ​

vue
<script setup>
import { useToast } from 'brutx-ui-vue'

const { success, error, warning, info, addToast } = useToast()

function handleSave() {
    success('Saved!', 'Your changes have been saved.')
}

function handleError() {
    error('Error', 'Something went wrong. Please try again.')
}
</script>

<template>
    <button @click="handleSave">Save</button>
    <button @click="handleError">Trigger Error</button>
</template>

Custom Toast ​

vue
<script setup>
import { useToast } from 'brutx-ui-vue'

const { addToast } = useToast()

function showCustomToast() {
    addToast({
        variant: 'warning',
        title: 'Warning',
        description: 'Your session will expire in 5 minutes.',
        duration: 10000,
    })
}
</script>

Hover Pause ​

Toast has pauseOnHover enabled by default (true): when the mouse enters the toast, the countdown timer and top progress bar animation are paused; when the mouse leaves, the timer resumes from the remaining time. This helps users read longer content. Set :pause-on-hover="false" to disable this behavior.

Note: pauseOnHover is a prop on the <Toast> component itself, not passed through useToast's addToast / ToastItem. When rendering <Toast> inside a custom ToastContainer, bind it directly.

vue
<script setup>
import { useToast, ToastContainer, Toast } from 'brutx-ui-vue'

const { toasts, addToast, removeToast } = useToast()
</script>

<template>
    <ToastContainer position="bottom-right">
        <Toast
            v-for="toast in toasts"
            :key="toast.id"
            :duration="toast.duration"
            :pause-on-hover="true"
            @close="removeToast(toast.id)"
        />
    </ToastContainer>

    <button @click="addToast({ title: 'Hover Me', description: 'Hover over the toast to pause the countdown.', duration: 10000 })">
        Show Pausable Toast
    </button>
</template>

Variants ​

VariantBackgroundIcon
defaultbg-brutal-bgZap
successbg-brutal-successCheckCircle
errorbg-brutal-destructiveAlertCircle
warningbg-brutal-accentAlertTriangle
infobg-brutal-secondaryInfo

All variants use text-brutal-fg text color and shadow-brutal-lg shadow.

Sizes ​

SizeWidth
smw-72 (288px)
defaultw-80 (320px)
lgw-96 (384px)

Data Types ​

ToastItem ​

ts
interface ToastItem {
    id: string
    variant?: 'default' | 'success' | 'error' | 'warning' | 'info'
    size?: 'sm' | 'default' | 'lg'
    title?: string
    description?: string
    duration?: number
}

PromiseToastOptions ​

ts
interface PromiseToastOptions<T> {
    loading: string                                        // loading state text
    success: string | ((data: T) => string)                // success text or formatter function
    error: string | ((error: Error) => string)             // error text or formatter function
    duration?: number                                      // display duration after success/error
    loadingVariant?: 'default' | 'success' | 'error' | 'warning' | 'info'  // loading state variant
    successVariant?: 'default' | 'success' | 'error' | 'warning' | 'info'  // success state variant
    errorVariant?: 'default' | 'success' | 'error' | 'warning' | 'info'    // error state variant
}

Composables ​

useToast ​

ts
import { useToast } from 'brutx-ui-vue'

const {
    toasts,          // Ref<ToastItem[]> - reactive toast list
    addToast,        // (toast: Omit<ToastItem, 'id'>) => string
    removeToast,     // (id: string) => void
    clearToasts,     // () => void
    clearAllTimers,  // () => void
    success,         // (title: string, description?: string) => string
    error,           // (title: string, description?: string) => string
    warning,         // (title: string, description?: string) => string
    info,            // (title: string, description?: string) => string
    promise,         // <T>(promise: Promise<T> | (() => Promise<T>), options: PromiseToastOptions<T>) => Promise<T>
} = useToast()

Return Values ​

PropTypeDescription
toastsRef<ToastItem[]>Reactive toast list
addToast(toast: Omit<ToastItem, 'id'>) => stringAdd a custom toast, returns the toast ID
removeToast(id: string) => voidRemove a specific toast
clearToasts() => voidClear all toasts
clearAllTimers() => voidClear all timers
success(title: string, description?: string) => stringShow a success toast
error(title: string, description?: string) => stringShow an error toast
warning(title: string, description?: string) => stringShow a warning toast
info(title: string, description?: string) => stringShow an info toast
promise<T>(promise: Promise<T> | (() => Promise<T>), options: PromiseToastOptions<T>) => Promise<T>Automatically track Promise state

provideToast ​

Call provideToast() in the app root component to provide the toast instance. Child components will automatically inject the instance via useToast().

vue
<!-- App.vue -->
<script setup>
import { provideToast } from 'brutx-ui-vue'

provideToast()
</script>

Note: If provideToast() is not called, useToast() will fall back to a shared singleton and output a warning. Production apps should call provideToast() explicitly in the root component; the shared singleton is a compatibility fallback. Tests, multi-app pages, and hot-reload boundaries can call destroyBrutxFallbacks() to clear toast/theme/message fallback state together.

Promise Toast ​

Automatically tracks Promise state, showing a loading -> success/error flow:

vue
<script setup>
import { useToast } from 'brutx-ui-vue'

const { promise } = useToast()

async function handleSave() {
    await promise(saveData(), {
        loading: 'Saving...',
        success: 'Saved successfully!',
        error: 'Save failed, please try again',
    })
}
</script>

API Reference ​

Toast

Toast — Props
NameTypeDefaultDescription
variant
"default" | "error" | "info" | "success" | "warning" | undefined
"default"
Sets the semantic and visual toast type, such as success, warning, info, or error.
Details

Declared type

NonNullable<"default" | "success" | "warning" | "info" | "error" | null | undefined> | undefined

Literal values

  • "default"
  • "error"
  • "info"
  • "success"
  • "warning"

Default value details

Declaration
'default'

Source: packages/ui/src/components/toast/Toast.vue

Resolved value
"default"

Source

Toast.vue:17

packages/ui/src/components/toast/Toast.vue

size
"default" | "lg" | "sm" | undefined
"default"
Sets the size variant of the toast container.
Details

Declared type

NonNullable<"default" | "lg" | "sm" | null | undefined> | undefined

Literal values

  • "default"
  • "lg"
  • "sm"

Default value details

Declaration
'default'

Source: packages/ui/src/components/toast/Toast.vue

Resolved value
"default"

Source

Toast.vue:18

packages/ui/src/components/toast/Toast.vue

title
string | undefined
undefined
The toast title text; the title area is omitted when not provided.
Details

Declared type

string | undefined

Default value details

Declaration
undefined

Source: packages/ui/src/components/toast/Toast.vue

Resolved value
undefined

Source

Toast.vue:19

packages/ui/src/components/toast/Toast.vue

description
string | undefined
undefined
The toast description text; the description area is omitted when not provided.
Details

Declared type

string | undefined

Default value details

Declaration
undefined

Source: packages/ui/src/components/toast/Toast.vue

Resolved value
undefined

Source

Toast.vue:20

packages/ui/src/components/toast/Toast.vue

duration
number | undefined
5000
The display duration before the toast closes automatically, in milliseconds; 0 disables automatic closing.
Details

Declared type

number | undefined

Default value details

Declaration
DEFAULT_TOAST_DURATION

Source: packages/ui/src/components/toast/Toast.vue

Resolved value
5000

Source

Toast.vue:21

packages/ui/src/components/toast/Toast.vue

pauseOnHover
boolean | undefined
true
Pauses the close timer and progress animation on hover, then resumes with the remaining time when the pointer leaves.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
true

Source

Toast.vue:22

packages/ui/src/components/toast/Toast.vue

class
string | undefined
undefined
CSS classes added to the toast root container.
Details

Declared type

string | undefined

Default value details

Declaration
undefined

Source: packages/ui/src/components/toast/Toast.vue

Resolved value
undefined

Source

Toast.vue:23

packages/ui/src/components/toast/Toast.vue

iconSize
IconSize | undefined
"xl"
Sets the size of the type icon.
Details

Declared type

IconSize | undefined

Literal values

  • "2xl"
  • "lg"
  • "md"
  • "sm"
  • "xl"
  • "xs"

Referenced types

IconSize
Type definition — IconSize
export type IconSize = NonNullable<VariantProps<typeof iconSizeVariants>['size']>

Default value details

Resolved value
"xl"

Source

Toast.vue:24

packages/ui/src/components/toast/Toast.vue

count
number | undefined
1
The aggregated count for similar toasts; values above 1 are shown in a count badge.
Details

Declared type

number | undefined

Default value details

Resolved value
1

Source

Toast.vue:25

packages/ui/src/components/toast/Toast.vue

Toast — Events
NameSignature or typeDescription
@close
[]
Emitted after the toast exit animation finishes so the caller can remove it.
Details

Declared type

[]

Source

Toast.vue

packages/ui/src/components/toast/Toast.vue

Toast — Slots
NameSignature or typeDescription
#default
{}
Custom supplemental content displayed after the title and description.
Details

Declared type

{}

Source

Toast.vue

packages/ui/src/components/toast/Toast.vue

ToastContainer

ToastContainer — Props
NameTypeDefaultDescription
position
ToastPosition | undefined
"bottom-right"
Sets a preset viewport position for the toast container or uses x, y, and anchor to specify an offset position.
Details

Declared type

ToastPosition | undefined

Literal values

  • "bottom-center"
  • "bottom-left"
  • "bottom-right"
  • "top-center"
  • "top-left"
  • "top-right"

Referenced types

ToastPosition
Type definition — ToastPosition
export type ToastPosition =
    | 'top-left'
    | 'top-center'
    | 'top-right'
    | 'bottom-left'
    | 'bottom-center'
    | 'bottom-right'
    | { x: number; y: number; anchor?: 'top-left' | 'bottom-left' | 'top-right' | 'bottom-right' }

Default value details

Resolved value
"bottom-right"

Source

ToastContainer.vue:22

packages/ui/src/components/toast/ToastContainer.vue

stack
ToastStackOptions | undefined
{ "expandDirection": "down", "gap": 12, "maxVisible": 5 }

Factory evaluated per instance

Configures the visible-toast limit, spacing between toasts, and the direction in which the stack expands.
Details

Declared type

ToastStackOptions | undefined

Referenced types

ToastStackOptions
Type definition — ToastStackOptions
export interface ToastStackOptions {
    maxVisible?: number
    gap?: number
    expandDirection?: 'down' | 'up'
}

Default value details

Declaration
() => ({ maxVisible: DEFAULT_TOAST_MAX_VISIBLE, gap: DEFAULT_TOAST_GAP_PX, expandDirection: DEFAULT_EXPAND_DIRECTION, })

Source: packages/ui/src/components/toast/ToastContainer.vue

Resolved value
{ "expandDirection": "down", "gap": 12, "maxVisible": 5 }

Source

ToastContainer.vue:23

packages/ui/src/components/toast/ToastContainer.vue

class
string | undefined
undefined
CSS classes added to the fixed-position toast container.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

ToastContainer.vue:24

packages/ui/src/components/toast/ToastContainer.vue

ToastContainer — Slots
NameSignature or typeDescription
#default
{}
Custom container content; when provided, the caller renders and manages the toast list. Otherwise, the container automatically renders toasts from useToast.
Details

Declared type

{}

Source

ToastContainer.vue

packages/ui/src/components/toast/ToastContainer.vue

Accessibility ​

  • Keyboard: Supports Escape to close the current toast
  • ARIA Attributes: The Toast container uses role="status" and aria-live="polite" to notify screen readers
  • Reduced Motion: Respects the prefers-reduced-motion system setting and automatically disables or simplifies animations

Brute force builds.