MaterialUI TextField : changing background color is not working as it is supposed to
Asked Answered
S

2

11

I'm trying to set the background color for TextField components in the app I'm working on, however it seems that when I add style={{background: "rgb(232, 241, 250)"}} to this component with my custom RGB values it displays them on top of the default gray background color.

Background color supposed to be same light blue as in the components above: problem screenshot

  1. I tried to resolve it by just adding the style property to it

  2. Also, by adding makeStyles() to the component and attaching it through className

In both cases, I got this output as on the screenshot above.

  1. I was able to get the correct background color by removing variant=filled or setting it to standard or outlined, but then the padding around the text would be removed.

I don't really understand what is this issue and how it could be actually fixed?

import React from "react";
import {TextField} from "@material-ui/core";

import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles((theme) => ({
     root: {
         background: 'rgb(232, 241, 250)'
      },
}));

export interface InquiryContentInputProps {
   content: string;
   onChange: (content: string) => void;
}

export function InquiryContentInput(props: InquiryContentInputProps) {
   const classes = useStyles();

   return (
       <TextField
          variant="filled"
          // style={{background: "rgb(232, 241, 250)"}}
          className={classes.root}
          fullWidth={true}
          multiline={true}
          rows={5}
          rowsMax={10}
          value={props.content}
          onChange={(e) => props.onChange(e.target.value as string)}
          label="Суть обращения"/>
   )
}
Sept answered 3/11, 2020 at 15:24 Comment(0)
C
31

TextField renders several elements -- an outer <div> for the FormControl element, and then within that the InputLabel and the Input element (e.g. FilledInput).

The className prop on TextField applies that class to the FormControl. The default background color for FilledInput, is rgba(0, 0, 0, 0.09), so this was still being applied over your light blue background on the FormControl.

You can instead override the background-color on the FilledInput as follows:

import React from "react";
import TextField from "@material-ui/core/TextField";

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

const useStyles = makeStyles((theme) => ({
  root: {
    "& .MuiFilledInput-root": {
      background: "rgb(232, 241, 250)"
    }
  }
}));

export default function InquiryContentInput(props) {
  const classes = useStyles();

  return (
    <TextField
      variant="filled"
      className={classes.root}
      fullWidth={true}
      multiline={true}
      rows={5}
      rowsMax={10}
      value={props.content}
      onChange={(e) => props.onChange(e.target.value)}
      label="Суть обращения"
    />
  );
}

Edit filled TextField background

Another option is to leverage InputProps to specify the className for the input:

import React from "react";
import TextField from "@material-ui/core/TextField";

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

const useStyles = makeStyles((theme) => ({
  input: {
    background: "rgb(232, 241, 250)"
  }
}));

export default function InquiryContentInput(props) {
  const classes = useStyles();

  return (
    <TextField
      variant="filled"
      InputProps={{ className: classes.input }}
      fullWidth={true}
      multiline={true}
      rows={5}
      rowsMax={10}
      value={props.content}
      onChange={(e) => props.onChange(e.target.value)}
      label="Суть обращения"
    />
  );
}

Edit filled TextField background (forked)

Just a follow up question: if I wanted to change the background color scheme on this TextField on focus and hover, would I also do it via some class override in the makeStyles? And what would it be or where could I find the names of those classes?

There are two main ways to determine the names of the classes:

  1. Inspect the elements in the browser developer tools to see the classes that are added by Material-UI.

  2. Look at the source code. This requires understanding some of how the Material-UI CSS class names are generated.

In FilledInput you can find the following styles defined (simplifying below to only include the background-color styles):

