リンクボタンに disabled 属性のサポートを追加

shoelace-style/webawesome

Web Awesome のボタンコンポーネントにおいて、リンク(<a> 要素)として描画されるボタンが disabled 属性を正しく処理できるようになりました。これにより、ボタンタイプに関わらず一貫した無効化の挙動が実装されています。

背景

これまで <wa-button> コンポーネントでは、href 属性を指定してリンクとして機能させた場合、disabled 属性が実質的に無視されていました。#106 で報告されているように、リンクボタンは disabled 状態でもクリック可能な状態のままでした。

HTML 標準では <a> 要素に disabled 属性が存在しないため、ボタン(<button> 要素)とリンク(<a> 要素)で異なる無効化の実装が必要です。この制約により、両者で一貫した disabled の挙動を提供することが課題となっていました。

技術的な変更

inert 属性の活用により、リンクボタンの無効化を実現しています。button.ts では、<a> 要素として描画される場合に inert 属性を設定するようになりました。

変更前:

?disabled=${ifDefined(isLink ? undefined : this.disabled)}

変更後:

?disabled=${ifDefined(isLink ? undefined : this.disabled)}
?inert=${ifDefined(isLink ? this.disabled : undefined)}

inert 属性は HTML 標準の機能で、要素をインタラクティブでない状態にします。リンクの場合は inert を、ボタンの場合は従来通り disabled を使用することで、要素タイプによらず無効化が機能します。

スタイル定義も、クラスセレクタから属性セレクタベースに変更されました。button.styles.ts では、.button.disabled から :host([disabled]) へ移行しています。

変更前:

.button.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.button.disabled * {
  pointer-events: none;
}

変更後:

:host([disabled]) {
  opacity: 0.5;
  cursor: not-allowed;

  .button {
    pointer-events: none;
  }
}

ホスト要素の disabled 属性を直接参照することで、内部の要素タイプ(<button> または <a>)に関わらず統一されたスタイリングが適用されます。

設計判断

ホストレベルでの無効化という設計が採用されました。

PR では、disabled 状態のスタイリングを .button クラスではなく :host([disabled]) で制御する方式に変更されています。この判断により、コンポーネントの disabled 属性が shadow DOM 内の要素タイプに依存しない形で機能するようになりました。

inert 属性の選択も重要な設計判断です。aria-disabledtabindex="-1" といった代替手段も存在しますが、inert はフォーカス不可・クリック不可・スクリーンリーダーからの除外を一度に実現できる点で、より宣言的なアプローチとなっています。

ドキュメントには、リンクボタンの無効化例が追加されました。通常のリンク、新規ウィンドウで開くリンク、ダウンロードリンクの3パターンが示されており、すべてのリンクタイプで disabled が機能することを明示しています。

まとめ

本 PR は、inert 属性を活用してリンクボタンの無効化を実現した変更です。要素タイプに応じた適切な無効化手段(<button> には disabled<a> には inert)を使い分けることで、ボタンコンポーネントの API を変更せずに一貫した挙動を提供しています。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「総論→各論→結論」の構成が記事全体とセクションの両方で明確に適用されています。リード文、背景、技術詳細、設計判断、まとめの各要素が適切に配置されています。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```言語:ファイルパス)とGitHubリンク記法([#123](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

WebコンポーネントやHTML/CSSの知識を持つエンジニアを対象としており、専門用語のレベルや説明の粒度が適切です。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論から始まり、各段落はトピックセンテンスで開始されています。1段落1トピックの原則と適切な段落長が守られており、非常に読みやすい構成です。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のコードブロックは、提供されたDiffの内容を正確に反映しています。変更前後のコード引用が適切で、ファイルパスも一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`inert`属性、`:host`セレクタ、shadow DOMなど、関連する技術用語が正確かつ適切な文脈で使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

「`inert`属性によるリンクボタンの無効化」「ホスト要素の`disabled`属性を利用したスタイリング」など、技術的な変更点に関する説明はDiffの内容と整合しており、論理的かつ正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張は、PRのタイトル、Description、Diff内のコード変更によって裏付けられています。根拠のない推測や憶測は見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#1848)およびIssue番号(#106)が正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトル「リンクボタンに disabled 属性のサポートを追加」は、PRのタイトル「Support disabled link buttons」の内容を正確に反映しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

「設計判断」セクションでの`inert`属性の代替手段(`aria-disabled`等)に関する言及はPR外の知識ですが、変更の意図を明確にするための妥当な補足説明であり、捏造ではありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「これまで...無視されていた」といった時間表現は、PRが修正であるという事実と一致しており、正確です。