feat(ui): phone layout with a bottom tab bar and one panel sheet at a time

At 720px and narrower the globe stays full screen and a bottom tab bar (Layers,
Cameras, Context, Search, More) opens one bottom sheet at a time, presenting the
existing rail and dock panels in place. Sheets borrow panels without persisting
or sharing them and put back what they changed. Cockpit, recording and clean
view close the sheet; scene playback keeps STOP reachable. Focus moves into the
sheet and back to its tab, the required attribution stays visible above the
voice control and any sheet, and the page uses safe-area insets. Wider
viewports are unchanged.

Adapted from the phone tab-shell proposed in #203 by @blearymoth.
This commit is contained in:
Sameh Khamis committed 2026-10-22 22:09:37 -07:00
1 parent 224745bd0a
commit fff16f3884
17 files changed
+1405 -20

No files matched your search

+18
View File
@@ -3,6 +3,7 @@ import { ShellFacade } from './shellFacade.js';
import { AircraftDisplay } from './aircraftDisplay.js';
import { LayerBindings } from './layerBindings.js';
import { PanelChrome } from './panelChrome.js';
import { initMobileShell } from './mobileShell.js';
import { VisualSettings } from './visualSettings.js';
import { NavigationController } from './navigationController.js';
import { ShareRestoration } from './shareRestoration.js';
@@ -124,6 +125,8 @@ export class StyleManager extends ShellFacade {
readInitialShare: () => this._initialShareState,
readScrollRestoreOwner: () => this._displayPortalScrollRestoreOwner,
readDisplayScrollTop: () => this._standardDisplayScrollTop,
readSharedCollapsed: (panelId) =>
this._mobileShell?.sharedCollapsed(panelId),
});
this._feedback = new ShellFeedback({
readLayers: () => this._dataManager?.getAll?.() || [],
@@ -587,6 +590,7 @@ export class StyleManager extends ShellFacade {
this._initStreetLevelPanel();
this._initGlobalContextPanel();
this._initLocationBar();
this._initMobileShell();
this._initShareButton();
this._initCameraOrientationControls();
this._initClearSelectedLayersButton();
@@ -848,6 +852,19 @@ export class StyleManager extends ShellFacade {
}
}
/**
* Phone layout: a bottom tab bar presenting one panel sheet at a time
* (src/ui/mobileShell.js). Inactive above 720px.
* @returns {void}
*/
_initMobileShell() {
this._mobileShell = initMobileShell({
setPanelCollapsed: (panelId, collapsed, options) =>
this._panelChrome.setPanelCollapsed(panelId, collapsed, options),
onSheetsClosed: () => this._syncShareState(),
});
}
/**
* Renders the owner-approved map stack chip row from the matching controller
* entries. Cesium ion/Bing chips remain keyboard-focusable but unavailable,
@@ -1707,6 +1724,7 @@ export class StyleManager extends ShellFacade {
this._localePicker?.destroy();
this._localePicker = null;
this._recording.destroy();
this._mobileShell?.destroy();
this._panelChrome.destroy();
this._feedback.destroy();