Reputation: 23
I have an input which is contained within a wrapper div. On mousedown on the wrapper, I want the inner input to take focus.
import "./styles.css";
import { useRef } from "react";
export default () => {
const ref = useRef(null);
return (
<div className="App">
<div
className="Wrapper"
onMouseDown={(e) => {
ref.current.focus();
// e.preventDefault();
}}
>
<input ref={ref} />
</div>
</div>
);
};
However, focus does not work, unless I include e.preventDefault()
. But the problem with this approach is that it disables text highlighting on the input, which seems to be a default behavior for mouse down, so it's undesirable. On the other hand, if I use onClick
instead of onMouseDown
, it works fine even without preventing default, but I would like to focus on onMouseDown
.
Why is this happening, and what is the best way to solve it?
Upvotes: 0
Views: 56
Reputation: 36
This happens because as soon as you click in the container, the callback fires. And the input is focused, but then the default handler executes and blurs the input. Now, one way is to use setTimeout - to delay the focus()
call. So that, the element.focus() runs after browser's default handler execution.
(e) => {
setTimeout(()=>ref.current.focus(), 100)
}
Another way is to stopPropagation
from the input element and then preventDefault
in the wrapper.
export default () => {
const ref = useRef(null);
return (
<div className="App">
<div
className="Wrapper"
onMouseDown={(e) => {
ref.current.focus();
e.preventDefault();
}}
>
<input ref={ref} onMouseDown={(e) => {
e.stopPropagation();
}}/>
</div>
</div>
);
};
Upvotes: 1