Horizontally Align Primary/Secondary ListItemText, Material UI? - reactjs

I want the primary and secondary text within a ListItemText to both be center-aligned, unlike the question here.
However, after trying alignItems, alignContent, alignSelf, and primaryTypographyProps={{ align: "center" }}, I am stumped.
What's the correct way to go about this?

Below is an example with center-aligned text.
import React from "react";
import { makeStyles, withStyles } from "#material-ui/core/styles";
import List from "#material-ui/core/List";
import ListItem from "#material-ui/core/ListItem";
import ListItemText from "#material-ui/core/ListItemText";
const useStyles = makeStyles(theme => ({
root: {
width: "100%",
maxWidth: 360,
backgroundColor: theme.palette.background.paper
}
}));
const CenteredListItemText = withStyles({
root: {
textAlign: "center"
}
})(ListItemText);
export default function SimpleList() {
const classes = useStyles();
return (
<div className={classes.root}>
<List component="nav" aria-label="main mailbox folders">
<ListItem button>
<CenteredListItemText primary="Inbox" secondary="Inbox secondary" />
</ListItem>
<ListItem button>
<CenteredListItemText primary="Drafts" secondary="Drafts secondary" />
</ListItem>
</List>
</div>
);
}

Related

Material-UI ListItem "flex-start" not working

