[fix] Focus events (actually) (#2015)
This PR restores the controlled nature of focus. Focus allows keyboard shortcuts and other interactions to occur. The editor's focus should always / entirely be controlled via the autoFocus prop or by manually setting `editor.instanceState.isFocused`. Design note: I'm starting to think that focus is the wrong abstraction, and that we should instead use a kind of "disabled" state for editors that the user isn't interacting with directly. In a page where multiple editors exit (e.g. a notion page), a developer could switch from disabled to enabled using a first interaction. ### Change Type - [x] `patch` — Bug fix ### Test Plan - [x] End to end tests
This commit is contained in:
parent
6b19d70a9e
commit
d715fa3a2e
11 changed files with 236 additions and 122 deletions
|
@ -7,25 +7,26 @@ export function useFocusEvents(autoFocus: boolean) {
|
|||
const editor = useEditor()
|
||||
const container = useContainer()
|
||||
useLayoutEffect(() => {
|
||||
function handleFocus() {
|
||||
if (autoFocus) {
|
||||
// When autoFocus is true, update the editor state to be focused
|
||||
// unless it's already focused
|
||||
if (!editor.instanceState.isFocused) {
|
||||
editor.updateInstanceState({ isFocused: true })
|
||||
}
|
||||
}
|
||||
|
||||
container.addEventListener('focus', handleFocus)
|
||||
container.addEventListener('pointerdown', handleFocus)
|
||||
|
||||
if (autoFocus && !editor.instanceState.isFocused) {
|
||||
editor.updateInstanceState({ isFocused: true })
|
||||
container.focus()
|
||||
} else if (editor.instanceState.isFocused) {
|
||||
editor.updateInstanceState({ isFocused: false })
|
||||
}
|
||||
|
||||
return () => {
|
||||
container.removeEventListener('focus', handleFocus)
|
||||
container.removeEventListener('pointerdown', handleFocus)
|
||||
// Note: Focus is also handled by the side effect manager in tldraw.
|
||||
// Importantly, if a user manually sets isFocused to true (or if it
|
||||
// changes for any reason from false to true), the side effect manager
|
||||
// in tldraw will also take care of the focus. However, it may be that
|
||||
// on first mount the editor already has isFocused: true in the model,
|
||||
// so we also need to focus it here just to be sure.
|
||||
editor.getContainer().focus()
|
||||
} else {
|
||||
// When autoFocus is false, update the editor state to be not focused
|
||||
// unless it's already not focused
|
||||
if (editor.instanceState.isFocused) {
|
||||
editor.updateInstanceState({ isFocused: false })
|
||||
}
|
||||
}
|
||||
}, [editor, container, autoFocus])
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue