npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-multiple-select-dropdown-lite

v2.1.0

Published

React Multiple Select Light Weight Dropdown list | Searchable | Addable | Groupable etc

Readme

React Multiple Select Dropdown Lite

A lightweight Multiple/Single Select Pure functional component for react using React-Hooks.

Screenshot

react-multiple-select-dropdown-menu

Install

npm i react-multiple-select-dropdown-lite

Basic Initialization

import React, { useState } from 'react'
import MultiSelect from  'react-multiple-select-dropdown-lite'
import  'react-multiple-select-dropdown-lite/dist/index.css'

const App = () => {

  const [value, setvalue] = useState('')

  const  handleOnchange  =  val  => {
    setvalue(val)
  }

  const  options  = [
    { label:  'Option 1', value:  'option_1'  },
    { label:  'Option 2', value:  'option_2'  },
    { label:  'Option 3', value:  'option_3'  },
    { label:  'Option 4', value:  'option_4'  },
  ]

  return(
    <div className="app">
      <div  className="preview-values">
        <h4>Values</h4>
        {value}
      </div>

      <MultiSelect
        onChange={handleOnchange}
        options={options}
      />
    </div>
)}
export  default App

Features and Roadmap

  • [x] JSON Value
  • [x] Clearable
  • [x] Disable Chip
  • [x] Custom Down Arrow Icon
  • [x] Disabled
  • [x] Select Limit
  • [x] Group
  • [x] Searchable
  • [x] Custom Creatable Value
  • [x] Themeable (using css var)
  • [x] Controlled value
  • [x] Keyboard navigation
  • [x] Accessible (ARIA combobox)
  • [x] TypeScript types
  • [x] SSR and Next.js App Router

Props Options

| Props | type | default | description | | ----------------- | ----------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | options | array | an Empty option | options and groups (see Groups) label: string or JSX value: string title: text for search and chips, required with a JSX label disabled: bool style: (object) custom style classes: (string) class names example: [ { label : "Option 1", value : "opt_1", style: {textAlign: 'center'}, classes: "classA classB" } ] | | width | | | deprecated, no effect: set the --input-width CSS variable (since 2.0.1) | | name | string | '' | specify a name for form | | disabled | bool | false | disable input | | defaultValue | string | array of object | string array | '' | initial value: comma separated string, or an array of values or option objects. Resolves once options load, and follows later changes until the user picks (use value to stay in sync) | | value | string | array of object | string array | | controlled selection, same forms as defaultValue; update it from onChange | | jsonValue | bool | false | onChange gets the selected option objects instead of a comma joined string | | singleSelect | bool | false | allow one select only | | downArrowIcon | ReactNode | SVG | custom down arrow icon | | closeIcon | ReactNode | SVG | custom clear icon | | clearable | bool | true | show / hide close icon to clear value | | downArrow | bool | true | show / hide down icon in dropdown | | className | string | | custom class for the wrapper | | placeholder | string | Select... | Input Placeholder | | disableChip | bool | false | disable multiple select chips show value or total selected value only | | attr | object | | props for the wrapper div, e.g. id or data-*. aria-label / aria-labelledby name the dropdown for screen readers | | customValue | bool | false | create options by typing and pressing Enter or comma (,); they are listed under Custom Values | | largeData | bool | false | render options only while the menu is open, for long lists | | chipAlternateText | string | (number) Item Selected | Show text when chip disabled. | | closeOnSelect | bool | unset | close the menu after a pick. Unset: single select closes, multi select stays open | | limit | number | null | null | max number of selected values, null for no limit. The wrapper gets msl-limit-reached once hit | | clearAll | bool | false | clears the value when it turns true | | emptyDataLabel | string | No Data Found | text shown when there are no options or no search results | | disableSearch | bool | false | hide the search input | | style | object | {} | inline style for the wrapper |

Groups

Put options in a group with type: 'group'. Groups can nest.

const options = [
  { label: 'Option 1', value: 'option_1' },
  {
    type: 'group',
    title: 'Group A',
    emptyDataLabel: 'Nothing here', // shown when childs is empty
    childs: [
      { label: 'Option 2', value: 'option_2' },
      { label: 'Option 3', value: 'option_3' }
    ]
  }
]