I am using the Material-UI List item (https://material-ui.com/components/lists/)
And I would like to "left-justify" my items in my list item to the left. Apparantly I can do this with the flex property "flex-start" which I can set on the alignItems property of a ListItem like so :
<List>
<ListItem alignItems="flex-start">
<ListItemText primary={"First Element "} />
<ListItemText primary={" Second Element"} />
</ListItem>
</List>
However this does not seem to work as they are evenly spaced out when I see it in the browser.
Am I doing something wrong?
Try this...
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles({
root: {
display:'flex',
alignItems:'flex-start',
flexDirection: "row"
},
});
export default function MyComponent(props) {
const classes = useStyles(props);
return (
<List className={classes.root}>
<ListItem>
<ListItemText primary={"First Element "} />
</ListItem>
<ListItem>
<ListItemText primary={"Second Element "} />
</ListItem>
</List>
);
}
ListItemText has default flex: 1 1 auto; style. You need to change it like:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import { List, ListItem, ListItemText } from "#material-ui/core";
const useStyles = makeStyles((theme) => ({
root: {
"& .MuiListItemText-root": {
flex: "initial"
}
}
}));
export default function CustomStyles() {
const classes = useStyles();
return (
<List classes={classes}>
<ListItem alignItems="flex-start">
<ListItemText primary={"First Element "} />
<ListItemText primary={" Second Element"} />
</ListItem>
</List>
);
}

Can I use ::selection Selector in Material-UI

I wanted to know if there is some way we can use ::selection in Material-UI.
Code :-
import React from 'react';
import { makeStyles } from '#material-ui/core';
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 InboxIcon from '#material-ui/icons/Inbox';
const styles = makeStyles((theme) => ({
root: {
'&:hover': {
backgroundColor: theme.palette.primary.contrastText,
},
'&:selection': {
backgroundColor: 'tomato',
},
},
}));
const Items: React.FC = () => {
const classes = styles();
return (
<List component='nav' aria-label='management side bar'>
<div className={classes.root}>
<ListItem button>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary='Inbox' />
</ListItem>
</div>
</List>
);
};
export default Items;
I just want to change the color of the background on selecting the List Component, can I do that using the simple '::selection' selector in material-ui?
In your example you are using the hover pseudo-class and the selection pseudo-element
All pseudo-classes are used via : and pseudo-elements via ::
Therefore, your styled code should look like this:
const styles = makeStyles((theme) => ({
root: {
'&:hover': {
backgroundColor: theme.palette.primary.contrastText,
},
'&::selection': {
backgroundColor: 'tomato',
},
},
}));

Conditional Rendering in Nextjs & TypeScript not working

Trying to render a component conditionally. I have a drawHelper variable & a function to toggle it true or false. The component renders or not based on the initial value of drawHelper. (false, doesn't render, true it does).
The toggle function changes the value. I checked with console.log(drawHelper) But changing the value does not make the component appear or disappear.
Am I missing something here?
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import CssBaseline from '#material-ui/core/CssBaseline';
import Divider from '#material-ui/core/Divider';
import Drawer from '#material-ui/core/Drawer';
import Hidden from '#material-ui/core/Hidden';
import IconButton from '#material-ui/core/IconButton';
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 DashboardIcon from '#material-ui/icons/Dashboard';
import MenuIcon from '#material-ui/icons/Menu';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import { makeStyles, useTheme, Theme, createStyles } from '#material-ui/core/styles';
import { User } from './User';
import { Draw } from "components/Layout/Countryballs/Draw";
const drawerWidth = 240;
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex',
color: '#fff',
},
drawer: {
[theme.breakpoints.up('sm')]: {
width: drawerWidth,
flexShrink: 0,
},
},
appBar: {
marginLeft: drawerWidth,
[theme.breakpoints.up('sm')]: {
width: `calc(100% - ${drawerWidth}px)`,
},
},
menuButton: {
marginRight: theme.spacing(2),
[theme.breakpoints.up('sm')]: {
display: 'none',
},
},
toolbar: theme.mixins.toolbar,
drawerPaper: {
width: drawerWidth,
backgroundColor: theme.palette.primary.main
},
content: {
flexGrow: 1,
},
menuItem: {
color: '#fff',
},
}),
);
export const Layout: React.FC<LayoutProps> = (props) => {
const { container } = props;
const classes = useStyles();
const theme = useTheme();
const [mobileOpen, setMobileOpen] = React.useState(false);
function handleDrawerToggle() {
setMobileOpen(!mobileOpen);
}
// Display Draw component
// 1 Create property
var drawHelper: Boolean = false;
function toggleDraw() {
console.log(drawHelper);
drawHelper = !drawHelper;
}
const drawer = (
<div>
<div className={classes.toolbar} />
<Divider />
<List>
{['Draw'].map((text) => (
<ListItem button key={text} onClick={toggleDraw} className={classes.menuItem}>
<ListItemIcon className={classes.menuItem}><DashboardIcon /></ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</div>
);
return (
<div className={classes.root}>
<CssBaseline />
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Project name
</Typography>
<User/>
</Toolbar>
</AppBar>
<nav className={classes.drawer} aria-label="mailbox folders">
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
<Hidden smUp implementation="css">
<Drawer // this one is for mobile
container={container}
variant="temporary"
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer // This one is for desktop
classes={{
paper: classes.drawerPaper,
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
</nav>
<main className={classes.content}>
{/* This is where my components renders */}
{
drawHelper === true && (<Draw/>)
}
<div className={classes.toolbar} />
{props.children}
</main>
</div>
);
}
The variable drawHelper in your code is instantiated on every render. You'd want to use React's state to make sure your drawHelper's value is preserved on the next re-renders.
const [drawHelper, toggleDrawHelper] = React.useState(false)
function toggleDraw() {
toggleDrawHelper(!drawHelper);
}

Change style of children in MaterialUI only in one element

I am using <ListItemIcon/> from Material-UI. In one component I use two different Icons and I want them to be different sizes and other styles in general. <ListItemIcon/> is build with svg which has class name MuiSvgIcon-root - this is where I should change the fontSize of Icon. I dont know how to do it. When I do
const useStyles = makeStyles({
root:{
fontSize: "2rem"
}
},{name: 'MuiSvgIcon'});
It changes setting for every Icon size in my project.
My component
function Section(props) {
const classes = useStyles();
const { title, listInfo, icon, gridSize } = props;
return (
<List>
<ListItem>
<ListItemIcon >{icon}</ListItemIcon> //here icon bigger
<ListItemText primary={title} />
</ListItem>
<Divider variant="middle" />
<Grid container>
{listInfo.map((item, index) => {
return (
<Grid item xs={gridSize}>
<ListItem key={index}>
<ListItemIcon>
<Brightness1Icon /> //here icon smaller
</ListItemIcon>
<ListItemText
primary={item.primaryText}
secondary={item.secondaryText}
/>
</ListItem>
</Grid>
);
})}
</Grid>
</List>
);
}
By specifying name: 'MuiSvgIcon' in your makeStyles call, you are causing Material-UI to override the global MuiSvgIcon-root class. If you use the name option in makeStyles, you should never give it a Mui name since these are treated differently and intended for use within the library code.
Below is one way to customize the icon size:
const BiggerListItemIcon = withStyles({
root: {
"& .MuiSvgIcon-root": { fontSize: "2em" }
}
})(ListItemIcon);
This can then be used as in the following example:
import React from "react";
import { makeStyles, 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 InboxIcon from "#material-ui/icons/Inbox";
import DraftsIcon from "#material-ui/icons/Drafts";
const useStyles = makeStyles(theme => ({
root: {
width: "100%",
maxWidth: 360,
backgroundColor: theme.palette.background.paper
}
}));
const BiggerListItemIcon = withStyles({
root: {
"& .MuiSvgIcon-root": { fontSize: "2em" }
}
})(ListItemIcon);
export default function SimpleList() {
const classes = useStyles();
return (
<div className={classes.root}>
<List component="nav" aria-label="main mailbox folders">
<ListItem button>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Inbox" />
</ListItem>
<ListItem button>
<BiggerListItemIcon>
<DraftsIcon />
</BiggerListItemIcon>
<ListItemText primary="Drafts" />
</ListItem>
</List>
</div>
);
}
There are many ways to do styling with material-ui, I won't say this is the best way, but personally it is my own favorite way
import { styled } from "#material-ui";
const Section = () => {
return (
...
<SmallerListItemIcon>
<Brightness1Icon />
</SmallerListItemIcon>
...
)
}
const SmallerListItemIcon = styled(ListItemIcon)({
fontSize: "<your size here>"
});

how to create a space between list items in React material

I learn React Material and I want to have space between each row in React Material List but I cant figure out how to do that.
I read trough the Material docs but cant figure this out because im a newbee
I try something like this:
<li className="list-group-item" key={el.id}>
{el.title}
</li>
Using the list-group-item because it works on another list but dont work now.
Picture of two list row that dont have vertical space between
import React, { Component } from 'react';
import { Grid, Paper, Typography } from "#material-ui/core";
import Card from "#material-ui/core/Card";
import CardActionArea from "#material-ui/core/CardActionArea";
import CardActions from "#material-ui/core/CardActions";
import CardContent from "#material-ui/core/CardContent";
import CardMedia from "#material-ui/core/CardMedia";
import Button from "#material-ui/core/Button";
import { connect } from "react-redux";
import { makeStyles } from '#material-ui/core/styles';
import List from '#material-ui/core/List';
import ListItem from '#material-ui/core/ListItem';
import ListItemText from '#material-ui/core/ListItemText';
import ListItemAvatar from '#material-ui/core/ListItemAvatar';
import Avatar from '#material-ui/core/Avatar';
import ImageIcon from '#material-ui/icons/Image';
import WorkIcon from '#material-ui/icons/Work';
import BeachAccessIcon from '#material-ui/icons/BeachAccess';
import Divider from '#material-ui/core/Divider';
import { withStyles } from '#material-ui/styles';
const styles = theme => ({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
padding: '0 30px',
},
});
export class Posts extends Component {
constructor() {
super();
}
componentDidUpdate(prevProps) {
}
render() {
const { classes } = this.props;
return (
<ul className="list-group list-group-flush">
{this.props.books.map(el => (
<List className={classes.root}>
<ListItem>
<ListItemText primary="Title" secondary={el.title} />
</ListItem>
<Divider variant="middle" component="li" />
<ListItem>
<ListItemText primary="Author" secondary={el.author} />
</ListItem>
<Divider variant="middle" component="li" />
<ListItem>
<ListItemText primary="Genre" secondary={el.genre} />
</ListItem>
<Divider variant="middle" component="li" />
<ListItem>
<ListItemText primary="Price" secondary={el.price} />
</ListItem>
</List>
))}
</ul>
);
}
}
function mapStateToProps(state) {
return {
books: state.reducer.booksList
}
}
export default connect(mapStateToProps)(withStyles(styles)(Posts));
Here is a row in the list:
<book id="13543">
<author>Roger, more</author>
<title>Helping hand club</title>
<genre>Space</genre>
<price>234.00</price>
</book>
You can do this using CSS,
const styles = theme => ({
root: {
//Your existing styles
margin: 5px 0;
},
});

Resources