사용자에게 정보 또는 피드백을 제공하는 간결한 메시지입니다.

Usage

응용 프로그램에 토스트를 표시하려면 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>
앱을 Reka UI의 ToastProvider 구성 요소를 사용하는 Toaster 구성 요소를 사용하는 App 구성 요소로 래핑해야 합니다.
App 컴포넌트 toaster prop을 확인하여 Toaster를 전역적으로 구성하는 방법을 확인할 수 있습니다.

제목

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 메서드에 전달하여 설명을 표시합니다.

<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 메서드에 전달하여 Avatar를 표시합니다.

<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>

Close 아이콘

closeIcon 필드를 전달하여 종료 단추 [Iconxph12x/docs/components/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>
ui.icons.close 키 아래의 app.config.ts에서 이 아이콘을 전역적으로 사용자 정의할 수 있습니다.
ui.icons.close 키 아래의 vite.config.ts에서 이 아이콘을 전역적으로 사용자 정의할 수 있습니다.

Actions (### 액션)

actions 필드를 전달하여 일부 Button 액션을 Toast에 추가합니다.

<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로 설정하여 Toast가 수동으로 닫힐 때까지 열려 있도록 합니다.
<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 막대(false 값 포함)를 사용자 정의하거나 숨깁니다.

진행률 표시줄은 기본적으로 토스트 색상을 상속하지만 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 필드를 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 구성 요소를 제공합니다.Nuxt UI provides an App component that wraps your app to provide global configurations.

전역 위치 변경

App 구성 요소에서 toaster.position prop을 변경하여 토스트의 위치를 변경합니다.

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 prop을 변경하여 토스트의 지속 시간을 변경합니다.

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>

전역 변경 최대:badge{label="4.1+" class="align-text-top"}

App 구성 요소의 toaster.max prop을 변경하여 한 번에 표시되는 최대 토스트 수를 변경합니다.

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 Prop을 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 콘텐츠 포함

title 또는 description 필드에서 h() render function를 사용하여 사용자 정의 스타일을 사용하여 HTML 요소 또는 Vue 구성 요소를 렌더링합니다.

<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 (### 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; }

Slots

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]

exose 소개

템플릿 참조를 통해 컴포넌트에 액세스하는 경우 다음을 사용할 수 있습니다.

이름 (Name)유형 (Type)
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'
          }
        }
      }
    })
  ]
})

변경 로그

No recent changes