Multi Select
The VMultiSelect component is a customizable multiselect dropdown for Vue. It allows users to select multiple items from a list and displays the selected items in the form of badges.
Usage
Basic Usage
To use the VMultiSelect component, just use it in the template.
INFO
The VMultiSelect component is registered globally when you install with @morpheme/ui. So you don't need to import it manually.
Clearable
To enable the clearable feature, which allows users to clear their selections, add the clearable prop to the VMultiSelect component.
Max Badge
To limit the number of badges displayed, you can use the max-badge prop. This prop specifies the maximum number of badges that will be displayed before a "and X more" badge is shown.
Label
You can add a label to the VMultiSelect component by using the label prop.
Custom Style
You can customize the style of the VMultiSelect component using various props.
Initial Errors
You can display initial errors for the VMultiSelect component by using the initialErrors prop in the useForm hook.
Custom Compare Function
You can use a custom compare function for the search feature of the VMultiSelect component by using the search-by prop.
Props
| Name | Type | Default |
|---|---|---|
items | Array as PropType<VMultiSelectItem[]> | [] |
itemText | string | 'text' |
itemValue | string | value |
searchBy | string | '' |
placeholder | string | 'Search...' |
name | string | '' |
error | boolean | false |
errorMessages | Array | '[]' |
clearable | boolean | 'false' |
disabled | boolean | 'false' |
readonly | boolean | 'false' |
maxBadge | number | 0 |
delay | number | '500' |
id | string | '' |
inputProps | Object as PropType<Record<string, any>> | '{}' |
selectAll | boolean | false |
loading | boolean | false |
wrapperClass | string | '' |
inputClass | string | '' |
badgeColor | string | 'primary' |
badgeClass | string | '' |
badgeProps | object | {} |
dropdownClass | string | '' |
itemClass | string | '' |
checkWrapperClass | string | '' |
checkIconClass | string | '' |
noDataClass | string | '' |
loadingClass | string | '' |
label | string | '' |
labelClass | string | 'mb-2 block' |
rules | string | '' |
errorClass | string | 'text-error-600 mt-1 text-sm' |
transition | string | 'fade' |
hint | String | '' |
hideError | Boolean | false |
Events
click:outside
This event is emitted when the user clicks outside of the VMultiSelect component. It can be useful for closing the dropdown menu when the user clicks outside of it.
<template>
<VMultiSelect @click:outside="closeDropdown" />
</template>
<script>
export default {
methods: {
closeDropdown() {
// Close the dropdown menu
},
},
};
</script><template>
<VMultiSelect @click:outside="closeDropdown" />
</template>
<script>
export default {
methods: {
closeDropdown() {
// Close the dropdown menu
},
},
};
</script>update:modelValue
This event is emitted when the selected values of the VMultiSelect component are updated. It is emitted with an array of the selected values.
<template>
<VMultiSelect @update:modelValue="updateSelectedValues" />
</template>
<script>
export default {
methods: {
updateSelectedValues(values) {
// values is an array of the selected values
},
},
};
</script><template>
<VMultiSelect @update:modelValue="updateSelectedValues" />
</template>
<script>
export default {
methods: {
updateSelectedValues(values) {
// values is an array of the selected values
},
},
};
</script>search
This event is emitted when the user performs a search in the VMultiSelect component. It is emitted with the search query string.
<template>
<VMultiSelect @search="searchItems" />
</template>
<script>
export default {
methods: {
searchItems(query) {
// query is the search query string
},
},
};
</script><template>
<VMultiSelect @search="searchItems" />
</template>
<script>
export default {
methods: {
searchItems(query) {
// query is the search query string
},
},
};
</script>selected
This event is emitted when the user selects an item from the VMultiSelect component. It is emitted with the selected item.
<template>
<VMultiSelect @selected="itemSelected" />
</template>
<script>
export default {
methods: {
itemSelected(item) {
// item is the selected item
},
},
};
</script><template>
<VMultiSelect @selected="itemSelected" />
</template>
<script>
export default {
methods: {
itemSelected(item) {
// item is the selected item
},
},
};
</script>Slots
selection
Allow customized selection rendering. Will only be run when there is selected value. If maxBadge is set to valid value, it will only be run for items within the set limit.
Slot Props
| Prop | Value | Description |
|---|---|---|
index | number | Index of the current selection |
item | any | Current selected item at given index |
value | string | Label of selected item. |
onRemove | function | Callback to remove selected item |
max-selection
Allows customized rendering for max-selection rendering. This will only be run if maxBadge props is set to valid value.
Slot Props
| Prop | Value | Description |
|---|---|---|
length | number | Number of selected items being hidden |
select-all
Allows custom render for select all option. This will only be run if selectAll props is set to valid value.
Slot Props
| Prop | Value | Description |
|---|---|---|
iSelected | boolean | A flag to indicate if all options is currently selected |
onClick | function | Callback to toggle select all state |
prepend.item
Add custom element before option list
append.item
Add custom element after option list
item.label
Allows custom render for option item.
Slot Props
| Prop | Value | Description |
|---|---|---|
index | number | Index of the current selection |
item | any | Current selected item at given index |
value | string | Label of selected item. |
iSelected | boolean | A flag to indicate if it is currently selected |
CSS Variables
:root {
--v-multi-select-border-color: var(--v-input-border-color);
--v-multi-select-border-radius: var(--v-input-border-radius);
--v-multi-select-bg-color: var(--v-input-bg-color);
--v-multi-select-text-color: var(--color-gray-700);
--v-multi-select-height: auto;
--v-multi-select-min-height: var(--v-input-height);
--v-multi-select-placeholder-color: var(--v-input-placeholder-color);
--v-multi-select-border-radius: var(--v-input-border-radius);
--v-multi-select-padding-x: var(--v-input-padding-x);
--v-multi-select-padding-y: var(--size-spacing-2);
--v-multi-select-font-size: var(--v-input-font-size);
/* label */
--v-multi-select-label-font-size: var(--v-input-label-font-size);
--v-multi-select-label-font-weight: var(--v-input-label-font-weight);
--v-multi-select-label-display: var(--v-input-label-display);
--v-multi-select-label-margin-bottom: var(--v-input-label-margin-bottom);
--v-multi-select-label-color: var(--v-input-label-color);
/* item */
--v-multi-select-item-font-size: var(--size-font-sm);
--v-multi-select-item-font-weight: var(--font-weight-regular);
--v-multi-select-item-bg-color: var(--color-white);
--v-multi-select-item-text-color: var(--color-gray-800);
--v-multi-select-item-padding-x: var(--size-spacing-3);
--v-multi-select-item-padding-y: var(--size-spacing-2);
--v-multi-select-item-hover-bg-color: var(--color-gray-100);
--v-multi-select-item-hover-text-color: var(--color-gray-700);
/* error */
--v-multi-select-error-border-color: var(--color-error-500);
/* icon */
--v-multi-select-icon-color: var(--color-gray-500);
--v-multi-select-icon-size: var(--size-spacing-5);
--v-multi-select-check-icon-color: var(--color-primary-700);
/* dropdown */
--v-multi-select-dropdown-bg-color: var(--color-white);
--v-multi-select-dropdown-border-radius: var(--border-radius-lg);
// hint
--v-multi-select-hint-font-size: var(--v-input-hint-font-size, 14px);
--v-multi-select-hint-color: var(--color-gray-500);
--v-multi-select-hint-margin-top: var(--size-spacing-1);
}:root {
--v-multi-select-border-color: var(--v-input-border-color);
--v-multi-select-border-radius: var(--v-input-border-radius);
--v-multi-select-bg-color: var(--v-input-bg-color);
--v-multi-select-text-color: var(--color-gray-700);
--v-multi-select-height: auto;
--v-multi-select-min-height: var(--v-input-height);
--v-multi-select-placeholder-color: var(--v-input-placeholder-color);
--v-multi-select-border-radius: var(--v-input-border-radius);
--v-multi-select-padding-x: var(--v-input-padding-x);
--v-multi-select-padding-y: var(--size-spacing-2);
--v-multi-select-font-size: var(--v-input-font-size);
/* label */
--v-multi-select-label-font-size: var(--v-input-label-font-size);
--v-multi-select-label-font-weight: var(--v-input-label-font-weight);
--v-multi-select-label-display: var(--v-input-label-display);
--v-multi-select-label-margin-bottom: var(--v-input-label-margin-bottom);
--v-multi-select-label-color: var(--v-input-label-color);
/* item */
--v-multi-select-item-font-size: var(--size-font-sm);
--v-multi-select-item-font-weight: var(--font-weight-regular);
--v-multi-select-item-bg-color: var(--color-white);
--v-multi-select-item-text-color: var(--color-gray-800);
--v-multi-select-item-padding-x: var(--size-spacing-3);
--v-multi-select-item-padding-y: var(--size-spacing-2);
--v-multi-select-item-hover-bg-color: var(--color-gray-100);
--v-multi-select-item-hover-text-color: var(--color-gray-700);
/* error */
--v-multi-select-error-border-color: var(--color-error-500);
/* icon */
--v-multi-select-icon-color: var(--color-gray-500);
--v-multi-select-icon-size: var(--size-spacing-5);
--v-multi-select-check-icon-color: var(--color-primary-700);
/* dropdown */
--v-multi-select-dropdown-bg-color: var(--color-white);
--v-multi-select-dropdown-border-radius: var(--border-radius-lg);
// hint
--v-multi-select-hint-font-size: var(--v-input-hint-font-size, 14px);
--v-multi-select-hint-color: var(--color-gray-500);
--v-multi-select-hint-margin-top: var(--size-spacing-1);
}Standalone Installation
You can also install the Multi Select component individually via @morpheme/multi-select package:
npm i @morpheme/multi-selectnpm i @morpheme/multi-selectThen, use it in your component:
<script setup lang="ts">
import {ref} from 'vue';
import VMultiSelect from '@morpheme/multi-select';
const items = ref([
{
text: 'Item 1',
value: 1,
},
{
text: 'Item 2',
value: 2,
},
{
text: 'Item 2',
value: 2,
},
]);
const selected = ref();
</script>
<template>
<VMultiSelect v-model="selected" :items="items" />
</template><script setup lang="ts">
import {ref} from 'vue';
import VMultiSelect from '@morpheme/multi-select';
const items = ref([
{
text: 'Item 1',
value: 1,
},
{
text: 'Item 2',
value: 2,
},
{
text: 'Item 2',
value: 2,
},
]);
const selected = ref();
</script>
<template>
<VMultiSelect v-model="selected" :items="items" />
</template>Storybook
View Storybook documentation here.
Morpheme