#Overview

Dropdowns are used with Forms (Code).

Show codeHide code
export const DropdownFieldDemo = () => {
  const form = useForm<{ fruits: ISelectOption<string> | null }>();
  return (
    <form onSubmit={form.handleSubmit(() => {})}>
      <DropdownField
        form={form}
        name="fruits"
        label="Favourite Fruit"
        items={fruitOptions}
        options={{
          required: {
            value: true,
            message: "Please provide a value",
          },
        }}
      />
      <ButtonGroup>
        <Button onClick={() => form.reset()}>Reset value</Button>
        <Button variant="primary" type="submit">
          Send
        </Button>
      </ButtonGroup>
    </form>
  );
};

NameTypeDefaultDescription
form *UseFormReturn<TFieldValues>
-

The connected form that the form field is part of

items *Array<ISelectOption<DefaultSelectOption>>
-

The selectable items

name *TFieldName
-

The name of the input being registered from the form

ariaLabelstring
-

An accessible label for screen readers to describe the dropdown's action. Use this when the dropdown is not labelled by any other label element.

ariaLabelledBystring
-

Not applicable when ariaLabel is provided.

dialogLabelReactNode
-

The title that is shown in the dialog option

disabledboolean
-

If true, the input field is disabled

hasErrorboolean
-

If true, turns the border red

helpTextReactNode
-

A help text that can be displayed below the dropdown field

hideHelpAndValidationboolean
-

Hides the help text and validation message

idstring
-

The id of the dropdown

labelReactNode
-

The visible label of the field, displayed in the GUI.

labelOptionalAppendixReactNode
-

Marker inside the label, when the field is optional

labelRequiredAppendixReactNode
-

Marker inside the label, when the field is required

listboxOffsetnumber

4 Distance between the listbox and the actual dropdown.

listboxPlacement"end" | "start"

"start" Placement of the dropdown listbox relative to the parent container. This is only needed if you manipulate the width of the dropdown listbox with styling.

noWrapboolean
-
onBlurFocusEventHandler<HTMLDropdownElement<T>>
-

Callback the field is blurred

onChangeChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the selected item changes

onMenuClose() => void
-

Callback when the menu closes

onMenuOpen() => void
-

Callback when the menu opens

onSelectChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the selected item changes

optionsOmit<RegisterOptions<FormValues, "example">, "disabled" | "setValueAs" | "valueAsDate" | "valueAsNumber">

{ required: { value: true, message: __("Required") } }

The options that can be set for the registration of the field

placeholderstring
-

A hint for the expected value

refRef<HTMLButtonElement>
-

Ref of the dropdown

#Interface ISelectOption

The interface ISelectOption<T> is used to define the items of the dropdown. It is generic typed and will receive the interface of your actual data definition. It has the following properties:

NameTypeDefaultDescription
label *string
-

The label of the option

value *T
-

The value of the option

descriptionstring
-

Description underneath the label on mobile viewports

disabledboolean
-

If the option is disabled

iconReactNode
-

Icon in front of the label

#Customize item rendering

You can add an additional icon and a description for mobile viewports to the dropdown items.

import { LightModeIcon } from "@blocks/icons/LightMode";
import type { ISelectOption } from "@segments/dropdown";

const items: ISelectOption[] = [
  {
    label: "Light",
    description: "Always use the light design",
    value: "light",
    icon: <LightModeIcon />,
  },
  // ...
];

#Styling

Dropdowns are generic components, generic props are exposed for each to style them and preserve their type.

import { Dropdown, type GenericDropdownProps } from "@segments/dropdown";
import { type GenericYakComponentOf, styled } from "next-yak";

const StyledDropdown = styled(Dropdown)`
  margin-bottom: ${spacing[8]};
` as GenericYakComponentOf<GenericDropdownProps>;

#Autocomplete Dropdown

A Dropdown that lets you search for items by keyboard input.

Show codeHide code
export const AutocompleteDropdownFieldDemo = () => {
  const form = useForm<{ fruits: ISelectOption<string> | null }>();
  const [result, setResult] = useState<ISelectOption<string> | null>(null);
  return (
    <>
      <form
        onSubmit={form.handleSubmit(() => {
          setResult(form.getValues().fruits);
        })}
      >
        <AutocompleteDropdownField
          clearable
          form={form}
          name="fruits"
          label="Favourite Fruit"
          items={fruitOptions}
          options={{
            required: {
              value: true,
              message: "Please provide a value",
            },
          }}
        />
        <ButtonGroup>
          <Button onClick={() => form.reset()}>Reset value</Button>
          <Button variant="primary" type="submit">
            Send
          </Button>
        </ButtonGroup>
      </form>
      {result && <div>{`Submitted: ${result.value}`}</div>}
    </>
  );
};

