the drawer covers the page - css

my drawer is covering the page i want it to be flex to the left without covering any content. this is my first time using material-ui so if anyone can explain i would appreciate that
const drawerWidth = 240;
const SideBar = (props) => {
const useStyles = makeStyles((theme) => ({
root: { display: "flex" },
}));
const classes = useStyles();
return (
<div>
<Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
"& .MuiDrawer-paper": {
width: drawerWidth,
boxSizing: "border-box",
},
}}
variant="permanent"
anchor="left"
>
<Toolbar />
<List>
<Divider />
{props.jobs.map((job, i) => (
<ListItem
alignItems="flex-start"
key={i}
onClick={() => {
props.onClick(job);
}}
>
<ListItemText primary={job.title} secondary={job.career_level} />
</ListItem>
))}
</List>
</Drawer>
</div>````

What you're probably looking for is the variant='persistent' drawer
import * as React from 'react';
import { styled, useTheme } from '#mui/material/styles';
import Box from '#mui/material/Box';
import Drawer from '#mui/material/Drawer';
import CssBaseline from '#mui/material/CssBaseline';
import MuiAppBar from '#mui/material/AppBar';
import Toolbar from '#mui/material/Toolbar';
import List from '#mui/material/List';
import Typography from '#mui/material/Typography';
import Divider from '#mui/material/Divider';
import IconButton from '#mui/material/IconButton';
import MenuIcon from '#mui/icons-material/Menu';
import ChevronLeftIcon from '#mui/icons-material/ChevronLeft';
import ChevronRightIcon from '#mui/icons-material/ChevronRight';
import ListItem from '#mui/material/ListItem';
import ListItemIcon from '#mui/material/ListItemIcon';
import ListItemText from '#mui/material/ListItemText';
import InboxIcon from '#mui/icons-material/MoveToInbox';
import MailIcon from '#mui/icons-material/Mail';
const drawerWidth = 240;
const Main = styled('main', { shouldForwardProp: (prop) => prop !== 'open' })(
({ theme, open }) => ({
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: `-${drawerWidth}px`,
...(open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
}),
}),
);
const AppBar = styled(MuiAppBar, {
shouldForwardProp: (prop) => prop !== 'open',
})(({ theme, open }) => ({
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
...(open && {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: `${drawerWidth}px`,
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
}),
}));
const DrawerHeader = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: 'flex-end',
}));
export default function PersistentDrawerLeft() {
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
return (
<Box sx={{ display: 'flex' }}>
<CssBaseline />
<AppBar position="fixed" open={open}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
sx={{ mr: 2, ...(open && { display: 'none' }) }}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap component="div">
Persistent drawer
</Typography>
</Toolbar>
</AppBar>
<Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
'& .MuiDrawer-paper': {
width: drawerWidth,
boxSizing: 'border-box',
},
}}
variant="persistent"
anchor="left"
open={open}
>
<DrawerHeader>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
</IconButton>
</DrawerHeader>
<Divider />
<List>
{['Inbox', 'Starred', 'Send email', 'Drafts'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
<Divider />
<List>
{['All mail', 'Trash', 'Spam'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</Drawer>
<Main open={open}>
<DrawerHeader />
<Typography paragraph>
Content
</Typography>
<Typography paragraph>
More content
</Typography>
</Main>
</Box>
);
}

Related

MaterialUI - Card Component positioning issues

Newbie to React, have mercy on my soul.
I'm attempting to create a card with a Collapse component. Cool. I have the following ugly result:
now, once I expand the Collapse component, my bottom bottoms move a bit upwards,
making my ugly result even uglier:
If I turn on pesticide extension, I get the following result once expanded:
it seems like the item below pushes my like and review buttons upwards, or perhaps I'm wrong.
Now, what is weird for me is that my buttons are absolute. by my understanding, they're supposed to be 'relative' to their parents, and act as a 'free entity', so I don't get why would it be moved anyway?
The code for that component:
import React, { useContext, useState } from "react";
import { styled } from "#mui/material/styles";
import Card from "#mui/material/Card";
import CardHeader from "#mui/material/CardHeader";
import CardMedia from "#mui/material/CardMedia";
import CardContent from "#mui/material/CardContent";
import CardActions from "#mui/material/CardActions";
import Collapse from "#mui/material/Collapse";
import Avatar from "#mui/material/Avatar";
import IconButton from "#mui/material/IconButton";
import Typography from "#mui/material/Typography";
import { red } from "#mui/material/colors";
import FavoriteIcon from "#mui/icons-material/Favorite";
import ShareIcon from "#mui/icons-material/Share";
import ExpandMoreIcon from "#mui/icons-material/ExpandMore";
import ExpandLessIcon from "#mui/icons-material/ExpandLess";
import MoreVertIcon from "#mui/icons-material/MoreVert";
import ThumbUpIcon from '#mui/icons-material/ThumbUp';
import ThumbDownIcon from '#mui/icons-material/ThumbDown';
import AuthContext from "../Contexts/isLoggedIn-context";
import usersAndProductsContext from "../Contexts/usersAndProducts-context";
import RateReviewIcon from '#mui/icons-material/RateReview';
import Farmers from "../Pages/Farmers";
import { useNavigate } from "react-router-dom";
import { Paper } from "#mui/material";
import ReviewText from "./ReviewText";
import { Box } from "#mui/system";
import { ExpandLess } from "#mui/icons-material";
// import logo_img from "../../Images/logo.png";
const ExpandMore = styled((props) => {
const { expand, ...other } = props;
return <IconButton {...other} />;
})(({ theme, expand }) => ({
transform: !expand ? "rotate(0deg)" : "rotate(180deg)",
marginLeft: "auto",
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest,
}),
}));
function FarmerComponent(props) {
let navigate = useNavigate();
let authCtx = useContext(AuthContext)
let usersAndItemsCtx = useContext(usersAndProductsContext)
let [isWritingReviewFlag, edit_isWritingReviewFlag] = useState(false);
let current_logged_user = usersAndItemsCtx.usersVal.find(user => user.id === authCtx.currentLoggedUserId);
console.log(current_logged_user.likedProfilesId)
let flag = (current_logged_user.likedProfilesId.find((id) =>id === props.id) ? true : false)
console.log(flag)
let [isCurrentFarmerLikedFlag, isCurrentFarmerLikedFlagToggle] = useState(flag)
const [expanded, setExpanded] = React.useState(false);
// let [favouriteClicked, set_favouriteClicked] = useState(false);
const handleFavouriteClicked = () => {
let prevLikedStatus = isCurrentFarmerLikedFlag
if(isCurrentFarmerLikedFlag){
current_logged_user.likedProfilesId = current_logged_user.likedProfilesId.filter(userid => props.id !== userid)
isCurrentFarmerLikedFlagToggle(!prevLikedStatus)
}
else {
current_logged_user.likedProfilesId.push(props.id);
isCurrentFarmerLikedFlagToggle(!prevLikedStatus)
}
}
const handleExpandClick = () => {
setExpanded(!expanded);
};
const handleCardClick = () => { //choosing a farmer to view his shop/products.
navigate('/farmershop/'+props.id)
}
const handleNewReview = () => {
edit_isWritingReviewFlag(true)
}
return (
<Paper sx={{width: "300px", border: "none"}}>
{/* props===the farmer card we're on */}
{isWritingReviewFlag ? <ReviewText
edit_isWritingReviewFlag={edit_isWritingReviewFlag}
reviewingFarmer={current_logged_user}
reviewedFarmer={props}
/> : <></>}
<Card
sx={{
height: "600px",
width: "350px",
padding: "5px",
backgroundColor: "#D37C65",
marginTop: "20px",
marginLeft: "20px",
marginRight: "20px",
boxShadow: "5px 16px 5px 0px rgba(0,0,0,0.75)",
borderRadius: "7px",
border: "none",
padding: "50px"
}}>
<div onClick={handleCardClick} style={{marginTop: "10%", letterSpacing: "2px", fontFamily: "sans-serif", cursor: "pointer"}}><h1>{props.firstname + " " + props.lastname}</h1></div>
<CardMedia
component="img"
height="194"
image={props.img}
sx={{borderRadius: "5px"}}
title={props.firstname + " " + props.lastname}
onClick={handleCardClick}
style={{cursor: "pointer", backgroundColor: "#5CBEFD"}}
/>
<Box sx={{borderRadius: "5px", opacity: "80%", position: "relative"}}>
<Typography variant="body2" color="text.secondary" sx={{backgroundColor: "#5CBEFD"}}> <span>Location: {props.location}</span></Typography>
{expanded ? <></> : <Typography variant="body2" color="text.secondary" sx={{backgroundColor: "#5CBEFD"}}><span>more info...</span></Typography>}
<IconButton onClick={handleExpandClick}>
{expanded ? <ExpandLessIcon/> : <ExpandMoreIcon/> }
</IconButton>
<Box sx={{marginTop: "80%"}}>
<Collapse sx={{position: "absolute", marginTop: "-70%" }} in={expanded}>{props.about}</Collapse>
</Box>
</Box>
<Box sx={{position: "absolute", marginTop: "-5%"}}>
<CardActions>
<IconButton onClick={handleFavouriteClicked} aria-label="add to favorites">
{!isCurrentFarmerLikedFlag ? <ThumbUpIcon style={{color: "rgba(0, 194, 0, 1)"}}/> : <ThumbDownIcon style={{color: "rgba(255, 30, 127, 1"}}/> }
</IconButton>
<IconButton onClick={handleNewReview} sx={{display: "flex", alignItems: "center", flexWrap: 'wrap'}} aria-label="add review">
<RateReviewIcon/>
<span style={{letterSpacing: "1px", marginLeft: "3px", marginBottom: "5px", fontSize: "15px"}}>add new review</span>
</IconButton>
</CardActions>
</Box>
</Card>
</Paper>
);
}
export default FarmerComponent;
Many thanks!

