fix(stat-card): only look interactive when it actually is #1

Merged
enricobuehler merged 2 commits from worktree-statcard-affordance into main 2026-08-09 14:05:08 +00:00
Owner

StatCard applied whileHover={{ scale: 1.02 }} unconditionally while having no click handler in its API at all — not "the handler was forgotten", but no way for the component to be interactive in the first place. So every stat card on every dashboard lifted under the cursor and did nothing. Its own doc comment described the lift as intended.

A scale-on-hover is the plainest "you can click this" signal there is; a card that lifts without acting is a promise the UI does not keep.

Reported from the Punktfunk console's Overview tab, where four of them sit in a row.

Change

Adds an optional onClick. Given one, the card lifts, presses, shows a pointer, takes focus, and responds to Enter/Space with role="button". Without one it is inert and looks inert.

Existing call sites pass no handler, so they simply stop pretending — no API break.

Story

stat-card/StatCard → Interactive vs static puts an inert card beside an interactive one. If the static card ever moves on hover again, that story shows it immediately.

Verification

tsc --noEmit clean, biome check clean on both touched files, bun run build clean.

Also refreshes bun.lock, which predated @unom/ui, class-variance-authority, lucide-react and motion being declared as peers in package.json. No dependency change.

⚠️ Not published. @unom/app-ui is still 0.2.0 on the registry — this needs a version bump and a manual publish (there is no CI workflow in this repo) before the fix reaches consumers.

Related

Same shape as unom/ui#1: the affordance and the behaviour have to be gated by the same prop. That PR fixes Select and InputNumber for the same underlying reason — the design system cannot see how its components behave on a consumer's palette or in a consumer's layout.

`StatCard` applied `whileHover={{ scale: 1.02 }}` **unconditionally while having no click handler in its API at all** — not "the handler was forgotten", but no way for the component to be interactive in the first place. So every stat card on every dashboard lifted under the cursor and did nothing. Its own doc comment described the lift as intended. A scale-on-hover is the plainest "you can click this" signal there is; a card that lifts without acting is a promise the UI does not keep. Reported from the Punktfunk console's Overview tab, where four of them sit in a row. ### Change Adds an optional `onClick`. Given one, the card lifts, presses, shows a pointer, takes focus, and responds to Enter/Space with `role="button"`. Without one it is inert and looks inert. Existing call sites pass no handler, so they simply stop pretending — no API break. ### Story `stat-card/StatCard → Interactive vs static` puts an inert card beside an interactive one. If the static card ever moves on hover again, that story shows it immediately. ### Verification `tsc --noEmit` clean, `biome check` clean on both touched files, `bun run build` clean. Also refreshes `bun.lock`, which predated `@unom/ui`, `class-variance-authority`, `lucide-react` and `motion` being declared as peers in `package.json`. No dependency change. ⚠️ **Not published.** `@unom/app-ui` is still `0.2.0` on the registry — this needs a version bump and a manual publish (there is no CI workflow in this repo) before the fix reaches consumers. ### Related Same shape as `unom/ui#1`: the affordance and the behaviour have to be gated by the same prop. That PR fixes `Select` and `InputNumber` for the same underlying reason — the design system cannot see how its components behave on a consumer's palette or in a consumer's layout.
enricobuehler added 2 commits 2026-08-09 11:03:04 +00:00
StatCard applied `whileHover={{ scale: 1.02 }}` unconditionally while having no click
handler in its API at all — so every stat on every dashboard lifted under the cursor and
did nothing. A scale-on-hover is the plainest "you can click this" signal there is; a card
that lifts without acting is a promise the UI does not keep. Reported from the Punktfunk
console's Overview tab, where four of them sit in a row.

Adds an optional `onClick`. Given one, the card lifts, presses, shows a pointer, takes
focus and responds to Enter/Space with role="button". Without one it is inert and looks
inert. Existing call sites pass no handler, so they simply stop pretending.

The new stat-card/StatCard → "Interactive vs static" story puts both side by side, which
is the cheapest way to see the regression return.
The lockfile predated @unom/ui, class-variance-authority, lucide-react and motion
being listed as peers; an install adds them back. No dependency change.
enricobuehler merged commit 1212f05441 into main 2026-08-09 14:05:08 +00:00
enricobuehler deleted branch worktree-statcard-affordance 2026-08-09 14:05:08 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unom/app-ui#1