PRODUCTVARIANTSELECTOR COMPONENT
Interactive color and size picker for product variants. Handles inventory states and variant selection.
PREVIEW
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 <VariantSelector10 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 showInventory17 />18 19 <p>Price: {formatPrice(selectedVariant.price.amount)}</p>20 <p>SKU: {selectedVariant.sku}</p>21 </div>22 );23}PROPS
| Prop | Type | Default | Description |
|---|---|---|---|
| variants | Variant[] | - | Array of product variants to choose from |
| selectedVariantId | string | - | ID of currently selected variant |
| onVariantSelect | (id) => void | - | Callback when variant is selected |
| showInventory | boolean | true | Show inventory status badges |
| attribute | string | color | Which attribute to display (color, size, etc.) |
VARIANTS
Color Only
Size Only
With Low Stock Badge
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 variant6 const selectedVariant = product.variants.find(v =>7 v.attributes.color === selectedColor &&8 v.attributes.size === selectedSize9 );10 11 return (12 <>13 <VariantSelector14 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 <VariantSelector25 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<VariantSelector2 variants={product.variants}3 selectedVariantId={selectedVariant.id}4 onVariantSelect={handleVariantSelect}5 disableOutOfStock6 showInventoryCount7 lowStockThreshold={10}8/>CUSTOM STYLING
Override default styles for brand consistency
1<VariantSelector2 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/>