プロンプトのはみ出しをウィンドウではなくエディタ境界で制御する
エディタがモーダル内に表示される場合、右端付近でプロンプトを開くとウィンドウ幅を基準にしたクリッピング判定が機能せず、ポップオーバーが画面外にはみ出す問題がありました。この修正により、判定基準をウィンドウからエディタ自身の矩形に変更し、プロンプトが常にエディタの範囲内に収まるようになります。
背景
メンションやスラッシュコマンドなどのプロンプトは、入力位置に応じてポップオーバーを表示します。このポップオーバーが右端に近い位置で開かれた際に data-clipped-at-right 属性を付与してレイアウトを調整する仕組みが既に存在していましたが、その判定に window.innerWidth を使用していました。
エディタがページ全体を占める通常のユースケースでは window.innerWidth での判定が概ね機能しますが、モーダルやサイドバーなどエディタがビューポートの一部に配置される場合、エディタの右端よりも先にウィンドウ右端が存在するため、クリッピング判定が実際の表示領域を正しく捉えられていませんでした。結果として、ポップオーバーのアイテムが読み取り不能な状態になっていました。
技術的な変更
変更の核心は src/elements/prompt.js の判定条件を1行変更することです。ポップオーバーの右端が超えてはならない境界を、ウィンドウ幅からエディタ自身の右端座標に切り替えました。
変更前:
if (popoverRect.right > window.innerWidth) {
this.popoverElement.toggleAttribute("data-clipped-at-right", true)
}
変更後:
if (popoverRect.right > editorRect.right) {
this.popoverElement.toggleAttribute("data-clipped-at-right", true)
}
なお、editorRect はこのコードよりも前の処理で getBoundingClientRect() を使って取得済みであり、新たなDOM操作の追加は不要でした。
テストコード(test/browser/tests/prompts/mentions.test.js)も合わせて更新されています。変更前のテストはビューポートサイズ400pxに対してエディタを右寄せで150px幅に設定し、ポップオーバーがビューポート内(rect.right <= 400)に収まることを確認していました。変更後は、エディタを220px幅にしてビューポート端との余白を確保したうえで、ポップオーバーの境界が エディタの境界(editorRect.right / editorRect.left)に対して収まっているかを検証するよう変更されました。テストのタイトルも "popover stays within viewport" から "popover stays within the editor" へと修正され、意図が明確になっています。
設計判断
「コンテナを基準にする」 というアプローチは、エディタをどの文脈に埋め込んでも正しく機能するという点で汎用性が高い判断です。ウィンドウ幅を基準にする実装はエディタがフルページで表示される前提を暗黙的に持っており、モーダルやパネルへの埋め込みを想定した設計ではありませんでした。editorRect.right を使うことで、エディタ自身が自分のレイアウトコンテキストを参照するようになり、外部の状態(ウィンドウサイズ)への依存が排除されます。
この変更は1行の差分でありながら、テストの検証対象も「ビューポート」から「エディタ」へと整合性が取れており、修正の意図が実装・テスト・テスト名の3箇所すべてに一貫して反映されています。
まとめ
クリッピング判定の基準を window.innerWidth から editorRect.right へ変更したことで、モーダルやパネルなどあらゆる埋め込みコンテキストでプロンプトが正しくエディタ内に収まるようになります。「自分のコンテナを基準にする」という単純な原則の適用が、埋め込みユースケース全般の堅牢性を高めています。