esc

Type to search...

Grouped Dropdowns

Both single and multi-select variants with grouped options. Categories are computed dynamically from the filtered results. Try searching to see how group headers update as options are filtered.

Single Select with Groups

Dropdown Icon

Multi Select with Groups

Dropdown Icon

The code

GroupsExample.tsx
import { SearchableDropdown } from "@luciodale/react-searchable-dropdown";
import "@luciodale/react-searchable-dropdown/dist/single-style.css";
import { useState } from "react";

type Food = {
  label: string;
  value: string;
  category: string;
  disabled?: boolean;
};

const foods: Food[] = [
  { label: "Pork", value: "pork", category: "meat", disabled: true },
  { label: "Chicken", value: "chicken", category: "meat" },
  { label: "Carrots", value: "carrots", category: "veggies" },
  { label: "Tuna", value: "tuna", category: "fish" },
  { label: "Apple", value: "apple", category: "fruit" },
  // ...
];

function handleGroups(matchingOptions: Food[]) {
  const grouped = matchingOptions.reduce(
    (acc, entry) => {
      const key = entry.category || "Other";
      acc[key] = (acc[key] || 0) + 1;
      return acc;
    },
    {} as Record<string, number>,
  );

  return {
    groupCategories: Object.keys(grouped),
    groupCounts: Object.values(grouped),
  };
}

function GroupedFoodPicker() {
  const [value, setValue] = useState<Food | undefined>(undefined);

  return (
    <SearchableDropdown
      options={foods}
      value={value}
      setValue={setValue}
      searchOptionKeys={["label"]}
      placeholder="Pick a food..."
      dropdownOptionsHeight={320}
      handleGroups={handleGroups}
      groupContent={(index, categories) => (
        <div className="lda-dropdown-group">
          {categories[index]}
        </div>
      )}
    />
  );
}