fix(web/store): restore the plugin cards' top padding, and capitalise platform names
ci / web (push) Successful in 1m5s
ci / docs-site (push) Successful in 1m5s
apple / swift (push) Successful in 1m24s
decky / build-publish (push) Successful in 19s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 8s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 31s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 8s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 9s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 10s
ci / bench (push) Successful in 5m34s
apple / screenshots (push) Successful in 6m33s
windows-host / package (push) Successful in 9m46s
deb / build-publish (push) Successful in 9m19s
docker / deploy-docs (push) Successful in 26s
deb / build-publish-host (push) Successful in 9m48s
android / android (push) Successful in 17m6s
arch / build-publish (push) Successful in 18m10s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 15m30s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 21m38s
ci / rust (push) Successful in 27m42s

Two things looked wrong in the store:

The cards had no space above the icon. `CardContent` zeroes its own top padding
(`pt-0`/`sm:pt-0`) because it normally sits under a `CardHeader` that supplies
it — but these cards have no header, so the top padding simply vanished while
the other three sides kept `p-card`. `p-card` does not undo it: `card` is a
custom `--spacing-*` token, which tailwind-merge does not recognise as a
spacing value and so never dedupes against `pt-0`, leaving the longhand to win.
Both header-less cards in this section now restore it explicitly, at both
breakpoints.

Platform chips read "windows" / "linux". Those are the catalog's platform
IDENTIFIERS (the index validator pins `linux | windows | macos`), which is right
for the wire and wrong on screen; the card now maps them to display names —
Linux, Windows, macOS. Proper nouns, so deliberately not routed through i18n.

Adds Store/StoreCard stories covering the padding, the platform labels, and the
installed / update / incompatible / blocked / external states, so the card can
be eyeballed without a host or a catalog.
This commit is contained in:
2026-07-21 00:00:37 +02:00
parent d783d5445c
commit 402ec90edc
3 changed files with 116 additions and 3 deletions
+24 -2
View File
@@ -127,6 +127,26 @@ export const BrowseTab: FC<{
);
};
/**
* The catalog stores platform IDENTIFIERS (`linux | windows | macos` — see the index
* validator); these are their display names. Proper nouns, so deliberately not routed
* through i18n, and `macos` is spelled the way Apple spells it.
*/
const PLATFORM_LABELS: Record<string, string> = {
linux: "Linux",
windows: "Windows",
macos: "macOS",
};
/**
* `CardContent` zeroes its top padding (`pt-0`/`sm:pt-0`) because it normally sits under a
* `CardHeader` that already supplies it — these cards have no header, so the top padding
* has to come back explicitly, at BOTH breakpoints. `p-card` alone does not do it: `card`
* is a custom `--spacing-*` token, which tailwind-merge does not recognise as a spacing
* value and therefore never dedupes against `pt-0`, leaving the longhand to win.
*/
const HEADERLESS_CARD_PADDING = "p-card pt-card sm:pt-card";
/** One catalog entry. Blocked entries shout; incompatible ones grey out; neither can be installed. */
export const StoreCard: FC<{ entry: StoreEntry; onInstall: () => void }> = ({
entry,
@@ -145,7 +165,9 @@ export const StoreCard: FC<{ entry: StoreEntry; onInstall: () => void }> = ({
!entry.compatible && !blocked && "opacity-60",
)}
>
<CardContent className="flex flex-1 flex-col gap-3 p-card">
<CardContent
className={cn("flex flex-1 flex-col gap-3", HEADERLESS_CARD_PADDING)}
>
<div className="flex items-start gap-3">
<span className="flex size-10 shrink-0 items-center justify-center rounded-md bg-primary/15">
<Icon className="size-5 text-foreground" />
@@ -173,7 +195,7 @@ export const StoreCard: FC<{ entry: StoreEntry; onInstall: () => void }> = ({
<div className="flex flex-wrap gap-1.5">
{entry.platforms.map((p) => (
<Badge key={p} variant="secondary" className="font-normal">
{p}
{PLATFORM_LABELS[p] ?? p}
</Badge>
))}
</div>