NameTypeDefaultDescription
form *UseFormReturn<TFieldValues>
-

The connected form that the form field is part of

items *Array<ISelectOption<DefaultSelectOption>>
-

The selectable items

name *TFieldName
-

The name of the input being registered from the form

ariaLabelstring
-

An accessible label for screen readers to describe the dropdown's action. Use this when the dropdown is not labelled by any other label element.

ariaLabelledBystring
-

Not applicable when ariaLabel is provided.

clearableboolean
-

If a selected item can be cleared again, default false

createNewValueMessagestring
-

The label that is shown above the creatable option

dialogLabelReactNode
-

The title that is shown in the dialog option

disabledboolean
-

If true, the input field is disabled

hasErrorboolean
-

If true, turns the border red

helpTextReactNode
-

A help text that can be displayed below the input field

hideChevronboolean
-

Hides the chevron toggle button; pair with a custom trailing icon. ref isn't attached on desktop when set. Default false.

hideHelpAndValidationboolean
-

Hides the help text and validation message

idstring
-

The id of the dropdown

initialInputValuestring
-

Seeds the input field with this string when no item is selected. Behaves as if the user had typed it: items are filtered and highlighted accordingly. The menu is not opened until the user interacts. If a value is provided, that item's label takes precedence.

itemsPreFilteredboolean
-

Skips the built-in substring filter and match highlighting — use when items is already filtered to the typed text by the caller (e.g. a server search). Default false.

keepInputValueOnBlurboolean
-

Preserves what the visitor typed when the field blurs, instead of resetting it to the selected item's label (or clearing it). Default false.

keepMenuOpenWhileLoadingboolean
-

Keeps the menu open for existing items while loading, instead of collapsing it during async work. The "no results" message still waits for loading to finish. Default false.

labelReactNode
-

The visible label of the field, displayed in the GUI.

labelOptionalAppendixReactNode
-

Marker inside the label, when the field is optional

labelRequiredAppendixReactNode
-

Marker inside the label, when the field is required

loadingboolean
-

Marks the dropdown as busy with async work the caller manages itself, in addition to onCreateItem's/onInputValueChange's own loading state. Shows the spinner and hides the clear button. Default false.

noItemsMessageReactNode
-

The message shown when no results remain after filtering. Defaults to "No results"; pass null to disable the empty state entirely.

noWrapboolean
-
onBlurChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the dropdown is blurred

onChangeChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the selected item changes and when dropdown changes

onCreateItem(inputValue: string) => Promise<void | ISelectOption<DefaultSelectOption> | undefined>
-

Async callback to create new items. An option for that is shown when the user types something that is not present as an item

onFocusFocusEventHandler<HTMLInputElement>
-

OnFocus of the input field

onInputValueChange(inputValue?: string | undefined) => Promise<void>
-

An optional callback to filter items asynchronous - useful to fetch an API again

onMenuClose() => void
-

Callback when the menu closes

onMenuOpen() => void
-

Callback when the menu opens

onSelectChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the selected item changes

optionsOmit<RegisterOptions<FormValues, "example">, "disabled" | "setValueAs" | "valueAsDate" | "valueAsNumber">

{ required: { value: true, message: __("Required") } }

The options that can be set for the registration of the field

placeholderstring
-

A hint for the expected value

refRef<HTMLDivElement>
-

the ref of the input field

showDialogBackButtonboolean
-

if true, the back button is shown in the dialog on mobile and tablet viewports

#Creating new items

When you pass an onCreateItem callback function, users can create and add new items to the dropdown that don't exist in the original list. This is useful for fields where users might need custom values.

