Skip to content

Select ​

Dropdown select built on Nuxt UI's USelectMenu with form field wrapper, v-model support, and optional creatable mode.

vue
<script setup lang="ts">
import RyderSelect from "@opeolluwa/ryder/components/primitives/Select.vue"
import { ref } from "vue";

const items = ref(["apple", "banana"]);
const value = ref("");
</script>

<template>
  <RyderSelect v-model="value" :items="items" label="Fruit" />
</template>

Examples ​

Basic ​

vue
<script setup lang="ts">
import Select from "../../../src/components/primitives/Select.vue";
import { ref } from "vue";

const items = ref([
  { label: "Apple", value: "apple" },
  { label: "Banana", value: "banana" },
  { label: "Orange", value: "orange" },
]);
const value = ref("");
</script>

<template>
  <div class="flex flex-col gap-4">
    <Select
      v-model="value"
      label="Fruit"
      placeholder="Select a fruit"
      :items="items"
    />
    <p class="text-sm text-muted">{{ value }}</p>
  </div>
</template>

Creatable ​

Allows typing new values not in items; emits @create so parent can append.

vue
<script setup lang="ts">
import Select from "../../../src/components/primitives/Select.vue";
import { ref } from "vue";

const items = ref([
  { label: "Apple", value: "apple" },
  { label: "Banana", value: "banana" },
  { label: "Orange", value: "orange" },
]);
const value = ref("");

function handleCreate(term: string) {
  const newValue = term.toLowerCase().trim();
  if (!newValue) return;
  const exists = items.value.some((item) => {
    const itemValue = typeof item === "string" ? item : item.value;
    return itemValue.toLowerCase() === newValue;
  });
  if (!exists) {
    items.value.push({ label: term, value: newValue });
  }
  value.value = newValue;
}
</script>

<template>
  <div class="flex flex-col gap-4">
    <Select
      v-model="value"
      label="Fruit"
      placeholder="Type to add new fruit"
      :items="items"
      creatable
      @create="handleCreate"
    />
    <p class="text-sm text-muted">{{ value }}</p>
  </div>
</template>

Props ​

PropTypeDefaultDescription
labelstringundefinedField label.
iconstringundefinedLeading icon name.
classNamestringundefinedAdditional classes for select.
namestringundefinedField name for form validation.
trailingIconstringundefinedTrailing icon name.
placeholderstringundefinedPlaceholder text.
hintstringundefinedHint text below field.
avatarstringundefinedAvatar image src passed to USelectMenu.
disabledbooleanfalseDisable the select.
preserveCasebooleanfalsePreserve case instead of lowercasing.
size"xs" | "sm" | "md" | "lg" | "xl""md"Select size.
itemsstring[] | { label: string; value: string }[]undefinedRequired: list of options.
labelClassstringundefinedAdditional classes for label.
creatablebooleanfalseAllow creating new items; emits create event.

Emits ​

EventPayloadWhen
create[term: string]When a new item is created in creatable mode.

Slots ​

None.

Notes ​

  • Uses v-model with defineModel<string>().
  • Adjusts placeholder text size based on size prop (matches Input).
  • When creatable is true, the typed term is emitted via @create — parent must append to items for it to remain selectable (see examples).
  • value-key="value" is set; items can be strings or objects with label/value.