-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Closed
Description
Is your feature request related to a problem? Please describe.
null
Describe the solution you'd like
import React, {Key, useEffect, useState} from "react";
import {Chip, Autocomplete, AutocompleteItem} from "@heroui/react";
type Option = {
id: number;
title: string;
};
type MultiSelectAutocompleteProps = {
options: Option[];
defaultSelected?: Option[];
placeholder?: string;
};
const options = [
{id: 1, title: "Title 1"},
{id: 2, title: "Title 2"},
{id: 3, title: "Title 3"},
{id: 4, title: "Title 4"},
{id: 5, title: "Title 5"},
];
const defaultSelected = [
{id: 3, title: "Title 3"},
{id: 5, title: "Title 5"},
];
const MultiSelectAutocomplete: React.FC<MultiSelectAutocompleteProps> = ({
// options,
// defaultSelected = [],
placeholder = "Search...",
...rest
}) => {
const [data, setData] = useState<Option[]>((defaultSelected as unknown as Option[]) ?? []);
const [search, setSearch] = useState("");
const [selectedItems, setSelectedItems] = useState<Option[]>([]);
useEffect(() => {
if (selectedItems.length === 0 && defaultSelected.length > 0) {
setSelectedItems(defaultSelected);
setData(defaultSelected);
}
}, [selectedItems, setData]);
const filteredOptions = options.filter(
(option) =>
option.title.toLowerCase().includes(search.toLowerCase()) &&
!selectedItems.find((selected) => selected.title === option.title),
);
const handleSelect = (item: Option) => {
if (!selectedItems.find((selected) => selected.title === item.title)) {
const updatedItems = [...selectedItems, item];
setSelectedItems(updatedItems);
setData(updatedItems);
}
};
const handleRemove = (item: Option) => {
const updatedItems = selectedItems.filter((selected) => selected.title !== item.title);
setSelectedItems(updatedItems);
setData(updatedItems);
};
console.log(data);
// will output
// [
// {id: 3, title: "Title 3"},
// {id: 5, title: "Title 5"},
// ];
return (
<div className="space-y-4">
<Autocomplete
{...rest}
labelPlacement="outside"
variant="bordered"
aria-labelledby="search"
shouldCloseOnBlur={false}
placeholder={placeholder}
value={search}
onChange={(e: {target: {value: React.SetStateAction<string>}}) => setSearch(e.target.value)}
onSelectionChange={(value: Key | null) => {
const item = options.find((option) => option.title === value);
if (item) handleSelect(item);
setSearch("");
}}
>
{filteredOptions.map((option) => (
<AutocompleteItem key={option.title} data-selected="true" value={option.id}>
{option.title}
</AutocompleteItem>
))}
</Autocomplete>
<div className="flex flex-wrap gap-2">
{selectedItems.map((item) => (
<Chip key={item.id} color="primary" variant="flat" onClose={() => handleRemove(item)}>
{item.title}
</Chip>
))}
</div>
</div>
);
};
export default MultiSelectAutocomplete;
Still a little buggy and can be improved further...
Describe alternatives you've considered
null
Screenshots or Videos
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels

