New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

react-token-autocomplete

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-token-autocomplete

A style-agnostic token/tag autocomplete component for React

latest
Source
npmnpm
Version
1.0.1
Version published
Maintainers
1
Created
Source

react-token-autocomplete

A style-agnostic token/tag autocomplete component for React. Ships with zero default styles — bring your own CSS, Tailwind, CSS modules, or any styling solution.

Install

npm install react-token-autocomplete

Requires React 18 or 19 as a peer dependency.

Quick Start

import { TokenAutocomplete } from 'react-token-autocomplete'

function App() {
  return (
    <TokenAutocomplete
      options={['React', 'Vue', 'Svelte', 'Angular', 'Solid']}
      placeholder="Add a framework..."
      onAdd={(value) => console.log('Added:', value)}
      onRemove={(value) => console.log('Removed:', value)}
    />
  )
}

Styling with Tailwind

Every element exposes a className prop — no style overrides or CSS specificity battles:

<TokenAutocomplete
  options={['React', 'Vue', 'Svelte']}
  className="flex flex-wrap items-center gap-1 border rounded-lg p-2 focus-within:ring-2 focus-within:ring-blue-500"
  inputClassName="outline-none flex-1 min-w-[120px] bg-transparent"
  tokenClassName="inline-flex items-center gap-1 bg-blue-100 text-blue-800 px-2 py-0.5 rounded-full text-sm"
  tokenRemoveClassName="hover:text-red-600 cursor-pointer text-blue-400"
  optionsClassName="absolute z-10 mt-1 w-full bg-white border rounded-lg shadow-lg max-h-60 overflow-auto"
  optionClassName="px-3 py-2 cursor-pointer hover:bg-gray-50"
  optionSelectedClassName="bg-blue-50"
  placeholderClassName="text-gray-400"
  processingClassName="animate-spin h-4 w-4 border-2 border-blue-500 border-t-transparent rounded-full"
/>

Props

PropTypeDefaultDescription
valuestring[]Controlled value (see Controlled Mode)
onChange(values: string[]) => voidCalled with full values array on every add/remove
optionsstring[][]Available options to select from
defaultValuesstring[][]Initial selected tokens (uncontrolled mode only)
placeholderstring''Placeholder text when empty
thresholdnumber0Min characters before showing suggestions
processingbooleanfalseShow a loading indicator
autoFocusbooleanfalseFocus input on mount
filterOptionsbooleantrueFilter options by input text
simulateSelectbooleanfalseSingle-value select mode (hides input after selection)
limitToOptionsbooleanfalseOnly allow values from options (no custom input)
parseOption(option: string) => ReactNodeCustom render for dropdown options
parseToken(token: string) => ReactNodeCustom render for tokens
parseCustom(value: string) => stringTransform custom input values
onInputChange(value: string) => voidCalled when input text changes
onAdd(value: string) => voidCalled when a token is added
onRemove(value: string, index: number) => voidCalled when a token is removed

className Props

PropElement
classNameOuter container <div>
inputClassNameText <input>
tokenClassNameToken <span>
tokenRemoveClassNameToken remove <button>
optionsClassNameDropdown <ul>
optionClassNameEach option <li>
optionSelectedClassNameCurrently highlighted option (added alongside optionClassName)
placeholderClassNamePlaceholder <span>
processingClassNameLoading indicator <span>

Keyboard Shortcuts

KeyAction
EnterAdd the currently highlighted option
EscapeClose the dropdown
BackspaceRemove last token (when input is empty)
ArrowUp / ArrowDownNavigate options

Controlled Mode / react-hook-form

The component supports both uncontrolled (defaultValues) and controlled (value + onChange) modes. Controlled mode works seamlessly with form libraries like react-hook-form.

Basic controlled usage

import { useState } from 'react'
import { TokenAutocomplete } from 'react-token-autocomplete'

function App() {
  const [tags, setTags] = useState<string[]>([])

  return (
    <TokenAutocomplete
      options={['React', 'Vue', 'Svelte']}
      value={tags}
      onChange={setTags}
    />
  )
}

With react-hook-form

The component forwards a ref to its internal <input> element, so react-hook-form's Controller can manage focus automatically.

import { useForm, Controller } from 'react-hook-form'
import { TokenAutocomplete } from 'react-token-autocomplete'

interface FormData {
  tags: string[]
}

function TagForm() {
  const { control, handleSubmit } = useForm<FormData>({
    defaultValues: { tags: [] },
  })

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <Controller
        name="tags"
        control={control}
        rules={{ validate: (v) => v.length > 0 || 'At least one tag required' }}
        render={({ field }) => (
          <TokenAutocomplete
            ref={field.ref}
            value={field.value}
            onChange={field.onChange}
            options={['React', 'Vue', 'Svelte', 'Angular', 'Solid']}
            placeholder="Add tags..."
            limitToOptions
          />
        )}
      />
      <button type="submit">Submit</button>
    </form>
  )
}

Note: onAdd and onRemove still fire alongside onChange, so you can use them for analytics or side effects without interfering with form state.

Headless Hook

For full control over rendering, use the useTokenAutocomplete hook:

import { useTokenAutocomplete } from 'react-token-autocomplete'

function CustomAutocomplete() {
  const {
    values,
    inputValue,
    availableOptions,
    showOptions,
    setInputValue,
    addValue,
    removeValue,
    handleKeyDown,
    handleOptionMouseEnter,
    handleOptionSelect,
    inputRef,
    containerRef,
    focus,
    selectedIndex,
  } = useTokenAutocomplete({
    options: ['React', 'Vue', 'Svelte'],
    onAdd: (v) => console.log('added', v),
  })

  return (
    <div ref={containerRef} onClick={focus}>
      {values.map((v, i) => (
        <span key={i}>
          {v}
          <button onClick={() => removeValue(i)}>&times;</button>
        </span>
      ))}
      <input
        ref={inputRef}
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
        onKeyDown={handleKeyDown}
        onFocus={focus}
      />
      {showOptions && (
        <ul>
          {availableOptions.map((opt, i) => (
            <li
              key={opt}
              onClick={() => handleOptionSelect(opt)}
              onMouseEnter={() => handleOptionMouseEnter(opt)}
              style={{ background: i === selectedIndex ? '#eee' : undefined }}
            >
              {opt}
            </li>
          ))}
        </ul>
      )}
    </div>
  )
}

Exports

// Components
import { TokenAutocomplete, Token, Options, Option } from 'react-token-autocomplete'

// Headless hook
import { useTokenAutocomplete } from 'react-token-autocomplete'

// Types
import type {
  TokenAutocompleteProps,
  TokenProps,
  OptionsProps,
  OptionProps,
  UseTokenAutocompleteOptions,
  UseTokenAutocompleteReturn,
} from 'react-token-autocomplete'

Development

npm install        # install dependencies
npm run dev        # run examples playground
npm run build      # build library (ESM + CJS + types)
npm test           # run unit tests
npm run test:watch # run unit tests in watch mode
npm run e2e        # run Playwright e2e tests (mobile, tablet, desktop)
npm run lint       # type-check with tsc

License

ISC

FAQs

Package last updated on 30 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts