[fix] iframe losing focus on pointer down (#1848)
This PR fixes a bug that would cause an interactive iframe (e.g. a youtube video) to lose its editing state once clicked. ### Change Type - [x] `patch` — Bug fix ### Test Plan 1. Create an interactive iframe. 2. Begin editing. 3. Click inside of the iframe
This commit is contained in:
parent
48a1bb4d88
commit
20704ea417
5 changed files with 115 additions and 66 deletions
56
packages/editor/src/lib/hooks/useFocusEvents.ts
Normal file
56
packages/editor/src/lib/hooks/useFocusEvents.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
import { debounce } from '@tldraw/utils'
|
||||
import { useLayoutEffect } from 'react'
|
||||
import { useContainer } from './useContainer'
|
||||
import { useEditor } from './useEditor'
|
||||
|
||||
/** @internal */
|
||||
export function useFocusEvents(autoFocus: boolean) {
|
||||
const editor = useEditor()
|
||||
const container = useContainer()
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!container) return
|
||||
|
||||
// We need to debounce this because when focus changes, the body
|
||||
// becomes focused for a brief moment. Debouncing means that we
|
||||
// check only when focus stops changing: when it settles, what
|
||||
// has it settled on? If it's settled on the container or something
|
||||
// inside of the container, then focus or preserve the current focus;
|
||||
// if not, then turn off focus. Turning off focus is a trigger to
|
||||
// also turn off keyboard shortcuts and other things.
|
||||
const updateFocus = debounce(() => {
|
||||
const { activeElement } = document
|
||||
const { isFocused: wasFocused } = editor.instanceState
|
||||
const isFocused =
|
||||
document.hasFocus() && (container === activeElement || container.contains(activeElement))
|
||||
|
||||
if (wasFocused !== isFocused) {
|
||||
editor.updateInstanceState({ isFocused })
|
||||
editor.updateViewportScreenBounds()
|
||||
|
||||
if (!isFocused) {
|
||||
// When losing focus, run complete() to ensure that any interacts end
|
||||
editor.complete()
|
||||
}
|
||||
}
|
||||
}, 32)
|
||||
|
||||
container.addEventListener('focusin', updateFocus)
|
||||
container.addEventListener('focus', updateFocus)
|
||||
container.addEventListener('focusout', updateFocus)
|
||||
container.addEventListener('blur', updateFocus)
|
||||
|
||||
return () => {
|
||||
container.removeEventListener('focusin', updateFocus)
|
||||
container.removeEventListener('focus', updateFocus)
|
||||
container.removeEventListener('focusout', updateFocus)
|
||||
container.removeEventListener('blur', updateFocus)
|
||||
}
|
||||
}, [container, editor])
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (autoFocus) {
|
||||
editor.getContainer().focus()
|
||||
}
|
||||
}, [editor, autoFocus])
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue