简体   繁体   English

JSS 中的 MUI 全局类名称有多可靠?

[英]How reliable are MUI Global Class names in JSS?

I have code like this:我有这样的代码:

const formControlStyles = {
  root: {
    '&:hover .MuiFormLabel-root': {

     }
  }
}

Is it safe to use the class name in theme overrides to access other components?在主题覆盖中使用类名来访问其他组件是否安全? Additionally, is there a JSS way of nesting styles from other components?另外,是否有一种 JSS 方式可以从其他组件中嵌套样式?

UPDATE for v5 This answer was originally written regarding v4 of Material-UI. v5 的更新这个答案最初是关于 Material-UI 的 v4 编写的。 In v5, the global class names are no longer used by Material-UI to apply the default styles -- the classes used for the default styles have class names generated by Emotion.在 v5 中,Material-UI 不再使用全局类名来应用默认样式——用于默认样式的类具有由 Emotion 生成的类名。 The global class names are still applied, but they are no longer impacted by nested themes, so in v5 it is completely safe to leverage the global class names for overrides without needing to use the [class*=... syntax mentioned in my original answer below.全局类名仍然适用,但它们不再受嵌套主题的影响,因此在 v5 中利用全局类名进行覆盖是完全安全的,而无需使用[class*=...下面回答。


It is fairly safe to use global class names, but with one caveat (in v4).使用全局类名是相当安全的,但有一个警告(在 v4 中)。 If you leverage nested themes, the global class names applied within the nested theme will have an unpredictable suffix (eg MuiFormLabel-root-371 ).如果您利用嵌套主题,嵌套主题中应用的全局类名称将具有不可预测的后缀(例如MuiFormLabel-root-371 )。 This suffixing is necessary, because the default styles associated with a nested theme can be different.此后缀是必要的,因为与嵌套主题关联的默认样式可能不同。

In order to target the class names in a completely safe manner, you can use the *= attribute selector (eg [class*="MuiFormLabel-root"] ) which checks to see if the element has a class name that contains MuiFormLabel-root rather than needing to match it exactly.为了以完全安全的方式定位类名,您可以使用*= 属性选择器(例如[class*="MuiFormLabel-root"] ),它检查元素是否具有包含MuiFormLabel-root的类名而不是需要完全匹配它。 You can see this approach used within Material-UI itself here .您可以在此处查看Material-UI 本身中使用的这种方法。

So long as you don't intend on using nested themes, it is safe (and much more readable) to use the simpler syntax of matching the global class names exactly.只要您不打算使用嵌套主题,使用精确匹配全局类名的更简单的语法是安全的(并且更具可读性)。 An alternative approach is to specify a JSS class on the nested component and refer to that class using the JSS syntax for referring to another rule in the same stylesheet (eg $myFormLabel in my example), but this requires being able to apply that class (eg classes.myFormLabel in my example) to the nested component.另一种方法是在嵌套组件上指定一个 JSS 类,并使用 JSS 语法引用该类以引用同一样式表中的另一个规则(例如,在我的示例中$myFormLabel ),但这需要能够应用该类(例如在我的示例中的classes.myFormLabel ) 到嵌套组件。

Below is an example which demonstrates the issue (and some possible solutions) when using nested themes.下面是一个示例,它演示了使用嵌套主题时的问题(以及一些可能的解决方案)。

import React from "react";
import {
  ThemeProvider,
  createMuiTheme,
  makeStyles
} from "@material-ui/core/styles";
import FormLabel from "@material-ui/core/FormLabel";

const theme1 = createMuiTheme();
const theme2 = createMuiTheme({
  overrides: {
    MuiFormLabel: {
      root: {
        color: "#00ff00"
      }
    }
  }
});

const useStyles = makeStyles({
  mostlySafe: {
    "&:hover .MuiFormLabel-root": {
      color: "red"
    }
  },
  safeButTediousAndMoreErrorProneSyntax: {
    '&:hover [class*="MuiFormLabel-root"]': {
      color: "purple"
    }
  },
  alternativeApproach: {
    "&:hover $myFormLabel": {
      color: "blue"
    }
  },
  myFormLabel: {}
});
export default function App() {
  const classes = useStyles();
  return (
    <ThemeProvider theme={theme1}>
      <div>
        <div className={classes.mostlySafe}>
          <FormLabel>FormLabel within top-level theme</FormLabel>
        </div>
        <ThemeProvider theme={theme2}>
          <div className={classes.mostlySafe}>
            <FormLabel>
              FormLabel within nested theme (hover styling doesn't work)
            </FormLabel>
          </div>
          <div className={classes.safeButTediousAndMoreErrorProneSyntax}>
            <FormLabel>
              FormLabel within nested theme using safe approach
            </FormLabel>
          </div>
          <div className={classes.alternativeApproach}>
            <FormLabel className={classes.myFormLabel}>
              FormLabel within nested theme without using global class names
            </FormLabel>
          </div>
        </ThemeProvider>
      </div>
    </ThemeProvider>
  );
}

编辑全局类名

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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