How to update material-ui button focus style? - reactjs

material-ui introduces a way of using classname for styling component. I have a button component shown as below. It uses createStyles and withStyles to inject the styles as classes into the component. But I don't know how to set the focus style of the Button.
import Button from '#material-ui/core/Button';
const styles = createStyles({
button: {
minHeight: '3rem',
lineHeight: '3rem',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-around',
fontSize: '0.8rem',
fontFamily: 'Roboto',
color: '#008091',
border: '2px solid #008091',
borderRadius: '0.375rem',
marginRight: '1rem',
marginTop: '2rem',
marginBottom: '2rem',
minWidth: '180px',
textAlign: 'center',
fontWeight: 700,
margin: '1rem 0',
padding: 0
},
selected: {
backgroundColor: '#008091',
color: 'white'
}
});
interface Props {
classes: { [className in keyof typeof styles]: string };
style?: React.CSSProperties;
text: string;
selected?: boolean;
onClick: (event: React.MouseEvent<HTMLElement>) => void;
}
const TextButton = ({ classes, style, text, onClick, selected }: Props) => {
return (
<Button
className={selected ? classNames(classes.button, classes.selected) : classes.button}
style={style}
onClick={onClick}
>
{text}
</Button>
);
};

Psuedo selectors can be added by:
const styles = createStyles({
button: {
// main styles,
"&:focus": {
color: "red"
}
}
});

This should do the trick
overrides: {
MuiButton: {
root: {
'&:focus': {
color: 'rgba(0, 0, 0, 0.87)',
backgroundColor: 'rgba(0, 0, 0, 0.87)',
},
},
},
},

Related

MUI Data Grid Pro - how to remove column menu animation

im using the MUI Data Grid Pro, and trying removing the animations.
currently i managed to remove the open animation but when closing the closing animation remains.
for example: the column menu on closing has a delay/disappearing-effect which i try to get rid off.
Attempts:
i used the prop componentProps to set all the css related to animation to unset or none.
i used the components prop to replace the columnMenu with custom menu.
Table Column Menu Component
const StyledGridColumnMenuContainer = styled(GridColumnMenuContainer)(() => ({
background: 'var(--neutral-element-dark)',
color: 'white',
borderRadius: '5px',
transition: 'none !important',
transformOrigin: 'unset !important',
}));
export const TableMenu = ({
hideMenu,
currentColumn,
color,
open,
...rest
}) => {
return (
<StyledGridColumnMenuContainer
open={open}
hideMenu={hideMenu}
currentColumn={currentColumn}
{...rest}
>
<SortGridMenuItems onClick={hideMenu} column={currentColumn} />
<GridFilterMenuItem onClick={hideMenu} column={currentColumn} />
</StyledGridColumnMenuContainer>
);
};
MUI Table
const componentProps = {
basePopper: {
sx: {
backgroundColor: 'var(--neutral-element-dark)',
borderRadius: '5px',
fontFamily: 'Open Sans',
fontWeight: 300,
transformOrigin: 'unset !important',
'& .MuiPaper-root': {
backgroundColor: 'var(--neutral-element-dark)',
borderRadius: '5px',
transition: 'none !important',
animationDuration: '0s !important',
transitionDuration: '0s !important',
fontFamily: 'Open Sans',
fontWeight: 300,
transformOrigin: 'unset !important',
},
'& .MuiInputLabel-formControl, .MuiInput-input, .MuiButtonBase-root': {
color: 'white !important',
transitionDuration: '0s !important',
},
'& .MuiInput-underline::after': {
// transitionDuration: '0s !important',
borderColor: 'black !important',
},
},
},
columnMenu: {
transition: 'none !important',
},
};
const MUITable = (props: DataGridProProps) => {
return (
<StyledTableContainer>
<StyledTable
components={{
Pagination,
ColumnMenu: TableMenu,
}}
componentsProps={componentProps}
{...props}
/>
</StyledTableContainer>
);
};

Change default hover color of TableRow MUI

I would like to change the default hover color of a MUI TableRow by adding styles to the TableRow.
This question has been asked before, but the solutions are 3-4 years old, and they aren't working for me in my case. The docs also make it seem like there shouldn't be such arduous workarounds to achieve the goal.
The most relevant thread regarding solutions is here. At best, I can change the color of the hover for a cell, but not the whole row.
Below is my code; included you will find all of my attempts commented out:
import React, { Dispatch, SetStateAction, useCallback } from 'react';
import { makeStyles, TableCell, TableRow } from '#material-ui/core';
import EditIcon from '../../assets/common/edit-icon.svg';
import { Link } from 'react-router-dom';
import { COLORS } from '../../constants/theme';
import { format } from 'date-fns';
import { Box } from '#material-ui/core';
const useStyles = makeStyles(theme => ({
tableRow: {
'& .MuiTableCell-root': {
borderRight: `1px solid ${theme.palette.grey[200]}`,
borderBottom: 'none',
padding: 5,
paddingTop: 8,
paddingBottom: 8,
cursor: 'pointer',
minWidth: 25,
//this works but only for cell hover, not the full row
// "&:hover": {
// backgroundColor: `${COLORS.BLUE} !important`,
// },
},
//this doesn't work
// hover: {
// backgroundColor: `${COLORS.BLUE} !important`
// },
//this doesn't work
// '& .MuiTableRow-hover': {
// backgroundColor: `${COLORS.BLUE} !important`
// },
//this doesn't work
// hover: {
// "&:hover": {
// backgroundColor: "green !important",
// },
// },
//this doesn't work
// root: {
// '&:hover': {
// backgroundColor: `${COLORS.BLUE} !important`
// },
// },
//this doesn't work
// '& .MuiTableRow-hover': {
// backgroundColor: `${COLORS.BLUE} !important`
// },
//this doesn't work
// MuiTableRow: {
// root: {
// '&:hover': {
// backgroundColor: `${COLORS.BLUE} !important`,
// }
// }
// },
//this doesn't work
// '& .MuiTableRow-root': {
// hover: { backgroundColor: "green !important" }
// },
// root: {
// '&:hover': {
// backgroundColor: `${COLORS.BLUE} !important`
// },
// },
'& .MuiTableCell-root:first-child': {
border: 'none'
},
},
selectedRow: {
backgroundColor: `${COLORS.BLUE} !important`,
'& .MuiTableCell-root': {
color: COLORS.WHITE
}
},
editIcon: {
backgroundImage: `url(${EditIcon})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
width: 18,
height: 18
}
}));
interface IProps extends Omit<unknown, 'children'> {
children?: React.ReactNode;
isSelected: boolean;
redirectTo: string;
onSelect: Dispatch<SetStateAction<string>>;
cells: Array<string | number | Date | boolean | null | undefined>;
id: string;
}
const TableRowComponent = ({
isSelected,
onSelect,
redirectTo,
cells,
id
}: IProps): JSX.Element => {
const classes = useStyles();
const getCorrectFormat = useCallback(
cell => {
return cell instanceof Date
? format(cell as Date, "MM/dd/yyyy hh:mmaaaaa'm'")
: cell;
},
[cells]
);
return (
<TableRow
className={classes.tableRow}
classes={{ selected: classes.selectedRow }}
selected={isSelected}
onClick={() => onSelect(id)}
hover={true}
>
<TableCell align="center">
{isSelected && (
<Link to={redirectTo}>
<div className={classes.editIcon} />
</Link>
)}
</TableCell>
{cells.map(cell => (
<TableCell key={(id + Math.random()).toString()} align="center">
<Link to={redirectTo}>
<Box>
{cell || cell === 0 ? getCorrectFormat(cell) : 'null'}
</Box>
</Link>
</TableCell>
))
}
</TableRow >
);
};
export default TableRowComponent;
Thanks for your help!
check with below method. tested in MuiV5 and working for me. adjust according to your need. also you dont need to add hover={true} just hover is sufficient.
Option1 : with sx props
<TableRow
...
hover
sx={{
'&.MuiTableRow-root:hover':{
backgroundColor: 'red'
},
}}
>
...
</TableRow>
option 2: with useStyles
const useStyles = makeStyles(theme => ({
tableRow: {
...
'&.MuiTableRow-root:hover':{
backgroundColor: 'red' ,
},
},
}));
Using MUI v5.3.0:
You can change the color with the sx property like this:
<TableRow
sx={{
'&.MuiTableRow-hover': {
'&:hover': {
backgroundColor: 'papayawhip',
},
},
}}
hover
>
...
</TableRow>
haven't tried it but I guess you can use this as well in your useStyles
The solution that worked with useStyles was to add
"&:hover": {
backgroundColor: `${COLORS.BLUE} !important`,
},
into the tableRow. It seems kinda naked...but it works.
Full context in useStyles below
const useStyles = makeStyles(theme => ({
tableRow: {
'& .MuiTableCell-root': {
borderRight: `1px solid ${theme.palette.grey[200]}`,
borderBottom: 'none',
padding: 5,
paddingTop: 8,
paddingBottom: 8,
cursor: 'pointer',
minWidth: 25,
},
//this worked
"&:hover": {
backgroundColor: `${COLORS.BLUE} !important`,
},
'& .MuiTableCell-root:first-child': {
border: 'none'
},
},
selectedRow: {
backgroundColor: `${COLORS.BLUE} !important`,
'& .MuiTableCell-root': {
color: COLORS.WHITE
},
'& ..MuiTableRow-root.Mui-selected': {
hover: { backgroundColor: 'red' }
}
},
editIcon: {
backgroundImage: `url(${EditIcon})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
width: 18,
height: 18
}
}));
I'm not sure why seemingly better/more logical options did not work.

can't pass theme to child components Material-Ui - React?

I am trying to create a global theme with shared styles between component, so i don't need to repeat the same classes in each component, so i have a theme file:
export default {
palette: {
primary: {
light: '#039be5',
main: '#01579b',
dark: '#b22a00',
contrastText: '#fff'
},
secondary: {
main: '#004d40',
contrastText: '#fff'
}
},
typography: {
userNextVariants: true
},
form: {
textAlign: 'center',
},
img: {
maxWidth: 60,
margin: '1.5rem auto 5px'
},
textField: {
margin: 20
},
button: {
marginTop: 16,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
margin: 'auto',
width: 80,
height: 50
},
customError: {
color: 'red',
fontSize: '0.7rem'
},
small: {
display: 'block',
marginTop: '1rem'
},
circularProgress: {
color: '#fff',
position: 'absolute'
}
}
and in App.js
import themeFile from './theme';
import createMuiTheme from '#material-ui/core/styles/createMuiTheme';
import {MuiThemeProvider} from '#material-ui/core/styles';
const theme = createMuiTheme(themeFile);
<MuiThemeProvider theme={theme}>
<Signin />
</MuiThemeProvider>
in Signin page:
import makeStyles from '#material-ui/core/styles/makeStyles';
const useStyles = makeStyles(theme => ({
...theme
}));
const Signin = (props) => {
const classes = useStyles();
return //some form and style elements using classes
}
But i get an error TypeError: color.charAt is not a function, i don't know if i am doing it right, i tried to use withStyles but ii got the same error, what is wrong in my code?
Ciao, the problem is on color in customError. You cannot use 'red' in material ui theme. Try to replace it with #FF0000.
I found a solution for my problem, is by wrapping all properties other than pallette in an object like this
theme.js
export default {
palette: {
primary: {
light: '#039be5',
main: '#01579b',
dark: '#b22a00',
contrastText: '#fff'
},
secondary: {
main: '#004d40',
contrastText: '#fff'
}
},
spread: {
typography: {
userNextVariants: true
},
form: {
textAlign: 'center',
},
img: {
maxWidth: 60,
margin: '1.5rem auto 5px'
},
textField: {
margin: 20
},
button: {
marginTop: 16,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
margin: 'auto',
width: 90,
height: 50
},
customError: {
color: '#FF0000',
fontSize: '0.7rem'
},
small: {
display: 'block',
marginTop: '1rem'
},
circularProgress: {
color: '#fff',
position: 'absolute'
}
}
}
Signin page
const useStyles = makeStyles(theme => ({
...theme.spread
}));

ToggleButtonGroup react material ui