custom accordion in Mui Nextjs and mui

there is quite a new component introduced in #mui/lab which is Masonary which deals with accordions on the sidebar but not the one I posted above. so far I have achieved
import React from 'react';
import IconButton from '#mui/material/IconButton';
import FavoriteIcon from '#mui/icons-material/Favorite';
import Devider from '#mui/material/Divider';
import ExpandMoreIcon from '#mui/icons-material/ExpandMore';
import { styled } from '#mui/material/styles';
import { css } from '#emotion/react';
import { Rating, Paper, Card, Box, CardHeader, CardContent, CardMedia, CardActions, Toolbar, Typography, Collapse } from '#mui/material';
const ExpandMore = styled((props) => {
const { expand, ...other } = props;
return <IconButton {...other} />;
})(({ theme, expand }) => ({
transform: !expand ? 'rotate(0deg)' : 'rotate(180deg)',
marginLeft: 'auto',
transition: theme.transitions.create('transform', {
duration: theme.transitions.duration.shortest,
}),
}));
const DropDownPaperSection = ({ Pages, error }) => {
const [expanded, setExpanded] = React.useState(false);
const handleExpandClick = () => {
setExpanded(!expanded);
};
if (error) {
return <div className={style.Container} >An error occured: {error.message}</div>;
}
return (
<>
<Toolbar sx={{ bgcolor : '#f4f4f8'}}>
{Pages.data.map(Pages => (
//<div classname={style.main}>
<Box key={`$Pages.id`} variant='outlined' spacing={2 } elevation={1} style={{ margin: "16px 0px", border: "1px solid black" }}
css={css`
color: #20b2aa;
:hover {
color: #2e8b57;
}
`}>
{/* {Pages.attributes.Title}
{Pages.attributes.createdAt}
*/}
<Box>
<Typography variant="body2" color="text.secondary" className="hover:bg-violet-300">
{Pages.attributes.Title}</Typography>
</Box>
<Box enableSpacing>
<ExpandMore
expand={expanded}
onClick={handleExpandClick}
aria-expanded={expanded}
aria-label="show more"
>
<ExpandMoreIcon />
</ExpandMore>
</Box>
<Collapse in={expanded} timeout="auto" unmountOnExit>
<Typography paragraph padding="10px">
<Box sx={{ my: 8, spacing: 10, margin: 2 }} key={`$Pages.id`}> {Pages.attributes.Description} </Box></Typography>
<Devider />
<Box sx={{ my: 8, spacing: 10, margin: 2 }} key={`$Pages.id`}> {Pages.attributes.Content} </Box>
</Collapse>
</Box>
))} </Toolbar>
</>
)
}
export default DropDownPaperSection
But I am stuck with detaching those two elements as seen in the picture.
if you need you may find the rest of the code in github is there any possible way to achieve the closest one? I am not very sure how can i proceed next to detach this accordion. Maybe I am missing very evil details to detach them.
EDIT :
if we somehow use the portal and update the component it comes out as a combined section of multiple rows of data But not the desired output that I want.
```..........
<Collapse in={expanded} timeout="auto" unmountOnExit>
<Portal container={container.current} key={`$Pages.id`}>
<Typography paragraph padding="10px">
<Box sx={{ my: 8, spacing: 10, margin: 2 }} key={`$Pages.id`}> {Pages.attributes.Description} </Box></Typography>
<Devider />
<Box sx={{ my: 8, spacing: 10, margin: 2 }} key={`$Pages.id`}> {Pages.attributes.Content} </Box>
</Portal>
</Collapse>
<Box sx={{ p: 1, my: 1, border: '1px solid' }} key={`$Pages.id`} ref={container} />
</Box>
))} </Toolbar>
</React.Fragment> ```

