Documentation

Everything you need to install, configure, and use @shakiraliswe/searchable-select.

Installation

Install the package with your preferred package manager:

terminal
npm install @shakiraliswe/searchable-select

The following peer dependencies must be installed in your app:

terminal
npm install react react-dom @mui/material @mui/icons-material @emotion/react @emotion/styled

Basic usage

Import SearchableSelect and use it like a controlled MUI Select:

tsx
import { useState } from "react";
import { SearchableSelect } from "@shakiraliswe/searchable-select";

const options = [
  { value: "apple", label: "Apple" },
  { value: "banana", label: "Banana" },
  { value: "cherry", label: "Cherry" },
];

export function FruitPicker() {
  const [value, setValue] = useState<string | number>("apple");

  return (
    <SearchableSelect
      label="Fruit"
      options={options}
      value={value}
      onChange={setValue}
    />
  );
}

Props

SearchableSelect also accepts every other prop of MUI’s Select (except value, onChange, and children), and forwards a ref to the underlying FormControl.

PropTypeDefaultDescription
optionsrequiredSelectOption[]Options rendered in the dropdown.
valuerequiredstring | numberCurrently selected value.
onChangerequired(value: string | number) => voidCalled when a new option is selected.
labelstring""Field label.
loadingbooleanfalseShows a spinner in place of the dropdown arrow and disables the control.
hasSearchbooleantrueShow or hide the in-menu search field.
searchPlaceholderstring"Type to search..."Placeholder text for the search input.
searchDebounceMsnumber0Debounce delay applied to the search filter.
noOptionsContentReactNode"No options found"Rendered when no options match the search query.

Types

The SelectOption shape:

types.ts
interface SelectOption {
  value: string | number;
  label: string;
  disabled?: boolean;
}

Common patterns

Async / loading state

Set loading to true while fetching. The component shows a spinner and blocks interaction until loading completes.

tsx
<SearchableSelect
  label="Fruit"
  options={options}
  value={value}
  onChange={setValue}
  loading={isFetchingOptions}
/>

Debounce large lists

For lists larger than a few hundred items, debounce the search filter to keep typing snappy.

tsx
<SearchableSelect
  label="Country"
  options={countries}
  value={value}
  onChange={setValue}
  searchDebounceMs={200}
/>

Integrating with react-hook-form

The component is controlled — wire it up with a Controller:

tsx
import { Controller, useForm } from "react-hook-form";
import { SearchableSelect } from "@shakiraliswe/searchable-select";

const { control, handleSubmit } = useForm({ defaultValues: { fruit: "apple" } });

<Controller
  name="fruit"
  control={control}
  render={({ field }) => (
    <SearchableSelect
      label="Fruit"
      options={fruits}
      value={field.value}
      onChange={field.onChange}
    />
  )}
/>