How to align primary and secondary text horizontally and not vertically with Material-UI? - material-ui

I have this code:
import React from 'react';
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 ArrowForwardIos from '#material-ui/icons/ArrowForwardIos';
import ListSubheader from '#material-ui/core/ListSubheader';
import Switch from '#material-ui/core/Switch';
import TextField from '#material-ui/core/TextField';
import ListItemAvatar from '#material-ui/core/ListItemAvatar';
import Avatar from '#material-ui/core/Avatar';
import FolderIcon from '#material-ui/icons/Folder';
import ListItemSecondaryAction from '#material-ui/core/ListItemSecondaryAction';
import DeleteIcon from '#material-ui/icons/Delete';
import IconButton from '#material-ui/core/IconButton';
function App() {
return (
<ListItem>
<ListItemAvatar>
<Avatar>
<FolderIcon />
</Avatar>
</ListItemAvatar>
<ListItemText
primary="Single-line item"
secondary="Secondary text"
/>
<ListItemSecondaryAction>
<IconButton edge="end" aria-label="delete">
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
);
}
export default App;
"Single-line item" and "Secondary text" is vertically aligned, but I need align it horizontally. Do you have any idea how to do it?
Instead of left I need rendering on the right here:
https://gitlab.com/j4nos/tableitem/blob/master/src/App.js
How? :)

I managed to get the desired output using a few other elements and referring the material-ui documentation. here is a working example: https://codesandbox.io/s/sweet-bose-4e26h
function App() {
return (
<ListItem>
<ListItemAvatar>
<Avatar>
<FolderIcon />
</Avatar>
</ListItemAvatar>
<Box
textAlign="right"
style={{ paddingRight: 5 }}
>
Single-line item
</Box>
<ListItemText
secondaryTypographyProps={{ align: "left" }}
secondary="Secondary text"
/>
<ListItemSecondaryAction>
<IconButton edge="end" aria-label="delete">
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
);
}

Alternative using Material-UI's built-in overrides on ListItemText.classes.root as seen below:
<ListItem className={classes.listItem}>
<ListItemText
classes={{ root: classes.listItemRootOverride }}
className={classes.listText}
primary={`${tc('Foo')}:`}
/>
<ListItemText
classes={{ root: classes.listItemRootOverride }}
secondary={bars}
/>
</ListItem>
Classes in useStyles:
listItemRootOverride: { /* this is the important one */
flex: 'none',
paddingRight: 4
},
listItem: {
padding: theme.spacing(0)
},
listText: {
color: theme.palette.common.black,
paddingRight: theme.spacing(2)
}
Example output (disregard minor alignment issue):

Related

How can I add linear-gradient to my Material-UI (v5.11.5) background

I have an Appbar that has a fixed colour background that has been applied using the createTheme module for material-ui. I have been asked to apply a linear gradient for a transitioning color effect to the Appbar. I have tried using palette: {
background: {
paper: '-webkit-linear-gradient(to left, #30e8bf, #ff8235)',
}, in my createTheme then using sx={{ bgcolor: 'background.paper' }} in my Appbar.
Any suggestion to changes I need to make ?
import * as React from 'react'
import AppBar from '#mui/material/AppBar'
import Box from '#mui/material/Box'
import Toolbar from '#mui/material/Toolbar'
import Stack from '#mui/material/Stack'
import Button from '#mui/material/Button'
import Tabs from '#mui/material/Tabs'
import Tab from '#mui/material/Tab'
import Typography from '#mui/material/Typography'
import IconButton from '#mui/material/IconButton'
import MenuIcon from '#mui/icons-material/Menu'
import AccountCircle from '#mui/icons-material/AccountCircle'
import Switch from '#mui/material/Switch'
import FormControlLabel from '#mui/material/FormControlLabel'
import FormGroup from '#mui/material/FormGroup'
import MenuItem from '#mui/material/MenuItem'
import Menu from '#mui/material/Menu'
import CssBaseline from '#mui/material/CssBaseline'
import { ThemeProvider, createTheme } from '#mui/material/styles'
import Chip from '#mui/material/Chip'
import Check from '#mui/icons-material/Check'
const finalTheme = createTheme({
components: {
// Name of the component
MuiButton: {
styleOverrides: {
// Name of the slot
root: {
// Some CSS
fontSize: '3rem',
backgroundColor: '#fff',
},
},
},
},
typography: {
// In Chinese and Japanese the characters are usually larger,
// so a smaller fontsize may be appropriate.
fontSize: 15,
},
palette: {
background: {
paper: '-webkit-linear-gradient(to left, #30e8bf, #ff8235)',
},
},
})
export default function NavBar() {
const [auth, setAuth] = React.useState(true)
const [anchorEl, setAnchorEl] = React.useState(null)
const [value, setValue] = React.useState('apple')
const handleChange = (event) => {
setAuth(event.target.checked)
}
const handleMenu = (event) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}
return (
<React.StrictMode>
<Box sx={{ flexGrow: 1 }}>
<ThemeProvider theme={finalTheme}>
<AppBar position="static" sx={{ bgcolor: 'background.paper' }}>
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" component="div" sx={{ flexGrow: 1 }} />
<Tab value="0" label="Sessions" />
<Tab value="1" label="Gallery" />
<Tab value="2" label="About Us" />
{auth && (
<div>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleMenu}
color="inherit"
>
<AccountCircle />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
</Menu>
</div>
)}
</Toolbar>
</AppBar>
</ThemeProvider>
</Box>
</React.StrictMode>
)
}

