Can MUI 5 replicate the Emotions 'css' function through analog?

From what I've learned, MUI 5 utilizes Emotion for its styling framework. Emotion offers a convenient helper function called css, which generates a string - a class name that can be used as a value for the className property or any other relevant property.

import { css, cx } from '@emotion/css'

render(
  <div
    className={css`
      padding: 32px;
      background-color: hotpink;
      font-size: 24px;
    `}
  >
    Text
  </div>
)

I've searched extensively but couldn't find an equivalent in MUI. While there is a css function in system and styled-engine, it doesn't function similarly as it returns SerializedStyles.

The scenario where I aim to utilize it is as follows:

I have a component that allows you to pass class names (as strings) for different parts of that component, enabling flexibility in changing the component's styles. It seems like this css function (as demonstrated in the Emotion documentation) could assist with this.

For example:

const headerStyle = css`
  color: blue;
  border-bottom: 1px solid red;
`;

<Component
  headerClassName={headerStyle}
  footerClassName={css`
    color: gray;
    font-size: 2rem;
  `}
/>

Although I could potentially resolve it using makeStyles(), the syntax presented in the screenshot above appeals more to me than the "legacy" solution.

Answer №1

To incorporate styles into your Component, you can create a wrapper and pass the style down from the parent component as shown below:

<Box sx={{
  '& .myHeader': {
    // define header styles here
  },
  '& .myFooter': {
    // define footer styles here
  },
}}>
  <Component
    headerClassName='myHeader'
    footerClassName='myFooter'
  />
</Box>

Another option is to use styled:

import { styled } from "@mui/material/styles";

const headerClass = "header";
const footerClass = "footer";

const Container = styled("div")`
  & .${headerClass} {
    background-color: red;
  }
  & .${footerClass} {
    background-color: blue;
  }
`;

function Component({ headerClassName, footerClassName }) {
  return (
    <div>
      <div className={headerClassName}>h</div>
      <div className={footerClassName}>f</div>
    </div>
  );
}
<Container>
  <Component headerClassName={headerClass} footerClassName={footerClass} />
</Container>

https://codesandbox.io/s/69262127-is-there-an-analog-of-emotions-css-function-in-mui-5-k78uz?file=/demo.tsx

Answer №2

import { ClassNames } from '@emotion/react';

export const CustomComponent = ({ customClassName, styles, ...otherProps }) => (
  <ClassNames>
    {({ css, cx }) => (
      <div className={cx(customClassName, css(styles))} {...otherProps} /> 
    )}
  </ClassNames>
);

Example of how to use:

<CustomComponent styles={{ color: "green" }} customClassName="someCustomClass">text</CustomComponent>

You can also apply css() function to customClassName:

<div className={cx(css(customClassName), css(styles))} {...otherProps} /> 

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

Is there a better method to determine the width when utilizing the jQuery UI resizable feature for improved efficiency?

I'm currently working on a website that features a resizable sidebar. I want the icons and text within the sidebar to shrink proportionally when the user resizes it. Right now, I have implemented an if statement to check if the sidebar's width fa ...

Customizing the direction of the Stepper component in React.js using Material UI

I'm facing an unusual challenge where I'm attempting to create a stepper component for my application. Everything is working smoothly so far, but I want the stepper to progress from right to left. Here's what I've tried: Installed i18n ...

Slate Map by Google Navigation

I have a situation here that is similar to the grey maps, except all the buttons are visible. Everything appears normal except for the Map tiles, which are all grey! It's strange because it loads nicely at zoom level 8 and then zooms in to the maximum ...

Display or conceal div elements using JavaScript

Is there a way to hide certain divs when clicking on a specific div box? Clicking on the box will trigger the hiding of some application divs. See the first image below: When the boxes are hidden, the other divs will readjust in place of the current divs ...

"The Material-UI ListItem component acts as a link, updating the URL but failing to render the expected

Seeking help for the first time on this platform because I am completely perplexed. I'm working on coding a navbar for my school project website using Material-UI's List component within the Appbar component. However, I have encountered two issu ...

"Complete with Style: Expand Your Horizons with Material-UI

The Autocomplete feature in Material UI is not expanding to the full width of the TextField element. Any suggestions on how to fix this issue? ...

Intriguing flashing dark streak, reminiscent of a boundary within NextJS

I have recently encountered an unexpected issue with my full-width video header that worked perfectly on multiple pages before. Strangely, a thin black line has appeared around the bottom and right side of the div (.header) containing the video, even thoug ...

Tabs within the AutoComplete popup in Material-UI

Would it be feasible to showcase the corresponding data in the AutoComplete popover using Tabs? There could be potentially up to three categories of data that match the input value, and my preference would be to present them as tabs. Is there a way to in ...

Safari and mobile browsers do not support animation functionality

My animation works flawlessly in Chrome, but it's not functioning properly on Safari. Quite odd, right? Here is the code snippet: <header> <div class="ripple-1"></div> <div class="ripple-2"></div> ...

Checking if children have certain text using jQuery

My task involves filtering an HTML table. In order to accomplish this, I have created an 'each' callback for all 'tr' elements and check if any of their children contain a specific pattern. $("#filter").keypress(function() { var fi ...

jQuery's capability to select multiple elements simultaneously appears to be malfunctioning

I am dynamically creating div elements with unique ids and adding span elements with specific CSS properties. $(".main").append("<div class=largeBox id=" + counter + "</div>"); $(".largeBox").append("<span class=mainTitle></span>"); ...

Is there a method to prevent OnNodeSelect from triggering expand or collapse actions in Material UI TreeView?

Can someone help me understand the distinction between OnNodeSelect and OnNodeToggle in material ui treeview? They both appear to have a similar function of expanding/collapsing the treeview. Is there a way to differentiate between the two? ...

Embed a video within an image while ensuring it remains responsive on all devices

I have a picture that resembles something like this one My goal is to embed a video into it while maintaining its aspect ratio when the screen size is reduced. The responsive design should only affect the width since the image will be displayed in portrai ...

Unfortunately, the header and footer are not lining up correctly with the main body on our mobile site

I've been tasked with creating a fully responsive website, but I'm encountering difficulties with the mobile design. Specifically, when I switch to mobile dimensions like an iPhone 12, the header and footer don't line up properly with the ma ...

Handling type errors with React Typescript MuiAccordion OnChange event handler

I'm a beginner in typescript and seeking advice on defining the type for an event handler. I have a component that utilizes material ui Accordion and triggers the handler from a container. Therefore, I need to specify the type of handleChange in my co ...

What is the best way to transfer attribute values from multiple elements and paste them each into a separate element?

I have multiple elements with the tag <a class="banner2">. Each of these elements has a different URL for the background image and href value. <a href="#" target="_blank" class="banner2" style="background-image:url('<?php echo get_templat ...

Customizing the Material UI v5 theme with Typescript is impossible

I'm attempting to customize the color scheme of my theme, but I am encountering issues with accessing the colors from the palette using theme.palette. Here is a snippet of my theme section: import { createTheme } from "@mui/material/styles&qu ...

How can I use map functions to change the border color of specific items when clicked?

I have an array filled with various data. Here is how my Array looks like, const faqData = [ { q: "How Can We Help You?", a: "Find answers to our most frequently asked questions below. If you can't find what you need, pl ...

Tips for defining a relative path in the base URL with AngularJS

Encountering an issue with AngularJS routes related to file paths. The folder structure is as follows: js -> Angular -> css -> Bootstrap -> index.html Routes work fine when hosted on a server like IIS. However, copying and pasting the direct ...

Setting the height of a child div: A step-by-step guide

Within a nested div with a height of 48px and positioned relatively, there is another child div also with a height of 48px. The goal is to set the maximum height of the child div to 80% and the minimum height to 40%. However, even after applying these sett ...