`<wa-textarea>` の無効状態スタイリングを他フォームコントロールと統一
<wa-textarea> の disabled 状態に視覚的スタイルが適用されていなかったバグを修正し、<wa-input> や <wa-select> など他のフォームコントロールと同等の外観を実現しました。
背景
<wa-textarea> を disabled 属性で無効化しても、有効な状態と見た目が変わらないというバグが #2416 で報告されていました。他のフォームコントロールでは無効状態に明確な視覚的フィードバック(半透明表示やカーソル変更)が適用されているにもかかわらず、<wa-textarea> だけがその一貫性から外れていました。
ユーザーはフォームの送信可否やフィールドの操作可否をUIの見た目から判断します。無効フィールドが有効フィールドと区別できない状態は、アクセシビリティおよびユーザビリティ上の問題です。Issue では cursor: not-allowed の欠如と視覚的差異のなさが具体的に指摘されており、Firefox / Ubuntu 環境で確認されています。
技術的な変更
textarea.styles.ts に2か所の CSS 変更が加えられました。変更はいずれも既存のスタイル構造に自然に統合されており、影響範囲は <wa-textarea> コンポーネントのスタイルに限定されます。
1つ目は、コンテナ要素への :has(:disabled) セレクタの追加です。ラッパー要素に対して opacity と cursor を適用することで、Shadow DOM 内部の <textarea> 要素が disabled になったときにコンポーネント全体の外観を制御します。
変更前:
&:focus-within {
outline-color: var(--wa-color-focus);
}
変更後:
&:focus-within {
outline-color: var(--wa-color-focus);
}
/* Style disabled textareas */
&:has(:disabled) {
cursor: not-allowed;
opacity: 0.5;
}
2つ目は、<textarea> 要素自体に cursor: inherit を追加する変更です。コンテナ側で設定した cursor: not-allowed を内側の <textarea> 要素が継承できるよう、明示的に inherit を指定しています。
変更後:
background: transparent;
font: inherit;
color: inherit;
cursor: inherit; /* 追加 */
padding: calc(var(--wa-form-control-padding-block) - ((1lh - 1em) / 2)) var(--wa-form-control-padding-inline);
この2段階の構成により、コンテナで not-allowed を宣言し、内側の <textarea> がそれを継承することで、コンポーネント全体にわたって一貫したカーソル表示が実現されます。
設計判断
:has(:disabled) セレクタをコンテナ側に適用する方式 が採用されました。<wa-textarea> は Shadow DOM を持つ Web Components であり、実際の <textarea> 要素はシャドウルート内に存在します。コンテナ側で :has(:disabled) を使うことで、内部の disabled 状態をコンポーネント全体のスタイルに反映できます。
opacity: 0.5 と cursor: not-allowed という値の選択は、他のフォームコントロール(<wa-input> など)との視覚的一貫性を意図したものです。コンポーネント間でスタイルの語彙を統一することは、デザインシステムの保守性に直結します。
また、cursor: inherit を <textarea> に追加しない場合、ブラウザのデフォルトスタイルがコンテナの cursor 指定を上書きしてしまうため、この記述は省略できません。コンテナと内部要素の2点でスタイルを協調させることで、Shadow DOM を跨いだプロパティの伝播を確実にしています。
まとめ
:has(:disabled) と cursor: inherit の組み合わせにより、Shadow DOM を持つ Web Components でもコンテナ起点でコンポーネント全体の無効状態を制御できることが示されました。この修正により、Web Awesome のフォームコントロール群における視覚的一貫性が回復し、disabled 状態のアフォーダンスが他コンポーネントと揃いました。