Material UI's Stepper StepLabel Icon issue with undefined - javascript

just having issues with trying to implememnt a custom Step Label Icon within the nodes of the Stepper Component provided by Material UI. I am trying to implement an icon within each circle, as seen here from Material UI's demo
however, am coming across an error
Please see my code below. Thanks!
import React from 'react';
import { Typography } from '#material-ui/core';
import { withStyles, styles } from '#material-ui/core/styles';
const styles = theme => ({
checklistHeader: {
fontWeight: 'bold',
marginTop: '80px',
color: 'white'
},
connectorIcon: {
color: theme.palette.text.secondary
},
active: {
backgroundColor: 'green'
}
});
const steps = ['Select campaign settings', 'Select campaign settings', 'Select campaign settings'];
const ColorlibStepIconRoot = styled('div')(({ theme, ownerState }) => ({
backgroundColor: theme.palette.mode === 'dark' ? theme.palette.grey[700] : '#ccc',
zIndex: 1,
color: '#fff',
width: 50,
height: 50,
display: 'flex',
borderRadius: '50%',
justifyContent: 'center',
alignItems: 'center',
...(ownerState.active && {
backgroundImage:
'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)',
boxShadow: '0 4px 10px 0 rgba(0,0,0,.25)',
}),
...(ownerState.completed && {
backgroundImage:
'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)',
}),
}));
const ColorlibStepIcon = ({
icon, active, completed, className
}) => {
const icons = {
1: <Icon style={{ color: 'red' }}>create_outline</Icon>,
2: <Icon style={{ color: 'red' }}>star</Icon>,
3: <Icon style={{ color: 'red' }}>people</Icon>,
};
return (
<ColorlibStepIconRoot ownerState={{ completed, active }} className={className}>
{icons[String(icon)]}
</ColorlibStepIconRoot>
);
};
const Stepper = ({ classes }) => {
return (
<React.Fragment>
<Typography variant="h6" align="center" gutterBottom className={classes.checklistHeader}>Please complete the following criterion</Typography>
<Stepper alternativeLabel activeStep={2} style={{ background: 'none' }}>
{steps.map(label => (
<Step key={label}>
<StepLabel StepIconComponent={ColorlibStepIcon}>{label}</StepLabel>
</Step>
))}
</Stepper>
</React.Fragment>
);
};
Stepper.defaultProps = {
};
Stepper.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles, { withTheme: true })(Stepper);
It seems like the styled component is undefined. Is there any way that I can bypass this

The styled() function is only available in v5. You either need to upgrade to MUI v5 using this installation guide or use the older API in v4, (The equivalent is withStyles):
V5
import { styled } from '#mui/material/styles';
const StyledComponent = styled(Component)({
// your styles
});
V4
import { withStyles, styles } from '#material-ui/core/styles';
const StyledComponent = withStyles({
// your styles
})(Component);
You can see the v4 docs here and the v5 docs here.

Related

Cannot change selected style of Mui tab

I am trying to create a custom Tab using Mui's Tab.
The style I want is:
The indicator applied by default is made transparent.
Designate the default background color and font color of the tab.
When a tab is selected, only the background color and font color of the selected tab are changed.
Problem
As follows, 1 and 2 were applied, but the color of the selected tab could not be changed. I am changing the css directly using Mui's styled function, but I don't know where is wrong.
const StyledMuiTab = styled(MuiTab)({
...
'&.Mui-selected': {
backgroundColor: 'red',
color: 'red',
},
});
Also onChange doesn't work.
Source
Tab
import React, { ReactElement, useState } from 'react';
import { Tabs as MuiTabs, Tab as MuiTab, styled } from '#mui/material';
interface Props {
color: string;
children: ReactElement | ReactElement[];
}
const StyledMuiTabs = styled(MuiTabs)<Props>(({ color }) => ({
borderBottom: `1px solid ${color}`,
overflow: 'hidden',
display: 'flex',
'& .MuiTabs-indicator': {
backgroundColor: 'transparent',
},
'& .MuiTab-root.Mui-selected': { // not working
backgroundColor: 'red',
color: 'red',
},
}));
const BasicTabs = ({ children, color }: Props) => {
const [tabIndex, setTabIndex] = useState<number>(0);
const handleChange = (_event: React.SyntheticEvent, newValue: number) => {
console.log(newValue); //not working
setTabIndex(newValue);
};
return (
<StyledMuiTabs
value={tabIndex}
color={color}
variant="scrollable"
scrollButtons={false}
onChange={handleChange}
>
{children}
</StyledMuiTabs>
);
};
interface TabProps {
text: string;
}
const StyledMuiTab = styled(MuiTab)({
textTransform: 'none',
fontFamily: 'Noto Sans KR',
fontStyle: 'normal',
fontWeight: '500',
fontSize: '14px',
lineHeight: '20px',
textAlign: 'center',
background: '#F5F6FA',
border: '1px solid #D4DAE4',
borderRadius: '6px 6px 0px 0px',
color: '#9CA3AF',
'&.Mui-selected': { // not working
backgroundColor: 'red',
color: 'red',
},
});
const Tab = ({ text }: TabProps) => <StyledMuiTab disableRipple label={text} />;
const Tabs = Object.assign(BasicTabs, {
Tab,
});
export default Tabs;
caller
<Tabs color="#0D58EE">
<Tabs.Tab text="one" />
<Tabs.Tab text="two" />
</Tabs>

