コンテンツにスキップ

ui:tabs

汎用的なTabsコンポーネントです。

  • Web Component (<ui-tabs>) として提供しています。
  • WAI-ARIA Authoring Practices の Tabs Pattern に準拠しています。

<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>

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>

矢印キーでフォーカスのみ移動し、 Enter Enter / Space Space でアクティブ化します。 パネル切替が高コスト(ネットワーク呼び出し等)な場合に有効です。

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>
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>
属性要素効果
data-sizerootsmallサイズ指定
data-activationrootmanualフォーカス移動とアクティブ化を分離(Enter/Space で確定)
aria-disabled<a>.ui:tabs__tabtrueタブを無効化(キーボード移動からもスキップ)
disabled<button>.ui:tabs__tab-タブを無効化(キーボード移動からもスキップ)
キー動作
Tab Tab タブリストに入る / 出る
Left Arrow Left Arrow / Right Arrow Right Arrow 前後のタブへ移動 + パネルアクティブ化
Home Home / End End 最初 / 最後のタブへ移動
Enter Enter / Space Space パネルアクティブ化(Manual Activationのときのみ)

初期表示パネルのコントロール

Section titled “初期表示パネルのコントロール”

初期表示しないパネル には、hidden を付けます(FOUC・No-JS対策)。JS が自動で hidden="until-found" に昇格させます。ブラウザのページ内検索( Command + F Control + F )でマッチした場合、対応するタブが自動で開きます。

  1. URL hash にマッチするタブ
  2. 最初の hidden でないパネル
  3. 最初のタブ

タブを <a href="#{key}"> で書いた場合のみ、URL hash と双方向に同期します。 パネルの id がそのまま hash になるので、#{panel-id} で外部からも直接開けます。

  • 初期表示: location.hash がパネルの id とマッチすればそのタブが開く(hidden よりも優先)。初期表示が hash 由来の場合は対象パネルを scrollIntoView でビューに送ります。
  • クリック / キーボード遷移: history.replaceState で URL が更新される(履歴を汚さない)
  • 戻る / 進む: 各 <ui-tabs> インスタンスが hashchange を購読しており、対応するタブを自動で開く
  • Command Control / Shift Shift + クリック: デフォルト動作を尊重(別タブで開く等)。遷移先ページでも該当タブが開く

<button> で書いた場合は一切 URL を変更しません。

<ui-tabs> は Light DOM の Web Component です。Shadow DOM を使わないため、JS がロードされる前でも中のマークアップは通常通りレンダリングされます。

ブラウザは未定義のカスタム要素を HTMLUnknownElement として扱うため、<ui-tabs> 自体はパース時に存在し、Web Componentsライフサイクル管理(接続 / 切断)はブラウザが自動的に行います。

イベント発火元cancelablebubblesdetail
ui-tabs:change<ui-tabs>TabsChangeDetail
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}"`);
});
プロパティ説明
keystring新しくアクティブになったタブの key (panel の id)
previousKeystring | null直前にアクティブだったタブの key (無い場合 null)
$tabHTMLElement新しくアクティブになったタブ要素
$panelHTMLElement対応するパネル要素
操作発火
クリック / Enter / Space
矢印キーで auto activation
ブラウザのページ内検索でマッチ
URL hash の戻る / 進む / 直接遷移
同じタブを再アクティブ化
初期化 (connectedCallback)
Manual mode の矢印キー (focus のみ)