Give every empty list one empty state and one add action

EmptyState now has a single action shape: centred at its own width on
the 44 px tap floor, never stretched edge to edge on some pages and
compact on others; the per-call-site size switch is gone, and the
dashed card takes the card radius. While a list is empty its empty
state carries the add action, so the header drops its own add button
there (measurements, mood, medications, labs, vaccinations, documents,
illness, check-ups, visits, procedures). The dashboard medication tile
of an account without medications offers 'Add a medication' instead of
'no data in the chosen range'.
This commit is contained in:
Marc-André Bombeck committed 2026-10-08 18:53:24 +02:00
1 parent 793c19e179
commit 005cb32ea8
30 files changed
+158 -65

No files matched your search

+7 -23
View File
@@ -36,16 +36,6 @@ export interface EmptyStateProps extends Omit<
* Compact density for use inside tiles or table-row empty rows.
*/
size?: "default" | "compact";
/**
* v1.4.27 MB7 / CF-36 — size hint for the inner action wrapper.
*
* `"default"` keeps the legacy inline-tight CTA. `"lg"` adds a
* `[&_button]:min-h-11 [&_a]:min-h-11` selector so the inner button
* or `asChild` link meets the 44 px floor on mobile, and lifts the
* wrapper to `w-full sm:w-auto` so the CTA fills the column at
* narrow viewports and centres at `sm+`.
*/
ctaSize?: "default" | "lg";
}
function EmptyState({
@@ -55,7 +45,6 @@ function EmptyState({
action,
variant = "card",
size = "default",
ctaSize = "default",
className,
...props
}: EmptyStateProps) {
@@ -97,17 +86,12 @@ function EmptyState({
</div>
{action ? (
<div
className={cn(
"mt-1",
// v1.4.27 MB7 / CF-36 — when `ctaSize === "lg"` the wrapper
// lifts to full-width on mobile and constrains the inner
// `<Button>` / `asChild` `<Link>` to the 44 px tap floor.
// The selectors target the wrapper's immediate child so
// existing CTAs that pass a plain `<Button>` (no class
// overrides) pick up the lift automatically.
ctaSize === "lg" &&
"w-full sm:w-auto [&>a]:min-h-11 [&>a]:w-full sm:[&>a]:w-auto [&>button]:min-h-11 [&>button]:w-full sm:[&>button]:w-auto",
)}
// One shape for every empty state's action: centred under the
// copy at its own width, never stretched edge to edge, and on the
// 44 px tap floor (back to the compact 36 px under a mouse). A
// per-call-site "lg" variant used to stretch some CTAs full width
// on a phone and leave others compact, side by side in the app.
className="mt-1 [&>a]:min-h-11 pointer-fine:[&>a]:min-h-9 [&>button]:min-h-11 pointer-fine:[&>button]:min-h-9"
>
{action}
</div>
@@ -135,7 +119,7 @@ function EmptyState({
role="status"
aria-live="polite"
className={cn(
"border-border bg-card rounded-lg border border-dashed",
"border-border bg-card rounded-xl border border-dashed",
className,
)}
{...props}