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
| Name | Type | Default |
|---|---|---|
value | [Object, String, Number, Boolean] | '' |
modelValue | [Object, String, Number, Boolean] | '' |
items | Array as PropType<SelectItem[]> | [] |
color | String | 'primary' |
placeholder | String | 'Select' |
searchable | Boolean | false |
hideCheckIcon | Boolean | false |
btnClass | String | '' |
top | Boolean | false |
itemText | String | 'text' |
itemValue | String | 'value' |
name | String | '' |
error | Boolean | false |
errorMessages | Array | [] |
returnObject | Boolean | false |
clearable | Boolean | false |
clearText | String | 'Clear' |
disabled | Boolean | false |
readonly | Boolean | false |
label | String | '' |
labelClass | String | 'mb-1 block' |
wrapperClass | String | '' |
errorClass | String | 'text-error-600 mt-1 text-sm' |
rules | String | '' |
shadow | Boolean | false |
shadowClass | String | 'shadow-sm' |
transition | String | 'fade' |
size | String as PropType<'sm' | 'md' | 'lg'> | 'md' |
searchSize | String as PropType<'sm' | 'md' | 'lg'> | 'md' |
searchPlaceholder | String | 'Search...' |
searchProps | Object as PropType<InstanceType<typeof VInput>['$props']> | {} |
fieldOptions | Object as PropType<Partial<FieldOptions<any>>> | {} |
hint | String | '' |
hideError | Boolean | false |
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.
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.
search
Emitted when the search input is changed.
Slots
The VSelect component provides the following slots for customization:
selected
Customize the selected item display.
<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.
<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.
<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.
<template>
<VSelect>
<template #item="item">
{{ item?.text.toUpperCase() }}
</template>
</VSelect>
</template><template>
<VSelect>
<template #item="item">
{{ item?.text.toUpperCase() }}
</template>
</VSelect>
</template>CSS Variables
: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:
npm i @morpheme/selectnpm i @morpheme/select<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.
Morpheme