Skip to content

Multiselect Component

A customizable, feature-rich dropdown select component that replaces external multiselect packages. Supports single selection, multiple selection, tagging, autocomplete search, grouping, custom styling, lazy loading, and debounce search.


Table of Contents


Import

ts
import { Multiselect } from "dolphin-components";
import type { MultiselectProps, MultiselectOption } from "dolphin-components";

Props

Prop NameTypeDefaultDescription
modelValueany[]Selected option(s). Can be an object, string, or array.
optionsMultiselectOption[]-Array of available options.
multiplebooleanfalseEnable multiple selections.
searchablebooleantrueShow search input field for filtering options.
placeholderstring"Select option"Placeholder text when empty.
disabledbooleanfalseDisable interactions.
loadingbooleanfalseShow built-in spinner.
labelstring-Key to use as label when options are objects.
trackBystring-Key to track option identity (needed for objects).
allowEmptybooleantrueAllow clearing selection entirely.
closeOnSelectbooleantrueAutomatically close dropdown after selection.
hideSelectedbooleanfalseHide selected options from the dropdown list.
taggablebooleanfalseAllow user to create custom tags.
tagPlaceholderstring"Press enter to create a tag"Placeholder shown when entering a new tag.
tagPosition"top" | "bottom""top"Position of the custom tag in suggestions.
groupValuesstring-Property key containing nested group option arrays.
groupLabelstring-Property key representing group labels.
groupSelectbooleanfalseAllow clicking a group label to select/deselect the whole group.
maxHeightnumber300Maximum height in pixels of the options dropdown.
limitnumber99999Maximum number of tags visible in display field before truncating.
limitText(count: number) => stringand X moreFormatter function for truncated items.
debounceSearchbooleanfalseDebounce the search-change emission.
debounceSecondnumber3Seconds to debounce search inputs.
useTeleportbooleanfalseTeleport dropdown menu to target container.
teleportTargetstring | object"body"Teleport destination element selector.

Emitted Events

Event NamePayloadDescription
update:modelValueanyEmitted when value is selected/removed (supports v-model).
select(option, id)Emitted when an option is selected.
remove(option, id)Emitted when an option is deselected.
tag(label, id)Emitted when a new tag is created.
open(id)Emitted when dropdown opens.
close(value, id)Emitted when dropdown closes.
search-change(query)Emitted when user types in search input.

Slots

Slot NameScope ParametersDescription
carettoggleCustom caret dropdown button.
clearsearchElement to clear selection/search.
selectionsearch, remove, values, isOpenCustom display area for selected tags/values.
tagoption, search, removeCustom tag elements layout.
optionoption, search, indexCustom item layout in suggestions dropdown.
noResultsearchContent to show when search returns zero results.
noOptions-Content to show when options list is empty.

Usage Examples

1. Basic Single Select

vue
<template>
  <Multiselect
    v-model="selectedUser"
    :options="users"
    label="name"
    trackBy="id"
    placeholder="Select a manager"
  />
</template>

<script setup>
import { ref } from "vue";
import { Multiselect } from "dolphin-components";

const selectedUser = ref(null);
const users = ref([
  { id: 101, name: "Alice Smith" },
  { id: 102, name: "Bob Jones" },
  { id: 103, name: "Charlie Miller" },
]);
</script>

2. Multi-Select with Search Limit

vue
<template>
  <Multiselect
    v-model="selectedTechs"
    :options="technologies"
    :multiple="true"
    :closeOnSelect="false"
    :limit="3"
    placeholder="Choose your tech stack"
  />
</template>

<script setup>
import { ref } from "vue";
import { Multiselect } from "dolphin-components";

const selectedTechs = ref([]);
const technologies = ref([
  "Vue",
  "React",
  "TypeScript",
  "Node.js",
  "Vite",
  "TailwindCSS",
]);
</script>

3. Option Grouping

vue
<template>
  <Multiselect
    v-model="selectedDrink"
    :options="menu"
    groupValues="items"
    groupLabel="category"
    :groupSelect="true"
    label="name"
    trackBy="id"
    placeholder="Choose a beverage"
  />
</template>

<script setup>
import { ref } from "vue";
import { Multiselect } from "dolphin-components";

const selectedDrink = ref(null);
const menu = ref([
  {
    category: "Hot Drinks",
    items: [
      { id: 1, name: "Espresso" },
      { id: 2, name: "Green Tea" },
    ],
  },
  {
    category: "Cold Drinks",
    items: [
      { id: 3, name: "Iced Latte" },
      { id: 4, name: "Lemonade" },
    ],
  },
]);
</script>

TypeScript Interfaces

typescript
interface MultiselectOption {
  [key: string]: any;
}

interface MultiselectProps {
  modelValue: any;
  options: MultiselectOption[];
  multiple?: boolean;
  searchable?: boolean;
  placeholder?: string;
  disabled?: boolean;
  loading?: boolean;
  label?: string;
  trackBy?: string;
  allowEmpty?: boolean;
  closeOnSelect?: boolean;
  hideSelected?: boolean;
  taggable?: boolean;
  tagPlaceholder?: string;
  tagPosition?: "top" | "bottom";
  groupValues?: string;
  groupLabel?: string;
  groupSelect?: boolean;
  maxHeight?: number;
  limit?: number;
  limitText?: (count: number) => string;
  debounceSearch?: boolean;
  debounceSecond?: number;
  useTeleport?: boolean;
  teleportTarget?: string | object;
}

Styling Notes

The component relies on .multiselect classes. It integrates with the standard input validation state:

  • When using the v-input-error directive, if there is a validation error, the container's .multiselect__tags element will automatically receive the .input-error class, highlighting its border in red.

Best Practices

  1. Always use label and trackBy for object options — Without these, the component can't identify or display options.
  2. Use closeOnSelect="false" for multi-select — Keeps the dropdown open for selecting multiple items in succession.
  3. Use debounceSearch for API-backed search — Prevents rapid-fire API calls while the user types.
  4. Set reasonable limit values — Controls how many selected tags are visible before showing a "+X more" badge.
  5. Use useTeleport inside scrollable containers — Prevents the dropdown from being clipped by parent overflow: hidden.

Troubleshooting

  • Check that disabled is not set to true.
  • Ensure the options array is populated.

Selected value not displaying

  • Verify that label points to the correct property on your option objects.
  • Ensure trackBy is set when using object options.
  • Use :useTeleport="true" and teleportTarget="body" to render the dropdown outside the parent container.