How can I pass a variable to withStyles in Material UI?

Here is the code I am currently working with:

class StyledInput extends React.Component{


  styles = (color, theme) => ({
    underline: {
      borderBottom: `2px solid ${color}`,
      '&:after': {
        borderBottom: `2px solid ${color}`,
      }
    }
  })
  
  div = props => (
    <TextField
    placeholder="temp input"
    InputProps={{
      classes:{
        root: props.classes.underline
      },
      style:{
        height: '1.5rem',
        fontSize:'1rem',
        marginTop: '-1rem',
      }
    }}
    >
      <div>
        {props.children}
      </div>
    </TextField>
  )
  
  Styled = withStyles(this.styles('white'))(this.div)

  render(){
    return(
      <div>
        <this.Styled>{this.props.children}</this.Styled>
      </div>
    );
  }
}

export default StyledInput;

The current functionality successfully changes the color of the bottom bar in a material UI text field to white when clicked by the user.

However, my goal is to make it more dynamic, like this:

<this.Styled color={someDefinedColor}>{this.props.children}</this.Styled>

where Styled would be changed to:

Styled = (color) => withStyles(this.styles(color))(this.div)

I have attempted to implement this, but haven't been successful so far. Material-ui can be challenging when it comes to dynamically changing colors. Does anyone have any insight or suggestions on how to achieve this?

Thank you!

Answer №1

Check out this demo showcasing the usage of the new hook syntax:

index.js

import React from "react";
import ReactDOM from "react-dom";
import StyledComponent from "./StyledComponent";

const CustomComponent = ({ children, className }) => {
  return (
    <p className={className}>
      Instead of automatically using a div, here we pass in the component to use.
      <br />
      {children}
    </p>
  );
};

function App() {
  return (
    <div className="App">
      <StyledComponent color="green">
        Here's my content with green underline
      </StyledComponent>
      <StyledComponent
        component={CustomComponent}
        color="blue"
        hoverColor="orange"
      >
        Here's my content with blue underline that changes to orange on hover.
      </StyledComponent>
    </div>
  );
}

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

StyledComponent.js

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

const useStyles = makeStyles({
  root: {
    borderBottom: ({ color }) => `2px solid ${color}`,
    "&:hover": {
      borderBottom: ({ color, hoverColor }) => {
        const borderColor = hoverColor ? hoverColor : color;
        return `2px solid ${borderColor}`;
      }
    }
  }
});

const StyledComponent = ({
  component: ComponentProp = "div",
  children,
  color,
  hoverColor
}) => {
  const classes = useStyles({ color, hoverColor });
  return <ComponentProp className={classes.root}>{children}</ComponentProp>;
};

export default StyledComponent;

https://codesandbox.io/s/mq3n246008?fontsize=14

If needed, you can extract the useStyles method into its own file and use it as a custom hook to provide the generated classes (including variable support) to multiple components beyond just StyledComponent.

Answer №2

Discover a new way to utilize props or a combination of props and themes with makeStyles(), similar to styled-components

element.js

import { tableCellStyles } from './element.styled.js';

