5

I'm having a bit of difficulties with the theming in Material-UI when it comes to coloring elements. Some elements automatically choose 'theme.palette.main.dark'. I want to know how to force them not to.

For instance the TextField and SpeedDial components automatically choose the dark property from the theme. I've tried to just remove the dark property, but than the TextField is black and the text inside the TextField is unreadable.

My theme file is configured as following:

import {createMuiTheme} from "@material-ui/core";
import {green, indigo, red} from "@material-ui/core/colors";

const theme = createMuiTheme({
  palette: {
    primary: {
      main: indigo.A200,
      dark: green.A100
    },
    white: {
      text: '#fff',
    },
    secondary: {
      main: red.A100,
      dark: green.A100,
    }
  }
});

export default theme;

I expect the TextField and SpeedDial to choose the primary color but the actual outcome is that they choose the dark property, probably because it would otherwise interfere with people not being able to see the component properly, but I want to custom choose the colors. I haven't been able to find an explanation on how to change the color for the underline and the float in the TextField component.

https://codesandbox.io/s/material-demo-o52c8

Ezrab_
  • 825
  • 5
  • 19
  • 44
  • See my answer [here](https://stackoverflow.com/questions/56023814/how-do-i-custom-style-the-underline-of-material-ui-without-using-theme/56026253#56026253) for how to change the underline color in TextField. – Ryan Cogswell Sep 03 '19 at 20:43
  • @RyanCogswell Ok but how about the floating text? – Ezrab_ Sep 03 '19 at 20:45
  • Can you setup a code sandbox where your problem is clearer? – JCQuintas Sep 03 '19 at 20:55
  • See my answer [here](https://stackoverflow.com/questions/54525334/how-can-i-change-the-label-size-of-a-material-ui-textfield/54525703#54525703) for an example of customizing the label. Another related answer on styling labels is [here](https://stackoverflow.com/questions/56639689/change-inputlabel-color-of-a-select-component-when-clicked-focused/56639982#56639982). – Ryan Cogswell Sep 03 '19 at 20:57
  • @RyanCogswell I think this is old because, FormLabelClasses doesn't exist. – Ezrab_ Sep 03 '19 at 21:01
  • @JCQuintas I would, but I really don't know how to set up babel. And so es6 doesn't work. – Ezrab_ Sep 03 '19 at 21:02
  • You can probably start from here: https://codesandbox.io/s/pf22z – JCQuintas Sep 03 '19 at 21:05
  • @Ezrab_ I've updated my answer to work with v4. – Ryan Cogswell Sep 03 '19 at 21:07
  • @JCQuintas thanks: https://codesandbox.io/s/material-demo-o52c8 – Ezrab_ Sep 03 '19 at 21:09
  • @RyanCogswell So your example with the ```classes: { root: classes.labelRoot, focused: classes.labelFocused },``` works, but I still can't get the underline to get a color in a TextField. – Ezrab_ Sep 03 '19 at 21:23
  • 1
    [Here](https://codesandbox.io/s/material-demo-d79l4) is a modified version of your sandbox. – Ryan Cogswell Sep 03 '19 at 21:25
  • @RyanCogswell Awesome, thanks! So would it also be possible to actually change the text color when people write stuff inside the TextField? – Ezrab_ Sep 03 '19 at 21:27
  • @RyanCogswell Never mind just added className to InputProps. – Ezrab_ Sep 03 '19 at 21:36
  • @RyanCogswell Do you know how to add ::selection in the textfield, so that if you highlight your input you'll see the selection in lets say red? I tried just adding a classname to the textfield component and add ```selection: { "&::selection": { color: 'red', } }``` – Ezrab_ Sep 03 '19 at 21:59

1 Answers1

5

Below is an example with many obnoxious colors on the different aspects of the TextField.

import React from "react";
import ReactDOM from "react-dom";

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

const useStyles = makeStyles({
  root: {
    color: "white",
    backgroundColor: "fuchsia",
    "&.Mui-focused": {
      color: "orange",
      backgroundColor: "pink"
    },
    "&:before": {
      borderBottomColor: "blue"
    },
    "&:hover:not(.Mui-focused):before": {
      borderBottomColor: "green"
    },
    "&:after": {
      // focused
      borderBottomColor: "purple"
    }
  },
  input: {
    "&::selection": {
      backgroundColor: "lightgreen",
      color: "black"
    }
  }
});
const useLabelStyles = makeStyles({
  root: {
    color: "brown",
    "&.Mui-focused": {
      color: "aqua"
    }
  }
});
function App() {
  const classes = useStyles();
  const labelClasses = useLabelStyles();
  return (
    <div className="App">
      <TextField
        InputProps={{ classes: classes }}
        InputLabelProps={{ classes: labelClasses }}
        label="label"
        defaultValue="text"
      />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit TextField colors

Here's the same look, but controlled via the theme:

import React from "react";
import ReactDOM from "react-dom";

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

const theme = createMuiTheme({
  overrides: {
    MuiInput: {
      root: {
        color: "white",
        backgroundColor: "fuchsia",
        "&.Mui-focused": {
          color: "orange",
          backgroundColor: "pink"
        },
        "&:before": {
          borderBottomColor: "blue"
        },
        "&:hover:not(.Mui-focused):before": {
          borderBottomColor: "green"
        },
        "&:after": {
          // focused
          borderBottomColor: "purple"
        }
      },
      input: {
        "&::selection": {
          backgroundColor: "lightgreen",
          color: "black"
        }
      }
    },
    MuiInputLabel: {
      root: {
        color: "brown",
        "&.Mui-focused": {
          color: "aqua"
        }
      }
    }
  }
});

function App() {
  return (
    <ThemeProvider theme={theme}>
      <div className="App">
        <TextField label="label" defaultValue="text" />
      </div>
    </ThemeProvider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit TextField colors via theme

Related answers:

Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198
  • Is it also achievable using createMuiTheme ? – Rasmus Puls Oct 20 '20 at 08:32
  • 1
    @RasmusPuls I've added an example using the theme. – Ryan Cogswell Oct 20 '20 at 14:07
  • One more question. If I want to control the color of the border on the outlined variant of the textField when it is focused, how would that be done? I can see that the fieldset gets the focused style from `.MuiOutlinedInput-root.MuiFocused .MuiOutlinedInput-notchedOutline` here the border-color is set to #3f51b5. I would assume that I could override those styles with `'&$focused$notchedOutline'` but it doesn't seem to have an effect. – Rasmus Puls Oct 21 '20 at 12:39
  • 1
    @RasmusPuls See https://stackoverflow.com/questions/58963242/change-border-color-on-material-ui-textfield/58963947#58963947 – Ryan Cogswell Oct 21 '20 at 12:58
  • 1
    @RasmusPuls Main thing you're missing is the space. The notched outline is a descendant of the element with the focused class -- not the same element, so you want `&$focused $notchedOutline` (assuming this is under `MuiOutlinedInput: { root: {`). – Ryan Cogswell Oct 21 '20 at 13:02
  • 1
    @RasmusPuls Theme example here: https://stackoverflow.com/questions/54789989/global-outlined-override/54794340#54794340 – Ryan Cogswell Oct 21 '20 at 13:02
  • Gotcha! Thanks again, I was trying to override it for `MuiTextField` and that didn't work. So it is the `MuiOutlinedInput`. Very nice examples ! – Rasmus Puls Oct 21 '20 at 13:22
  • @RasmusPuls It is possible to do it using `MuiTextField`, but you would have to target `MuiOutlinedInput-root` as a descendant (the root element for `TextField` is a div for the [FormControl](https://github.com/mui-org/material-ui/blob/v4.11.0/packages/material-ui/src/TextField/TextField.js#L156)), so it is more straightforward to do it via `MuiOutlinedInput`. – Ryan Cogswell Oct 21 '20 at 13:30