Target multiple classes at once Material UI

I am currently using material ui and I would like to change the color of my icon class when the active class is triggered by react-router-dom's NavLink
my code is as follows:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
import Typography from "#material-ui/core/Typography";
import PeopleIcon from "#material-ui/icons/People";
import AssignmentOutlinedIcon from "#material-ui/icons/AssignmentOutlined";
import TransferWithinAStationOutlinedIcon from "#material-ui/icons/TransferWithinAStationOutlined";
import ScheduleIcon from "#material-ui/icons/Schedule";
import { NavLink } from "react-router-dom";
import { BrowserRouter as Router } from "react-router-dom";
const drawerWidth = 220;
const useStyles = makeStyles((theme) => ({
paper: {
width: drawerWidth,
borderBottomLeftRadius: 10,
borderTopLeftRadius: 10,
height: "calc(100% - 10px)",
border: "solid 1px #CCCCCC",
paddingTop: 5
},
icon: {
width: 20,
height: 20,
color: "#999999"
},
listItem: {
textDecoration: "none",
color: "inherit",
padding: 5,
cursor: "pointer",
"&:hover": {
backgroundColor: "#EEEEEE"
}
},
active: {
backgroundColor: "#999999",
color: "white",
"&:hover": {
backgroundColor: "#999999"
}
}
}));
const App = () => {
const classes = useStyles();
const routes = [
{
path: "/admin/users",
name: "Users",
icon: <PeopleIcon className={classes.icon} />
},
{
path: "/admin/assignments",
name: "Assignments",
icon: <AssignmentOutlinedIcon className={classes.icon} />
},
{
path: "/admin/transfers",
name: "Transfers",
icon: <TransferWithinAStationOutlinedIcon className={classes.icon} />
},
{
path: "/admin/liveClock",
name: "Live Clock",
icon: <ScheduleIcon className={classes.icon} />
}
];
return (
<>
<Paper variant="outlined" square className={classes.paper}>
{routes.map((r, i) => {
return (
<Router>
<NavLink
activeClassName={classes.active}
to={r.path}
key={i}
style={{
display: "flex",
alignItems: "center",
paddingLeft: 10
}}
className={classes.listItem}
>
{r.icon}
<Typography
variant="body1"
style={{ marginLeft: 10, fontSize: "15px" }}
>
{r.name}
</Typography>
</NavLink>
</Router>
);
})}
</Paper>
</>
);
};
export default App;
I would like the icon color to be white when the active class is triggered but I cannot seem to target the icon class within the active class.
Please Note: I understand my react router logic is set up incorrectly this is just to allow the active class to be triggered within my code sandbox. Thanks!
attached is a code sandbox for debuggging:
https://codesandbox.io/s/vigilant-curran-iwdtq?file=/src/App.js:0-2628
Try to reference your icon style within your active style:
active: { ...
'& $icon':{ color: '#EEEEEE'}
See it live: https://codesandbox.io/s/so-answer-cute1?file=/src/App.js
I put the activeClassname behavior on hover to show it working, as you did before.

React.js, Material Ui Stepper direction

I have a weird situation right here where I try to build a stepper component within my app.
everything goes well so far but I try to make this stepper to go from Right to left.
things I have tried:
I tried to instal i18next (translation library) and it didn't work out.
I tried to go from 3 down to 2, and it also is not a satisfying result
here is the result:
and here is my code:
import {
makeStyles,
Theme,
createStyles,
withStyles,
} from '#material-ui/core/styles';
import clsx from 'clsx';
import Stepper from '#material-ui/core/Stepper';
import Step from '#material-ui/core/Step';
import StepLabel from '#material-ui/core/StepLabel';
import SettingsIcon from '#material-ui/icons/Settings';
import GroupAddIcon from '#material-ui/icons/GroupAdd';
import VideoLabelIcon from '#material-ui/icons/VideoLabel';
import StepConnector from '#material-ui/core/StepConnector';
import Button from '#material-ui/core/Button';
import Typography from '#material-ui/core/Typography';
import { StepIconProps } from '#material-ui/core/StepIcon';
const ColorlibConnector = withStyles({
alternativeLabel: {
top: 22,
},
active: {
'& $line': {
backgroundImage:
'linear-gradient( 95deg,rgb(242,113,33) 0%,rgb(233,64,87) 50%,rgb(138,35,135) 100%)',
},
},
completed: {
'& $line': {
backgroundImage:
'linear-gradient( 95deg,rgb(242,113,33) 0%,rgb(233,64,87) 50%,rgb(138,35,135) 100%)',
},
},
line: {
height: 3,
border: 0,
backgroundColor: '#eaeaf0',
borderRadius: 1,
},
})(StepConnector);
const useColorlibStepIconStyles = makeStyles({
root: {
backgroundColor: '#ccc',
zIndex: 1,
color: '#fff',
width: 50,
height: 50,
display: 'flex',
borderRadius: '50%',
justifyContent: 'center',
alignItems: 'center',
},
active: {
backgroundImage:
'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)',
boxShadow: '0 4px 10px 0 rgba(0,0,0,.25)',
},
completed: {
backgroundImage:
'linear-gradient( 136deg, rgb(242,113,33) 0%, rgb(233,64,87) 50%, rgb(138,35,135) 100%)',
},
});
function ColorlibStepIcon(props: StepIconProps) {
const classes = useColorlibStepIconStyles();
const { active, completed } = props;
const icons: { [index: string]: React.ReactElement } = {
1: <SettingsIcon />,
2: <GroupAddIcon />,
3: <VideoLabelIcon />,
};
return (
<div
className={clsx(classes.root, {
[classes.active]: active,
[classes.completed]: completed,
})}
>
{icons[String(props.icon)]}
</div>
);
}
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
width: '100%',
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
},
button: {
marginRight: theme.spacing(1),
},
instructions: {
marginTop: theme.spacing(1),
marginBottom: theme.spacing(1),
},
stepperContainer: {
width: '100%',
},
contentContainer: {
width: '50%',
display: 'flex',
justifyContent: 'center',
},
})
);
function getSteps() {
return ['Select campaign settings', 'Create an ad group', 'Create an ad'];
}
function getStepContent(step: number) {
switch (step) {
case 0:
return 'Select campaign settings...';
case 1:
return 'What is an ad group anyways?';
case 2:
return 'This is the bit I really care about!';
default:
return 'Unknown step';
}
}
const SignUp: React.FC = () => {
const classes = useStyles();
const [activeStep, setActiveStep] = React.useState(0);
const steps = getSteps();
const handleNext = () => {
setActiveStep((prevActiveStep) => prevActiveStep + 1);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const handleReset = () => {
setActiveStep(0);
};
return (
<div className={classes.root}>
<div className={classes.stepperContainer}>
<Stepper
dir="rtl"
alternativeLabel
activeStep={activeStep}
connector={<ColorlibConnector />}
>
{steps.map((label) => (
<Step key={label}>
<StepLabel StepIconComponent={ColorlibStepIcon}>
{label}
</StepLabel>
</Step>
))}
</Stepper>
</div>
<div className={classes.contentContainer}>
<div>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>
All steps completed - you&apos;re finished
</Typography>
<Button onClick={handleReset} className={classes.button}>
Reset
</Button>
</div>
) : (
<div>
<Typography className={classes.instructions}>
{getStepContent(activeStep)}
</Typography>
<div>
<Button
disabled={activeStep === 0}
onClick={handleBack}
className={classes.button}
>
Back
</Button>
<Button
variant="contained"
color="primary"
onClick={handleNext}
className={classes.button}
>
{activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
)}
</div>
</div>
</div>
);
};
export default SignUp;
Hi I was fiddling around with the material UI sandbox,
here's the sandbox with working left to right
things I've change, were:
line 43 - initate step to 2
line 62 - handleNext, prevActiveStep - 1 (from +1)
line 67 - handleBack, prevActiveStep + 1 (from -1)
line 86 - setActiveStep(2) (from setActiveStep(0))
the Stepper component:
<Stepper activeStep={activeStep}>
{steps.map((label, index) => {
const stepProps: { completed?: boolean } = {
completed: activeStep < index // <<< this setting
};
const labelProps: { optional?: React.ReactNode } = {};
if (isStepOptional(index)) {
labelProps.optional = (
<Typography variant="caption">Optional</Typography>
);
}
if (isStepSkipped(index)) {
stepProps.completed = false;
}
return (
<Step key={label} {...stepProps}>
<StepLabel {...labelProps}>{label}</StepLabel>
</Step>
);
})}
</Stepper>
hope that helps

color change for the loading bar component of material ui

I am trying to learn material ui.
I am trying to change the css of the loading bar.
I referred to the documentation and used colorPrimary classes
but its not changing.
can you tell me how to fix it so taht in future I will fix it myself
providing my code snippet below.
all my code is in ReceipeReviewCardList.js
https://codesandbox.io/s/2zonj08v5r
const styles = {
root: {
flexGrow: 1
},
colorPrimary: {
color: "green"
}
};
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<LinearProgress
className={classes.colorPrimary}
variant="determinate"
value={this.state.completed}
you can use example as was in the reply of the issue in material ui github project: https://github.com/mui-org/material-ui/issues/12858#issuecomment-421150158
import React, { Component } from 'react';
import { withStyles } from '#material-ui/core/styles';
import { LinearProgress } from '#material-ui/core';
class ColoredLinearProgress extends Component {
render() {
const { classes } = this.props;
return <LinearProgress {...this.props} classes={{colorPrimary: classes.colorPrimary, barColorPrimary: classes.barColorPrimary}}/>;
}
}
const styles = props => ({
colorPrimary: {
backgroundColor: '#00695C',
},
barColorPrimary: {
backgroundColor: '#B2DFDB',
}
});
export default withStyles(styles)(ColoredLinearProgress);
It works perfect.
You can override the background colors with makeStyles.
On makeStyles file:
export const useStyles = makeStyles(() => ({
root: {
"& .MuiLinearProgress-colorPrimary": {
backgroundColor: "red",
},
"& .MuiLinearProgress-barColorPrimary": {
backgroundColor: "green",
},
},
})
Import and use:
import { useStyles } from "./myFile.style";
...
const classes = useStyles();
...
<div className={classes.root}>
<LinearProgress />
</div>
It is because you set the CSS is not correctly,
const styles = {
root: {
flexGrow: 1
},
colorPrimary: {
background: 'green'
}
};
not:
const styles = {
root: {
flexGrow: 1
},
colorPrimary: {
color: "green",
}
};
Hope it help!
If you want to overwrite with sx:
sx={{
'& .MuiLinearProgress-bar1Determinate': {
backgroundColor: 'red',
}
}}
the color of the main bar is set as the BACKGROUNDCOLOR, NOT the COLOR
For Material UI v5 (#mui)
<LinearProgress sx={{
backgroundColor: 'white',
'& .MuiLinearProgress-bar': {
backgroundColor: 'green'
}
}}
variant="determinate"
value={10}/>
I did do it by this way, creating your own theme
import {createMuiTheme, MuiThemeProvider } from '#material-ui/core/styles';
const theme = createMuiTheme({
palette: {
secondary: {
main: '#42baf5'
}
}
})
<MuiThemeProvider theme={theme}>
<LinearProgress color="secondary"/>
</MuiThemeProvider>
An easy workaround i stumbled upon which doesn't seem too much of a hack:
<LinearProgress
className="VolumeBar"
variant="determinate"
value={volume}
/>
.VolumeBar > * { background-color:green; }
.VolumeBar{background-color:gray ;}
The first rule makes the progress appear green(completed part).
The second rule takes care of the uncompleted part .
const BorderLinearProgress = withStyles((theme: Theme) =>
createStyles({
root: {
width: '95%',
height: 10,
borderRadius: 5,
marginTop: 8,
marginBottom: 20
},
colorPrimary: {
backgroundColor: Liquidity.colors.main.pink,
},
bar: {
borderRadius: 5,
backgroundColor: Liquidity.colors.main.yellow,
},
}),
)(LinearProgress);
This worked for me (Material ui version 4):
progressbar: {
background: 'yellow',
'& .MuiLinearProgress-bar': {
backgroundColor: theme.palette.success.main,
},
},
And then
<LinearProgress
className={classes.progressbar}
variant="determinate"
value={30}
/>
That have worked for me !
First set a className to the LinearProgress component
<LinearProgress
className="custom-class"
variant="determinate"
value={MyValue}
/>
then style it from your attached css file as shown in the following :
.custom-class > * { background-color:green !important; }
.custom-class{background-color:gray !important;}
using the !important tag is premordial to override the original color.
style: progress: { color: 'red' },
Component:
<LinearProgress color="inherit" className={classes.progress} />

MUI Drawer set background color

How to simply set background color of MUI Drawer?
tried this, but doesn't work
<Drawer
style={listStyle3}
open={this.state.menuOpened}
docked={false}
onRequestChange={(menuOpened) => this.setState({menuOpened})}
/>
const listStyle3 = {
background: '#fafa00',
backgroundColor: 'red'
}
Edit: (May-21) - Material UI V4.11.1
This can be done differently in version 4.11.1 and functional components.
There's no need to use an HoC anymore. Here's how it's done:
You should use the makeStyles helper to create the hook with a definitions of the classes and use the hook to pull them out.
const useStyles = makeStyles({
list: {
width: 250
},
fullList: {
width: "auto"
},
paper: {
background: "blue"
}
});
const DrawerWrapper = () => {
const classes = useStyles();
return (
<Drawer
classes={{ paper: classes.paper }}
open={isOpen}
onClose={() => setIsOpen(false)}
>
<div
tabIndex={0}
role="button"
onClick={() => setIsOpen(true)}
classes={{ root: classes.root }}
>
{sideList}
</div>
</Drawer>
)
}
Here's a working sandbox
Edit: (Jan-19) - Material UI V3.8.3
As for the latest version asked, the way to configure the backgroundColor would be by overriding the classes.
Based on material-ui documentation here, and the css api for drawer here - This can be done by creating an object in the form of:
const styles = {
paper: {
background: "blue"
}
}
and passing it to the Drawer component:
<Drawer
classes={{ paper: classes.paper }}
open={this.state.left}
onClose={this.toggleDrawer("left", false)}
>
A working example can be seen in this codesandbox.
Don't forget to wrap your component with material-ui's withStyles HoC as mentioned here
Based on the props you used I have the reason to think that you're using a version which is lower than v1.3.1 (the last stable version) but for the next questions you'll ask, I recommend writing the version you're using.
For version lower than V1, you can change the containerStyle prop like this:
<Drawer open={true} containerStyle={{backgroundColor: 'black'}}/>
In MUI v5, you can use the sx prop to style MUI components:
<Drawer
PaperProps={{
sx: {
backgroundColor: "pink",
color: "red",
}
}}
Or use styleOverrides to define the custom styles in createTheme:
const theme = createTheme({
components: {
MuiDrawer: {
styleOverrides: {
paper: {
backgroundColor: "pink",
color: "red",
}
}
}
}
});
Material UI V4.3.2
As in this version you can change the backgroundColor by making use of makeStyles from '#material-ui/core/styles' as shown below:
import Drawer from '#material-ui/core/Drawer';
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles({
paper: {
background: 'black',
color: 'white'
}
});
const SideDrawer = props => {
const styles = useStyles();
return (
<Drawer
anchor="right"
open={props.drawerOpen}
onClose={() => props.toggleDrawer(false)}
classes={{ paper: styles.paper }}
>
Items
</Drawer>
);
};
export default SideDrawer;
Drawer doesn't accept style props. Use classes instead
See Drawer API
If anyone's looking for how to do this conditionally for dark/light mode, you can make 2 separate classes and use a conditional to use the right one in the component. Here's an example of how to modify #Yirenkyi's answer do achieve this:
import Drawer from '#material-ui/core/Drawer';
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles({
paperLight: {
background: 'white',
color: 'black'
},
paperDark: {
background: 'black',
color: 'white'
}
});
const SideDrawer = props => {
const userPrefersDarkMode = true; //here's your condition
const styles = useStyles();
return (
<Drawer
anchor="right"
open={props.drawerOpen}
onClose={() => props.toggleDrawer(false)}
classes={{ paper: userPrefersDarkMode ? styles.paperDark : styles.paperLight }}
>
Items
</Drawer>
);
};
export default SideDrawer;

Categories

Resources