四种不同颜色chips/tags,自定义颜色
Four different colour chips/tags, customizing their colour
现在我的自动完成菜单中包含两个数组,它们 chip/tag 的颜色是主要颜色还是次要颜色,具体取决于所选组件是哪个数组的元素。
我想在菜单中包含所有四个数组(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" })),
];
下面是一种方法。
首先将另外两种颜色添加到您的主题中:
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
函数 returns 自定义 Chip
,它会覆盖当 color prop 等于“primary”时使用的颜色。可以找到被覆盖的默认样式 here and 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" }))
];
相关回答:
现在我的自动完成菜单中包含两个数组,它们 chip/tag 的颜色是主要颜色还是次要颜色,具体取决于所选组件是哪个数组的元素。
我想在菜单中包含所有四个数组(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" })),
];
下面是一种方法。
首先将另外两种颜色添加到您的主题中:
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
函数 returns 自定义 Chip
,它会覆盖当 color prop 等于“primary”时使用的颜色。可以找到被覆盖的默认样式 here and 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" }))
];
相关回答: