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/select
npm 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.