React / MUI Popover позиционируется неправильно с anchorPosition - PullRequest
1 голос
/ 20 мая 2019

Я использую всплывающее окно React / MUI внутри реагирующего окна Элемент списка и не могу правильно установить Popover - он всегда оказывается в левом верхнем углу окна (компонент не может выполнить getBoundingClientRctd () для элемента привязки [anchorEl в документах]).

Поэтому, чтобы временно обойти эту проблему, я решил использовать параметр anchorPosition, который позволяетустановить абсолютную позицию - в моем случае, просто середина окна.Это тоже не работает.

Я просмотрел значения в Chrome DevTools, и все вроде бы нормально (т.е. я получаю anchorEl, когда использую это; я получаю действительные значения positionLeft / Top; и т. Д....

Возможно, что-то действительно простое и надеется, что кто-то укажет, что я сделал не так.

Отредактировано: ключевые элементы решения

  1. Row компонент должен быть определен за пределами содержащего его компонента.
  2. компонент <List> имеет атрибут itemData, который используется для передачи пользовательских данных в Row.

Отредактировано для добавления окна вывода окна реакции.

Вот основные настройки:

Средство визуализации Popover

  renderPopover(template, itemId) {
    const { anchorEl, anchorId } = this.state;
    const { classes } = this.props;
    const open = Boolean(anchorEl) && anchorId === itemId;
    const bgColor = '#babaef';
    const { innerHeight, innerWidth } = window;
    const positionLeft = innerWidth / 2;
    const positionTop = innerHeight / 2;
    console.log(`renderPopover: ${positionLeft} / ${positionTop}`);
      <Popover
        id="simple-popper"
        open={open}
        style={{ color: 'Black' }}
        anchorEl={anchorEl}
        onClose={event => this.handlePopoverClose(event)}
        anchorPosition={{ left: {positionLeft}, top: {positionTop} }}
        anchorReference="anchorPosition"
      >
        <Typography style={{ backgroundColor: bgColor }} className={classes.typography}>
          {this.renderScheduleElements(template, itemId)}
        </Typography>
      </Popover>
    );
  }

Средство визуализации элементов кнопки

 renderScheduleComponent(template, itemId) {
    const { anchorEl, anchorId } = this.state;
    const open = Boolean(anchorEl) && anchorId === itemId;
    const { classes } = this.props;
    const id = open ? 'simple-popper' : undefined;
    return (
      <Grid key={itemId} item>
        <Paper className={classes.paper}>
          <div style={{ padding: '4px' }}>
            <Button
              NO_ref={itemId}
              NODE_ref={(node) => this.buttonRef = node}
              id={itemId}
              name={itemId}
              aria-owns={id}
              aria-haspopup="true"
              variant="outlined"
              color="primary"
              style={{
                fontWeight: 'bold',
                padding: '8px',
                margin: 'auto',
                display: 'block',
                width: '100%',
              }}
              onClick={event => this.handlePopoverClick(event, itemId)}
            >
              {template.templateName}
            </Button>
            {(this.renderPopover).call(this, template, itemId)}
          </div>
        </Paper>
      </Grid>
    );
  }

Обработчик событий клика

  handlePopoverClick(event, id) {
  event.preventDefault();
    console.log(`handlePopoverClick : ${event.currentTarget.name}`);
    this.setState({
      anchorEl: event.currentTarget,
      anchorId: id,
    });
  }

рендеринг списка окна реакции

  renderScheduleColumn(columnData) {
    const { classes } = this.props;
    const { scheduleDate, scheduleTemplates } = columnData;
    this.scheduleTemplates = scheduleTemplates;

    const Row = ({ index, style }) => {
      return (
        <div className={index % 2 ? "ListItemOdd" : "ListItemEven"} style={style}>
          {this.renderScheduleComponent(scheduleTemplates[index], `${scheduleDate}:${index}`)}
        </div>
      );
    }

    const { columnHeight, columnWidth } = this.state;
    return (
      <Grid id={scheduleDate} key={scheduleDate} item>
        <Paper className={classes.paper}>
          <div style={{ width: '100%', textAlign: 'center' }}>
            <Typography variant="h6" style={{ padding: '24px', color: 'white', backgroundColor: '#3f51b5' }}>
              {scheduleDate}
            </Typography>
          </div>
          <List
            className="List"
            height={columnHeight}
            itemCount={scheduleTemplates.length}
            itemSize={50}
            width={columnWidth}
          >
            {Row}
          </List>
        </Paper>
      </Grid>
    );
  }

1 Ответ

0 голосов
/ 21 мая 2019

Это похоже на проблему, аналогичную следующей: Якорь меню React Material-UI, сломанный списком реагирующих окон .

Вы должны переместить определение вашей функции Row изrenderScheduleColumn так что это согласованный тип.Это также потребует перемещения / переделки renderScheduleComponent.Вы можете использовать свойство itemData в Списке для передачи информации в Строку.

...