How do you set the ripple color of a material-ui ListItem? - material-ui

I can seem to find anywhere in the documentation how to go about setting the ripple color on a material-ui ListItem. I have the ListItem wrapped in a MuiThemeProvider with my overridden theme like this:
const muiTheme = getMuiTheme({
palette: {
hoverColor: 'red',
},
});
<MuiThemeProvider muiTheme={muiTheme}>
<ListItem>
...
</ListItem>
</MuiThemeProvider>
What palette color property should I set to change the ripple color?

The ripple effect comes from a child component called TouchRipple. Specifically, the ripple color comes from the background-color of an element which is selectable using the MuiTouchRipple-child class. The ripple color is currentColor by default, but can be overridden easily.
Note that this works for any button-based component, not just ListItem.
Examples:
Styled Components API:
const MyListItem = styled(ListItem)`
.MuiTouchRipple-child {
background-color: red;
}
`;
Hook API:
const useStyles = makeStyles({
root: {
'.MuiTouchRipple-child': {
backgroundColor: 'red';
}
}
});
const MyListItem = () {
const classes = useStyles();
return <ListItem button className={classes.root}>Hook</ListItem>;
}
Global CSS:
.MuiListItem-root .MuiTouchRipple-child {
background-color: red;
}

I got here working on a similar issue on the Button, but it appears to be consistent across ripple effect, so perhaps this will help someone in the future.
In Material-UI next/v1, the rippleColor is linked explicitly to the label color of the element. If you want the ripple and label to be different colors, you have to override the label color separately.
import MUIButton from 'material-ui/Button';
import {withStyles} from 'material-ui/styles';
const Button = (props) => {
return <MUIButton className={props.classes.button}>Hat</MUIButton>
const styles = {
button: {color: 'rebeccapurple'}
};
export default withStyles(styles)(Button);
This should get you an overridden ripple color.

This is how you can globally change ripple color to red.
import React from "react";
import { createMuiTheme, ThemeProvider } from "#material-ui/core/styles";
import List from "#material-ui/core/List";
import ListItem from "#material-ui/core/ListItem";
import ListItemText from "#material-ui/core/ListItemText";
const theme = createMuiTheme({
overrides: {
// Style sheet name
MuiTouchRipple: {
// Name of the rule
child: {
// Some CSS
backgroundColor: "red"
}
}
}
});
const App = () => {
return (
<ThemeProvider theme={theme}>
<List>
<ListItem button>
<ListItemText primary="Item One" />
</ListItem>
<ListItem button>
<ListItemText primary="Item Two" />
</ListItem>
{/* <ListItem button> ... </ListItem> */}
</List>
</ThemeProvider>
);
};
export default App;
Play with the code in CodeSandBox.
Useful links:
Here's what the theme object looks like with the default values.
The overrides key enables you to customize the appearance of all instances of a component type.

You're on the right track! To change the ripple color, your theme should be:
const muiTheme = getMuiTheme({
ripple: {
color: 'red',
},
});
...however, that changes the ripple color for most of the material-ui components, not just ListItem. You can change the ripple color directly on the ListItem with the focusRippleColor and touchRippleColor properties:
<ListItem focusRippleColor="darkRed" touchRippleColor="red" primaryText="Hello" />

If you want to change the color of the ripple effect it can be done through the theme like you tried to do.
In the theme you can change the TouchRippleProps's classes and define your color in the CSS style you have.
import React from 'react';
import { createMuiTheme, ThemeProvider, Button } from '#material-ui/core';
const theme= createMuiTheme({
props:{
MuiButtonBase: {
TouchRippleProps: {
classes: {
root: 'CustomizeTouchRipple'
}
}
}
}
});
export default function App() {
return (
<ThemeProvider theme={theme}>
<Button>Click</Button>
</ThemeProvider>
);
}
And in the CSS style file:
.CustomizeTouchRipple {
color: red;
}
Simple as that.
Update 1:
Instead of using a CSS class style you can directly put style: {color: red[500]}.

It seems like in the current version I need to use the sx prop on <ListItem />.
<ListItem
sx={(theme) => ({
"& .MuiTouchRipple-child": {
backgroundColor: `${theme.palette.primary.main} !important`,
},
})}
>
Content
</ListItem>

this worked for me:
.mat-radio-button.mat-accent .mat-radio-inner-circle,
.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element,
.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),
.mat-radio-button.mat-accent:active .mat-radio-persistent-ripple {
background-color: mat-color($my-gray, 500);
}

Related

Material UI Customized styled element with theme

I'm starting to use Material UI in my project.
I have created a theme with some basic definitions, using my css variables:
import { createTheme } from '#mui/material/styles';
import theme from './_my-variables.scss';
const muiTheme = createTheme({
palette: {
primary: {
main: theme['color-blue'], // 'color-blue' is my css variable
},
},
typography: {
fontFamily: theme['brand-font'], // 'brand-font' is my css variable
},
}
I also used ThemeProvider in my App layout:
export const App = (props) => {
return (<Provider store={store}>
<ThemeProvider theme={muiTheme}>
<ConnectedRouter history={historyRef.history}>
<Layout {...props} />
</ConnectedRouter>
</ThemeProvider>
</Provider>);
};
I have a page with MUI elements, and it works fine and takes the new primary color and the new font.
<Box>
<Paper>
<Checkbox color="primary" /> <!-- I can see my new color in the page! Yay! -->
some text
</Paper>
</Box>
Now I want to create a custom element - like <MyCustomizeBox> that will have a different properties, using my css variables (for example - a specific width, defined in my variables).
How do I define them in my theme and how to use it to customize a new element?
I prefer not to user classes () because I want to create a generic elements for reusing. Also I don't want to change all Boxes in my app - only the customized ones.
I tries to use "withStyles" but I was getting the default theme instead of my customized theme and I saw on Google that I'm not support to use both "withStyles" and theme together.
At last, found the answer:
import { styled } from '#mui/system';
const MyCustomizedPaper = styled(Paper)(({ theme }) => ({
width: theme.custom.myCustomWidthCssVar
}));
<MyCustomizedPaper ></MyCustomizedPaper >

How can I change a color of Material UI GridActionsCellItem icon button using a theme?

I have an action button in a data grid (pro):
<GridActionsCellItem icon={ <EditIcon/> } />
how can I put color="inhereted" or color="#123" to all my action icon buttons using a theme?
I want to make all my action icon buttons to default to the same color.
If you want to set the change in your theme the code below should work for you.
MuiDataGrid: {
root: {
'& .MuiDataGrid-actionsCell': {
'& .MuiSvgIcon-root': {
color: 'red'
}
}
}
}
Or you can use styled components like this
const GridActionsCellItemStyled = styled(GridActionsCellItem)(({ theme }) => ({
"& .MuiSvgIcon-root": {
color: "red"
}
}));
<GridActionsCellItemStyled
icon={<EditIcon />}
label="Edit"
/>,

Change color of selected row on Material UI table

How to change/customize the default color of selected rows in a Material-UI table (of type Sorting & Selecting)? By default it is secondary (red) color (Codesandbox here: https://codesandbox.io/s/3sjxh). How to change it to a custom color, or at least to primary (blue), as it appears in the new beta version (https://next.material-ui.com/components/tables/#main-content) (v5).
You have to pass your styles to the classes props in order to change the styles for the TableRow.
To achieve the background-color change you want to override the default classes: .MuiTableRow-root.Mui-selected and .MuiTableRow-root.Mui-selected:hover.
To override them you have to use a parent reference with a so called $ruleName in your makeStyles hook. Here is a very good explanation from #Ryan Cogswell if you are more interested how it works.
This would then look like this:
const useStyles = makeStyles((theme) => ({
// your other styles
...,
tableRowRoot: {
"&$tableRowSelected, &$tableRowSelected:hover": {
backgroundColor: theme.palette.primary.main
}
},
tableRowSelected: {
backgroundColor: theme.palette.primary.main
}
}));
...
<TableRow
// your other props
...
classes={{
root: classes.tableRowRoot,
selected: classes. tableRowSelected,
}}
>
...
</TableRow>;
For the checkboxes, you only have to add the color prop in order to change it:
<Checkbox
// other props
...
color="primary"
/>
and for your Toolbar, you only need to change the provided highlight class inside your useToolbarStyles in order to get things working:
import { alpha } from "#material-ui/core/styles";
...
const useToolbarStyles = makeStyles((theme) => ({
...,
highlight:
theme.palette.type === "light"
? {
color: theme.palette.primary.main,
backgroundColor: alpha(
theme.palette.primary.light,
theme.palette.action.selectedOpacity
)
}
: {
color: theme.palette.text.primary,
backgroundColor: theme.palette.primary.dark
},
}));
Live demo:

In my Material-UI theme, my global override for MuiButton works, but not MuiAppBar

Basically, I can change the colors of all Button elements in my theme, but I've been unable to do the same for AppBar. I'm puzzled. Here's a snippet of my code:
overrides: {
MuiButton: {
root: {
background: 'blue',
},
label: {
color: 'white',
}
},
MuiAppBar: {
root: {
background: 'white'
}
},
I've tried a lot of different variations on that, but nothing works. Please advise!
The problem you are seeing is due to the color prop in AppBar overriding your custom styling. By default, your .MuiAppBar-root class styling is being applied as expected, but the .MuiAppBar-colorPrimary class is setting the background-color to the default theme primary color. This differs from MuiButton which has the color prop set to "default" if you don't explicitly set it. If you change this to 'inherit' or 'default', the custom color should work for you.
export default function CustomAppBar() {
const theme = createMuiTheme({
overrides: {
MuiAppBar: {
root: {
background: "white"
}
}
}
});
return (
<ThemeProvider theme={theme}>
<AppBar color="default">
...
</AppBar>
</ThemeProvider>
);
}
Resources:
https://material-ui.com/api/button/
https://material-ui.com/api/app-bar/

Material UI > Backdrop > only for some subcomponent of the page

Is there any way how to enhance a backdrop from example in https://material-ui.com/components/backdrop/ to show loading circle only above the single component (in case some page has more component), not above the whole page?
Thanks for reply.
Backdrop are fixed positioned by default, that's why it covers the whole page.
To achieve the result you want, we have to change its position to absolute and contain it inside an element with relative position — this element can be your component. If you're new in CSS positions check this docs from developer.mozilla.org.
Knowing all that, we can come up with the following codes
const useStyles = makeStyles({
parent: {
position: "relative",
width: 200,
height: 200,
backgroundColor: "red",
zIndex: 0,
},
backdrop: {
position: "absolute"
}
});
export default function App() {
const classes = useStyles();
return (
<div className={classes.parent}>
<Backdrop className={classes.backdrop} open={true}>
<CircularProgress color="inherit" />
</Backdrop>
</div>
);
}
Also we have to define z-index on either parent or backdrop element to make it work. Not sure why though.
I created a codesandbox for you to play with.
The Backdrop component of Material UI is set to position: 'fixed' by default, that's why it covers the whole page.
If you want it to reside and position itself like any other component typically on the DOM, all you have to do is to reset its position back to relative, for instance:
<Backdrop open={true} sx={{ position: 'relative' }}>
<CircularProgress color="inherit" />
</Backdrop>
and you don't need to change the parent component since it should be in your case see to relative by default if you're not changing it. But if you have crazy positions going in your app here and there, then you might consider changing that as well.
i have created a custom componenet that i use if i want to block only part of the UI:
"use strict";
/** external libraries */
import React from "react";
import Backdrop from "#mui/material/Backdrop";
import CircularProgress from "#mui/material/CircularProgress";
const BlockUi = ({open, onClose, children}) => {
return (
<div style={{"position": "relative"}}>
<Backdrop
sx={{color: "#FFFFFF", zIndex: (theme) => theme.zIndex.drawer + 1, "position": "absolute"}}
open={open}
onClick={() => onClose()}
>
<CircularProgress color="inherit"/>
</Backdrop>
{children}
</div>
);
}
export default BlockUi;
and i use it like this:
"use strict";
/** external libraries */
import React from "react";
import BlockUi from "./BlockUi";
const JsonForm = ({fields, onSubmit}) => {
const [loading, setLoading] = React.useState(false)
const stopLoading = () => {
setLoading(false)
}
return (
<div>
<BlockUi open={loading} onClose={stopLoading}>
<button type="submit" onClick={() => {
console.log(loading)
setLoading(true)
}}>Submit
</button>
</BlockUi>
</div>
);
}
export default JsonForm;