How can you change the style of a disabled button in Material-UI using themes ?
The following code doesn't work
const theme = createMuiTheme({
props: {
// Name of the component
MuiButtonBase: {
// The default props to change
disableRipple: true // No more ripple, on the whole application !
}
},
overrides: {
MuiButton: {
text: {
color: "red"
},
disabled: {
text: {
color: "blue"
}
}
}
}
});
function DefaultProps() {
return (
<ThemeProvider theme={theme}>
<Button disabled>Change default props</Button>
</ThemeProvider>
);
}
The following works:
const theme = createMuiTheme({
props: {
// Name of the component
MuiButtonBase: {
// The default props to change
disableRipple: true // No more ripple, on the whole application !
}
},
overrides: {
MuiButton: {
root: {
color: "red",
'&$disabled': {
color: "blue"
}
},
}
}
});
Related
I tried to change label's margin (see the attached image to the question) from px to em/rem, but i don't know where i should write styles to structure. I can't find in MUI documentation "adjacent sibling combinator".
createTheme({
MuiTextField: {
defaultProps: {
// props
},
styleOverrides: {
root: {
// styles
}
}
}
})
generated css style in inspector tab
If you are using material-ui 5:
import { createTheme } from '#mui/material';
const theme = createTheme({
components: {
MuiTextField: {
styleOverrides: {
root: {
'& label': {
margin: '2rem',
},
},
},
},
},
});
export default theme;
https://mui.com/pt/material-ui/customization/theme-components/
I finally resolve it ;) I added to InputLabel this line "& + .MuiInputBase-root" to change TextField's (and another inputs) label
MuiInputLabel: {
defaultProps: {
// props
},
styleOverrides: {
root: {
// styles
"& +.MuiInputBase-root": {
marginTop: '2em'
}
}
}
}
I'm trying to create my own theme with Material-Ui v.5.4.0. And I faced with problem. I can't change TextField focused border color and width. I spend hours for research and didn't find working solution. And I started to think is it even possible to do that in theme? But it's not logical.
My current theme code:
import { createTheme } from '#mui/material/styles'
// Colors
const blue = '#5A5BD4'
const blueDark = '#4f4fd8'
// Parameters
const buttonsBorderRadius = 20
const buttonPadding = '5px 15px'
const inputBorderRadius = 10
const theme = createTheme({
components: {
// Buttons
MuiButton: {
variants: [
// Blue button
{
props: { variant: 'blueButton' },
style: {
backgroundColor: blue,
color: '#ffffff',
borderRadius: buttonsBorderRadius,
textTransform: 'none',
padding: buttonPadding,
'&:hover': {
backgroundColor: blueDark
}
}
},
// Transparent button
{
props: { variant: 'transparentButton' },
style: {
color: blue,
borderRadius: buttonsBorderRadius,
textTransform: 'none',
padding: buttonPadding
}
}
]
},
// Inputs
MuiOutlinedInput: {
styleOverrides: {
root: {
borderRadius: inputBorderRadius,
'& fieldset': {
border: `1px solid ${blue}`
}
},
focus: {
border: `1px solid ${blueDark}`
}
}
}
}
})
export default theme
My input code:
<TextField
size='small'
variant='outlined'
label={t('paslelbimo_data_nuo')}
type='date'
InputLabelProps={{
shrink: true
}}
fullWidth
value={publicationDateFrom}
onChange={(e) => setPublicationDateFrom(e.target.value)}
/>
Since I wasn't able to tell exactly what your desired effect was on focus vs not focused, I decided to just create a generic example, with overly dramatic styling, that may be useful to modify for your needs:
Essentially, I'm just overriding .MuiOutlinedInput-notchedOutline for both the focused an unfocused states:
const theme = createTheme({
components: {
// Inputs
MuiOutlinedInput: {
styleOverrides: {
root: {
...
"& .MuiOutlinedInput-notchedOutline": {
border: `5px solid green`,
},
"&.Mui-focused": {
"& .MuiOutlinedInput-notchedOutline": {
border: `5px dotted red`,
},
}
},
}
}
}
});
Working example CodeSandbox: https://codesandbox.io/s/customstyles-material-demo-forked-uri26?file=/theme.js:84-531
I'm styling my inputs inside Chakra UI's extendTheme function however I'm struggling to style an input that has been autocompleted. Using the :autofill pseudo selector doesn't seem to have any bearing because the browser (Chrome) has its own styles set with !important which forces the input's background colour to be white.
const theme = extendTheme({
components: {
Input: {
baseStyle: {
field: {
bg: "gray.700",
color: "gray.300",
_hover: {
bg: "gray.500",
},
_focus: {
bg: "gray.500",
},
// This does not work
_autofill: {
bg: "gray.500",
}
}
}
}
}
})
Just incase anyone has the same issue, I couldn't figure out how to override the default browser background-color, so instead I gave it a box-shadow value that creates a similar effect. Box-shadow is not set by the browser's autofill styles so this works well for my case.
const theme = extendTheme({
components: {
Input: {
baseStyle: {
field: {
bg: "gray.700",
color: "gray.300",
_hover: {
bg: "gray.500",
},
_focus: {
bg: "gray.500",
},
_autofill: {
border: "1px solid transparent",
textFillColor: "#c6c6c6",
boxShadow: "0 0 0px 1000px #232323 inset",
transition: "background-color 5000s ease-in-out 0s",
},
}
}
}
}
})
As TommyR's answer explains, this is currently broken in Chakra UI.
However, this does work in variants.
A somewhat clean fix would be to create a variant for this, and set it as a defaultProp:
Input: {
variants: {
backgroundFix: {
field: {
bg: "green.500",
},
},
},
defaultProps: {
variant: "backgroundFix",
},
},
If wanted, you could extend other existing variants, like so:
Input: {
variants: {
outlineBackgroundFix: (props) => ({
field: {
...defaultTheme.components.Input.variants.outline(props).field,
bg: props.colorMode === "light" ? "white" : "gray.800",
},
}),
},
defaultProps: {
variant: "outlineBackgroundFix",
},
},
If I understand correctly, the reason that Input background styles are not applied via baseStyles is that styles for variants override baseStyles, and each variant sets background (often to 'transparent'). As such, I don't think this is a bug, and is alluded to in a callout in the docs:
Pro tip 💡: If you're looking for a list of parts of a multipart component you can check it by clicking on the "View theme source" button at the top of the documentation page for that certain component.
https://chakra-ui.com/docs/styled-system/component-style#styling-multipart-components
To override the variant's default theme, you can define just the parts you want to change, which will be merged with the default styles for the variant.
Check the source for Input: https://github.com/chakra-ui/chakra-ui/blob/%40chakra-ui/react%402.4.2/packages/components/theme/src/components/input.ts#L115
HT to previous answers for pointing the way!
const variantFilled = {
field: {
bg: "red.500", // merged with the default styles for `filled`
/* // default styles:
border: "2px solid",
borderColor: "transparent",
bg: mode("gray.100", "whiteAlpha.50")(props),
_hover: {
bg: mode("gray.200", "whiteAlpha.100")(props),
},
_readOnly: {
boxShadow: "none !important",
userSelect: "all",
},
_invalid: {
borderColor: getColor(theme, ec),
},
_focusVisible: {
bg: "transparent",
borderColor: getColor(theme, fc),
},
*/
},
addon: {
/*
border: "2px solid",
borderColor: "transparent",
bg: mode("gray.100", "whiteAlpha.50")(props),
*/
},
};
export const theme = extendTheme({
components: {
Input: {
variants: { filled: variantFilled },
},
},
});
If you need access to props to toggle mode:
Docs: Component Style > Styling multipart components
import { inputAnatomy } from "#chakra-ui/anatomy";
import { createMultiStyleConfigHelpers, extendTheme } from "#chakra-ui/react";
import { mode } from "#chakra-ui/theme-tools"
const { definePartsStyle } = createMultiStyleConfigHelpers(inputAnatomy.keys);
const variantFilled = definePartsStyle((props) => ({
field: {
bg: mode("gray.100", "whiteAlpha.50")(props),
}
}))
I'm using Material UI with React for the first time. I want to change my global theme, but what I want to change has two classes:
.MuiListItem-root.Mui-selected, .MuiListItem-root.Mui-selected:hover {
background-color: rgba(0, 0, 0, 0.08);
}
How can I select them with createMuiTheme? I've tried this:
createMuiTheme({
overrides: {
MuiListItem: {
root: {
Mui: {
selected: {
backgroundColor: "black",
"&:hover": {
backgroundColor: "blue",
},
},
},
},
},
}
})
Thank you in advance
Here's the correct syntax:
const theme = createMuiTheme({
overrides: {
MuiListItem: {
root: {
"&.Mui-selected": {
backgroundColor: "black",
"&:hover": {
backgroundColor: "blue"
}
}
}
}
}
});
It is also equivalent to do:
const theme = createMuiTheme({
overrides: {
MuiListItem: {
root: {
"&$selected": {
backgroundColor: "black",
"&:hover": {
backgroundColor: "blue"
}
}
}
}
}
});
Just try this code
createMuiTheme({
overrides: {
MuiListItem: {
root: {
'&$selected': {
backgroundColor: "black"
},
'&$selected:hover'{
backgroundColor: "blue"
}
},
},
},
})
and look to this response
Material UI adds the global Mui-selected classes to make it easier to change specific elements globally.
However, you should just be targeting the MuiListItem classes according to the docs like so:
createMuiTheme({
overrides: {
MuiListItem: {
selected: {
backgroundColor: "black",
"&:hover": {
backgroundColor: "blue",
},
},
},
}
})
I see that this doesn't work anymore in the current version of Material UI. In the source code of the ListItem component, it is now defined like so:
root: {
'&$selected, &$selected:hover': {
backgroundColor: theme.palette.action.selected,
},
...
}
I have a scrollbar in multiple lists in the React app.
My global CSS within Material-UI is:
MuiCssBaseline: {
...theme.overrides?.MuiCssBaseline,
'#global': {
'#font-face': fontFace,
'*::-webkit-scrollbar': {
width: '1.3%',
maxWidth: '5px'
},
'*::-webkit-scrollbar-thumb': {
backgroundColor: 'white'
},
'*:focus': {
outline: 'none'
}
}
}
};
I am trying to add global state for hover.
When I hover on the box(!) not on the scroll itself, the scrollbar should be changed to gray.
Let's say I have box like:
<Box className={listStyle.root}>
<AutoSizer>
{({ height, width }) => (
<List dense ......
return (
<ListItem
/>
);
})}
</List>
)}
</AutoSizer>
I tried something like the following and it's not working:
.listStyle:{
'&:hover':{
'*::-webkit-scrollbar-thumb': {
backgroundColor: 'gray'
},
}
}
How can I achieve that?
The primary issue I see is that when nesting a rule (e.g. ::-webkit-scrollbar-thumb pseudo-element within :hover pseudo-class), you need to use & to refer to the parent rule instead of using *. So your listStyle should look like:
.listStyle:{
'&:hover':{
'&::-webkit-scrollbar-thumb': {
backgroundColor: 'gray'
},
}
}
It would also be equivalent to do the following:
.listStyle:{
'&:hover::-webkit-scrollbar-thumb': {
backgroundColor: 'gray'
}
}
If you want to apply this globally, you can do something like the following (I've changed the colors just to make the effects more easily distinguishable from browser defaults):
const theme = createMuiTheme({
overrides: {
MuiCssBaseline: {
"#global": {
"*::-webkit-scrollbar": {
width: "1.3%",
maxWidth: "5px"
},
"*::-webkit-scrollbar-thumb": {
backgroundColor: "purple"
},
"*:hover": {
"&::-webkit-scrollbar-thumb": {
backgroundColor: "green"
}
}
/* Equivalent alternative:
"*:hover::-webkit-scrollbar-thumb": {
backgroundColor: "green"
}
*/
}
}
}
});
Here is a full example showing both the global approach and overriding that using a class name at a lower level:
import React from "react";
import CssBaseline from "#material-ui/core/CssBaseline";
import {
ThemeProvider,
createMuiTheme,
makeStyles
} from "#material-ui/core/styles";
const theme = createMuiTheme({
overrides: {
MuiCssBaseline: {
"#global": {
"*::-webkit-scrollbar": {
width: "1.3%",
maxWidth: "5px"
},
"*::-webkit-scrollbar-thumb": {
backgroundColor: "purple"
},
"*:hover": {
"&::-webkit-scrollbar-thumb": {
backgroundColor: "green"
}
}
/* Equivalent alternative:
"*:hover::-webkit-scrollbar-thumb": {
backgroundColor: "green"
}
*/
}
}
}
});
const useStyles = makeStyles({
divStyle: {
"&:hover::-webkit-scrollbar-thumb": {
backgroundColor: "red"
}
}
});
export default function App() {
const classes = useStyles();
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<div style={{ height: "200px", overflowY: "scroll" }}>
<h1>
Div with enough content to scroll. Globally controlled scrollbar hover
color
</h1>
<h2>1</h2>
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
<h2>5</h2>
<h2>6</h2>
</div>
<div
style={{ height: "200px", overflowY: "scroll" }}
className={classes.divStyle}
>
<h1>
Div with enough content to scroll. Scrollbar hover color controlled by
classes.divStyle.
</h1>
<h2>1</h2>
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
<h2>5</h2>
<h2>6</h2>
</div>
</ThemeProvider>
);
}