Edit Profile

Dark Mode

Copy config

Copy and paste the following code into your global.css file to apply the styles.

Combobox

Autocomplete input and command palette with a list of suggestions.

Installation

Run the following cli command or copy/paste the component code into your project

qwik-ui add combobox
import { type PropsOf, Slot, component$ } from '@builder.io/qwik';
import { Combobox as HeadlessCombobox } from '@qwik-ui/headless';
import { cn } from '@qwik-ui/utils';
import { LuChevronDown } from '@qwikest/icons/lucide';
 
const Root = (props: PropsOf<typeof HeadlessCombobox.Root>) => {
  return (
    <HeadlessCombobox.Root
      {...props}
      class={cn(
        'flex h-full w-48 flex-col overflow-hidden bg-popover text-popover-foreground',
        props.class,
      )}
      comboboxItemComponent={Item}
      comboboxItemLabelComponent={ItemLabel}
    >
      {props.children}
    </HeadlessCombobox.Root>
  );
};
 
const Label = component$<PropsOf<typeof HeadlessCombobox.Label>>(({ ...props }) => {
  return (
    <HeadlessCombobox.Label {...props} class={cn('text-sm', props.class)}>
      <Slot />
    </HeadlessCombobox.Label>
  );
});
 
const ItemLabel = component$<PropsOf<typeof HeadlessCombobox.ItemLabel>>(
  ({ ...props }) => {
    return (
      <HeadlessCombobox.ItemLabel {...props} class={cn('text-sm', props.class)}>
        <Slot />
      </HeadlessCombobox.ItemLabel>
    );
  },
);
 
const ItemIndicator = component$<PropsOf<typeof HeadlessCombobox.ItemIndicator>>(
  ({ ...props }) => {
    return (
      <HeadlessCombobox.ItemIndicator {...props} class={cn('text-sm', props.class)}>
        <Slot />
      </HeadlessCombobox.ItemIndicator>
    );
  },
);
 
const Control = component$<PropsOf<typeof HeadlessCombobox.Control>>((props) => {
  return (
    <HeadlessCombobox.Control
      {...props}
      class={cn('relative flex items-center rounded-base', props.class)}
    >
      <Slot />
    </HeadlessCombobox.Control>
  );
});
 
const Input = component$<PropsOf<typeof HeadlessCombobox.Input>>((props) => {
  return (
    <HeadlessCombobox.Input
      {...props}
      class={cn(
        'flex h-10 w-full rounded-md border border-input py-3 pl-2 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',
        props.class,
      )}
    />
  );
});
 
const Trigger = component$<PropsOf<typeof HeadlessCombobox.Trigger>>(({ ...props }) => {
  return (
    <HeadlessCombobox.Trigger
      {...props}
      class={cn('group absolute right-0 h-6 w-6', props.class)}
    >
      <LuChevronDown class="stroke-foreground transition-transform duration-500 group-aria-expanded:-rotate-180" />
    </HeadlessCombobox.Trigger>
  );
});
 
const Popover = component$<PropsOf<typeof HeadlessCombobox.Popover>>((props) => {
  return (
    <HeadlessCombobox.Popover
      {...props}
      class={cn('w-48 rounded-base border p-2', props.class)}
    >
      <Slot />
    </HeadlessCombobox.Popover>
  );
});
 
const Item = component$<PropsOf<typeof HeadlessCombobox.Item>>(({ ...props }) => {
  return (
    <HeadlessCombobox.Item
      {...props}
      class={cn(
        'group flex justify-between gap-4 rounded-sm px-2 text-foreground aria-disabled:font-light aria-disabled:text-muted-foreground data-[highlighted]:cursor-pointer data-[highlighted]:bg-accent',
        props.class,
      )}
    >
      <Slot />
    </HeadlessCombobox.Item>
  );
});
 
export const Combobox = {
  Root,
  Label,
  Control,
  Input,
  Trigger,
  Popover,
  Item,
  ItemLabel,
  ItemIndicator,
};