四种不同的颜色芯片/标签,定制它们的颜色

Posted

技术标签:

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

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

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

我的问题是:

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

我是 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" )),
];

【问题讨论】:

【参考方案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”时使用的颜色。可以在here 和here 中找到被覆盖的默认样式。

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?

【讨论】:

以上是关于四种不同的颜色芯片/标签,定制它们的颜色的主要内容,如果未能解决你的问题,请参考以下文章

VueJS/Vuetify v-for 中的不同颜色芯片,检查带有参数的对象:使用点表示法的颜色

python matplotlib:为堆栈图添加标签并正确设置它们的颜色

如何使用 2 个不同颜色的标签制作 UITableViewCell?

标签栏控制器中标签栏项目的不同颜色

在 plotly 中显式设置箱线图的颜色

如何更改在 ngFor 中单击的每个 div 的背景颜色?