CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-autosuggest

WAI-ARIA compliant React autosuggest component with extensive customization options

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

React Autosuggest

React Autosuggest is a WAI-ARIA compliant React component that provides accessible autosuggest/autocomplete functionality. It offers extensive customization options, supports both single-section and multi-section suggestion layouts, handles asynchronous suggestion loading, and provides full keyboard navigation with mobile-friendly interactions.

Package Information

  • Package Name: react-autosuggest
  • Package Type: npm
  • Language: JavaScript (React)
  • Installation: npm install react-autosuggest

Core Imports

import Autosuggest from 'react-autosuggest';

For CommonJS:

const Autosuggest = require('react-autosuggest');

Basic Usage

import React, { useState } from 'react';
import Autosuggest from 'react-autosuggest';

const languages = [
  { name: 'C', year: 1972 },
  { name: 'JavaScript', year: 1995 },
  { name: 'Python', year: 1991 }
];

// Function that tells Autosuggest how to calculate suggestions for any given input value
const getSuggestions = value => {
  const inputValue = value.trim().toLowerCase();
  const inputLength = inputValue.length;

  return inputLength === 0 ? [] : languages.filter(lang =>
    lang.name.toLowerCase().slice(0, inputLength) === inputValue
  );
};

// Function that tells Autosuggest what should be the input value when suggestion is clicked
const getSuggestionValue = suggestion => suggestion.name;

// Function that renders each suggestion
const renderSuggestion = suggestion => (
  <div>
    {suggestion.name}
  </div>
);

function MyAutosuggest() {
  const [value, setValue] = useState('');
  const [suggestions, setSuggestions] = useState([]);

  const onChange = (event, { newValue }) => {
    setValue(newValue);
  };

  const onSuggestionsFetchRequested = ({ value }) => {
    setSuggestions(getSuggestions(value));
  };

  const onSuggestionsClearRequested = () => {
    setSuggestions([]);
  };

  const inputProps = {
    placeholder: 'Type a programming language',
    value,
    onChange: onChange
  };

  return (
    <Autosuggest
      suggestions={suggestions}
      onSuggestionsFetchRequested={onSuggestionsFetchRequested}
      onSuggestionsClearRequested={onSuggestionsClearRequested}
      getSuggestionValue={getSuggestionValue}
      renderSuggestion={renderSuggestion}
      inputProps={inputProps}
    />
  );
}

Capabilities

Autosuggest Component

The main React component providing autosuggest functionality with full accessibility support.

class Autosuggest extends React.Component {
  constructor(props);
  render();
}

Required Props

interface AutosuggestProps {
  /** Array of suggestions to display */
  suggestions: Array<any>;
  
  /** Called when suggestions need to be recalculated */
  onSuggestionsFetchRequested: (request: SuggestionsFetchRequest) => void;
  
  /** Returns input value for a selected suggestion */
  getSuggestionValue: (suggestion: any) => string;
  
  /** Renders individual suggestions */
  renderSuggestion: (
    suggestion: any, 
    params: RenderSuggestionParams
  ) => React.ReactNode;
  
  /** Input props including required value and onChange */
  inputProps: InputProps;
}

interface SuggestionsFetchRequest {
  value: string;
  reason: 'input-changed' | 'input-focused' | 'escape-pressed' | 'suggestions-revealed' | 'suggestions-updated' | 'suggestion-selected' | 'input-blurred';
}

interface RenderSuggestionParams {
  query: string;
  isHighlighted: boolean;
}

interface InputProps {
  value: string;
  onChange: (event: Event, params: InputChangeParams) => void;
  onBlur?: (event: Event, params: InputBlurParams) => void;
  [key: string]: any; // Additional HTML input attributes
}

interface InputBlurParams {
  highlightedSuggestion: any | null;
}

interface InputChangeParams {
  newValue: string;
  method: 'down' | 'up' | 'escape' | 'enter' | 'click' | 'type';
}

