How to customize TextField error color in Material-UI using conditional logic in React

Currently, I am incorporating the React Material-UI library into my project and faced with a challenge of conditionally changing the error color of a TextField.

My goal is to alter the color of the helper text, border, text, and required marker to yellow in case of a specific type of error. Here is a visual representation of what I aim to achieve:

https://i.sstatic.net/RlMiG.png

For other types of errors, I would like to maintain the default red color. Even though I attempted to follow the method used in this codesandbox, I found it challenging to identify all the components that needed modification. Consequently, I had to resort to using the "important" keyword extensively to notice any changes.

Fortunately, I did succeed in selectively altering the color of the helper text as shown below:

                        <TextField
                            label="Name"
                            className={formClasses.textField}
                            margin="normal"
                            variant="outlined"
                            required
                            error={!!errors}
                            helperText={errors && "Incorrect entry."}
                            FormHelperTextProps={{classes: {root: getColorType(AnErrorType)}}}
                        />

The function getColorType is designed to return a CSS object specifying the desired color based on the given error type. For instance, the following snippet demonstrates how it determines the color for hard required hint text:

hardRequiredHintText: {
    color: `${theme.palette.warning.light} !important`
},

In conclusion, I wonder if there exists a simpler approach to override the MUI error color consistently across all relevant components?

Answer №1

To indicate different types of validation with distinct colors, we have the ability to send parameters to makeStyles

import { makeStyles } from "@material-ui/core/styles";
const useStyles = params =>
  makeStyles(theme => ({
    root: {
    }
  }));
