Created
August 10, 2024 17:28
-
-
Save jubayer-webdev/40572dafdc273d8e7087cd90800f0f7b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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; |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note
******************* Resources *******************
https://headlessui.com/react/combobox
https://tailwind-react-kit.tarikulcraft.com/components/forms