Skip to content
Vy logo
  • Identitet
  • Spor
  • Resources
Components

Combobox

A Combobox is a dropdown list you can search in and filter.

GitHub

Examples

A simple combobox

<Combobox label="Velg et land">
  <Item key="no" textValue="Norge">Norge</Item>
  <Item key="se" textValue="Sverige">Sverige</Item>
  <Item key="dk" textValue="Danmark">Danmark</Item>
  <Item key="fi" textValue="Finland">Finland</Item>
  <Item key="de" textValue="Tyskland">Tyskland</Item>
  <Item key="fr" textValue="Frankerike">Frankrike</Item>
  <Item key="nl" textValue="Nederland">Nederland</Item>
</Combobox>

A combobox with a label and a description

<Combobox label="Velg et land">
  <Item key="no" textValue="Norge">
    <ItemLabel>Norge</ItemLabel>
    <ItemDescription>Europa</ItemDescription>
  </Item>
  <Item key="br" textValue="Brasil">
    <ItemLabel>Brasil</ItemLabel>
    <ItemDescription>Sør-Amerika</ItemDescription>
  </Item>
  <Item key="as" textValue="Australia">
    <ItemLabel>Australia</ItemLabel>
    <ItemDescription>Oseania</ItemDescription>
  </Item>
  <Item key="jp" textValue="Japan">
    <ItemLabel>Japan</ItemLabel>
    <ItemDescription>Asia</ItemDescription>
  </Item>
  <Item key="ca" textValue="Canada">
    <ItemLabel>Canada</ItemLabel>
    <ItemDescription>Nord-Amerika</ItemDescription>
  </Item>
  <Item key="sa" textValue="Sør-Afrika">
    <ItemLabel>Sør-Afrika</ItemLabel>
    <ItemDescription>Afrika</ItemDescription>
  </Item>
</Combobox>

A combobox with invalid state and error text, for form validation

<Combobox label="Velg et land" invalid errorText="This field is required">
  <Item key="de" textValue="Tyskland">Tyskland</Item>
  <Item key="fr" textValue="Frankerike">Frankrike</Item>
  <Item key="nl" textValue="Nederland">Nederland</Item>
</Combobox>

A combobox with sections

<Combobox label="Hvor vil du reise">
  <Section title="Skandinavia">
    <Item key="no">
      🇳🇴 Norge
    </Item>
    <Item key="se">
      🇸🇪 Sverige
    </Item>
    <Item key="dk">
      🇩🇰 Danmark
    </Item>
  </Section>
  <Section title="Asia">
    <Item key="jp">
      🇯🇵 Japan
    </Item>
    <Item key="ch">
      🇨🇳 Kina
    </Item>
    <Item key="in">
      🇮🇳 India
    </Item>
  </Section>
</Combobox>

A slightly more advanced combobox with controlled input and dynamic data

() => {
  const [query, setQuery] = React.useState("");
  const items = [
    {
      title: "Nylige søk",
      children: [
        {
          title: "Oslo S",
          description: "Kollektivknutepunkt i Oslo",
        },
        {
          title: "Sesam Stasjon",
          description: "Barnehagestasjon i Lørenskog",
        },
      ],
    },
    {
      title: "Stopp",
      children: [
        {
          title: "Lillestrøm S",
          description: "Kollektivknutepunkt i Oslo",
        },
        {
          title: "Lillehammer S",
          description: "Kollektivknutepunkt i Innlandet",
        },
      ],
    },
  ];
  return (
    <Combobox
      label="Fra"
      items={items}
      onInputChange={setQuery}
      inputValue={query}
    >
      {(section) => (
        <Section
          key={section.title}
          items={section.children}
          title={section.title}
        >
          {(item) => (
            <Item key={item.title} textValue={item.title}>
              <ItemLabel textStyle="sm" fontWeight="bold">
                {item.title}
              </ItemLabel>
              <ItemDescription textStyle="xs">
                {item.description}
              </ItemDescription>
            </Item>
          )}
        </Section>
      )}
    </Combobox>
  );
};

A combobox with icon on the left

<Combobox label="Velg et land" leftIcon={<DepartureFill24Icon/>}>
  <Item key="no" textValue="Norge">Norge</Item>
  <Item key="se" textValue="Sverige">Sverige</Item>
  <Item key="dk" textValue="Danmark">Danmark</Item>
  <Item key="fi" textValue="Finland">Finland</Item>
  <Item key="de" textValue="Tyskland">Tyskland</Item>
  <Item key="fr" textValue="Frankerike">Frankrike</Item>
  <Item key="nl" textValue="Nederland">Nederland</Item>
</Combobox>

Guidelines

A combobox is a useful tool when you need to choose from a long list of options. It allows users to search within the list, making it easier and faster to navigate using the keyboard rather than scrolling through potentially many items.

If there are fewer options or filtering isn’t necessary, you might want to use the InfoSelect or NativeSelect components instead.

Each item in a combobox dropdown can be styled however you like — but try to keep them simple and easy to scan, so users experience the list as clear and organized.

Code

<Combobox />

import { Combobox } from "@vygruppen/spor-react";

A combobox is a searchable select box

Props

Name
Type
Required?
Description
labelstringText that describes what to choose from. One or few words
itemsobject[]If you want to render a dynamic list of items, pass them in here instead of mapping them out as <Item /> items
children((item: Item) => React.ReactElement) | React.ReactElementEither a list of <Item /> or <Section /> items, or a render function that accepts each element as a prop, and returns an Item component.
onSelectionChange(selectedItem: T) => voidCallback that receives the selected item
loadingbooleanSet if the combobox is waiting for new items from the server
variant"core" | "floating"Defaults to base.

<SelectItem />

import { SelectItem } from "@vygruppen/spor-react";

Used in a InfoSelect or Combobox

Props

Name
Type
Required?
Description
keystring
textValuestringThe text version of the item, used by screen readers
childrenReact.ReactNodeThe content of the item
valuenumber | stringThe value returned when selected
itemobject[]Example { label: "Train", value: "train", description: "Tougher than trains", icon: "arrow" }

<Section />

import { Section } from "@vygruppen/spor-react";

A Section can be used to split up lists in InfoSelect and Combobox

Props

Name
Type
Required?
Description
titlestringThe title of the section
children((item: T) => React.ReactElement) | React.ReactElementEither a render function that retuns a list of item tags, or a hard coded list of Item tags

<ItemLabel />

import { ItemLabel } from "@vygruppen/spor-react";

Used within an Item, and used to enhance the experience for scren reader users

Props

Name
Type
Required?
Description
childrenReact.ReactNode

<ItemDescription />

import { ItemDescription } from "@vygruppen/spor-react";

Further description or context for screen reader users

Props

Name
Type
Required?
Description
childrenReact.ReactNode