Элементы не обрабатывают событие, когда отображается всплывающее окно Material-ui - PullRequest
1 голос
/ 21 февраля 2020

У меня есть простой материал-пользовательский интерфейс List, содержащий ListItem элементов.

Я хочу, чтобы Popover появлялся рядом с любым ListItem, на который я помещаю мышь. Для этого я использую событие mouseEnter. В его обработчике я установил элемент привязки из Popover равным ListItem, над которым в данный момент находится указатель мыши.

Это отлично работает для первого элемента, над которым я наведите курсор мыши. , Однако из-за того, что Popover по существу ведет себя как "модальный" тип, когда я перехожу к другому ListItem в Списке, его событие mouseEnter не срабатывает.

Я занимаюсь этим уже несколько часов и не могу найти способ обойти это?

Вот CodeSandbox. Попробуйте навести курсор на одну из ListItem s, и вы увидите вывод в консоли. Попробуйте перейти к другому, и ничего не происходит.

Edit loving-currying-zpw8y

import React, { useState } from "react";
import "./styles.css";
import { List, ListItem, ListItemText, Popover } from "@material-ui/core";

export default function App() {
  const [popoverAnchorElement, setPopoverAnchorElement] = useState(null);
  const handleMouseEnter = event => {
    console.log("onMouseEnter - " + event.currentTarget.textContent);
    setPopoverAnchorElement(event.currentTarget);
  };

  const handleClose = (event, index) => {
    setPopoverAnchorElement(null);
  };

  let isPopoverOpen = Boolean(popoverAnchorElement);
  return (
    <div className="App">
      <List style={{ maxWidth: "100px" }}>
        <ListItem button>
          <ListItemText onMouseEnter={handleMouseEnter}>ListItem1</ListItemText>
        </ListItem>
        <ListItem button>
          <ListItemText onMouseEnter={handleMouseEnter}>ListItem2</ListItemText>
        </ListItem>
        <ListItem button>
          <ListItemText onMouseEnter={handleMouseEnter}>ListItem3</ListItemText>
        </ListItem>
      </List>
      <Popover
        open={isPopoverOpen}
        onClose={handleClose}
        anchorEl={popoverAnchorElement}
        anchorOrigin={{
          vertical: "top",
          horizontal: "center"
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "left"
        }}
      >
        <ListItem button>
          <ListItemText>ListItemInPopover</ListItemText>
        </ListItem>
      </Popover>
    </div>
  );
}


1 Ответ

1 голос
/ 21 февраля 2020

Компонент Popover перекрывает весь экран (position:fixed; left:0; top:0; right:0; bottom:0; z-index:1300), эффективно блокируя любые события мыши от нижних элементов.

Вы можете попытаться обойти это, например, добавив pointer-events:none; к своему элементу наложения позволил бы событиям курсора проходить через него.

Но использование компонента, блокирующего весь видовой экран только для небольшого пункта меню, кажется мне странным и, вероятно, тяжелым сражением.

Существует аналогичный компонент в той же библиотеке под названием Popper, который, вероятно, больше соответствует вашим потребностям. Здесь вы можете видеть, что я преобразовал ваш Popover в Popper, и вы получите результаты, немного больше, чем вы ожидаете. (Обратите внимание, что я добавил немного CSS к этому элементу в изолированной программной среде кода, чтобы сделать его более понятным.)

  <Popper
    open={isPopoverOpen}
    onClose={handleClose}
    anchorEl={popoverAnchorElement}
    className="popper-item"
  >
    <ListItem button>
      <ListItemText>ListItemInPopover</ListItemText>
    </ListItem>
  </Popper>

https://codesandbox.io/s/keen-smoke-x8tu7

Я отмечу, что В документации отмечается, что Popper не будет автоматически закрываться, если вы щелкнете по этим элементам, но это можно добавить.

Вы также можете заглянуть в компонент MenuList, который использует Popper под капотом. но также обрабатывает некоторое состояние для вас.

...