How do I override compiled classes? - reactjs

I cam trying to apply override styles to a compiled class name. my compiled code is like...
<div class="MuiListItemText-root-262" >
I want to be able to target that specific item like this
const styles = () => { MultiListItemText-root-262: { color: red; } }
in vanilla CSS I could just do .MultiListItemText-root-262: { color: red; }
How can I do the equivalent in JSS?

You cannot do it this way.
The classname "MuiListItemText-root-262" is dynamic, and the id "262" is not reliable and may change.
Please look at the official documentation of Material UI for using JSS overrides : https://material-ui.com/customization/overrides/
There are several techniques available depending on the level of variation your want to achieve.
For a typical "one time" override, see the first sample code which uses the withStyles HOC
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
// We can inject some CSS into the DOM.
const styles = {
button: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
borderRadius: 3,
border: 0,
color: 'white',
height: 48,
padding: '0 30px',
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
},
};
function ClassNames(props) {
return (
<Button className={props.classes.button}>
{props.children ? props.children : 'class names'}
</Button>
);
}
ClassNames.propTypes = {
children: PropTypes.node,
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(ClassNames);

Related

"Type 'never' has no call signatures" using withStyles in a React Component

My problem is the error "This expression is not callable. Type 'never' has no call signatures."
Seen in the following code
import React from 'react'
import {Component} from "react";
import {Grid, withStyles} from "#mui/material";
const styles = (theme: any) => ({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
});
class AnswerButton extends Component<AnswerButtonProps>{
constructor(props: any){
super(props);
}
render(){
const { classes } = this.props;
return (
<Grid >
wew
</Grid>
)
}
}
interface AnswerButtonProps {
classes: any,
}
export default withStyles(styles)(AnswerButton);
^^^^^^^^^^^^^^^^^^ error here
Is using React.Component inadvisable these days? Every solution I find online suggests making AnswerButton a normal const variable and using useEffect instead to monitor changes.

MUI styled cannot pass component prop to Typography in typescript

Using MUI with typescript and want to use styled from MUI as well. When passing the component prop to the styled component I get an error from the typescript sandbox below, maybe anyone knows a workaround.
https://codesandbox.io/s/material-demo-forked-lxdrj?file=/demo.tsx
You have to manually add the 'component' prop.
From https://mui.com/material-ui/guides/typescript/#complications-with-the-component-prop
import React from "react";
import type { TypographyProps } from "#material-ui/core";
import { styled } from "#material-ui/core/styles";
import Typography from "#material-ui/core/Typography";
type MyT = React.ComponentType<TypographyProps<"span", { component: "span" }>>;
const MyTypography: MyT = styled(Typography)({
background: "linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)",
border: 0,
borderRadius: 3,
boxShadow: "0 3px 5px 2px rgba(255, 105, 135, .3)",
color: "white",
height: 48,
padding: "0 30px"
});
export default function StyledComponents() {
return (
<MyTypography component="span">Styled with styled-components API</MyTypography>
);
}
You can use generic type parameter in HOC created by styled:
import { styled } from '#mui/material/styles';
import Typography from '#mui/material/Typography';
type ExtraProps = {
component: React.ElementType;
};
const MyTypography = styled(Typography)<ExtraProps>({
// ...
});
Live Demo
Same idea as #GitGitBoom, but without having to define a type. You can use the solution described in the MUI Typescript Guide where you just cast your styled component to the typeof Typography
import React from "react";
import { styled } from "#material-ui/core/styles";
import Typography from "#material-ui/core/Typography";
const MyTypography = styled(Typography)({
background: "linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)",
border: 0,
borderRadius: 3,
boxShadow: "0 3px 5px 2px rgba(255, 105, 135, .3)",
color: "white",
height: 48,
padding: "0 30px"
}) as typeof Typography;
export default function StyledComponents() {
return (
<MyTypography component="span">
Styled with styled-components API
</MyTypography>
);
}

Hooks can only be called inside of the body of a function component

I created a react js project with Material UI
And then I was building and publishing the whole project with
build": "./node_modules/.bin/babel src --out-file BuildTest/index.js
When I installed this module in Client-side(Other Project) I got this problem:
Module :
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
const styles = {
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
};
function HigherOrderComponent(props) {
const { classes } = props;
return <Button className={classes.root}>Higher-order component</Button>;
}
HigherOrderComponent.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(HigherOrderComponent);
Client-Side:
import Mtest from "testmodule";
import React, { Component } from "react";
export default class App extends Component {
render() {
return (
<div>
<Mtest/>
</div>
)
}
}

Material-UI. Invalid hook call

I've been following some examples on how to setup Material-UI with React.
Whatever I try, I'm getting back the following error:
Error: Minified React error #321; visit
https://reactjs.org/docs/error-decoder.html?invariant=321 for the full
message or use the non-minified dev environment for full errors and
additional helpful warnings.
This seems to be Hook related, but I can't find any reason why this happens.
The component
Button
import React from 'react';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
const styles = {
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
};
function ButtonComp(props) {
const { classes } = props;
return <Button className={classes.root}>Higher-order component</Button>;
}
export default withStyles(styles)(ButtonComp);
Implemented like this
import * as React from 'react';
import ButtonComp from './ButtonComp';
const App = ({ children }) => {
return (
<React.Fragment>
<ButtonComp />
<main>
{children}
</main>
</React.Fragment>
);
};
export default (App);
I'm running on react#16.11.0 and #material-ui/core#4.5.1.
What am I missing here? I can't find the problem at all.

material ui styles inside react component

Here you can see example of using material ui styles outside of a react component.
import React from 'react';
import { makeStyles } from '#material-ui/styles';
import Button from '#material-ui/core/Button';
const useStyles = makeStyles({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
});
export default function Hook() {
const classes = useStyles();
return <Button className={classes.root}>Hook</Button>;
}
I want to do the same, but inside react component:
class Component extends React.Component {
render() {
const {height} = this.props
const useStyles = makeStyles({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: height,
padding: '0 30px',
},
});
const classes = useStyles();
return <Button className={classes.root}>Hook</Button>;
}}
Is it possible?
I see that here have to be correct version of react with hooks , but I've not found any example where peoples use it inside class makeStyles
makeStyles creates a React hook; because of this, you cannot inter-operate with class components.
Hooks are used to replace classes entirely since React is moving more in the direction of purely functional components for the sake of compiler optimizations and other low level things (though there are external benefits for devs as well such as being less verbose and taking better advantage of and being more intuitive with the functional nature of JS). In the case of makeStyles, you get additional benefits such as being able to use any variable including those from what would traditionally be props and state, and automatically your JSS re-calculates only based on observable params you have provided vs when any prop changes.
Instead, as #Richard Ansell pointed out, you should use withStyles if you are not comfortable outside classes. This is a High Order Component. Would suggest though that in newer code bases, you learn hooks and adapt to that as hooks can represent almost all functionality from both HOCs and components when you become better at them.
Below is the example given from the material-ui documentation (RTFM here):
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/styles';
import Button from '#material-ui/core/Button';
const styles = {
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
};
function HigherOrderComponent(props) {
const { classes } = props;
return <Button className={classes.root}>Higher-order component</Button>;
}
HigherOrderComponent.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(HigherOrderComponent);
From what I can gather, you can simply use the withStyles API that can wrap your component and inject your style directly into your exported component. See the following page that will explain this in more detail: withStyles
Example:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/styles';
import Button from '#material-ui/core/Button';
const styles = {
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
padding: '0 30px',
},
};
function HigherOrderComponent(props) {
const { classes, customHeight } = props;
return <Button className={classes.root} style={{minHeight: customHeight, maxHeight: customHeight}}>Higher-order
component</Button>;
}
HigherOrderComponent.propTypes = {
classes: PropTypes.object.isRequired,
customHeight: PropTypes.object.isRequired
};
export default withStyles(styles)(HigherOrderComponent);

Resources