Grapes homepage1.57.0
  • Guide
  • Tokens
  • Components
    Grapes on GithubGrapes on Figma
    Interaction
    • Button
    • IconButton
    • FloatingActionBar
    • Link
    Icons
    • Icon
    • HighlightIcon
    Form
    • AmountInput
    • Autocomplete
    • AutocompleteMultiple
    • AutocompletePlace
    • CheckboxBox
    • CheckboxField
    • DatePicker
    • FormField
    • Input
    • OptionGroup
    • PasswordInput
    • PhoneInput
    • RadioBox
    • RadioField
    • RadioGroup
    • Select
    • SwitchField
    • TextArea
    • TextInput
    • Upload
    • UploadButton
    Feedback
    • Badge
    • Banner
    • Callout
    • EmptyState
    • Modal
    • ModalSlideshow
    • DeprecatedModalSlideshow
    • PageModal
    • Skeleton
    • Tag
    • Toast
    • Tooltip
    Data display
    • Accordion
    • Avatar
    • Box
    • Calendar
    • CalendarRange
    • CollapsibleList
    • FileCard
    • InfoTip
    • ListBox
    • ListView
    • Panel
    • SidePanel
    • DeprecatedPreview
    • Table
    • Timeline
    • useDateFormatter
    Navigation
    • DropdownItem
    • DropdownMenu
    • Navigation
    • NavigationItem
    • Popover
    • Tabs

    DropdownMenu

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

    Usage
    This component is not intended to be used within a form. If you need a form element, please refer to the Autocomplete or AutocompleteMultiple components documentation.
    View source code
    • Usage
    • Props

    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} />
    </>
    

    Dropdown width

    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={() => {}} />
                }
              />
            );
          }}
        />
      );
    };