Outfit Builder
A mix-and-match selector across four categories (Top, Bottom, Shoes, Accessory) with a running total that recomputes live as you swap items. Built for apparel product pages that want to sell a full look, not just a single item.
Docs
Installation
A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its button dependencies and any missing npm packages, and installs them straight into your project.
npx shadcn add https://staaarter.com/r/outfit-builder.jsonPrefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/ecommerce/ecommerce27.tsx instead.
Usage
The file also exports ecommerce27Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.
import { Ecommerce27, ecommerce27Demo } from "@/components/blocks/ecommerce/ecommerce27"; export default function Page() { return <Ecommerce27 {...ecommerce27Demo} />; }
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| heading | string | "Build your outfit" | Heading above the category rows. |
| description | string | "Pick one item per category and see the total update as you go." | Supporting sentence under the heading. |
| categories | OutfitCategory[] | [] | Category rows, each rendered as its own radio group. |
| ctaLabel | string | "Add all to cart" | Label for the bottom call-to-action button. |
| className | string | none | Extra classes for the outer section element. |
Types
type OutfitItem = { id: string; name: string; price: number; // dollars; formatted with toFixed(2) at render, never pre-formatted image?: { src: string; alt: string }; }; type OutfitCategory = { name: string; // also used as the native radio group's `name` attribute items: OutfitItem[]; };
Behavior notes
- Each category row is a real native <input type="radio"> group (grouped by category.name), so exactly one item per category is selectable, and it's fully keyboard operable, the swatch card is just a styled <label> wrapping a visually hidden input.
- The first item in each category is preselected on mount so the running total is never $0.00 on first render.
- The running total is computed inline on every render from the four currently-selected item prices, it is not stored in state and synced via an effect.
- "Add all to cart" has no click handler; it reflects the current total but doesn't perform a real add-to-cart action.
- A category with no items simply renders an empty swatch row rather than being hidden, since that would silently drop it from the running total logic.
More Ecommerce Blocks
View all →wishlist-manager
Wishlist Manager
Saved-items list with stock-status badges, move-to-cart and remove actions, and a real empty state.
product-information-tabs
Product Information Tabs
Tabbed product details with Description, Features, Specifications, Reviews, and Shipping panels.
collection-showcase-grid
Collection Showcase Grid
A large featured-collection hero card alongside a grid of smaller supporting collection tiles.
shop-by-brand-grid
Shop by Brand Grid
A grid of bordered brand tiles with a wordmark-style name, product count, and a hover affordance.
sale-countdown-timer
Sale Countdown Timer
A live days/hours/minutes/seconds countdown in default, compact, or full-width banner layouts.
gift-card-redemption-form
Gift Card Redemption Form
A code-entry form that validates against a fixed list of demo gift cards and shows a real success or error state.