コンポーネントパターン — よく使うUIの作り方
この章では実務でよく使うUIパターンをTailwindで実装する方法をまとめます。コピペで使えるボタン・カード・フォームなどの実装例を集めました。
学習者同じボタンを何度も書いていると、クラスの羅列をコピペするのが大変…。これって毎回書くものなの?
先生よく使うUIはReactコンポーネントに切り出して、クラスを中に閉じ込めるのが基本だよ。まずこの章で「型」を覚えて、次の章でコンポーネント化を学ぼう。

ボタン
<!-- プライマリボタン -->
<button class="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-semibold rounded-lg transition-colors focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:outline-none disabled:opacity-50 disabled:cursor-not-allowed">
送信
</button>
<!-- アウトラインボタン -->
<button class="inline-flex items-center gap-2 px-4 py-2 border border-blue-600 text-blue-600 hover:bg-blue-50 text-sm font-semibold rounded-lg transition-colors">
キャンセル
</button>
<!-- ゴーストボタン(背景なし) -->
<button class="inline-flex items-center gap-2 px-4 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-100 text-sm font-medium rounded-lg transition-colors">
詳細
</button>バッジ
<!-- ステータスバッジ -->
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
完了
</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
処理中
</span>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
エラー
</span>カード
<div class="bg-white rounded-2xl border border-gray-200 shadow-sm overflow-hidden hover:shadow-md transition-shadow">
<img src="..." alt="..." class="w-full h-48 object-cover" />
<div class="p-5">
<span class="text-xs font-medium text-blue-600 uppercase tracking-wide">カテゴリ</span>
<h3 class="mt-1 text-lg font-semibold text-gray-900 line-clamp-2">
カードタイトル
</h3>
<p class="mt-2 text-sm text-gray-500 line-clamp-3">
説明テキストが入ります。長い場合は3行で省略されます。
</p>
<div class="mt-4 flex items-center justify-between">
<span class="text-xs text-gray-400">2024/01/01</span>
<button class="text-sm text-blue-600 hover:underline">続きを読む</button>
</div>
</div>
</div>フォーム
<form class="space-y-5">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1.5">
メールアドレス
<span class="text-red-500 ml-0.5">*</span>
</label>
<input
type="email"
class="block w-full px-3 py-2.5 border border-gray-300 rounded-lg text-sm
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
placeholder:text-gray-400"
placeholder="example@email.com"
/>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1.5">メッセージ</label>
<textarea
rows="4"
class="block w-full px-3 py-2.5 border border-gray-300 rounded-lg text-sm
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
resize-none"
></textarea>
</div>
<button type="submit" class="w-full py-2.5 bg-blue-600 hover:bg-blue-700 text-white font-semibold rounded-lg transition-colors">
送信する
</button>
</form>アラート
<!-- 情報 -->
<div class="flex gap-3 p-4 bg-blue-50 border border-blue-200 rounded-lg text-blue-800">
<svg class="w-5 h-5 flex-shrink-0 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
<!-- info icon -->
</svg>
<p class="text-sm">情報メッセージです。</p>
</div>
<!-- エラー -->
<div class="flex gap-3 p-4 bg-red-50 border border-red-200 rounded-lg text-red-800">
<p class="text-sm">エラーが発生しました。</p>
</div>ちゃんと使うためのポイント
- Reactコンポーネントにまとめてクラスを閉じ込めるとHTMLの長さ問題が解消される
- 繰り返し使うパターンはコンポーネント化して
cn()(clsx) でクラスを管理する - バリアントはpropsで切り替えると再利用性が高まる
次の章では、テーマカスタマイズの方法を学びます。