Change the styling of the component with props or css variables? - javascript

There is the following block, which I put in a separate component: img
And at certain breakpoints, I need to change its styling.
I see 2 possible normal options, but I can't figure out which one is more convenient.
through the props :
<InfoBlock
options={
iconWidth: 100,
iconMargin: 50,
color: 'red',
breakpoints: {
991: {
iconWidth: 50,
iconMargin: 25
},
767: {
iconWidth: 20,
color: 'brown'
}
}
}
/>
That is, in this scenario, I can essentially turn the received props inside the component itself as much as I want and change what is necessary
change the component styling via css variables
<InfoBlock class="info-block"/>
.info-block {
--icon-width: 100px;
--icon-margin: 50px;
--color: red;
#media (max-width: 991px) {
--icon-width: 50px;
--icon-margin: 25px;
}
#media (max-width: 767px) {
--icon-width: 20px;
--color: brown;
}
}
Both options are working, and the question is, is it logical to change the css properties by using the component's propses? Just for me personally, using #media looks easier and more familiar

I use makeStyles from Material UI to achieve the same.
const useStyles = makeStyles({
anyClassName:{
backgroundColor: 'red', // You can't type background-color as '-' are not accepted as variable names
fontSize: '1Rem';
// After doing the styling
},
AnotherClassName: {
backgroundColor: 'green';
fontSize: '0.8rem';
}
})
// Now we have to assign it like this
const classes = useStyles();
Once if we do this we can assign the class to any component we want like this.
<td className={classes.anyClassName}>I'm the red boi</td>
<h3 className={classes.AnotherClassName}>I'm the Green Guy</h3>

Related

How can I style a toastify toast in the same js file, without using the styled toastcontainer?

in my app I use the ToastContainer component to display more than one type of toast. I do not want them both to have the same style, therefore I cannot use a styled ToastContainer to achieve what I want.
I know from the documentation for toastify that a toast can have it's own className for which you can specify the color etc. in a css file. But I want to have the css in the javascript file. But I have not yet found a way for it to work.
This is what I have come up with:
const notify = () => {
toast(customMsg, {
className: container,
autoClose: false,
closeOnClick: false,
position: toast.POSITION.BOTTOM_RIGHT,
});
};
const container = {
backgroundColor: 'yellow !important',
color: ' black !important',
borderRadius: '10px !important',
border: '2px solid orange',
width: '200px'
};
This does not work, but if I change className to "container" and put the styling in a css file it works. Is there a way for the className to be specified in the javascript file?

How to override MUI PaperProps with styled components?

I am using MUI and I want to override the width of the menu with styled components.
I tried this:
const StyledMenu = styled(Menu)`
&& {
width: 100%;
}
`;
And nothing happened.
Then I found out that MUI has the PaperProps and when applying:
<StyledMenu
id="menu-appbar"
PaperProps={{
style: {
width: '100%',
},
}}
>
I got the desiered result but I would like to accomplish it via styled-components, is it possible?
Every style that you write in PaperProps attribute will make it's impact in .MuiPaper-root class.
So your code can be like this:
const StyledMenu = styled(Menu)`
&& {
& .MuiPaper-root {
width: 100%;
}
}
`;
More insights can be found in the docs.

How to custom color text and icon in TableSortText component of Material-ui?

What I'm trying to do:
I am trying to provide the user the option to provide custom styling to my EnhancedTable component by passing in a styles object containing properties such as headCellColor, headCellBackgroundColor, bodyCellColor, bodyCellBackgroundColor etc which can be used to color the cells in TableHead and TableBody.
In the TableHead component, I use a TableSortLabel in a way similar to what they've done in this material-ui docs example: https://material-ui.com/components/tables/#sorting-amp-selecting
I wish to custom color the text and the arrow icons on hover and when active based on the props provided by the user.
Let's see the colors of TableSortLabel in different situations:
The color of the text is grey initially and there is no arrow. When mouse is hovered over it, a grey arrow appears and the text turns black. On clicking it, active state is set, the grey arrow turns black and the text turns black permanently until active state is removed.
What I've tried so far:
const useStyles = makeStyles({
tableSortLabel: props => ({
backgroundColor: "blue",
color: props.headCellColor,
fill: props.headCellColor,
"&:hover": {
backgroundColor: "blue"
}
})
});
function EnhancedTableHeadCell(props) {
const { isActive, onHoverSortState, clickHandler, ...otherProps } = props;
const classes = useStyles(props.styles);
return (
<FancyTableCell styles={props.styles} {...otherProps}>
<TableSortLabel
active={isActive}
classes={{
icon: classes.tableSortLabel,
active: classes.tableSortLabel
}}
direction={onHoverSortState}
onClick={clickHandler}
>
{props.children}
</TableSortLabel>
</FancyTableCell>
);
}
This is what it looks like in the browser:
https://i.postimg.cc/fW7W2MRB/c1.jpg
The first one is a normal header, the second is on hover and the third is when clicked (active state).
From what we can observe, the text color is totally unaffected by the color css property in all the three cases (normal, hover, active). On hover, backgroundColor only affects the icon and not the text. However, we can see that backgroundColor affects the text when it is active. Everything is going as expected with the icon. The only issue is with the text.
What could I be possible doing wrong? How can I solve my problem?
What worked for me is:
const StyledTableSortLabel = withStyles((theme: Theme) =>
createStyles({
root: {
color: 'white',
"&:hover": {
color: 'white',
},
'&$active': {
color: 'white',
},
},
active: {},
icon: {
color: 'inherit !important'
},
})
)(TableSortLabel);
You can reference the following for increasing css specificity:
https://material-ui.com/customization/components/#pseudo-classes
Solution for your problem is following:
MuiTableSortLabel: {
root: {
color: textPrimary,
// if you want to have icons visible permanently
// '& $icon': {
// opacity: 1,
// color: primaryMain
// },
"&:hover": {
color: primaryMain,
'&& $icon': {
opacity: 1,
color: primaryMain
},
},
"&$active": {
color: primaryMain,
// && instead of & is a workaround for https://github.com/cssinjs/jss/issues/1045
'&& $icon': {
opacity: 1,
color: primaryMain
},
},
},
}
This restyling I use globally via my ThemeProvider, but you can of course use it individually in your single component by using "withStyles" HOC (see "BootstrapButton" in example)
I could'nt find a proper way to do it so I came up with a temporary solution overriding the material ui css.
I added this to my global css:
.MuiTableSortLabel-root.MuiTableSortLabel-active,
.MuiTableSortLabel-root:hover,
.MuiTableSortLabel-icon {
color: inherit !important;
}
Worked for me with Mui5:
sx = {
{
'&.MuiTableSortLabel-root': {
color: 'white',
},
'&.MuiTableSortLabel-root:hover': {
color: 'blue',
},
'&.Mui-active': {
color: 'blue',
},
'& .MuiTableSortLabel-icon': {
color: 'blue !important',
},
}
}
'&.MuiTableSortLabel-root' <-- no space &.
'&.Mui-active' <-- no space &.
'& .MuiTableSortLabel-icon' <-- space

How to test styles and media queries rendered by a React component with Jest and/or Enzyme

I'm using styled-components to develop a framework that my company will use internally. We need to create new responsive components and when I test this in a browser, I can see how the rendered component changes its background-color when I resize the window. I'm trying to achieve the same programatically and test the functionality with Jest and/or Enzyme, but I've got no success so far. Anybody knows?
This is the code for the component:
const Component = styled.div`
height: 200px;
width: 200px;
background-color: purple;
#media (max-width: ${DESKTOP}px) {
background-color: purple;
}
#media (max-width: ${TABLET}px) {
background-color: yellow;
}
#media (max-width: ${MOBILE}px) {
background-color: red;
}
`
I wrote the following tests using toHaveStyleRule from the jest-styled-components package. Tests are passing because they effectively verify that 'background-color' is 'red' for the MOBILE media query, and so on.
expect(<Component />).toHaveStyleRule(
{ 'background-color': 'red' },
{ media: `(max-width: ${MOBILE}px)` }
)
expect(<Component />).toHaveStyleRule(
{ 'background-color': 'yellow' },
{ media: `(max-width: ${TABLET}px)` }
)
expect(<Component />).toHaveStyleRule(
{ 'background-color': 'blue' },
{ media: `(max-width: ${DESKTOP}px)` }
)
However, tests fail if I resize the window doing window.resizeTo(250, 250), because I expect the component to look red and instead, 'background-color' always seem to be 'purple'
For resizing window, I use and I've been trying this snippet with JSDOM: https://gist.github.com/javierarques/d95948ac7e9ddc8097612866ecc63a4b
Any clue? Thanks in advance!
I was able to recreate this locally, but what I realized was the first 2 expects passed, whereas the last one did not. That was because the DESKTOP media query block is setting the background-color to "purple", whereas the expect is looking for "blue".
background-color: purple;
#media (max-width: ${DESKTOP}px) {
background-color: purple;
}
expect(<Component />).toHaveStyleRule(
{ 'background-color': 'blue' },
{ media: `(max-width: ${DESKTOP}px)` }
)
Let me know if that's not the problem you are actually seeing.

What's the most performant but full-featured styling method in React.js

I have been reading a lot blog posts, best practices and slides (e.g. CSS in JS by Christopher Chedeau aka 'vjeux' which I think is great).
I totally understand why it is "better" to set your styling directly within your React Component, but I then found out that this might be limited as well. You may not use CSS pseudo-classes nor media queries to handle some responsive styling issues.
As someone who is used to do a lot of work with CSS and lately with SASS (which I still love) this drives me in some kind of cleavage, because I do not want to disclaim any styling property which standard CSS gives me.
My question now is:
Is it possible to have your styling within your React Components without those given disadvantages, and if: How would you actually do it to achieve the best performance and maximum of clarity.
Check out https://github.com/FormidableLabs/radium. It's pretty cool. Here's an example where they show how to add media queries among other things.
var styles = {
base: {
backgroundColor: '#0074d9',
border: 0,
borderRadius: '0.3em',
color: '#fff',
cursor: 'pointer',
fontSize: 16,
outline: 'none',
padding: '0.4em 1em',
':hover': {
backgroundColor: '#0088FF'
},
':focus': {
backgroundColor: '#0088FF'
},
':active': {
backgroundColor: '#005299',
transform: 'translateY(2px)',
},
// Media queries must start with #media, and follow the same syntax as CSS
'#media (min-width: 992px)': {
padding: '0.6em 1.2em'
},
'#media (min-width: 1200px)': {
padding: '0.8em 1.5em',
// Media queries can also have nested :hover, :focus, or :active states
':hover': {
backgroundColor: '#329FFF'
}
}
},
red: {
backgroundColor: '#d90000',
':hover': {
backgroundColor: '#FF0000'
},
':focus': {
backgroundColor: '#FF0000'
},
':active': {
backgroundColor: '#990000'
}
}
};

Categories

Resources