ui:tabs
汎用的なTabsコンポーネントです。
- Web Component (
<ui-tabs>) として提供しています。 - WAI-ARIA Authoring Practices の Tabs Pattern に準拠しています。
Examples
Section titled “Examples”Default (with URL hash sync)
Section titled “Default (with URL hash sync)”<a href="#key"> で書くと URL に状態が反映され、#account 等のリンクで直接開けます。
Source Code
<ui-tabs class="ui:tabs" aria-label="アカウント設定"> <div class="ui:tabs__list"> <a class="ui:tabs__tab" href="#profile">プロフィール</a> <a class="ui:tabs__tab" href="#account">アカウント</a> <a class="ui:tabs__tab" href="#notifications">通知</a> </div> <div class="ui:tabs__panel" id="profile"> <p>プロフィール情報を編集できます。</p> </div> <div class="ui:tabs__panel" id="account" hidden> <p>アカウント情報の設定です。</p> </div> <div class="ui:tabs__panel" id="notifications" hidden> <p>通知の設定です。</p> </div></ui-tabs>Without URL hash (button)
Section titled “Without URL hash (button)”URL を汚したくない場面(モーダル内のタブ等)では <button> を使います。
Source Code
<ui-tabs class="ui:tabs" aria-label="ローカル状態のタブ"> <div class="ui:tabs__list"> <button class="ui:tabs__tab" data-href="#local-one">Tab 1</button> <button class="ui:tabs__tab" data-href="#local-two">Tab 2</button> <button class="ui:tabs__tab" data-href="#local-three">Tab 3</button> </div> <div class="ui:tabs__panel" id="local-one"> <p>Tab 1 のコンテンツ (URLは変わりません)</p> </div> <div class="ui:tabs__panel" id="local-two" hidden> <p>Tab 2 のコンテンツ</p> </div> <div class="ui:tabs__panel" id="local-three" hidden> <p>Tab 3 のコンテンツ</p> </div></ui-tabs>Manual Activation
Section titled “Manual Activation”矢印キーでフォーカスのみ移動し、
Source Code
<ui-tabs class="ui:tabs" data-activation="manual" aria-label="Manual activation"> <div class="ui:tabs__list"> <a class="ui:tabs__tab" href="#manual-one">Tab 1</a> <a class="ui:tabs__tab" href="#manual-two">Tab 2</a> <a class="ui:tabs__tab" href="#manual-three">Tab 3</a> </div> <div class="ui:tabs__panel" id="manual-one"> <p>Tab 1 のコンテンツ</p> </div> <div class="ui:tabs__panel" id="manual-two" hidden> <p>Tab 2 のコンテンツ</p> </div> <div class="ui:tabs__panel" id="manual-three" hidden> <p>Tab 3 のコンテンツ</p> </div></ui-tabs>Source Code
<ui-tabs class="ui:tabs" data-size="small" aria-label="小サイズ例"> <div class="ui:tabs__list"> <a class="ui:tabs__tab" href="#small-one">Tab 1</a> <a class="ui:tabs__tab" href="#small-two">Tab 2</a> <a class="ui:tabs__tab" href="#small-three">Tab 3</a> </div> <div class="ui:tabs__panel" id="small-one"> <p>Small Tab 1 のコンテンツ</p> </div> <div class="ui:tabs__panel" id="small-two" hidden> <p>Small Tab 2 のコンテンツ</p> </div> <div class="ui:tabs__panel" id="small-three" hidden> <p>Small Tab 3 のコンテンツ</p> </div></ui-tabs>Disabled Tab
Section titled “Disabled Tab”Source Code
<ui-tabs class="ui:tabs" aria-label="無効化されたタブを含む例"> <div class="ui:tabs__list"> <a class="ui:tabs__tab" href="#disabled-one">Tab 1</a> <a class="ui:tabs__tab" href="#disabled-two" aria-disabled="true">Tab 2 (無効)</a> <a class="ui:tabs__tab" href="#disabled-three">Tab 3</a> </div> <div class="ui:tabs__panel" id="disabled-one"> <p>Tab 1 のコンテンツ</p> </div> <div class="ui:tabs__panel" id="disabled-two" hidden> <p>Tab 2 のコンテンツ</p> </div> <div class="ui:tabs__panel" id="disabled-three" hidden> <p>Tab 3 のコンテンツ</p> </div></ui-tabs>Variants
Section titled “Variants”| 属性 | 要素 | 値 | 効果 |
|---|---|---|---|
data-size | root | small | サイズ指定 |
data-activation | root | manual | フォーカス移動とアクティブ化を分離(Enter/Space で確定) |
aria-disabled | <a>.ui:tabs__tab | true | タブを無効化(キーボード移動からもスキップ) |
disabled | <button>.ui:tabs__tab | - | タブを無効化(キーボード移動からもスキップ) |
Keyboard Controll
Section titled “Keyboard Controll”| キー | 動作 |
|---|---|
| タブリストに入る / 出る | |
| 前後のタブへ移動 + パネルアクティブ化 | |
| 最初 / 最後のタブへ移動 | |
| パネルアクティブ化(Manual Activationのときのみ) |
Behavior
Section titled “Behavior”初期表示パネルのコントロール
Section titled “初期表示パネルのコントロール”初期表示しないパネル
Section titled “初期表示しないパネル”初期表示しないパネル には、hidden を付けます(FOUC・No-JS対策)。JS が自動で hidden="until-found" に昇格させます。ブラウザのページ内検索(
初期表示パネルの優先度
Section titled “初期表示パネルの優先度”- URL hash にマッチするタブ
- 最初の
hiddenでないパネル - 最初のタブ
URL Hash 同期
Section titled “URL Hash 同期”タブを <a href="#{key}"> で書いた場合のみ、URL hash と双方向に同期します。
パネルの id がそのまま hash になるので、#{panel-id} で外部からも直接開けます。
- 初期表示:
location.hashがパネルのidとマッチすればそのタブが開く(hiddenよりも優先)。初期表示がhash由来の場合は対象パネルをscrollIntoViewでビューに送ります。 - クリック / キーボード遷移:
history.replaceStateで URL が更新される(履歴を汚さない) - 戻る / 進む: 各
<ui-tabs>インスタンスがhashchangeを購読しており、対応するタブを自動で開く Command Cmd Control Ctrl /Shift Shift Shift Shift + クリック: デフォルト動作を尊重(別タブで開く等)。遷移先ページでも該当タブが開く
<button> で書いた場合は一切 URL を変更しません。
Progressive Enhancement
Section titled “Progressive Enhancement”<ui-tabs> は Light DOM の Web Component です。Shadow DOM を使わないため、JS がロードされる前でも中のマークアップは通常通りレンダリングされます。
ブラウザは未定義のカスタム要素を HTMLUnknownElement として扱うため、<ui-tabs> 自体はパース時に存在し、Web Componentsライフサイクル管理(接続 / 切断)はブラウザが自動的に行います。
Custom Events
Section titled “Custom Events”| イベント | 発火元 | cancelable | bubbles | detail |
|---|---|---|---|---|
ui-tabs:change | <ui-tabs> | ❌ | ✅ | TabsChangeDetail |
ui-tabs:change
Section titled “ui-tabs:change”import type { TabsChangeDetail } from "@packages/ui/tabs";
document.addEventListener("ui-tabs:change", (e) => { const { key, previousKey, $tab, $panel } = e.detail; console.log(`tab "${previousKey}" → "${key}"`);});TabsChangeDetail
Section titled “TabsChangeDetail”| プロパティ | 型 | 説明 |
|---|---|---|
key | string | 新しくアクティブになったタブの key (panel の id) |
previousKey | string | null | 直前にアクティブだったタブの key (無い場合 null) |
$tab | HTMLElement | 新しくアクティブになったタブ要素 |
$panel | HTMLElement | 対応するパネル要素 |
発火タイミング
Section titled “発火タイミング”| 操作 | 発火 |
|---|---|
| クリック / Enter / Space | ✅ |
| 矢印キーで auto activation | ✅ |
| ブラウザのページ内検索でマッチ | ✅ |
| URL hash の戻る / 進む / 直接遷移 | ✅ |
| 同じタブを再アクティブ化 | ❌ |
| 初期化 (connectedCallback) | ❌ |
| Manual mode の矢印キー (focus のみ) | ❌ |