Toast

Een beknopt bericht om informatie of feedback te geven aan de gebruiker.

Gebruik

Gebruik de useToast composable om een toast in uw applicatie weer te geven.

<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>
Zorg ervoor dat u uw app omhult met de App -component die onze Toaster -component gebruikt die de ToastProvider -component van Reka UI gebruikt.
U kunt de App component toaster prop bekijken om te zien hoe u de broodrooster globaal configureert.

Titel

Geef een title veld door aan de toast.add methode om een titel weer te geven.

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

Beschrijving

Geef een description veld door aan de toast.add methode om een beschrijving weer te geven.

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

Icoon

Geef een icon-veld door aan de toast.add-methode om een Icon weer te geven.

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

Geef een avatar-veld door aan de toast.add-methode om een Avatar weer te geven.

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

Kleur

Geef een color veld door aan de toast.add methode om de kleur van de Toast te veranderen.

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

Sluiten

Geef een close-veld door om de Button (met false-waarde) aan te passen of te verbergen.

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

Sluit pictogram

Geef een closeIcon-veld door om de knop Sluiten Icon aan te passen. Standaard 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>
U kunt dit pictogram globaal aanpassen in uw app.config.ts onder ui.icons.close-sleutel.
U kunt dit pictogram globaal aanpassen in uw vite.config.ts onder ui.icons.close-sleutel.

Acties

Geef een actions-veld door om enkele Button acties aan de Toast toe te voegen.

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

Duur

Geef een duration-veld door aan de toast.add-methode om te wijzigen hoe lang de Toast zichtbaar blijft (in milliseconden). Standaard 5000.

Zet het duration veld op 0 om de Toast open te houden totdat deze handmatig wordt gesloten.
<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>

Voortgang

Geef een progress-veld door om de Progress (met false-waarde) aan te passen of te verbergen.

De voortgangsbalk neemt standaard de Toast-kleur over, maar u kunt deze overschrijven met het veld 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>

Oriëntatie

Geef een orientation veld door aan de toast.add methode om de oriëntatie van de Toast te veranderen.

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

Voorbeelden

Nuxt UI biedt een App-component die uw app omhult om wereldwijde configuraties te bieden.

Wereldwijde positie wijzigen

Verander de toaster.position prop op de App om de positie van de toasts te veranderen.

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>

Globale duur wijzigen

Verander de toaster.duration prop op de App om de duur van de toasts te wijzigen.

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>

Wijzig globaal max: badge{label="4.1+" class="align-text-top"}

Wijzig de toaster.max prop op de App component om het maximale aantal toasts dat tegelijk wordt weergegeven te wijzigen.

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>

Gestapelde toasts

Stel de toaster.expand prop in op false op het App om gestapelde toasts weer te geven (geïnspireerd door Sonner).

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

<template>
  <UApp :toaster="toaster">
    <NuxtPage />
  </UApp>
</template>
U kunt met de muis over de toasts bewegen om ze uit te breiden. Hierdoor wordt ook de timer van de toasts onderbroken.
<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>

Ontdubbelde toasts: badge{label="4.5+" class="align-text-top"}

Bij het aanroepen van toast.add met een id die al bestaat, zal de bestaande toast pulseren in plaats van een duplicaat te maken.

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

Met terugbellen

Geef een onUpdateOpen-veld door om een callback uit te voeren wanneer de toast is gesloten (door verlopen of door ontslag van de gebruiker).

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

Met HTML-inhoud

Gebruik de h()-weergave function in de title- of description-velden om HTML-elementen of Vue-componenten met aangepaste styling weer te geven.

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

Slots

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

Uitzendt

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

Expose

Wanneer u de component opent via een sjabloonref, kunt u het volgende gebruiken:

NaamType
heightRef<number>

Thema

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'
          }
        }
      }
    })
  ]
})

Wijzigingsgelog

No recent changes