Home > other >  Is there a Material-UI component to search/select tags like in stackoverflow?
Is there a Material-UI component to search/select tags like in stackoverflow?

Time:10-12

I am looking for something like this to implement in ReactJS/Material-UI. Any existing component or library for this?

enter image description here

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)

  • Related