diff --git a/packages/devbar/src/constants.test.ts b/packages/devbar/src/constants.test.ts index deed9c2..0dada32 100644 --- a/packages/devbar/src/constants.test.ts +++ b/packages/devbar/src/constants.test.ts @@ -197,17 +197,18 @@ describe('DEVBAR_STYLES responsive custom controls', () => { expect(customStatusBlock).not.toContain('flex: 1 1 auto'); }); - it('uses compact simulated-mobile controls instead of touch-sized controls', () => { + it('keeps mobile toolbar controls at the 44px touch-target floor', () => { const mobileStart = DEVBAR_STYLES.indexOf('@media (max-width: 639px)'); const mobileBlock = DEVBAR_STYLES.slice(mobileStart); - expect(mobileBlock).toContain('grid-template-columns: repeat(5, 32px)'); - expect(mobileBlock).toContain('width: 32px !important'); - expect(mobileBlock).toContain('min-height: 0 !important'); + expect(mobileBlock).toContain('grid-template-columns: repeat(5, 44px)'); + expect(mobileBlock).toContain('width: 44px !important'); + expect(mobileBlock).toContain('min-height: 44px !important'); + expect(mobileBlock).toContain('[data-devbar] > button'); expect(mobileBlock).toContain('.devbar-custom-controls-inline'); expect(mobileBlock).toContain('padding: 0 !important'); - expect(mobileBlock).not.toContain('grid-template-columns: repeat(5, 44px)'); - expect(mobileBlock).not.toContain('min-height: 44px !important'); + expect(mobileBlock).not.toContain('grid-template-columns: repeat(5, 32px)'); + expect(mobileBlock).not.toContain('min-height: 32px !important'); }); }); diff --git a/packages/devbar/src/constants.ts b/packages/devbar/src/constants.ts index 26b1159..0be4dcf 100644 --- a/packages/devbar/src/constants.ts +++ b/packages/devbar/src/constants.ts @@ -888,7 +888,7 @@ export const DEVBAR_STYLES = ` } .devbar-actions { display: grid; - grid-template-columns: repeat(5, 32px); + grid-template-columns: repeat(5, 44px); justify-content: center; justify-items: center; align-items: center; @@ -904,10 +904,17 @@ export const DEVBAR_STYLES = ` display: none; } .devbar-actions button { - width: 32px !important; - height: 32px !important; - min-width: 32px !important; - min-height: 32px !important; + width: 44px !important; + height: 44px !important; + min-width: 44px !important; + min-height: 44px !important; + } + /* Compact mode mounts its controls directly under the toolbar root instead + of inside .devbar-actions. Keep the icon small while expanding its real + hit box to the same mobile floor. */ + [data-devbar] > button { + min-width: 44px !important; + min-height: 44px !important; } .devbar-actions button svg { width: 14px; @@ -922,7 +929,7 @@ export const DEVBAR_STYLES = ` padding: 0 !important; } .devbar-custom-control { - min-height: 0 !important; + min-height: 44px !important; max-width: 100% !important; padding: 0.25rem 0.5rem !important; font-size: 0.5625rem !important; diff --git a/packages/playground/src/release-notes.json b/packages/playground/src/release-notes.json index df9a516..b45b868 100644 --- a/packages/playground/src/release-notes.json +++ b/packages/playground/src/release-notes.json @@ -1,5 +1,6 @@ { "devbar": { + "1.18.4": "Restore the 44px mobile touch-target floor for every devbar control (DEV-7422). The responsive toolbar had deliberately reduced action buttons and custom controls to 32px, which made the fixed developer toolbar fail the same mobile hit-target audit used on host applications. Action buttons, compact-mode direct controls, and custom controls now retain at least a 44x44px interactive area while their icons stay visually compact.", "1.18.3": "Retry the badge-hide shadow-root injection for quiescent captures (DEV-6497). `suppressFrameworkDevIndicators` dropped its injection when the `nextjs-portal` element was present but its shadow root had not attached yet: the light-DOM MutationObserver sees the portal insertion (shadow still null) but never the later shadow attach — a shadow-DOM mutation it cannot observe — so on a *quiescent* captured page (no further mutations to self-heal) the resting Next.js badge leaked into the screenshot, the exact failure the badge-hide prevents. It now retries for a bounded number of animation frames (`setTimeout` fallback) when the portal is present but its shadow root is not ready, then gives up so a never-attaching portal cannot spin forever.", "1.18.2": "Hide the framework's own floating dev indicator (the Next.js dev-tools \"N\" badge) while it is benign — but never while it is signalling an error. Next renders the badge inside a `nextjs-portal` **shadow root**, fixed to a bottom corner; at rest it duplicates the devbar, sits on top of page content, and pollutes screenshots — and shadow-DOM encapsulation means no capture pipeline can hide it from the outside (a main-document `