Skip to content

feat(home): refresh the tokens and collectibles lists - #2937

Draft
CassioMG wants to merge 3 commits into
masterfrom
feature/home-refresh-lists
Draft

feat(home): refresh the tokens and collectibles lists#2937
CassioMG wants to merge 3 commits into
masterfrom
feature/home-refresh-lists

Conversation

@CassioMG

@CassioMG CassioMG commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Part of the Home refresh project. This is the Home screen's list bodies; the chrome around them is #2936.

What changed

Per Figma frames 9567-17044, 9569-38124, 9569-37947, 9569-38140:

  • Token rows restyled — icon + name/amount left, fiat + 24h delta right.
  • XLM now shows "Stellar Lumens" instead of the bare code. ⚠️ See the overlap note below.
  • Unfunded empty state moved out of View.Footer into the Tokens pane, rebuilt as a centred badge + heading + body + "Add XLM".
  • Collections are collapsible — the collection header is the toggle, with a count chip and a chevron. All expanded on mount.
  • Collectibles empty state gains a badge and a second line.

⚠️ Overlaps with existing draft #2887 — please reconcile before merging

#2887 "Parity/native asset display name" already does the XLM rename app-wide. It adds to extension/src/helpers/transaction.ts:

export const NATIVE_ASSET_DISPLAY_NAME = "Stellar Lumens";
export const getDisplayNameFromCode = (code, isNative) =>
  isNative ? NATIVE_ASSET_DISPLAY_NAME : code;

and consumes it across AccountAssets, AssetTile, TokenList, AssetDetail, and SwapAmount.

This PR arrived at the same rename independently and hardcodes the literal inline in BalanceRow:

const displayName = code === "XLM" && !issuerKey ? "Stellar Lumens" : code;

It was kept self-contained deliberately — this PR has to match its frame, and making it depend on an unmerged branch that's been idle since early July would be worse. But whichever of the two merges second should collapse this inline conditional into getDisplayNameFromCode so the string lives in one place.