Show codeHide code
export const CreatableAutocompleteDropdownFieldDemo = () => {
  const [creatableOptions, setCreatableOptions] = useState(fruitOptions);
  const [result, setResult] = useState<ISelectOption<string> | null>(null);
  const form = useForm<{ fruits: ISelectOption<string> }>();
  return (
    <>
      <form
        onSubmit={form.handleSubmit(() => {
          setResult(form.getValues().fruits);
        })}
      >
        <AutocompleteDropdownField
          form={form}
          name="fruits"
          label="Favourite Fruit"
          items={creatableOptions}
          onCreateItem={async (inputValue: string) => {
            const newValue = { label: inputValue, value: inputValue };
            setCreatableOptions([...fruitOptions, newValue]);
            return newValue;
          }}
          options={{
            required: {
              value: true,
              message: "Please provide a value",
            },
          }}
        />
        <Button type="submit">Send</Button>
      </form>
      {result && <div>{`Submitted: ${result.value}`}</div>}
    </>
  );
};

#Lazy loading items

If you're using an <AutocompleteDropdown /> or <MultiselectDropdown />, then you can implement the callback onInputValueChange to filter/fetch items. This is useful for data sources that can't be fully loaded initially. So you can use this callback to fetch the items with a new API request. The callback will be called on every keystroke - so it is recommended to implement this with a debounce function to avoid too many requests.

#Multiselect Dropdown

A Dropdown that let you select multiple items and also search for them by keyboard input.

Show codeHide code
export const MultiSelectDropdownFieldDemo = () => {
  const form = useForm<{ fruits: ISelectOption[] }>();
  const [result, setResult] = useState<ISelectOption[] | null>(null);
  return (
    <>
      <form
        onSubmit={form.handleSubmit(() => {
          setResult(form.getValues().fruits);
        })}
      >
        <MultiSelectDropdownField
          form={form}
          name="fruits"
          label="Favourite Fruit"
          items={fruitOptions}
          options={{
            required: {
              value: true,
              message: "Please provide a value",
            },
          }}
        />
        <ButtonGroup>
          <Button onClick={() => form.reset()}>Reset value</Button>
          <Button variant="primary" type="submit">
            Send
          </Button>
        </ButtonGroup>
      </form>
      {result && (
        <div>{`Submitted: ${result.map((item) => item.value).join(", ")}`}</div>
      )}
    </>
  );
};

NameTypeDefaultDescription
form *UseFormReturn<TFieldValues>
-

The connected form that the form field is part of

items *Array<ISelectOption<string>>
-

The selectable items

name *TFieldName
-

The name of the input being registered from the form

ariaLabelstring
-

An accessible label for screen readers to describe the dropdown's action. Use this when the dropdown is not labelled by any other label element.

ariaLabelledBystring
-

Not applicable when ariaLabel is provided.

createNewValueMessagestring
-

The label that is shown above the creatable option

dialogLabelReactNode
-

The title that is shown in the dialog option

disabledboolean
-

If true, the input field is disabled

hasErrorboolean
-

If true, turns the border red

helpTextReactNode
-

A help text that can be displayed below the input field

hideHelpAndValidationboolean
-

Hides the help text and validation message

idstring
-

The id of the dropdown

labelReactNode
-

The visible label of the field, displayed in the GUI.

labelOptionalAppendixReactNode
-

Marker inside the label, when the field is optional

labelRequiredAppendixReactNode
-

Marker inside the label, when the field is required

noItemsMessagestring
-

The message that will show when there are no results left after filtering

noOptionsMessagestring
-

The message that will show when all items have been selected

noWrapboolean
-
onBlurFocusEventHandler<HTMLMultiSelectDropdownElement<T>>
-

Callback when the input field is blurred

onChangeChangeEventHandler<HTMLMultiSelectDropdownElement<T>>
-

Callback when the selected item changes and when input changes

onCreateItem(inputValue: string) => Promise<void | ISelectOption<string> | undefined>
-

Async callback to create new items. An option for that is shown when the user types something that is not present as an item

onInputValueChange(inputValue?: string | undefined) => Promise<void>
-

An optional callback to filter items asynchronous - useful to fetch an API again

optionsOmit<RegisterOptions<FormValues, "example">, "disabled" | "setValueAs" | "valueAsDate" | "valueAsNumber">

{ required: { value: true, message: __("Required") } }

The options that can be set for the registration of the field

placeholderstring
-

A hint for the expected value

refRef<HTMLDivElement>
-

The ref of the input field

showDialogBackButtonboolean
-

if true, the back button is shown in the dialog on mobile and tablet viewports

#Outside of a form

#Dropdown

NameTypeDefaultDescriptionControls
items *Array<ISelectOption<T>>
-

The selectable items

-
value *ISelectOption<T> | null | undefined
-

The value of the input field

-
ariaLabelstring
-

An accessible label for screen readers to describe the dropdown's action. Use this when the dropdown is not labelled by any other label element.

ariaLabelledBystring
-

Not applicable when ariaLabel is provided.

dialogDescriptionstring
-

The description that is shown in the dialog option

dialogLabelReactNode
-

The title that is shown in the dialog option

-
disabledboolean
-

If true, the input field is disabled

hasErrorboolean
-

If true, turns the border red

idstring
-

The id of the dropdown

listboxOffsetnumber

4 Distance between the listbox and the actual dropdown.

listboxPlacement"end" | "start"

"start" Placement of the dropdown listbox relative to the parent container. This is only needed if you manipulate the width of the dropdown listbox with styling.

namestring
-

The name of the dropdown

onBlurFocusEventHandler<HTMLDropdownElement<T>>
-

Callback the field is blurred

-
onChangeChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the selected item changes

-
onMenuClose() => void
-

Callback when the menu closes

-
onMenuOpen() => void
-

Callback when the menu opens

-
onSelectChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the selected item changes

-
placeholderstring
-

A hint for the expected value

refRef<HTMLButtonElement>
-

Ref of the dropdown

-

#Autocomplete Dropdown

NameTypeDefaultDescriptionControls
items *Array<ISelectOption<T>>
-

The selectable items

-
value *ISelectOption<T> | null | undefined
-

The value of the input field

-
ariaLabelstring
-

An accessible label for screen readers to describe the dropdown's action. Use this when the dropdown is not labelled by any other label element.

-
ariaLabelledBystring
-

Not applicable when ariaLabel is provided.

clearableboolean
-

If a selected item can be cleared again, default false

createNewValueMessagestring
-

The label that is shown above the creatable option

dialogLabelReactNode
-

The title that is shown in the dialog option

-
disabledboolean
-

If true, the input field is disabled

hasErrorboolean
-

If true, turns the border red

hideChevronboolean
-

Hides the chevron toggle button; pair with a custom trailing icon. ref isn't attached on desktop when set. Default false.

idstring
-

The id of the dropdown

initialInputValuestring
-

Seeds the input field with this string when no item is selected. Behaves as if the user had typed it: items are filtered and highlighted accordingly. The menu is not opened until the user interacts. If a value is provided, that item's label takes precedence.

itemsPreFilteredboolean
-

Skips the built-in substring filter and match highlighting — use when items is already filtered to the typed text by the caller (e.g. a server search). Default false.

keepInputValueOnBlurboolean
-

Preserves what the visitor typed when the field blurs, instead of resetting it to the selected item's label (or clearing it). Default false.

keepMenuOpenWhileLoadingboolean
-

Keeps the menu open for existing items while loading, instead of collapsing it during async work. The "no results" message still waits for loading to finish. Default false.

loadingboolean
-

Marks the dropdown as busy with async work the caller manages itself, in addition to onCreateItem's/onInputValueChange's own loading state. Shows the spinner and hides the clear button. Default false.

namestring
-

The name of the dropdown

noItemsMessageReactNode
-

The message shown when no results remain after filtering. Defaults to "No results"; pass null to disable the empty state entirely.

-
onBlurChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the dropdown is blurred

-
onChangeChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the selected item changes and when dropdown changes

-
onCreateItem(inputValue: string) => Promise<void | ISelectOption<T> | undefined>
-

Async callback to create new items. An option for that is shown when the user types something that is not present as an item

-
onFocusFocusEventHandler<HTMLInputElement>
-

OnFocus of the input field

-
onInputValueChange(inputValue?: string | undefined) => Promise<void>
-

An optional callback to filter items asynchronous - useful to fetch an API again

-
onMenuClose() => void
-

Callback when the menu closes

-
onMenuOpen() => void
-

Callback when the menu opens

-
onSelectChangeEventHandler<HTMLDropdownElement<T>>
-

Callback when the selected item changes

-
placeholderstring
-

A hint for the expected value

refRef<HTMLButtonElement>
-

Ref of the dropdown

-
showDialogBackButtonboolean
-

if true, the back button is shown in the dialog on mobile and tablet viewports

#Multiselect Dropdown

NameTypeDefaultDescriptionControls
items *Array<ISelectOption<T>>
-

The selectable items

-
value *Array<ISelectOption<T>> | null | undefined
-

The value of the mutli select dropdown

-
ariaLabelstring
-

