CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-select

A Select control built with and for ReactJS that provides comprehensive dropdown functionality with support for single/multi-select, async data loading, search filtering, and extensive customization.

Pending
Overview
Eval results
Files

core-components.mddocs/

Core Components

React-Select provides four main component variants that cover different interaction patterns and use cases. Each component is fully generic and type-safe, supporting custom Option and Group types.

Capabilities

Select (Default Component)

The main select component with built-in state management for standard dropdown interactions.

/**
 * Main select component with built-in state management
 * @param props - Complete Props interface with 69+ configuration options
 * @returns JSX.Element representing the select component
 */
function Select<
  Option = unknown,
  IsMulti extends boolean = false,
  Group extends GroupBase<Option> = GroupBase<Option>
>(props: Props<Option, IsMulti, Group>): JSX.Element;

interface Props<Option, IsMulti extends boolean, Group extends GroupBase<Option>> {
  // Core Data Props
  options: OptionsOrGroups<Option, Group>;
  value?: PropsValue<Option>;
  defaultValue?: PropsValue<Option>;
  isMulti?: IsMulti;
  
  // Event Handlers
  onChange?: (newValue: OnChangeValue<Option, IsMulti>, actionMeta: ActionMeta<Option>) => void;
  onInputChange?: (newValue: string, actionMeta: InputActionMeta) => void;
  onMenuOpen?: () => void;
  onMenuClose?: () => void;
  onFocus?: FocusEventHandler<HTMLInputElement>;
  onBlur?: FocusEventHandler<HTMLInputElement>;
  
  // Behavior Configuration
  isSearchable?: boolean;
  isClearable?: boolean;
  isDisabled?: boolean;
  isLoading?: boolean;
  autoFocus?: boolean;
  openMenuOnClick?: boolean;
  openMenuOnFocus?: boolean;
  closeMenuOnSelect?: boolean;
  closeMenuOnScroll?: boolean | ((event: Event) => boolean);
  
  // Display Options
  placeholder?: ReactNode;
  noOptionsMessage?: (obj: { inputValue: string }) => ReactNode;
  loadingMessage?: (obj: { inputValue: string }) => ReactNode;
  
  // Data Processing
  getOptionLabel?: (option: Option) => string;
  getOptionValue?: (option: Option) => string;
  getOptionValue?: (option: Option) => string;
  isOptionDisabled?: (option: Option, selectValue: Options<Option>) => boolean;
  isOptionSelected?: (option: Option, selectValue: Options<Option>) => boolean;
  filterOption?: ((option: FilterOptionOption<Option>, inputValue: string) => boolean) | null;
  
  // Menu Configuration
  menuIsOpen?: boolean;
  menuPlacement?: MenuPlacement;
  menuPosition?: MenuPosition;
  menuPortalTarget?: HTMLElement | null;
  maxMenuHeight?: number;
  minMenuHeight?: number;
  
  // Styling
  className?: string;
  classNamePrefix?: string;
  classNames?: ClassNamesConfig<Option, IsMulti, Group>;
  styles?: StylesConfig<Option, IsMulti, Group>;
  theme?: ThemeConfig;
  unstyled?: boolean;
  
  // Component Customization
  components?: SelectComponentsConfig<Option, IsMulti, Group>;
  
  // Accessibility
  'aria-label'?: string;
  'aria-labelledby'?: string;
  'aria-describedby'?: string;
  ariaLiveMessages?: AriaLiveMessages<Option, IsMulti, Group>;
  
  // Form Integration
  name?: string;
  id?: string;
  inputId?: string;
  instanceId?: number | string;
  required?: boolean;
  form?: string;
}

Usage Examples:

import Select from "react-select";

// Basic single-select
const BasicSelect = () => (
  <Select
    options={[
      { value: "red", label: "Red" },
      { value: "green", label: "Green" },
      { value: "blue", label: "Blue" },
    ]}
    placeholder="Choose a color..."
  />
);

// Multi-select with controlled state
const MultiSelect = () => {
  const [selectedOptions, setSelectedOptions] = useState([]);
  
  return (
    <Select
      isMulti
      value={selectedOptions}
      onChange={setSelectedOptions}
      options={colorOptions}
      closeMenuOnSelect={false}
    />
  );
};

