Skip to content

FormSelect Component

The FormSelect component is built with Vue 3 and provides a customizable select input with support for custom icons and slots. It's designed to be flexible and easy to integrate into your forms.

Basic Usage

Import and use FormSelect in your Vue components as follows:

vue
<template>
  <FormSelect v-model="select1">
    <option value="">Select an option</option>
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option value="option3">Option 3</option>
  </FormSelect>
</template>

<script setup>
import { FormSelect } from '@robuust-digital/vue-components/core';
</script>

Props

The FormSelect component accepts the following props:

PropTypeDefaultDescription
modelValueString, Number, ObjectnullThe selected value(s)
iconObject, FunctionnullSpecifies an icon to display within the select. @heroicons/vue can be used, or you can import your own .svg files.
prefixIconObject, FunctionnullSpecifies an icon to display on the left side of the select. @heroicons/vue can be used, or you can import your own .svg files.
rootClassString''Additional classes for the root div

Slots

The FormSelect component provides several slots for customization:

Default Slot

The default slot is used for the select options:

Show code
vue
<template>
  <FormSelect v-model="select2">
    <option value="">Choose a color</option>
    <option value="red">Red</option>
    <option value="blue">Blue</option>
    <option value="green">Green</option>
  </FormSelect>
</template>

Icon Slot

You can customize the dropdown icon using the icon slot:

Show code
vue
<template>
  <FormSelect v-model="select3">
    <option value="">Select an option</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
    <template #icon>
      <BeakerIcon />
    </template>
  </FormSelect>
</template>

<script setup>
import { BeakerIcon } from '@heroicons/vue/16/solid';
</script>

icon-left Slot

You can customize the icon-left using the icon-left slot:

Show code
vue
<template>
  <FormSelect v-model="select3">
    <template #icon-left>
      <BeakerIcon />
    </template>
    <option value="">Select an option</option>
    <option value="1">Option 1</option>
    <option value="2">Option 2</option>
  </FormSelect>
</template>

<script setup>
import { BeakerIcon } from '@heroicons/vue/16/solid';
</script>

Examples

Pre-selected Value

Show code
vue
<template>
  <FormSelect v-model="select4">
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option value="option3">Option 3</option>
  </FormSelect>
</template>

<script setup>
const select4 = ref('option2');
</script>

Custom Icon

Show code
vue
<template>
  <FormSelect :icon="BeakerIcon">
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option selected value="option3">Option 3</option>
  </FormSelect>
</template>

<script setup>
import { BeakerIcon } from '@heroicons/vue/16/solid';
</script>

Pre Icon

Show code
vue
<template>
  <FormSelect :icon-left="BeakerIcon">
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option selected value="option3">Option 3</option>
  </FormSelect>
</template>

<script setup>
import { BeakerIcon } from '@heroicons/vue/16/solid';
</script>

Refs

The FormSelect component's native HTML <select> element can be accessed using a template ref combined with a ref. This allows you to call native select methods or set properties directly:

vue
<template>
  <FormSelect ref="selectRef" />
</template>

<script setup>
import { ref, onMounted } from 'vue';

const selectRef = ref();

onMounted(() => {
  // Access the native select element
  const nativeSelect = selectRef.value.$refs.select.$el;
  
  // Use native select properties and methods
  nativeSelect.focus(); // Focus the select
});
</script>

CSS Customization ⚡️

To customize the select styles global

css
:root {
  /* Available variables */
  --rvc-select-border-radius: var(--rvc-base-border-radius);
  --rvc-select-border-width: var(--rvc-base-border-width);
  --rvc-select-border-color: var(--rvc-base-border-color);
  --rvc-select-font-size: var(--rvc-base-input-font-size);
  --rvc-select-font-weight: var(--rvc-base-input-font-weight);
  --rvc-select-box-shadow: var(--rvc-base-box-shadow);
  --rvc-select-color: var(--rvc-base-input-color);
  --rvc-select-bg-color: var(--rvc-base-input-bg-color);
  --rvc-select-bg-color-disabled: var(--rvc-base-input-bg-color-disabled);
  --rvc-select-disabled-opacity: var(--rvc-base-input-disabled-opacity);
  --rvc-select-icon-size: var(--rvc-base-input-icon-size);
  --rvc-select-icon-color: var(--rvc-base-input-icon-color);
  --rvc-select-padding-x: var(--rvc-base-input-padding-x);
  --rvc-select-height: var(--rvc-base-input-height);
  --rvc-select-placeholder-color: var(--rvc-base-input-placeholder-color);

  /* Small variant */
  --rvc-select-font-size-sm: calc(var(--rvc-base-input-font-size) * 0.9);
  --rvc-select-padding-x-sm: calc(var(--rvc-base-input-padding-x) * 0.85);
  --rvc-select-icon-size-sm: calc(var(--rvc-base-input-icon-size) * 0.85);
  --rvc-select-height-sm: 1.875rem;
}