이 사이트는 shadcn-svelte 공식 문서의 한국어 번역입니다.
6.9k

Sonner

Previous Next

Svelte를 위한 토스트 컴포넌트입니다.

Docs
<script lang="ts">
  import { toast } from "svelte-sonner";
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<Button
  variant="outline"
  onclick={() =>
    toast("이벤트가 생성되었습니다", {
      description: "2023년 12월 3일 일요일 오전 9:00",
      action: {
        label: "취소",
        onClick: () => console.info("Undo")
      }
    })}
>
  토스트 표시
</Button>

소개

Sonner 컴포넌트는 svelte-sonner에서 제공하며, Emil Kowalski가 React용으로 만든 Sonner를 Svelte로 포팅한 것입니다.

설치

테마 지원 설정

기본적으로 Sonner는 사용자의 시스템 환경설정을 사용하여 라이트 또는 다크 테마를 표시합니다. 이를 우회하려면 컴포넌트에 커스텀 theme prop을 전달하거나, mode-watcher를 사용하면 원하는 경우 dark 또는 light 모드로 하드코딩할 수 있습니다.

다크 모드 지원 설정에 대한 자세한 내용은 여기를 참조하세요.

다크 모드 지원을 원하지 않는 경우 CLI로 설치한 후 mode-watcher를 제거하고 컴포넌트에서 theme prop을 제거하거나, 컴포넌트를 수동으로 설치하고 mode-watcher를 포함하지 않으면 됩니다.

다음 명령어를 실행하세요:
pnpm dlx shadcn-svelte@latest add sonner
Toaster 컴포넌트 추가
+layout.svelte
<script lang="ts">
  import { Toaster } from "$lib/components/ui/sonner/index.js";
  let { children } = $props();
</script>
 
<Toaster />
 
{@render children?.()}

사용법

<script lang="ts">
  import { toast } from "svelte-sonner";
  import { Button } from "$lib/components/ui/button/index.js";
</script>
<Button onclick={() => toast("안녕하세요")}>토스트 표시</Button>

예제

<script lang="ts">
  import { toast } from "svelte-sonner";
  import { Button } from "$lib/components/ui/button/index.js";
</script>
 
<div class="flex flex-wrap gap-2">
  <Button variant="outline" onclick={() => toast("이벤트가 생성되었습니다")}
    >기본</Button
  >
  <Button
    variant="outline"
    onclick={() => toast.success("이벤트가 생성되었습니다")}>성공</Button
  >
  <Button
    variant="outline"
    onclick={() => toast.info("이벤트 시간 10분 전에 도착해주세요")}
  >
    정보
  </Button>
  <Button
    variant="outline"
    onclick={() =>
      toast.warning("이벤트 시작 시간은 오전 8시보다 빠를 수 없습니다")}
  >
    경고
  </Button>
  <Button
    variant="outline"
    onclick={() => toast.error("이벤트가 생성되지 않았습니다")}
  >
    오류
  </Button>
  <Button
    variant="outline"
    onclick={() => {
      toast.promise<{ name: string }>(
        () =>
          new Promise((resolve) =>
            setTimeout(() => resolve({ name: "이벤트" }), 2000)
          ),
        {
          loading: "로딩 중...",
          success: (data) => `${data.name}가 생성되었습니다`,
          error: "오류"
        }
      );
    }}
  >
    Promise
  </Button>
</div>

변경 이력

2025-12 아이콘

Sonner 컴포넌트를 lucide의 아이콘을 사용하도록 업데이트했습니다. sonner.svelte 파일을 업데이트하여 새 아이콘을 사용하세요.

components/ui/sonner.svelte
<script lang="ts">
  import CircleCheckIcon from "@lucide/svelte/icons/circle-check";
  import InfoIcon from "@lucide/svelte/icons/info";
  import Loader2Icon from "@lucide/svelte/icons/loader-2";
  import OctagonXIcon from "@lucide/svelte/icons/octagon-x";
  import TriangleAlertIcon from "@lucide/svelte/icons/triangle-alert";
 
  import {
    Toaster as Sonner,
    type ToasterProps as SonnerProps,
  } from "svelte-sonner";
  import { mode } from "mode-watcher";
 
  let { ...restProps }: SonnerProps = $props();
</script>
 
<Sonner
  theme={mode.current}
  class="toaster group"
  style="--normal-bg: var(--color-popover); --normal-text: var(--color-popover-foreground); --normal-border: var(--color-border);"
  {...restProps}
  >{#snippet loadingIcon()}
    <Loader2Icon class="size-4 animate-spin" />
  {/snippet}
  {#snippet successIcon()}
    <CircleCheckIcon class="size-4" />
  {/snippet}
  {#snippet errorIcon()}
    <OctagonXIcon class="size-4" />
  {/snippet}
  {#snippet infoIcon()}
    <InfoIcon class="size-4" />
  {/snippet}
  {#snippet warningIcon()}
    <TriangleAlertIcon class="size-4" />
  {/snippet}
</Sonner>