From 5324ee893a642295aae801f3c4ed58c2f6e9acb8 Mon Sep 17 00:00:00 2001 From: Nico Date: Thu, 4 Jun 2026 05:06:57 -0700 Subject: [PATCH] fix: stabilize mobile map toolbar width --- .../src/styles/pages/LocationMapManager.css | 37 +++++++++++++++++-- frontend/tests/location-map-manager.spec.ts | 8 +++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/frontend/src/styles/pages/LocationMapManager.css b/frontend/src/styles/pages/LocationMapManager.css index 5170000..109cc79 100644 --- a/frontend/src/styles/pages/LocationMapManager.css +++ b/frontend/src/styles/pages/LocationMapManager.css @@ -846,18 +846,21 @@ .location-map-toolbar { display: grid; - grid-template-columns: minmax(0, 1fr) auto; + grid-template-columns: minmax(0, 8.25rem) auto; align-items: center; - gap: 0.15rem; + justify-content: space-between; + column-gap: 0.15rem; + row-gap: 0.35rem; padding: 0.35rem 0.25rem; } .location-map-toolbar.has-history-slot { - grid-template-columns: minmax(0, 1fr) 82px auto; + grid-template-columns: minmax(0, 8.25rem) 5rem auto; } .location-map-mode-group { grid-column: 1; + width: 100%; min-width: 0; } @@ -885,7 +888,8 @@ .location-map-history-buttons { grid-column: 2; gap: 0.12rem; - width: 82px; + width: 5rem; + justify-self: center; } .location-map-history-buttons.is-reserved { @@ -930,3 +934,28 @@ grid-template-columns: repeat(2, minmax(0, 1fr)); } } + +@media (max-width: 380px) { + .location-map-toolbar { + grid-template-columns: minmax(0, 7.35rem) auto; + } + + .location-map-toolbar.has-history-slot { + grid-template-columns: minmax(0, 7.35rem) 4.6rem auto; + } + + .location-map-history-buttons { + width: 4.6rem; + } + + .location-map-history-buttons button, + .location-map-zoom-controls button { + min-width: 36px; + padding: 0.3rem; + } + + .location-map-zoom-controls span { + min-width: 30px; + font-size: 0.78rem; + } +} diff --git a/frontend/tests/location-map-manager.spec.ts b/frontend/tests/location-map-manager.spec.ts index 9a56d10..06ae0a5 100644 --- a/frontend/tests/location-map-manager.spec.ts +++ b/frontend/tests/location-map-manager.spec.ts @@ -770,27 +770,33 @@ test("mobile keeps draft preview status compact in the topbar", async ({ page }) expect(statusBox.y).toBeLessThan(titleBox.y + titleBox.height); expect(statusBox.x).toBeGreaterThan(titleBox.x); expect(toolbarBox.height).toBeLessThanOrEqual(64); + expect(modeBox.width).toBeLessThanOrEqual(150); expect(zoomBox.y).toBeLessThan(modeBox.y + modeBox.height); + expect(zoomBox.x + zoomBox.width).toBeLessThanOrEqual(toolbarBox.x + toolbarBox.width + 1); await page.getByRole("button", { name: "Edit Draft" }).click(); const historyActions = page.locator(".location-map-history-buttons"); await expect(historyActions.getByRole("button", { name: "Undo" })).toBeVisible(); await expect(historyActions.getByRole("button", { name: "Redo" })).toBeVisible(); + const editToolbarBox = await toolbar.boundingBox(); const editModeGroupBox = await modeGroup.boundingBox(); const editModeBox = await modeButtons.boundingBox(); const editHistoryBox = await historyActions.boundingBox(); const editZoomBox = await zoomControls.boundingBox(); + expect(editToolbarBox).not.toBeNull(); expect(editModeGroupBox).not.toBeNull(); expect(editModeBox).not.toBeNull(); expect(editHistoryBox).not.toBeNull(); expect(editZoomBox).not.toBeNull(); - if (!editModeGroupBox || !editModeBox || !editHistoryBox || !editZoomBox) { + if (!editToolbarBox || !editModeGroupBox || !editModeBox || !editHistoryBox || !editZoomBox) { throw new Error("Mobile edit controls layout was not measurable"); } + expect(Math.abs(editModeBox.x - modeBox.x)).toBeLessThanOrEqual(1); expect(Math.abs(editModeGroupBox.width - modeGroupBox.width)).toBeLessThanOrEqual(1); expect(Math.abs(editModeBox.width - modeBox.width)).toBeLessThanOrEqual(1); expect(editHistoryBox.x).toBeGreaterThan(editModeBox.x + editModeBox.width); expect(editZoomBox.x).toBeGreaterThan(editHistoryBox.x + editHistoryBox.width); + expect(editZoomBox.x + editZoomBox.width).toBeLessThanOrEqual(editToolbarBox.x + editToolbarBox.width + 1); }); test("admin selecting an object does not mark a draft dirty until it changes", async ({ page }) => {