Skip to content

Taggable Selector ​

A searchable multi-select dropdown that displays selected options as tags inside the trigger, and can emit a create event when the user types a value that isn't in the list. Built on top of Selector and Tag.

Live Demo ​

Basic ​

Selected: None

Creatable ​

Type a value that isn't in the list, then either click the Create "…" button or press Enter while nothing matches. The @create handler decides what to do with the new value.

Selected: None

Usage ​

Basic (select only) ​

Pass :allow-create="false" when the list is fixed and users should not add new options.

vue
<script setup>
const selected = ref([]);
const options = [
  { id: 1, text: "Option A", variant: "accent" },
  { id: 2, text: "Option B", variant: "neutral" },
];
</script>

<template>
  <orio-taggable-selector
    v-model="selected"
    :options="options"
    :allow-create="false"
    placeholder="Select options"
  />
</template>

Creatable with a custom label key ​

field and option-name let you use any option shape — they default to "id" and "text".

vue
<script setup>
const allSkills = ref([
  { id: "vue", name: "Vue" },
  { id: "nuxt", name: "Nuxt" },
]);
const selected = ref([]);
const search = ref("");

function createSkill(name) {
  const skill = { id: name.toLowerCase(), name };
  allSkills.value.push(skill);
  selected.value.push(skill);
}
</script>

<template>
  <orio-taggable-selector
    v-model="selected"
    v-model:search="search"
    :options="allSkills"
    field="id"
    option-name="name"
    label="Skills"
    @create="createSkill"
  />
</template>

How It Works ​

TaggableSelector wraps Selector with multiple forced on. The trigger renders each selected option as an <orio-tag> plus a search <input>. As you type, the option list is fuzzy-filtered (via useFuzzySearch, keyed on optionName). Selecting an option checks it in the dropdown and adds a chip to the trigger.

The create flow is opt-out. When allow-create is true (the default) and the search text is non-empty and does not exactly match an existing option, a sticky "Create …" button appears at the bottom of the dropdown. The component emits @create(searchText) when:

  • the Create button is clicked, or
  • the user presses Enter while no options match the search.

If matches are visible, Enter selects the highlighted option instead of creating. When the search matches nothing, the dropdown shows a "No matches found" empty state above the Create button. On create, the search input is cleared.

@create does not mutate options or the selection — the parent owns persistence. Push the new option into your list (and into v-model, if it should be selected) inside the handler, as the examples above do.

Keyboard ​

The dropdown reuses Selector's roving-list navigation, so it is keyboard-operable just like a plain multi-select:

  • ↓ / ↑ — move the highlighted option (opening the list seeds the highlight, so the first press has an anchor).
  • Enter — select the highlighted option; or, when nothing matches, create (see above).
  • Esc — close the dropdown.

Typing keys stay with the search input — only arrows and Esc drive the list while the input is focused.

Props ​

Inherits all Selector props except multiple (always true).

PropTypeDefaultDescription
optionsSelectableOption[]—Options to select from (strings or objects).
fieldstring'id'Key used as the unique identifier on object options.
optionNamestring'text'Key used for the visible label and fuzzy search on object options.
placeholderstringi18n defaultPlaceholder shown in the search input when nothing is selected.
tagVariant'neutral' | 'accent'—Variant applied to every chip (there is no per-option variant).
allowCreatebooleantrueShow the "Create …" button and allow Enter-to-create. false disables it.
labelstring—Label text (passed through to ControlElement).
size'xs'…'xl'inheritedControl size (passed through to ControlElement).

Models ​

ModelTypeDefaultDescription
v-modelSelectableOption[][]Two-way binding for the selected options array.
v-model:searchstring''Two-way binding for the search input. Cleared on create.

Events ​

EventPayloadDescription
createstringThe user asked to create a new option (Create button, or Enter with no matches). The search text.

i18n ​

KeyEnglish
taggableSelector.placeholderSelect options
taggableSelector.createCreate "{search}"
taggableSelector.noMatchesNo matches found

Styling ​

Selected tags wrap inside the trigger with flex-wrap:

css
--color-accent-soft   /* Accent tag background */
--color-accent-border /* Accent tag border */
--color-surface       /* Neutral tag background */
--color-border        /* Neutral tag border */