Skip to content

Select ​

The VSelect component is a form control for presenting a list of options to the user. It provides various customization options such as the ability to search for items, display a label, and show or hide a check icon. It can also display in an error state and include a shadow effect.

Usage ​

Basic Usage ​

To use the VSelect component, you will need to import the ref function from vue and the VSelectItem type from @morpheme/select. Then, create a ref of an array of VSelectItem objects and pass it to the items prop of the VSelect component in your template.

INFO

The VSelect component is registered globally when you install with @morpheme/ui. So you don't need to import it manually.

Searchable ​

To enable search functionality in the VSelect component, pass the searchable prop.

No Check Icon ​

To hide the check icon in the VSelect component, pass the no-check-icon prop.

Label ​

To display a label for the VSelect component, pass the label prop.

Shadow ​

To apply a shadow effect to the VSelect component, pass the shadow prop.

Error ​

To display the VSelect component in an error state, pass the error prop.

Clearable ​

To enable the ability to clear the selected value in the VSelect component, pass the clearable prop.

Custom Transition ​

To customize the transition effect of the VSelect component, pass the desired transition name to the transition prop.

Return Object ​

To return the selected item as an object rather than just the value, pass the return-object prop.

Sizes ​

The VSelect component supports three sizes: sm, md, and lg. To specify the size of the component, use the size prop.

Validation ​

The VSelect component can be used with the vee-validate library to provide form validation. To use the VSelect component in a form with validation, import the useForm hook and pass it an object with a validationSchema property. Then, bind the VSelect component to the form values using the v-model directive.

Props ​

NameTypeDefault
value[Object, String, Number, Boolean]''
modelValue[Object, String, Number, Boolean]''
itemsArray as PropType<SelectItem[]>[]
colorString'primary'
placeholderString'Select'
searchableBooleanfalse
hideCheckIconBooleanfalse
btnClassString''
topBooleanfalse
itemTextString'text'
itemValueString'value'
nameString''
errorBooleanfalse
errorMessagesArray[]
returnObjectBooleanfalse
clearableBooleanfalse
clearTextString'Clear'
disabledBooleanfalse
readonlyBooleanfalse
labelString''
labelClassString'mb-1 block'
wrapperClassString''
errorClassString'text-error-600 mt-1 text-sm'
rulesString''
shadowBooleanfalse
shadowClassString'shadow-sm'
transitionString'fade'
sizeString as PropType<'sm' | 'md' | 'lg'>'md'
searchSizeString as PropType<'sm' | 'md' | 'lg'>'md'
searchPlaceholderString'Search...'
searchPropsObject as PropType<InstanceType<typeof VInput>['$props']>{}
fieldOptionsObject as PropType<Partial<FieldOptions<any>>>{}
hintString''
hideErrorBooleanfalse

Types ​

VSelectItem ​

The VSelectItem interface represents an item in the list of options. It has the following properties:

  • text: The text to be displayed for the item.
  • value: The value of the item.
ts
export interface VSelectItem = {
  text: string;
  value: any;

  [x: string]: any;
};
export interface VSelectItem = {
  text: string;
  value: any;

  [x: string]: any;
};

Events ​

update:modelValue ​

Emitted when the selected item changes.

update:value ​

Emitted when the selected item changes.

change ​

Emitted when the selected item changes.

Emitted when the search input is changed.

Slots ​

The VSelect component provides the following slots for customization:

selected ​

Customize the selected item display.

vue
<template>
  <VSelect>
    <template #selected="item">
      {{ item.text.toUpperCase() }}
    </template>
  </VSelect>
</template>
<template>
  <VSelect>
    <template #selected="item">
      {{ item.text.toUpperCase() }}
    </template>
  </VSelect>
</template>

empty ​

Customize the display for when there are no items.

vue
<template>
  <VSelect>
    <template #empty> No item found. </template>
  </VSelect>
</template>
<template>
  <VSelect>
    <template #empty> No item found. </template>
  </VSelect>
</template>

icon ​

Customize the icon displayed for the selected item.

vue
<template>
  <VSelect>
    <template #icon="item">
      <VIcon name="ri:check-line" />
    </template>
  </VSelect>
</template>
<template>
  <VSelect>
    <template #icon="item">
      <VIcon name="ri:check-line" />
    </template>
  </VSelect>
</template>

item ​

Customize the display for each item in the list.

vue
<template>
  <VSelect>
    <template #item="item">
      {{ item?.text.toUpperCase() }}
    </template>
  </VSelect>
</template>
<template>
  <VSelect>
    <template #item="item">
      {{ item?.text.toUpperCase() }}
    </template>
  </VSelect>
</template>

CSS Variables ​

scss
:root {
  /* input control / button */
  --v-select-border-color: var(--v-input-border-color);
  --v-select-border-radius: var(--v-input-border-radius);
  --v-select-bg-color: var(--v-input-bg-color);
  --v-select-height: var(--v-input-height);
  --v-select-placeholder-color: var(--v-input-placeholder-color);
  --v-select-border-radius: var(--v-input-border-radius);
  --v-select-padding-x: var(--v-input-padding-x);
  --v-select-padding-y: var(--v-input-padding-y);
  --v-select-font-size: var(--v-input-font-size);

  /* label */
  --v-select-label-color: var(--v-input-label-color);
  --v-select-label-font-size: var(--v-input-label-font-size);
  --v-select-label-font-weight: var(--v-input-label-font-weight);
  --v-select-label-display: var(--v-input-label-display);
  --v-select-label-margin-bottom: var(--v-input-label-margin-bottom);

  /* text */
  --v-select-text-color: var(--v-input-text-color);
  --v-select-text-font-size: var(--v-input-text-font-size);
  --v-select-text-font-weight: var(--v-input-text-font-weight);

  /* icon */
  --v-select-icon-width: var(--size-spacing-4);
  --v-select-icon-height: var(--size-spacing-4);
  --v-select-icon-color: var(--v-input-icon-color);

  // options
  --v-select-options-bg-color: var(--color-white);

  /* option item */
  --v-select-option-padding-x: var(--size-spacing-4);
  --v-select-option-padding-y: var(--size-spacing-2);
  --v-select-option-bg-color: var(--color-white);
  --v-select-option-text-color: var(--color-gray-700);

  /* option item on hover */
  --v-select-option-hover-bg-color: var(--color-gray-100);
  --v-select-option-hover-text-color: var(--color-gray-700);

  // selected
  --v-select-selected-color: var(--v-input-label-color);

  // error
  --v-select-error-border-color: var(--color-error-300);

  // hint
  --v-select-hint-font-size: var(--v-input-hint-font-size, 14px);
  --v-select-hint-color: var(--v-input-hint-color);
  --v-select-hint-margin-top: var(--v-input-hint-margin-top);

  --v-select-option-check-selected-color: var(--color-primary-700);
}
:root {
  /* input control / button */
  --v-select-border-color: var(--v-input-border-color);
  --v-select-border-radius: var(--v-input-border-radius);
  --v-select-bg-color: var(--v-input-bg-color);
  --v-select-height: var(--v-input-height);
  --v-select-placeholder-color: var(--v-input-placeholder-color);
  --v-select-border-radius: var(--v-input-border-radius);
  --v-select-padding-x: var(--v-input-padding-x);
  --v-select-padding-y: var(--v-input-padding-y);
  --v-select-font-size: var(--v-input-font-size);

  /* label */
  --v-select-label-color: var(--v-input-label-color);
  --v-select-label-font-size: var(--v-input-label-font-size);
  --v-select-label-font-weight: var(--v-input-label-font-weight);
  --v-select-label-display: var(--v-input-label-display);
  --v-select-label-margin-bottom: var(--v-input-label-margin-bottom);

  /* text */
  --v-select-text-color: var(--v-input-text-color);
  --v-select-text-font-size: var(--v-input-text-font-size);
  --v-select-text-font-weight: var(--v-input-text-font-weight);

  /* icon */
  --v-select-icon-width: var(--size-spacing-4);
  --v-select-icon-height: var(--size-spacing-4);
  --v-select-icon-color: var(--v-input-icon-color);

  // options
  --v-select-options-bg-color: var(--color-white);

  /* option item */
  --v-select-option-padding-x: var(--size-spacing-4);
  --v-select-option-padding-y: var(--size-spacing-2);
  --v-select-option-bg-color: var(--color-white);
  --v-select-option-text-color: var(--color-gray-700);

  /* option item on hover */
  --v-select-option-hover-bg-color: var(--color-gray-100);
  --v-select-option-hover-text-color: var(--color-gray-700);

  // selected
  --v-select-selected-color: var(--v-input-label-color);

  // error
  --v-select-error-border-color: var(--color-error-300);

  // hint
  --v-select-hint-font-size: var(--v-input-hint-font-size, 14px);
  --v-select-hint-color: var(--v-input-hint-color);
  --v-select-hint-margin-top: var(--v-input-hint-margin-top);

  --v-select-option-check-selected-color: var(--color-primary-700);
}

Standalone Installation ​

You can also install the Select component individually via @morpheme/select package:

bash
npm i @morpheme/select
npm i @morpheme/select
vue
<script setup lang="ts">
import VSelect from '@morpheme/select';

const items = ref([
  {
    text: 'Item 1',
    value: 1,
  },
  {
    text: 'Item 2',
    value: 2,
  },
]);
</script>

<template>
  <VSelect :items="items" />
</template>
<script setup lang="ts">
import VSelect from '@morpheme/select';

const items = ref([
  {
    text: 'Item 1',
    value: 1,
  },
  {
    text: 'Item 2',
    value: 2,
  },
]);
</script>

<template>
  <VSelect :items="items" />
</template>

Storybook ​

View Storybook documentation here.