fix(dashboard): scope h-full to xl + tighter mobile sizing on KPIs
The Alerts rail and Reminders rail were using h-full unconditionally, which
worked at xl: where the dashboard grid pairs them with a sibling chart
column, but produced weirdly stretched empty cards in the single-column
mobile stack (no fixed-height context to fill).
alert-rail / my-reminders-rail: h-full -> xl:h-full
KPI tiles + skeleton rendered the same desktop padding (p-5) and font sizes
on phone, leaving the value cramped against a wide white frame. Tighter
mobile defaults that scale up at sm:
KPITile p-3 sm:p-5, label text-[10px] sm:text-xs,
value mt-1 text-lg sm:mt-2 sm:text-2xl, value truncates
KpiTileSkeleton: matching p-3 sm:p-5 + smaller skeleton bars on mobile
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,11 @@ export function AlertRail() {
|
|||||||
<section
|
<section
|
||||||
data-testid="alert-rail"
|
data-testid="alert-rail"
|
||||||
aria-label="Active alerts"
|
aria-label="Active alerts"
|
||||||
className="flex h-full flex-col gap-3"
|
// `h-full` is intentional only at xl: where the parent dashboard grid
|
||||||
|
// gives this rail a sibling column whose height it should match. On
|
||||||
|
// mobile (single-column stack) there's no fixed-height context, so
|
||||||
|
// forcing 100% height makes the section overflow / look stretched.
|
||||||
|
className="flex flex-col gap-3 xl:h-full"
|
||||||
>
|
>
|
||||||
<div className="flex items-baseline justify-between">
|
<div className="flex items-baseline justify-between">
|
||||||
<h2 className="text-sm font-semibold tracking-tight">Alerts</h2>
|
<h2 className="text-sm font-semibold tracking-tight">Alerts</h2>
|
||||||
|
|||||||
@@ -28,11 +28,10 @@ function formatPercent(value: number): string {
|
|||||||
|
|
||||||
function KpiTileSkeleton() {
|
function KpiTileSkeleton() {
|
||||||
return (
|
return (
|
||||||
<div className="relative overflow-hidden rounded-xl border border-border bg-card p-5 shadow-sm">
|
<div className="relative overflow-hidden rounded-xl border border-border bg-card p-3 shadow-sm sm:p-5">
|
||||||
<div className="absolute inset-x-0 top-0 h-1 bg-muted" aria-hidden />
|
<div className="absolute inset-x-0 top-0 h-1 bg-muted" aria-hidden />
|
||||||
<Skeleton className="h-3 w-24" />
|
<Skeleton className="h-3 w-20" />
|
||||||
<Skeleton className="mt-3 h-7 w-32" />
|
<Skeleton className="mt-2 h-6 w-24 sm:mt-3 sm:h-7" />
|
||||||
<Skeleton className="mt-2 h-3 w-12" />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,8 +67,11 @@ export function MyRemindersRail() {
|
|||||||
return `/${portSlug}/reminders`;
|
return `/${portSlug}/reminders`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `h-full` only at xl: where the dashboard grid pairs this rail with
|
||||||
|
// a sibling chart column. On mobile (stacked) it produced a weirdly
|
||||||
|
// tall empty card.
|
||||||
return (
|
return (
|
||||||
<Card className="h-full">
|
<Card className="xl:h-full">
|
||||||
<CardHeader className="flex flex-row items-start justify-between gap-2 space-y-0 pb-3">
|
<CardHeader className="flex flex-row items-start justify-between gap-2 space-y-0 pb-3">
|
||||||
<div className="space-y-0.5">
|
<div className="space-y-0.5">
|
||||||
<CardTitle className="flex items-center gap-1.5 text-base">
|
<CardTitle className="flex items-center gap-1.5 text-base">
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export function KPITile({
|
|||||||
<div
|
<div
|
||||||
data-testid="kpi-tile"
|
data-testid="kpi-tile"
|
||||||
className={cn(
|
className={cn(
|
||||||
'group relative overflow-hidden rounded-xl border border-border bg-gradient-brand-soft p-5 shadow-sm transition-all duration-base ease-smooth hover:shadow-md',
|
'group relative overflow-hidden rounded-xl border border-border bg-gradient-brand-soft p-3 shadow-sm transition-all duration-base ease-smooth hover:shadow-md sm:p-5',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@@ -53,10 +53,12 @@ export function KPITile({
|
|||||||
<div className={cn('absolute inset-x-0 top-0 h-1', ACCENT_STRIPES[accent])} aria-hidden />
|
<div className={cn('absolute inset-x-0 top-0 h-1', ACCENT_STRIPES[accent])} aria-hidden />
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="flex items-start justify-between gap-4">
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<div className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
|
<div className="text-[10px] font-medium uppercase tracking-wide text-muted-foreground sm:text-xs">
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 text-2xl font-semibold tabular-nums text-foreground">{value}</div>
|
<div className="mt-1 truncate text-lg font-semibold tabular-nums text-foreground sm:mt-2 sm:text-2xl">
|
||||||
|
{value}
|
||||||
|
</div>
|
||||||
{typeof delta === 'number' ? (
|
{typeof delta === 'number' ? (
|
||||||
<div className={cn('mt-1 text-xs font-medium', deltaClass)}>
|
<div className={cn('mt-1 text-xs font-medium', deltaClass)}>
|
||||||
{deltaPrefix}
|
{deltaPrefix}
|
||||||
|
|||||||
Reference in New Issue
Block a user