Variant Selector Options
Overview
VariantSelectorOptions is the inline variant picker for a product detail page. It walks every entry in options and renders one row per attribute (size, material, color, finish), so a single component handles products with any number of configurable dimensions.
For text attributes it renders OptionTileText per value. When an option's name is "color" (case-insensitive), it auto-mounts VariantSelectorOptionsImageGrid on desktop and VariantSelectorOptionsImageSlider on mobile so swatches show their media thumbnails. Availability is computed per option from the variants list, so a value disabled by the current selection is shown as unavailable rather than hidden. If a single value is the only remaining choice for an option, it's selected automatically on mount.
Selection is exposed through a Record<string, string> v-model keyed by option name, which plugs straight into a Field wrapper for required-variant validation.
When the buy-box gets crowded, hand the variant picker off to a sheet with VariantSelectorMultiple. For high-consideration purchases that benefit from one-decision-at-a-time accordions, use VariantSelectorConfigurator.
Auto-import tag: <LVariantSelectorOptions>.
Key Business & UX Benefits
- One component covers products with any number of attributes (size only, size + color, size + color + material), so the PDP layout stays consistent as the catalog grows.
- Automatic swap to image grid (desktop) or slider (mobile) for the
colorattribute gives swatches the visual treatment shoppers expect, without extra wiring. - Unavailable values stay visible and clearly marked, so shoppers see the full attribute set and understand why a combination is blocked instead of seeing options disappear.
v-modelplusFieldwrapper plays nicely with form validation, so required-variant errors surface inline before the add-to-cart click fails.
Usage
<script setup lang="ts">
import { ref } from 'vue';
const selected = ref<Record<string, string>>({});
const options = [
{
id: 'opt-size',
name: 'Size',
values: [
{ id: 'val-s', value: 'S' },
{ id: 'val-m', value: 'M' },
{ id: 'val-l', value: 'L' },
],
},
{
id: 'opt-color',
name: 'Color',
values: [
{ id: 'val-red', value: 'Red', media: { type: 'image', url: '/red.jpg' } },
{ id: 'val-blue', value: 'Blue', media: { type: 'image', url: '/blue.jpg' } },
],
},
];
const variants = [
{
id: 'v1',
availableForSale: true,
selectedOptions: [
{ name: 'Size', value: 'M' },
{ name: 'Color', value: 'Red' },
],
},
];
</script>
<template>
<VariantSelectorOptions v-model="selected" :options="options" :variants="variants" />
</template>
Feature List
- Walks every entry in options and renders one row per attribute (size, material, color, finish) so a single component handles any number of dimensions
- Auto-mounts VariantSelectorOptionsImageGrid on desktop and VariantSelectorOptionsImageSlider on mobile when the option name is 'color' (case-insensitive)
- Text attributes render OptionTileText per value; color attributes use swatch media thumbnails
- Availability computed per option from the variants list, so values blocked by the current selection show as unavailable instead of disappearing
- When a single value is the only remaining option, it's selected automatically on mount so shoppers don't repeat trivial picks
- Selection exposed as Record<string, string> v-model keyed by option name, which plugs straight into a Field wrapper for required-variant validation
API Reference
| Prop | Default | Type |
|---|---|---|
optionsrequired | { id, name, values }[] | |
variantsrequired | { id, availableForSale, selectedOptions }[] | |
id | string | |
disabled | boolean | |
required | boolean | |
invalid | boolean | |
modelValue | Record<string, string> |
| Event | Type |
|---|---|
update:modelValue | (event: "update:modelValue", value: Record<string, string>): void |