How to hide/show elements at certain breakpoints with Material UI? - reactjs

I want to show/hide elements on certain break points, like what I would do with Bootstraph or Zurb Foundation.
I see in the documentation here https://material-ui.com/system/display/#api we add
display={{ xs: 'block', md: 'none' }}
to our elements. I have done this, but I don't get any results - no hiding/showing elements, no errors, no compilation problems.
Would anyone know how this is done?
My code is:
import React from 'react'
import PropTypes from 'prop-types'
import makeStyles from '#material-ui/core/styles/makeStyles'
import Button from '#material-ui/core/Button'
const useStyles = makeStyles(styles)
const PhoneActionLink = ({ children, prefix, href, value, display, isFirst, ...other }) => {
const classes = useStyles()
return (
<Button
display={{ xs: 'block', md: 'none' }}
{...other}
>
{children}
</Button>
</div>
)
}

Here you go with a solution
import React from 'react'
import PropTypes from 'prop-types'
import makeStyles from '#material-ui/core/styles/makeStyles'
import Box from '#material-ui/core/Box'
import Button from '#material-ui/core/Button'
const useStyles = makeStyles(styles)
const PhoneActionLink = ({ children, prefix, href, value, display, isFirst, ...other }) => {
const classes = useStyles()
return (
<Box component="Button" display={{ xs: 'block', md: 'none' }} m={1}>
{children}
</Box>
)
}
Wrap the Button component within Box component.

The answer strictly depends on the version of MUI you're using.
The accepted answer should work for MUI v4 and prior versions, but didn't work for me (MUI v5).
I dug into the documentation From the official MUI website and found that the following code works for me:
<Box sx={{ display: { xs: 'block', md:'none' } }}>
{children}
</Box>
I'm guessing that the sx attribute allows you to modify some of the CSS properties based off specific breakpoints.
I'm no expert so I can't fully explain the solution, but I'm hoping that this solution helps another person out there.

Along with the other solutions, you could also use the component. Although it's deprecated now.

Related

MUI: cannot apply background color to Paper component

I'm trying to style the MUI <Paper> component, however setting the background color isn't working. Following the online tutorials I'm applying the background-color CSS property to the root element of the Paper but the color remains white while other CSS properties - in this case padding and text-align work. Can someone please tell me what I am missing?
import React from 'react';
import { Paper, Typography } from '#mui/material';
import { makeStyles } from '#mui/styles';
import AccessAlarmIcon from '#mui/icons-material/AccessAlarm';
const useStyles = makeStyles({
root: {
textAlign: 'center',
padding: 15,
backgroundColor: '#37474f',
}
});
export default function Header() {
const classes = useStyles();
return(
<Paper outlined square className={classes.root}
>
<Typography variant="h2" component="h1">
Pomodoro Cl
<AccessAlarmIcon sx={{ fontSize: 45, color: 'red' }} />
ck
</Typography>
</Paper>
)
}
First of all your attribute outlined is incorrect, it should bevariant="outlined" as per the documentation.
For the background-color not working, you will need to add !important to the property so it takes precedence over mui's default styling.
Here's a working codesandbox for you: https://codesandbox.io/s/strange-smoke-y6yhv?file=/src/App.tsx

changing background color in drawer - MUI

i cannot change backgroundColor in Drawer component. I do as I found in other refs and it is not working for me. I created two classes
import { makeStyles } from '#mui/styles'
import { Drawer, Typography } from '#mui/material';
const drawerWidth = 240;
const useStyles = makeStyles({
drawer: {
width: drawerWidth,
},
drawerPaper: {
width: drawerWidth,
backgroundColor: "#fcba03"
},
});
export default function Sidebar() {
const classes=useStyles()
return (
<>
<Drawer
className={classes.drawer}
variant="permanent"
anchor="left"
classes={{paper: classes.drawerPaper},
{root:classes.drawerRoot}}
>
<div>
<Typography variant='h5'> Home </Typography>
</div>
</Drawer>
</>
)
}
thanks for answer!
You're not passing the classes in correct way. The classes prop expects an object with keys containing the class names from makeStyle hook. The correct syntax should be like
classes={{ paper: classes.drawerPaper, root: classes.drawerRoot }}
The updated code could be
import { makeStyles } from "#mui/styles";
import { Drawer, Typography } from "#mui/material";
const drawerWidth = 240;
const useStyles = makeStyles({
drawer: {
width: drawerWidth
},
drawerPaper: {
"&&": {
width: drawerWidth,
backgroundColor: "#fcba03"
}
}
});
export default function Sidebar() {
const classes = useStyles();
return (
<>
<Drawer
className={classes.drawer}
variant="permanent"
anchor="left"
classes={{ paper: classes.drawerPaper, root: classes.drawerRoot }}
>
<div>
<Typography variant="h5"> Home </Typography>
</div>
</Drawer>
</>
);
}
Note: && is added to increase the specificity of the applied styles to the paper.
Also, the support of makeStyles is going to be a legacy solution at sometime in future. If possible, you should probably look at the newer styling option provided in the mui v5.
Yes, this "improved" props like p, px, my, bgcolor etc are on the component listed above, but MUI expose for each of their components, a sx prop, that is an object that accept this kind of prop ! Also, I don't know if it could help, but you still can customize MUI components from the theme object if you want this style to be applied on all components occurences

Style Material UI textfield

I'm trying to style a material-ui textfield but I don't get it to work the way I want. I just want a plain simple white input field with standard MUI animations. I want the textfield to always have a white background and text to be black.
You find the code on Code Sandbox: https://codesandbox.io/s/material-demo-2coo8?fontsize=14&hidenavigation=1&theme=dark
Thanks in advance!
You can custom style the TextField font and background color with the following code:
const useStyles = makeStyles((theme) => ({
root: {
"& .MuiInputBase-root": {
color: 'black' //or try theme.palette.primary.main
backgroundColor: 'white' //It should be white by default
}
}
}));
Then simply add the 'root' class to your TextField. As info, the above syntax is called JSS. .MuiInputBase-root is a class applied to the input component, which is a subcomponent of the TextField. This article explores the TextField component with dev tools open, so you can understand how the subcomponents work and get styled by MUI.
One more piece of info about the JSS syntax. Notice the 'space' between the '&' and the '.'. This space is important and acts as part of the selector, informing that .MuiInputBase-root class is on a child component of the parent that receive 'root' class styling.
I would highly suggest you to use functional components since it is the future of React.
Below you can see your example as functional component with regular Material-UI styles.
import React from "react";
import Grid from "#material-ui/core/Grid";
import TextField from "#material-ui/core/TextField";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles(theme => ({
root: { backgroundColor: "white" },
box: { backgroundColor: "white" },
input: {
root: { backgroundColor: "white", color: "black" }
}
}));
export default function FunctionalDemo() {
const classes = useStyles();
return (
<Grid
container
direction="row"
justify="center"
alignItems="center"
className={classes.root}
>
<Grid item xs={12} md={6} className={classes.box}>
<form noValidate>
<TextField
id="email"
label="Type here"
variant="filled"
color="secondary"
className={classes.input.root}
/>
</form>
</Grid>
</Grid>
);
}
Code sandbox: https://codesandbox.io/s/material-ui-plain-text-field-x2s48?fontsize=14&hidenavigation=1&theme=dark

Material-UI - Why should I use makeStyles instead of inline styles?

In Material-UI, there is the makeStyles function which can be used to get custom CSS-Styling.
Should I use it if I am not using a theme in that specific CSS?
For example:
import React from "react";
import { TextField, Paper, Button, Box } from "#material-ui/core";
const classes = {
paper: {
backgroundColor: "#eee",
marginLeft: "30%",
marginRight: "30%"
},
textField: {
backgroundColor: "#fff"
},
button: {
backgroundColor: "green",
marginLeft: 20
}
};
const Ohne = () => {
console.log(classes);
return (
<Paper style={classes.paper}>
<Box>
<TextField style={classes.textField} />
<Button style={classes.button}>abc</Button>
</Box>
</Paper>
);
};
export default Ohne;
The object was:
{
"paper": {
"backgroundColor": "#eee",
"marginLeft": "30%",
"marginRight": "30%"
},
"textField": {
"backgroundColor": "#fff"
},
"button": {
"backgroundColor": "green",
"marginLeft": 20
}
}
vs
import React from "react";
import { makeStyles } from "#material-ui/styles";
import { TextField, Paper, Button, Box } from "#material-ui/core";
const useStyles = makeStyles(theme => ({
paper: {
backgroundColor: "#eee",
marginLeft: "30%",
marginRight: "30%"
},
textField: {
backgroundColor: "#fff"
},
button: {
backgroundColor: "green",
marginLeft: 20
}
}));
const Mit = () => {
const classes = useStyles();
console.log(classes);
return (
<Paper className={classes.paper}>
<Box>
<TextField className={classes.textField} />
<Button className={classes.button}>abc</Button>
</Box>
</Paper>
);
};
export default Mit;
The object was:
{
"paper": "makeStyles-paper-85",
"textField": "makeStyles-textField-86",
"button": "makeStyles-button-87"
}
So there are 3 main points (that I see):
One way creates classes and references them, the other just uses the object as is.
In the first case an object is assigned to the style property which is inline and has a higher priority.
In the first example it is important to keep the const outside of the class, so the object is still created only once and won't trigger a rerender.
But the resulting component looks identical (in my Firefox).
My questions:
Can an example be constructed where these two approaches result in different controls?
Is there any performance aspect to it?
Any other differences?
There are a few scenarios where using CSS classes (e.g. via makeStyles or withStyles) is necessary:
If you want to use media queries in your CSS
If you want to target pseudo-classes (e.g. :hover)
If you are creating a reusable customization of one of the Material-UI components and want to customize some of the classes that are conditionally applied to the element based on props or some other context (e.g. if you want to customize the "error" look of an Input while leaving it up to the places where the custom component is used to specify the error prop either directly or via the FormControl context)
As far as performance concerns, I would expect inline styles to be faster for most use cases. Whether the difference is enough to matter would depend on a lot of specifics regarding your particular application. The team I work with uses makeStyles or withStyles for most of our styling.
Inline styles can result in a lot of duplicated CSS in the DOM if a particular component is rendered many times within the document (e.g. list items, table cells, etc.). One nice thing about always using classes is that you can change the CSS for the class in the browser's developer tools and see that change applied throughout all its usages in the document.

Material UI v1 with React - styling buttons

I'm trying to learn how to use Material UI with React.
I have incorporated v1 of Material UI in my project.
Nothing about coding comes intuitively to me, so I struggle to fill the gaps between the clues left in the documentation for resources.
I know I haven't got the hang of this yet, but piecing together what others have been able to do, I have set up a button in my project, as follows:
import React from 'react';
import Button from 'material-ui/Button';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import { fade } from 'material-ui/styles/colorManipulator';
const MyButton = (props) => {
return <span>
<Button {...props} />
</span>
};
export default MyButton;
I then try to use my button in a couple of places:
import React from 'react';
import MyButton from '../materialui/Button.js';
const style = {
background: '#FF5349',
color: 'white',
padding: '0 30px',
// marginBottom: '30px',
};
const Start = () => (
<span>
<MyButton style={style} size="large">
GET STARTED
</MyButton>
</span>
);
export default Start;
I am trying to change the size of the button.
The Material UI documentation indicates that I should be able to toggle the size property by inserting size="large".
The example given in the documentation is:
<Button size="large" className={classes.button}>
Large
</Button>
I've tried to insert size="large" in the const style in my Start component, in the use of MyButton in the start component and in the Button component itself. None of these attempts do anything to alter the size. The text label in the button looks miniature at the moment and I can't figure out how to manipulate the size.
Can anyone see how to increase the size of the button?
Here is how I have been using it.
You need to set the root Class of the button object (or another available class, refer to the documentation for each available class by components)
import React, { Component } from "react";
import { withStyles } from "material-ui/styles";
import Button from "material-ui/Button";
const styles = theme => ({
button: {
width: "300px",
margin: "0 auto",
textTransform: "uppercase",
padding: "20px 30px",
alignSelf: "center",
},
});
class MyCustomButton extends Component {
render() {
const { classes } = this.props;
return (
<Button color="primary" raised={true} classes={{ root: classes.button }} />
);
}
}
export default withStyles(styles)(MyCustomButton);

Resources