Skip to content

Options Selector

The FTOptionsSelector component provides a visually appealing way to select between multiple options. It displays options as cards with titles and descriptions, making it ideal for plan selections, preference choices, or any scenario where users need to choose from a set of mutually exclusive options.

Usage

The options selector displays each option as a card with a title, optional description, and a circular indicator that fills when selected.

Composition api (script setup)

vue
<script setup lang="ts">
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';
</script>
<script setup lang="ts">
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';
</script>

Options api

vue
<script>
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';
  export default {
    components: {
      FTOptionsSelector
    }
  }
</script>
<script>
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';
  export default {
    components: {
      FTOptionsSelector
    }
  }
</script>

Basic Usage

Options Selector

vue
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('');
  
  const basicOptions = ref([
    {
      title: 'Option 1',
      description: 'This is the first option',
      value: 'option1'
    },
    {
      title: 'Option 2',
      description: 'This is the second option',
      value: 'option2'
    },
    {
      title: 'Option 3',
      description: 'This is the third option',
      value: 'option3'
    }
  ]);
</script>

<template>
  <FTOptionsSelector v-model="selectedOption" :options="basicOptions" />
</template>
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('');
  
  const basicOptions = ref([
    {
      title: 'Option 1',
      description: 'This is the first option',
      value: 'option1'
    },
    {
      title: 'Option 2',
      description: 'This is the second option',
      value: 'option2'
    },
    {
      title: 'Option 3',
      description: 'This is the third option',
      value: 'option3'
    }
  ]);
</script>

<template>
  <FTOptionsSelector v-model="selectedOption" :options="basicOptions" />
</template>

With Label

Options Selector with Label

