Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new
DocumentationCombobox

Combobox

Autocomplete input and command palette with a list of suggestions.

Interactive preview

Rendered from the shared Frontfriend stories with React Base, the same preview Studio shows. Styling comes from your Design System; the code below is native to Reka UI.

Installation

Complete project setup first. Your configuration must select vue/reka and include your Design System ID.

pnpm exec frontfriend download combobox -f vue --primitive reka

Review dependencies reported by the downloader and keep your source changes in version control.

Usage

<script setup lang="ts">
import { Combobox } from "@/components/ui/combobox";
import { ComboboxInput } from "@/components/ui/combobox";
import { ComboboxContent } from "@/components/ui/combobox";
import { ComboboxList } from "@/components/ui/combobox";
import { ComboboxItem } from "@/components/ui/combobox";
import { reactive } from "vue";
import * as UI from "@/components/ui/combobox";

const Component = UI.Combobox;

const args = reactive(
  {
    "disabled": false,
    "showClear": false,
    "value": "option",
  } satisfies Partial<
    InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
  > &
    Record<string, unknown>,
);
</script>

<template>
  <Combobox v-model="args.value" :disabled="args.disabled"
    ><ComboboxInput
      placeholder="Search..."
      :show-clear="args.showClear"
    /><ComboboxContent
      ><ComboboxList
        ><ComboboxItem value="option">Option 1</ComboboxItem
        ><ComboboxItem value="option2">Option 2</ComboboxItem></ComboboxList
      ></ComboboxContent
    ></Combobox
  >
</template>

Examples

Default

<script setup lang="ts">
import { ref } from "vue";
import { Combobox } from "@/components/ui/combobox";
import { ComboboxAnchor } from "@/components/ui/combobox";
import { ComboboxTrigger } from "@/components/ui/combobox";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
import { ComboboxContent } from "@/components/ui/combobox";
import { ComboboxInput } from "@/components/ui/combobox";
import { ComboboxEmpty } from "@/components/ui/combobox";
import { ComboboxList } from "@/components/ui/combobox";
import { ComboboxItem } from "@/components/ui/combobox";
import * as UI from "@/components/ui/combobox";

const frameworks = [
  { value: "next.js", label: "Next.js" },
  { value: "sveltekit", label: "SvelteKit" },
  { value: "nuxt", label: "Nuxt" },
  { value: "remix", label: "Remix" },
  { value: "astro", label: "Astro" },
];

const Component = UI.Combobox;

