Как отключить выбор элемента при нажатии первой буквы опции в компоненте «Выбрать»? - PullRequest
1 голос
/ 14 октября 2019

Я использую компонент выбора пользовательского интерфейса материала и пытаюсь создать фильтр внутри, чтобы отображать только те элементы, которые соответствуют вводу, введенному пользователем.

Я создаю минимальный пример того, что я 'm развивающихся.

function App() {
  const [selectedOption, setSelectedOption] = React.useState("");
  const [filterExpression, setFilterExpression] = React.useState("");

  const onChangeSelection = (
    event: React.ChangeEvent<{ name?: string | undefined; value: unknown }>,
    child: React.ReactNode
  ) => {
    const value = event.target.value.toString();
    setSelectedOption(value);
  };

  const onChangeExpression = (
    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    const value = event.target.value.toString();
    console.log(`value:`, value);
    setFilterExpression(value);
  };

  const stopImmediatePropagation = (e: any) => {
    e.stopPropagation();
    e.preventDefault();
  };

  return (
    <div className="App">
      <Select onChange={onChangeSelection} value={selectedOption}>
        <MenuItem
          dense
          divider
          value={""}
          onClickCapture={stopImmediatePropagation}
        >
          <TextField value={filterExpression} onChange={onChangeExpression} />
        </MenuItem>

        <MenuItem dense key={"One"} value={"One"}>
          One
        </MenuItem>
        <MenuItem dense key={"Two"} value={"Two"}>
          Two
        </MenuItem>
        <MenuItem dense key={"Three"} value={"Three"}>
          Three
        </MenuItem>
      </Select>
    </div>
  );
}

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

Итак, если у меня есть 3 варианта (One, Two и Three) и пользовательские типы O, компонент выбора выберет параметр One и значение моего текстового поля. не изменитсяОднако, если пользователь введет F, текстовое поле будет обновлено до F.

Я хотел бы отключить это поведение, поэтому я пытался остановить распространение таких событий, как onKeyUpCapture, onChangeCapture, onKeyDownCapture но я не смог этого избежать.

Есть ли у вас какие-либо предложения, чтобы это исправить? Вы можете проверить функциональный пример здесь:

https://codesandbox.io/s/inspiring-ramanujan-sv25c

1 Ответ

1 голос
/ 14 октября 2019

Функция навигации по текстовому фокусу реализована в onKeyDown из MenuList (I реализовал ее около 6 месяцев назад). Остановка распространения этого события на MenuItem (это также будет работать для остановки распространения на TextField) не позволяет событию достигнуть MenuList.

import * as React from "react";
import { render } from "react-dom";
import TextField from "@material-ui/core/TextField";
import Select from "@material-ui/core/Select";
import MenuItem from "@material-ui/core/MenuItem";

import "./styles.css";

function App() {
  const [selectedOption, setSelectedOption] = React.useState("");
  const [filterExpression, setFilterExpression] = React.useState("");

  const onChangeSelection = (
    event: React.ChangeEvent<{ name?: string | undefined; value: unknown }>,
    child: React.ReactNode
  ) => {
    const value = event.target.value.toString();
    setSelectedOption(value);
  };

  const onChangeExpression = (
    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    const value = event.target.value.toString();
    console.log(`value:`, value);
    setFilterExpression(value);
  };

  const stopImmediatePropagation = (e: any) => {
    e.stopPropagation();
    e.preventDefault();
  };

  return (
    <div className="App">
      <Select onChange={onChangeSelection} value={selectedOption}>
        <MenuItem
          dense
          divider
          value={""}
          onClickCapture={stopImmediatePropagation}
          onKeyDown={e => e.stopPropagation()}
        >
          <TextField value={filterExpression} onChange={onChangeExpression} />
        </MenuItem>

        <MenuItem dense key={"One"} value={"One"}>
          One
        </MenuItem>
        <MenuItem dense key={"Two"} value={"Two"}>
          Two
        </MenuItem>
        <MenuItem dense key={"Three"} value={"Three"}>
          Three
        </MenuItem>
      </Select>
    </div>
  );
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);

Edit Stop text focus navigation

...