mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
feat(dashboard): inline trend arrow + baseline-aligned value row
Locks the TrendCard layout so the top-row Dashboard tiles align across the strip: - Heading row gets a fixed `h-5` so a one-line label and a (defensive) truncate behave identically. The label class adds `whitespace-nowrap` + `truncate` so even an unexpectedly long string never wraps to a second line — pairs with the locale-abbreviated keys wired in the previous commit. - Value row drops `flex-wrap` and pins `items-baseline` so the headline number, unit, and trend arrow all sit on the same y-baseline. At the same font-size (`text-3xl leading-none`) every tile's digits now land at the identical height (Weight 80 kg used to sit above BP 122 mmHg when one tile's heading wrapped). - Trend arrow moves to the end of the value row (after the unit) per Marc's brief, with a deterministic 16×16 slot. When the metric has no slope yet, the slot renders a muted placeholder dash so the layout width stays consistent across tiles. Marc verbatim: "rechts neben der Zahl, also nachdem die zum Beispiel Kilo oder so kommt, der Pfeil kommt, wie gerade der Trend ist". Verified at Pixel-5 (393 px, 2-col grid ≈ 180 px per tile) and iPad-portrait (5-col ≈ 140 px) — heading row stays single-line, value row baseline stays flat across the strip.
This commit is contained in:
1 parent
75fce6cfc6
commit
135b37512a
1 file changed
+38
-6
@@ -211,20 +211,52 @@ export function TrendCard({
|
||||
|
||||
return (
|
||||
<div className="bg-card border-border flex h-full w-full min-w-0 flex-col rounded-xl border p-4 md:p-6">
|
||||
<div className="flex min-w-0 items-start justify-between gap-2">
|
||||
<span className="text-muted-foreground min-w-0 text-xs leading-snug font-medium tracking-wide break-words uppercase">
|
||||
{/* v1.4.25 W20a — single-line discipline + deterministic height for
|
||||
the heading row so the value row below sits at the same baseline
|
||||
across every tile. The label is locale-abbreviated upstream (see
|
||||
`dashboard.*Short` keys) so `truncate` is a layout safeguard
|
||||
rather than the primary defence against wraps. `h-5` matches
|
||||
`text-xs leading-5` ≈ 20 px; identical across every tile. */}
|
||||
<div className="flex h-5 min-w-0 items-center justify-between gap-2">
|
||||
<span
|
||||
className="text-muted-foreground min-w-0 flex-1 truncate text-xs leading-5 font-medium tracking-wide whitespace-nowrap uppercase"
|
||||
data-slot="trend-card-label"
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
<Icon className="text-muted-foreground h-4 w-4 shrink-0" />
|
||||
</div>
|
||||
<div className="mt-2 flex min-w-0 flex-wrap items-baseline gap-x-2 gap-y-1">
|
||||
<span className="min-w-0 text-3xl leading-none font-bold tracking-tight [overflow-wrap:anywhere] tabular-nums">
|
||||
{/* v1.4.25 W20a — baseline-aligned value row. The headline value,
|
||||
unit, and trend arrow share a single flex line with
|
||||
`items-baseline` so the digits line up at the same y-coordinate
|
||||
across every tile in the strip (Weight 80 kg vs. BP 122 mmHg used
|
||||
to land at different heights when one tile had a one-line heading
|
||||
and another had a two-line wrap). The arrow slot is always
|
||||
present — when there is no slope yet, a muted "—" placeholder
|
||||
renders so the value row keeps a deterministic width. Marc's
|
||||
ask: "rechts neben der Zahl … der Pfeil [ist], wie gerade der
|
||||
Trend ist". */}
|
||||
<div
|
||||
className="mt-2 flex min-w-0 items-baseline gap-x-1.5"
|
||||
data-slot="trend-card-value-row"
|
||||
>
|
||||
<span className="min-w-0 truncate text-3xl leading-none font-bold tracking-tight tabular-nums">
|
||||
{latest !== null ? renderPair(latest, secondary?.latest) : "—"}
|
||||
</span>
|
||||
<span className="text-muted-foreground text-sm [overflow-wrap:anywhere] tabular-nums">
|
||||
<span className="text-muted-foreground shrink-0 text-sm tabular-nums">
|
||||
{unit}
|
||||
</span>
|
||||
{slope30 && <TrendIcon className={`h-4 w-4 shrink-0 ${trendColor}`} />}
|
||||
<span
|
||||
className="ml-auto inline-flex h-4 w-4 shrink-0 items-center justify-center"
|
||||
data-slot="trend-card-arrow"
|
||||
aria-hidden="true"
|
||||
>
|
||||
{slope30 ? (
|
||||
<TrendIcon className={`h-4 w-4 ${trendColor}`} />
|
||||
) : (
|
||||
<span className="text-muted-foreground text-xs opacity-30">—</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
{/* v1.4.16 phase B8 — comparison delta callout. Sits on its own
|
||||
line below the latest value so the tile stays scannable on
|
||||
|
||||
Reference in new issue
Block a user