const DataGridRow = (props) => {
    const { noPaddingTopBottom } = tableCellStyles(props);
    return(
        <StyledTableRow>
            {data.map( (row,i) => (
                <StyledTableCell className={noPaddingTopBottom}>
                    {row.data}
                </StyledTableCell>
            )}
        </StyledTableRow>
    )
};

Assuming that the props object passed from DataGridRow Component to tableCellStyles contains { color: 'grey', thinRow: true }

element.styled.js

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

export const tableCellStyling = makeStyles(theme => ({
    noPaddingTopBottom: {
        borderBottom: ({ color }) => color ? `2px solid ${color}` : '2px solid red',
        paddingBottom: props => props.hasActions && 0,
        paddingTop: props => props.hasActions && 0,
        backgroundColor: theme.palette.common.white,
    },
}));

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

Using CSS to enhance typography in Material UI

When attempting to apply CSS to a Typography element, I am facing an issue where the styling does not seem to be taking effect. Interestingly, when I use the same CSS on a different div element, it works perfectly fine. Here is the code for my Typography e ...

Incorporating an if condition within the componentDidUpdate method in React resulted in an unforeseen infinite loop

I have a link tag that I am sending to the same component but with a different parameter. To achieve this, I am utilizing componentDidUpdate. If I had used an anchor tag, this step would not have been necessary. However, I encountered an issue where adding ...

Tailwind's unique approach to custom @font-faces allows for

Recently, I've been working on a project with Tailwind CSS. I encountered an issue when trying to implement a custom font using @font-face. Despite placing the font file in public/assets/font directory, it still doesn't seem to load properly. Her ...

When AutoSizer is applied, make sure to automatically scroll the FixedSizeList to the final element

I have successfully implemented AutoSizer for my list, but I am facing an issue where the list does not automatically scroll to the last element after loading. I attempted to use a ref to the FixedSizeList component, but unfortunately, it did not work as e ...

The parameter 'CallHistoryMethodAction<[string, unknown?]>' does not match the 'UserActionType' parameter

Using a development environment with React, TypeScript, and connected-react-router. My Intention: I aim to utilize the router action asynchronously within the user action. After successful login, I want the application to navigate to the main screen. Err ...

Styling CSS code to centrally align a background image in the footer of a

Within my MVC app, there is a footer displayed on every page that includes an image. I am looking to align the image in the center if possible. The current CSS code for the footer is as shown below: footer { position:absolute; bottom:-150px; /* Th ...

Is there a way to automatically change the full screen background on refresh?

Is there a way to have the background image of this website change to different pictures every time the page is refreshed? I'm curious about how this can be achieved. I noticed that Offliberty is able to do this. I tried looking at the source code b ...

Is there a method for configuring NextAuth to utilize the /src/app directory instead?

Is there a specific method to instruct NextAuth to redirect to this particular directory, but within the src/app directory? All of my routes are now located there due to the changes in Next.js 13. Below is an example of the code I am using: export const a ...

The Material UI month picker interface is not displaying correctly

When trying to implement the code snippet below, <MonthPicker/> I am encountering issues with the UI of the month picker both on the website and at times. https://i.stack.imgur.com/EKsYA.png It seems like the month picker is being utilized in a di ...

Optimal methods for sending Redux state to components

Currently, I am collaborating on a React + Redux project alongside other developers, and we are at an impasse regarding the best practice for passing state and actions throughout our components. My strategy involves creating a 'container' or &ap ...

Changes in the Redux state are not being displayed or updated in the component

I am currently working on implementing a shopping cart feature using Redux. Below is my cart reducer code snippet: export const cartReducer = ( state = { cartItems: JSON.parse(localStorage.getItem("cartItems") || "[]")}, action) => { ...

The Hamburger Menu Opens Smoothly But Refuses to Shut Down

Below is the HTML code for my website. I have managed to open the hamburger menu with the code, but I am facing an issue where it won't close. I have checked the HTML structuring using a validator and found no errors. Additionally, I have reviewed my ...

The element's width set to 100% is not functioning properly when used within a container

Struggling to create a full-width image header but the image always ends up being the width of the container, not 100%. Tried various solutions without success, and the suggested answer here did not solve the issue. Modifying the .container width in custom ...

Tips for receiving feedback when uploading multiple images

I've been facing challenges with receiving a response when uploading multiple images using the API. Despite getting a valid response when uploading a single image, I'm not getting the expected response for multiple uploads. Below is my code: fil ...

How do I make the YouTube Grid Gallery player show up in a pop-up window?

I have been experimenting with the following code: <head> <script type="text/javascript" src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js"></script> <script type="text/javascript"> function loadVideo(playerUrl, ...

Instructions for compiling node-sass within the present directory for specific files

In my project, the directory structure looks like this: - folder1 - styles1.scss - folder2 - styles2.scss I want to utilize node-sass through the command line to generate the following output: - folder1 - styles1.scss - styles1.css - folder2 ...

Attempting to emulate the grid showcase using flexbox styling

Creating this layout using CSS Grid was a breeze. However, I wonder if it can be achieved with Flexbox. What do you think? .Message { display: inline-grid; grid-template-areas: ". name""date text"; } .Date { align-items: ...

Incorporate the React modal component into your project

Having recently started with react, I decided to create a react modal component that displays an image along with a close button. const BoxModal = ({children, modalIsOpen, setModalIsOpen}) => { return ( <> <Modal isOpen={mod ...

The ng-style directive is not functioning properly

After selecting a category, I attempted to change the color using "ng-style" in my HTML code. However, it seems that the color change is not taking effect. This is the snippet from my HTML code: <div ng-repeat="item in ListExpense" ng-class-odd="&apos ...

Is dynamic rendering advisable over static rendering with fetch headers in Next.js v13?

I'm currently in a debate with myself over whether I misunderstood the latest 13 new concepts or if there is actually a bug. I'm uncertain and would appreciate it if someone more knowledgeable could shed some light on the situation. I have a sim ...