I have created a list in react which has the following structure:
I have created the structure fine until the delete icon. How can I add this? Currently, it is overlapping the edit icon as both are ListItemSecondaryAction
but I can't find on the documentation how to add an additional object and what it should be called? https://material-ui.com/components/lists/
Current implementation:
<List>
<ListItemAvatar>
<Avatar src="image" />
</ListItemAvatar>
<ListItemText primary="name" />
<ListItemSecondaryAction>
<IconButton>
<EditIcon />
</IconButton>
</ListItemSecondaryAction>
<ListItemSecondaryAction>
<IconButton>
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</List>
What seems to confuse people about secondary action is the word “action”. Secondary action is not so much physical as it is behavioral. The primary action of a scene is the thing the scene is about. It’s the action the character is manifestly trying to accomplish; it’s the main idea the of the story at that moment.
Good secondary action energizes your shots and marks the difference between being a competent animator and an entertaining visual storyteller. What seems to confuse people about secondary action is the word “action”. Secondary action is not so much physical as it is behavioral. The primary action of a scene is the thing the scene is about.
Secondary action is something else the character is doing, something on top of or in addition to the primary action. It is a behavior that enlivens the scene, adds nuance and authenticity. It also reveals character, hints at back story, and so on. In the best cases, it helps provide the subtext of the storytelling.
Above are two nice, back-to-back examples of secondary action by former-AM students (now mentors) Matt Garward and Mike Stern. The action with the filing cabinet and the folder in the first shot turns the administrative assistant character into someone real and sympathetic.
It is almost sufficient to just put both actions in one ListItemSecondaryAction
(as indicated by comments and another answer). The only issue is that if you have long content it will overlap the first icon.
Here are the styles for the secondary action from ListItem:
/* Styles applied to the `component` element if `children` includes `ListItemSecondaryAction`. */
secondaryAction: {
// Add some space to avoid collision as `ListItemSecondaryAction`
// is absolutely positioned.
paddingRight: 48,
},
The paddingRight: 48
will not be sufficient for two icons. You can customize this as follows:
const ListItemWithWiderSecondaryAction = withStyles({
secondaryAction: {
paddingRight: 96
}
})(ListItem);
Here is a full working example (based on one of the demos) that shows the first two list items without this customization (so overlap occurs) and the second two with the fix:
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 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 DeleteIcon from "@material-ui/icons/Delete";
const useStyles = makeStyles(theme => ({
root: {
width: "100%",
maxWidth: 360,
backgroundColor: theme.palette.background.paper
}
}));
const ListItemWithWiderSecondaryAction = withStyles({
secondaryAction: {
paddingRight: 96
}
})(ListItem);
export default function CheckboxList() {
const classes = useStyles();
const [checked, setChecked] = React.useState([0]);
const handleToggle = value => () => {
const currentIndex = checked.indexOf(value);
const newChecked = [...checked];
if (currentIndex === -1) {
newChecked.push(value);
} else {
newChecked.splice(currentIndex, 1);
}
setChecked(newChecked);
};
return (
<>
<List className={classes.root}>
{[0, 1].map(value => {
const labelId = `checkbox-list-label-${value}`;
return (
<ListItem
key={value}
role={undefined}
dense
button
onClick={handleToggle(value)}
>
<ListItemIcon>
<Checkbox
edge="start"
checked={checked.indexOf(value) !== -1}
tabIndex={-1}
disableRipple
inputProps={{ "aria-labelledby": labelId }}
/>
</ListItemIcon>
<ListItemText
id={labelId}
primary={`Line item ${value +
1} with some more text to make it longer`}
/>
<ListItemSecondaryAction>
<IconButton aria-label="comments">
<CommentIcon />
</IconButton>
<IconButton edge="end" aria-label="delete">
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
);
})}
</List>
<List className={classes.root}>
{[2, 3].map(value => {
const labelId = `checkbox-list-label-${value}`;
return (
<ListItemWithWiderSecondaryAction
key={value}
role={undefined}
dense
button
onClick={handleToggle(value)}
>
<ListItemIcon>
<Checkbox
edge="start"
checked={checked.indexOf(value) !== -1}
tabIndex={-1}
disableRipple
inputProps={{ "aria-labelledby": labelId }}
/>
</ListItemIcon>
<ListItemText
id={labelId}
primary={`Line item ${value +
1} with some more text to make it longer`}
/>
<ListItemSecondaryAction>
<IconButton aria-label="comments">
<CommentIcon />
</IconButton>
<IconButton edge="end" aria-label="delete">
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItemWithWiderSecondaryAction>
);
})}
</List>
</>
);
}
I removed ListItemSecondaryAction
entirely and replaced it with ListItemIcon
, so now the code looks something like this:
<ListItem>
<ListItemAvatar>
<Avatar src="image" />
</ListItemAvatar>
<ListItemText primary="name" />
<ListItemIcon>
<IconButton>
<EditIcon />
</IconButton>
</ListItemIcon>
<ListItemIcon>
<IconButton>
<DeleteIcon />
</IconButton>
</ListItemIcon>
</ListItem>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With