Select a plan
vue
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('premium');
  
  const planOptions = ref([
    {
      title: 'Basic',
      description: 'Perfect for individuals and small teams',
      value: 'basic'
    },
    {
      title: 'Premium',
      description: 'Advanced features for growing businesses',
      value: 'premium'
    },
    {
      title: 'Enterprise',
      description: 'Unlimited access with dedicated support',
      value: 'enterprise'
    }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="planOptions" 
    label="Select a plan"
  />
</template>
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('premium');
  
  const planOptions = ref([
    {
      title: 'Basic',
      description: 'Perfect for individuals and small teams',
      value: 'basic'
    },
    {
      title: 'Premium',
      description: 'Advanced features for growing businesses',
      value: 'premium'
    },
    {
      title: 'Enterprise',
      description: 'Unlimited access with dedicated support',
      value: 'enterprise'
    }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="planOptions" 
    label="Select a plan"
  />
</template>

Required Field

Required Options Selector

Choose your subscription*
vue
<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="planOptions" 
    label="Choose your subscription"
    :is-required="true"
  />
</template>
<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="planOptions" 
    label="Choose your subscription"
    :is-required="true"
  />
</template>

Without Description

Options can omit the description property for a more compact layout. The description element is only rendered when a description is provided.

Options Without Description

Notification method
vue
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('');

  const options = ref([
    { title: 'Email', value: 'email' },
    { title: 'SMS', value: 'sms' },
    { title: 'Push Notification', value: 'push' }
  ]);
</script>

<template>
  <FTOptionsSelector
    v-model="selectedOption"
    :options="options"
    label="Notification method"
  />
</template>
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('');

  const options = ref([
    { title: 'Email', value: 'email' },
    { title: 'SMS', value: 'sms' },
    { title: 'Push Notification', value: 'push' }
  ]);
</script>

<template>
  <FTOptionsSelector
    v-model="selectedOption"
    :options="options"
    label="Notification method"
  />
</template>

Disabled State

Entire Component Disabled

Disabled Options Selector

Select a plan
vue
<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="planOptions" 
    label="Select a plan"
    :disabled="true"
  />
</template>
<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="planOptions" 
    label="Select a plan"
    :disabled="true"
  />
</template>

Individual Options Disabled

Options Selector with Disabled Options

Select an option
vue
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('');
  
  const disabledOptions = ref([
    {
      title: 'Available',
      description: 'This option is available',
      value: 'available'
    },
    {
      title: 'Sold Out',
      description: 'This option is currently unavailable',
      value: 'soldout',
      disabled: true
    },
    {
      title: 'Coming Soon',
      description: 'This option will be available soon',
      value: 'comingsoon',
      disabled: true
    }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="disabledOptions" 
    label="Select an option"
  />
</template>
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('');
  
  const disabledOptions = ref([
    {
      title: 'Available',
      description: 'This option is available',
      value: 'available'
    },
    {
      title: 'Sold Out',
      description: 'This option is currently unavailable',
      value: 'soldout',
      disabled: true
    },
    {
      title: 'Coming Soon',
      description: 'This option will be available soon',
      value: 'comingsoon',
      disabled: true
    }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="disabledOptions" 
    label="Select an option"
  />
</template>

Custom Option Content with Slots

The component provides an option slot that allows you to customize the content of each option. The slot receives the option data as props.

Custom Layout with Icons

Custom Option Layout

Choose your preference
vue
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('');
  
  const options = ref([
    {
      title: 'Fast',
      description: 'Quick delivery option',
      value: 'option1'
    },
    {
      title: 'Express',
      description: 'Instant processing',
      value: 'option2'
    },
    {
      title: 'Standard',
      description: 'Regular delivery',
      value: 'option3'
    }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="options" 
    label="Choose your preference"
  >
    <template #option="{ title, description, value }">
      <div style="display: flex; align-items: center; gap: 12px; flex: 1;">
        <div style="font-size: 24px;">
          {{ value === 'option1' ? '🚀' : value === 'option2' ? '⚡' : '🎯' }}
        </div>
        <div>
          <div style="font-weight: 700; color: var(--ft-options-selector-title-color);">
            {{ title }}
          </div>
          <div style="font-size: 14px; color: var(--ft-options-selector-description-color);">
            {{ description }}
          </div>
        </div>
      </div>
      <div class="option__circle"></div>
    </template>
  </FTOptionsSelector>
</template>
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedOption = ref('');
  
  const options = ref([
    {
      title: 'Fast',
      description: 'Quick delivery option',
      value: 'option1'
    },
    {
      title: 'Express',
      description: 'Instant processing',
      value: 'option2'
    },
    {
      title: 'Standard',
      description: 'Regular delivery',
      value: 'option3'
    }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedOption" 
    :options="options" 
    label="Choose your preference"
  >
    <template #option="{ title, description, value }">
      <div style="display: flex; align-items: center; gap: 12px; flex: 1;">
        <div style="font-size: 24px;">
          {{ value === 'option1' ? '🚀' : value === 'option2' ? '⚡' : '🎯' }}
        </div>
        <div>
          <div style="font-weight: 700; color: var(--ft-options-selector-title-color);">
            {{ title }}
          </div>
          <div style="font-size: 14px; color: var(--ft-options-selector-description-color);">
            {{ description }}
          </div>
        </div>
      </div>
      <div class="option__circle"></div>
    </template>
  </FTOptionsSelector>
</template>

Pricing Cards with Custom Content

Pricing Cards

Select your plan
vue
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedPlan = ref('pro');
  
  const pricingOptions = ref([
    {
      title: 'Basic',
      description: 'For individuals',
      value: 'basic',
      meta: {
        price: '$9',
        features: ['5 Projects', '10GB Storage']
      }
    },
    {
      title: 'Pro',
      description: 'For professionals',
      value: 'pro',
      meta: {
        price: '$29',
        features: ['Unlimited Projects', '100GB Storage', 'Priority Support']
      }
    },
    {
      title: 'Enterprise',
      description: 'For teams',
      value: 'enterprise',
      meta: {
        price: '$99',
        features: ['Unlimited Everything', 'Dedicated Support', 'Custom Integration']
      }
    }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedPlan" 
    :options="pricingOptions" 
    label="Select your plan"
  >
    <template #option="option">
      <div style="display: flex; flex-direction: column; gap: 12px; flex: 1;">
        <div>
          <div style="font-weight: 700; font-size: 18px; color: var(--ft-options-selector-title-color);">
            {{ option.title }}
          </div>
          <div style="font-size: 24px; font-weight: 700; color: var(--ft-options-selector-circle-color); margin-top: 4px;">
            {{ option.meta?.price }}/mo
          </div>
        </div>
        <div style="font-size: 14px; color: var(--ft-options-selector-description-color);">
          {{ option.description }}
        </div>
        <ul style="font-size: 13px; color: var(--ft-options-selector-description-color); padding-left: 20px; margin: 0;">
          <li v-for="feature in option.meta?.features" :key="feature">{{ feature }}</li>
        </ul>
      </div>
      <div class="option__circle"></div>
    </template>
  </FTOptionsSelector>
</template>
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedPlan = ref('pro');
  
  const pricingOptions = ref([
    {
      title: 'Basic',
      description: 'For individuals',
      value: 'basic',
      meta: {
        price: '$9',
        features: ['5 Projects', '10GB Storage']
      }
    },
    {
      title: 'Pro',
      description: 'For professionals',
      value: 'pro',
      meta: {
        price: '$29',
        features: ['Unlimited Projects', '100GB Storage', 'Priority Support']
      }
    },
    {
      title: 'Enterprise',
      description: 'For teams',
      value: 'enterprise',
      meta: {
        price: '$99',
        features: ['Unlimited Everything', 'Dedicated Support', 'Custom Integration']
      }
    }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedPlan" 
    :options="pricingOptions" 
    label="Select your plan"
  >
    <template #option="option">
      <div style="display: flex; flex-direction: column; gap: 12px; flex: 1;">
        <div>
          <div style="font-weight: 700; font-size: 18px; color: var(--ft-options-selector-title-color);">
            {{ option.title }}
          </div>
          <div style="font-size: 24px; font-weight: 700; color: var(--ft-options-selector-circle-color); margin-top: 4px;">
            {{ option.meta?.price }}/mo
          </div>
        </div>
        <div style="font-size: 14px; color: var(--ft-options-selector-description-color);">
          {{ option.description }}
        </div>
        <ul style="font-size: 13px; color: var(--ft-options-selector-description-color); padding-left: 20px; margin: 0;">
          <li v-for="feature in option.meta?.features" :key="feature">{{ feature }}</li>
        </ul>
      </div>
      <div class="option__circle"></div>
    </template>
  </FTOptionsSelector>
</template>

Simple Badge Style

Badge Style Selector

Select size
vue
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedSize = ref('medium');
  
  const sizeOptions = ref([
    { title: 'S', description: 'Small', value: 'small' },
    { title: 'M', description: 'Medium', value: 'medium' },
    { title: 'L', description: 'Large', value: 'large' },
    { title: 'XL', description: 'Extra Large', value: 'xlarge' }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedSize" 
    :options="sizeOptions" 
    label="Select size"
  >
    <template #option="{ title, description }">
      <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1; gap: 8px;">
        <div style="font-weight: 700; font-size: 28px; color: var(--ft-options-selector-title-color);">
          {{ title }}
        </div>
        <div style="font-size: 12px; color: var(--ft-options-selector-description-color);">
          {{ description }}
        </div>
      </div>
    </template>
  </FTOptionsSelector>
</template>
<script setup lang="ts">
  import { ref } from 'vue';
  import { FTOptionsSelector } from '@fasttrack-solutions/vue-components-lib';

  const selectedSize = ref('medium');
  
  const sizeOptions = ref([
    { title: 'S', description: 'Small', value: 'small' },
    { title: 'M', description: 'Medium', value: 'medium' },
    { title: 'L', description: 'Large', value: 'large' },
    { title: 'XL', description: 'Extra Large', value: 'xlarge' }
  ]);
</script>

<template>
  <FTOptionsSelector 
    v-model="selectedSize" 
    :options="sizeOptions" 
    label="Select size"
  >
    <template #option="{ title, description }">
      <div style="display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1; gap: 8px;">
        <div style="font-weight: 700; font-size: 28px; color: var(--ft-options-selector-title-color);">
          {{ title }}
        </div>
        <div style="font-size: 12px; color: var(--ft-options-selector-description-color);">
          {{ description }}
        </div>
      </div>
    </template>
  </FTOptionsSelector>
</template>

Props

NameTypeDefaultDescription
optionsArray<FTOptionSelectorOption>[]Array of options to display. Each option should have title, value, and optionally description, disabled, and meta
labelStringundefinedLabel text displayed above the options
isRequiredBooleanfalseShows a red asterisk (*) next to the label when true
disabledBooleanfalseDisables all options when true
modelValueString | Boolean | Number''The currently selected option's value (used with v-model)

FTOptionSelectorOption Interface

typescript
interface FTOptionSelectorOption {
  title: string;
  description?: string;
  value: string | boolean | number;
  disabled?: boolean;
  meta?: Record<string, any>;
}
interface FTOptionSelectorOption {
  title: string;
  description?: string;
  value: string | boolean | number;
  disabled?: boolean;
  meta?: Record<string, any>;
}

The meta property allows you to pass any additional custom data to your option slot template.

Slots

NamePropsDescription
optiontitle, description, value, disabled, metaAllows complete customization of each option's content. Receives the option object properties as slot props

The option slot receives all properties from the FTOptionSelectorOption object, allowing you to build completely custom layouts while maintaining the selection behavior. Use the meta property to pass any additional custom data to your slot template.

Styling

The component supports CSS custom properties for theming:

CSS VariableDefaultDescription
--ft-options-selector-title-colorvar(--color-mono-700)Color of the option title
--ft-options-selector-title-color-selected#105dbaColor of the selected option title
--ft-options-selector-description-colorvar(--color-mono-600)Color of the option description
--ft-options-selector-description-color-selectedvar(--color-mono-700)Color of the selected option description
--ft-options-selector-circle-colorvar(--color-mono-700)Border color of the selection circle
--ft-options-selector-circle-color-selected#2782cfBorder color of the selected circle
--ft-options-selector-border-colorvar(--color-mono-400)Border color of option cards
--ft-options-selector-border-color-selected#2782cfBorder color of selected option card
--ft-options-selector-background-colortransparentBackground color of option cards
--ft-options-selector-background-color-selected#d8edf9Background color of selected option card
--ft-options-selector-required-colorvar(--color-brand-pink-400)Color of the required asterisk