I cant seem to get the ToggleButton selected property from material ui to work on ToggleButton.
I have made a StyledToggleButton as the documentation from Material Ui.
const StyledToggleButton = withStyles({
root: {
fontFamily: 'Arial',
fontSize: '14px',
lineHeight: '20px',
letterSpacing: '0.25',
color: 'rgba(0, 0, 0, 0.87)',
padding: '15px 15px',
textTransform: 'none',
width: '100%',
'&$selected': { //<--this is my attempt as per documentation
color: 'red !important',
backgroundColor: 'red !important',
},
selected: {},
},
})(ToggleButton);
I am using the ToggleButtonGroup and passing ToggleButton as a child.
I have looked at using MuiTheme but i did not understand how to make that work in this example.
here is the rest for reference:
const StyledToggleButton = withStyles({
root: {
fontFamily: 'Arial',
fontSize: '14px',
lineHeight: '20px',
letterSpacing: '0.25',
color: 'rgba(0, 0, 0, 0.87)',
padding: '15px 15px',
textTransform: 'none',
width: '100%',
'&$selected': {
color: 'red !important',
backgroundColor: 'red !important',
},
selected: {},
},
})(ToggleButton);
const StyledGroupButton = withStyles({
root: {
padding: '15px 15px',
width: '100%',
},
})(ToggleButtonGroup);
export default function ObjectViewCard(props) {
const classes = useStyles();
const [alignment, setAlignment] = React.useState('none');
const handleChange = (
event: React.MouseEvent<HTMLElement>,
newAlignment: string,
) => {
setAlignment(newAlignment);
};
const children = [
<StyledToggleButton key={1} value="left">
{props.leftButtonContent}
</StyledToggleButton>,
<StyledToggleButton key={2} value="right">
{props.rightButtonContent}
</StyledToggleButton>,
];
return (
<Card>
<hr className={classes.divider}/>
<div className={`row ${classes.rowContainer}`}>
<div className="col-6">
<span className={classes.header}>Velg visning</span>
</div>
<div className="col-6">
<span className={classes.info}>
<InfoOutlinedIcon className={classes.icon}/> Vis tegnforklaring
</span>
</div>
</div>
<StyledGroupButton value={alignment} exclusive onChange={handleChange}>
{children}
</StyledGroupButton>
</Card>
);
}
```
call it like i did, but selected: {} need to be on same tree-level as root, solution here:
const StyledToggleButton = withStyles({
root: {
fontFamily: 'Arial',
fontSize: '14px',
lineHeight: '20px',
letterSpacing: '0.25px',
color: 'rgba(0, 0, 0, 0.87)',
padding: '15px 15px',
textTransform: 'none',
width: '100%',
'&$selected': {
backgroundColor: 'rgba(33, 137, 214, 0.14)',
color: 'rgb(26, 88, 159)',
'&:hover': {
backgroundColor: 'rgba(33, 137, 214, 0.14)',
color: 'rgb(26, 88, 159)',
},
},
},
selected: {},
})(ToggleButton);

Material-ui Override StepLabel nested property

I want to override the marginTop: 16 property that occurs in this implementation of StepLabel:
label: {
color: theme.palette.text.secondary,
'&$active': {
color: theme.palette.text.primary,
fontWeight: 500,
},
'&$completed': {
color: theme.palette.text.primary,
fontWeight: 500,
},
'&$alternativeLabel': {
textAlign: 'center',
marginTop: 16,
},
'&$error': {
color: theme.palette.error.main,
},
},
So that I get this as the desired outcome:
But I cannot for the life of me figure out how.... here's my implementation:
<StepLabel
classes={{
root: classes.root,
labelContainer: classes.labelContainer,
label: classes.myLabel
}}
>
{this.state.labels[label - 1]}
</StepLabel>
Here's the classes:
const styles = theme => ({
root: {
marginTop: 0,
padding: 0,
"& $alternativeLabel": {
marginTop: 0
}
},
labelContainer: {
backgroundColor: "green",
marginTop: 0,
"& $alternativeLabel": {
marginTop: 0
}
},
myLabel: {
backgroundColor: "red",
marginTop: 0,
"& $alternativeLabel": {
marginTop: 0
}
},
});
The result - the marginTop DOES NOT get overridden. :(
Further information - the property that I want to override:
seems like the way to do it is like this - credit to this answer Material-UI Style Override?
Put an empty alternativeLabel: {} in, so that the property &$alternativeLabel is overridden:
const styles = theme => ({
labelContainer: {
"& $alternativeLabel": {
marginTop: 0
}
},
alternativeLabel: {},
});
and then call it like this in your component:
<StepLabel
classes={{
alternativeLabel: classes.alternativeLabel,
labelContainer: classes.labelContainer
}}
>

Resources