3
votes

Avoir deux éléments d'action secondaires dans une liste

J'ai créé une liste dans react qui a la structure suivante:

  • Avatar
  • Texte
  • Modifier l'icône
  • Supprimer l'icône

J'ai créé la structure bien jusqu'à l'icône de suppression. Comment puis-je ajouter cela? Actuellement, il chevauche l'icône d'édition car les deux sont ListItemSecondaryAction mais je ne trouve pas dans la documentation comment ajouter un objet supplémentaire et comment il doit être appelé? https://material-ui.com/components/lists/

Implémentation actuelle:

<List>
    <ListItemAvatar>
        <Avatar src="image" />
    </ListItemAvatar>
    <ListItemText primary="name" />
    <ListItemSecondaryAction>
        <IconButton>
            <EditIcon />
        </IconButton>
    </ListItemSecondaryAction>
    <ListItemSecondaryAction>
        <IconButton>
            <DeleteIcon />
        </IconButton>
    </ListItemSecondaryAction>
</List>

entrez la description de l'image ici


2 commentaires

créer un stackblitz de ceci afin que nous puissions jouer et trouver une réponse


pouvez-vous simplement faire une seule ListItemSecondaryAction et modifier et supprimer à la fois l'intérieur de celle-ci, comme "<ListItemSecondaryAction> <IconButton> <EditIcon /> </IconButton> <IconButton> <DeleteIcon/></IconButton> </ListItemSecondaryAction>"


3 Réponses :


1
votes

J'ai essayé d'afficher deux icônes de suppression l'une à côté de l'autre en utilisant ce code HTML:

<ListItemSecondaryAction>
    <IconButton edge="end" aria-label="delete">
        <DeleteIcon />
    </IconButton>
    <IconButton>
        <DeleteIcon />
    </IconButton>
</ListItemSecondaryAction>

Donc, utilisez simplement un ListItemSecondaryAction et imbriquez des icônes à l'intérieur.


1 commentaires

Cela ne fonctionne pas, car ListItemText n'obtient un remplissage que pour une seule icône, lorsqu'il y a une action secondaire



2
votes

Il suffit presque de placer les deux actions dans un ListItemSecondaryAction (comme indiqué par des commentaires et une autre réponse). Le seul problème est que si vous avez un contenu long, il chevauchera la première icône.

Voici les styles de l'action secondaire de ListItem :

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>
    </>
  );
}

Le paddingRight: 48 ne sera pas suffisant pour deux icônes. Vous pouvez le personnaliser comme suit:

const ListItemWithWiderSecondaryAction = withStyles({
  secondaryAction: {
    paddingRight: 96
  }
})(ListItem);

Voici un exemple de travail complet (basé sur l'une des démos) qui montre les deux premiers éléments de la liste sans cette personnalisation (donc un chevauchement se produit) et les deux seconds avec le correctif:

  /* Styles applied to the `component` element if `children` includes `ListItemSecondaryAction`. */
  secondaryAction: {
    // Add some space to avoid collision as `ListItemSecondaryAction`
    // is absolutely positioned.
    paddingRight: 48,
  },

Modifier l'action secondaire plus large


0 commentaires

0
votes

J'ai entièrement supprimé ListItemSecondaryAction et l'ai remplacé par ListItemIcon , donc maintenant le code ressemble à ceci:

<ListItem>
    <ListItemAvatar>
        <Avatar src="image" />
    </ListItemAvatar>
    <ListItemText primary="name" />
    <ListItemIcon>
        <IconButton>
            <EditIcon />
        </IconButton>
    </ListItemIcon>
    <ListItemIcon>
        <IconButton>
            <DeleteIcon />
        </IconButton>
    </ListItemIcon>
</ListItem>


0 commentaires