Material-UI: 如何访问组件内的所有调色板阴影

Material-UI: how to access all palette shades inside component

为了自定义我的 Material UI 调色板,我做了这样的事情来设置我的主题:

import blue from '@material-ui/core/colors/blue';

const theme = createMuiTheme({
  palette: {
    primary: blue,
  },
});

blue包含很多色号,如下图:

现在如何访问我的组件内 primary 调色板的所有阴影?访问 palette.grey 的所有阴影很容易,如下所示:

但是除了 maindarklightcontrastColor 之外,我似乎无法访问 primary 的阴影,如图所示以下:

如何从我的组件访问所有阴影(例如 theme.palette.primary.A100)?

根据Material UI color systems docs, it automatically calculates several values, such as dark, light, main. However, for more variant, it says using color objects@material-ui/core/colors/blue。它可能是您在第一个示例代码中使用的 blue

颜色对象的结构如下。 github link

const blue = {
  50: '#e3f2fd',
  100: '#bbdefb',
  200: '#90caf9',
  300: '#64b5f6',
  400: '#42a5f5',
  500: '#2196f3',
  600: '#1e88e5',
  700: '#1976d2',
  800: '#1565c0',
  900: '#0d47a1',
  A100: '#82b1ff',
  A200: '#448aff',
  A400: '#2979ff',
  A700: '#2962ff',
};

export default blue;

因此,如果您想为未作为 color object 使用的颜色使用更多变体,您应该将颜色变化设为您自己。

Now how do I access all the shades of primary palette inside of my component?

我觉得这里有个误会。您已经可以访问主题颜色的变体(darklightcontrastText),但如果您的意思是颜色对象的所有阴影(blue[100]blue[200],...)。那么不,createTheme() 不会自动为您生成。

来自Material-UI docs:

Only the main shades need be provided (unless you wish to further customize light, dark or contrastText), as the other colors will be calculated by createTheme(), as described in the Theme customization section.

当您仅向 main 属性 提供一种颜色时,如下所示:

const theme = createTheme({
  palette: {
    primary: {
      main: "#607d8b"
    }
  }
});

Material-UI 将计算该颜色的 lightdark 变体以及文本颜色的 contrastText。您可以登录 theme.palette.main 来确认这一点:

const useStyles = makeStyles((theme) => {
  console.log(theme.palette.main);
  return {};
});
{
  main: "#607d8b",
  light: "rgb(127, 151, 162)",
  dark: "rgb(67, 87, 97)",
  contrastText: "#fff",
}

如果您决定通过 color object:

import { createTheme } from '@material-ui/core/styles';
import blue from '@material-ui/core/colors/blue';

const theme = createTheme({
  palette: {
    primary: blue,
  },
});

然后Material-UI会找到那个物体的主要阴影。默认为blue[500],根据main颜色正常计算darklightcontrastText。最终结果将如下所示:

const useStyles = makeStyles((theme) => {
  console.log(theme.palette.main);
  return {};
});
{
  50: "#eceff1",
  100: "#cfd8dc",
  200: "#b0bec5",
  300: "#90a4ae",
  400: "#78909c",
  500: "#607d8b", // createPalette() uses this color as main
  600: "#546e7a",
  700: "#455a64",
  800: "#37474f",
  900: "#263238",
  A100: "#cfd8dc",
  A200: "#b0bec5",
  A400: "#78909c",
  A700: "#455a64",
  main: "#607d8b", // added from createPalette()
  light: "#90a4ae", // added from createPalette()
  dark: "#455a64", // added from createPalette()
  contrastText: "#fff", // added from createPalette()
}

打字稿用法

正如 this 问题指出的那样,如果您使用的是 Typescript,您可能会意识到它不会为您提供主题中的阴影信息 PaletteColor

const useStyles = makeStyles((theme) => {
  const shade = theme.palette.main[500]; // shade is any instead of string
  return {};
});

维护者建议的解决方案是使用模块扩充来扩展PaletteColor定义:

import { ColorPartial } from "@material-ui/core/styles/createPalette";

declare module "@material-ui/core/styles/createPalette" {
  interface PaletteColor extends ColorPartial {}
}

如果您使用 this linter 规则建议来避免导入私有模块(任何比 2 级导入更深的模块)。您可以像这样轻松地自己创建 ColorPartial

import { Color } from "@material-ui/core";

type ColorPartial = Partial<Color>;

declare module "@material-ui/core/styles/createPalette" {
  interface PaletteColor extends ColorPartial {}
}

现在打字稿可以识别您 PaletteColor:

中所有可能的阴影
const useStyles = makeStyles((theme) => {
  const shade = theme.palette.main[500]; // shade is string
  return {};
});

现场演示