Toast
현재 작업과 함께 짧은 피드백을 순서대로 알립니다.
용법
자동 닫힘
잠시 표시한 알림을 자동으로 닫되 사용자가 바로 닫을 수 있는 버튼도 함께 제공합니다.
잠시 표시한 알림을 자동으로 닫되 사용자가 바로 닫을 수 있는 버튼도 함께 제공합니다.
<!-- Toast / Automatic -->
<script setup lang="ts">
import { ToastClose, ToastProvider, ToastRoot, ToastTitle, ToastViewport } from '@sectile/vue/toast'
</script>
<template>
<ToastProvider :default-duration-ms="5000" :max-visible="3" v-slot="{ toasts, toast }">
<button @click="toast({ id: crypto.randomUUID(), title: 'Release saved', kind: 'success' })">Notify</button>
<ToastViewport>
<ToastRoot v-for="item in toasts" :key="item.id" :value="item.id">
<ToastTitle /><ToastClose>Dismiss</ToastClose>
</ToastRoot>
</ToastViewport>
</ToastProvider>
</template>계속 유지되는 알림
사용자가 직접 닫을 때까지 알림을 계속 표시합니다.
사용자가 직접 닫을 때까지 알림을 계속 표시합니다.
<!-- Toast / Persistent -->
<script setup lang="ts">
import { ToastClose, ToastProvider, ToastRoot, ToastTitle, ToastViewport } from '@sectile/vue/toast'
</script>
<template>
<ToastProvider :default-duration-ms="null" :max-visible="3" v-slot="{ toasts, toast }">
<button @click="toast({ id: crypto.randomUUID(), title: 'Release saved', kind: 'success' })">Notify</button>
<ToastViewport>
<ToastRoot v-for="item in toasts" :key="item.id" :value="item.id">
<ToastTitle /><ToastClose>Dismiss</ToastClose>
</ToastRoot>
</ToastViewport>
</ToastProvider>
</template>개수 제한
기존 값을 유지하면서 설정한 항목 수나 화면 표시 개수를 지킵니다.
기존 값을 유지하면서 설정한 항목 수나 화면 표시 개수를 지킵니다.
<!-- Toast / Limited -->
<script setup lang="ts">
import { ToastClose, ToastProvider, ToastRoot, ToastTitle, ToastViewport } from '@sectile/vue/toast'
</script>
<template>
<ToastProvider :default-duration-ms="5000" :max-visible="2" v-slot="{ toasts, toast }">
<button @click="toast({ id: crypto.randomUUID(), title: 'Release saved', kind: 'success' })">Notify</button>
<ToastViewport>
<ToastRoot v-for="item in toasts" :key="item.id" :value="item.id">
<ToastTitle /><ToastClose>Dismiss</ToastClose>
</ToastRoot>
</ToastViewport>
</ToastProvider>
</template>setup에서 호출
useToast()는 ToastProvider의 슬롯 하위 컴포넌트 setup에서 호출합니다. 반환된 state와 함수는 템플릿이나 이벤트·비동기 함수에서 사용할 수 있습니다. Context를 사용하는 컴포넌트를 Provider 슬롯 아래에 두면 같은 트리에서 toast 상태와 동작을 공유합니다.
<!-- AppShell.vue -->
<ToastProvider v-slot="{ toasts }">
<RequestButton />
<ToastViewport class="toast-viewport">
<ToastRoot v-for="item in toasts" :key="item.id" :value="item.id" class="toast-item">
<ToastTitle />
<ToastDescription />
<ToastClose>닫기</ToastClose>
</ToastRoot>
</ToastViewport>
</ToastProvider>// RequestButton.vue <script setup>
const { toast, update } = useToast()
async function save() {
const id = crypto.randomUUID()
toast({ id, title: '저장 중', kind: 'deployment-pending', durationMs: null })
try {
const result = await saveRelease()
update(id, { title: '저장 완료', kind: 'deployment-complete', durationMs: 3_000 })
return result
} catch (error) {
update(id, { title: '저장 실패', description: '다시 시도해 주세요.', kind: 'error', durationMs: 5_000 })
throw error
}
}애플리케이션이 요청을 실행하고 pending·성공·실패 문구, 시간, 오류 노출 정책을 결정합니다. markup, 아이콘, class, 위치, 모션도 Provider의 compound parts를 조립하는 애플리케이션이 소유합니다.
kind는 사용자 정의 문자열입니다. 생략하거나 빈 문자열이면 info가 되고, 그 외 값은 data-kind까지 그대로 전달됩니다. 기존 접근성 호환성을 위해 정확히 error인 항목만 role="alert", 나머지는 role="status"를 사용합니다.
CSS로 직접 스타일링
아이콘과 별도 설정을 생략하는 구성에서는 data-kind 선택자만 사용합니다.
.toast-item[data-kind='deployment-pending'] {
background: var(--toast-pending-background);
}
.toast-item[data-kind='deployment-complete'] {
background: var(--toast-complete-background);
}class와 아이콘 등록
애플리케이션의 일반 객체에 kind 표시 정보를 등록합니다. 미등록 값은 명시적인 fallback으로 처리합니다.
// toast-kinds.ts
import type { Component } from 'vue'
import InfoIcon from './InfoIcon.vue'
import SpinnerIcon from './SpinnerIcon.vue'
import SuccessIcon from './SuccessIcon.vue'
import ErrorIcon from './ErrorIcon.vue'
interface ToastKindPresentation {
readonly class: string
readonly icon: Component
}
export const toastKinds = {
info: { class: 'toast--info', icon: InfoIcon },
'deployment-pending': { class: 'toast--pending', icon: SpinnerIcon },
'deployment-complete': { class: 'toast--complete', icon: SuccessIcon },
error: { class: 'toast--error', icon: ErrorIcon },
} as const satisfies Record<string, ToastKindPresentation>
export type AppToastKind = keyof typeof toastKinds
const fallbackKind: ToastKindPresentation = {
class: 'toast--unknown',
icon: InfoIcon,
}
export function resolveToastKind(kind: string): ToastKindPresentation {
return kind in toastKinds
? toastKinds[kind as AppToastKind]
: fallbackKind
}<ToastRoot
v-for="item in toasts"
:key="item.id"
:value="item.id"
:class="resolveToastKind(item.kind).class"
>
<component :is="resolveToastKind(item.kind).icon" />
<ToastTitle />
<ToastDescription />
</ToastRoot>애플리케이션 내부에서 kind 제한
Sectile은 모든 문자열을 허용하지만 애플리케이션 wrapper에서는 등록된 kind만 받도록 좁힐 수 있습니다.
// use-app-toast.ts
import type { ToastInput } from '@sectile/vue/toast'
import { useToast } from '@sectile/vue/toast'
import type { AppToastKind } from './toast-kinds'
type AppToastInput = Omit<ToastInput<string>, 'kind'> & {
readonly kind?: AppToastKind
}
export function useAppToast() {
const api = useToast()
return {
...api,
toast(input: AppToastInput) {
api.toast(input)
},
}
}API
Vue 패키지: @sectile/vue/toast
ToastProviderToastPortalToastViewportToastRootToastTitleToastDescriptionToastClose
함수
useToast
function useToast(): UseToastReturnProps
ToastProviderProps
closeLabel각 알림 닫기 작업에 제공할 접근 가능한 이름입니다.
defaultDurationMs밀리초 단위의 초기 타이머 길이입니다.
dismissOnEscapeEscape 키로 포커스된 알림을 닫을지 여부입니다.
hotkey알림 표시 영역으로 포커스를 옮길 문서 단축키입니다. false는 단축키를 해제합니다.
initialToastsProvider가 처음 마운트될 때 존재할 알림입니다.
maxVisible한 번에 표시할 수 있는 최대 알림 수입니다.
pauseOnWindowBlur브라우저 창이 비활성 상태일 때 자동 닫기 시간을 멈출지 여부입니다.
swipeDirection포인터로 알림을 밀어 닫을 방향입니다.
swipeThreshold밀어서 닫을 때 필요한 포인터 이동 거리(픽셀)입니다.
toasts부모가 Provider를 제어할 때 사용할 현재 알림 목록입니다.
ToastPartProps
as이 파트가 렌더링할 요소 또는 컴포넌트입니다.
asChild하나뿐인 자식 요소에 파트 속성을 직접 합칠지 여부입니다.
ToastPortalProps
deferTeleport 대상을 현재 mount 또는 update tick이 끝날 때 찾을지 여부입니다.
disabled사용자 조작을 막을지 여부입니다.
to포털 콘텐츠를 옮길 대상입니다.
ToastRootProps
as이 파트가 렌더링할 요소 또는 컴포넌트입니다.
asChild하나뿐인 자식 요소에 파트 속성을 직접 합칠지 여부입니다.
value이 계약이 노출하는 현재 값입니다.
슬롯
ToastProviderSlotProps
dismiss알림 하나를 닫는 함수입니다.
dismissAll모든 알림을 닫는 함수입니다.
paused자동 갱신이 멈춘 상태인지 여부입니다.
toast이 항목이 나타내는 알림입니다.
toasts현재 알림 컬렉션입니다.
update식별자를 유지하면서 알림 하나를 갱신하는 함수입니다.
ToastRootSlotProps
open연결된 팝업이나 펼침 영역이 열려 있는지 여부입니다.
toast이 항목이 나타내는 알림입니다.
이벤트
ToastProvider
update:toastsProvider가 새 외부 제어 알림 목록을 요청할 때 발생합니다.
기타 타입
UseToastReturn
| 이름 | 타입 | 필수 |
|---|---|---|
toasts | ComputedRef<readonly ToastItem<string>[]> | 필수 |
paused | ComputedRef<boolean> | 필수 |
toast | void | 필수 |
update | void | 필수 |
dismiss | void | 필수 |
dismissAll | void | 필수 |
파트
공통 범위: [data-scope="toast"]. 컴포넌트 내부로 스타일을 제한할 때 파트 선택자와 함께 사용합니다.
| 파트 | 선택자 | 역할 | 추가 속성 |
|---|---|---|---|
viewport | [data-part="viewport"] | 현재 보이는 콘텐츠를 배치하고 경계를 정합니다. | — |
root | [data-part="root"] | 컴포넌트 경계와 내부 파트를 묶습니다. | — |
title | [data-part="title"] | 연결된 콘텐츠의 제목을 표시합니다. | — |
description | [data-part="description"] | 연결된 콘텐츠나 결정 내용을 설명합니다. | — |
close | [data-part="close"] | 현재 화면을 닫거나 해제합니다. | — |
키보드 동작
| 키 | 동작 |
|---|---|
| F8 | 알림 표시 영역으로 포커스를 옮깁니다. |
| Tab / Shift+Tab | 알림 작업 컨트롤 사이에서 포커스를 이동합니다. |
| Escape | 포커스된 알림을 닫습니다. |
| Pointer swipe | 설정한 거리보다 멀리 알림을 밀면 닫습니다. |
접근성
표시 영역이 알림 순서와 키보드 접근을 유지하며 각 알림에 지역화된 닫기 작업을 제공하고 사용자 조작이나 창 상태에 따라 자동 닫기를 멈춥니다.
