React Material UI 从自动完成中打开模式失去焦点

Dek*_*kel 6 javascript autocomplete modal-dialog reactjs material-ui

我正在使用 material-ui lib,我需要有一个自动完成功能,其中该自动完成功能中的每个项目都是可点击的并打开一个模态。

一般结构为:

const ModalBtn = () => {
    ...
    return (
        <>
            <button ... (on click set modal to open)
            <Modal ...
        </>

    );
}

const AutoCompleteWithBtns = () => {
    return (
        <Autocomplete
            renderTags={(value, getTagProps) =>
                value.map((option, index) => <ModalBtn />)
            }
            ...
        />
    );

}
Run Code Online (Sandbox Code Playgroud)

注意 ModalBtn 是一个组件,不能分为 Button 和 Modal 两个组件。

问题是,当您单击模态内的按钮时 - 焦点保持在自动完成内,并且模态永远不会获得焦点(如果我在模态中有输入 - 我不能在里面写任何东西)。

尝试了所有的标准自动完成/莫代尔焦点相关的道具(disableEnforceFocusdisableEnforceFocus,等...),但没有任何工程。

这是一个有效的代码和框示例。如您所见 - 如果您单击不在自动完成组件内的按钮 - 一切正常(您可以在输入字段内添加文本)。如果您单击自动完成内的按钮 - 模态内的输入字段不可编辑(您失去焦点)。

以下是该问题的一个示例:
在此处输入图片说明

Rya*_*ell 7

Modal从 内部渲染的问题Autocomplete是事件从 传播ModalAutocomplete。特别是,单击和鼠标按下事件的处理Autocomplete方式都会导致您的情况出现问题。这主要是为了在您与Autocomplete.

下面(来自https://github.com/mui-org/material-ui/blob/v4.9.11/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js#L842)是Autocomplete代码的一部分正在妨碍您:

  // Prevent input blur when interacting with the combobox
  const handleMouseDown = (event) => {
    if (event.target.getAttribute('id') !== id) {
      event.preventDefault();
    }
  };

  // Focus the input when interacting with the combobox
  const handleClick = () => {
    inputRef.current.focus();

    if (
      selectOnFocus &&
      firstFocus.current &&
      inputRef.current.selectionEnd - inputRef.current.selectionStart === 0
    ) {
      inputRef.current.select();
    }

    firstFocus.current = false;
  };
Run Code Online (Sandbox Code Playgroud)

当鼠标按下事件发生在可聚焦元素上时,浏览器的默认行为是让该元素接收焦点,但是鼠标按下处理程序的Autocomplete调用event.preventDefault()阻止了这种默认行为,从而阻止了鼠标按下事件的焦点变化(因此焦点保持在其Modal自身上,如其蓝色焦点轮廓所示)。但是,您可以使用 tab 键成功地将焦点移动到 Modal 的 TextField,因为没有什么可以阻止焦点更改的机制。

Autocomplete单击处理程序是保持上的输入焦点Autocomplete,即使你点击的其他部分Autocomplete。当您Modal打开时,其效果是当您单击 时Modal,焦点会短暂移动到Autocompleteinput 元素,但Modal由于其“强制焦点”功能,焦点会立即返回到。如果您将disableEnforceFocus属性添加到Modal您将看到当您单击Modal(例如在 TextField 上)时,光标将保留在 的输入中Autocomplete

解决方法是确保这两个事件不会传播到Modal. 通过同时调用event.stopPropagation()上的单击和鼠标按下事件ModalAutocomplete当这些事件发生在Modal.

      <Modal
        onClick={event => event.stopPropagation()}
        onMouseDown={event => event.stopPropagation()}
        ...
Run Code Online (Sandbox Code Playgroud)

在自动完成中编辑模态

相关答案:如何在 Material UI Labs Autocomplete 中创建可点击的第一个选项