Change component alignment in react mui, ListItemIcon - reactjs

Default direction of ListItemIcon is ltr and it start from left to right.
How can I change the default behaviour ?
Any idea apperciate.
code snipped :
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon>
{<CloseIcon style={{ direction: "rtl" }} />}
</ListItemIcon>
</ListItemButton>
</ListItem>

Try like this.
<ListItem>
<ListItemText primary="Hello" />
<IconButton edge="end">
<CloseIcon />
</IconButton>
</ListItem>

You can specify how you want to align you items in the ListItemIcon like this:
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon sx={{justifyContent: 'right'}}>
{<CloseIcon />}
</ListItemIcon>
</ListItemButton>
</ListItem>

Related

How to remove the paddingRight when a MUI Drawer is opened

My problem its quite simple but i not know how to solve that, when the Drawer from MaterialUI is opened are added some css into the body in my page, and one of the css add a padding-right and that are screwing the page indentation.
Drawer closed:
Drawer opened:
The problem:
Code:
<React.Fragment key={"menu-button"} >
<MenuIcon onClick={toggleDrawer(true)} />
<Drawer
anchor={"left"}
open={state}
onClose={toggleDrawer(false)}
>
<Box
sx={{ width: 250, height: '100%'}}
className={styles.background}
role="presentation"
onClick={toggleDrawer(false)}
onKeyDown={toggleDrawer(false)}
>
<List>
{['About me', 'Projects', 'Experience', 'Education'].map((text, index) => (
<ListItem key={text} disablePadding>
<ListItemButton className={styles.option}>
<ListItemIcon className={styles.optionIcon}>
{icons[index]}
</ListItemIcon>
<ListItemText primary={text} />
</ListItemButton>
</ListItem>
))}
</List>
</Box>
</Drawer>
</React.Fragment>
The styles are adding only colors.
I fixed adding "disableScrollLock={ true }" into the Drawer component :)

When i click one button its open all buttons simultaneously

