Saltar al contenido

Reaccionar material UI modal abierto desde dentro de autocompletar perder foco

Solución:

El problema de tener el Modal renderizado desde dentro de la Autocomplete es que los eventos se propagan desde el Modal al Autocomplete. En particular, los eventos de clic y mouse-down son manejados por Autocomplete de una manera que cause problemas en su caso. Esto es principalmente lógica destinada a mantener el enfoque en el lugar correcto mientras interactúa con diferentes partes del Autocomplete.

A continuación (de https://github.com/mui-org/material-ui/blob/v4.9.11/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js#L842) está la parte del Autocomplete código que se interpone en tu camino:

  // 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;
  };

El comportamiento predeterminado del navegador cuando se produce un evento de mouse hacia abajo en un elemento enfocable es que ese elemento reciba el foco, pero el controlador de mouse hacia abajo para Autocomplete llamadas event.preventDefault() lo que evita este comportamiento predeterminado y, por lo tanto, evita un cambio de enfoque desde el evento de mouse hacia abajo (por lo que el enfoque permanece en el Modal sí mismo como lo indica su contorno de enfoque azul). Sin embargo, puede mover con éxito el enfoque al TextField de Modal usando la tecla de tabulación, ya que nada impide que ese mecanismo de enfoque cambie.

los Autocomplete El manejador de clics mantiene el foco en la entrada del Autocomplete incluso si hace clic en alguna otra parte del Autocomplete. Cuando tu Modal está abierto, el efecto de esto es que cuando hace clic en el Modal, el foco se mueve brevemente a la Autocomplete elemento de entrada, pero el foco se devuelve inmediatamente al Modal debido a su funcionalidad de “hacer cumplir el enfoque”. Si agrega el disableEnforceFocus propiedad a la Modal, verá que cuando haga clic en el Modal (por ejemplo, en TextField) el cursor permanece en la entrada del Autocomplete.

La solución es asegurarse de que estos dos eventos NO propagarse más allá del Modal. Llamando event.stopPropagation() para los eventos de clic y mouse en el Modal, previene la Autocomplete funcionalidad para que estos dos eventos se ejecuten cuando estos eventos ocurren dentro del Modal.

      <Modal
        onClick={event => event.stopPropagation()}
        onMouseDown={event => event.stopPropagation()}
        ...

Editar modal en Autocompletar

Respuesta relacionada: ¿Cómo puedo crear una primera opción en la que se pueda hacer clic en Material UI Labs Autocompletar?

El problema en su código fue que el Modal fue renderizado desde dentro de la etiqueta del AutoComplete componente, que no estaba bien debido a la visibilidad de los componentes, la jerarquía de los componentes era el problema.

La solución es mover el Modal dentro de FixedTags componente y pasar el manejador abierto al ModalBtn en el renderTags apuntalar;

Actualicé su sandbox con una variante funcional AQUÍ

Los cambios están debajo

const ModalBtn = ({ handleOpen }) => (
  <button type="button" onClick={handleOpen}>
    Open Modal (not working)
  </button>
);

const FixedTags = function() {
  const classes = useStyles();
  const [modalStyle] = React.useState(getModalStyle);
  const [open, setOpen] = React.useState(false);

  const handleOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  return (
    <>
      <Autocomplete
        multiple
        options={autoCompleteItems}
        getOptionLabel={option => option.title}
        defaultValue={[autoCompleteItems[1], autoCompleteItems[2]]}
        renderTags={(value, getTagProps) =>
          value.map((option, index) => <ModalBtn handleOpen={handleOpen} />)
        }
        style={{ width: 500 }}
        renderInput={params => (
          <TextField
            {...params}
            label="Fixed tag"
            variant="outlined"
            placeholder="items..."
          />
        )}
      />
      <Modal open={open} onClose={handleClose}>
        <div style={modalStyle} className={classes.paper}>
          <h2 style={{ color: "red" }}>This one doesn't work</h2>
          <p>Text field is not available</p>
          <TextField label="Filled" variant="filled" /> <br />
          <br />
          <br />
          <FixedTags label="Standard" />
        </div>
      </Modal>
    </>
  );
};
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *