All components (204)
Product card
Commerce · ProductCard · .amset-product
What it is and when to use it
The listing of a product in a store grid: the photo, the name, a line of detail, the stars, the price and, at the bottom, its actions (add to cart, choose size).
When to use it
- In a category listing, in search results or in "You may also like": each card leads to the page of its product.
priceBeforefor a discount: the old price appears struck through, with the saving, and the screen reader says "Was".soldOutwhen there is no stock left: the photo is dimmed and "Out of stock" is written over it.badgefor a short ribbon in the corner of the photo: "New", "Last few units".
When not to
- A card that is not a product (a category, a blog post):
Card, which also stretches its link over the top. - The line of a cart or an order:
OrderSummary. - Several cards in a row that does not fit: inside a
Carousel.
Keyboard: Tab reaches the name, which is the only link, and Enter opens the page. The next Tab enters the actions. The focus ring is drawn on the whole card, not just on the name.
Accessibility: it is an article named after the product. The link wraps only the name and is stretched over the card with a pseudo-element, so it can be pressed anywhere and can be opened in another tab; the actions sit on top and are pressed without opening the page. Without photoText the photo is decorative (alt=""), because the name is already next to it. The stars are read-only and are named "Rating for" followed by the name.
Context: it goes inside LocaleProvider (or AmsetProvider), which decides how the price is written.
Fine-tuning: CSS variables --amset-product-*: -detail, -gap, -inner-gap, -name, -padding, -photo-radius, -radius. The size moves the padding, the radius, the gap and the font sizes.
What it looks like
<ProductCard name="Performance T-shirt" href="/p/camiseta" price={24.9} priceBefore={32} />Props
Import it with import { ProductCard } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
hrefrequired | string | — |
namerequired | string | — |
pricerequired | number | — |
actions | ReactNode | What goes at the bottom: an add-to-cart button, a size selector. |
badge | string | Corner ribbon: "New", "Last units". |
className | string | Merged with the library classes; it does not replace them. |
currency | string | — |
detail | string | Second line below the name: the brand, the category. |
photo | string | — |
photoRatio | PhotoRatio | — |
photoText | string | What is seen in the photo. Without this the photo is decorative: the name is already beside it. |
priceBefore | number | Previous price: it appears struck through, together with the savings. |
rating | number | Average rating, from 0 to 5. |
reviewCount | number | — |
size | "sm" | "md" | "lg" | — |
soldOut | boolean | Out of stock: it is turned off and says so. |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-product-gap | var(--amset-space-3) |
--amset-product-inner-gap | var(--amset-space-2) |
--amset-product-padding | var(--amset-space-3) |
--amset-product-radius | var(--amset-radius-lg) |
--amset-product-photo-radius | var(--amset-radius) |
--amset-product-name | var(--amset-text-base) |
--amset-product-detail | var(--amset-text-sm) |
How to change it
.amset-product {
--amset-product-gap: ...;
--amset-product-inner-gap: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