Optional Props

interface OptionalAutosuggestProps {
  /** Called to clear suggestions (required unless alwaysRenderSuggestions=true) */
  onSuggestionsClearRequested?: () => void;
  
  /** Props passed to outer container div */
  containerProps?: object;
  
  /** Called when suggestion is selected */
  onSuggestionSelected?: (event: Event, params: SuggestionSelectedParams) => void;
  
  /** Called when highlighted suggestion changes */
  onSuggestionHighlighted?: (params: SuggestionHighlightedParams) => void;
  
  /** Controls when suggestions are rendered */
  shouldRenderSuggestions?: (value: string, reason: string) => boolean;
  
  /** Render suggestions even when input not focused */
  alwaysRenderSuggestions?: boolean;
  
  /** Automatically highlight first suggestion */
  highlightFirstSuggestion?: boolean;
  
  /** Keep input focused on suggestion click */
  focusInputOnSuggestionClick?: boolean;
  
  /** Enable multi-section suggestions layout */
  multiSection?: boolean;
  
  /** Renders section titles (required when multiSection=true) */
  renderSectionTitle?: (section: any) => React.ReactNode;
  
  /** Gets suggestions for a section (required when multiSection=true) */
  getSectionSuggestions?: (section: any) => Array<any>;
  
  /** Custom input component renderer */
  renderInputComponent?: (inputProps: object) => React.ReactElement;
  
  /** Custom suggestions container renderer */
  renderSuggestionsContainer?: (params: RenderSuggestionsContainerParams) => React.ReactElement;
  
  /** CSS class names for styling */
  theme?: Theme;
  
  /** Unique identifier for multiple Autosuggest instances */
  id?: string;
  
  /** Control suggestions visibility after selection */
  shouldKeepSuggestionsOnSelect?: (suggestion: any) => boolean;
}

interface SuggestionSelectedParams {
  suggestion: any;
  suggestionValue: string;
  suggestionIndex: number;
  sectionIndex: number | null;
  method: 'click' | 'enter';
}

interface SuggestionHighlightedParams {
  suggestion: any | null;
}

interface RenderSuggestionsContainerParams {
  containerProps: object;
  children: React.ReactNode;
  query: string;
}

interface Theme {
  container?: string;
  containerOpen?: string;
  input?: string;
  inputOpen?: string;
  inputFocused?: string;
  suggestionsContainer?: string;
  suggestionsContainerOpen?: string;
  suggestionsList?: string;
  suggestion?: string;
  suggestionFirst?: string;
  suggestionHighlighted?: string;
  sectionContainer?: string;
  sectionContainerFirst?: string;
  sectionTitle?: string;
}

Multi-Section Usage

For organizing suggestions into multiple sections:

const languages = [
  {
    title: 'C',
    languages: [
      { name: 'C', year: 1972 },
      { name: 'C#', year: 2000 },
      { name: 'C++', year: 1983 }
    ]
  },
  {
    title: 'JavaScript',  
    languages: [
      { name: 'JavaScript', year: 1995 },
      { name: 'TypeScript', year: 2012 }
    ]
  }
];

const getSectionSuggestions = section => section.languages;

const renderSectionTitle = section => (
  <strong>{section.title}</strong>
);

// In component:
<Autosuggest
  multiSection={true}
  suggestions={languages}
  onSuggestionsFetchRequested={onSuggestionsFetchRequested}
  onSuggestionsClearRequested={onSuggestionsClearRequested}
  getSuggestionValue={getSuggestionValue}
  renderSuggestion={renderSuggestion}
  renderSectionTitle={renderSectionTitle}
  getSectionSuggestions={getSectionSuggestions}
  inputProps={inputProps}
/>

Custom Styling with Theme