React material-ui AvatarGroup rounded shape for extra child

How can I control the shape of the extra item that is appended to a React Material-UI AvatarGroup (when the number of Avatars is more than max) so that it matches the rounded variant of the Avatars.
<AvatarGroup max={4}>
<Avatar
variant="rounded"
alt="Remy Sharp"
src="/static/images/avatar/1.jpg"
/>
<Avatar
variant="rounded"
alt="Travis Howard"
src="/static/images/avatar/2.jpg"
/>
<Avatar
variant="rounded"
alt="Cindy Baker"
src="/static/images/avatar/3.jpg"
/>
<Avatar
variant="rounded"
alt="Agnes Walker"
src="/static/images/avatar/4.jpg"
/>
<Avatar
variant="rounded"
alt="Trevor Henderson"
src="/static/images/avatar/5.jpg"
/>
</AvatarGroup>
API doc doesn't mention how to set this: https://material-ui.com/api/avatar-group/
Although the "next" version does: https://next.material-ui.com/es/api/avatar-group/
You can override the shape's style using a mui global class selectors:
import React from "react";
import Avatar from "#material-ui/core/Avatar";
import AvatarGroup from "#material-ui/lab/AvatarGroup";
import { createStyles, makeStyles, Theme } from "#material-ui/core/styles";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
"& .MuiAvatar-root": { borderRadius: 0 }
}
})
);
export default function GroupAvatars() {
const classes = useStyles();
return (
<AvatarGroup max={4} className={classes.root}>
<Avatar
alt="Remy Sharp"
variant="rounded"
src="/static/images/avatar/1.jpg"
/>
<Avatar
alt="Travis Howard"
variant="rounded"
src="/static/images/avatar/2.jpg"
/>
<Avatar
alt="Cindy Baker"
variant="rounded"
src="/static/images/avatar/3.jpg"
/>
<Avatar
alt="Agnes Walker"
variant="rounded"
src="/static/images/avatar/4.jpg"
/>
<Avatar
alt="Trevor Henderson"
variant="rounded"
src="/static/images/avatar/5.jpg"
/>
</AvatarGroup>
);
}
please find a working example on codesandbox

How to remove default padding from material ui List Item?

Material ui add default padding on List and ListItem how to remove it ?
Any help or direction to resources would be appreciated.
You can override the root class of the ListItem component and pass the padding you want.
const styles = theme => ({
root: {
width: "100%",
maxWidth: 360,
backgroundColor: theme.palette.background.paper
},
item: {
padding: 0
}
});
function SimpleList(props) {
const { classes } = props;
return (
<div className={classes.root}>
<List component="nav">
<ListItem button classes={{ root: classes.item }}>
<ListItemText primary="Item 01" />
</ListItem>
<ListItem button classes={{ root: classes.item }}>
<ListItemText primary="Item 02" />
</ListItem>
<ListItem button classes={{ root: classes.item }}>
<ListItemText primary="Item 03" />
</ListItem>
</List>
</div>
);
}
See working sample.
For anyone else coming here the easy way to remove the default padding from the list is to use the disablePadding prop on the List Component.
https://material-ui.com/api/list/
import React from 'react'
import List from '#material-ui/core/List'
import ListItem from '#material-ui/core/ListItem'
import ListItemText from '#material-ui/core/ListItemText'
function Sidebar() {
return (
<List disablePadding>
<ListItem button>
<ListItemText>Home</ListItemText>
</ListItem>
<ListItem button>
<ListItemText>Billing</ListItemText>
</ListItem>
<ListItem button>
<ListItemText>Settings</ListItemText>
</ListItem>
</List>
)
}
export default Sidebar
If you're just using a ListItem component, you can use the disableGutters (Boolean) property to disable the left and right padding, as seen from the API documentation: https://material-ui.com/api/list-item/
<ListItem disableGutters={true} button={true} key='Home' component={Link} to={"/"} selected={'/' === pathname}>
<ListItemIcon><Home /></ListItemIcon>
<ListItemText primary='Home' />
</ListItem>

