Nextjsでshadcn/uiを使ってtoasterを表示

# 結論

すぐ使えるようなのを期待しているなら、[shadcn/ui](https://ui.shadcn.com/docs/components/sonner)のsonnarを使おう。

https://ui.shadcn.com/docs/components/sonner

## 1. はじめに

### shadcn/ui とは何か

shadcn/uiとは、[tailwindcss](https://tailwindcss.com/docs/installation)を使って、構成されたヘッドレスUIです。

https://ui.shadcn.com/

[components](https://ui.shadcn.com/docs/components/accordion)が用意されていますが、カスタムしたい場合は、[tailwindcss](https://tailwindcss.com/docs/installation)のclassを与えてカスタムします。


## 2. 前提条件

今回はNextjsで使うので、Nextjsのセットアップに沿っています。

https://ui.shadcn.com/docs/installation/next

## 3. toaster(sonner)のセットアップ

shadcn/uiのcomponentsにに[toaster](https://ui.shadcn.com/docs/components/toast)が用意されていますが、より使いやすく準備されている[sonner](https://ui.shadcn.com/docs/components/sonner)の方を使います。

https://ui.shadcn.com/docs/components/sonner

### 3.1 CLIでコンポーネント追加

```bash
npx shadcn-ui@latest add sonner
```

### 3.2 Layout.tsxにコンポーネント追加

`richColors`を使うと、自分で色（successやfailedの時に色分け）を設定しなくてもOKです。

```layout.tsx
+ import { Toaster } from "@/components/ui/sonner"

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head />
      <body>
        <main>{children}</main>
+        <Toaster richColors />
      </body>
    </html>
  )
}

```

# sonnarとtoasterの比較
`shadcn/ui`のtoasterは、一から見た目やメソッドを用意する人向けです。
[sonnar](https://sonner.emilkowal.ski/)は、すぐ使いやすい形から準備ほぼなしで使えます。

### sonnarの場合

#### info

```sonnar.ts
import { Toaster, toast } from 'sonner'

function App() {
  return (
    <div>
      <Toaster />
      <button onClick={() => toast.info('お気に入りを更新しました')}>
        Show toast
      </button>
    </div>
  )
}
```

![スクリーンショット 2024-05-21 20.08.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/70052f28-35d0-635d-4fe7-e532ea481968.png)

#### success

```sonnar.ts
import { Toaster, toast } from 'sonner'

function App() {
  return (
    <div>
      <Toaster />
      <button onClick={() => toast.success("お気に入り追加しました")}>
        Show toast
      </button>
    </div>
  )
}
```

![スクリーンショット 2024-05-21 20.13.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/5c9f9e9c-f8d7-f681-c33e-be50d7041b32.png)


#### error


```sonnar.ts
import { Toaster, toast } from 'sonner'

function App() {
  return (
    <div>
      <Toaster />
      <button onClick={() => toast.error("お気に入り削除しました");}>
        Show toast
      </button>
    </div>
  )
}
```

![スクリーンショット 2024-05-21 20.14.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/180ae12c-66d9-4268-5eae-fe603887b870.png)



### toasterの場合

例えば、`shadcn/ui`のtoasterは`useToast`をimportし、見た目が薄ーくしか用意されてません

```toaster.ts
import { useToast } from "@/components/ui/use-toast"

export const ToastDemo = () => {
  const { toast } = useToast()

  return (
    <Button
      onClick={() => {
        toast({
          description: "your message has been sent.",
        })
      }}
    >
      Show Toast
    </Button>
  )
}
```

![スクリーンショット 2024-05-21 19.51.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/d890c45a-c49c-9381-23aa-e98fb011003d.png)

### failed な toaster

`variant: "destructive"`を追加します。

```toaster.ts
"use client"

import { Button } from "@/components/ui/button"
import { ToastAction } from "@/components/ui/toast"
import { useToast } from "@/components/ui/use-toast"

export function ToastDestructive() {
  const { toast } = useToast()

  return (
    <Button
      variant="outline"
      onClick={() => {
        toast({
          variant: "destructive",
          title: "Uh oh! Something went wrong.",
          description: "There was a problem with your request.",
          action: <ToastAction altText="Try again">Try again</ToastAction>,
        })
      }}
    >
      Show Toast
    </Button>
  )
}
```

![スクリーンショット 2024-05-21 19.51.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/70f5b178-3721-4b74-f68f-2b0b76db5a6e.png)


## success な toaster
用意されていないので、自分で追加する必要があります。


## まとめ
- すぐ使える形で使うなら、sonnarを使う
- 1からカスタマイズしたい、sonnarの見た目を差別化したいであれば、toasterを使う

## 参考リンク

- [shadcn/ui toaster](https://ui.shadcn.com/docs/components/toast)
- [shadcn/ui sonnar](https://ui.shadcn.com/docs/components/sonner)
- [サンプルリポジトリ](https://github.com/yuyakinjo/next-view-transition)