// Disabled and clearable select
const ConfiguredSelect = () => (
  <Select
    options={options}
    isDisabled={false}
    isClearable
    isSearchable
    placeholder="Search and select..."
  />
);

AsyncSelect

Select component with async option loading capabilities for dynamic data fetching.

/**
 * Select component with async option loading
 * @param props - Props interface extended with async-specific properties
 * @returns JSX.Element with async loading capabilities
 */
function AsyncSelect<
  Option = unknown,
  IsMulti extends boolean = false,
  Group extends GroupBase<Option> = GroupBase<Option>
>(props: Props<Option, IsMulti, Group> & AsyncProps<Option>): JSX.Element;

interface AsyncProps<Option> {
  /** Default options to show before any input, or true to load options immediately */
  defaultOptions?: OptionsOrGroups<Option, Group> | boolean;
  /** Enable caching of loaded options */
  cacheOptions?: any;
  /** Function to load options asynchronously based on input value */
  loadOptions?: (
    inputValue: string,
    callback: (options: OptionsOrGroups<Option, Group>) => void
  ) => Promise<OptionsOrGroups<Option, Group>> | void;
}

Usage Examples:

import AsyncSelect from "react-select/async";

// Basic async select
const AsyncExample = () => {
  const loadOptions = (inputValue: string) =>
    new Promise<Option[]>((resolve) => {
      setTimeout(() => {
        resolve(
          colorOptions.filter((option) =>
            option.label.toLowerCase().includes(inputValue.toLowerCase())
          )
        );
      }, 1000);
    });

  return (
    <AsyncSelect
      cacheOptions
      defaultOptions
      loadOptions={loadOptions}
      placeholder="Type to search..."
    />
  );
};

// Async with callback pattern
const CallbackAsync = () => {
  const loadOptions = (inputValue: string, callback: Function) => {
    setTimeout(() => {
      callback(
        inputValue
          ? colorOptions.filter((option) =>
              option.label.toLowerCase().includes(inputValue.toLowerCase())
            )
          : colorOptions
      );
    }, 1000);
  };

  return <AsyncSelect loadOptions={loadOptions} />;
};

CreatableSelect

Select component with the ability to create new options that don't exist in the options list.

/**
 * Select component with option creation capability
 * @param props - Props interface extended with creatable-specific properties
 * @returns JSX.Element with option creation features
 */
function CreatableSelect<
  Option = unknown,
  IsMulti extends boolean = false,
  Group extends GroupBase<Option> = GroupBase<Option>
>(props: Props<Option, IsMulti, Group> & CreatableProps<Option>): JSX.Element;

interface CreatableProps<Option> {
  /** Allow creating options while async loading is in progress */
  allowCreateWhileLoading?: boolean;
  /** Position of the create option in the menu */
  createOptionPosition?: 'first' | 'last';
  /** Custom formatter for the create option label */
  formatCreateLabel?: (inputValue: string) => ReactNode;
  /** Validation function to determine if new option creation is allowed */
  isValidNewOption?: (
    inputValue: string,
    value: Options<Option>,
    options: OptionsOrGroups<Option, Group>,
    accessors: { getOptionValue: GetOptionValue<Option>; getOptionLabel: GetOptionLabel<Option> }
  ) => boolean;
  /** Function to generate data for new options */
  getNewOptionData?: (inputValue: string, optionLabel: ReactNode) => Option;
  /** Handler called when a new option is created */
  onCreateOption?: (inputValue: string) => void;
}

Usage Examples:

import CreatableSelect from "react-select/creatable";

// Basic creatable select
const CreatableExample = () => {
  const [options, setOptions] = useState(initialOptions);
  
  const handleCreate = (inputValue: string) => {
    const newOption = { value: inputValue.toLowerCase(), label: inputValue };
    setOptions((prev) => [...prev, newOption]);
  };

  return (
    <CreatableSelect
      options={options}
      onCreateOption={handleCreate}
      formatCreateLabel={(inputValue) => `Create "${inputValue}"`}
    />
  );
};

