Как оформить InputAdornment как вырезанный OutlinedInput? - PullRequest
1 голос
/ 09 января 2020

Я использую React JS и Framework UI Material.

Мне нужен цвет значка украшения внутри текстового поля, чтобы он вел себя как граница ввода.

Если вы посмотрите на примере из документации вы можете видеть, что когда:

  • При наведении на вход граница становится более широкой и черной
  • Фокусировка ввода, граница будет шире и будет иметь основной цвет

Я обнаружил, что эти настройки исходят из стиля, заданного для компонента .

Как применить эти правила к цветам на иконку?

Еще один связанный с этим вопрос - какой самый простой способ дать цвет, отличный от основного или дополнительного? Только путем переопределения классов, как описано в документации?

1 Ответ

1 голос
/ 09 января 2020

Ниже приведен пример того, как это сделать - ключевыми аспектами являются класс outlinedInput и (если вы также хотите синхронизировать c метку) класс 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>
  );
}

Edit Sync adornment color with border

Последующие вопросы из комментариев:

Как правильно переопределить несколько классов? Я вижу, что это работает, и я понимаю ваше объяснение, однако, кажется, что я не совсем понимаю, где мне нужно добавить пробел между именами классов или после '&: hover'. Например, в моей демонстрации, чтобы закрасить метку в фокусе, я написал «& .Mui-focus.MuiInputLabel- root», в то время как в вашей демонстрации это «& .Mui-focus.MuiInputLabel- root» с пробелом после «&». Конечно, разница в том, что я применил стили к InputLabel, а вы к TextField, но почему он отличается?

& относится к классу CSS, созданному для текущего стиля правило (например, classes.textField или classes.outlinedInput). Пробел является потомком CSS селектором . Элемент с классом «MuiInputLabel- root» является потомком элемента, получающего класс classes.textField, поэтому & .Mui-focused.MuiInputLabel-root успешно нацеливается на метку. Без пробела он будет предназначен только для элементов, которые имеют класс classes.textField и класс MuiInputLabel-root. Если бы класс classes.textField применялся к элементу метки, это сработало бы, но, поскольку нам нужно нацеливать наведение на весь ввод, а не только на метку, этот класс необходимо применить к родительскому элементу.

Соответствующая документация:

...