Segmented Field Picker のトレーリングアイコンを軸揃えにした共通スタイル導入

shoelace-style/webawesome

リード文<wa-time-input><wa-date-input> のクリア・展開ボタンが他のフォームコントロールと垂直軸で揃っていなかった問題を、共通スタイルモジュール segmented-field.styles.ts に集約して解決しました。この変更により、ボタンのヒット領域とフォーカスリングは維持しつつ、全ピッカーが同一のトレーリング軸に収まります。

背景

<wa-time-input> の時計トグルとクリアボタンは従来、個別に微調整されており、<wa-select> のチェブロンや <wa-input> のエンドスロットアイコンと比較して数ピクセル内側に位置していました。 その結果、同一行に混在させたときに右端がわずかにずれるという UI の不整合が発生していました。

この視覚的ずれは、ユーザーが複数のフォームコントロールを横並びで使用するシナリオで特に顕在化し、デザインの一貫性が損なわれる要因となっていました。 PR #2543 ではこの問題を根本的に解消し、フォーム全体の統一感を高めることが目的です。

結論として、トレーリング側の揃えを設計要件に据えることで、見た目の統一感が得られ、開発者は個別のピクセル調整から解放されます。

技術的な変更

新規追加された共通スタイルモジュール **segmented-field.styles.ts が、クリア・展開ボタンと開始/終了デコレーションスロットのレイアウトを一元管理します。** 主要な実装は以下の通りです。

+export default css`
+  /* ボタンは 0.25rem のパディングを保持し、マイナスのマージンでトレーリング端にオーバーハングさせます */
+  [part~='clear-button'],
+  [part~='expand-button'] {
+    flex: 0 0 auto;
+    display: inline-flex;
+    align-items: center;
+    justify-content: center;
+    background: transparent;
+    border: none;
+    cursor: pointer;
+    color: var(--wa-color-text-quiet);
+    font: inherit;
+    padding: 0.25em;
+    margin-inline-end: -0.25em;
+    border-radius: var(--wa-border-radius-s);
+    transition: color var(--wa-transition-fast);
+  }
+
+  /* 固定幅でアイコンを中央揃えし、スロット幅に依存しない軸揃えを実現 */
+  [part~='expand-button'] {
+    inline-size: 1.75em; /* expand glyph (1.25em) + 2×0.25em padding */
+    margin-inline-start: calc(var(--wa-form-control-padding-inline) - 0.125em);
+  }
+`;

このモジュールは、各ボタンに固定 **inline-size(expand: 1.75 em、clear: 1.5 em)を設定し、margin-inline-end: -0.25em によってパディングがトレーリング端にオーバーハングする設計です。** さらに --wa-form-control-padding-inline トークンに基づく間隔調整により、テーマやサイズ変更に対しても自動的に適応します。

<wa-time-input> コンポーネントはこのスタイルを組み込み、個別のボタン定義を削除しました。 具体的にはインポートと CSS 配列への追加が行われています。

@@
-import formControlStyles from '../../styles/component/form-control.styles.js';
+import formControlStyles from '../../styles/component/form-control.styles.js';
+import segmentedFieldStyles from '../../styles/component/segmented-field.styles.js';
@@
-  static css = [sizeStyles, formControlStyles, styles];
+  static css = [sizeStyles, formControlStyles, segmentedFieldStyles, styles];

time-input.styles.ts からは従来のボタンスタイルが削除され、代わりに共通モジュールへの参照コメントが残されています。 これにより重複実装が排除され、保守性が向上します。

@@
-  .clear-button,
-  .expand-button {
-    /* 従来の個別スタイル */
-    ...
-  }
+  /* Trailing buttons (.clear-button, .expand-button) と start/end スロットは
+     segmentedFieldStyles で共通化され、<wa-select> のトレーリング軸に合わせます */

視覚的揃えが壊れないことを保証するテストが追加されました。 iconCenterFromRight ヘルパーで対象アイコンの中心座標を取得し、<wa-select> の同軸アイコンと 2 px 未満の差で比較しています。

@@
+    const expandDelta = Math.abs(
+      iconCenterFromRight(time, '[part~="expand-icon"]') -
+      iconCenterFromRight(select, '[part~="expand-icon"]'),
+    );
+    const clearDelta = Math.abs(
+      iconCenterFromRight(time, '[part~="clear-button"]') -
+      iconCenterFromRight(select, '[part~="clear-button"]'),
+    );
+
+    expect(expandDelta, 'expand icon is off the select trailing axis').to.be.lessThan(2);
+    expect(clearDelta, 'clear button is off the select trailing axis').to.be.lessThan(2);

これらのテストは、<wa-select><wa-input> を基準(アンカー)とし、将来的なレイアウト変更が軸を逸脱しないようガードしています。

設計判断

トレーリングアフォーダンスのスタイルを共通モジュールに集約したことは、重複実装を排除し UI 整合性を強化する明確な設計選択です。 同一モジュールが <wa-time-input><wa-date-input> の両方で使用され、プロジェクト全体で一貫した配置が保証されます。

軸の基準を <wa-select><wa-input> に固定した点は、これらを「視覚的アンカー」として扱う設計判断を示しています。 テストでアンカーを比較対象とすることで、レイアウト回帰が自動的に検出される仕組みが導入されています。

結果として、UI の一貫性とコードベースの可読性・保守性が同時に向上し、将来的なテーマ追加やサイズ変更にも安定して対応できる基盤が整いました。

まとめ

本 PR は segmented-field.styles.ts にトレーリングボタンの共通レイアウトを実装し、<wa-time-input><wa-date-input> のアイコンを <wa-select><wa-input> と同一軸に揃えました。重複スタイルの除去とテストガードにより、見た目のずれが再発しない設計となり、テーマやサイズに依存しない安定した UI が提供されます。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
4bd840f4

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

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

リード文、背景、技術的な変更、設計判断、まとめの全てが揃っており、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ✓ PASS

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

コードブロックは ``言語:ファイルパス`` 形式で正しく記述され、PRリンクも ``[#2543](URL)`` で正しくハイパーリンク化されています。

対象読者への適合性 ✓ PASS

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

専門的な UI コンポーネントの実装内容で、余計な初心者向け説明はなく、エンジニアに適したレベルです。

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

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

各セクションは総論パラグラフ→各論パラグラフ→結論パラグラフの構成で、段落はトピックセンテンスで始まり、1段落1トピック・6文以内に収まっています。空行で区切られている点も良好です。

Diff内容との照合 ⚠ WARNING

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

記事内の ``segmented-field.styles.ts`` コードブロックは Diff の主要部分(import 文や冒頭コメント)を省略しています。重要なロジックは一致していますが、完全な照合ができないため警告とします。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている用語(inline-size、margin-inline-end、part etc.)は PR と一致しており、誤用はありません。

説明の技術的正確性 ✓ PASS

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

技術的な主張はすべて PR の説明や Diff の変更点と整合しており、根拠が示されています。

事実の突合 ✓ PASS

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

記事の主張は PR のタイトル・説明・Diff に裏付けられており、外部知識の捏造や推測はありません。

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

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

inline-size の数値(1.75 em、1.5 em)やマージン値は PR の記載と合致しています。

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

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

記事タイトルは PR タイトル「Align Segmented-Field Picker Trailing Icons」の意味を日本語で適切に表現しています。

外部知識の正確性 ✓ PASS

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

バージョン情報やリリース予定等、PR に記載されていない外部知識は含まれていません。

時間表現の正確性 ✓ PASS

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

時間表現の歪曲はなく、PR の記述と一致しています。