Appearance
Dashboard viewport contract
Platform-wide rules so dashboards render correctly on phone, tablet, and desktop.
Source of truth
DashboardViewportProvider (frontend/src/features/dashboards/context/DashboardViewportContext.tsx) owns the canvas ([data-dashboard-surface]) and classifies width:
| Mode | Canvas width | Layout |
|---|---|---|
phone | ≤ 640px | Full-width stack |
tablet | ≤ 1240px | Full-width stack |
desktop | > 1240px | 48-col grid |
Hooks:
useDashboardViewport()→mode,isStacked,isDesktop, …useDashboardCompact()→ alias ofisStacked(legacy)useWidgetMobileLayout()→ body helpers for stack vs grid
Shell rules (WidgetContainer)
- Stacked: auto height, overflow visible (prefer one page scroll; avoid nested scrollbars).
- Desktop grid: fill tile; body may scroll only if content exceeds the tile.
- Layout edit is desktop-only (disabled while stacked).
Rollback
- Revert
DashboardViewportContext.tsx,useDashboardCompact.ts,useWidgetMobileLayout.ts,WidgetGrid.tsx,WidgetContainer.tsx, and theDashboardPageedit-mode guards. - Or temporarily force desktop:
<DashboardViewportProvider forcedMode="desktop">.
Confirmed vs next
Confirmed in this change:
- Single canvas-based
phone|tablet|desktopmode switch - Shared
WidgetContaineroverflow policy - Shared stack CSS for all registered widget types (
dashboardWidgetSurface.css) - Per-mode defaults: min stack height, chart height, desktop min grid rows (
mobileWidgetSupport.ts) - Desktop tiles enforce type
desktopMinRowsso short saved layouts do not clip chrome - Chart widgets use
ChartResponsiveArea(explicit stack plot height); Recharts CSS fallback remains for stragglers - Coverage: all registry types mapped in
MOBILE_WIDGET_MODES(currently 80)
Tables / alarm lists intentionally keep inner scroll (data-scroll="allow").
Rollback: see Viewport ownership section above; revert surface CSS + min-row enforcement if needed.
