Пользовательский интерфейс материала Popper over TextField, как держать Popper открытым, если выбраны параметры Popper - PullRequest
0 голосов
/ 10 апреля 2020

Я использую пользовательский интерфейс React Material, и у меня есть текстовое поле, которое, если я сосредоточусь на нем, развернет Popper с простым меню. Если текстовое поле теряет фокус, то Поппер закрывается. Дело в том, что мне нужно выбрать любую опцию из меню без закрытия Popper, но когда я это сделаю, текстовое поле теряет фокус. Что мне нужно, так это держать Popper, только если я нажму за пределами текстового поля или меню.

Все на этом codesandbox .

Я пробовал это:

const selected = prop => {
   console.log(prop);
}

...

        <Paper elevation={3} className={classes.paper}>
          <MenuList>
            <MenuItem onClick={() => selected('first')}>
              First Option
            </MenuItem>
            <MenuItem onClick={() => selected('next')}>
              Next Option
            </MenuItem>
            <MenuItem onClick={() => selected('last')}>
              And Last Option
            </MenuItem>
          </MenuList>
        </Paper>
      </Popper>

Также пробовал с ClickAwayListener, оборачивая оба компонента, TextField и Поппер:

<ClickAwayListener onClickAway={blur}>
  <>
    <TextField ... />
    <Popper ...>
     ...
    </Popper>
  </>
</ClickAwayListener>

Неудачно оба раза ... Как мне этого добиться?

Ответы [ 2 ]

3 голосов
/ 11 апреля 2020

Хотя решение @Dekel работает достаточно хорошо. Но на мой взгляд, было бы лучше, если бы мы использовали React.useRef () для фокусировки на текстовом поле.

Вот обновленная ссылка на решение: https://codesandbox.io/s/goofy-frost-bb88l?file= /src/MyApp.js

const textFieldRef = React.useRef();

Внутри return ()

<TextField
  aria-describedby={id}
  onFocus={focus}
  onBlur={blur}
  placeholder="Focus on me"
  inputRef={textFieldRef}
/>

При выборе любого элемента списка меню

const selected = event => {
  console.log("Selected ", event.target.innerText);
  textFieldRef.current.focus();
};

1 голос
/ 10 апреля 2020

Я думаю, что лучше всего реализовать это с помощью автозаполнения, но, поскольку OP запросил другое решение - вот еще один вариант:

После размытия - проверьте элемент, вызвавший размытие. Если этот элемент является одним из элементов в поппере - не размытие:

if (e.relatedTarget && e.relatedTarget.classList.contains("MuiListItem-root")) {
    return;
}

Функция полного размытия будет выглядеть следующим образом:

const blur = (e) => {
    if (e.relatedTarget && e.relatedTarget.classList.contains("MuiListItem-root")) {
        e.target.focus();
        return;
    }
    setAnchorEl(null);
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...