简体   繁体   中英

How to create a highly customized Select component using MUI (React)?

I'm working on a front-end task and I need to create a Select menu that allows the user to choose several period options (last 7 days, 15 days, etc). The frontend is built in React + TypeScript and uses Material UI (MUI).

The problem is that they need two pieces of information to be displayed within the menu options: a main text (example: "Today") and an auxiliary text with that date/period (In the case of today's example, it would be "12/14/ 2022")

Here's the prototype: 在此处输入图像描述

However, I am not able to make the MUI work the way I need it to.

Here's what i tried to do:

     <FormControl sx={{ width: "300px" }}>
            <InputLabel id="demo-simple-select-label">Comparar com</InputLabel>
            <Select
              size="small"
              labelId="demo-simple-select-label"
              id="demo-simple-select"
              value={1}
              label="Comparar com"
              onChange={() => {}}
            >
              <MenuItem value={1}>
                <Stack
                  direction="row"
                  justifyContent="space-between"
                  alignItems="center"
                >
                  <Typography sx={{ mr: 1 }}>Hoje</Typography>
                  <Typography variant="subtitle2">
                    {dayjs().format("DD/MM/YYYY")}
                  </Typography>
                </Stack>
              </MenuItem>
              <MenuItem value={20}>placeholder</MenuItem>
              <MenuItem value={30}>placeholder</MenuItem>
            </Select>
     </FormControl>

Here's the result of the code above:

在此处输入图像描述

As shown in the prototype (first image attached), when selecting one of the options, the "label" of the select needs to display only the auxiliary text (which contains the selected date, ex: 12/14/2022, instead of "Today", or "07/12/2022 - 14/12/2022" instead of "Last 7 days").

Also, for some reason the justifyContent="space-between" in <MenuItem> is not applied inside the options, only when the option is selected and displayed in the select menu.

I would like to know if it is possible to solve these two problems with MUI and how I can get as close as possible to the prototype using MUI.

Thanks in advance for any help.

I created an example that I believe could help you:

import React from "react";
import {
  FormControl,
  InputLabel,
  MenuItem,
  Select,
  Typography,
} from "@mui/material";
import { useState } from "react";

const Control = () => {
  const data = [
    { name: "a", date: "2 nov 2023" },
    { name: "b", date: "3 nov 2022" },
    { name: "c", date: "7 nov 2021" },
  ];
  const [value, setValue] = useState(0);

  const items = data.map((item, key) => (
    <MenuItem
      onClick={() => {
        setValue(key);
      }}
      style={{ display: "block" }}
      key={key}
      value={key}
    >
      <Typography style={{}}>{item.name}</Typography>

      <div style={{ color: "#D3D3D3" }}>{item.date}</div>
    </MenuItem>
  ));

  return (
    <FormControl sx={{ width: "300px" }}>
      <InputLabel htmlFor="open-select" id="demo-simple-select-label">
        Comparar com
      </InputLabel>
      <Select
        size="small"
        labelId="demo-simple-select-label"
        id="demo-simple-select"
        value={value}
        label="Comparar com"
        onChange={() => {}}
        inputProps={{
          renderValue: (option) => data[value].name,
        }}
      >
        {items}
      </Select>
    </FormControl>
  );
};

export default Control;

The main thing is:

 inputProps={{
          renderValue: (option) => data[value].name,
        }}

in this way you can choose what the Select will show

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM