fully configurable react multi select component
npm install react-multiselect-dropdown-configurableFully configurable and lightweight multi select dropdown component using React and Typescript
- 🕶 Zero Dependency
- 🍃 Lightweight
- 💅 Themeable / Configurable
- ✌ Written w/ TypeScript
- 🥷🏼 Support available : email me if you need any additional features
``bash`
npm i react-multiselect-dropdown-configurable # npm
yarn add react-multiselect-dropdown-configurable # yarn
`tsx
import React, { useState } from "react";
import MultiSelect from "react-multiselect-dropdown-configurable";
const options = [
{ label: "Grapes", value: "grapes" },
{ label: "Mango", value: "mango" },
{ label: "Strawberry", value: "strawberry", disabled: true },
{ label: "Pinapple", value: "Pinapple", disabled: true },
{ label: "Pomogranate", value: "Pomogranate" },
{ label: "Papaya", value: "Papaya" },
{ label: "Sapota", value: "Sapota" },
];
const Example = () => {
//you can optionally add preselected options and pass to value
// or you can just keep it empty array []
const [selected, setSelected] = useState([
{ label: "Grapes", value: "grapes" },
{ label: "Papaya", value: "Papaya" },
]);
return (
{JSON.stringify(selected)}📦 Detailed Example - fully configured
`tsx
import React, { useState } from "react";
import MultiSelect from "react-multiselect-dropdown-configurable";
import { Cross, ChevronUp, ChevronDown } from "./lib";const apiData = [
{
id: 2,
firstName: "Michael",
lastName: "Williams",
image: "https://dummyjson.com/icon/michaelw/128",
company: {
department: "Support",
name: "Spinka - Dickinson",
title: "Support Specialist",
},
},
{
id: 3,
firstName: "Sophia",
lastName: "Brown",
image: "https://dummyjson.com/icon/sophiab/128",
company: {
department: "Research and Development",
name: "Schiller - Zieme",
title: "Accountant",
},
},
{
id: 4,
firstName: "James",
lastName: "Davis",
image: "https://dummyjson.com/icon/jamesd/128",
company: {
department: "Support",
name: "Pagac and Sons",
title: "Research Analyst",
},
},
{
id: 5,
firstName: "Emma",
lastName: "Miller",
image: "https://dummyjson.com/icon/emmaj/128",
company: {
department: "Human Resources",
name: "Graham - Gulgowski",
title: "Quality Assurance Engineer",
},
},
{
id: 6,
firstName: "Olivia",
lastName: "Wilson",
image: "https://dummyjson.com/icon/oliviaw/128",
company: {
department: "Product Management",
name: "Pfannerstill Inc",
title: "Research Analyst",
},
},
{
id: 7,
firstName: "Alexander",
lastName: "Jones",
image: "https://dummyjson.com/icon/alexanderj/128",
company: {
department: "Engineering",
name: "Dickens - Beahan",
title: "Web Developer",
},
},
];
const Example = () => {
const apiOptions = apiData.map((user, index) => {
return {
label: user.firstName + " " + user.lastName,
value: user.username,
disabled: index === 2,
data: {
image: user.image,
firstName: user.firstName,
lastName: user.lastName,
description: user.company.department + " " + user.company.title,
},
};
});
const [selected, setSelected] = useState([]);
return (
{JSON.stringify(selected)}
options={apiOptions}
value={selected}
onChange={setSelected}
labelledBy="Select"
isLoading={false}
className="dropdown"
shouldToggleOnHover={false}
ClearIcon={ }
overrideStrings={{
selectItems: "Pick all that you like",
}}
isCreatable={true}
HideClearIcon={false}
ItemRenderer={({ checked, option, onClick, disabled }) => (
style={{
display: "flex",
flexDirection: "row",
alignItems: "center",
gap: "15px",
}}
onClick={onClick}
>
src={option.data.image}
style={{
width: "30px",
height: "30px",
}}
alt="user avatar"
/>{" "}
style={{
fontSize: "16px",
lineHeight: "1.55",
color: "black",
}}
>
{option.data.firstName} {option.data.lastName}
style={{
color: "rgb(134, 142, 150)",
fontSize: "12px",
lineHeight: "1.55",
textDecoration: "none",
}}
>
{option.data.description}
)}
showCheckedOnSelectedItems={true}
hidePickedOptions={false}
PillRenderer={({ selectedOption, handlePillClose }) => {
return (
style={{
backgroundColor: "lightgray",
borderRadius: "3px",
padding: "5px",
display: "flex",
flexDirection: "row",
alignItems: "center",
gap: "5px",
}}
onClick={handlePillClose}
>
src={selectedOption.data.image}
style={{
width: "15px",
height: "15px",
}}
alt="user avatar"
/>{" "}
{selectedOption.label}
✨ Possible props
`tsx
interface Option {
value: string | number;
label: string;
key?: string;
disabled?: boolean;
data?: any; //can be utilized in Item Renderer or Pill Renderer
}interface MultiSelect {
options: Option[];
//array of objects with mandatory label and value properties
value: Option[];
//selected array of objects
onChange?;
//you need to map this with your setOptions setState function
PillRenderer?: ({ selectedOption, handlePillClose }) => React.JSX.Element;
//how selected item should render in the header
ItemRenderer?: (props: ItemRendererProps) => React.JSX.Element;
//how options should render in the dropdown popper
showCheckedOnSelectedItems?: boolean;
//should selected items have check icon in the dropdown popper
ArrowRenderer?: ({ expanded }) => React.JSX.Element;
//custom icon in the header to toggle dropdown popper
isLoading?: boolean;
//adds a loading icon in the header and disables selection temporarily
disabled?: boolean;
// completly disables the dropdown - no user action is permitted
disableSearch?: boolean;
//by default enabled, user can search the options by typing text in the header
shouldToggleOnHover?: boolean;
//by default false, if enabled then dropdown toggles on mouse hover
searchFilterFunction?: (
options: Option[],
filterString: string
) => Promise
``