Skip to content

[bug] Profile still scrolls sideways on mobile — the roles row can't wrap, and the e2e guard only counts scrollable elements #333

Description

@serge-ivo

#235 was closed by 0a7a3b4 ("the thing that scrolled sideways on Profile was the nav, and the
guard excused it"). The nav fix was real; the page still scrolls sideways on mobile, from a
second cause the same guard also excuses.

Cause on Profile: the roles row cannot wrap

store/console/src/pages/Profile.tsx:156:

<div className="flex gap-1.5 mt-1.5">
  {user.roles.map(r => (
    <span className="text-[0.7rem] px-2 py-0.5 rounded-full font-semibold …">{r}</span>
  ))}
</div>

flex defaults to nowrap. Each chip is padded, non-shrinking content, so with admin,
creator and user the row is wider than a 390px viewport minus the 72px avatar and gap — and it
pushes the page. The parent has min-w-0, so the parent can shrink; the non-wrapping row inside
cannot.

Owner's diagnosis, and it is correct: the roles don't wrap and stretch it on mobile.

flex-wrap on that div is the fix. VoiceFields.tsx:202 and :221 already do exactly this for
their chip rows, so the pattern is established a few files away.

The guard has a hole, which is why this shipped twice

e2e/console.spec.ts:1648, measureOverflow:

const over = h.scrollWidth - h.clientWidth;
if (over <= 1) continue;
const ox = getComputedStyle(h).overflowX;
if (ox !== "auto" && ox !== "scroll") continue;   // ← only elements that SCROLL are counted

It only inspects elements with an explicit overflow-x of auto or scroll. A non-wrapping flex
row has the default overflow-x: visible, so it overflows visibly, widens the page, and is
skipped by the check
.

The measurement that would catch it already exists —

document.documentElement.scrollWidth - document.documentElement.clientWidth

— at :1056, but only inside the stats test. Profile and Preferences never get it.

Suggested: assert document-level overflow at 390px on every top-level route, and keep
measureOverflow as the diagnostic that names the culprit. The current guard answers "is any
scroller overflowing" when the question is "is the page wider than the screen".

Preferences: same symptom, different cause, needs a bisect

Reported: at mobile width the page is scrollable into empty space on the right, with no content
out there.

Ruled out already:

  • <Page width={960}> is correct — Page renders w-full max-w-[960px] mx-auto and its docstring
    documents this exact failure mode.
  • VoiceFields chip rows already carry flex-wrap.
  • No fixed w-[…], min-w-[…] or whitespace-nowrap in Preferences.tsx,
    VoiceFields.tsx or TranslationFields.tsx.

So the culprit is elsewhere in the subtree and needs finding in a browser rather than guessed at.
The document-level assertion above would identify the page; measureOverflow (with the
overflow-x filter removed) would name the element.

Worth checking PrefOverride and any <input type="range"> — a range input has an intrinsic
width and does not shrink below it without w-full min-w-0.

Verification

  • At 390px, document.documentElement.scrollWidth === clientWidth on Profile, Preferences
    and every other top-level route.
  • A user with three roles sees them wrapped, not clipped or pushing the layout.
  • The e2e guard fails if either regresses — including for an element whose overflow-x is
    visible, which is the case it currently ignores.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions