mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 06:40:50 +00:00
fix(ui): keep date/time pickers inside their dialog
The add and edit surfaces could be scrolled sideways and the time picker sat past the right edge: measurements, mood, the medication intake editor and the cycle log sheet all showed it, so the cause is in what they share. Two mechanisms, both in shared primitives. DateField and TimeField wrap a text input. A flex item's min-width:auto resolves to a content-based minimum, and for a text input that is its intrinsic size attribute — 20 characters, about 180px. Neither field could render below ~230px whatever width the parent offered, so the date + time row demanded ~470px inside a 400px dialog body and pushed the clock button 58px past the edge. min-w-0 on the field box and on the overlay input releases that floor; the row now fits at every width from 360px up. The scrolling body only declares overflow-y. CSS promotes the other axis from visible to auto, so every deliberate outward bleed in the tree turned the form into a pannable surface — SheetSection's trigger row was 8px wider than its own container for no benefit (a focus ring already draws outside the box), and Switch's hit-target pseudo reaches 13px past the track. The bodies and the dialog surface now state overflow-x explicitly, the section trigger no longer bleeds, and the dialog's grid column is pinned so an over-wide child cannot drag the surface out with it. Measured before and after on the four reported surfaces at 360 / 390 / 430 / 768 / 1280 / 1440: the date/time row spilled 83px on every width from 640px up and none of it remains. An e2e spec asserts the two harms directly — the surface is not a horizontal scroll container, and no focusable control lies outside its visible box — with a canary that proves the reachability check can fail.
This commit is contained in:
1 parent
d5f176ac4d
commit
eb5c8a91fb
7 files changed
+333
-15
No files matched your search
@@ -220,7 +220,10 @@ export function ResponsiveSheet({
|
||||
<div
|
||||
data-slot="responsive-sheet-body"
|
||||
className={cn(
|
||||
"flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4",
|
||||
// Vertical-only scroll port — see the note on the Dialog
|
||||
// branch's body below for why `overflow-y-auto` alone does not
|
||||
// say that.
|
||||
"flex min-h-0 flex-1 flex-col gap-4 overflow-x-clip overflow-y-auto p-4",
|
||||
bodyClassName,
|
||||
)}
|
||||
>
|
||||
@@ -304,7 +307,20 @@ export function ResponsiveSheet({
|
||||
<div
|
||||
data-slot="responsive-sheet-body"
|
||||
className={cn(
|
||||
"flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto",
|
||||
// `overflow-x-clip` states the invariant the surrounding comment
|
||||
// already claims: this body scrolls VERTICALLY. `overflow-y-auto`
|
||||
// alone does not say that — CSS promotes the other axis from
|
||||
// `visible` to `auto`, so any child wider than the port turned the
|
||||
// whole form into a sideways-pannable surface. That is how the
|
||||
// date/time row and `<SheetSection>`'s deliberate 4 px hover bleed
|
||||
// (`-mx-1 w-[calc(100%+0.5rem)]`) both produced a horizontal
|
||||
// scrollbar on the desktop dialog. `clip` is not `visible`, so the
|
||||
// promotion does not happen and the vertical scroll is kept.
|
||||
//
|
||||
// Content that genuinely needs to scroll sideways (a wide table)
|
||||
// owns its own `overflow-x-auto` wrapper — that is the correct
|
||||
// place for it, and it still works inside a clipped port.
|
||||
"flex min-h-0 flex-1 flex-col gap-4 overflow-x-clip overflow-y-auto",
|
||||
bodyClassName,
|
||||
)}
|
||||
>
|
||||
|
||||
Reference in new issue
Block a user