-
Notifications
You must be signed in to change notification settings - Fork 47.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: autoFocus broken inside <dialog /> #23301
Comments
@jantimon until it's not fixed you can try this workaround: export default function App() {
const [showDialog1, setShowDialog1] = useState(false);
const [showDialog2, setShowDialog2] = useState(false);
return (
<>
// ...
<Dialog open={showDialog2} onClose={() => setShowDialog2(false)}>
<input value="don't focus on me" />
<input value="please focus me" autoFocus={showDialog2} />
</Dialog>
</>
);
} |
Hi, I would like to work on this issue. I am taking Open Source course where I must contribute to a project (in my case it is reactJS). |
I can reproduce this, and have to find a workaround as it's impacting our application. It's important to note that the dialog spec confirms that the Because react has special/custom handling of So far, the only workaround I can find is using setTimeout to run custom focus/blur logic after the dialog/browser 's logic has run. if (ref.current) {
const dialog = ref.current
dialog.showModal()
setTimeout(() => {
const focus = dialog.querySelector(':focus')
if (focus) {
focus.blur()
}
// or call .focus() on something you do want
})
} |
The dialog html element is dead bugged with React 18.2.0, if you try to use useState within a dialog it will just gave you a lot of autoFocus bugs. |
Any update to this? |
And that's why I'm probably not gonna bother anymore with the |
Another bump 👊 |
bump ++ |
I'm ok if it takes time to fix, but no one responding to this open ticket is very disappointing. |
Also found the same thing. In a dialog element, if I set the
It does not work, instead the first focusable element in the dialog receives the autofocus. However, if I set the prop like a normal html prop and use a string
This works properly, although the React compiler/linting breaks here because obviously that's not how React accepts the prop. As a workaround, we can use this to manually set the autofocus attribute via DOM APIs.
|
What worked for me:
const autoFocusRef = useRef<HTMLElement>(null);
const showModal = async (): Promise<void> => {
dialog.showModal();
const hasAnimation =
window.getComputedStyle(dialog).animationName !== "none";
if (!hasAnimation) {
autoFocusRef.current?.focus();
return;
}
dialog.addEventListener(
"animationend",
() => autoFocusRef.current?.focus(),
{ once: true, passive: true }
);
}; This accounts for the dialog possibly being animated, which can otherwise also lead to |
What I am using as a workaround to handle this case with MUI TextField and MUI Dialog is to use a reference "useRef" and then to find the nested "input" element and to apply "focus()" method on it, as the following:
|
Looks like this works for me! |
React version: 17 and 18.0.0-rc.0-next-27b569969-20220211
Steps To Reproduce
<input /><input autoFocus />
inside<dialog />
showModal()
method of the dialogLink to code example:
https://codesandbox.io/s/dreamy-meninsky-460wbr?file=/src/App.tsx
The current behavior
In Chrome and Safari TP the element with
autofocus="true"
will receive focus.However the element with
autoFocus={true}
will not receive focus.The expected behavior
From the html-spec https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute
From https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus
Therefore
autoFocus={true}
should also set the focus similar toautofocus="true"
for elements inside<dialog />
The text was updated successfully, but these errors were encountered: