リンクボタンのdisabled処理をinert属性からイベント制御へ変更
Web Awesomeの<wa-button>コンポーネントにおいて、リンク型ボタン(href属性を持つボタン)の無効化処理がinert属性の使用からクリックイベントの制御へと変更されました。この変更により、disabled状態のリンクボタンが確実にクリック不可となります。
背景
<wa-button>コンポーネントはボタン型とリンク型の両方をサポートしていますが、通常のボタン要素とは異なり、アンカー要素(<a>)には標準のdisabled属性が存在しません。#1848では、リンク型ボタンを無効化する機能が実装され、その実装ではinert属性が採用されていました。
本PRは、このinert属性による実装をrevertし、クリックイベントを直接防ぐ方法へと変更しています。PRタイトルに「Revert inert」と明記されているように、以前の実装方法からの方針転換が行われました。
技術的な変更
handleClickメソッドの先頭に、disabled状態とloading状態のチェック処理が追加されました。
変更前:
private handleClick() {
// Only create a light dom button for submit / reset buttons.
if (this.type !== 'submit' && this.type !== 'reset') {
return;
}
変更後:
private handleClick(event: PointerEvent) {
// Prevent disabled and loading buttons from being clicked
if (this.disabled || this.loading) {
event.preventDefault();
event.stopImmediatePropagation();
return;
}
// Only create a light dom button for submit / reset buttons.
if (this.type !== 'submit' && this.type !== 'reset') {
return;
}
テンプレート部分では、inert属性の条件付き設定が削除され、aria-disabled属性の設定もリンク型かつdisabled状態の場合のみに限定されました。
変更前:
?disabled=${ifDefined(isLink ? undefined : this.disabled)}
?inert=${ifDefined(isLink ? this.disabled : undefined)}
aria-disabled=${this.disabled ? 'true' : 'false'}
変更後:
?disabled=${ifDefined(isLink ? undefined : this.disabled)}
aria-disabled=${ifDefined(isLink && this.disabled ? 'true' : undefined)}
ボタン型要素の場合は引き続き標準のdisabled属性が使用され、リンク型要素の場合はイベントハンドラでクリックを防ぎます。
設計判断
イベントレベルでのクリック防止が選択されました。event.preventDefault()とevent.stopImmediatePropagation()による制御は、クリックイベントのみをターゲットとした限定的な処理です。stopImmediatePropagation()の使用により、同じ要素に登録された他のイベントリスナーも実行されなくなるため、disabled状態の一貫性が保証されます。
aria-disabled属性の設定もifDefinedを使用してリンク型かつdisabled状態の場合のみに限定することで、ボタン型要素では標準のdisabled属性による暗黙的なARIAサポートを活用し、属性の重複を避ける判断がなされています。この変更により、ボタン型とリンク型で異なるアプローチを取りつつ、両者で一貫したdisabled状態の実現を目指しています。
まとめ
本PRは、リンク型ボタンの無効化処理をinert属性からイベント制御へと変更することで、より予測可能な動作を実現しています。event.preventDefault()とevent.stopImmediatePropagation()の組み合わせにより、disabled状態のリンクボタンが確実にクリック不可となり、loading状態も同様に処理されます。ARIA属性の最適化も併せて行われ、標準のHTML要素の振る舞いとの一貫性が向上しています。