Xzero UI
Pro library

Product listingPro

A storefront grid with price, color and size filters, a sort menu, hover photo swaps, and quick add with a size row.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/product-listing
Live · keyboard ready

Use this for a category or collection page. Pass products from your catalog, call your cart API in onAddToCart, and move filter state into the URL if you need shareable links.

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/product-listing

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { ProductListing } from "@/components/xzero/blocks/product-listing/product-listing";

export function CollectionPage({ products }) {
  return (
    <ProductListing
      title="Lighting"
      products={products}
      onAddToCart={(product, size) => cart.add(product.id, size)}
    />
  );
}

API reference

ProductListing

A storefront listing with a filter sidebar (dual price range, color swatches, sizes, in stock switch), a sort menu, and product cards that swap to a second photo on hover. Quick add opens a size row inside the card and the bag count rolls.

PropTypeDefaultDescription
productsListingProduct[]sample catalogProducts to list. The price range bounds come from these prices, rounded to 10.
colorsListingColor[]sample colors{ id, name, swatch } for the color filter and the dots under each card.
sizesstring[]["S", "M", "L"]Size filter options.
defaultSort"featured" | "newest" | "price-asc" | "price-desc""featured"Initial sort. Featured uses rank, newest uses added.
onAddToCart(product: ListingProduct, size: string) => void–Called when a product is added from its card. Single size products add straight away.
defaultCartCountnumber0Items already in the bag.
currencystring"USD"ISO currency for prices.
localestring"en-US"Locale for price formatting.
titlestring"Home goods"Collection heading.
classNamestring–Extra class on the root.

ListingProduct

PropTypeDefaultDescription
id, name, detail (required)string–Identity and a short line under the name, such as the material.
price (required)number–Price in whole currency units.
compareAtnumber–Previous price. Shows struck through beside the sale price.
image, alt (required)string–Main photo and its description.
hoverImagestring–Second photo that crossfades in on hover inside the same 4:5 box, without zooming.
colors, sizes (required)string[]–Color ids and sizes this product comes in. A product matches a filter when any of its values is selected.
inStock (required)boolean–False shows Sold out in the card meta row and disables quick add.
badgestring–Short status text in the card meta row, such as New. Sale is already shown by compareAt.
added, rank (required)number–Sort keys for newest and featured.

Keyboard interactions

KeysAction
TabMove through filters, the sort menu, and each card's quick add.
Arrow keysMove a price handle by 10, or move through sort options while the menu is open.
Enter / SpaceToggle a swatch or size, choose a sort option, or open quick add.
EscapeClose the sort menu, the size row, or the filter sheet.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Guidance for AI tools

Blocks are complete, self-contained screens with sample data. Replace the sample data and connect the callbacks described above. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components