はい、承知いたしました。
「shadcn/uiの基本的な使い方とカスタマイズ方法」についての詳細な説明を含む、約5000語の記事を作成します。以下、記事の内容です。
【コピペでOK】shadcn/uiの基本的な使い方とカスタマイズ方法を徹底解説
モダンフロントエンド開発の世界では、UIコンポーネントライブラリは必要不可欠なツールです。MUI (Material-UI)、Chakra UI、Ant Designなど、数多くの優れたライブラリが存在し、私たちの開発を支えてきました。しかし、近年、これらとは一線を画す新しいアプローチを提唱するツールが登場し、世界中のReact開発者から絶大な支持を集めています。それが「shadcn/ui」です。
shadcn/uiは、従来のコンポーネントライブラリとは根本的に思想が異なります。それは「ライブラリではない」と公言しており、コンポーネントをnpmパッケージとしてインストールするのではなく、必要なコンポーネントのコードを直接あなたのプロジェクトにコピー&ペーストするというユニークな仕組みを採用しています。
このアプローチにより、開発者はコンポーネントの完全な所有権を持つことができ、無限のカスタマイズ性を手に入れることができます。ブラックボックス化されたコンポーネントの挙動に悩まされることなく、プロジェクトの要件に合わせて自由にコードを改変できるのです。
この記事では、そんな革新的なツールであるshadcn/uiの魅力を余すところなくお伝えします。環境構築から基本的な使い方、そしてshadcn/uiの真骨頂である詳細なカスタマイズ方法、さらには実践的な応用例まで、この1記事でマスターできるように網羅的に解説します。
「コピペでOK」なコードスニペットを豊富に用意しましたので、ぜひ実際に手を動かしながら、次世代のUI開発体験を味わってみてください。
第1章: shadcn/uiの概要と特徴
まず、shadcn/uiがどのようなもので、なぜこれほどまでに注目されているのかを深く理解しましょう。
1. shadcn/uiとは?
shadcn/uiは、一言で言えば「再利用可能なコンポーネントのコレクション」です。しかし、重要なのはその提供方法です。
従来のライブラリでは npm install @mui/material
のようにパッケージをインストールし、import { Button } from '@mui/material';
のようにnode_modules
内のコードをインポートして使います。この場合、コンポーネントの内部実装はブラックボックスであり、カスタマイズは提供されたpropsやテーマ機能の範囲内に限られます。
一方、shadcn/uiはCLI(コマンドラインインターフェース)を提供します。
npx shadcn-ui@latest add button
このコマンドを実行すると、Button
コンポーネントのソースコード(.tsx
ファイル)が、あなたのプロジェクト内の指定したディレクトリ(例: src/components/ui/button.tsx
)に直接生成されます。
つまり、あなたはコンポーネントの「利用者」ではなく、「所有者」になるのです。
このアーキテクチャは、2つの強力な技術スタックの上に成り立っています。
- Radix Primitives: アクセシビリティに優れたヘッドレスUIコンポーネントライブラリです。キーボード操作、フォーカス管理、WAI-ARIA属性など、複雑で面倒なアクセシビリティ対応を裏側で完璧に処理してくれます。shadcn/uiは、このRadixをベースにロジックを構築しています。
- Tailwind CSS: ユーティリティファーストのCSSフレームワークです。shadcn/uiのコンポーネントはすべてTailwind CSSのユーティリティクラスでスタイリングされており、直感的かつ柔軟なデザイン調整が可能です。
shadcn/uiは、Radixの堅牢なロジックとアクセシビリティに、Tailwind CSSの無限の表現力を組み合わせた、美しく設計されたコンポーネント群を、あなたの手元に直接届けてくれるツールなのです。
2. shadcn/uiのメリット
shadcn/uiが提供する価値は多岐にわたります。
- 完全な所有権と無限のカスタマイズ性: コードが自分のプロジェクト内にあるため、propsを追加したり、内部ロジックを変更したり、アニメーションを加えたりと、文字通り何でもできます。外部ライブラリの仕様に縛られることはありません。
- 高いデザイン自由度: Tailwind CSSベースであるため、
tailwind.config.js
で定義したデザイントークン(色、スペーシング、フォントなど)がそのまま活かされます。プロジェクトのデザインシステムと完全に統合することが容易です。 - 最高のアクセシビリティ: Radix Primitivesをベースにしているため、提供されるコンポーネントは最初からアクセシビリティが考慮されています。これは、すべてのユーザーにとって使いやすいアプリケーションを構築する上で非常に重要です。
- バンドルサイズの最適化: 必要なコンポーネントだけをプロジェクトに追加するため、未使用のコンポーネントコードが最終的なバンドルに含まれることはありません。アプリケーションを軽量に保つことができます。
- 依存関係からの解放:
node_modules
に巨大なUIライブラリを追加しないため、依存関係の競合や、ライブラリの破壊的変更に追従するコストから解放されます。 - 学習教材として: よく設計されたReactコンポーネントの生コードに触れることができるため、ReactやTypeScript、アクセシビリティのベストプラクティスを学ぶための絶好の教材にもなります。
3. 従来のコンポーネントライブラリとの比較
項目 | MUI, Chakra UIなど | shadcn/ui |
---|---|---|
提供方法 | npmパッケージとしてインストール | CLIでソースコードをプロジェクトに追加 |
所有権 | 利用者(ライブラリのコードはnode_modules 内) |
所有者(コードは自分のプロジェクト内) |
スタイリング | CSS-in-JS, スタイル付きコンポーネント | Tailwind CSS(ユーティリティクラス) |
カスタマイズ | propsやテーマAPI経由での制限付きカスタマイズ | コードの直接編集による無制限のカスタマイズ |
依存関係 | ライブラリ自身と、その依存パッケージ | Radix Primitives, Tailwind CSSなど(個別に管理) |
アップデート | npm update (破壊的変更のリスクあり) |
CLIで再取得 or 手動で差分をマージ |
バンドルサイズ | Tree Shakingに依存(不要なコードが含まれる可能性) | 使うものだけを追加するため常に最小 |
この比較からも、shadcn/uiがいかに開発者にコントロール権を与える設計思想であるかがわかります。
第2章: 環境構築と導入
それでは、実際にshadcn/uiをプロジェクトに導入してみましょう。ここでは、最も一般的で相性の良いNext.js (App Router)をベースに解説します。
1. 前提条件
- Node.js (v18.17.0以降を推奨)
- npm, yarn, pnpmなどのパッケージマネージャ
- React / Next.js の基本的な知識
2. Next.jsプロジェクトへの導入手順
Step 1: Next.jsプロジェクトの作成
まだプロジェクトがない場合は、以下のコマンドで新しいNext.jsプロジェクトを作成します。TypeScriptの使用を強く推奨します。
bash
npx create-next-app@latest my-shadcn-app
ウィザードでは、TypeScript
, Tailwind CSS
, App Router
を選択してください。
Step 2: shadcn/uiの初期化
作成したプロジェクトのディレクトリに移動し、init
コマンドを実行します。
bash
cd my-shadcn-app
npx shadcn-ui@latest init
このコマンドを実行すると、対話形式でいくつかの質問をされます。これらはプロジェクトの構成をshadcn/uiに伝えるための重要な設定です。
text
Would you like to use TypeScript (recommended)? › yes
Which style would you like to use? › Default
Which color would you like to use as base color? › Slate
Where is your global CSS file? › app/globals.css
Do you want to use CSS variables for colors? › yes
Where is your tailwind.config.js located? › tailwind.config.js
Configure import alias for components: › @/components
Configure import alias for utils: › @/lib/utils
Are you using React Server Components? › yes
Write configuration to components.json. Proceed? › yes
各質問の意味を詳しく見ていきましょう。
- Use TypeScript?:
yes
を選択。shadcn/uiはTypeScriptと非常に相性が良いです。 - Which style?:
Default
とNew York
の2つのスタイルプリセットから選べます。Default
はよりミニマル、New York
は少し装飾的なスタイルです。後から変更も可能なので、まずはDefault
で始めましょう。 - Base color?: アプリケーションの基本となるテーマカラーを選びます。ここで選んだ色(例:
Slate
)を元に、様々な階調のカラーパレットがCSS変数として生成されます。 - Global CSS file?: Tailwind CSSのディレクティブ(
@tailwind base;
など)や、テーマ全体のCSS変数が書き込まれるグローバルなCSSファイルの場所を指定します。Next.js App Routerのデフォルトはapp/globals.css
です。 - Use CSS variables for colors?:
yes
を強く推奨します。これにより、テーマカラーやダークモードの切り替えが非常に簡単になります。 tailwind.config.js
location?: Tailwind CSSの設定ファイルの場所です。通常はプロジェクトルートにあります。- Import alias for components/utils: コンポーネントやユーティリティ関数をインポートする際のエイリアス(別名)を設定します。
@/components
のように設定すると、import { Button } from '@/components/ui/button'
のように階層を意識せずスッキリと記述できます。tsconfig.json
(またはjsconfig.json
)にも対応する設定が自動で追加されます。 - React Server Components?: Next.js App Routerを使っている場合は
yes
を選択します。
すべての質問に答えると、設定がcomponents.json
というファイルに保存され、必要な設定ファイルが自動で変更・作成されます。
Step 3: init
コマンドによる変更内容の確認
init
コマンドは、あなたのプロジェクトにいくつかの重要な変更を加えます。
-
tailwind.config.ts
(または.js
):tailwindcss-animate
プラグインが追加されます。- shadcn/uiのテーマ設定(色、角丸、キーフレームアニメーションなど)が
theme.extend
内に追加されます。
-
app/globals.css
:- ファイルの先頭に、選択したベースカラーに基づいた大量のCSS変数が追加されます。これらがサイト全体のデザイントークンとなります。ダークモード用の変数も含まれています。
“`css
/ 例: globals.css に追加される内容 /
@tailwind base;
@tailwind components;
@tailwind utilities;@layer base {
:root {
–background: 0 0% 100%;
–foreground: 222.2 84% 4.9%;
/ … 大量のCSS変数が続く … /
–radius: 0.5rem;
}.dark {
–background: 222.2 84% 4.9%;
–foreground: 210 40% 98%;
/ … ダークモード用の変数が続く … /
}
}
“` -
@/lib/utils.ts
:clsx
とtailwind-merge
という2つの便利なライブラリを組み合わせたcn
というヘルパー関数が作成されます。これは、コンポーネントに渡されるclassName
を安全にマージするためのユーティリティです。例えば、cn("p-2", "p-4")
はp-4
だけを適用し、クラス名の衝突を解決してくれます。
-
components.json
:init
コマンドで答えた設定内容が保存されるファイルです。CLIはこのファイルを見て、コンポーネントをどこに、どのように追加するかを判断します。
これで、shadcn/uiを使う準備が整いました。
第3章: コンポーネントの追加と基本的な使い方
準備ができたので、実際にコンポーネントをプロジェクトに追加して使ってみましょう。
1. CLIを使ったコンポーネントの追加
shadcn/uiのコンポーネントは、add
コマンドで個別に追加します。まずは最も基本的なButton
コンポーネントを追加してみましょう。
bash
npx shadcn-ui@latest add button
コマンドを実行すると、init
時に設定したコンポーネントのパス(例: @/components
)配下に、ui/button.tsx
というファイルが作成されます。
- components/
- ui/
- button.tsx <-- これが生成される
- lib/
- ...
このbutton.tsx
が、あなたが所有するButton
コンポーネントのソースコードです。
同様に、他のコンポーネントも追加できます。複数同時に追加することも可能です。
bash
npx shadcn-ui@latest add card input label dialog
2. Buttonコンポーネントを使ってみる
app/page.tsx
を開き、追加したButton
コンポーネントを使ってみましょう。
app/page.tsx
“`tsx
import { Button } from “@/components/ui/button”;
export default function Home() {
return (
shadcn/ui Buttons
{/* 基本的な使い方 */}
<Button>Default Button</Button>
{/* variant props で見た目を変更 */}
<div className="flex gap-2">
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
</div>
{/* size props でサイズを変更 */}
<div className="flex gap-2 items-center">
<Button size="lg">Large</Button>
<Button size="default">Default</Button>
<Button size="sm">Small</Button>
<Button size="icon">
{/* Heroicons などのアイコンライブラリと組み合わせる */}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M11 13H5v-2h6V5h2v6h6v2h-6v6h-2v-6Z"/></svg>
</Button>
</div>
{/* className props でスタイルを上書き・追加 */}
<Button className="bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 text-white">
Custom Gradient
</Button>
</main>
);
}
“`
このコードを貼り付けて開発サーバーを起動すると、様々なスタイルのボタンが表示されるはずです。
variant
やsize
といったprops
で見た目を簡単に変更できること、そしてclassName
を使えばTailwind CSSのクラスを自由に追加してカスタマイズできることがわかります。
3. その他の基本的なコンポーネントの例
いくつかの代表的なコンポーネントの使い方を見てみましょう。
Dialog (モーダルウィンドウ)
インタラクティブなコンポーネントは、状態管理が必要になるため、'use client'
ディレクティブを付けたクライアントコンポーネント内で使用します。
1. コンポーネントの追加
bash
npx shadcn-ui@latest add dialog
2. app/page.tsx
での使用例
“`tsx
‘use client’; // Dialogはインタラクティブなのでクライアントコンポーネントにする
import { Button } from “@/components/ui/button”;
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
DialogFooter,
} from “@/components/ui/dialog”;
import { Input } from “@/components/ui/input”; // 事前に追加: npx shadcn-ui@latest add input
import { Label } from “@/components/ui/label”; // 事前に追加: npx shadcn-ui@latest add label
export default function Home() {
return (
);
}
``
DialogTriggerでダイアログを開くトリガー(ここではボタン)を指定し、
DialogContent`内にモーダルの内容を記述します。非常に宣言的にUIを構築できます。
Toast (通知)
Toastは少し特殊で、useToast
フックと、Toastを表示するためのコンテナであるToaster
コンポーネントが必要です。
1. コンポーネントの追加
bash
npx shadcn-ui@latest add toast
2. Toaster
の配置
アプリケーションのルートレイアウトにToaster
を配置する必要があります。
app/layout.tsx
“`tsx
import type { Metadata } from “next”;
import { Inter } from “next/font/google”;
import “./globals.css”;
import { Toaster } from “@/components/ui/toaster”; // Toasterをインポート
const inter = Inter({ subsets: [“latin”] });
export const metadata: Metadata = {
title: “Create Next App”,
description: “Generated by create next app”,
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
{children}
);
}
“`
3. Toastの使用
useToast
フックを使って、任意の場所からToastを表示できます。
app/page.tsx
“`tsx
‘use client’;
import { Button } from “@/components/ui/button”;
import { useToast } from “@/components/ui/use-toast”;
export default function Home() {
const { toast } = useToast();
return (
);
}
“`
ボタンをクリックすると、画面の右下にスタイリッシュな通知が表示されます。
第4章: shadcn/uiのカスタマイズ方法
ここからがshadcn/uiの真骨頂です。コンポーネントを自分の思い通りにカスタマイズする方法を、3つのレベルに分けて解説します。
レベル1: className
propを使った直接的なスタイル上書き
最も手軽な方法は、コンポーネントにclassName
propを渡してTailwind CSSのユーティリティクラスを適用することです。
前述のcn
ユーティリティ関数のおかげで、既存のスタイルと競合することなく、安全にスタイルを上書き・追加できます。
“`tsx
import { Button } from “@/components/ui/button”;
import { Card, CardContent, CardHeader, CardTitle } from “@/components/ui/card”;
function CustomComponent() {
return (
{/* カードに影とボーダーを追加 */}
<Card className="mt-4 shadow-xl border-2 border-fuchsia-500">
<CardHeader>
<CardTitle>Custom Card</CardTitle>
</CardHeader>
<CardContent>
<p>This card has custom styles applied via className.</p>
</CardContent>
</Card>
</div>
);
}
“`
特定の箇所だけ少しスタイルを変えたい、という場合に非常に便利です。
レベル2: コンポーネントファイルの直接編集
より根本的な変更や、新しいバリアントの追加を行いたい場合は、生成されたコンポーネントのソースコードを直接編集します。これこそがshadcn/uiの最大のメリットです。
components/ui/button.tsx
を開いてみましょう。内部ではcva
(Class Variance Authority)というライブラリが使われています。
components/ui/button.tsx
(抜粋)
“`tsx
import { cva, type VariantProps } from “class-variance-authority”;
const buttonVariants = cva(
“inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50”,
{
variants: {
variant: {
default: “bg-primary text-primary-foreground hover:bg-primary/90”,
destructive: “bg-destructive text-destructive-foreground hover:bg-destructive/90”,
outline: “border border-input bg-background hover:bg-accent hover:text-accent-foreground”,
secondary: “bg-secondary text-secondary-foreground hover:bg-secondary/80”,
ghost: “hover:bg-accent hover:text-accent-foreground”,
link: “text-primary underline-offset-4 hover:underline”,
},
size: {
default: “h-10 px-4 py-2”,
sm: “h-9 rounded-md px-3”,
lg: “h-11 rounded-md px-8”,
icon: “h-10 w-10”,
},
},
defaultVariants: {
variant: “default”,
size: “default”,
},
}
);
// … Reactコンポーネントの定義が続く
“`
cva
は、propsに応じて適用するクラス名を管理するための関数です。
– 第一引数: 全てのバリアントに共通で適用されるベースとなるクラス群です。
– variants
オブジェクト: variant
やsize
などのpropsの値ごとに適用するクラスを定義します。
– defaultVariants
オブジェクト: propsが指定されなかった場合に適用されるデフォルトの値を定義します。
このbuttonVariants
を編集することで、Button
コンポーネントの挙動を自由自在に変更できます。
実践的なカスタマイズ例
1. 既存のバリアントのスタイルを変更する
destructive
バリアントの背景色を、より鮮やかな赤に変更してみましょう。
“`tsx
// 変更前
destructive: “bg-destructive text-destructive-foreground hover:bg-destructive/90”,
// 変更後
destructive: “bg-red-500 text-white hover:bg-red-600 dark:bg-red-600 dark:hover:bg-red-700”,
“`
Tailwind CSSのクラスを書き換えるだけです。ダークモード用のスタイルも追加しました。
2. 新しいvariant
を追加する
きらびやかなグラデーションのpremium
バリアントを追加してみましょう。
variants.variant
オブジェクトに新しいキーを追加します。
tsx
// ...
variant: {
default: "...",
destructive: "...",
// ...
premium: "bg-gradient-to-r from-yellow-400 to-orange-500 text-white border-transparent hover:scale-105 transition-transform",
},
// ...
これで、<Button variant="premium">Go Premium</Button>
のように新しいバリアントを呼び出せるようになります。
3. 新しいsize
を追加する
特大サイズのxl
を追加します。
variants.size
オブジェクトに新しいキーを追加します。
tsx
// ...
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
xl: "h-14 rounded-lg px-12 text-lg", // xlサイズを追加
icon: "h-10 w-10",
},
// ...
<Button size="xl">Extra Large</Button>
が使えるようになりました。
このように、コンポーネントのソースコードを直接編集することで、デザインシステムを無限に拡張していくことができます。
レベル3: テーマとデザイントークンの一括変更
プロジェクト全体で一貫したデザイン変更を行いたい場合は、globals.css
やtailwind.config.ts
を編集します。
globals.css
でのCSS変数のカスタマイズ
init
時に生成されたCSS変数を書き換えることで、サイト全体の見た目を一括で変更できます。
app/globals.css
“`css
@layer base {
:root {
/ … /
/* 例1: サイト全体の角丸を大きくする */
--radius: 1rem; /* 0.5remから変更 */
}
.dark {
/ … /
}
}
``
–radius`変数は、多くのコンポーネントで角丸の大きさを定義するために使われています。この値を変更するだけで、ButtonやCardなど、すべてのコンポーネントの角丸が一斉に大きくなります。
同様に、--primary
や--background
などのカラー変数のHSL値を変更すれば、サイトのテーマカラーを簡単に変更できます。
css
:root {
/* ... */
/* プライマリカラーを緑系に変更 */
--primary: 142.1 76.2% 36.3%;
--primary-foreground: 355.7 100% 97.3%;
/* ... */
}
tailwind.config.ts
のカスタマイズ
tailwind.config.ts
を編集して、独自のデザイントークンを追加することも非常に有効です。
“`ts
// tailwind.config.ts
import type { Config } from “tailwindcss”
const config = {
// …
theme: {
container: {
// …
},
extend: {
colors: {
// … shadcn/uiのデフォルトカラー設定
// ここに独自のブランドカラーを追加する
brand: {
light: ‘#67e8f9’,
DEFAULT: ‘#06b6d4’,
dark: ‘#0e7490’,
},
},
keyframes: {
// …
},
animation: {
// …
},
},
},
// …
} satisfies Config
export default config
``
brand
このようにカラーを追加すると、コンポーネントファイルや
classNamepropで
bg-brand,
text-brand-light` のようにカスタムカラーを使えるようになります。
第5章: 実践的な応用例
shadcn/uiのコンポーネントを組み合わせて、より複雑で実践的なUIを構築する方法を見ていきましょう。
1. フォームの構築 (react-hook-form
+ zod
)
shadcn/uiは、react-hook-form
(フォームの状態管理)とzod
(スキーマバリデーション)との連携を前提としたForm
コンポーネントを提供しています。
1. 必要なライブラリのインストール
bash
npm install react-hook-form zod @hookform/resolvers
2. shadcn/uiのForm関連コンポーネントの追加
bash
npx shadcn-ui@latest add form input label
3. フォームコンポーネントの実装例
“`tsx
“use client”
import { zodResolver } from “@hookform/resolvers/zod”
import { useForm } from “react-hook-form”
import * as z from “zod”
import { Button } from “@/components/ui/button”
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from “@/components/ui/form”
import { Input } from “@/components/ui/input”
import { toast } from “@/components/ui/use-toast”
// 1. Zodでバリデーションスキーマを定義
const formSchema = z.object({
username: z.string().min(2, {
message: “Username must be at least 2 characters.”,
}),
email: z.string().email({
message: “Please enter a valid email address.”,
}),
})
export function ProfileForm() {
// 2. useFormフックでフォームを初期化
const form = useForm
resolver: zodResolver(formSchema),
defaultValues: {
username: “”,
email: “”,
},
})
// 3. 送信ハンドラを定義
function onSubmit(values: z.infer
console.log(values)
toast({
title: “You submitted the following values:”,
description: (
{JSON.stringify(values, null, 2)}
),
})
}
return (
// 4. Formコンポーネントでラップ
)
}
``
FormField
このコードは、状態管理、バリデーション、UIを綺麗に分離した、非常に堅牢なフォームを構築します。コンポーネントが
react-hook-formと
Input`コンポーネントをうまくつなぎ合わせてくれるのがポイントです。
2. ダークモードの実装 (next-themes
)
shadcn/uiはCSS変数ベースで設計されているため、ダークモードの実装が非常に簡単です。next-themes
ライブラリと組み合わせるのがベストプラクティスです。
1. next-themes
のインストール
bash
npm install next-themes
2. tailwind.config.ts
の確認
darkMode
オプションが"class"
になっていることを確認します。init
コマンドで自動設定されているはずです。
ts
// tailwind.config.ts
const config = {
darkMode: ["class"],
// ...
}
3. ThemeProviderの作成
next-themes
のプロバイダーコンポーネントを作成します。これはクライアントコンポーネントである必要があります。
components/theme-provider.tsx
“`tsx
“use client”
import * as React from “react”
import { ThemeProvider as NextThemesProvider } from “next-themes”
import { type ThemeProviderProps } from “next-themes/dist/types”
export function ThemeProvider({ children, …props }: ThemeProviderProps) {
return
}
“`
4. ルートレイアウトにThemeProviderを適用
app/layout.tsx
で、アプリケーション全体をThemeProvider
でラップします。
app/layout.tsx
“`tsx
// …
import { ThemeProvider } from “@/components/theme-provider”
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
)
}
“`
5. テーマ切り替えスイッチの作成
useTheme
フックを使って、ライトモードとダークモードを切り替えるコンポーネントを作成します。
components/mode-toggle.tsx
“`tsx
“use client”
import * as React from “react”
import { Moon, Sun } from “lucide-react” // npm i lucide-react
import { useTheme } from “next-themes”
import { Button } from “@/components/ui/button”
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from “@/components/ui/dropdown-menu” // npx shadcn-ui@latest add dropdown-menu
export function ModeToggle() {
const { setTheme } = useTheme()
return (
Light
Dark
System
)
}
“`
あとは、このModeToggle
コンポーネントをヘッダーなど、好きな場所に配置すれば完了です。<html>
タグにclass="dark"
が付与されると、globals.css
の.dark
ブロック内のCSS変数が適用され、瞬時にテーマが切り替わります。
第6章: トラブルシューティングとFAQ
Q: npx shadcn-ui@latest add
コマンドが失敗する
A: 最も一般的な原因は、tsconfig.json
のpaths
設定とcomponents.json
のエイリアス設定の不一致です。両方のファイルを開き、@/components
や@/lib
などのパスが正しく、かつ一致しているか確認してください。
Q: コンポーネントのスタイルが適用されない
A: いくつか確認点があります。
1. app/globals.css
がapp/layout.tsx
で正しくインポートされているか。
2. tailwind.config.ts
のcontent
配列に、コンポーネントが配置されているディレクトリ(例: ./components/**/*.{ts,tsx}
)が含まれているか。
3. postcss.config.js
ファイルがプロジェクトルートに存在し、tailwindcss
とautoprefixer
プラグインが設定されているか。
Q: Dialog
やDropdownMenu
などのインタラクティブなコンポーネントが動かない
A: これらのコンポーネントは、内部でuseState
やuseEffect
などのクライアントサイドのフックを使用しています。Next.js App Routerでは、これらを使用するコンポーネント(またはその親コンポーネント)のファイルの先頭に'use client'
ディレクティブを記述する必要があります。
Q: shadcn/uiのコンポーネントをアップデートするには?
A: shadcn/uiはライブラリではないため、npm update
のようなコマンドはありません。アップデート方法は主に2つです。
1. add
コマンドで上書き: npx shadcn-ui@latest add button --overwrite
のように--overwrite
フラグを付けてコマンドを再実行します。ただし、あなた自身が加えたカスタマイズはすべて失われるため注意が必要です。
2. 手動で差分をマージ(推奨): shadcn/uiの公式サイトのChangelogや、GitHubリポジトリのコミット履歴を確認し、変更点(diff)を自分のコンポーネントファイルに手動で適用します。これにより、自分のカスタマイズを維持しながらコンポーnentを最新の状態に保つことができます。
まとめ
shadcn/uiは、単なるUIコンポーネントのコレクションではありません。それは、現代のフロントエンド開発におけるベストプラクティスを凝縮した、新しい開発哲学です。
「ライブラリではない、あなたのコンポーネントだ」
この思想は、私たち開発者に完全なコントロールと無限の創造性をもたらします。依存関係の呪縛から解放され、プロジェクトの要件に100%合致した、パフォーマンスが高く、アクセシブルなUIを、驚くほどの速さで構築することを可能にします。
この記事では、その導入から基本的な使い方、そしてshadcn/uiの真価を発揮するためのカスタマイズ方法や実践例までを網羅的に解説しました。しかし、shadcn/uiの世界はさらに奥深く、データテーブルやカレンダーなど、数多くの強力なコンポーネントがあなたを待っています。
ぜひ、公式ドキュメントを片手に、あなた自身のプロジェクトでshadcn/uiの力を体験してみてください。あなたはもはやUIライブラリの「消費者」ではありません。今日から、UIコンポーネントの「創造者」となるのです。