CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-downshift

A set of primitives to build simple, flexible, WAI-ARIA compliant React autocomplete, combobox or select dropdown components.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

Downshift

Downshift is a set of primitives to build simple, flexible, WAI-ARIA compliant React autocomplete, combobox or select dropdown components. It provides both a traditional render prop class component and modern React hooks for maximum flexibility and control over your UI components while maintaining accessibility standards.

Package Information

  • Package Name: downshift
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install downshift

Core Imports

import Downshift, { useSelect, useCombobox, useMultipleSelection, resetIdCounter } from "downshift";

For CommonJS:

const Downshift = require("downshift");
const { useSelect, useCombobox, useMultipleSelection, resetIdCounter } = require("downshift");

Basic Usage

import { useSelect } from "downshift";

function SelectExample() {
  const items = ['apple', 'pear', 'orange', 'grape', 'banana'];
  
  const {
    isOpen,
    selectedItem,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    highlightedIndex,
    getItemProps,
  } = useSelect({ items });

  return (
    <div>
      <label {...getLabelProps()}>Choose a fruit:</label>
      <button type="button" {...getToggleButtonProps()}>
        {selectedItem || 'Select item'}
      </button>
      <ul {...getMenuProps()}>
        {isOpen &&
          items.map((item, index) => (
            <li
              style={
                highlightedIndex === index ? { backgroundColor: '#bde4ff' } : {}
              }
              key={`${item}${index}`}
              {...getItemProps({ item, index })}
            >
              {item}
            </li>
          ))}
      </ul>
    </div>
  );
}

Architecture

Downshift is built around several key design patterns:

  • Prop Getters Pattern: Functions that return props to spread onto DOM elements, handling events, accessibility, and state management
  • State Reducers: Customizable state management allowing developers to override default behaviors
  • Accessibility First: Built-in ARIA compliance with screen reader support and keyboard navigation
  • Composition: Hooks can be composed together for complex scenarios like multi-selection
  • Environment Abstraction: Support for different environments (SSR, React Native, testing) through environment prop
  • Generic Type Safety: Full TypeScript support with generic Item types throughout all APIs

Capabilities

Select Components

Hook for building accessible select/dropdown components with full keyboard navigation and ARIA compliance.

function useSelect<Item>(props: UseSelectProps<Item>): UseSelectReturnValue<Item>;

interface UseSelectProps<Item> {
  items: Item[];
  itemToString?: (item: Item | null) => string;
  onSelectedItemChange?: (changes: UseSelectSelectedItemChange<Item>) => void;
  stateReducer?: (
    state: UseSelectState<Item>,
    actionAndChanges: UseSelectStateChangeOptions<Item>
  ) => Partial<UseSelectState<Item>>;
  // ... additional props
}

interface UseSelectReturnValue<Item> {
  isOpen: boolean;
  selectedItem: Item | null;
  highlightedIndex: number;
  getToggleButtonProps: <Options>(options?: UseSelectGetToggleButtonPropsOptions & Options) => UseSelectGetToggleButtonReturnValue;
  getLabelProps: <Options>(options?: UseSelectGetLabelPropsOptions & Options) => UseSelectGetLabelPropsReturnValue;
  getMenuProps: <Options>(options?: UseSelectGetMenuPropsOptions & Options) => UseSelectGetMenuReturnValue;
  getItemProps: <Options>(options: UseSelectGetItemPropsOptions<Item> & Options) => UseSelectGetItemPropsReturnValue;
  // ... additional methods and state
}

Select Components

Combobox Components

Hook for building accessible combobox/autocomplete components with input field and filtering capabilities.

function useCombobox<Item>(props: UseComboboxProps<Item>): UseComboboxReturnValue<Item>;

interface UseComboboxProps<Item> {
  items: Item[];
  itemToString?: (item: Item | null) => string;
  inputValue?: string;
  onInputValueChange?: (changes: UseComboboxInputValueChange<Item>) => void;
  onSelectedItemChange?: (changes: UseComboboxSelectedItemChange<Item>) => void;
  stateReducer?: (
    state: UseComboboxState<Item>,
    actionAndChanges: UseComboboxStateChangeOptions<Item>
  ) => Partial<UseComboboxState<Item>>;
  // ... additional props
}

