ユーザーに情報やフィードバックを提供するための簡潔なメッセージ。

使用法

useToastを構成して、アプリケーションにトーストを表示します。

<script setup lang="ts">
const toast = useToast()

function addToCalendar() {
  const eventDate = new Date(Date.now() + Math.random() * 31536000000)
  const formattedDate = eventDate.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric'
  })

  toast.add({
    title: 'Event added to calendar',
    description: `This event is scheduled for ${formattedDate}.`,
    icon: 'i-lucide-calendar-days'
  })
}
</script>

<template>
  <UButton
    label="Add to calendar"
    color="neutral"
    variant="outline"
    icon="i-lucide-plus"
    @click="addToCalendar"
  />
</template>
Appコンポーネントは、Reka UIのToastProviderコンポーネントを使用するToasterコンポーネントを使用しています。
Toasterをグローバルに設定する方法は、Appコンポーネントtoasterプロパティを確認できます。

Title

タイトルを表示するには、titleフィールドをtoast.addメソッドに渡します。

<script setup lang="ts">
const props = defineProps<{
  title: string
}>()

const toast = useToast()

function showToast() {
  toast.add(props)
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

Description

toast.addメソッドにdescriptionフィールドを渡して説明を表示します。

<script setup lang="ts">
const props = defineProps<{
  title: string
  description: string
}>()

const toast = useToast()

function showToast() {
  toast.add(props)
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

Icon

iconフィールドをtoast.addメソッドに渡し、Iconを表示します。

<script setup lang="ts">
const props = defineProps<{
  icon: string
}>()

const toast = useToast()

function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    icon: props.icon
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

アバター

Avatarを表示するには、avatarフィールドをtoast.addメソッドに渡します。

<script setup lang="ts">
import type { AvatarProps } from '@nuxt/ui'

const props = defineProps<{
  avatar: AvatarProps
}>()

const toast = useToast()

function showToast() {
  toast.add({
    title: 'User invited',
    description: 'benjamincanac was invited to the team.',
    avatar: props.avatar
  })
}
</script>

<template>
  <UButton label="Invite user" color="neutral" variant="outline" @click="showToast" />
</template>

Color

colorフィールドをtoast.addメソッドに渡して、Toastの色を変更します。

<script setup lang="ts">
import type { ToastProps } from '@nuxt/ui'

const props = defineProps<{
  color: ToastProps['color']
}>()

const toast = useToast()

function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    icon: 'i-lucide-wifi',
    color: props.color
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

閉じる

closeフィールドを渡して、close Button false値をカスタマイズまたは非表示にします。

<script setup lang="ts">
const toast = useToast()

function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    icon: 'i-lucide-wifi',
    close: {
      color: 'primary',
      variant: 'outline',
      class: 'rounded-full'
    }
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

アイコンを閉じる

closeIconフィールドを渡して閉じるボタンIconをカスタマイズします。デフォルトはi-lucide-xです。

<script setup lang="ts">
const props = defineProps<{
  closeIcon: string
}>()

const toast = useToast()

function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    closeIcon: props.closeIcon
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
このアイコンは、app.config.tsのui.icons.closeキーでグローバルにカスタマイズできます。
このアイコンはvite.config.tsのui.icons.closeキーでグローバルにカスタマイズできます。

Actions

actionsフィールドを渡して、Buttonアクションをトーストに追加します。

<script setup lang="ts">
const toast = useToast()

const props = defineProps<{
  description: string
}>()

function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: props.description,
    actions: [{
      icon: 'i-lucide-refresh-cw',
      label: 'Retry',
      color: 'neutral',
      variant: 'outline',
      onClick: (e) => {
        e?.stopPropagation()
      }
    }]
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

Duration

durationフィールドをtoast.addメソッドに渡して、Toastが表示される時間(ミリ秒単位)を変更します。デフォルトは5000です。

durationフィールドを0に設定し、手動で閉じるまでトーストを開いたままにします。
<script setup lang="ts">
const toast = useToast()

const props = defineProps<{
  duration: number
}>()

function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    duration: props.duration
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

Progress

progressフィールドを渡して、Progressバー false値をカスタマイズまたは非表示にします。

プログレスバーはデフォルトでToastカラーを継承しますが、progress.colorフィールドを使用してオーバーライドできます。
<script setup lang="ts">
const toast = useToast()

function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    description: 'There was a problem with your request.',
    icon: 'i-lucide-wifi',
    progress: false
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

Orientation

orientationフィールドをtoast.addメソッドに渡して、Toastの向きを変更します。

<script setup lang="ts">
const toast = useToast()

const props = defineProps<{
  orientation: 'horizontal' | 'vertical'
}>()

function showToast() {
  toast.add({
    title: 'Uh oh! Something went wrong.',
    orientation: props.orientation,
    actions: [{
      icon: 'i-lucide-refresh-cw',
      label: 'Retry',
      color: 'neutral',
      variant: 'outline',
      onClick: (e) => {
        e?.stopPropagation()
      }
    }]
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

例

Nuxt UIは、アプリケーションをラップしてグローバル設定を提供するAppコンポーネントを提供します。

グローバルポジションを変更

トーストの位置を変更するには、Appコンポーネントのtoaster.positionプロパティを変更します。

app.vue
<script setup lang="ts">
const toaster = { position: 'bottom-right' }
</script>

<template>
  <UApp :toaster="toaster">
    <NuxtPage />
  </UApp>
</template>
<script setup lang="ts">
const toast = useToast()

function addToCalendar() {
  const eventDate = new Date(Date.now() + Math.random() * 31536000000)
  const formattedDate = eventDate.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric'
  })

  toast.add({
    title: 'Event added to calendar',
    description: `This event is scheduled for ${formattedDate}.`,
    icon: 'i-lucide-calendar-days'
  })
}
</script>

<template>
  <UButton
    label="Add to calendar"
    color="neutral"
    variant="outline"
    icon="i-lucide-plus"
    @click="addToCalendar"
  />
</template>

グローバル期間の変更

トーストの長さを変更するには、Appコンポーネントのtoaster.durationプロパティを変更します。

app.vue
<script setup lang="ts">
const toaster = { duration: 5000 }
</script>

<template>
  <UApp :toaster="toaster">
    <NuxtPage />
  </UApp>
</template>
<script setup lang="ts">
const toast = useToast()

function addToCalendar() {
  const eventDate = new Date(Date.now() + Math.random() * 31536000000)
  const formattedDate = eventDate.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric'
  })

  toast.add({
    title: 'Event added to calendar',
    description: `This event is scheduled for ${formattedDate}.`,
    icon: 'i-lucide-calendar-days'
  })
}
</script>

<template>
  <UButton
    label="Add to calendar"
    color="neutral"
    variant="outline"
    icon="i-lucide-plus"
    @click="addToCalendar"
  />
</template>

Change global max badge{label="4.1+" class="align-text-top"}

一度に表示されるトーストの最大数を変更するには、Appコンポーネントのtoaster.maxプロパティを変更します。

app.vue
<script setup lang="ts">
const toaster = { max: 3 }
</script>

<template>
  <UApp :toaster="toaster">
    <NuxtPage />
  </UApp>
</template>
<script setup lang="ts">
const toast = useToast()

function addToCalendar() {
  const eventDate = new Date(Date.now() + Math.random() * 31536000000)
  const formattedDate = eventDate.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric'
  })

  toast.add({
    title: 'Event added to calendar',
    description: `This event is scheduled for ${formattedDate}.`,
    icon: 'i-lucide-calendar-days'
  })
}
</script>

