ツールバーのオーバーフロー制御に「固定ボタン」機能を追加
data-prevent-overflow="true" 属性を持つボタンは、ツールバーが幅不足でオーバーフローしても常にツールバー本体に残留するようになりました。モバイル環境でも添付ファイルボタンが常時アクセス可能になります。
背景
ツールバーが狭い画面幅に収まらない場合、lexxy-toolbar はボタンをオーバーフローメニューへ移動する「オーバーフロー機構」を持っています。しかし、アクション種別に関わらず全ボタンが移動対象になっていたため、モバイル環境で「添付ファイルのアップロード」のような頻繁に使われる重要なボタンがオーバーフローメニューの奥に隠れてしまうケースがありました。
PR本文では「Attachments button is one of the most important actions on mobile」として、この問題が明示されています。
技術的な変更
src/elements/toolbar.js の #buttons ゲッター にセレクタの除外条件を追加することで、オーバーフロー移動の対象から特定ボタンを除外できるようになりました。
変更箇所は #buttons ゲッターのクエリセレクタ1行のみです。
変更前:
get #buttons() {
return Array.from(this.querySelectorAll(":scope > button"))
}
変更後:
get #buttons() {
return Array.from(this.querySelectorAll(":scope > button:not([data-prevent-overflow='true'])"))
}
このゲッターがオーバーフロー発生時に「移動対象として取り出すボタンのリスト」を返しているため、:not([data-prevent-overflow='true']) を追加するだけで、当該属性を持つボタンは移動対象から自動的に除外されます。
あわせて、添付ファイルボタン(name="upload")に data-prevent-overflow="true" が付与されました。
変更後のボタン定義:
<button class="lexxy-editor__toolbar-button" type="button" name="upload"
data-command="uploadAttachments"
data-prevent-overflow="true"
title="Upload file">
${ToolbarIcons.attachment}
</button>
設計判断
HTMLデータ属性によるオプトイン方式 が採用されました。JavaScriptコード側でボタン名をハードコードして除外リストを持つのではなく、マークアップ側で data-prevent-overflow="true" を付与するだけで固定化できるため、将来的に他のボタンにも同じ振る舞いを適用しやすい設計です。
オーバーフロー対象のリストアップを :not(...) セレクタで表現していることも特徴的です。「除外したいものを除外する」という記述になっており、デフォルトはすべてのボタンが移動対象という方針を維持しつつ、例外をマークアップで宣言的に表現しています。
テストの追加
test/browser/tests/formatting/toolbar.test.js に "overflow compaction keeps upload button visible" テストが追加されました。ビューポート幅を300pxに縮小してオーバーフロー状態を発生させ、以下を検証します:
- アップロードボタンがツールバーに残留していること(
toBeVisible()・toHaveCount(1)) - オーバーフローメニュー内にアップロードボタンが存在しないこと(
toHaveCount(0)) - アップロードボタンがクリック可能な状態であること(
toBeEnabled()) - ビューポートを元に戻すとオーバーフロー状態が解消されること
ビューポートサイズの動的変更でオーバーフロー状態を再現するアプローチにより、実際のモバイル利用シナリオに即したE2Eテストになっています。
まとめ
data-prevent-overflow="true" というHTMLデータ属性を1つ追加するだけで、ボタンをオーバーフロー移動から除外できる仕組みが導入されました。JavaScriptロジックへの変更を最小限に抑えつつ、マークアップ側の宣言で挙動を制御できる拡張性の高い設計です。