【问题标题】:How to style InputAdornment like notched OutlinedInput?如何像缺口 OutlinedInput 一样设置 InputAdornment 的样式?
【发布时间】:2020-04-26 12:02:27
【问题描述】:

我正在使用 React JS 和 Material UI 框架。

我需要文本字段内的装饰图标颜色表现得像输入的边框。

如果您查看文档中的example,您可以看到:

  • 悬停输入,边框会变宽变黑
  • 聚焦输入,边框会更宽,有原色

我发现这些设置来自component 的样式。

如何将这些规则颜色应用于图标?

另一个相关问题 - 除了主要或次要颜色之外,最简单的方法是什么?仅通过覆盖文档中描述的类?

【问题讨论】:

    标签: reactjs material-ui jss


    【解决方案1】:

    以下是如何执行此操作的示例——关键方面是 outlinedInput 类和(如果您还想同步标签)textField 类。颜色可以是您想要使用的任何颜色,但在此示例中,我使用的主题颜色与用于边框的颜色相同。

    import React from "react";
    import clsx from "clsx";
    import { makeStyles } from "@material-ui/core/styles";
    import IconButton from "@material-ui/core/IconButton";
    import OutlinedInput from "@material-ui/core/OutlinedInput";
    import InputLabel from "@material-ui/core/InputLabel";
    import InputAdornment from "@material-ui/core/InputAdornment";
    import FormControl from "@material-ui/core/FormControl";
    import Visibility from "@material-ui/icons/Visibility";
    import VisibilityOff from "@material-ui/icons/VisibilityOff";
    
    const useStyles = makeStyles(theme => ({
      root: {
        display: "flex",
        flexWrap: "wrap"
      },
      margin: {
        margin: theme.spacing(1)
      },
      textField: {
        width: 200,
        "&:hover .MuiInputLabel-root": {
          color: theme.palette.text.primary
        },
        "& .Mui-focused.MuiInputLabel-root": {
          color: theme.palette.primary.main
        }
      },
      outlinedInput: {
        "&:hover .MuiInputAdornment-root .MuiSvgIcon-root": {
          color: theme.palette.text.primary
        },
        "&.Mui-focused .MuiInputAdornment-root .MuiSvgIcon-root": {
          color: theme.palette.primary.main
        }
      }
    }));
    
    export default function InputAdornments() {
      const classes = useStyles();
      const [values, setValues] = React.useState({
        password: "",
        showPassword: false
      });
    
      const handleChange = prop => event => {
        setValues({ ...values, [prop]: event.target.value });
      };
    
      const handleClickShowPassword = () => {
        setValues({ ...values, showPassword: !values.showPassword });
      };
    
      const handleMouseDownPassword = event => {
        event.preventDefault();
      };
    
      return (
        <div className={classes.root}>
          <div>
            <FormControl
              className={clsx(classes.margin, classes.textField)}
              variant="outlined"
            >
              <InputLabel htmlFor="outlined-adornment-password">
                Password
              </InputLabel>
              <OutlinedInput
                id="outlined-adornment-password"
                type={values.showPassword ? "text" : "password"}
                value={values.password}
                onChange={handleChange("password")}
                className={classes.outlinedInput}
                endAdornment={
                  <InputAdornment position="end">
                    <IconButton
                      aria-label="toggle password visibility"
                      onClick={handleClickShowPassword}
                      onMouseDown={handleMouseDownPassword}
                      edge="end"
                    >
                      {values.showPassword ? <Visibility /> : <VisibilityOff />}
                    </IconButton>
                  </InputAdornment>
                }
                labelWidth={70}
              />
            </FormControl>
          </div>
        </div>
      );
    }
    

    来自 cmets 的后续问题:

    如何正确覆盖多个类?我看到它有效并且我理解你的解释,但是 - 似乎我不太明白我需要在类名之间或“&:悬停”之后添加空格的位置。例如,在我的演示中,为了在聚焦时为标签着色,我写了“&.Mui-focused.MuiInputLabel-root”,而在您的演示中,它是“&.Mui-focused.MuiInputLabel-root”,“&”后面有空格。当然,区别是因为我在 InputLabel 上应用了样式,而你在 TextField 上应用了样式,但为什么不一样呢?

    &amp; 指的是为当前样式规则生成的 CSS 类(例如 classes.textFieldclasses.outlinedInput)。该空间是descendant CSS selector。具有“MuiInputLabel-root”类的元素是接收classes.textField 类的元素的后代,因此&amp; .Mui-focused.MuiInputLabel-root 成功定位标签。如果没有空格,它只会针对具有classes.textField 类和MuiInputLabel-root 类的元素。如果 classes.textField 类被应用于标签元素,那么这将起作用,但由于我们需要将鼠标悬停在整个输入上而不仅仅是标签上,因此需要将类应用于父元素。

    相关文档:

    【讨论】:

    • 非常感谢!这正是我想要的:-)
    • 另一个相关问题,悬停时如何设置标签颜色的样式?我设法同步了:文本、标签、边框(缺口)和装饰,以及何时不聚焦和聚焦。同步也适用于悬停文本边框和装饰,但不适用于标签。演示:codesandbox.io/s/…
    • 我已更新我的答案以包含标签,这是您的沙盒的更改版本:codesandbox.io/s/…。由于 label 是输入的兄弟,因此您需要使用它们的共同父级 - FormControl 元素来控制悬停。 FormControlTextField 的根元素,因此您可以使用 TextField 上的 className 属性定位它。
    • 感谢您的大力帮助!同样,另一个相关问题:如何正确覆盖多个类?我看到它有效并且我理解你的解释,但是 - 似乎我不太明白我需要在类名之间或“&:悬停”之后添加空格的位置。例如,在我的演示中,为了在聚焦时为标签着色,我写了“&.Mui-focused.MuiInputLabel-root”,而在您的演示中,它是“&.Mui-focused.MuiInputLabel-root”,“&”后面有空格。当然,区别是因为我在 InputLabel 上应用了样式,而你在 TextField 上应用了样式,但为什么不一样呢?
    • 在答案末尾查看我的补充。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 2012-04-18
    • 1970-01-01
    相关资源
    最近更新 更多