DropdownMenu

A dropdown menu displays a list of actions or options to a user.

View source code

Import

  • DropdownMenu: The dropdown component.
  • DropdownItem: A helper component designed to represent a complex item inside a list.

Basic usage

const costCenters = [
  { key: "marketing", label: "Marketing" },
  { key: "legal", label: "Legal" },
  { key: "office", label: "Office" },
  { key: "platform", label: "Platform" },
  { key: "finance", label: "Finance" },
  { key: "recruitment", label: "Recruitment" },
];

const Demo = () => {
  const [selectedOption, setSelectedOption] = useState<string | undefined>();

  return (
    <DropdownMenu
      options={costCenters}
      renderButton={(getToggleButtonProps) => (
        <Button
          {...getToggleButtonProps()}
          variant="tertiaryNeutral"
          text="Cost centers"
        />
      )}
      renderOption={(option) => (
        <DropdownItem
          label={option.label}
          isSelected={selectedOption === option.key}
        />
      )}
      onSelect={(option) => {
        if (option) {
          setSelectedOption(option.key);
        }
      }}
    />
  );
};

Placement

The placement prop lets you decide where the dropdown content should appear.

<>
  <DropdownMenu placement="bottom-start" {...otherProps} />
  <DropdownMenu placement="bottom-end" {...otherProps} />
  <DropdownMenu placement="top-start" {...otherProps} />
  <DropdownMenu placement="top-end" {...otherProps} />
</>

Setting a width and the button fit prop to parent will make the dropdown content fit the button's size.

<DropdownMenu
  renderButton={(getToggleButtonProps) => (
    <div className="w-[300px]">
      <Button fit="parent" {...otherButtonProps} />
    </div>
  )}
  {...otherProps}
/>

Keep open on select

The keepOpenOnSelect prop makes the dropdown content stay visible when options are selected. This can be useful for filters.

const costCenters = [
  { key: "marketing", label: "Marketing" },
  { key: "legal", label: "Legal" },
  { key: "office", label: "Office" },
  { key: "platform", label: "Platform" },
  { key: "finance", label: "Finance" },
  { key: "recruitment", label: "Recruitment" },
];

const Demo = () => {
  const [selectedOptions, setSelectedOptions] = useState<string[] | undefined>(
    undefined
  );

  return (
    <DropdownMenu
      keepOpenOnSelect
      renderButton={(getToggleButtonProps) => (
        <Button
          {...getToggleButtonProps()}
          variant="tertiaryNeutral"
          text="Cost centers"
        />
      )}
      options={costCenters}
      onSelect={(option) => {
        if (selectedOptions?.includes(option.key)) {
          const filteredSelectedOptions = selectedOptions?.filter(
            (s) => s !== option.key
          );
          setSelectedOptions(
            filteredSelectedOptions.length ? filteredSelectedOptions : undefined
          );
        } else {
          setSelectedOptions([...(selectedOptions ?? []), option.key]);
        }
      }}
      renderOption={(option) => {
        const isSelected = selectedOptions
          ? selectedOptions.includes(option.key)
          : false;
        return (
          <DropdownItem
            key={option.key}
            label={option.label}
            isSelected={isSelected}
            isHighlighted={isSelected}
            prefix={
              <CheckboxInput isChecked={isSelected} onChange={() => {}} />
            }
          />
        );
      }}
    />
  );
};