CSS icon button half going offscreen on mobile view

I was able to make it so that the search bar stays to the right of the search bar. Not mandatory of course. I can be inside the right side of the search bar. This is the gitHub link for this: https://github.com/strawberries73/telescope/tree/Issue-1226
What I did try was an InputAdornment method. https://material-ui.com/components/text-fields/#input-adornments. This code can be found here: https://github.com/strawberries73/telescope/tree/Issue-1225
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import PropTypes from 'prop-types';
import SearchIcon from '#material-ui/icons/Search';
import {
Grid,
MenuItem,
TextField,
FormControl,
Paper,
IconButton,
Box,
Typography,
Fab,
} from '#material-ui/core';
const useStyles = makeStyles((theme) => ({
root: {
overflow: 'visible',
maxWidth: '785px',
padding: 0,
marginTop: '10rem',
marginLeft: 'auto',
marginRight: 'auto',
},
card: {
padding: theme.spacing(2, 4, 2, 4),
backgroundColor: theme.palette.background.default,
},
input: {
fontSize: '1.6rem',
'& > *': {
fontSize: '1.6rem !important',
color: theme.palette.text.default,
},
},
header: {
padding: 0,
marginBottom: theme.spacing(2),
backgroundColor: theme.palette.primary.main,
},
h1: {
display: 'block',
transition: 'all linear 350ms',
fontWeight: 600,
color: theme.palette.text.secondary,
[theme.breakpoints.between('xs', 'sm')]: {
fontSize: '3rem',
},
[theme.breakpoints.between('md', 'lg')]: {
fontSize: '4rem',
},
[theme.breakpoints.up('xl')]: {
fontSize: '5rem',
},
},
iconButton: {
backgroundColor: theme.palette.secondary.main,
'&:hover': {
backgroundColor: theme.palette.secondary.dark,
},
'& * > .MuiSvgIcon-root': {
fontSize: '2rem',
color: theme.palette.text.primary,
},
margin: 0,
marginRight: theme.spacing(-1.45),
bottom: theme.spacing(-2),
float: 'right',
marginBottom: theme.spacing(-5.5),
[theme.breakpoints.only('xs')]: {
marginTop: theme.spacing(6),
marginRight: theme.spacing(-8),
},
},
selectControl: {
'& > *': {
fontSize: '1.2rem',
textTransform: 'capitalize',
color: theme.palette.primary.main,
},
},
selectItem: {
fontSize: '1.4rem',
textTransform: 'capitalize',
color: theme.palette.primary.main,
},
}));
function CustomizedInputBase(props) {
const classes = useStyles();
const { searchText, onChangeHandler, onFilterChangeHandler, filter, onFormSubmit } = props;
const onFilterChange = (event) => {
onFilterChangeHandler(event.target.value);
};
const onTextChange = (event) => {
onChangeHandler(event.target.value);
};
const onSubmit = (event) => {
event.preventDefault();
onFormSubmit();
};
const searchOptions = ['post', 'author'];
return (
<Box className={classes.root} boxShadow={2}>
<Paper component="form" className={classes.card} elevation={0}>
<Grid
container
className={classes.header}
direction="row"
spacing={8}
alignItems="center"
justify="flex-start"
>
<Grid item xs={12}>
<Typography variant="h1" className={classes.h1}>
Search
</Typography>
</Grid>
</Grid>
<Fab size="large" className={classes.iconButton}>
<FormControl>
<IconButton type="submit" onClick={(event) => onSubmit(event)} aria-label="search">
<SearchIcon />
</IconButton>
</FormControl>
</Fab>
<Grid container direction="row" spacing={2} alignItems="center" justify="flex-start">
<Grid item xs={12} sm={2} lg={2}>
<FormControl fullWidth={true}>
<TextField
id="standard-select-search-type"
select
label="Filter"
value={filter}
variant="outlined"
className={classes.selectControl}
onChange={(event) => onFilterChange(event)}
>
{searchOptions.map((option) => (
<MenuItem key={option} value={option} className={classes.selectItem}>
{option}
</MenuItem>
))}
</TextField>
</FormControl>
</Grid>
<Grid item xs={12} sm={10} lg={10}>
<FormControl fullWidth={true}>
<TextField
className={classes.input}
placeholder="How to Get Started in Open Source"
inputProps={{ 'aria-label': 'search telescope' }}
variant="outlined"
value={searchText}
onChange={(event) => onTextChange(event)}
/>
</FormControl>
</Grid>
</Grid>
</Paper>
</Box>
);
}
CustomizedInputBase.propTypes = {
searchText: PropTypes.string,
onChangeHandler: PropTypes.func,
onFilterChangeHandler: PropTypes.func,
onFormSubmit: PropTypes.func,
filter: PropTypes.string,
};
export default CustomizedInputBase;
Solved! My solution to my answer.
import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles } from '#material-ui/core/styles';
import SearchIcon from '#material-ui/icons/Search';
import InputAdornment from '#material-ui/core/InputAdornment';
import {
Grid,
MenuItem,
TextField,
FormControl,
Paper,
IconButton,
Box,
Typography,
} from '#material-ui/core';
import SearchHelp from '../SearchHelp';
const useStyles = makeStyles((theme) => ({
root: {
overflow: 'visible',
maxWidth: '785px',
padding: 0,
marginTop: '10rem',
marginLeft: 'auto',
marginRight: 'auto',
marginBottom: theme.spacing(6),
},
card: {
padding: theme.spacing(2, 4, 2, 4),
backgroundColor: theme.palette.background.default,
},
header: {
padding: 0,
marginBottom: theme.spacing(2),
backgroundColor: theme.palette.primary.main,
},
h1: {
display: 'block',
transition: 'all linear 350ms',
fontWeight: 600,
color: theme.palette.text.secondary,
[theme.breakpoints.between('xs', 'sm')]: {
fontSize: '3rem',
},
[theme.breakpoints.between('md', 'lg')]: {
fontSize: '4rem',
},
[theme.breakpoints.up('xl')]: {
fontSize: '5rem',
},
},
iconButton: {
backgroundColor: theme.palette.secondary.main,
'&:hover': {
backgroundColor: theme.palette.secondary.dark,
},
'& * > .MuiSvgIcon-root': {
fontSize: '2rem',
color: theme.palette.primary.contrastText,
},
margin: 0,
position: 'relative',
bottom: theme.spacing(6),
float: 'right',
marginBottom: theme.spacing(-12),
},
selectControl: {
'& > *': {
fontSize: '1.2rem',
textTransform: 'capitalize',
color: theme.palette.primary.main,
},
},
selectItem: {
fontSize: '1.4rem',
textTransform: 'capitalize',
color: theme.palette.primary.main,
},
}));
function CustomizedInputBase(props) {
const classes = useStyles();
const { text, onTextChange, onFilterChange, filter, onSubmit } = props;
const searchOptions = ['post', 'author'];
return (
<Box className={classes.root} boxShadow={2}>
<Paper component="form" className={classes.card} elevation={0}>
<Grid
container
className={classes.header}
direction="row"
spacing={8}
alignItems="center"
justify="flex-start"
>
<Grid item>
<Typography variant="h1" className={classes.h1}>
Search
</Typography>
</Grid>
<SearchHelp />
</Grid>
<Grid container direction="row" spacing={2} alignItems="center" justify="flex-start">
<Grid item xs={12} sm={2} lg={2}>
<FormControl fullWidth={true}>
<TextField
id="standard-select-search-type"
select
label="Filter"
value={filter}
variant="outlined"
className={classes.selectControl}
onChange={(event) => onFilterChange(event.target.value)}
>
{searchOptions.map((option) => (
<MenuItem key={option} value={option} className={classes.selectItem}>
{option}
</MenuItem>
))}
</TextField>
</FormControl>
</Grid>
<Grid item xs={12} sm={10} lg={10}>
<FormControl fullWidth={true}>
<TextField
className={classes.input}
placeholder="How to Get Started in Open Source"
inputProps={{ 'aria-label': 'search telescope' }}
variant="outlined"
value={text}
InputProps={{
endAdornment: (
<InputAdornment>
<IconButton type="submit" className={classes.iconButton} onClick={onSubmit}>
<SearchIcon />
</IconButton>
</InputAdornment>
),
}}
onChange={(event) => onTextChange(event.target.value)}
/>
</FormControl>
</Grid>
</Grid>
</Paper>
</Box>
);
}
CustomizedInputBase.propTypes = {
text: PropTypes.string,
onTextChange: PropTypes.func,
filter: PropTypes.string,
onFilterChange: PropTypes.func,
onSubmit: PropTypes.func,
};
export default CustomizedInputBase;