Both PRs also edit extension/e2e-tests/sendPayment.test.ts (this one 7+/4−, #2887 5+/5−) for the same reason: locators that targeted the native-asset row by its old "XLM" text.

The rename had a wider blast radius than expected

Changing that one label broke 11 assertions across three test files that located rows by their visible text:

  • loadAccount.test.ts — 7 stale toContainText("XLM") assertions. These were missed on the first pass because of a bad grep exclusion, and only surfaced by actually running the suite. Worth remembering that grep is not a substitute for running the tests.
  • sendPayment.test.ts — 2 locators (.filter({ hasText: "XLM" }), getByText("XLM").click()).
  • views/__tests__/Account.test.tsx — 2 sort-order tests asserting toHaveTextContent("XLM"). Not structural: the tests still verify sort order, only the expected substring changed.

BalanceRow is shared with the Swap picker — intentionally

Restyling it in place means the Swap destination picker's "Your tokens" section inherits the new look. That's the point: one row style app-wide. Verified by screenshot on the final build — "Your tokens" matches Home exactly, and "Popular tokens" below it (a different component, AssetListRow) is correctly unaffected. swap.test.ts (12 passed) and sendPayment.test.ts (37 passed) both green.

BalanceRow__delta deliberately has no colour in CSS — it composes with getPriceDeltaColor(), and hardcoding would flatten gains and losses to one colour. There's a comment in the stylesheet saying so.

Two inconsistencies flagged, not silently resolved

  1. NotFundedMessage badge icon — implemented as Icon.Link04 per the plan's literal code, but the plan's own cited measurement doc says Coins01. Followed the plan; worth 10 seconds of your judgement.
  2. AccountAssets/styles.scss ended up with no functional change — the frame's spacing was already satisfied elsewhere. An explanatory comment was left rather than inventing unscoped CSS.

Collapse state

Local React state tracking collapsed collection ids in a Set, so "expanded by default" falls out of an empty set. Deliberately not persisted: chrome.storage.local is background-owned here, so persisting would drag a message handler and background changes into a styling PR.

Merge note

extension/e2e-tests/loadAccount.test.ts is touched by four PRs in this batch: this one (35+/7−, XLM assertions), #2933 (39+/11−, rename navigation), #2931 (1+/1−, button label), #2935 (1+/1−, card copy). This PR and #2933 are the two large ones — expect a real conflict between them, and take both sets of changes.

Also touches views/Account/index.tsx, which #2936 edits in a different region. Trivial rebase for whichever is second.

Verification

  • yarn test:ci — 1521/1572, exactly baseline +1 (the new collapse/expand test)
  • yarn build:extension — clean
  • e2e: loadAccount 9✓/2 skipped, swap 12✓, sendPayment 37✓/1 skipped, hideCollectible 3✓, addCollectible 1✓
  • AccountCollectibles.test.tsx gained a collapse/expand case (fireEvent added to its imports)

Known repo issue

yarn build:extension:translations is broken on master (i18next-scanner-webpack needs .default, extension/webpack.extension.js:3) and the pre-commit hook swallows the failure. New locale keys added by hand to en and pt.

🤖 Generated with Claude Code

CassioMG and others added 3 commits August 4, 2026 02:48
BalanceRow is shared between the Home tokens list and the Swap
destination picker's "Your tokens" section, so both surfaces pick up
the new type scale, spacing, and fiat/delta styling from this single
stylesheet pass. The native asset now renders "Stellar Lumens" instead
of "XLM" (issued assets that happen to use the code XLM are unaffected
via the existing !issuerKey guard).

The negative-delta color changes from a muted gray to
--sds-clr-red-09 so losses actually read as red, matching gains'
green; the color is still resolved entirely through the
positive/negative modifier classes composed from getPriceDeltaColor(),
never hardcoded on &__delta itself.

Updates the two Account.test.tsx sort-order assertions and three
e2e specs (loadAccount, sendPayment) whose "XLM" text/hasText
lookups on Home's BalanceRow-rendered rows no longer match now that
the row reads "Stellar Lumens" - all other testid-based lookups
(SwapTokenRow-XLM, account-assets-item, etc.) are unaffected since
they key off the raw asset code, not the display text.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the SDS Notification + two stacked buttons with a centered
badge, heading, body copy (inline "Learn more" link), and a single
"Add XLM" action; Friendbot stays as a secondary action for
non-mainnet. Moves NotFundedMessage out of the account View.Footer and
into the Tokens pane of the MultiPaneSlider, carrying over the
!hasError and !error.horizon guards verbatim so a Horizon outage still
shows the Horizon notice instead of the empty state over a funded
account.

The "2 XLM" copy in the body text is a padded recommendation shown in
the frame, not the 1 XLM protocol minimum - confirmed intentional with
the project owner.

New copy is hand-added to the en/pt locale files rather than run
through `yarn build:extension:translations`, which is broken on
master independent of this change (i18next-scanner-webpack needs
`.default`; see extension/webpack.extension.js).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…y state

Adds local collapse state to CollectionsList - a Set of collapsed
collection addresses, so an empty set naturally means everything is
expanded on mount (spec D5). No Redux slice, chrome.storage, or
message types: this is intentionally React-local UI state that resets
whenever Home unmounts. Each collection's header is now the toggle
(name, count chip, chevron-up/down) and its own grid hides
independently when collapsed; the Icon.Grid01 that used to sit before
the collection name is removed to match the frame.

Enriches the empty state with a badge, "No collectibles yet" (kept
verbatim - asserted by two sites in AccountCollectibles.test.tsx), and
a new "Collectibles you own will appear here." subtitle.

Adds a Jest case for the collapse/expand toggle, reusing the existing
"renders collectibles" mock (3 valid collections) - since that fixture
isn't a single collection, the assertions check the grid count drops
from 3 to 2 and back rather than a single grid's presence/absence.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

PR Preview build is ready: https://github.com/stellar/freighter/releases/tag/untagged-2a60662d94f702977b85 (SDF collaborators only — install instructions in the release description)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant