In this tutorial, we will demonstrate how to implement a MultiSelect feature in React.js with Tailwind CSS. For this purpose, we will utilize headless UI and React Select for the Multi Select dropdown.
Tool Use
React JS
Tailwind CSS
Headless UI
React Select
First you need to setup react project with tailwind css. You can install manually or you read below blog.
How to install Tailwind CSS in React
Install & Setup Vite + React + Typescript + Tailwind CSS 3
Example 1
To use Multi Select in react with tailwind css you can use React Select library.
Start by installing react-select.
yarn add react-select
#0r
npm i --save react-select
import Select from "react-select";
const colourOptions = [
{ value: "ocean", label: "Ocean" },
{ value: "blue", label: "Blue" },
{ value: "purple", label: "Purple" },
{ value: "red", label: "Red" },
{ value: "orange", label: "Orange" },
{ value: "yellow", label: "Yellow" },
{ value: "green", label: "Green" },
{ value: "forest", label: "Forest" },
{ value: "slate", label: "Slate" },
{ value: "silver", label: "Silver" },
];
export default function MultiSelect() {
return (
<div className="container mx-auto mt-20">
<Select
defaultValue={[colourOptions[1], colourOptions[4]]}
isMulti
name="colors"
options={colourOptions}
className="lg:w-1/2 w-full"
classNamePrefix="select"
/>
</div>
);
}
Example 2
To use Multi Select dropdown in react with tailwind css you can use Headless UI library.
To get started, install Headless UI via npm:
npm install @headlessui/react
Install react heroicons Icon.
npm i @heroicons/react
import { Fragment, useState } from "react";
import { Combobox, Transition } from "@headlessui/react";
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/react/20/solid";
const people = [
{ id: 1, name: "Wade Cooper" },
{ id: 2, name: "Arlene Mccoy" },
{ id: 3, name: "Devon Webb" },
{ id: 4, name: "Tom Cook" },
{ id: 5, name: "Tanya Fox" },
{ id: 6, name: "Hellen Schmidt" },
];
export default function MultiSelect() {
const [selectedPeople, setSelectedPeople] = useState([people[2], people[4]]);
const [query, setQuery] = useState("");
const filteredPeople =
query === ""
? people
: people.filter((person) =>
person.name
.toLowerCase()
.replace(/\s+/g, "")
.includes(query.toLowerCase().replace(/\s+/g, ""))
);
return (
<div className="flex justify-center items-center h-screen">
<div className="fixed top-16 lg:w-1/4 w-full">
<Combobox value={selectedPeople} onChange={setSelectedPeople} multiple>
<div className="relative mt-1">
<div className="relative w-full cursor-default overflow-hidden rounded-lg bg-white text-left shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-teal-300 sm:text-sm">
<Combobox.Input
className="w-full border-none py-2 pl-3 pr-10 text-sm leading-5 text-gray-900 focus:ring-0"
displayValue={(people) =>
people.map((person) => person.name).join(", ")
}
/>
<Combobox.Button className="absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon
className="h-5 w-5 text-gray-400"
aria-hidden="true"
/>
</Combobox.Button>
</div>
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
afterLeave={() => setQuery("")}
>
<Combobox.Options className="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{filteredPeople.length === 0 && query !== "" ? (
<div className="relative cursor-default select-none py-2 px-4 text-gray-700">
Nothing found.
</div>
) : (
filteredPeople.map((person) => (
<Combobox.Option
key={person.id}
className={({ active }) =>
`relative cursor-default select-none py-2 pl-10 pr-4 ${
active ? "bg-teal-600 text-white" : "text-gray-900"
}`
}
value={person}
>
{({ selected, active }) => (
<>
<span
className={`block truncate ${
selected ? "font-medium" : "font-normal"
}`}
>
{person.name}
</span>
{selected ? (
<span
className={`absolute inset-y-0 left-0 flex items-center pl-3 ${
active ? "text-white" : "text-teal-600"
}`}
>
<CheckIcon
className="h-5 w-5"
aria-hidden="true"
/>
</span>
) : null}
</>
)}
</Combobox.Option>
))
)}
</Combobox.Options>
</Transition>
</div>
</Combobox>
</div>
</div>
);
}