RadioButtonGroup within nested List

I'm using Material-UI and I'd like to use the List/ListItem Component to group my Radio Buttons.
Similar to this one:
<RadioButtonGroup ...>
<List>
<ListItem
...
nestedItems={[
<RadioButton ... />,
<RadioButton ... />
]}
/>
<ListItem
...
nestedItems={[
<RadioButton ... />,
<RadioButton ... />
]}
/>
</List>
</RadioButtonGroup>
Is there a way to archive this?
Thanks.
My temporary workaround is to use checkboxes which look and behave like radio buttons.
import List from 'material-ui/lib/lists/list';
import ListItem from 'material-ui/lib/lists/list-item';
import Checkbox from 'material-ui/lib/checkbox';
import RadioChecked from 'material-ui/lib/svg-icons/toggle/radio-button-checked';
import RadioUnchecked from 'material-ui/lib/svg-icons/toggle/radio-button-unchecked';
...
onChangeRadio = (event) => this.setState({ radioValue: event.target.value });
...
<List>
<ListItem
primaryText='First Group'
primaryTogglesNestedList={true}
nestedItems={[
<ListItem
primaryText='Radio 1'
leftCheckbox={
<Checkbox
value='1'
onCheck={this.onChangeRadio}
checked={this.state.radioValue == '1'}
checkedIcon={<RadioChecked />}
unCheckedIcon={<RadioUnchecked />}
/>
}
/>
<ListItem
primaryText='Radio 2'
leftCheckbox={
<Checkbox
value='2'
onCheck={this.onChangeRadio}
checked={this.state.radioValue == '2'}
checkedIcon={<RadioChecked />}
unCheckedIcon={<RadioUnchecked />}
/>}
/>
]}
/>
<ListItem
primaryText='Second Group'
primaryTogglesNestedList={true}
nestedItems={[
<ListItem
primaryText='Radio 3'
leftCheckbox={
<Checkbox
value='3'
onCheck={this.onChangeRadio}
checked={this.state.radioValue == '3'}
checkedIcon={<RadioChecked />}
unCheckedIcon={<RadioUnchecked />}
/>
}
/>
<ListItem
primaryText='Radio 4'
leftCheckbox={
<Checkbox
value='4'
onCheck={this.onChangeRadio}
checked={this.state.radioValue == '4'}
checkedIcon={<RadioChecked />}
unCheckedIcon={<RadioUnchecked />}
/>
}
/>
]}
/>
</List>
I hope there is a better solution than this.
Maybe this will help
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 ListItemSecondaryAction from '#material-ui/core/ListItemSecondaryAction';
import ListItemText from '#material-ui/core/ListItemText';
import Checkbox from '#material-ui/core/Checkbox';
import IconButton from '#material-ui/core/IconButton';
import CommentIcon from '#material-ui/icons/Comment';
import Radio from '#material-ui/core/Radio';
import RadioGroup from '#material-ui/core/RadioGroup';
import FormHelperText from '#material-ui/core/FormHelperText';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import FormControl from '#material-ui/core/FormControl';
import FormLabel from '#material-ui/core/FormLabel';
const styles = theme => ({
root: {
width: '100%',
maxWidth: 360,
overflow: 'auto',
maxHeight: 500,
backgroundColor: theme.palette.background.paper,
},
});
class RadioList extends React.Component {
state = {
checked: 0,
};
handleToggle = value => () => {
this.setState({ checked: value });
};
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<List>
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(value => (
<ListItem
key={value}
role={undefined}
dense
button
onClick={this.handleToggle(value)}
className={classes.listItem}
>
<FormControlLabel control={<Radio />}
checked={this.state.checked === value}
tabIndex={-1}
disableRipple
/>
<ListItemText primary={`Line item ${value + 1}`} />
</ListItem>
))}
</List>
</div>
);
}
}
RadioList.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(RadioList);