const theme = {
  container: 'my-autosuggest-container',
  containerOpen: 'my-autosuggest-container--open',
  input: 'my-autosuggest-input',
  inputOpen: 'my-autosuggest-input--open',
  inputFocused: 'my-autosuggest-input--focused',
  suggestionsContainer: 'my-autosuggest-suggestions-container',
  suggestionsContainerOpen: 'my-autosuggest-suggestions-container--open',
  suggestionsList: 'my-autosuggest-suggestions-list',
  suggestion: 'my-autosuggest-suggestion',
  suggestionFirst: 'my-autosuggest-suggestion--first',
  suggestionHighlighted: 'my-autosuggest-suggestion--highlighted',
  sectionContainer: 'my-autosuggest-section-container',
  sectionContainerFirst: 'my-autosuggest-section-container--first',
  sectionTitle: 'my-autosuggest-section-title'
};

<Autosuggest
  theme={theme}
  // ... other props
/>

Custom Input Component

const renderInputComponent = inputProps => (
  <div>
    <input {...inputProps} />
    <div>custom stuff</div>
  </div>
);

<Autosuggest
  renderInputComponent={renderInputComponent}
  // ... other props
/>

Custom Suggestions Container

const renderSuggestionsContainer = ({ containerProps, children }) => (
  <div {...containerProps}>
    <div>custom header</div>
    {children}
    <div>custom footer</div>
  </div>
);

<Autosuggest
  renderSuggestionsContainer={renderSuggestionsContainer}
  // ... other props
/>

Asynchronous Suggestions

const onSuggestionsFetchRequested = ({ value }) => {
  // Clear previous suggestions
  setSuggestions([]);
  
  // Fetch suggestions asynchronously
  fetch(`/api/suggestions?q=${encodeURIComponent(value)}`)
    .then(response => response.json())
    .then(data => {
      setSuggestions(data.suggestions);
    })
    .catch(error => {
      console.error('Error fetching suggestions:', error);
      setSuggestions([]);
    });
};

Default Values

// Default prop values
const defaultProps = {
  renderSuggestionsContainer: ({ containerProps, children }) => (
    <div {...containerProps}>{children}</div>
  ),
  shouldRenderSuggestions: (value) => value.trim().length > 0,
  alwaysRenderSuggestions: false,
  multiSection: false,
  shouldKeepSuggestionsOnSelect: () => false,
  focusInputOnSuggestionClick: true,
  highlightFirstSuggestion: false,
  theme: {
    container: 'react-autosuggest__container',
    containerOpen: 'react-autosuggest__container--open',
    input: 'react-autosuggest__input',
    inputOpen: 'react-autosuggest__input--open',
    inputFocused: 'react-autosuggest__input--focused',
    suggestionsContainer: 'react-autosuggest__suggestions-container',
    suggestionsContainerOpen: 'react-autosuggest__suggestions-container--open',
    suggestionsList: 'react-autosuggest__suggestions-list',
    suggestion: 'react-autosuggest__suggestion',
    suggestionFirst: 'react-autosuggest__suggestion--first',
    suggestionHighlighted: 'react-autosuggest__suggestion--highlighted',
    sectionContainer: 'react-autosuggest__section-container',
    sectionContainerFirst: 'react-autosuggest__section-container--first',
    sectionTitle: 'react-autosuggest__section-title'
  },
  id: '1',
  containerProps: {}
};

Accessibility Features

React Autosuggest is fully WAI-ARIA compliant and provides:

  • Keyboard Navigation: Arrow keys to navigate suggestions, Enter to select, Escape to close
  • Screen Reader Support: Proper ARIA attributes for announcing suggestions and changes
  • Focus Management: Maintains proper focus throughout interactions
  • Live Regions: Announces suggestion counts and selection changes to screen readers
  • Role Attributes: Proper semantic roles for autosuggest functionality

The component automatically handles all accessibility concerns without requiring additional configuration.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-autosuggest@10.1.x
Publish Source
CLI
Badge
tessl/npm-react-autosuggest badge