Skip to content

Instantly share code, notes, and snippets.

@jubayer-webdev
Created August 10, 2024 17:28
Show Gist options
  • Save jubayer-webdev/40572dafdc273d8e7087cd90800f0f7b to your computer and use it in GitHub Desktop.
Save jubayer-webdev/40572dafdc273d8e7087cd90800f0f7b to your computer and use it in GitHub Desktop.
// 10 August 2024
import {
Combobox,
ComboboxInput,
ComboboxOption,
ComboboxOptions,
Field,
Label,
} from "@headlessui/react";
import { CheckIcon } from "@heroicons/react/16/solid";
import { useEffect, useState } from "react";
const people = [
{ id: 1, name: "Durward Reynolds" },
{ id: 2, name: "Kenton Towne" },
{ id: 3, name: "Therese Wunsch" },
{ id: 4, name: "Benedict Kessler" },
{ id: 5, name: "Katelyn Rohan" },
{ id: 6, name: "Jame hossen" },
];
function AutocompleteMultiSelect () {
const [selectedPeople, setSelectedPeople] = useState([
// people[0],
// people[1],
]);
const [query, setQuery] = useState("");
const [filteredPeoples, setFilteredPeoples] = useState([]);
useEffect(() => {
const querySplitArray = query.split(",");
const lastQuery = querySplitArray[querySplitArray.length - 1].trim();
const currentFilteredPeoples =
query === "" || lastQuery === ""
? people //! this value (people) is the all options value, which will show in options chart
: people.filter((person) => {
return person.name
.toLowerCase()
.replace(/\s+/g, "")
.includes(
lastQuery.toLowerCase().replace(/\s+/g, "")
);
});
setFilteredPeoples(currentFilteredPeoples);
}, [query]);
//! when any selected or unselected is happen, this function will call and it will send all selected values
const onChangeHandler = (anyName) => {
// the anyName variable will get all selected values
console.log(anyName);
setSelectedPeople(anyName);
};
return (
// https://headlessui.com/react/combobox#adding-a-label
<div>
<Field>
<Label className="text-lg">Select permissions</Label>
<Combobox
multiple
immediate //https://headlessui.com/react/combobox#opening-the-dropdown-on-focus
value={selectedPeople} //This is the value which is currently selected
//! 1st Method (on documentation)
// onChange={setSelectedPeople}
//! 2nd method
onChange={onChangeHandler}
onClose={() => setQuery("")}
>
<div>
<ComboboxInput
aria-label="Assignee"
displayValue={
(people) =>
people?.map((person) => person.name) + "," //add "," for last query search
// people?.map((person) => person.name).join(", ")
}
onChange={(event) => setQuery(event.target.value)}
// https://tailwind-react-kit.tarikulcraft.com/components/forms
className="mt-2 w-full border-2 rounded-md bg-gray-50 p-2.5 pr-10 focus:border-blue-500 focus:outline-none" //focus:ring-1 focus:ring-blue-500
placeholder="Select permissions"
/>
<ComboboxOptions
//https://headlessui.com/react/combobox#positioning-the-dropdown
// https://headlessui.com/react/combobox#setting-the-dropdown-width
anchor="bottom start"
transition
className="[--anchor-gap:4px] empty:invisible sm:[--anchor-gap:8px] w-[var(--input-width)] max-h-60 rounded-md shadow-lg overflow-auto transition duration-200 ease-out data-[closed]:scale-95 data-[closed]:opacity-0"
// https://headlessui.com/react/combobox#adding-transitions
>
{/* here don't need to give ---> && query !== "" <---- condition */}
{/* https://tailwind-react-kit.tarikulcraft.com/components/forms */}
{filteredPeoples?.length === 0 ? (
<div className="relative cursor-default select-none px-4 py-2 text-gray-700">
Nothing found.
</div>
) : (
filteredPeoples?.map((person) => (
<ComboboxOption
key={person.id}
value={person}
className="group truncate flex gap-2 pl-2 py-1 bg-white font-normal data-[selected]:font-medium data-[focus]:bg-teal-500 data-[focus]:text-white cursor-pointer"
>
{/* https://headlessui.com/react/combobox#using-data-attributes */}
<CheckIcon className="invisible size-5 group-data-[selected]:visible text-teal-600 group-data-[focus]:text-white" />
{person.name}
</ComboboxOption>
))
)}
</ComboboxOptions>
</div>
</Combobox>
</Field>
</div>
);
}
export default AutocompleteMultiSelect;
@jubayer-webdev
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment