【问题标题】:Four different colour chips/tags, customizing their colour四种不同的颜色芯片/标签,定制它们的颜色
【发布时间】:2020-10-20 20:20:21
【问题描述】:

现在我的自动完成菜单中包含两个数组,它们的芯片/标签的颜色是主要的还是次要的,具体取决于所选组件是哪个数组的元素。

我想在菜单中包含所有四个数组(top10Songs、top10Artists、top10Films、top10Shows)。

我的问题是:

  1. 我怎么能有四种独特的颜色而不是两种(主要和次要)
  2. 如何自定义这些颜色

我是 Material UI 的新手,非常感谢您的帮助!

import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import { makeStyles } from "@material-ui/core/styles";
import { Chip } from "@material-ui/core";

const useStyles = makeStyles({
  textField: {
    "& input::placeholder": {
      color: "#a2a1a1",
      fontStyle: "italic",
    },
  },
});

export default function Tags() {
  const [selectedOptions, setSelectedOptions] = React.useState([]);

  const classes = useStyles();

  return (
    <div style={{ width: 500 }}>
      <Autocomplete
        disableClearable="true"
        filterSelectedOptions="true"
        multiple
        id="tags-standard"
        options={final}
        value={selectedOptions}
        onChange={(event, newValue) => {
          setSelectedOptions(newValue);
        }}
        getOptionSelected={(o, v) => o.title === v.title && o.year === v.year}
        getOptionLabel={(o) => o.title + " " + o.year}
        renderTags={(value, getTagProps) => []}
        renderInput={(params) => (
          <TextField
            {...params}
            className={classes.textField}
            variant="standard"
            placeholder="Favorites"
            margin="normal"
            //color="blue"
            fullWidth
          />
        )}
      />

      <div>
        {selectedOptions.map((option, index) => (
          <Chip
            key={index}
            color={option.type === "film" ? "primary" : "secondary"}
            label={`${option.title} ${option.year}`}
            onDelete={() =>
              setSelectedOptions([
                ...selectedOptions.slice(0, index),
                ...selectedOptions.slice(index + 1),
              ])
            }
          />
        ))}
      </div>
    </div>
  );
}

const top10Songs = [
  { title: "A", year: 1 },
  { title: "B", year: 2 },
  { title: "C", year: 3 },
  { title: "D", year: 4 },
  { title: "E", year: 5 },
  { title: "F", year: 6 },
  { title: "G", year: 7 },
  { title: "H", year: 8 },
  { title: "I", year: 9 },
  { title: "J", year: 10 },
  { title: "K", year: 11 },
  { title: "L", year: 12 },
  { title: "M", year: 13 },
  { title: "N", year: 14 },
  { title: "O", year: 15 },
  { title: "P", year: 16 },
];

const top10Artists = [
  { title: "Aa", year: 1 },
  { title: "Bb", year: 2 },
  { title: "Cc", year: 3 },
  { title: "Dd", year: 4 },
  { title: "Ee", year: 5 },
  { title: "Ff", year: 6 },
  { title: "Gg", year: 7 },
  { title: "Hh", year: 8 },
  { title: "Ii", year: 9 },
  { title: "Jj", year: 10 },
  { title: "Kk", year: 11 },
  { title: "Ll", year: 12 },
  { title: "Mm", year: 13 },
  { title: "Nn", year: 14 },
  { title: "Oo", year: 15 },
  { title: "Pp", year: 16 },
];

// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const top10Shows = [
  { title: "Once Upon a Time in the West", year: 1968 },
  { title: "American History X", year: 1998 },
  { title: "Interstellar", year: 2014 },
  { title: "Casablanca", year: 1942 },
  { title: "City Lights", year: 1931 },
  { title: "Psycho", year: 1960 },
  { title: "The Green Mile", year: 1999 },
  { title: "The Intouchables", year: 2011 },
  { title: "Modern Times", year: 1936 },
  { title: "Raiders of the Lost Ark", year: 1981 },
];