<template>
  <UButton
    label="Add to calendar"
    color="neutral"
    variant="outline"
    icon="i-lucide-plus"
    @click="addToCalendar"
  />
</template>

積み重ねたトースト

Appコンポーネントのtoaster.expandプロパティをfalseに設定して、スタックトーストを表示します(Sonnerに触発されて)。

app.vue
<script setup lang="ts">
const toaster = { expand: true }
</script>

<template>
  <UApp :toaster="toaster">
    <NuxtPage />
  </UApp>
</template>
トーストの上にカーソルを合わせると展開できます。これによりトーストのタイマーが一時停止します。
<script setup lang="ts">
const toast = useToast()

function addToCalendar() {
  const eventDate = new Date(Date.now() + Math.random() * 31536000000)
  const formattedDate = eventDate.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric'
  })

  toast.add({
    title: 'Event added to calendar',
    description: `This event is scheduled for ${formattedDate}.`,
    icon: 'i-lucide-calendar-days'
  })
}
</script>

<template>
  <UButton
    label="Add to calendar"
    color="neutral"
    variant="outline"
    icon="i-lucide-plus"
    @click="addToCalendar"
  />
</template>

重複しないトーストbadge{label="4.5+" class="align-text-top"}

すでに存在するidでtoast.addを呼び出すと、既存のトーストは重複を作成する代わりにパルス化されます。

<script setup lang="ts">
const toast = useToast()

function showToast() {
  toast.add({
    id: 'copy',
    title: 'Copied to clipboard',
    icon: 'i-lucide-circle-check',
    duration: 0
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

Withコールバック

onUpdateOpenフィールドを渡して、トーストが閉じられたときにコールバックを実行します。

<script setup lang="ts">
const toast = useToast()

function showToast() {
  const t = toast.add({
    'title': 'Uploading file...',
    'description': 'Your file is being uploaded.',
    'icon': 'i-lucide-cloud-upload',
    'duration': 3000,
    'onUpdate:open': (open: boolean) => {
      if (open) {
        return
      }

      toast.update(t.id, {
        'title': 'File uploaded!',
        'description': 'Your file has been successfully uploaded.',
        'icon': 'i-lucide-check',
        'color': 'success',
        'onUpdate:open': undefined
      })
    }
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

HTMLコンテンツ付き

カスタムスタイルでHTML要素またはVueコンポーネントをレンダリングするには、titleまたはdescriptionフィールドのh()レンダリング関数を使用します。

<script setup lang="ts">
const toast = useToast()

function showToast() {
  toast.add({
    title: h('span', {}, [
      'Item ',
      h('span', { class: 'text-primary font-bold' }, '#15'),
      ' deleted'
    ]),
    description: h('span', {}, [
      'You have successfully deleted the item from your ',
      h('span', { class: 'font-bold' }, 'account'),
      '.'
    ]),
    icon: 'i-lucide-trash-2'
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>
<script setup lang="ts">
import { h } from 'vue'

const toast = useToast()

function showToast() {
  toast.add({
    title: h('span', {}, [
      'Item ',
      h('span', { class: 'text-primary font-bold' }, '#15'),
      ' deleted'
    ]),
    description: h('span', {}, [
      'You have successfully deleted the item from your ',
      h('span', { class: 'font-bold' }, 'account'),
      '.'
    ]),
    icon: 'i-lucide-trash-2'
  })
}
</script>

<template>
  <UButton label="Show toast" color="neutral" variant="outline" @click="showToast" />
</template>

API

Props

Prop Default Type
as
'li'
any

The element or component this component should render as.

title
string | VNode<RendererNode, RendererElement, { [key: string]: any; }> | (): VNode<RendererNode, RendererElement, { [key: string]: any; }>
description
string | VNode<RendererNode, RendererElement, { [key: string]: any; }> | (): VNode<RendererNode, RendererElement, { [key: string]: any; }>
icon
any
avatar
AvatarProps
color
'primary'
"error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"
orientation
'vertical'
"vertical" | "horizontal"

The orientation between the content and the actions.

close
true
boolean | Omit<ButtonProps, LinkPropsKeys>

Display a close button to dismiss the toast. { size: 'md', color: 'neutral', variant: 'link' }

closeIcon
appConfig.ui.icons.close
any

The icon displayed in the close button.

actions
ButtonProps[]

Display a list of actions:

  • under the title and description when orientation is vertical
  • next to the close button when orientation is horizontal { size: 'xs' }
duration
5000
number

The time in milliseconds before the toast automatically closes. Overrides the global toaster.duration.

Set to 0 to keep the toast open until it's manually closed.

progress
true
boolean | Pick<ProgressProps, "color" | "ui">

Display a progress bar showing the toast's remaining duration. { size: 'sm' }

defaultOpen
boolean

The open state of the dialog when it is initially rendered. Use when you do not need to control its open state.

open
boolean

The controlled open state of the dialog. Can be bind as v-model:open.

type
"foreground" | "background"

Control the sensitivity of the toast for accessibility purposes.

For toasts that are the result of a user action, choose foreground. Toasts generated from background tasks should use background.

ui
{ root?: SlotClass; wrapper?: SlotClass; title?: SlotClass; description?: SlotClass; icon?: SlotClass; avatar?: SlotClass; avatarSize?: SlotClass; actions?: SlotClass; progress?: SlotClass; close?: SlotClass; }

スロット

Slot Type
leading
{ ui: object; }
title
{}
description
{}
actions
{}
close
{ ui: object; }

Emits

Event Type
pause
[]
escapeKeyDown
[event: KeyboardEvent]
resume
[]
swipeStart
[event: SwipeEvent]
swipeMove
[event: SwipeEvent]
swipeCancel
[event: SwipeEvent]
swipeEnd
[event: SwipeEvent]
update:open
[value: boolean]

Expose

テンプレート参照を介してコンポーネントにアクセスする場合、以下を使用できます:

名前タイプ
heightRef<number>

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    toast: {
      slots: {
        root: 'relative group overflow-hidden bg-default shadow-lg rounded-lg ring ring-default p-4 flex gap-2.5',
        wrapper: 'w-0 flex-1 flex flex-col',
        title: 'text-sm font-medium text-highlighted',
        description: 'text-sm text-muted',
        icon: 'shrink-0 size-5',
        avatar: 'shrink-0',
        avatarSize: '2xl',
        actions: 'flex gap-1.5 shrink-0',
        progress: 'absolute inset-x-0 bottom-0',
        close: 'p-0'
      },
      variants: {
        color: {
          primary: {
            root: 'outline-primary/25 focus-visible:outline-3 focus-visible:ring-primary',
            icon: 'text-primary'
          },
          secondary: {
            root: 'outline-secondary/25 focus-visible:outline-3 focus-visible:ring-secondary',
            icon: 'text-secondary'
          },
          success: {
            root: 'outline-success/25 focus-visible:outline-3 focus-visible:ring-success',
            icon: 'text-success'
          },
          info: {
            root: 'outline-info/25 focus-visible:outline-3 focus-visible:ring-info',
            icon: 'text-info'
          },
          warning: {
            root: 'outline-warning/25 focus-visible:outline-3 focus-visible:ring-warning',
            icon: 'text-warning'
          },
          error: {
            root: 'outline-error/25 focus-visible:outline-3 focus-visible:ring-error',
            icon: 'text-error'
          },
          neutral: {
            root: 'outline-inverted/25 focus-visible:outline-3 focus-visible:ring-inverted',
            icon: 'text-highlighted'
          }
        },
        orientation: {
          horizontal: {
            root: 'items-center',
            actions: 'items-center'
          },
          vertical: {
            root: 'items-start',
            actions: 'items-start mt-2.5'
          }
        },
        title: {
          true: {
            description: 'mt-1'
          }
        }
      },
      defaultVariants: {
        color: 'primary'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        toast: {
          slots: {
            root: 'relative group overflow-hidden bg-default shadow-lg rounded-lg ring ring-default p-4 flex gap-2.5',
            wrapper: 'w-0 flex-1 flex flex-col',
            title: 'text-sm font-medium text-highlighted',
            description: 'text-sm text-muted',
            icon: 'shrink-0 size-5',
            avatar: 'shrink-0',
            avatarSize: '2xl',
            actions: 'flex gap-1.5 shrink-0',
            progress: 'absolute inset-x-0 bottom-0',
            close: 'p-0'
          },
          variants: {
            color: {
              primary: {
                root: 'outline-primary/25 focus-visible:outline-3 focus-visible:ring-primary',
                icon: 'text-primary'
              },
              secondary: {
                root: 'outline-secondary/25 focus-visible:outline-3 focus-visible:ring-secondary',
                icon: 'text-secondary'
              },
              success: {
                root: 'outline-success/25 focus-visible:outline-3 focus-visible:ring-success',
                icon: 'text-success'
              },
              info: {
                root: 'outline-info/25 focus-visible:outline-3 focus-visible:ring-info',
                icon: 'text-info'
              },
              warning: {
                root: 'outline-warning/25 focus-visible:outline-3 focus-visible:ring-warning',
                icon: 'text-warning'
              },
              error: {
                root: 'outline-error/25 focus-visible:outline-3 focus-visible:ring-error',
                icon: 'text-error'
              },
              neutral: {
                root: 'outline-inverted/25 focus-visible:outline-3 focus-visible:ring-inverted',
                icon: 'text-highlighted'
              }
            },
            orientation: {
              horizontal: {
                root: 'items-center',
                actions: 'items-center'
              },
              vertical: {
                root: 'items-start',
                actions: 'items-start mt-2.5'
              }
            },
            title: {
              true: {
                description: 'mt-1'
              }
            }
          },
          defaultVariants: {
            color: 'primary'
          }
        }
      }
    })
  ]
})

Changelog

No recent changes