When I click on the post button it opens all buttons like media and user .i tried to define state function but when i click one button all buttons are open simultaneously.
this problem i am facing
My code are here
export default function ListItem() {
const [open, setOpen] = React.useState(false);
const handleClick = () => {
setOpen(!open);
};
return (
<div>
<List
sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}
component="nav"
aria-labelledby="nested-list-subheader"
>
{/* dashbord */}
<ListItemButton component="a" href="#simple-list">
<ListItemIcon>
<DashboardTwoToneIcon />
</ListItemIcon>
<ListItemText primary="DashBoard" />
</ListItemButton>
{/* post */}
<ListItemButton onClick={handleClick}>
<ListItemIcon>
<PostAddTwoToneIcon />
</ListItemIcon>
<ListItemText primary="Post" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="New post" component="a" />
</ListItemButton>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="All posts" />
</ListItemButton>
</List>
</Collapse>
{/* Media */}
<ListItemButton onClick={handleClick}>
<ListItemIcon>
<SubscriptionsTwoToneIcon />
</ListItemIcon>
<ListItemText primary="Media" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItemButton>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="All Media" component="a" />
</ListItemButton>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="Add New Media" />
</ListItemButton>
</List>
</Collapse>
You are using a single boolean state for all of them. I suggest storing the open status of each item/element you want to toggle in an object and check if the specific item/element is currently toggled open.
const [open, setOpen] = React.useState({});
const handleClick = (id) => () => {
setOpen(open => ({
...open,
[id]: !open[id],
}));
};
...
<ListItemButton onClick={handleClick("post")}> // <-- pass id
<ListItemIcon>
<PostAddTwoToneIcon />
</ListItemIcon>
<ListItemText primary="Post" />
{open["post"] ? <ExpandLess /> : <ExpandMore />} // <-- check by id
</ListItemButton>
<Collapse
in={open["post"]} // <-- check by id
timeout="auto"
unmountOnExit
>
<List component="div" disablePadding>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="New post" component="a" />
</ListItemButton>
<ListItemButton sx={{ pl: 4 }} component="a" href="#">
<ListItemText primary="All posts" />
</ListItemButton>
</List>
</Collapse>
Apply same for other buttons and collapsables but using specific unique keys.
You call function setOpen on a click on any object, however setOpen seems to change the state of a global variable that is used to determine whether the contents should be shown or not. Try to set a unique variable as open state for every button and only change this variable with a function in onClick

Creating Routes in React

I created my drawer using Materials UI and now I can't create links to other pages.I tried to set the link to https://www.google.com/ also.But it also didn't work.
Below is the part of my code.
<List
component="nav"
aria-labelledby="nested-list-subheader"
className={classes.menu}
>
<ListItem button>
<ListItemText primary="Buses" component={Link} to="/buses" />
</ListItem>
<ListItem button>
<ListItemText primary="Condutors" />
</ListItem>
<ListItem button onClick={handleClick}>
<ListItemText primary="Reports" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button className={classes.nested}>
<ListItemText primary="Generate Report" />
</ListItem>
<ListItem button className={classes.nested}>
<ListItemText primary="View Report" />
</ListItem>
<ListItem button>
<ListItemText primary="Profle" />
</ListItem>
<ListItem button>
<ListItemText primary="Log Out" />
</ListItem>
</List>
</Collapse>
</List>```
You can use Link for react-router-dom its like a in html
or if Is for page in tour web, you can use useHistory the same module
From react-router-dom documentation:
Provides declarative, accessible navigation around your application.
You can use the normal <a><a/> HTML tag for referring to external links.

The default "inset" property padding. ListItemText Component

I'm styling a nested list in a React app using material-ui. The default "inset" property padding is to large (56px) so I'm trying to override that default value. But I can't.
any suggestions? Thank you !!
<Fragment>
<ListItem button onClick={this.handleClick}>
<ListItemText
primary="Zones"
primaryTypographyProps={{ variant: 'subtitle2' }}
/>
{this.state.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={this.state.open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button
component={Link}
to={`${this.props.match.url}/zone/all-zones`}
onClick={THIS.handleMenuOpen}
>
<ListItemText
inset
primary="Show all"
primaryTypographyProps={{ variant: 'subtitle2' }}
/>
</ListItem>
</List>
</Collapse>
</Fragment>
The purpose of the inset prop on ListItemText is to align text of items that don't have an icon with the text of items that do (see the Inset List demo). It is not for indenting nested list items.
If you look at the Nested List demo, you will find that the indent is done via paddingLeft applied to the nested list items. In the demo, this is set to 32px (theme.spacing(4)), but you can set this to whatever you want it to be.
Here is the code from the Nested List demo:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import ListSubheader from "#material-ui/core/ListSubheader";
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 Collapse from "#material-ui/core/Collapse";
import InboxIcon from "#material-ui/icons/MoveToInbox";
import DraftsIcon from "#material-ui/icons/Drafts";
import SendIcon from "#material-ui/icons/Send";
import ExpandLess from "#material-ui/icons/ExpandLess";
import ExpandMore from "#material-ui/icons/ExpandMore";
import StarBorder from "#material-ui/icons/StarBorder";
const useStyles = makeStyles(theme => ({
root: {
width: "100%",
maxWidth: 360,
backgroundColor: theme.palette.background.paper
},
nested: {
paddingLeft: theme.spacing(4)
}
}));
export default function NestedList() {
const classes = useStyles();
const [open, setOpen] = React.useState(true);
const handleClick = () => {
setOpen(!open);
};
return (
<List
component="nav"
aria-labelledby="nested-list-subheader"
subheader={
<ListSubheader component="div" id="nested-list-subheader">
Nested List Items
</ListSubheader>
}
className={classes.root}
>
<ListItem button>
<ListItemIcon>
<SendIcon />
</ListItemIcon>
<ListItemText primary="Sent mail" />
</ListItem>
<ListItem button>
<ListItemIcon>
<DraftsIcon />
</ListItemIcon>
<ListItemText primary="Drafts" />
</ListItem>
<ListItem button onClick={handleClick}>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Inbox" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button className={classes.nested}>
<ListItemIcon>
<StarBorder />
</ListItemIcon>
<ListItemText primary="Starred" />
</ListItem>
</List>
</Collapse>
</List>
);
}
Group-Menu
<List component="nav" aria-label="patient-group">
<ListItem>
<ListItemText
primary="patients"
primaryTypographyProps={{variant:'button' }}
/>
</ListItem>
<PatientMenu />
<Divider />
<ListItem>
<ListItemText
primary="delivery sheets"
primaryTypographyProps={{ variant: 'button' }}
/>
</ListItem>
<DeliverySheetMenu />
</List>
Patient-Menu
<Fragment>
<List component="div" disablePadding>
<ListItem button
component={Link}
to={`${this.props.match.url}/patient/all_patients`}
onClick={this.handleOnClick};
>
<ListItemText
className='nested'
style={{paddingLeft: 20 }}
primary="Show all"
primaryTypographyProps={{variant:'subtitle2'}}
/>
</ListItem>
</List>
</Fragment>

Render component in Drawer with Material-ui Lists

This feels like it should be self-explanatory in the Docs, but they abstract out a key part of the List code to another file and don't show it. So, I'm left asking you fine folks.
I'm looking to do something pretty simple: Use a List-based sidebar with Material-ui (beta-version) to render a component in a Drawer. I have the list setup, but I can't figure out how to make the ListItems link to the components and perform the render. Here's my code:
class DashboardScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className={this.props.classes.container}>
<Appbar pagetitle="Dashboard" />
<div className={this.props.classes.appFrame}>
<Drawer
type="permanent"
classes={{
paper: this.props.classes.drawerPaper,
}}
anchor="left">
<div className={this.props.classes.drawerHeader} />
<List>
<ListItem button>
<ListItemIcon>
<AssessmentIcon />
</ListItemIcon>
<ListItemText primary="Analytics"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<ImportContactsIcon />
</ListItemIcon>
<ListItemText primary="Create Investigation"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<AssignmentIcon />
</ListItemIcon>
<ListItemText primary="Create Survey"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<AssignmentTurnedInIcon />
</ListItemIcon>
<ListItemText primary="Create Response"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<SettingsIcon />
</ListItemIcon>
<ListItemText primary="Settings"/>
</ListItem>
</List>
</Drawer>
<main className={this.props.classes.content}>
Testing Stuff!
</main>
</div>
</div>
)
}
}
What I'm rendering is just another separate component called "Analytics". There's nothing special about it. How do I get the first ListItem, with text = "Analytics", render said component <Analytics />?
The ListItem will have an onClick property that it propagates through to the appropriate child components. So, if you're searching to receive clicks for each ListItem, you can simply do this:
<ListItem button onClick={() => alert("Hey buddy this will alert when clicked.")}>
<ListItemIcon>
<AssessmentIcon />
</ListItemIcon>
<Analytics />
</ListItem>
<ListItem button onClick={() => alert("This is a click on a different item.")}>
<ListItemIcon>
<ImportContactsIcon />
</ListItemIcon>
<Analytics />
</ListItem>
The propagation of props down to the appropriate area is described at the bottom of the props section on the ListItem API page.
Solved!
Here's my code:
class DashboardScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className={this.props.classes.container}>
<Appbar pagetitle="Dashboard" />
<div className={this.props.classes.appFrame}>
<Drawer
type="permanent"
classes={{
paper: this.props.classes.drawerPaper,
}}
anchor="left">
<div className={this.props.classes.drawerHeader} />
<List>
<ListItem button component={({...props}) => <Link to={this.props.match.url + '/analytics'} {...props} />}>
<ListItemIcon>
<AssessmentIcon />
</ListItemIcon>
<ListItemText primary="Analytics"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<ImportContactsIcon />
</ListItemIcon>
<ListItemText primary="Create Investigation"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<AssignmentIcon />
</ListItemIcon>
<ListItemText primary="Create Survey"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<AssignmentTurnedInIcon />
</ListItemIcon>
<ListItemText primary="Create Response"/>
</ListItem>
<ListItem button>
<ListItemIcon>
<SettingsIcon />
</ListItemIcon>
<ListItemText primary="Settings"/>
</ListItem>
</List>
</Drawer>
<main className={this.props.classes.content}>
<Route path={this.props.match.url + "/analytics"} component={Analytics}/>
</main>
</div>
</div>
)
}
}
Essentially, you need to contain the Route for the component within the main section of the Drawer. Then, you need to Link to that route via the component wrapped within the component prop on the ListItem.
Hope this helps somebody!
Did you try to simply change ListItemText with your custom component?
<ListItem button>
<ListItemIcon>
<AssessmentIcon />
</ListItemIcon>
<Analytics />
</ListItem>

Resources