fix: responsive grid breakpoints for small screens (#41) #50

Merged
pitfriedrich merged 1 commits from ai/issue-41-responsive-grid-breakpoints into main 2026-07-29 05:56:56 +00:00
Collaborator

Closes #41

Problem

Dashboard grid was fixed at 12 columns, so on a phone a 6-wide widget only got half a ~380px viewport.

Fix

  • GridStackLayout.setResponsiveBreakpoint(maxWidthPx, columns): configures gridstack's columnOpts (window-width breakpoint, breakpointForWindow: true).
  • DashboardView wires it at 768px → 1 column, so widgets stack full-width below that width.
  • grid-stack.ts:
    • Skips localStorage persistence while the live column count differs from the configured full column count — gridstack's own responsive collapse fires the same change event a real drag/resize would, and save() while collapsed reports the forced 1-column shape. Without the guard, narrowing the window would silently overwrite the saved desktop layout.
    • Toggles grid.setStatic(...) via a matchMedia listener at the same breakpoint, so drag/resize is disabled on the stacked mobile view (touch rearranging a single-column stack is mostly misfires).
  • Restoring the desktop layout when the viewport widens back is gridstack's own column-change cache (grid.column()), not custom code — verified it isn't lost by the persistence guard above.

Tests

  • ResponsiveGridPlaywrightTest (new): drives a real browser at 1280×900 and 375×720.
    • mobileViewport_stacksWidgetsFullWidthAndDisablesDragging: widget width matches grid width below the breakpoint, grid-stack-static class present.
    • collapsingToMobile_doesNotOverwriteThePersistedDesktopLayout: localStorage entry is byte-for-byte unchanged across a collapse, and the widget returns to its exact desktop slot.
  • ./mvnw test: 78/78 green.
Closes #41 ## Problem Dashboard grid was fixed at 12 columns, so on a phone a 6-wide widget only got half a ~380px viewport. ## Fix - `GridStackLayout.setResponsiveBreakpoint(maxWidthPx, columns)`: configures gridstack's `columnOpts` (window-width breakpoint, `breakpointForWindow: true`). - `DashboardView` wires it at 768px → 1 column, so widgets stack full-width below that width. - `grid-stack.ts`: - Skips `localStorage` persistence while the live column count differs from the configured full column count — gridstack's own responsive collapse fires the same `change` event a real drag/resize would, and `save()` while collapsed reports the forced 1-column shape. Without the guard, narrowing the window would silently overwrite the saved desktop layout. - Toggles `grid.setStatic(...)` via a `matchMedia` listener at the same breakpoint, so drag/resize is disabled on the stacked mobile view (touch rearranging a single-column stack is mostly misfires). - Restoring the desktop layout when the viewport widens back is gridstack's own column-change cache (`grid.column()`), not custom code — verified it isn't lost by the persistence guard above. ## Tests - `ResponsiveGridPlaywrightTest` (new): drives a real browser at 1280×900 and 375×720. - `mobileViewport_stacksWidgetsFullWidthAndDisablesDragging`: widget width matches grid width below the breakpoint, `grid-stack-static` class present. - `collapsingToMobile_doesNotOverwriteThePersistedDesktopLayout`: `localStorage` entry is byte-for-byte unchanged across a collapse, and the widget returns to its exact desktop slot. - `./mvnw test`: 78/78 green.
claude-bot added 1 commit 2026-07-29 05:52:53 +00:00
fix: responsive grid breakpoints for small screens (#41)
CI / build-and-test (pull_request) Successful in 2m47s
7a4bc72799
Add a columnOpts breakpoint (768px -> 1 column) so widgets stack
full-width on mobile instead of staying at 12 columns. Persisting to
localStorage is skipped while gridstack's own responsive collapse is
active, so narrowing the window can no longer overwrite the saved
desktop layout; drag/resize is disabled below the same breakpoint to
avoid touch misfires.
pitfriedrich merged commit 0a8f7408f1 into main 2026-07-29 05:56:56 +00:00
pitfriedrich deleted branch ai/issue-41-responsive-grid-breakpoints 2026-07-29 05:56:56 +00:00
Sign in to join this conversation.