Skip to content

AddressCard

The one address rendering. Compound rather than slotted, so a section title, a top-right edit action and a footer indicator each compose instead of adding a prop — and so a surface that wants a different arrangement stays first-class.

import { AddressCard } from "@evolve-storefront/commerce-ui/address-card";

Renders inside AddressConfigProvider.

Design notes

There is no actions prop and deliberately no sugar for the common case: two ways to build the same card is what made the previous version impossible to reuse, since the sugar became the only path anyone took and the flexible one went untested.

Frame classes match the card this replaces exactly, so the three surfaces it consolidates do not shift. Unifying with ui's Card (whose padding and gaps differ) is a separate change.

Preview

DefaultOpen in Storybook ↗

Usage

A 200-character street with no spaces, in a column as narrow as a checkout sidebar. It wraps inside the card instead of running out of it.

<AddressLines lines={formatAddressLines(address, { locale })} />;

Props

No props of its own.

Change the layout

Pass children to AddressCard to arrange its parts yourself. Every part is exported from @evolve-storefront/commerce-ui/address-card.

AddressCardFooterFooter region — a default-address indicator, per-card actions, or both.

No props of its own.

AddressCardHeaderA title row: the heading plus, typically, an action pinned to its end.

No props of its own.

AddressCardTitleThe card's heading — a recipient name, or a section label such as "Delivery address".

It emits no size or weight class. A card title is a card title whatever heading level it carries, and the level is semantics while the size is appearance — but stating the size as a utility put it above every layer a brand can reach, so restyling it meant out-specifying a utility rather than writing a selector. The two declarations live in styles.css under @layer components instead, where a brand's plain [data-component="address-card-title"] wins with no arithmetic.

PropTypeDescription
level?HeadingLevel

Semantic heading level. Defaults to 3; set it where the card sits at a different depth and the document outline matters.

Any other props go to the root element, like on a plain HTML element.

AddressLinesThe address block itself.
PropTypeDescription
linesreadonly string[]

Display lines, already formatted — use formatAddressLines from @evolve-storefront/core/address.

More

Lines rather than an address object on purpose: the omission rules (what an absent postal code looks like) are a pure function that is unit tested, instead of .filter(Boolean) repeated in JSX, and a non-React caller can format an address too.

Any other props go to the root element, like on a plain HTML element.

Loading and empty states

Render these while the data loads or when there is nothing to show, so the page does not jump when it arrives.

LoadingAddressCardSkeletonMirrors AddressCard's box — same frame, same gaps, same line count — so nothing reflows when the real address lands.

Examples

Title Size Is Not The LevelA card title is a card title at any heading level, and a brand can say otherwise.
<AddressCardTitle level={2}>Delivery address</AddressCardTitle>
/* A brand restyles every card title, in its own stylesheet. */
[data-component="address-card-title"] { font-size: 1rem; }
Open in Storybook ↗