Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions packages/devbar/src/constants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});

Expand Down
19 changes: 13 additions & 6 deletions packages/devbar/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions packages/playground/src/release-notes.json
Original file line number Diff line number Diff line change
@@ -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 `<style>` or html2canvas `ignoreElements` never reaches into the portal's shadow root). The devbar now injects a hide rule INTO that shadow root on init (`suppressFrameworkDevIndicators`, watching for the portal to (re)mount), so every capture backend — agent-browser, sweetlink CDP/CLI, html2canvas — sees the resting badge hidden. The rule is scoped to `[data-next-badge][data-error=\"false\"]`, so an **errored** badge (`data-error=\"true\"`) stays fully visible: a capture that shows it is telling you the captured page is broken, and hiding that would mask a real defect. `data-error` is live, so the CSS reacts on its own as errors come and go; the `[data-nextjs-dialog-overlay]` error overlay is likewise untouched. Cleaned up on `destroy()`.",
"1.18.1": "Fix a leaked recording render-interval and a stuck record button (DEV-4874). The `record-start-response` handler now clears the timer the click handler started optimistically before starting its own (the first interval previously leaked and re-rendered forever) and rolls back the optimistic “recording” UI when the daemon reports the start failed. The Sweetlink WS record proxy now forwards `record-start` params (label/viewport) to the daemon instead of dropping them.",
Expand Down