The default "inset" property padding. ListItemText Component - reactjs

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>

Related

Change component alignment in react mui, ListItemIcon

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>

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

How to open a selected nested list on Material-UI?

I have a code in React where I have two list menus that have nested menus.
class Nav extends React.Component {
state = { open: false };
handleClick = () => {
this.setState({ open: !this.state.open });
};
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<List
component="nav"
>
<ListItem button onClick={this.handleClick}>
<ListItemText primary="Files" />
{this.state.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={this.state.open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button className={classes.nested}>
<ListItemText primary="Providers" />
</ListItem>
<ListItem button className={classes.nested}>
<ListItemText primary="Insurance Companies" />
</ListItem>
</List>
</Collapse>
<ListItem button onClick={this.handleClick}>
<ListItemText primary="Utilities" />
{this.state.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={this.state.open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button className={classes.nested}>
<ListItemText primary="Excel Templates" />
</ListItem>
<ListItem button className={classes.nested}>
<ListItemText primary="Upload File" />
</ListItem>
</List>
</Collapse>
</List>
</div>
);
}
}
When I click the first menu, the second menu also opens. How do I only open one menu and the other one remains closed?
I think you will need to have two seperate values in state in order to only open one at a time
state = { openMenu1: false, openMenu2: false }
And the click events should trigger only one of those to go to true/false.
Make sure to change the variable in the Collapse component to use the corresponding state as well

How do I replace the MuiTouchRipple-child background class from a listItem button?

The library is fantastic congratulations.
How do I replace the MuiTouchRipple-child background class from a listItem button?
Thank you.
<List component="nav">
<ListItem button component="a" href="#simple-list">
<ListItemText primary="Trash" secondary="Jan 9, 2014" />
</ListItem>
<Divider />
<ListItem button component="a" href="#simple-list" >
<ListItemText primary="Spam" secondary="Jan 9, 2014" />
</ListItem>
</List>
Its work.
I have used TouchRippleProps
Pass a classes object through TouchRippleProps:
TouchRippleProps={{ classes: { child: classes.rippleClasses } }}
JSS:
rippleClasses: {
backgroundColor: 'white',
},

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