Material UIよりもなんかいいらしいという噂のshadcnというUIライブラリを聞いたので、どこが優れているのか気になったので試してみます!
初期設定
公式ドキュメントのNext.jsのインストールページを参考にやっていきます
npx create-next-app@latest my-app --typescript --tailwind --eslint
新規Nextプロジェクトの作成
tailwindは必須なので、既存のプロジェクトにshadcnを導入する場合はtailwindも導入する必要があります
my-app/
├── app/
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx
├── components/
│ ├── ui/
│ │ └── 後々追加されていく
│ └── ...
├── lib/
│ └── utils.ts
├── components.json
├── tailwind.config.js
└── ...
npx shadcn-ui@latest init
shadcnの初期設定
何個か質問が来ますが、基本的には全てEnterで問題ないかと思います
実行が終わるとルートディレクトリにcomponents.json
が追加されています
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
先ほどの質問項目がまとまっています
フォントちょい変更
import type { Metadata } from 'next'
+ import { Noto_Sans_JP } from 'next/font/google'
import './globals.css'
+ const notoSansJP = Noto_Sans_JP({ subsets: ['latin'] })
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
+ <html lang="ja">
+ <body className={notoSansJP.className}>{children}</body>
</html>
)
}
UIの追加
それではまず、Buttonを試してみます
npx shadcn-ui@latest add button
components/ui/button.tsx
が追加されます
import { Button } from "@/components/ui/button";
export default function Home() {
return (
<main className="p-24">
<Button>Click me</Button>
</main>
);
}
サイトを見てみると、ボタンが設置されているはずです
シンプルですが、shadcnのデザインができました
もっとカスタマイズするのは、公式ドキュメントを参考にすると簡単にできました
import { Button } from "@/components/ui/button";
+ import { Mail } from "lucide-react";
export default function Home() {
return (
<main className="p-24">
<Button>Click me</Button>
+ <Button>
+ <Mail className="mr-2 h-4 w-4" /> Login with Email
+ </Button>
</main>
);
}
Tailwindを使い慣れている人ならbutton.tsx
も自由にカスタマイズできて便利かと思います
個人的いいとこ
- 新しく覚えることが少ない
- ほぼほぼTailwind
- コンポーネントのコード自体を追加してくれるから追加し終わったらあとは自分でいじれる
- 最低限の初期設定方法やコンポーネントの追加方法さえやってしまえば、あとは、tailwindで細かいカスタマイズをできたり、独自のpropsの設定方法を直接コンポーネントを見れば設定できたりする
- バージョン管理が容易
- 他のUIライブラリだと破壊的変更がある時がたまにあるそうですが、shadcnの場合はコード自体を追加しているので、破壊もクソもない
- 必要なもののみ追加
- 必要なコンポーネントのみを追加するので、他のUIライブラリより軽いのかもしれません
個人的お遊びタイム
ダークモード
ドキュメント
https://ui.shadcn.com/docs/dark-mode/next
もうあとはドキュメントコピペしてたらできます
npm install next-themes
npx shadcn-ui@latest add dropdown-menu
+ "use client";
import { Mail } from "lucide-react";
+ import { Moon, Sun } from "lucide-react";
+ import { useTheme } from "next-themes";
import { Button } from "@/components/ui/button";
+ import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+ } from "@/components/ui/dropdown-menu";
export default function Home() {
+ const { setTheme } = useTheme();
return (
<main className="p-24">
<Button>Click me</Button>
<Button>
<Mail className="mr-2 h-4 w-4" /> Login with Email
</Button>
<h2>ダークモード</h2>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</main>
);
}
あざしたおわり〜〜