interface UseComboboxReturnValue<Item> {
  isOpen: boolean;
  selectedItem: Item | null;
  highlightedIndex: number;
  inputValue: string;
  getInputProps: <Options>(options?: UseComboboxGetInputPropsOptions & Options) => UseComboboxGetInputPropsReturnValue;
  getToggleButtonProps: <Options>(options?: UseComboboxGetToggleButtonPropsOptions & Options) => UseComboboxGetToggleButtonPropsReturnValue;
  // ... additional methods and state
}

Combobox Components

Multiple Selection

Hook for managing multiple item selection state, designed to compose with other downshift hooks.

function useMultipleSelection<Item>(
  props?: UseMultipleSelectionProps<Item>
): UseMultipleSelectionReturnValue<Item>;

interface UseMultipleSelectionProps<Item> {
  selectedItems?: Item[];
  onSelectedItemsChange?: (changes: UseMultipleSelectionSelectedItemsChange<Item>) => void;
  stateReducer?: (
    state: UseMultipleSelectionState<Item>,
    actionAndChanges: UseMultipleSelectionStateChangeOptions<Item>
  ) => Partial<UseMultipleSelectionState<Item>>;
  // ... additional props
}

interface UseMultipleSelectionReturnValue<Item> {
  selectedItems: Item[];
  activeIndex: number;
  addSelectedItem: (item: Item) => void;
  removeSelectedItem: (item: Item) => void;
  setSelectedItems: (items: Item[]) => void;
  getSelectedItemProps: <Options>(options: UseMultipleSelectionGetSelectedItemPropsOptions<Item> & Options) => UseMultipleSelectionGetSelectedItemReturnValue;
  getDropdownProps: <Options>(options?: UseMultipleSelectionGetDropdownPropsOptions & Options) => UseMultipleSelectionGetDropdownReturnValue;
}

Multiple Selection

Class Component (Legacy)

Original render prop-based component for backwards compatibility and advanced use cases.

class Downshift<Item = any> extends React.Component<DownshiftProps<Item>> {
  static stateChangeTypes: StateChangeTypes;
}

interface DownshiftProps<Item> {
  children?: (options: ControllerStateAndHelpers<Item>) => React.ReactNode;
  itemToString?: (item: Item | null) => string;
  onChange?: (selectedItem: Item | null, stateAndHelpers: ControllerStateAndHelpers<Item>) => void;
  stateReducer?: (
    state: DownshiftState<Item>,
    changes: StateChangeOptions<Item>
  ) => Partial<StateChangeOptions<Item>>;
  // ... additional props
}

Class Component

Common Types

interface Environment {
  addEventListener: typeof window.addEventListener;
  removeEventListener: typeof window.removeEventListener;
  document: Document;
  Node: typeof window.Node;
}

// State change types for useSelect
enum UseSelectStateChangeTypes {
  ToggleButtonClick = '__togglebutton_click__',
  ToggleButtonKeyDownArrowDown = '__togglebutton_keydown_arrow_down__',
  ItemClick = '__item_click__',
  FunctionSelectItem = '__function_select_item__',
  // ... additional types
}

// State change types for useCombobox  
enum UseComboboxStateChangeTypes {
  InputKeyDownArrowDown = '__input_keydown_arrow_down__',
  InputChange = '__input_change__',
  ItemClick = '__item_click__',
  FunctionSelectItem = '__function_select_item__',
  // ... additional types
}

// State change types for useMultipleSelection
enum UseMultipleSelectionStateChangeTypes {
  SelectedItemClick = '__selected_item_click__',
  FunctionAddSelectedItem = '__function_add_selected_item__',
  FunctionRemoveSelectedItem = '__function_remove_selected_item__',
  // ... additional types
}

Utilities

resetIdCounter

/**
 * Resets the internal ID counter used for generating unique IDs.
 * Primarily used for server-side rendering to ensure consistent IDs between server and client.
 */
function resetIdCounter(): void;

Install with Tessl CLI

npx tessl i tessl/npm-downshift
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/downshift@9.0.x
Publish Source
CLI
Badge
tessl/npm-downshift badge