I'm getting some weird problems with the Material-UI drawer component. It scrolls horizontal on my iPad, compared to my MacBook and Android Phone, which actually scroll vertically..
Result on MacBook (how it's supposed to be..):
As you can see, it scrolls down and it overflows vertically, just like on my phone
Result on iPad (how it's not supposed to be..):
However, as you can see.. on my iPad it overflows horizontally..?
The code for the drawer:
<Drawer
anchor="right"
open={open}
onClose={HandleClose}
classes={{ paper: classes.drawerPaper }}>
<Toolbar />
<Typography className={classes.title}>Selecteer actieve regio's</Typography>
<FormControl component="fieldset" className={classes.formControl}>
<FormGroup>
{regios.map(regio => (
<FormControlLabel
control={
<Checkbox
checked={geselecteerdeRegios.includes(regio.ID)}
onChange={e => handleRegioChange(regio.ID, e.target.checked)}
/>
}
name={regio.Naam}
label={regio.Naam}
key={regio.Naam}
/>
))}
</FormGroup>
</FormControl>
</Drawer>
And these are the styles for the drawer
drawerPaper: {
width: 320
},
Why is this happening? And how can I prevent this and only allow vertical scroll/overflow instead of horizontal..?
Edit: codesandbox:
https://codesandbox.io/s/elated-khayyam-t6klg?file=/src/Drawer.js
Thanks in advance! :-)
This appears to be related to the default styles on FormGroup:
/* Styles applied to the root element. */
root: {
display: 'flex',
flexDirection: 'column',
flexWrap: 'wrap',
},
You can override this to nowrap to prevent the wrapping (as shown below with classes.formGroup in a modified version of your sandbox). I have not taken the time to understand why this behaves differently on iPads than on other devices.
import React from "react";
import {
Drawer,
FormControl,
FormGroup,
FormControlLabel,
Checkbox,
Toolbar,
Typography,
makeStyles
} from "#material-ui/core";
const useStyles = makeStyles(theme => ({
drawerPaper: {
width: 320
},
formGroup: {
flexWrap: "nowrap"
}
}));
export default () => {
let items = [];
for (let i = 0; i < 25; i++) items.push("foobarfazboo" + i);
const classes = useStyles();
return (
<Drawer anchor="right" open={true} classes={{ paper: classes.drawerPaper }}>
<Toolbar />
<Typography className={classes.title}>
Selecteer actieve regio's
</Typography>
<FormControl component="fieldset" className={classes.formControl}>
<FormGroup className={classes.formGroup}>
{items.map(item => (
<FormControlLabel
control={<Checkbox />}
name={item}
label={item}
key={item}
/>
))}
</FormGroup>
</FormControl>
</Drawer>
);
};
Unfortunately, this still leaves some odd behavior on the iPad. It seems to try to fit all of the content in the Drawer without scrolling (e.g. if I add 100 items instead of 25, they still are all forced to fit and become an unreadable, squished mess).
I don't fully understand what is happening, but it appears to be an interplay between the height and display: flex on the Drawer Paper. Changing the display from flex to block fixes this. I don't see any obvious new problems caused by this, but I haven't taken a lot of time to look at what other effects this change causes. With this change, the above "nowrap" change appears unnecessary.
import React from "react";
import {
Drawer,
FormControl,
FormGroup,
FormControlLabel,
Checkbox,
Toolbar,
Typography,
makeStyles
} from "#material-ui/core";
const useStyles = makeStyles(theme => ({
drawerPaper: {
width: 320,
display: "block"
}
}));
export default () => {
let items = [];
for (let i = 0; i < 25; i++) items.push("foobarfazboo" + i);
const classes = useStyles();
return (
<Drawer anchor="right" open={true} classes={{ paper: classes.drawerPaper }}>
<Toolbar />
<Typography className={classes.title}>
Selecteer actieve regio's
</Typography>
<FormControl component="fieldset" className={classes.formControl}>
<FormGroup>
{items.map(item => (
<FormControlLabel
control={<Checkbox />}
name={item}
label={item}
key={item}
/>
))}
</FormGroup>
</FormControl>
</Drawer>
);
};
Related
So I'm a newbie when it comes to React and thought to get familiar with the concepts utilizing mui. I'm creating a nav bar and one of the features is to have a search bar that is initially collapsed and expand once the search icon is pressed. This will also hide the typography element. My issue seems that no matter if I set flexgrow for both collapse or the text input that's being encapsulated the element doesn't seem to grow despite the extra space. I also observed when I set the width of the element using vw it adjusts but the right icons and search bar begin to overlap after minimizing it to a certain point. I wonder if this is a styling issue or whether if transition is incapable of doing this, if it's a styling issue how do I get the text input to expand the needed space?
Navbar.js
import React, { useState } from "react";
import {
AppBar,
Drawer,
Box,
IconButton,
List,
ListItemButton,
ListItemText,
Toolbar,
TextField,
Typography,
Collapse,
} from "#mui/material";
import MenuIcon from "#mui/icons-material/Menu";
import PersonOutlineOutlinedIcon from "#mui/icons-material/PersonOutlineOutlined";
import SearchOutlinedIcon from "#mui/icons-material/SearchOutlined";
import ShoppingBagOutlinedIcon from "#mui/icons-material/ShoppingBagOutlined";
import { createTheme } from "#mui/material";
const Navbar = () => {
const [drawer, setDrawer] = useState(false);
const [drawer2, setDrawer2] = useState(false);
const [clicked, setClicked] = useState(false);
const theme = createTheme({
typography: {
fontFamily: ["Abril Fatface", "cursive"].join(","),
},
});
return (
<AppBar position="fixed" sx={{ height: 70 }} className="navbar">
<Toolbar>
<IconButton onClick={() => setDrawer(!drawer)} className="id">
<MenuIcon fontSize="large"></MenuIcon>
</IconButton>
<Drawer open={drawer} onClose={() => setDrawer(!drawer)}>
<Box sx={{ width: 400, backgroundColor: "red" }}>
<List>
<ListItemButton>
<ListItemText primary="HI" />
</ListItemButton>
</List>
</Box>
</Drawer>
<Collapse orientation="horizontal" in={clicked} timeout={100} unmountOnExit>
<TextField sx={{ flexGrow: 2 }} />
</Collapse>
<Typography
component="a"
variant="h4"
theme={theme}
className="item"
sx={{
color: "black",
flexGrow: 2,
textAlign: "center",
display: clicked ? "none" : "block",
}}
>
APPSTUFF
</Typography>
<IconButton className="id">
<PersonOutlineOutlinedIcon fontSize="large"></PersonOutlineOutlinedIcon>
</IconButton>
<IconButton className="id" onClick={() => setClicked(!clicked)}>
<SearchOutlinedIcon fontSize="large"></SearchOutlinedIcon>
</IconButton>
<IconButton className="id" onClick={() => setDrawer2(!drawer2)}>
<ShoppingBagOutlinedIcon fontSize="large"></ShoppingBagOutlinedIcon>
</IconButton>
<Drawer
open={drawer2}
onClose={() => setDrawer2(!drawer2)}
anchor="right"
>
<Box sx={{ width: 400, backgroundColor: "red" }}>
<List>
<ListItemButton>
<ListItemText primary="HI" />
</ListItemButton>
</List>
</Box>
</Drawer>
</Toolbar>
</AppBar>
);
};
export default Navbar;
NavbarStyle.css
.id {
color: black;
margin-top: 0.5%;
display: flex;
flex-grow: 0;
}
.navbar {
width: 100vw;
box-shadow: none;
background-color: white;
}
I am importing the Card component from MUI but the component does not have any style.
import * as React from "react";
import Box from "#mui/material/Box";
import Card from "#mui/material/Card";
import CardActions from "#mui/material/CardActions";
import CardContent from "#mui/material/CardContent";
import Button from "#mui/material/Button";
import Typography from "#mui/material/Typography";
const bull = (
<Box
component="span"
sx={{ display: "inline-block", mx: "2px", transform: "scale(0.8)" }}
>
•
</Box>
);
export default function BasicCard() {
return (
<Card sx={{ minWidth: 275 }}>
<CardContent>
<Typography sx={{ fontSize: 14 }} color="text.secondary" gutterBottom>
Word of the Day
</Typography>
<Typography variant="h5" component="div">
be{bull}nev{bull}o{bull}lent
</Typography>
<Typography sx={{ mb: 1.5 }} color="text.secondary">
adjective
</Typography>
<Typography variant="body2">
well meaning and kindly.
<br />
{'"a benevolent smile"'}
</Typography>
</CardContent>
<CardActions>
<Button size="small">Learn More</Button>
</CardActions>
</Card>
);
}
What the component is supposed to look like:
MUI Component
What the component actually looks like:
Imported Component
How can I add styling?
You probably have text-align: center set somewhere in the parent. This usually happens when you create a react project with a template like CRA that has some CSS files like this:
.App {
text-align: center;
}
You can fix it by finding and removing that text-align property or reset it in your Card:
<Card sx={{ minWidth: 275, textAlign: "initial" }}>
If what you mean is the dark background, you can achieve it by setting the theme mode to dark:
import { ThemeProvider, createTheme } from "#mui/material/styles";
const theme = createTheme({
palette: {
mode: "dark"
}
});
<ThemeProvider theme={theme}>
<Card sx={{ minWidth: 275 }}>
{...}
</Card>
</ThemeProvider>
I have this appBar with a tab and an IconButton. I wanted to put the IconButton at the right side, but float: right does not work.
This is what it looks like:
I have also recreated this in code sandbox:
https://codesandbox.io/s/suspicious-morning-6pf26?file=/src/App.js:234-2709
Below are the entire codes:
export default function App() {
const [anchorEl, setAnchorEl] = useState(null);
const isMenuOpen = Boolean(anchorEl);
const handleProfileMenuOpen = (event) => {
setAnchorEl(event.currentTarget);
};
const handleMenuClose = () => {
setAnchorEl(null);
};
const menuId = "primary-search-account-menu";
const renderMenu = (
<Menu
anchorEl={anchorEl}
anchorOrigin={{ vertical: "top", horizontal: "right" }}
id={menuId}
keepMounted
transformOrigin={{ vertical: "top", horizontal: "right" }}
open={isMenuOpen}
onClose={handleMenuClose}
>
<MenuItem>Profile</MenuItem>
<MenuItem>Log Out</MenuItem>
</Menu>
);
const [value, setValue] = useState(0);
const [open, setOpen] = useState(false);
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<div className="App">
<AppBar
style={{
position: "sticky",
top: "0"
}}
>
<Toolbar variant="dense">
<div>
<>
<Grid
container
direction="row"
justifyContent="space-between"
alignItems="center"
>
<Grid item>
<Tabs
centered
value={value}
fullWidth={true}
indicatorColor="primary"
onChange={handleChange}
aria-label="simple tabs example"
variant="fullWidth"
>
<Tab disableRipple label="Homepage" to="/" />
<Tab disableRipple label="About" to="/about" />
<Tab disableRipple label="Admin" to="/admin" />
</Tabs>
</Grid>
<Grid item alignItems="flex-end" style={{ float: "right" }}>
<IconButton
edge="end"
right
aria-label="account of current user"
aria-controls={menuId}
aria-haspopup="true"
onClick={handleProfileMenuOpen}
color="inherit"
>
<AccountCircle />
</IconButton>
</Grid>
</Grid>
</>
</div>
</Toolbar>
</AppBar>
{renderMenu}
</div>
);
}
How should I love the AccountCircle at the right edge of the screen?
It looks like your snippet in the sandbox is working correctly. Can you double-check that there are no differences between the sandbox and your actual local code?
Looking at your code snippet, it looks like "float: right" is passed to the parent of IconButton, instead of iconbutton itself. Is it fixed (on your local environment, since code snippet appears to work) when you move the style to icon button?
I have an appBar and the homepage would appear behind the appbar. I wanted it to appear below it. This is what it looks like:
The AppBar codes:
const Header = () => {
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
//Breakpoints
const theme = useTheme();
const isMatch = useMediaQuery(theme.breakpoints.down("md"));
return (
<div>
<AppBar>
<Toolbar>
{/* //or just change this typography to an icon or picture */}
<Typography>Website</Typography>
{isMatch ? (
<h1>
<DrawerComponent />
</h1>
) : (
<Tabs
value={value}
indicatorColor="secondary"
onChange={handleChange}
aria-label="simple tabs example"
>
<Tab disableRipple label="Homepage" to="/" component={Link} />
<Tab disableRipple label="Login" to="/login" component={Link} />
<Tab disableRipple label="Settings" />
<Tab disableRipple label="Sample1" />
<Tab disableRipple label="Sample2" />
<Tab disableRipple label="Sample3" />
</Tabs>
)}
</Toolbar>
</AppBar>
</div>
);
};
export default Header;
I need to put a <br/> just to see the homepage:
const Homepage = (props) => {
return (
<section>
<br />
<h1>Homepage</h1>
</section>
);
};
export default Homepage;
And I have this drawerComponent for small screen sizes, it even got worse, you won't be able to see any message anymore not unless there will be a lot of <br/> before the message.
const DrawerComponent = () => {
const useStyles = makeStyles((theme) => ({
drawerContainer: {},
iconButtonContainer: {
marginLeft: "auto",
color: "white",
},
menuIconToggle: {
fontSize: "3rem",
},
link: {
textDecoration: "none",
},
}));
const [openDrawer, setOpenDrawer] = useState(false);
//Css
const classes = useStyles();
return (
<div>
<Drawer
anchor="left"
classes={{ paper: classes.drawerContainer }}
onClose={() => setOpenDrawer(false)}
open={openDrawer}
onOpen={() => setOpenDrawer(true)}
>
<List className={classes.link}>
<Link to="/">
<ListItem divider button onClick={() => setOpenDrawer(false)}>
<ListItemIcon>
<ListItemText> Homepage</ListItemText>
</ListItemIcon>
</ListItem>
</Link>
<Link to="/login">
<ListItem divider button onClick={() => setOpenDrawer(false)}>
<ListItemIcon>
<ListItemText> Login</ListItemText>
</ListItemIcon>
</ListItem>
</Link>
<ListItem divider button onClick={() => setOpenDrawer(false)}>
<ListItemIcon>
<ListItemText>Sample</ListItemText>
</ListItemIcon>
</ListItem>
<ListItem divider button onClick={() => setOpenDrawer(false)}>
<ListItemIcon>
<ListItemText> Sample</ListItemText>
</ListItemIcon>
</ListItem>
</List>
</Drawer>
<IconButton
edge="end"
className={classes.iconButtonContainer}
onClick={() => setOpenDrawer(!openDrawer)}
disableRipple
>
<MenuIcon className={classes.menuIconToggle} />
</IconButton>
</div>
);
};
export default DrawerComponent;
A way around this would be to add a margin-top or a padding-top to your homepage component equal to the height of the appbar.
Yet, a better approach would be ro use the following CSS properties on your appBar.
.app-bar {
position: sticky;
top: 0;
}
This will make your appbar stick to the top and will automatically adjust the height of its following DOM elements.
This post may answer your question: Creating a navbar with material-ui
You can either try:
Using CSS to implement padding-top (use "em" instead of "px" for a responsive padding height)
Reorganising your React components, making sure that the header (appbar) is not in the page, but rather a component at the same level (refer to the post linked above)
I am new in React and I am trying to align the component at a particular place but I am not able to do so.
import React from "react";
import "./styles.css";
import { Typography, Container, Grid, Button } from "#material-ui/core";
import useStyles from "./styles";
function Home() {
const classes = useStyles;
return (
<div className={classes.root}>
<Grid container>
<Grid item sm={6} xs={12}>
<Typography variant="h3" color="textPrimary" gutterBottom>
Hello, there.
</Typography>
<Typography variant="h5" paragraph>
I need to put this in the centre of the shaded region.
</Typography>
</Grid>
</Grid>
<div>
<Grid item sm={3} xs={6}>
<Button variant="contained" color="primary" disableElevation>
download
</Button>
</Grid>
</div>
</div>
);
}
I am using useStyles Hooks to do so.
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
top: "50%"
}
}));
export default useStyles;
But it is not working, is there a way to solve this?
It's not clear what you want to achieve, but I think this article about flex layout will help you understand how to position elements.
and try the following maybe it's what you want:
import React from "react";
import "./styles.css";
import { Typography, Container, Grid, Button } from "#material-ui/core";
function Home() {
return (
<Grid container style={{
justifyContent: "center"
}}>
<Grid container style={{
backgraoundColor: "blue",
maxWidth: "700px",
alignItems: "center",
justifyContent: "center"
}}>
<Typography variant="h3" color="textPrimary" gutterBottom>
Hello, there.
</Typography>
<Typography variant="h5" paragraph>
I need to put this in the centre of the shaded region.
</Typography>
<Button variant="contained" color="primary" disableElevation>
download
</Button>
</Grid>
</Grid>
);
}
Wrap your content into a div and apply following styles to it
shaded_region{
display:flex,
justify-content:"center",
}