coding script
Photo by Markus Spiske on Pexels.com

【中級者向け】Blade コンポーネントで作る再利用可能な UI パーツガイド

この記事で学べること

  • Blade コンポーネントの基本構造と作成手順
  • Props・Slot を活用した柔軟な設計方法
  • 色覚特性に配慮した配色とARIAロールの指定例
  • 実践的なサンプルコードとディレクトリ構成
  • アクセシビリティ向上のためのチェックリスト

想定読者

  • Laravel を一通り触ったことがあり、ビューの保守性を高めたい中級者
  • チーム開発で一貫したUIを効率的に提供したいフロントエンドエンジニア
  • アクセシビリティ対応を学びながら再利用性の高いコンポーネント設計を身につけたい方

アクセシビリティレベル:★★★★☆

色のコントラスト比検証、ARIA属性の具体例、キーボード操作への配慮を網羅


はじめに:なぜ Blade コンポーネントが必要なのか

Laravel で大規模なプロジェクトを進めると、
同じようなボタンやカード、モーダルを何度も書き直す場面に直面します。
ビューの冗長化は、保守コストやバグの温床になりがち……。
Blade コンポーネントを活用すると、一度定義した UI パーツをどこでも簡単に再利用でき、
開発効率とコードの読みやすさが飛躍的に向上します♡

  • 一貫性:デザインのばらつきを防ぎ、ブランドイメージを統一
  • 保守性:修正はコンポーネント一箇所だけでOK
  • 可読性:ビューがシンプルになり、チームメンバーも理解しやすい

1. コンポーネントディレクトリ構成と基本ファイル

まずはディレクトリ構成から。Laravel 9以降では resources/views/components 配下が推奨です。

resources/
└── views/
    └── components/
        ├── button.blade.php
        ├── card.blade.php
        ├── form/
        │   └── input.blade.php
        └── layout/
            └── app.blade.php
  • components/ 直下には汎用パーツ(ボタン、カードなど)
  • components/form/ にはフォーム系パーツ(入力欄、ラベル付きグループ)
  • components/layout/ にはレイアウト系(ヘッダー・フッター共通レイアウト)

ディレクトリを階層化することで、増え続けるコンポーネントも見通し良く管理できます。


2. Props と Slot の基本:パラメータ受け渡しと柔軟性

2.1 Props で外部から値を受け取る

{{-- resources/views/components/button.blade.php --}}
@props([
  'type'  => 'primary',
  'url'   => '#',
  'label' => 'ボタン',
])

@php
  // 色ごとにクラスを切り替え
  $baseClass = 'px-4 py-2 rounded ';
  $colors = [
    'primary'   => 'bg-blue-600 text-white hover:bg-blue-700',
    'secondary' => 'bg-gray-200 text-gray-800 hover:bg-gray-300',
  ];
@endphp

<a href="{{ $url }}"
   {{ $attributes->merge(['class' => $baseClass . ($colors[$type] ?? $colors['primary'])]) }}>
  {{ $label }}
</a>
  • @props で受け取るパラメータを宣言
  • $attributes->merge() で追加クラスやARIA属性を流し込み可能

2.2 Slot で柔軟なコンテンツ差し替え

{{-- resources/views/components/card.blade.php --}}
<div {{ $attributes->merge(['class'=>'border rounded-lg shadow-sm p-4']) }}>
  {{-- カードヘッダー --}}
  @if (isset($header))
    <div class="border-b mb-3">
      {{ $header }}
    </div>
  @endif

  {{-- メインコンテンツ --}}
  <div class="mb-3">
    {{ $slot }}
  </div>

  {{-- フッター(任意) --}}
  @if (isset($footer))
    <div class="border-t pt-2 text-right">
      {{ $footer }}
    </div>
  @endif
</div>
  • <x-card> タグに囲まれた部分が {{ $slot }} に展開
  • タグ属性で headerfooter スロットを指定可能

3. 色覚特性に配慮したカラーパレットとコントラスト

アクセシビリティ向上のため、WCAG 2.1 レベル AA を満たす コントラスト比(4.5:1以上)を意識しましょう。

色名 HEX コントラスト比 (白背景)
ブルー600 #2563EB 6.8:1
グレー200 #E5E7EB 12.5:1
グリーン600 #059669 7.2:1
  • オンラインツールで自動検証しながら調整
  • ボタンやリンク、テキストの識別性を確保

さらに、ダークモード対応時は反転色も確認し、ARIAの prefers-color-scheme メディアクエリを活用しましょう。


4. ARIA 属性・キーボード操作・スクリーンリーダー対応

4.1 ARIAロールの指定例

{{-- モーダルコンポーネントの一部 --}}
<div role="dialog" aria-modal="true" aria-labelledby="modal-title">
  <h2 id="modal-title">{{ $title }}</h2>
  {{ $slot }}
</div>
  • role="dialog":モーダルであることをスクリーンリーダーに伝達
  • aria-modal="true":背景のコンテンツを無効化
  • aria-labelledby:タイトル要素を関連づけ

4.2 キーボード操作の配慮

  • フォーカストラップ:モーダル内でTabキー移動をループ
  • Escキーで閉じる@keydown.escape でハンドリング
  • 視覚だけでなく操作性も確保しましょう♡

5. 実践サンプル:再利用可能なフォーム入力コンポーネント

{{-- resources/views/components/form/input.blade.php --}}
@props([
  'id',
  'label',
  'type'     => 'text',
  'name'     => $id,
  'value'    => old($id, ''),
  'required' => false,
])

<div class="mb-4">
  <label for="{{ $id }}" class="block text-gray-700 mb-1">
    {{ $label }}
    @if ($required)
      <span aria-hidden="true" class="text-red-500">*</span>
    @endif
  </label>
  <input id="{{ $id }}"
         type="{{ $type }}"
         name="{{ $name }}"
         value="{{ $value }}"
         @if($required) required @endif
         {{ $attributes->merge(['class'=>'w-full border rounded px-3 py-2']) }}
         aria-required="{{ $required }}"
         aria-describedby="{{ $id }}-error">
  @error($name)
    <p id="{{ $id }}-error" class="text-red-600 mt-1" role="alert">
      {{ $message }}
    </p>
  @enderror
</div>
  • required フラグで必須マーク&ARIA属性自動付与
  • aria-describedby でエラーメッセージと連携

6. まとめ・今すぐ試せるチェックリスト

  1. ディレクトリ構成 を整えて一目で把握
  2. Props・Slot で柔軟&型安全にパーツ化
  3. コントラスト比検証 で色覚配慮
  4. ARIA属性・キーボード操作 で包括的なアクセシビリティ
  5. 共通コンポーネント をライブラリ化してチーム内で共有

これらを実践すれば、チーム開発でも安心・安全な UI パーツが作成できます♡
ぜひ今日から自分のプロジェクトに取り入れて、Laravel Blade のパワーを実感してみてくださいね!

投稿者 greeden

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)