`<wa-popover>` のビューポート端マージンをShift Paddingで置き換え
<wa-popover> において、ビューポート端の余白を確保するために使用していたカスタムCSSマージンが shift-padding 属性に置き換えられ、top/bottom-start および top/bottom-end 配置でのポップオーバーとアロー位置ズレのリグレッションが修正されました。
背景
#2379 のモバイル対応修正において、ポップオーバーがビューポート端に近いときに視覚的な余白を確保するため、.body 要素に margin-inline / margin-block を用いたカスタムスタイルが導入されていました。しかし、このアプローチがリグレッションを引き起こしました。top/bottom-start や top/bottom-end のような斜め配置では、余白のためにずらされた .body の位置とアロー(▲)の位置がFloating UI内部で独立して計算されるため、両者が視覚的に乖離する問題が生じていました。
このリグレッションは、#2379のコメント で報告されており、本PRはその修正として作成されています。
技術的な変更
カスタムCSSマージンを削除し、Floating UIが提供する shift-padding 属性を用いてポップオーバーのシフト量を制御するように変更されました。
popover.styles.ts では、配置軸ごとに max-width / max-height と margin-inline / margin-block を設定していた13行のCSSルールセットが丸ごと削除されています。
変更前:
/* Reserve a small visual gap between the popover and the viewport edge on the axis where the popup can shift. */
.popover[data-current-placement^='top'] .body,
.popover[data-current-placement^='bottom'] .body {
max-width: min(var(--max-width), 100vw - (var(--wa-space-m) * 2));
margin-inline: var(--wa-space-m);
}
.popover[data-current-placement^='left'] .body,
.popover[data-current-placement^='right'] .body {
max-height: calc(100vh - (var(--wa-space-m) * 2));
margin-block: var(--wa-space-m);
}
変更後: (当該ルールセットを削除)
一方 popover.ts では、<wa-popup> コンポーネントへの属性として shift-padding="8" が1行追加されています。
変更後:
skidding=${this.skidding}
flip
shift
shift-padding="8"
?arrow=${!this.withoutArrow}
.anchor=${this.anchor}
shift はFloating UIのミドルウェアで、ポップオーバーがビューポートからはみ出さないように要素全体をシフトする処理です。shift-padding はそのシフト計算に使われるビューポート端からの余白値(px)を指定します。これによりシフト計算とアロー位置計算がFloating UIの内部で一貫して行われ、両者がずれなくなります。
設計判断
CSSによる見た目上の制約ではなく、レイアウトエンジン側へのパラメータ渡しという方向で問題が解決されました。
旧来のCSSアプローチは、.body に margin を加えることで視覚的な余白を表現していました。しかしこの手法では、Floating UIがアローの位置を .body の位置とは独立して算出するため、「見た目のポップオーバー位置」と「アローが指す位置」が一致しないという根本的な矛盾が生じます。shift-padding を使えば、シフトの計算時点でビューポート端の余白がFloating UIに伝わるため、アロー位置も含めてレイアウトが整合します。CSS変数(--wa-space-m)を使った動的な幅計算も不要になり、スタイル定義がシンプルになる利点もあります。
まとめ
この修正は、「CSSでレイアウトを調整する」から「レイアウトエンジンに正しい制約を渡す」への設計修正です。Floating UIが提供する shift-padding を正しく活用することで、ポップオーバーとアローの整合性をフレームワーク側に委ね、手動のCSSハックを排除しています。