export const styles = (theme) => {
  const light = theme.palette.type === 'light';
  const backgroundColor = light ? 'rgba(0, 0, 0, 0.09)' : 'rgba(255, 255, 255, 0.09)';

  return {
    /* Styles applied to the root element. */
    root: {
      backgroundColor,
      transition: theme.transitions.create('background-color', {
        duration: theme.transitions.duration.shorter,
        easing: theme.transitions.easing.easeOut,
      }),
      '&:hover': {
        backgroundColor: light ? 'rgba(0, 0, 0, 0.13)' : 'rgba(255, 255, 255, 0.13)',
        // Reset on touch devices, it doesn't add specificity
        '@media (hover: none)': {
          backgroundColor,
        },
      },
      '&$focused': {
        backgroundColor: light ? 'rgba(0, 0, 0, 0.09)' : 'rgba(255, 255, 255, 0.09)',
      },
      '&$disabled': {
        backgroundColor: light ? 'rgba(0, 0, 0, 0.12)' : 'rgba(255, 255, 255, 0.12)',
      },
    },

The keys in this structure (e.g. root) will be converted to class names with the general pattern of Mui${componentName}-${styleRuleKey} (e.g. MuiFilledInput-root). The pseudo-classes (e.g. $focused, $disabled) are documented here and get prefixed with Mui- (e.g. Mui-focused, Mui-disabled).

You can override the hover and focused colors, by following the same pattern as in the FilledInput source code:

import React from "react";
import TextField from "@material-ui/core/TextField";

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

const useStyles = makeStyles((theme) => ({
  root: {
    "& .MuiFilledInput-root": {
      backgroundColor: "rgb(232, 241, 250)"
    },
    "& .MuiFilledInput-root:hover": {
      backgroundColor: "rgb(250, 232, 241)",
      // Reset on touch devices, it doesn't add specificity
      "@media (hover: none)": {
        backgroundColor: "rgb(232, 241, 250)"
      }
    },
    "& .MuiFilledInput-root.Mui-focused": {
      backgroundColor: "rgb(250, 241, 232)"
    }
  }
}));

export default function InquiryContentInput(props) {
  const classes = useStyles();

  return (
    <TextField
      variant="filled"
      className={classes.root}
      fullWidth={true}
      multiline={true}
      rows={5}
      rowsMax={10}
      value={props.content}
      onChange={(e) => props.onChange(e.target.value)}
      label="Суть обращения"
    />
  );
}

Edit filled TextField background (hover and focus)

I have another follow up question. If I wanted to define those values in the theme (for example, MuiFilledInput for all states including hover and focus), how would I do it? I was able to add it on its regular state right now through adding: const theme = createMuiTheme({ "overrides": { "MuiFilledInput": { "root": { "backgroundColor": 'rgb(232, 241, 250)' } } } }) But I can't add custom background values to the theme for hover and focus

Here's the syntax for doing these same styles in the theme:

import React from "react";
import TextField from "@material-ui/core/TextField";

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

const theme = createMuiTheme({
  overrides: {
    MuiFilledInput: {
      root: {
        backgroundColor: "rgb(232, 241, 250)",
        "&:hover": {
          backgroundColor: "rgb(250, 232, 241)",
          // Reset on touch devices, it doesn't add specificity
          "@media (hover: none)": {
            backgroundColor: "rgb(232, 241, 250)"
          }
        },
        "&.Mui-focused": {
          backgroundColor: "rgb(250, 241, 232)"
        }
      }
    }
  }
});

export default function InquiryContentInput(props) {
  return (
    <ThemeProvider theme={theme}>
      <TextField
        variant="filled"
        fullWidth={true}
        multiline={true}
        rows={5}
        rowsMax={10}
        value={props.content}
        onChange={(e) => props.onChange(e.target.value)}
        label="Суть обращения"
      />
    </ThemeProvider>
  );
}

Edit filled TextField background (hover and focus) via theme

Codger answered 3/11, 2020 at 16:11 Comment(5)
Everything worked, thank you! Just a follow up question: if I wanted to change the background color scheme on this TextField on focus and hover, would I also do it via some class override in the makeStyles? And what would it be or where could I find the names of those classes?Sept
@Sept I've added another example to the end of my answer.Codger
@RyanCogswell Hello again, I have another follow up question. If I wanted to define those values in the theme (for example, MuiFilledInput for all states including hover and focus), how would I do it? I was able to add it on its regular state right now through adding: const theme = createMuiTheme({ "overrides": { "MuiFilledInput": { "root": { "backgroundColor": 'rgb(232, 241, 250)' } } } }) But I can't add custom background values to the theme for hover and focusSept
@Sept I've added a theme example at the end.Codger
You could change it in the inputprop.Woodman
P
0

This seems to be easier now in MUIv5 according to the documentation. If you want to style the root element of the component just add your CSS attributes directly to the sx property of the component. If you want to style nested elements that get rendered as part of this component, you can now just add the class name into this same sx property.

For example, I want to style a text input component. I add width: 100% to make it larger and if I want the background color to be white instead of transparent/grey I can add the nested div's CSS class name to sx as follows:

import TextField from '@mui/material/TextField';

<TextField
  id="text-search"
  label="Search for stuff"
  variant="filled"
  sx={{
    width: '100%',
    '& .MuiFilledInput-root': {
      backgroundColor: 'white'
    }
  }}
/>
Presnell answered 5/4 at 19:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.