Adjusting the gap between svg icon and text on Material-UI's List component

I've been trying to figure out how to lessen the gap using css with no luck. I created the style object and used leftPosition key but the result was not the one I expected. I was expecting that the text is the only thing that will move. However, if you look at the screenshot specifically the first menu, the icon also moved. What I'd like to achieve is reduce the gap between the svn icon and the text.
import React from 'react';
import List from 'material-ui/lib/lists/list';
import ListItem from 'material-ui/lib/lists/list-item';
import ActionGrade from 'material-ui/lib/svg-icons/action/grade';
import ActionInfo from 'material-ui/lib/svg-icons/action/info';
import ContentInbox from 'material-ui/lib/svg-icons/content/inbox';
import ContentDrafts from 'material-ui/lib/svg-icons/content/drafts';
import ContentSend from 'material-ui/lib/svg-icons/content/send';
import Divider from 'material-ui/lib/divider';
import Assignment from 'material-ui/lib/svg-icons/action/assignment';
import Settings from 'material-ui/lib/svg-icons/action/settings';
import ManageDB from 'material-ui/lib/svg-icons/content/unarchive';
const style = {
menu: {
marginRight: 32,
marginBottom: 32,
float: 'left',
position: 'relative',
zIndex: 0,
width: 235,
},
rightIcon: {
textAlign: 'center',
lineHeight: '24px',
},
width: {
width: 235
},
leftPosition: {
left: 50
}
};
const LeftNavigation = () => (
<div>
<List>
<ListItem style={style.leftPosition} primaryText="Logs" leftIcon={<Assignment />} />
<ListItem primaryText="Manage DB" leftIcon={<ManageDB style={style.gap}/>} />
<ListItem primaryText="Top Issues" leftIcon={<ContentSend style={style.gap}/>} />
<ListItem primaryText="Settings" leftIcon={<Settings style={style.gap}/>} />
<ListItem primaryText="Logout" leftIcon={<ContentInbox style={style.gap}/>} />
</List>
<Divider />
<List>
<ListItem primaryText="All mail" rightIcon={<ActionInfo />} />
<ListItem primaryText="Trash" rightIcon={<ActionInfo />} />
<ListItem primaryText="Spam" rightIcon={<ActionInfo />} />
<ListItem primaryText="Follow up" rightIcon={<ActionInfo />} />
</List>
</div>
);
export default LeftNavigation;
The accepted solution didn't work for me. Here is what I ended up doing after exploring the DOM.
const useStyles = makeStyles((theme) => ({
icon: {
minWidth: '30px',
}
}));
and then apply this class for the ListItemIcon as:
<ListItemIcon className={classes.icon}> <HelpOutlineIcon/> </ListItemIcon>
Hope it helps someone save time.
You can add style in ListItemIcon.
<ListItemIcon style={{minWidth: '40px'}} >
This is what worked for me. I set this in my global css file.
.MuiListItemIcon-root {
min-width: 40px !important;
}
If you want to do it globally use overrides in createMuiTheme
const theme = createMuiTheme({
overrides: {
MuiListItemIcon: {
root: {
minWidth: 40,
},
},
},
})
Note:
If you're using MUI version 5 then locate createTheme instead of createMuiTheme
This is my 2¢:
<ListItemText primary={<div style={{ margin: -25, marginTop: -7, color: 'white', fontSize: 11 }}>Your text here</div>} />
Adjusting margin (n.b., it's a negative number) and the top margin you can align the icon (on the left) with your text
You can also use sx prop instead of style, if you want access to the theme object, e.g.:
<ListItemIcon sx={{minWidth: (theme) => theme.spacing(4)}}>
This is only applicable to Mui 1.x.x. For later versions, please see responses to this answer below.
The ListItem renders a div called innerDiv with 72px left/right padding to render the left/right icon and label with sufficient space. You should try this in the Style -
<ListItem innerDivStyle={{paddingLeft: 60}} primaryText="Logs" leftIcon={<Assignment />} />
Replace 60 with whatever pleases you.
Just information for #Adam Mańkowski 's answer.
In MUI v5.5, you can config your theme like this.
createTheme({
components: {
MuiListItemIcon: {
styleOverrides: {
root: {
minWidth: 0
}
}
}
}
});