shadcn-ui-expert について
shadcn-ui-expertは、Reactプロジェクトでshadcn/uiを実装するエージェント向けスキルです。コンポーネントの選定、導入、カスタマイズ、フォーム、アクセシビリティを案内し、MCPサーバー経由の自然言語によるインストールも扱います。
主な機能
- 01コンポーネント選定と実装ガイド
- 02初期設定とCLIによる導入
- 03Tailwind CSSとテーマのカスタマイズ
- 04フォーム検証パターン
- 05アクセシビリティとコンポーネント構成
活用シーン
- 01インターフェースに適したコンポーネントの選定
- 02検証付きフォームやダイアログの作成
- 03テーマとダークモードのカスタマイズ
- 04自然言語でのコンポーネント導入
MCP 対応
自然言語のリクエストに応じて、MCPサーバーからshadcn/uiコンポーネントを導入する方法を案内します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ majesteitbart/ talentmatcher --skill shadcn-ui-expertインストール後、Claude Code で/shadcn-ui-expertを入力して読み込まれたか確認します。
詳細
shadcn-ui エキスパート
shadcn-ui は、TypeScript、Tailwind CSS、Radix UI プリミティブで構築された、美しくデザインされ、アクセシビリティに配慮した React コンポーネントのコレクションです。このスキルでは、コンポーネントの選択、実装、カスタマイズ、ベストプラクティスについて説明します。
クイックスタート
インストール
まず、プロジェクトで shadcn-ui を初期化します。
npx shadcn-ui@latest init
設定用の components.json ファイルが作成されます。フレームワークを選択してください。
- Next.js(App Router を推奨)
- Vite
- Remix
- Astro
- Laravel
- Gatsby
- React Router
- TanStack Router/Start
コンポーネントのインストール
CLI を使って、個々のコンポーネントをインストールします。
# Install a button component
npx shadcn-ui@latest add button
# Install form components
npx shadcn-ui@latest add form input select checkbox
# Install a data table
npx shadcn-ui@latest add data-table
または、「ログインフォームを追加して」と直接依頼してください。自然言語での指示に従って、MCP サーバーを使ってインストールできます。
コンポーネントのカテゴリ
フォームと入力コンポーネント
用途:データ収集、ユーザー入力、検証
form- React Hook Form を使った複雑なフォームinput- テキストフィールドtextarea- 複数行のテキストselect- ドロップダウン選択checkbox- 真偽値の入力radio-group- 選択肢からの単一選択switch- 真偽値の切り替えdate-picker- 日付の選択combobox- オートコンプリート機能付きの検索可能な選択
レイアウトとナビゲーション
用途:アプリの構造、ナビゲーションのフロー、コンテンツの整理
sidebar- 折りたたみ可能なサイドナビゲーションtabs- タブ形式のコンテンツaccordion- 折りたたみ可能なセクションbreadcrumb- ナビゲーションパスnavigation-menu- ドロップダウンメニューscroll-area- カスタムスクロール領域
オーバーレイとダイアログ
用途:モーダル、確認、フローティングコンテンツ
dialog- モーダルダイアログalert-dialog- 確認用プロンプトdrawer- モバイルに適したサイドパネルpopover- フローティングポップオーバーtooltip- ホバー時の情報表示dropdown-menu- ドロップダウンメニューcontext-menu- 右クリックメニュー
データ表示
用途:構造化データの表示
table- 基本的な HTML テーブルdata-table- 並べ替え、フィルタリング、ページネーションに対応した高度なテーブルavatar- ユーザープロフィール画像badge- ステータスラベルcard- コンテンツコンテナ
フィードバックとステータス
用途:ユーザーフィードバック、読み込み状態、アラート
alert- アラートメッセージtoast- 通知progress- プログレスバーskeleton- 読み込み中のプレースホルダーspinner- 読み込みインジケーター
コンポーネント選択ガイド
適切なコンポーネントを選ぶには、次の質問を自問してください。
-
ユーザーは何を操作しますか?
- テキスト入力 →
inputを使います - 選択肢から選ぶ →
selectまたはcomboboxを使います - はい/いいえの判断 →
checkboxまたはswitchを使います - 複数のフィールド →
formを使います
- テキスト入力 →
-
どのように表示しますか?
- ほかのコンテンツとインラインで表示 →
input、select - 画面中央に表示 →
dialog - 横からスライドして表示 →
drawer - 情報をツールチップで表示 →
tooltip
- ほかのコンテンツとインラインで表示 →
-
どのようなコンテキストですか?
- フォーム内 →
formと組み合わせてfieldコンポーネントを使います - 単独のボタン →
buttonを使います - テーブル内 → テーブルの行セルまたは
data-tableを使います
- フォーム内 →
-
検証が必要ですか?
- はい →
form、field、React Hook Form を組み合わせます - いいえ → シンプルなコンポーネント(
input、select)を使います
- はい →
よくある実装パターン
検証機能付きの基本的なフォーム
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import { Button } from "@/components/ui/button"
import { Form, FormField, FormItem, FormLabel, FormControl } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
const formSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
})
export function LoginForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
})
function onSubmit(values: z.infer<typeof formSchema>) {
console.log(values)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input placeholder="[email protected]" {...field} />
</FormControl>
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}
ダイアログのパターン
import { Button } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
export function DeleteDialog() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="destructive">Delete</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure?</DialogTitle>
<DialogDescription>
This action cannot be undone.
</DialogDescription>
</DialogHeader>
<div className="flex gap-3 justify-end">
<Button variant="outline">Cancel</Button>
<Button variant="destructive">Delete</Button>
</div>
</DialogContent>
</Dialog>
)
}
スタイリングとカスタマイズ
すべてのコンポーネントはスタイリングに Tailwind CSS を使用します。次の方法で外観をカスタマイズできます。
1. Tailwind クラス
コンポーネントにクラスを直接追加します。
<Button className="w-full text-lg">Full Width</Button>
<Input className="rounded-lg border-2" />
2. CSS 変数(テーマカラー)
shadcn/ui はテーマ設定に CSS 変数を使用します。app/globals.css を編集してください。
@layer base {
:root {
--primary: 222.2 47.4% 11.2%;
--secondary: 210 40% 96%;
}
}
3. ダークモード
使用するフレームワークでダークモードを有効にします。
- Next.js:
next.config.jsで設定します - Vite:
tailwind.config.jsにダーククラスの検出を追加します - コンポーネントは
darkクラスに自動的に対応します
4. コンポーネントのバリアント
多くのコンポーネントには組み込みのバリアントがあります。
<Button variant="outline" />
<Button variant="ghost" />
<Button variant="destructive" />
<Badge variant="secondary" />
コンポジションとベストプラクティス
1. カスタマイズよりコンポジション
大きなコンポーネントを変更するのではなく、小さなコンポーネントを組み合わせます。
// ✅ Good: Compose components
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>
<Form>...</Form>
</CardContent>
</Card>
// ❌ Avoid: Over-modifying single component
<CustomDialog withHeader={true} withForm={true} />
2. 型安全性を活用する
TypeScript を活用して、props の安全性を確保します。
import { Button } from "@/components/ui/button"
import type { ButtonProps } from "@/components/ui/button"
type CustomButtonProps = ButtonProps & {
label: string
}
3. アクセシビリティを標準でサポート
shadcn/ui は、アクセシビリティを標準で備えた Radix UI のプリミティブを使用しています。
- キーボードナビゲーション
- ARIA 属性
- スクリーンリーダーのサポート
- フォーカス管理
コンポーネントを正しく使用するだけで、アクセシビリティを利用できます。
4. パフォーマンス
- コンポーネントは小さく、モジュール化されています
- ツリーシェイキングに対応しています
- Radix UI 以外の実行時オーバーヘッドはありません
- 必要に応じて、頻繁に再レンダリングされるコンポーネントに
React.memoを使用します
フレームワーク固有の注意事項
Next.js
- React Hook Form との連携には
shadcn-ui@latest add formを使用します - フォームの送信には Server Actions を組み合わせます
- ダークモードは
next-themesで動作します
Vite
tailwind.config.jsにコンポーネントのパスが含まれていることを確認します- 高速な開発には Vite の HMR を使用します
Remix
- フォームは
remixの form actions で動作します - 楽観的な更新にはルート遷移を使用します
よくあるカスタマイズ作業
プライマリカラーの変更
初期化時に components.json を編集するか、globals.css の CSS 変数を手動で更新します。
カスタムコンポーネントの追加
shadcn/ui のパターンに従って、components/ui/ に独自のコンポーネントを作成します。
// components/ui/my-component.tsx
import * as React from "react"
export interface MyComponentProps
extends React.HTMLAttributes<HTMLDivElement> {}
const MyComponent = React.forwardRef<HTMLDivElement, MyComponentProps>(
({ className, ...props }, ref) => (
<div
ref={ref}
className={className}
{...props}
/>
)
)
MyComponent.displayName = "MyComponent"
export { MyComponent }
複数ブランド向けのテーマ設定
CSS 変数のレイヤーを使用します。
.brand-a {
--primary: 220 90% 56%;
--secondary: 0 0% 100%;
}
.brand-b {
--primary: 0 100% 50%;
--secondary: 200 100% 50%;
}
バリデーションとフォーム
React Hook Form + Zod を使用する場合
クライアント側のバリデーションを行う複雑なフォームでのベストプラクティスです。
npm install react-hook-form zod @hookform/resolvers
TanStack Form を使用する場合
高度なフォーム要件に対応する代替手段です。
npm install @tanstack/react-form
特定のフォームパターン(ログイン、サインアップ、複数ステップなど)については、お尋ねください。
トラブルシューティング
コンポーネントのスタイルが正しく適用されない
- ✅ Tailwind が
tailwind.config.jsで設定されていることを確認します - ✅
components.jsonのpath設定が正しいことを確認します - ✅ コンポーネントの追加後に
npm installを実行します
TypeScript のエラー
- ✅ コンポーネントが
/components/ui/nameからインポートされていることを確認します - ✅ コンポーネントに TypeScript のサポートが標準で備わっていることを確認します
フォームのバリデーションが機能しない
- ✅
zodと@hookform/resolversをインストールします - ✅
useFormでzodResolverを使用します
次のステップ
特定の作業について詳しく知りたい場合は、以下を参照してください。
- COMPONENT_GUIDE.md - 各コンポーネントの詳細な解説
- FORMS_GUIDE.md - 複雑なフォームの作成
- PATTERNS.md - よく使われる UI パターンと組み合わせ
- CUSTOMIZATION.md - テーマ設定とスタイルガイド