Controlled value

Pass value and update it from onChange to own the selection, e.g. to reset or set it from outside. It takes the same forms as defaultValue.

const [value, setValue] = useState('option_1')

<MultiSelect options={options} value={value} onChange={setValue} />
<button onClick={() => setValue('')}>Reset</button>

With defaultValue instead, the dropdown keeps its own state after the user picks.

TypeScript

Types ship with the package. onChange gets a string by default, or MultiSelectOption[] with jsonValue.

import MultiSelect from 'react-multiple-select-dropdown-lite'
import type { MultiSelectOption } from 'react-multiple-select-dropdown-lite'

const onChange = (value: string) => console.log(value)
<MultiSelect options={options} onChange={onChange} />

const onJsonChange = (value: MultiSelectOption[]) => console.log(value)
<MultiSelect jsonValue options={options} onChange={onJsonChange} />

Also exported: MultiSelectGroup, MultiSelectProps, MultiSelectValue.

Next.js and SSR

Server rendering works on React 16 to 19, with matching ids on hydration. The bundles start with 'use client', so a Next.js App Router Server Component can import it directly when it passes only serializable props (for example name inside a form). To handle onChange, render it from your own 'use client' component.

import MultiSelect from 'react-multiple-select-dropdown-lite'
import 'react-multiple-select-dropdown-lite/dist/index.css'

Events

| Props | Params | Description | | ----------- | ------ | ------------------------------------------------------------------------------------ | | onChange | value | after any change: a comma joined string, or MultiSelectOption[] with jsonValue | | onMenuOpen | null | Trigger when menu open | | onMenuClose | null | Trigger when menu close | | onClear | null | Trigger after the clear button empties the value (not for clearAll) |

Keyboard

| Key | Action | | --------------- | -------------------------------------------------------------------------- | | Arrow Down / Up | open the menu and move the highlight over enabled options | | Home / End | first / last option (in the search field only while it is empty) | | Enter | pick the highlighted option, else the first search result | | , (comma) | pick the first search result, or create the typed value with customValue | | Backspace | in an empty search field, remove the last chip | | Escape | close the menu | | Tab | move on; the menu closes once focus leaves | | Enter / Space | on a chip's delete button or the clear button, press it | | any character | on the focused dropdown, open the menu |

Accessibility

The search field (or the dropdown itself when there is no search field) is an ARIA combobox that controls a listbox of options, with aria-expanded, aria-activedescendant, aria-selected and aria-disabled. Groups are role="group", named by their title. Give it an accessible name through attr:

<MultiSelect options={options} attr={{ 'aria-label': 'Fruits' }} />
<MultiSelect options={options} attr={{ 'aria-labelledby': 'fruits-label' }} />

CSS Variables

CSS variable applied in .msl-vars class name.

| Variable | Default Value | Details | | ------------------------ | --------------------- | ------------------------------------------------ | | --menu-max-height | 400px | Dropdown menu maximum height. | | --input-width | 300px | Dropdown input width. | | --font-size | 16px | Dropdown font size. | | --border-radius | 8px 8px 8px 8px | Dropdown Border Radius. | | --active-menu-shadow | 0 2px 8px 0px #b1b1b1 | Menu Shadow when active. | | --line-height | 1.4 | fonts line height. | | --active-menu-background | white | Dropdown menu background color when active. | | --active-menu-radius | var(--border-radius) | Dropdown menu border radius when active. |

CSS Classes

State classes to style against:

| Class | Element | When | | ------------------------------ | ------- | ------------------------------------- | | msl-disabled | wrapper | disabled | | msl-limit-reached | wrapper | limit is reached | | msl-active / msl-active-up | .msl | menu is open, below / above the input | | msl-option-active | option | selected | | msl-option-focused | option | highlighted by the keyboard | | msl-option-disable | option | disabled |

Other parts: msl-wrp (wrapper), msl-chip, msl-chip-delete, msl-single-value, msl-input, msl-clear-btn, msl-arrow-btn, msl-options, msl-option, msl-grp-title.

Change Log

See CHANGELOG.md. Upgrading from 2.0.x? Check the 2.1.0 upgrade notes.

Sponsor

License

MIT © Arif-Un | Amin | Built for Bit Form