-
Notifications
You must be signed in to change notification settings - Fork 11
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
Focus the currently focused node when it mounts #593
Conversation
This also fixes #592 |
@pcardune "add a useEffect() that focuses the currently focused node when it mounts" This is not the desired behavior. If a blind user has focus on the "switch to blocks mode" button, they shouldn't have their focus jump to the first block of the editor. The only time focus should jump like that is when they're already in the block editor, and they make an edit that switches focus. |
How about this? |
nodeElementRef.current?.focus(); | ||
} | ||
}, [focusedNode?.id, props.node.id]); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding of line 250 is that this hook "subscribes" to the focusedNode
selector and the node id
. Does this mean that any time the focusedNode
changes, every node asks if the focused node's id is the same as the node's id? If not, what does it mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, that's what this means.
Perfect! Merging now. Thanks for adding the tests! |
Fixes #591
This ended up being surprisingly complicated. The solution to the actual problem was simple: add a useEffect() that focuses the currently focused node when it mounts. Doing this worked fine and all the tests passed, except there was a cryptic react warning message that showed up when the tests ran. The warning only showed up in tests and not when doing exactly the same thing in the browser.
The issue has to do with the timing of calls to
focus(),
though not the call tofocus()
that I added, but rather one that's been in there already for a while, and which is deeply buried in codemirror in the call tosetBookmark()
. I don't know why the warnings didn't show up until I made this change. In any case, you are theoretically not supposed to monkey with the dom (e.g. by callingfocus()
) while react is rendering, and instead useuseEffect()
to wait until rendering is finished, but we were callingsetBookmark()
while renderingToplevelBlockEditable
.Anyway, to fix the issue, I moved the call to
setBookmark()
to happen inside auseEffect()
, which resulted in a different problem. The order in whichuseEffect()
callbacks are called is depth first. So theuseEffect()
insideNodeEditable
which selects the text as soon as the NodeEditable component mounts was being called before it's parent component'suseEffect()
had calledsetBookmark()
, so text could node be selected because it wasn't in the document yet.To avoid the troubles with using
setAfterDOMUpdate
or similar to "wait until react is done", I had to move responsibility for calling selectElement() up the component hierarchy toToplevelBlockEditable
. So now we only select the element text after it's container element has been inserted into the document viasetBookmark()
. It's the first time I've had the chance to useuseImperativeHandle()
.codemirror really makes things 10x more complicated than they would otherwise be, but I hope the comments I've left behind are explanatory enough.