Условно показывать всплывающую подсказку в зависимости от того, открыт ли родительский компонент Popper

#reactjs #react-hooks #material-ui #tooltip #popper.js

#reactjs #реагирующие крючки #материал-пользовательский интерфейс #всплывающая подсказка #popper.js

Вопрос:

Я пытаюсь понять наилучший способ условного отображения всплывающей подсказки в зависимости от того, открыт ли компонент-брат Popper или сестра или нет. Я хочу показывать его по умолчанию при наведении курсора мыши на его дочерний элемент ButtonBase . Я хочу, чтобы всплывающая подсказка никогда не была открыта, если Popper она открыта. Заголовок всплывающей подсказки действует как краткое изложение того, что выбрано в списке параметров в Popper, когда он закрыт, его открытие при открытом Popper не является идеальным и загроможденным. Я новичок в перехватах, поэтому пытаюсь понять, как я могу включить перехват, чтобы правильно установить состояние tooltipOpen с учетом условной необходимости.

 export default function TooltipWithPopper() {
  const classes = useStyles();
  const [anchorEl, setAnchorEl] = React.useState(null);
  const [value, setValue] = React.useState([options[1], options[11]]);
  const [pendingValue, setPendingValue] = React.useState([]);
  const [tooltipOpen, setTooltipOpen] = React.useState(false);

  const handleClick = (event) => {
    setPendingValue(value);
    setAnchorEl(event.currentTarget);
    setTooltipOpen(false);
  };

  const handleClose = (event, reason) => {
    if (reason === "toggleInput") {
      return;
    }
    setValue(pendingValue);
    if (anchorEl) {
      anchorEl.focus();
    }
    setAnchorEl(null);
  };

  const open = Boolean(anchorEl);
  const id = open ? "github-label" : undefined;

  return (
    <React.Fragment>
      <div className={classes.root}>
        <Tooltip title={value.map((i) => i.title).join(", ")}>
          <ButtonBase
            disableRipple
            className={classes.button}
            aria-describedby={id}
            onClick={handleClick}
          >
            <span>Label</span>
            {value.length}/{options.length}
          </ButtonBase>
        </Tooltip>
      </div>
      <Popper
        id={id}
        open={open}
        anchorEl={anchorEl}
        placement="bottom-start"
        className={classes.popper}
      >
        <Autocomplete
          open
          onClose={handleClose}
          multiple
          classes={{
            paper: classes.paper,
            option: classes.option,
            popperDisablePortal: classes.popperDisablePortal
          }}
          value={pendingValue}
          onChange={(event, newValue) => {
            setPendingValue(newValue);
          }}
          disableCloseOnSelect
          disablePortal
          renderTags={() => null}
          noOptionsText="No labels"
          .....
        />
      </Popper>
    </React.Fragment>
  );
}
  

Вот демонстрация всплывающей подсказки, применяемой к элементу триггера. Как я могу установить его открытым только в зависимости от состояния других компонентов? Я попытался добавить setTooltipOpen(false) вызов, когда handleClick вызывается при открытии Popper .

Демонстрация: https://codesandbox.io/s/material-demo-forked-0wgyh?file=/demo.js:0-6181

Ответ №1:

Вы можете управлять значением Tooltip open prop с помощью своего tooltipOpen состояния (реализация зависит от вас) и предоставлять условия, при которых, если Popper есть open , то автоматически Tooltip open вычисление значения prop будет игнорировать tooltipOpen состояние и присваивать false .

В моем примере ниже я контролирую tooltipOpen состояние с помощью onMouseEnter amp;amp; onMouseLeave событий

 <Tooltip
  open={open === true ? false : tooltipOpen}
  title={value.map((i) => i.title).join(", ")}
>
  <ButtonBase
    disableRipple
    className={classes.button}
    aria-describedby={id}
    onClick={handleClick}
    onMouseEnter={() => setOpen(true)}
    onMouseLeave={() => setOpen(false)}
  >
    <span>Label</span>
    {value.length}/{options.length}
  </ButtonBase>
</Tooltip>
  

Редактировать демонстрационный материал (разветвленный)