How to change Material-UI TextFiled's border, text color and border color on hover

4.7k Views Asked by At

I'm not fully understanding how to customise MaterialUI components. After reading through the dos https://material-ui.com/customization/components/ I understand how to customise using classes and className. I don't understand the advanced techniques - really confusing.

Here is an example I've found on codesandbox on customising TextFields https://codesandbox.io/s/6rx8p?file=/demo.tsx:842-858

e.g.

const CssTextField = withStyles({
  root: {
    '& label.Mui-focused': {
      color: 'green',
    },
    '& .MuiInput-underline:after': {
      borderBottomColor: 'green',
    },
    '& .MuiOutlinedInput-root': {
      '& fieldset': {
        borderColor: 'red',
      },
      '&:hover fieldset': {
        borderColor: 'yellow',
      },
      '&.Mui-focused fieldset': {
        borderColor: 'green',
      },
    },
  },
})(TextField);

From the above example where does the property fieldset. I can't seen to find anywhere in the doc about the prop fieldset. Even looking through Chrome Dev tools I can't see where this property comes from.

How do you figure out which property does what. Is there and easy way to understand this with some example.

Is there a tutorial I can go through?

2

There are 2 best solutions below

0
On

fieldset is not a TextFields's property but a html tag from other component. if you check at Chrome Dev tools you can find <fieldset> with some css class.

TextFields is composed from other smaller components as you can check text-fields - components. fieldset comes from the small component OutlinedInput. it has the global css class MuiOutlinedInput-notchedOutline which you can find it at you css list.

you can check at github OutlinedInput implementation.fieldset comes from NotchedOutline.js.

As you said, it's not explicit in the documentation. it doesn't list the tag elements composing a given component. It required me some investigation to dig deeper to find out its structure.

0
On

You can use TextField props provided by material-ui/core actually:-

  • InputLabelProps: to apply styles on label
  • InputProps: to apply styles on input itself

this is an example of it:-

import React, { useState } from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { FormGroup, TextField } from '@material-ui/core'

const Demo = () => {
  const classes = useStyles()
  const [name, setName] = useState('')
  
  return (
    <FormGroup>
      <TextField 
        label="Name"
        variant="outlined"
        value={name}
        onChange={(e) => setName(e.target.value)} 
        required
        InputLabelProps={{
          classes: {
            root: classes.textFieldLabel,
            focused: classes.textFieldLabelFocused
          }
        }}
        InputProps={{
          classes: {
            root: classes.textFieldRoot,
            focused: classes.textFieldFocused,
            notchedOutline: classes.textFieldNotchedOutline
          }
        }}
      />
    </FormGroup>
  )
}

export default Demo

const useStyles = makeStyles(theme => ({
  textFieldLabel: {
    // this will be applied when input focused (label color change)
    "&$textFieldLabelFocused": {
      color: theme.palette.secondary.main
    }
  },
  textFieldLabelFocused: {},
  textFieldRoot: {
    // this will be applied when hovered (input text color change)
    "&:hover": {
      color: theme.palette.secondary.main,
    },
    // this will applied when hovered (input border color change)
    "&:hover $textFieldNotchedOutline": {
      borderColor: theme.palette.secondary.main
    },
    // this will be applied when focused (input border color change)
    "&$textFieldFocused $textFieldNotchedOutline": {
      borderColor: theme.palette.secondary.main
    }
  },
  textFieldFocused: {},
  textFieldNotchedOutline: {}
}));

You can see it in this working sandbox here