// Advanced creatable with validation
const ValidatedCreatable = () => {
  const isValidNewOption = (inputValue: string) => {
    return inputValue.length >= 3 && !options.some(
      option => option.label.toLowerCase() === inputValue.toLowerCase()
    );
  };

  return (
    <CreatableSelect
      options={options}
      isValidNewOption={isValidNewOption}
      formatCreateLabel={(inputValue) => 
        inputValue.length < 3 
          ? `"${inputValue}" is too short` 
          : `Add "${inputValue}"`
      }
    />
  );
};

AsyncCreatableSelect

Combines async data loading with option creation capabilities.

/**
 * Select component combining async loading and option creation
 * @param props - Props interface with both async and creatable properties
 * @returns JSX.Element with both async and creation capabilities
 */
function AsyncCreatableSelect<
  Option = unknown,
  IsMulti extends boolean = false,
  Group extends GroupBase<Option> = GroupBase<Option>
>(
  props: Props<Option, IsMulti, Group> & AsyncProps<Option> & CreatableProps<Option>
): JSX.Element;

Usage Examples:

import AsyncCreatableSelect from "react-select/async-creatable";

// Async creatable select
const AsyncCreatableExample = () => {
  const loadOptions = (inputValue: string) =>
    fetchOptionsFromAPI(inputValue);

  const handleCreate = (inputValue: string) => {
    return createNewOptionAPI(inputValue);
  };

  return (
    <AsyncCreatableSelect
      cacheOptions
      defaultOptions
      loadOptions={loadOptions}
      onCreateOption={handleCreate}
      allowCreateWhileLoading
    />
  );
};

Base Select Component

Unstyled base select component without state management for maximum customization.

/**
 * Base select component without state management
 * @param props - Raw Props interface without state management
 * @returns JSX.Element with minimal built-in behavior
 */
function BaseSelect<
  Option = unknown,
  IsMulti extends boolean = false,
  Group extends GroupBase<Option> = GroupBase<Option>
>(props: PublicBaseSelectProps<Option, IsMulti, Group>): JSX.Element;

State Management Hook

useStateManager

Hook for managing select state externally while using the base component.

/**
 * State management hook for select components
 * @param props - State manager props configuration
 * @returns Props object for base select component
 */
function useStateManager<
  Option = unknown,
  IsMulti extends boolean = false,
  Group extends GroupBase<Option> = GroupBase<Option>
>(
  props: StateManagerProps<Option, IsMulti, Group>
): PublicBaseSelectProps<Option, IsMulti, Group>;

interface StateManagerProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>>
  extends Omit<Props<Option, IsMulti, Group>, keyof ControlledProps> {
  defaultInputValue?: string;
  defaultMenuIsOpen?: boolean;
  defaultValue?: PropsValue<Option>;
}

Usage Example:

import BaseSelect from "react-select/base";
import { useStateManager } from "react-select";

const CustomSelect = (props) => {
  const selectProps = useStateManager(props);
  
  return <BaseSelect {...selectProps} />;
};

Component Instance Reference

SelectInstance

Type representing a Select component instance with available methods.

interface SelectInstance<
  Option = unknown,
  IsMulti extends boolean = false,
  Group extends GroupBase<Option> = GroupBase<Option>
> {
  /** Focus the select input */
  focus(): void;
  /** Blur the select input */
  blur(): void;
  /** Get current select value */
  getValue(): OnChangeValue<Option, IsMulti>;
  /** Check if menu is open */
  getMenuIsOpen(): boolean;
  /** Get current input value */
  getInputValue(): string;
}

Usage Example:

import { useRef } from "react";
import Select, { SelectInstance } from "react-select";

const ComponentWithRef = () => {
  const selectRef = useRef<SelectInstance<Option>>(null);
  
  const focusSelect = () => {
    selectRef.current?.focus();
  };
  
  return (
    <>
      <Select ref={selectRef} options={options} />
      <button onClick={focusSelect}>Focus Select</button>
    </>
  );
};

Install with Tessl CLI

npx tessl i tessl/npm-react-select

docs

async-data.md

core-components.md

customization.md

hooks-state.md

index.md

types-interfaces.md

tile.json