`wa-input`の`withoutSpinButtons`プロパティにリフレクションを追加
wa-inputコンポーネントのwithoutSpinButtonsプロパティにreflect: trueを追加し、プロパティバインディングが正しく機能するよう修正しました。
背景
withoutSpinButtons プロパティはHTMLAttributeへのリフレクションが設定されていなかったため、プロパティバインディングで値を変更してもDOM属性に反映されず、CSSセレクターやJavaScriptからの属性参照が機能しない問題がありました。Web Componentsでは、プロパティとHTML属性は独立した概念であり、reflect: trueを指定しない限り、プロパティへの変更はDOM属性に自動的に同期されません。
この問題は、各種JavaScriptフレームワークのプロパティバインディング構文を使用してwithoutSpinButtonsを動的に制御しようとした際に顕在化します。バインディングによってプロパティは更新されますが、対応するHTML属性without-spin-buttonsがDOMに現れないため、属性の有無に依存した処理が期待通りに動作しません。
技術的な変更
input.tsのwithoutSpinButtonsプロパティデコレーターにreflect: trueオプションを追加する1行の修正です。
変更前:
@property({ attribute: 'without-spin-buttons', type: Boolean }) withoutSpinButtons = false;
変更後:
@property({ attribute: 'without-spin-buttons', type: Boolean, reflect: true }) withoutSpinButtons = false;
この変更により、element.withoutSpinButtons = trueのようにJavaScriptからプロパティを設定した場合でも、DOM上の<wa-input>要素にwithout-spin-buttons属性が付与されるようになります。なお、同ファイル内のrequiredプロパティはすでにreflect: trueが設定されており、今回の修正はwithoutSpinButtonsを同等の挙動に揃えるものです。
設計判断
Boolean属性のリフレクション は、Lit(WebAwesomeが採用するWebコンポーネントライブラリ)においてプロパティと属性の双方向同期を実現する標準的なパターンです。
今回の修正が必要になった背景には、コンポーネント設計における一貫性の問題があります。同じコンポーネント内でもrequiredはリフレクションあり、withoutSpinButtonsはリフレクションなし、という状態が存在していました。特にスピンボタンの表示制御はCSSの[without-spin-buttons]属性セレクターで実装されていることが想定されるため、プロパティバインディング経由での変更がレンダリングに反映されないという実害が生じやすい箇所です。
まとめ
1文字のreflect: true追加ですが、この修正によってプロパティバインディングとDOM属性の一貫性が確保され、フレームワーク統合時の予期しない挙動が解消されます。コンポーネントライブラリの品質において、プロパティとHTML属性のリフレクション設計の一貫性がいかに重要かを示す好例です。