Element positioned absolute inside Dialog Material UI React

I have Dialog component where I have a button(bottom right corner) which shows another div with an item list. The problem I'm facing is that the list is being rendered inside the Dialog component and it's being cropped. I set the position: absolute, z-index and set the position: relative to the parent but it does not work. Here is how it looks like. Any helpful tips I would appreciate it.
1) Before I click the button to show the list
2) After I click the button. Highlighted css properties for the list element
And the code for Dialog component :
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core";
import Button from "#material-ui/core/Button";
import Dialog from "#material-ui/core/Dialog";
import DialogContent from "#material-ui/core/DialogContent";
import DialogContentText from "#material-ui/core/DialogContentText";
import DialogTitle from "#material-ui/core/DialogTitle";
import IconButton from "#material-ui/core/IconButton";
import CloseIcon from "#material-ui/icons/Close";
import Typography from "#material-ui/core/Typography";
import OutlinedInput from "#material-ui/core/OutlinedInput";
import { ProjectTreeWindow } from "../index";
const useStyles = makeStyles(theme => ({
addTaskButton: {
marginTop: 10
},
dialog: {
width: "40%",
maxHeight: 435
},
closeButton: {
position: "absolute",
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500]
},
controlsWrapper: {
display: "flex",
alignItems: "center",
justifyContent: "space-between"
}
}));
const AddQuickTaskDialog = props => {
const classes = useStyles(props);
const { open, close } = props;
const [quickTaskDescription, setQuickTaskDescription] = useState("");
const [textInputRef, setTextInputRef] = useState(null);
const handleChangeQuickTaskDescription = event => {
setQuickTaskDescription(event.target.value);
};
const handleAddQuickTaskSubmit = () => {
alert("Quick task submitted");
close(textInputRef);
};
return (
<Dialog
data-testid="add-task-quick"
classes={{
paper: classes.dialog
}}
maxWidth="lg"
open={open}
keepMounted
onClose={() => {
close(textInputRef);
}}
aria-labelledby="quick-task-dialog"
aria-describedby="quick-task-dialog-description"
>
<DialogTitle id="quick-task-dialog-title">
<Typography variant="h6">Quick Add Task</Typography>
{close ? (
<IconButton
aria-label="close"
className={classes.closeButton}
onClick={() => {
close(textInputRef);
}}
>
<CloseIcon />
</IconButton>
) : null}
</DialogTitle>
<DialogContent>
<div className={classes.wrapper}>
<OutlinedInput
onChange={handleChangeQuickTaskDescription}
inputRef={input => {
setTextInputRef(input);
return input && input.focus();
}}
fullWidth
// className={showAddTaskInput ? classes.show : classes.hide}
placeholder="e.g. Take the dog out for a walk"
inputProps={{ "aria-label": "add task" }}
/>
<div className={classes.controlsWrapper}>
<Button
className={classes.addTaskButton}
disabled={quickTaskDescription.length === 0}
data-testId="quick-add-task-submit"
// onClick={handleAddTaskSubmit}
color="primary"
onClick={handleAddQuickTaskSubmit}
>
Add Task
</Button>
<ProjectTreeWindow />
</div>
</div>
</DialogContent>
</Dialog>
);
};
export default AddQuickTaskDialog;
and for the List component:
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core";
import ListAltTwoToneIcon from "#material-ui/icons/ListAltTwoTone";
import IconButton from "#material-ui/core/IconButton";
import { CustomizedToolTip } from "../index";
import OutlinedInput from "#material-ui/core/OutlinedInput";
import DoneTwoToneIcon from "#material-ui/icons/DoneTwoTone";
import List from "#material-ui/core/List";
import ListItem from "#material-ui/core/ListItem";
import ListItemIcon from "#material-ui/core/ListItemIcon";
import ListItemText from "#material-ui/core/ListItemText";
import FiberManualRecordTwoToneIcon from "#material-ui/icons/FiberManualRecordTwoTone";
import { useProjectsValue, useSelectedProjectValue } from "../../context";
const useStyles = makeStyles(theme => ({
root: {
position: "absolute",
zIndex: 9999,
top: 200,
left: 0,
display: "flex",
flexDirection: "column",
"&:hover $child": {
visibility: "visible"
}
},
wrapper: {
position: "relative !important"
},
selected: {
"& $child": {
visibility: "visible !important"
}
},
hidden: {
visibility: "hidden"
},
listItemIcon: {
minWidth: 30
}
}));
const ProjectTreeWindowList = props => {
const [textInputRef, setTextInputRef] = useState(null);
const [typeProject, setTypedProject] = useState("");
const classes = useStyles(props);
const { projects } = useProjectsValue();
return (
<div className={classes.root}>
<OutlinedInput
// onChange={handleChangeQuickTaskDescription}
inputRef={input => {
setTextInputRef(input);
return input && input.focus();
}}
placeholder="Type a project"
inputProps={{ "aria-label": "select project" }}
/>
<List>
{projects &&
projects.map((project, index) => (
<ListItem
onClick={() => {
alert("move selected project to input");
}}
// selected={active === project.projectId}
button
// classes={{
// root: classes.root,
// selected: classes.selected
// }}
>
<ListItemIcon
className={classes.listItemIcon}
style={{ color: project.color }}
>
<FiberManualRecordTwoToneIcon />
</ListItemIcon>
<ListItemText primary={project.name} />
<ListItemIcon
className={`${classes.listItemIcon} ${classes.hidden}`}
>
<DoneTwoToneIcon />
</ListItemIcon>
</ListItem>
))}
</List>
</div>
);
};
const ProjectTreeWindow = props => {
const classes = useStyles(props);
const [showProjectTreeWindow, setShowProjectTreeWindow] = useState(false);
const handleShowProjectWindow = () => {
setShowProjectTreeWindow(!showProjectTreeWindow);
};
const handleCloseProjectWindow = () => {
setShowProjectTreeWindow(false);
};
return (
<div className={classes.wrapper}>
<CustomizedToolTip title="Select a project">
<IconButton onClick={handleShowProjectWindow} aria-label="add-project">
<ListAltTwoToneIcon />
</IconButton>
</CustomizedToolTip>
{showProjectTreeWindow ? <ProjectTreeWindowList /> : null}
</div>
);
};
export default ProjectTreeWindow;
It is because of the combinaison of position: relative and overflow-y: auto from the <Paper> component. If you override one of this property, it won't be hidden anymore.
To do this, there is a PaperProps property in <Dialog>.
Example:
<Dialog {...otherProps} PaperProps={{style: {position: 'static'} }}/>