const args = {
  "disabled": false,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
const value = ref<(typeof frameworks)[number] | undefined>();
const disabled = args.disabled;
</script>

<template>
  <Combobox v-model="value" by="label">
    <ComboboxAnchor as-child>
      <ComboboxTrigger as-child>
        <Button
          variant="tertiary"
          class="w-[200px] justify-between"
          :disabled="disabled"
        >
          {{ value?.label ?? "Select framework..." }}
          <Icon name="ChevronsUpDown" size="4" class="shrink-0 opacity-50" />
        </Button>
      </ComboboxTrigger>
    </ComboboxAnchor>
    <ComboboxContent>
      <ComboboxInput :show-trigger="false" placeholder="Search framework..." />
      <ComboboxEmpty>No framework found.</ComboboxEmpty>
      <ComboboxList>
        <ComboboxItem
          v-for="framework in frameworks"
          :key="framework.value"
          :value="framework"
          >{{ framework.label }}</ComboboxItem
        >
      </ComboboxList>
    </ComboboxContent>
  </Combobox>
</template>

Clearable

<script setup lang="ts">
import { Combobox } from "@/components/ui/combobox";
import { ComboboxInput } from "@/components/ui/combobox";
import { ComboboxContent } from "@/components/ui/combobox";
import { ComboboxList } from "@/components/ui/combobox";
import { ComboboxItem } from "@/components/ui/combobox";
import * as UI from "@/components/ui/combobox";

const Component = UI.Combobox;

const args = {
  "disabled": false,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <Combobox
    ><ComboboxInput show-clear placeholder="Search..." /><ComboboxContent
      ><ComboboxList
        ><ComboboxItem value="option">Option 1</ComboboxItem
        ><ComboboxItem value="option2">Option 2</ComboboxItem></ComboboxList
      ></ComboboxContent
    ></Combobox
  >
</template>

Disabled

<script setup lang="ts">
import { ref } from "vue";
import { Combobox } from "@/components/ui/combobox";
import { ComboboxAnchor } from "@/components/ui/combobox";
import { ComboboxTrigger } from "@/components/ui/combobox";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
import { ComboboxContent } from "@/components/ui/combobox";
import { ComboboxInput } from "@/components/ui/combobox";
import { ComboboxEmpty } from "@/components/ui/combobox";
import { ComboboxList } from "@/components/ui/combobox";
import { ComboboxItem } from "@/components/ui/combobox";
import * as UI from "@/components/ui/combobox";

const frameworks = [
  { value: "next.js", label: "Next.js" },
  { value: "sveltekit", label: "SvelteKit" },
  { value: "nuxt", label: "Nuxt" },
  { value: "remix", label: "Remix" },
  { value: "astro", label: "Astro" },
];

const Component = UI.Combobox;

const args = {
  "disabled": true,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
const value = ref<(typeof frameworks)[number] | undefined>();
const disabled = args.disabled;
</script>

<template>
  <Combobox v-model="value" by="label" :disabled="disabled">
    <ComboboxAnchor as-child>
      <ComboboxTrigger as-child>
        <Button
          variant="tertiary"
          class="w-[200px] justify-between"
          :disabled="disabled"
        >
          {{ value?.label ?? "Select framework..." }}
          <Icon name="ChevronsUpDown" size="4" class="shrink-0 opacity-50" />
        </Button>
      </ComboboxTrigger>
    </ComboboxAnchor>
    <ComboboxContent>
      <ComboboxInput :show-trigger="false" placeholder="Search framework..." />
      <ComboboxEmpty>No framework found.</ComboboxEmpty>
      <ComboboxList>
        <ComboboxItem
          v-for="framework in frameworks"
          :key="framework.value"
          :value="framework"
          >{{ framework.label }}</ComboboxItem
        >
      </ComboboxList>
    </ComboboxContent>
  </Combobox>
</template>

Grouped

<script setup lang="ts">
import { ref } from "vue";
import { Combobox } from "@/components/ui/combobox";
import { ComboboxAnchor } from "@/components/ui/combobox";
import { ComboboxTrigger } from "@/components/ui/combobox";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
import { ComboboxContent } from "@/components/ui/combobox";
import { ComboboxInput } from "@/components/ui/combobox";
import { ComboboxEmpty } from "@/components/ui/combobox";
import { ComboboxList } from "@/components/ui/combobox";
import { ComboboxGroup } from "@/components/ui/combobox";
import { ComboboxLabel } from "@/components/ui/combobox";
import { ComboboxItem } from "@/components/ui/combobox";
import { ComboboxSeparator } from "@/components/ui/combobox";
import * as UI from "@/components/ui/combobox";

const frameworks = [
  { value: "next.js", label: "Next.js" },
  { value: "sveltekit", label: "SvelteKit" },
  { value: "nuxt", label: "Nuxt" },
  { value: "remix", label: "Remix" },
  { value: "astro", label: "Astro" },
];

const Component = UI.Combobox;

const args = {
  "disabled": false,
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
const value = ref<(typeof frameworks)[number] | undefined>();
const disabled = args.disabled;
</script>

<template>
  <Combobox v-model="value" by="label">
    <ComboboxAnchor as-child>
      <ComboboxTrigger as-child>
        <Button
          variant="tertiary"
          class="w-[200px] justify-between"
          :disabled="disabled"
        >
          {{ value?.label ?? "Select framework..." }}
          <Icon name="ChevronsUpDown" size="4" class="shrink-0 opacity-50" />
        </Button>
      </ComboboxTrigger>
    </ComboboxAnchor>
    <ComboboxContent>
      <ComboboxInput :show-trigger="false" placeholder="Search framework..." />
      <ComboboxEmpty>No framework found.</ComboboxEmpty>
      <ComboboxList>
        <ComboboxGroup>
          <ComboboxLabel>Meta frameworks</ComboboxLabel>
          <ComboboxItem :value="frameworks[0]">Next.js</ComboboxItem>
          <ComboboxItem :value="frameworks[1]">SvelteKit</ComboboxItem>
        </ComboboxGroup>
        <ComboboxSeparator />
        <ComboboxGroup>
          <ComboboxLabel>Others</ComboboxLabel>
          <ComboboxItem :value="frameworks[4]">Astro</ComboboxItem>
        </ComboboxGroup>
      </ComboboxList>
    </ComboboxContent>
  </Combobox>
</template>

API reference

Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Reka UI.

ComboboxEmpty

Prop Type Default Description
class HTMLAttributes["class"] —

ComboboxGroup

Prop Type Default Description
class HTMLAttributes["class"] —
heading string —

ComboboxInput

Prop Type Default Description
class HTMLAttributes["class"] —
disabled boolean —
showClear boolean —
showTrigger boolean —

ComboboxItem

Prop Type Default Description
class HTMLAttributes["class"] —

ComboboxList

Prop Type Default Description
class HTMLAttributes["class"] —

ComboboxSeparator

Prop Type Default Description
class HTMLAttributes["class"] —

ComboboxTrigger

Prop Type Default Description
class HTMLAttributes["class"] —

Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.