Skip to content

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 ​

NameTypeDefault
itemsArray as PropType<VMultiSelectItem[]>[]
itemTextstring'text'
itemValuestringvalue
searchBystring''
placeholderstring'Search...'
namestring''
errorbooleanfalse
errorMessagesArray'[]'
clearableboolean'false'
disabledboolean'false'
readonlyboolean'false'
maxBadgenumber0
delaynumber'500'
idstring''
inputPropsObject as PropType<Record<string, any>>'{}'
selectAllbooleanfalse
loadingbooleanfalse
wrapperClassstring''
inputClassstring''
badgeColorstring'primary'
badgeClassstring''
badgePropsobject{}
dropdownClassstring''
itemClassstring''
checkWrapperClassstring''
checkIconClassstring''
noDataClassstring''
loadingClassstring''
labelstring''
labelClassstring'mb-2 block'
rulesstring''
errorClassstring'text-error-600 mt-1 text-sm'
transitionstring'fade'
hintString''
hideErrorBooleanfalse

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.

vue
<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.

vue
<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>

This event is emitted when the user performs a search in the VMultiSelect component. It is emitted with the search query string.

vue
<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.

vue
<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

PropValueDescription
indexnumberIndex of the current selection
itemanyCurrent selected item at given index
valuestringLabel of selected item.
onRemovefunctionCallback 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

PropValueDescription
lengthnumberNumber 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

PropValueDescription
iSelectedbooleanA flag to indicate if all options is currently selected
onClickfunctionCallback 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

PropValueDescription
indexnumberIndex of the current selection
itemanyCurrent selected item at given index
valuestringLabel of selected item.
iSelectedbooleanA flag to indicate if it is currently selected

CSS Variables ​

scss
: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:

bash
npm i @morpheme/multi-select
npm i @morpheme/multi-select

Then, use it in your component:

vue
<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.