# VariantSelector

> Visual product option selector for custom cards, quick views, and add-to-cart flows

Canonical URL: https://fa7e86e3d553:3005/islands/commerce/variant-selector

> Select product variants with dropdown, swatch, or button controls and emit a scoped `variant:changed` event.

## Preview

**Category**: Commerce

## Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| product | object | yes | - | Product with `variants` and `options` |
| render | enum | no | buttons | `dropdown`, `swatches`, or `buttons` |
| defaultVariant | string | no | - | Variant selected initially |

## Embed Example

```html
<lx-island name="VariantSelector">
  <script type="application/json">
{
  "product": {
    "variants": [
      {
        "id": "gid://shopify/ProductVariant/s",
        "title": "Small",
        "price": "$29.00",
        "available": true,
        "mediaId": "size-small",
        "options": { "Size": "Small" }
      },
      {
        "id": "gid://shopify/ProductVariant/m",
        "title": "Medium",
        "price": "$29.00",
        "available": false,
        "options": { "Size": "Medium" }
      }
    ],
    "options": [
      { "name": "Size", "values": ["Small", "Medium"] }
    ]
  },
  "render": "buttons",
  "defaultVariant": "gid://shopify/ProductVariant/s"
}
  </script>
</lx-island>
```

## Usage

Use inside custom product cards or quick-view flows and add a `data-scope`
when a page contains more than one selector. For PDP variant selection, use
[BuyBox](/islands/commerce/buy-box). For headless coordination without a UI,
use the `variant-select` behavior.

The selector emits its initial variant after listeners can attach. Its root
exposes `data-selected-variant-id` and `data-selected-available`.

## Events

| Event | Direction | Payload |
|---|---|---|
| `option:changed` | Emits | `{axis: string, value: string}` |
| `variant:changed` | Emits | `{variantId, title, price, compareAtPrice?, available, image?, mediaId?, mediaIds?, images?}` |
| `inventory:updated` | Listens | `{variantId: string, quantity: number, available: boolean}` |

Unavailable option combinations are disabled, dimmed, and labelled “Sold
out.” Dropdown options include the same state in visible text. Use the same
`data-scope` around every island coordinating one product.

## Stylable parts

`root`, `option-group`, `option-label`, `option-values`, `dropdown`, `swatch`,
and `option-btn`.

## Related Islands

- [QuickAdd](/islands/commerce/quick-add) — Add the selected variant to cart
- [ProductGallery](/islands/commerce/product-gallery) — React to variant image changes
- [BuyBox](/islands/commerce/buy-box) — Full PDP purchase flow
