Referencing another Rule in Material UI - material-ui

I have the following code where I need to reference another rule name to avoid style duplication in material ui. Unfortunately the rules aren't reflecting.
const useNavStyles = makeStyles((theme) => ({
active: {
color: 'green'
},
listItem: {
borderTopRightRadius: 100,
borderBottomRightRadius: 100,
paddingBottom: 12,
paddingTop: 12,
backgroundColor: theme.palette.background.paper,
},
subListItem: {
"&$listItem": { // I wish to copy over the properties from the above listItem rule and only add padding to it, but it isn't working.
paddingLeft: theme.spacing(4),
},
},
How do I resolve this?
Thanks

Referencing a local rule name does not "copy over" other styles. It changes your selector. You will still need to apply all those classes to your elements, which in return will then also apply the respective styles.
listItem: {
color: 'hotpink',
},
subListItem: {
"&$listItem": {
fontWeight: 'bold'
}
}
this compiles to
.listItem-1: {
color: hotpink;
}
.subListItem-0.listItem-1: {
font-weight: bold;
}
In other words, this will apply styles to an element that has both these classes:
<div className={clsx(classes.listItem, classes.subListItem)}>
hotpink and bold
</div>
<div className={classes.subListItem}>no styles at all</div>

Related

Backstage - Changing Page Header Color

I am trying to change the header text color on pages in Backstage (Spotify's open source software catalog). I have tried using themes as advised in Backstage documentation, but there is no way to specifically override the header text color (I can change the background colour, but not the color of the text.
I have tried a few solutions - this changes the background color of the header to white but the text remains white (default color) and actual header text cannot be read (white text on white background):
genPageTheme({colors: ['#ffffff', '#ffffff'], shape: shapes.wave})
I then found the ability to add a fontColor to the genPageTheme function and tried the following, but again it did not change the header color - I am not sure if I am calling it incorrectly:
genPageTheme({colors: ['#ffffff', '#ffffff'], shape: shapes.wave, options: {fontColor: '#B1D8FF'} }),
I also took a look at customizing the overall theme but found there is no field that allows the header to be modified (neither background nor text):
const myTheme = createTheme({
palette: {
...lightTheme.palette,
primary: {
main: '#2670A9',
},
:
:
I figure there is a way to do this using material-ui (MUI) directly since Backstage uses MUI but I would like to stay true to the Backstage customization approach of using their themes.
Any ideas how the header text color can be changed? Any ideas would be helpful!
You need to use BackstageOverrides. This will allow you to override default Backstage settings.
This will allow you to customize (a lot) your application.
A simple example:
import { BackstageOverrides } from '#backstage/core-components';
import { BackstageTheme } from '#backstage/theme';
export const customThemeOverrides = (
theme: BackstageTheme,
): BackstageOverrides => {
return {
BackstagePage: {
root: {
display: 'grid',
overflow: 'hidden !important',
gridTemplateColums: '30px 280px 3fr 30px',
gridTemplateAreas:
'"header header header header" ". sidenav content ." ". sidenav content . "',
},
},
BackstageHeader: {
header: {
height: '80px',
gridArea: 'header',
display: 'flex',
borderBottom: `1px solid #FFFFFF`,
backgroundImage: `none`,
backgroundPosition: 'center',
padding: '50px',
boxShadow: 'none',
background: `#FFFFFF`
},
rigthItemsBox: {
color: '#FFFFFF',
},
title: {
color: `#FFFFFF`,
fontSize: 24,
},
subtitle: {
color: `#666666`,
},
type: {
color: `#FFFFFF`,
},
},
BackstageHeaderLabel: {
label: {
color: '#FFFFFF',
},
root: { color: '#FFFFFF', },
value: { color: '#FFFFFF' },
},
};
};

How to override the styles in materialui-daterange-picker?

I am using https://github.com/jungsoft/materialui-daterange-picker which uses Material UI. It uses makeStyles to override the styles. I am trying to apply my own styles to things like button disabled, filled, outline, etc. How do you override a makeStyles override?
I tried directly overriding classes like this, but no success.
export const useDateRangePickerStyles = makeStyles({
'& button:disabled .materialui-daterange-picker-MuiTypography-colorTextSecondary': {
color: 'rgba(0, 0, 0, 0.26)'
},
'& .materialui-daterange-picker-makeStyles-filled': {
backgroundColor: '#03DAC5'
},
'& .materialui-daterange-picker-makeStyles-highlighted': {
backgroundColor: 'rgba(3, 218, 197, 0.08)'
},
'& .materialui-daterange-picker-makeStyles-outlined': {
borderColor: '#03DAC5'
},
'& .MuiPaper-elevation': {
boxShadow: 'none',
transition: 'none'
}
})
I even tried creating a new makeStyles with a hierarchy of MaterialUI class overrides. No success.
Looks like this issue came up multiple times with the plugin and the "Issues" section of the github package contains some css hacks that helped.

How to check a prop to output a block of code on a styled object in Emotion

What is the best practice to output a block of code on a styled object in Emotion?
A simple boolean statement looks like this:
const StyledComponent = styled('div')(({ check }) => ({
position: check ? 'relative' : undefined
})
But what is the best solution for a block of code like the following example if I don't want to check each line of code?
const StyledComponent = styled('div')(({ check }) => ({
// some style here
// ...
// only load pseud element if "check" is true
'&::before': {
content: `''`,
position: 'absolute',
left: '0%',
top: '0%',
width: '100%',
height: '100%',
background: 'blue'
}
}))
I have some solutions in mind.
Add the if statement on the content: as without content the rest won't show. It is not my favourite because the rest of the code still getting loaded.
Add the if statement to load a new div inside this component. This way I can target this specific div instead of using the pseudo-class before.
I gave it some thought and got to this solution:
const StyledComponent = styled('div')(
{
// some style here
position: 'relative'
},
({ check }) =>
// only load pseudo element if "check" is true
check
? {
'&::before': {
content: `''`,
position: 'absolute',
left: '0%',
top: '0%',
width: '100%',
height: '100%'
}
}
: undefined
)

How to use theme overrides with nested elements?

If I adjust the size of a button in the theme, like this:
const theme = createMuiTheme({
overrides: {
MuiButton: {
fab: {
width: 36,
height: 36,
},
},
MuiSvgIcon: {
root: {
width: 16,
},
},
},
};
Then the button and the icon appear at the size I want. However this affects all icons, whether they're inside a button or not!
How can I say that I only want the MuiSvgIcon properties to apply when the element is found inside a MuiButton element?
Well I've worked out one way to do it, but it's not ideal because it relies on the internal structure of the MuiSvgIcon. But it might serve as a starting point for someone else. Better answers are most welcome.
const theme = createMuiTheme({
overrides: {
MuiButton: {
fab: {
width: 36,
height: 36,
'& svg': {
width: 16,
},
},
},
},
};
It works by applying a style to the <svg> DOM element inside the JSX <Button variant="fab"> element.
It's not documented anywhere unfortunately, but you can use any sort of CSS selectors to help. Use the "attribute contains" pattern with the class attribute itself to target descendants:
const theme = createMuiTheme({
overrides: {
MuiButton: {
root: {
// Targets MuiSvgIcon elements that appear as descendants of MuiButton
'& [class*="MuiSvgIcon-root"]': {
width: 16
}
},
},
},
};
Note 1: Caution! Material UI minifies these classnames in prod builds by default. If you want to preserve these classnames for prod, you will need to tweak the class generator function: https://material-ui.com/customization/css-in-js/ (see dangerouslyUseGlobalCSS)
Note 2: with this pattern, occasionally you end having to use !important if there's already a competing inline style that you want to override. If you're using styled-components, you can increase the specificity by using && (see the Material UI docs).

How should I customize the Button color?

As stated in the doc, the color property accepts enums of "default", "inherit", "primary", "secondary". I want an arbitrary color other than "primary" and "secondary". A possible solution is by utilizing the "Overriding with classes" feature where I can specify the root background, and it works.
const styles = {
root: {
backgroundColor: "rgba(44, 152, 240)",
}
};
function FloatingActionButtons(props) {
const { classes } = props;
return (
<Button
variant="fab"
classes={{ root: classes.root }}
>
<Icon style={{ fontSize: 34 }}>play_arrow</Icon>
</Button>
);
}
However, when the mouse hangs over the button, the background restores to the default light grey. This behavior is different when I specify the color property to "primary", in which case the background dims a bit when the mouse hangs over.
How should I specify the customized color correctly?
Use hover selector
const styles = {
root: {
backgroundColor: "rgba(44, 152, 240)",
'&:hover':{
backgroundColor:"rgba(44, 152, 240)",
},
}
};
Have a look at Customized Buttons for more details.