refactor(ui): ProductList i18n data + link-card redesign#18815
refactor(ui): ProductList i18n data + link-card redesign#18815myelinated-wackerow wants to merge 11 commits into
Conversation
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Require a complete, self-descriptive ctaLabel per item and drop the shared actionLabel fallback and its synthesized aria-label, so the component is pure presentational -- no getTranslations, no async. Headings derive from a parentHeadingLevel prop, and the CTA now stacks below the content at every width instead of sitting inline on wide rows. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Move hardcoded product titles, descriptions, and CTAs into their intl namespaces and render the lists from async Server Components via getTranslations.
CTAs use a shared "Visit {brand}" skeleton that interpolates a translated brand key, rather than repeating the prefix across labels or injecting hardcoded English literals.
Stablecoins tool titles become keys too; Dune and Visa keep a long title key separate from the short CTA brand key.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
Document the Grid-as-semantic-list pattern (asChild ul, list-none plus role=list, fold-independent dividers) and the bare ul/li legacy-style gotcha. Clarify the translation boundary -- getTranslations for Server Components, the custom useTranslation hook for genuine client components, never next-intl useTranslations directly -- and the rule to interpolate a translated value rather than a hardcoded literal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
# Conflicts: # .claude/skills/design-system/references/i18n-rtl.md # .claude/skills/design-system/references/server-vs-client.md
Render each item as a ghost Card whose whole surface links to the product: href on the Card with a CardButtonFake as the sole action, so there are no nested links in the copy. Layout is a row -- a fixed-width logo thumbnail beside a content column. The CTA sits at the bottom of the column, full-width on narrow cards and fit-content once the card is wide enough (@container/card). Drops the old semantic-list + fold-independent-divider structure for the plain card-grid convention. Story updated to the current API. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
The whole ProductList card is now a single link, so a nested anchor in the copy is invalid HTML. Flatten Luna's TikTok link in its description to plain (bold) text. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
ProductList no longer uses the Grid-as-semantic-list + fold-independent-divider pattern, so remove that section from components.md and the now-dangling cross-reference from the bare-ul/li gotcha. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
asChild was added to support a Grid-as-<ul> semantic-list pattern that ProductList no longer uses, and nothing else consumes it. Remove the prop, its Slot import, and the doc bullet; the cols=1 support from the same original change stays. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com>
✅ Deploy Preview for ethereumorg ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
🔎 First-pass review — ✅ Looks mergeableRebuilds Since this is a visual redesign, it wants a design eye on the Chromatic diffs and a dev sign-off — hence the routing labels. Nothing blocking. AnalysisLane: code (component + consumers), with English-intl content extraction. Checked:
Non-blocking:
CI: lint/type-check ✅, unit ✅; Chromatic + Netlify still running.
|

Summary
Rebuilds
ProductListand migrates its four consumers.ctaLabel;parentHeadingLevel; pure presentational), then rebuilt items as ghost link cards: the whole card is the link (hrefonCard+CardButtonFakeas the sole action, no nested links), a logo thumbnail beside title/description, and a CTA that goes full-width on narrow cards and fit-content once the card is wide (@container/card).component-prediction-market-products.json,component-restaking-products.json); CTAs use a shared"Visit {brand}"skeleton fed a translated brand key rather than a hardcoded literal; stablecoins tool titles are now keyed (Dune/Visa keep a long title key separate from the short CTA brand); dropped an inline link from the Luna copy (invalid inside a card-link).columns={1}support (theasChildprop that briefly landed here was removed; nothing uses it).ProductListdocumented as a card grid.Test plan
/stablecoinstools list, AI-agents lists, prediction-markets, restaking: cards render, whole card links, single CTA works.ar): logo/text/CTA layout mirrors.