const top10Films = [
  { title: "Once Upon a Time in the West", year: 1968 },
  { title: "American History X", year: 1998 },
  { title: "Interstellar", year: 2014 },
  { title: "Casablanca", year: 1942 },
  { title: "City Lights", year: 1931 },
  { title: "Psycho", year: 1960 },
  { title: "The Green Mile", year: 1999 },
  { title: "The Intouchables", year: 2011 },
  { title: "Modern Times", year: 1936 },
  { title: "Raiders of the Lost Ark", year: 1981 },
];

const final = [
  ...top10Films.map((f) => Object.assign({}, f, { type: "film" })),
  ...top10Shows.map((s) => Object.assign({}, s, { type: "show" })),
];

【问题讨论】:

    标签: javascript reactjs autocomplete material-ui react-material


    【解决方案1】:

    以下是执行此操作的一种方法。

    首先将另外两种颜色添加到您的主题中:

    const theme = createMuiTheme({
      palette: {
        tertiary: lime,
        quaternary: orange
      }
    });
    // This is a step that Material-UI automatically does for the standard palette colors.
    theme.palette.tertiary = theme.palette.augmentColor(theme.palette.tertiary);
    theme.palette.quaternary = theme.palette.augmentColor(theme.palette.quaternary);
    

    以下getCustomChip 函数返回Chip 的自定义,它会覆盖在颜色属性等于“primary”时使用的颜色。可以在herehere 中找到被覆盖的默认样式。

    const getCustomChip = color =>
      withStyles(theme => ({
        colorPrimary: {
          backgroundColor: theme.palette[color].main,
          color: theme.palette[color].contrastText
        },
        deletableColorPrimary: {
          "&:focus": {
            backgroundColor: emphasize(theme.palette[color].main, 0.2)
          }
        }
      }))(Chip);
    

    然后设置选项类型到Chip自定义的映射:

    const typeToChip = {
      song: Chip,
      artist: getCustomChip("secondary"),
      film: getCustomChip("tertiary"),
      show: getCustomChip("quaternary")
    };
    

    然后使用该映射:

             {selectedOptions.map((option, index) => {
                const ChipForType = typeToChip[option.type];
                return (
                  <ChipForType
                    key={index}
                    color="primary"
                    label={`${option.title} ${option.year}`}
                    onDelete={() =>
                      setSelectedOptions([
                        ...selectedOptions.slice(0, index),
                        ...selectedOptions.slice(index + 1)
                      ])
                    }
                  />
                );
              })}
    

    这是完整的代码:

    import React from "react";
    import TextField from "@material-ui/core/TextField";
    import Autocomplete from "@material-ui/lab/Autocomplete";
    import {
      makeStyles,
      withStyles,
      ThemeProvider,
      createMuiTheme
    } from "@material-ui/core/styles";
    import { Chip } from "@material-ui/core";
    import { emphasize } from "@material-ui/core/styles/colorManipulator";
    import lime from "@material-ui/core/colors/lime";
    import orange from "@material-ui/core/colors/orange";
    
    const useStyles = makeStyles({
      textField: {
        "& input::placeholder": {
          color: "#a2a1a1",
          fontStyle: "italic"
        }
      }
    });
    
    const theme = createMuiTheme({
      palette: {
        tertiary: lime,
        quaternary: orange
      }
    });
    // This is a step that Material-UI automatically does for the standard palette colors.
    theme.palette.tertiary = theme.palette.augmentColor(theme.palette.tertiary);
    theme.palette.quaternary = theme.palette.augmentColor(theme.palette.quaternary);
    
    const getCustomChip = color =>
      withStyles(theme => ({
        colorPrimary: {
          backgroundColor: theme.palette[color].main,
          color: theme.palette[color].contrastText
        },
        deletableColorPrimary: {
          "&:focus": {
            backgroundColor: emphasize(theme.palette[color].main, 0.2)
          }
        }
      }))(Chip);
    
    const typeToChip = {
      song: Chip,
      artist: getCustomChip("secondary"),
      film: getCustomChip("tertiary"),
      show: getCustomChip("quaternary")
    };
    
    export default function Tags() {
      const [selectedOptions, setSelectedOptions] = React.useState([]);
    
      const classes = useStyles();
    
      return (
        <ThemeProvider theme={theme}>
          <div style={{ width: 500 }}>
            <Autocomplete
              disableClearable="true"
              filterSelectedOptions="true"
              multiple
              id="tags-standard"
              options={final}
              value={selectedOptions}
              onChange={(event, newValue) => {
                setSelectedOptions(newValue);
              }}
              getOptionSelected={(o, v) => o.title === v.title && o.year === v.year}
              getOptionLabel={o => o.title + " " + o.year}
              renderTags={(value, getTagProps) => []}
              renderInput={params => (
                <TextField
                  {...params}
                  className={classes.textField}
                  variant="standard"
                  placeholder="Favorites"
                  margin="normal"
                  //color="blue"
                  fullWidth
                />
              )}
            />
    
            <div>
              {selectedOptions.map((option, index) => {
                const ChipForType = typeToChip[option.type];
                return (
                  <ChipForType
                    key={index}
                    color="primary"
                    label={`${option.title} ${option.year}`}
                    onDelete={() =>
                      setSelectedOptions([
                        ...selectedOptions.slice(0, index),
                        ...selectedOptions.slice(index + 1)
                      ])
                    }
                  />
                );
              })}
            </div>
          </div>
        </ThemeProvider>
      );
    }
    
    const top10Songs = [
      { title: "A", year: 1 },
      { title: "B", year: 2 },
      { title: "C", year: 3 },
      { title: "D", year: 4 },
      { title: "E", year: 5 },
      { title: "F", year: 6 },
      { title: "G", year: 7 },
      { title: "H", year: 8 },
      { title: "I", year: 9 },
      { title: "J", year: 10 },
      { title: "K", year: 11 },
      { title: "L", year: 12 },
      { title: "M", year: 13 },
      { title: "N", year: 14 },
      { title: "O", year: 15 },
      { title: "P", year: 16 }
    ];
    
    const top10Artists = [
      { title: "Aa", year: 1 },
      { title: "Bb", year: 2 },
      { title: "Cc", year: 3 },
      { title: "Dd", year: 4 },
      { title: "Ee", year: 5 },
      { title: "Ff", year: 6 },
      { title: "Gg", year: 7 },
      { title: "Hh", year: 8 },
      { title: "Ii", year: 9 },
      { title: "Jj", year: 10 },
      { title: "Kk", year: 11 },
      { title: "Ll", year: 12 },
      { title: "Mm", year: 13 },
      { title: "Nn", year: 14 },
      { title: "Oo", year: 15 },
      { title: "Pp", year: 16 }
    ];
    
    // Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
    const top10Shows = [
      { title: "Psycho", year: 1960 },
      { title: "The Green Mile", year: 1999 },
      { title: "The Intouchables", year: 2011 },
      { title: "Modern Times", year: 1936 },
      { title: "Raiders of the Lost Ark", year: 1981 }
    ];
    
    const top10Films = [
      { title: "Once Upon a Time in the West", year: 1968 },
      { title: "American History X", year: 1998 },
      { title: "Interstellar", year: 2014 },
      { title: "Casablanca", year: 1942 },
      { title: "City Lights", year: 1931 }
    ];
    
    const final = [
      ...top10Songs.map(entry => ({ ...entry, type: "song" })),
      ...top10Artists.map(entry => ({ ...entry, type: "artist" })),
      ...top10Films.map(entry => ({ ...entry, type: "film" })),
      ...top10Shows.map(entry => ({ ...entry, type: "show" }))
    ];
    

    相关回答:Can you add an additional color in Material UI?

    【讨论】:

      猜你喜欢
      • 2021-10-21
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2023-04-08
      • 2019-08-25
      相关资源
      最近更新 更多