PRODUCTVARIANTSELECTOR COMPONENT

Interactive color and size picker for product variants. Handles inventory states and variant selection.

PREVIEW

Classic Band Tee

Classic Band Tee

€ 29,99

Selected SKU: TSH-BLK-S-001

In Stock (50 available)

CODE

variant-selector-example.tsxtsx
1import { VariantSelector } from '@/components/fanbace/variant-selector';
2import { useState } from 'react';
3
4export default function ProductPage() {
5 const [selectedVariant, setSelectedVariant] = useState(product.variants[0]);
6
7 return (
8 <div>
9 <VariantSelector
10 variants={product.variants}
11 selectedVariantId={selectedVariant.id}
12 onVariantSelect={(variantId) => {
13 const variant = product.variants.find(v => v.id === variantId);
14 setSelectedVariant(variant);
15 }}
16 showInventory
17 />
18
19 <p>Price: {formatPrice(selectedVariant.price.amount)}</p>
20 <p>SKU: {selectedVariant.sku}</p>
21 </div>
22 );
23}

PROPS

PropTypeDefaultDescription
variantsVariant[]-Array of product variants to choose from
selectedVariantIdstring-ID of currently selected variant
onVariantSelect(id) => void-Callback when variant is selected
showInventorybooleantrueShow inventory status badges
attributestringcolorWhich attribute to display (color, size, etc.)

VARIANTS

Color Only

Size Only

With Low Stock Badge

Low Stock

Only 8 left in stock

Out of Stock

USAGE EXAMPLES

MULTI-ATTRIBUTE SELECTION

Handle products with multiple attributes (color AND size)

1function ProductVariantPicker({ product }: Props) {
2 const [selectedColor, setSelectedColor] = useState(product.variants[0].attributes.color);
3 const [selectedSize, setSelectedSize] = useState(product.variants[0].attributes.size);
4
5 // Find matching variant
6 const selectedVariant = product.variants.find(v =>
7 v.attributes.color === selectedColor &&
8 v.attributes.size === selectedSize
9 );
10
11 return (
12 <>
13 <VariantSelector
14 label="Color"
15 variants={uniqueColorVariants}
16 selectedVariantId={selectedVariant.id}
17 onVariantSelect={(id) => {
18 const variant = product.variants.find(v => v.id === id);
19 setSelectedColor(variant.attributes.color);
20 }}
21 attribute="color"
22 />
23
24 <VariantSelector
25 label="Size"
26 variants={uniqueSizeVariants}
27 selectedVariantId={selectedVariant.id}
28 onVariantSelect={(id) => {
29 const variant = product.variants.find(v => v.id === id);
30 setSelectedSize(variant.attributes.size);
31 }}
32 attribute="size"
33 />
34 </>
35 );
36}

WITH INVENTORY VALIDATION

Disable out-of-stock variants

1<VariantSelector
2 variants={product.variants}
3 selectedVariantId={selectedVariant.id}
4 onVariantSelect={handleVariantSelect}
5 disableOutOfStock
6 showInventoryCount
7 lowStockThreshold={10}
8/>

CUSTOM STYLING

Override default styles for brand consistency

1<VariantSelector
2 variants={product.variants}
3 selectedVariantId={selectedVariant.id}
4 onVariantSelect={handleVariantSelect}
5 className="gap-4"
6 buttonClassName="rounded-full"
7 selectedClassName="ring-4 ring-brand-500"
8/>