An accessible label for screen readers to describe the dropdown's action. Use this when the dropdown is not labelled by any other label element.

ariaLabelledBystring
-

Not applicable when ariaLabel is provided.

createNewValueMessagestring
-

The label that is shown above the creatable option

dialogLabelReactNode
-

The title that is shown in the dialog option

-
disabledboolean
-

If true, the input field is disabled

hasErrorboolean
-

If true, turns the border red

idstring
-

The id of the dropdown

namestring
-

The name of the dropdown

noItemsMessagestring
-

The message that will show when there are no results left after filtering

noOptionsMessagestring
-

The message that will show when all items have been selected

onBlurFocusEventHandler<HTMLMultiSelectDropdownElement<T>>
-

Callback when the input field is blurred

-
onChangeChangeEventHandler<HTMLMultiSelectDropdownElement<T>>
-

Callback when the selected item changes and when input changes

-
onCreateItem(inputValue: string) => Promise<void | ISelectOption<T> | undefined>
-

Async callback to create new items. An option for that is shown when the user types something that is not present as an item

-
onInputValueChange(inputValue?: string | undefined) => Promise<void>
-

An optional callback to filter items asynchronous - useful to fetch an API again

-
placeholderstring
-

A hint for the expected value

refRef<HTMLButtonElement>
-

the ref of the mutli select dropdown

-
showDialogBackButtonboolean
-

if true, the back button is shown in the dialog on mobile and tablet viewports

#Colors

Generated from Figma Showcase
  • Token name
  • LABEL_TEXT#0009#fffb#0009#fffb
  • FIELD_BORDER#bbb#fff4#bbb#fff4
  • VALUE_TEXT#0004#fff4#0004#fff4
  • ICONAFTER_BACKGROUND#000d#fffb#000d#fffb
  • CHEVRON#000d#fffb#000d#fffb
  • ICON_SHAPE#000d#fffb#000d#fffb
  • FIELD_BACKGROUND#fff#111#fff#111
  • HELP_TEXT#0009#fffb#0009#fffb
  • LABEL_TEXT_FOCUS#0009#fffb#0009#fffb
  • FIELD_BORDER_FOCUS#555#fff#059#fff
  • VALUE_TEXT_FOCUS#0004#fff4#0004#fff4
  • ICONAFTER_BACKGROUND_FOCUS#000d#fffb#000d#fffb
  • FIELD_BACKGROUND_FOCUS#fff#111#fff#111
  • HELP_TEXT_FOCUS#0009#fffb#0009#fffb
  • LABEL_TEXT_DISABLED#0009#fffb#0009#fffb
  • FIELD_BACKGROUND_DISABLED#0000#fff1#0000#fff1
  • FIELD_BORDER_DISABLED#0001#fff1#0001#fff1
  • VALUE_TEXT_DISABLED#0004#fff4#0004#fff4
  • ICONAFTER_BACKGROUND_DISABLED#0004#fff4#0004#fff4
  • CHEVRON_DISABLED#0004#fff4#0004#fff4
  • ICON_SHAPE_DISABLED#0004#fff4#0004#fff4
  • HELP_TEXT_DISABLED#0009#fffb#0009#fffb
  • LABEL_TEXT_ERROR#0009#fffb#0009#fffb
  • FIELD_BORDER_ERROR#f75#f75#e02#f55
  • VALUE_TEXT_ERROR#0004#fff4#0004#fff4
  • ICONAFTER_BACKGROUND_ERROR#000d#fffb#000d#fffb
  • CHEVRON_ERROR#000d#fffb#000d#fffb
  • ICON_SHAPE_ERROR#000d#fffb#000d#fffb
  • FIELD_BACKGROUND_ERROR#fff#111#fff#111
  • HELP_TEXT_ERROR#c42#f75#e02#f44
  • LABEL_TEXT_FILLED#0009#fffb#0009#fffb
  • FIELD_BORDER_FILLED#555#fff#059#fff
  • VALUE_TEXT_FILLED#000#fff#000#fff
  • ICONAFTER_BACKGROUND_FILLED#000d#fffb#000d#fffb
  • CHEVRON_FILLED#000d#fffb#000d#fffb
  • ICON_SHAPE_FILLED#000d#fffb#000d#fffb
  • FIELD_BACKGROUND_FILLED#fff#111#fff#111
  • HELP_TEXT_FILLED#0009#fffb#0009#fffb