const Component = () => {
  const classes = useStyles(someParams)();

https://i.sstatic.net/ciD7k.png


Complete code:

import React from "react";
import "./styles.css";
import { TextField } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
const useStyles = value =>
  makeStyles(theme => ({
    root: {
      "& .Mui-error": {
        color: acquireValidationColor(value)
      },
      "& .MuiFormHelperText-root": {
        color: acquireValidationColor(value)
      }
    }
  }));

const acquireValidationColor = message => {
  switch (message) {
    case "Incorrect entry":
      return "green";
    case "Please input":
      return "orange";
    default:
      return "black";
  }
};

const ValidationTextField = ({ helperText }) => {
  const classes = useStyles(helperText)();
  return (
    <TextField
      label="Name"
      margin="normal"
      variant="outlined"
      required
      error={helperText !== ""}
      helperText={helperText}
      className={classes.root}
    />
  );
};

export default function App() {
  const data = ["Incorrect entry", "Please input", ""];
  return (
    <div className="App">
      {data.map((x, idx) => (
        <ValidationTextField helperText={x} key={idx} />
      ))}
    </div>
  );
}

Answer №2

https://i.sstatic.net/wcGJc.pngFor Class Based Components

import React from "react";
import { TextField } from "@material-ui/core";
import { withStyles, createStyles } from "@material-ui/core/styles";

const commonStyles = (theme) =>
  createStyles({
    root: {},

    warningStyles: {
      "& .MuiFormLabel-root.Mui-error": {
        color: "orange !important"
      },
      "& .MuiInput-underline.Mui-error:after": {
        borderBottomColor: "orange !important"
      },
      "& .MuiFormHelperText-root.Mui-error": {
        color: "orange !important"
      }
    }
  });

class DemoComponent extends React.Component {
  render() {
    const { classes } = this.props;
    const _text1HasWarning = false;
    const _text2HasWarning = true;
    const _text3HasWarning = false;

    return (
      <>
        <TextField
          error={false}
          className={_text1HasWarning ? classes.warningStyles : null}
          value="Valid Value"
          variant="standard"
          label="Valid label"
          helperText="Valid helper text"
        />
        <br />
        <br />
        <br />
        <TextField
          error={true}
          className={_text2HasWarning ? classes.warningStyles : null}
          value="warning value"
          variant="standard"
          label="warning label"
          helperText="warning helper text"
        />
        <br />
        <br />
        <br />
        <TextField
          error={true}
          className={_text3HasWarning ? classes.warningStyles : null}
          value="error value"
          variant="standard"
          helperText="error helper text"
          label="error label"
        />
      </>
    );
  }
}
export default withStyles(commonStyles)(DemoComponent);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Output

Answer №3

To achieve this, you can customize your Material-UI theme's default styles by overriding them and then encapsulating your text field or component within myTheme

import { createMuiTheme } from 'material-ui/styles';
 const myTheme = createMuiTheme({
 overrides:{
    MuiInput: {
        underline: {
                '&:after': {
                  backgroundColor: 'any_color_value_in_hex',
                }
             },
          },
       }
   });
   export default myTheme;

Afterwards, import it into your component and use:

import {MuiThemeProvider} from 'material-ui/styles';
import myTheme from './components/myTheme'

<MuiThemeProvider theme = {myTheme}>
  <TextField />
</MuiThemeProvider>

Hopefully this explanation is helpful to you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Disorganized eCommerce Fee Box tabs causing confusion

I'm struggling to understand why this feature isn't working correctly on my website. It's supposed to generate a box with text and fee information, utilizing custom product fields for the fees. However, the tabs seem to be missing and the ta ...

How to Keep PHP Include Visible within the div using Bootstrap 4

I utilized PHP include to add the information inside the modals for the albums, but it is not hidden as specified in the div class where it is included. You can check out the music page on . However, here is the code snippet for the music page where I in ...

adjust bootstrap column width to fill the container

https://i.stack.imgur.com/tCuL6.png I am hoping that this image will provide a visual aid for what I am trying to convey. My goal is to have the arrow and the boxes aligned in a row without any empty space on the right side. As you can see, the leftmost b ...

How can you transform a nested array into a flat JavaScript map?

If we consider a JavaScript Map structured like this: [ { id: 1, name: "Foo", contents: [1,2,3], morecontents: ["a","b"], }, { id: 2, name: "Bar", c ...

modify a column in a database table when a different field is chosen

I am working on a basic table with 4 columns, two of which are dropdown menus with the classes "ddm1" and "ddm2". Here is what I am trying to achieve: Users should not be able to select from "ddm2" until they have selected an option from "ddm1". When ...

Shared-component experiencing issues with Material-UI theme integration

I'm working on a custom reusable component library using material-ui, and I have imported it into my main application like this: import { theme, CustomComponent } from '@company/shared-components'; import { ThemeProvider } from '@mui/ma ...

What is the best way to conceal text while retaining icons on a compact screen?

How can I hide the text links for Home, Reservations, My Reservations, About, and Settings on smaller screens while still keeping the icons visible? Currently, I am using the following resources: http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.1 ...

What is the best way to overlay several hidden links on a single image using HTML?

Currently working on a project using Flask and I am interested in creating an interactive image where clicking on different sections will navigate to unique links. Is this achievable? Any guidance or resources on how to implement this feature would be mu ...

Sending data to server using Ajax and jQuery

Hey there, experiencing a little hiccup in the back-end of my system when I try to submit my form. It keeps showing me an error saying Unidentified index: file1 . Can't seem to pinpoint where the issue lies in my code. Even though I'm no beginner ...

Combining user input data using JavaScript and Vue.js

I am working on a form using Vue.js and I want to combine the data from the input fields upon submission. I have been struggling to achieve this and created a jsfiddle to showcase my attempt. In my form, I have three Vue components for each of the input f ...

The Role of Filling in a Process

I am looking to create a rectangle that fills up gradually every day, increasing by 1% each time. This is the basic concept. My main struggle is figuring out how to fill it up. I need the rectangle to increase by 1% of its width each day. So essentially, ...

What is the method for retrieving the XMLHttpRequest errors registered with addEventListener?

I am struggling to find a solution. https://i.stack.imgur.com/bRJho.gif ...

Is it better to have Angular and Laravel as separate applications or should Laravel serve the Angular app?

I have a new project in the works, aiming to create a large SAAS application. Although I come from a CakePHP background, I've decided to use Laravel and Angular for this venture. As I navigate through unfamiliar territory with these technologies, I a ...

Is there a way to simulate a minified module for testing purposes?

For my project, I developed a component intended to function as a module. The implementation involves the utilization of third-party code provided in the form of a config file (initOpinionLab.js) and a .min.js file (opinionlab.min.js). As part of the devel ...

Encountering the 'unsupported_grant_type' error while attempting to retrieve an access token from the Discord API

Having trouble implementing Discord login on my website. When trying to exchange the code for an access token from https://discord.com/api/oauth2/token, I keep getting the error { error: 'unsupported_grant_type' }. This is my code: const ...

Do you have any tips on incorporating a sinking hover effect to an image or link?

Custom Arrow Icon I Want to Add Animation To I have designed an arrow icon image that functions as a link. It is positioned on top of a background image. When the user hovers over the arrow, I would like to implement a "sink" effect similar to the example ...

The design breaks occur exclusively in the Android default browser

I am experiencing issues with the design of a nested div element when viewed in the default Android browser. Unfortunately, I don't have access to tools that would allow me to identify the cause of this problem. However, the design functions correctly ...

Sleek animation of the search bar seamlessly transitioning with the accompanying dropdown menu

My goal is to create a smooth animation for the search bar (MUI Autocomplete) specifically on smartphones (Screen < 600px). Check out this example (view it on your smartphone to see the animation): However, I am encountering a few issues with my imple ...

On the server side, the received Req.body appears as an empty object: { }

import { Injectable } from '@angular/core'; import { Http, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Headers } from '@angular/http'; import { Observable } from 'rxjs/Observable'; impo ...

Adjusting the color of an HTML slider button as it moves

In my setup, I have a straightforward slider that I plan to use for controlling the movement of a stepper motor based on the slider's position. I wanted to give the website where this will be hosted a professional look, so I've spent quite some t ...