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()}
...
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>
</>
);
};