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.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
StatCardappliedwhileHover={{ 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 withrole="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 staticputs an inert card beside an interactive one. If the static card ever moves on hover again, that story shows it immediately.Verification
tsc --noEmitclean,biome checkclean on both touched files,bun run buildclean.Also refreshes
bun.lock, which predated@unom/ui,class-variance-authority,lucide-reactandmotionbeing declared as peers inpackage.json. No dependency change.⚠️ Not published.
@unom/app-uiis still0.2.0on 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 fixesSelectandInputNumberfor 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 — 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.