I am looking for something like this to implement in ReactJS/Material-UI. Any existing component or library for this?
CodePudding user response:
You can do that with the Autocomplete
component by overriding the ListboxProps
of the Listbox
which is the container of the dropdown and set the CSS grid to display 3 equal width columns using the fr
unit:
<Autocomplete
ListboxProps={{
style: {
display: "grid",
gridTemplateColumns: "1fr 1fr 1fr",
maxHeight: "initial",
}
}}
Now assuming the option has the following type:
type TagOption = {
tag: string;
views: number;
description: string;
};
In the Stackoverflow dropdown, there are only 6 options at max, so we need to restrict the number of options shown in the Listbox
:
import Autocomplete, { createFilterOptions } from "@mui/material/Autocomplete";
const _filterOptions = createFilterOptions<TagOption>();
const filterOption = (props, state) => {
const results = _filterOptions(props, state);
return results.slice(0, 6);
};
<Autocomplete filterOptions={filterOption}
We also want to create a customized option component for each grid item. Here is a minimal example without any much styles to get you started:
function OptionItem({ option, ...other }) {
return (
<li
{...other}
style={{
display: "block"
}}
>
<div>
<Chip label={option.tag} />
{option.views}
</div>
<div>{option.description}</div>
</li>
);
}
renderOption={(props, option, { selected }) => (
<OptionItem {...props} option={option} />
)}
And finally set the isOptionEqualToValue
and getOptionLabel
to ensure that the option get filtered properly and the input display the correct tag when selected:
isOptionEqualToValue={(option, value) => option.tag === value.tag}
getOptionLabel={(option) => option.tag}
Live Demo (Source)
CodePudding user response:
That's not a perfect fit, but you can use autocomplete (using multiple, customizable and asynchronous)