How to align React Material-UI list items using fontAwesome icons and Tailwind.css

I want to left-align the text of my list items. I also want to make all the icons the same size. The size of the envelope icon used with the Gmail list item. Currently, I have this:
How can I accomplish this?
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import List from '#material-ui/core/List';
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
import DraftsIcon from '#material-ui/icons/Drafts';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faFacebook, faGoogle, faGooglePlus, faTwitter, faYoutube, } from '#fortawesome/free-brands-svg-icons';
const styles = theme => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
container: {
width: '20px', // this does not work
}
});
function SimpleList(props) {
const { classes } = props;
return (
<div className={classes.root}>
<List component="nav">
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faGoogle} />
</ListItemIcon>
<ListItemText primary="Login with Google" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faTwitter} />
</ListItemIcon>
<ListItemText primary="Login with Twitter" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<DraftsIcon />
</ListItemIcon>
<ListItemText primary="Login with Gmail" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faFacebook} />
</ListItemIcon>
<ListItemText primary="Login with Facebook" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faYoutube} />
</ListItemIcon>
<ListItemText primary="Login with Youtube" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faGooglePlus} />
</ListItemIcon>
<ListItemText primary="Login with Google Plus" />
</ListItem>
</List>
</div>
);
}
SimpleList.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SimpleList);
Using fontSize CSS on the FontAwesomeIcon and DraftsIcon should do the trick. You most likely will also need to override any default padding and margin on the icons.
...
const styles = theme => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
faIcon: {
fontSize: 18,
// padding if needed (e.g., theme.spacing.unit * 2)
// margin if needed
},
muiIcon: {
fontSize: 18,
// padding if needed
// margin if needed
}
});
class SimpleList extends React.Component {
render() {
const { classes } = this.props;
const list = [
{
label: 'label 1',
icon: <FontAwesomeIcon className={classes.faIcon} icon={faTwitter} />
},
{
label: 'label 2',
icon: <DraftsIcon className={classes.muiIcon} />
}
];
return <div className={classes.root}>
<List component='nav'>
{
list.map((item, key) => (
<ListItem button>
<ListItemIcon>
{ item.icon }
</ListItemIcon>
<ListItemText primary={ item.label } />
</ListItem>
))
}
</List>
</div>;
}
}
SimpleList.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SimpleList);

Resources