fix: cancel inline input refocus frames (#3488)
This commit is contained in:
parent
e6b04820ea
commit
e7be9c50f0
|
|
@ -97,10 +97,27 @@ export function InlineInputRow({
|
|||
// of auto-submitting, which would dismiss the empty input.
|
||||
const focusSettled = useRef(false)
|
||||
const settleTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
const refocusFrame = useRef<number | null>(null)
|
||||
|
||||
const cancelRefocusFrame = useCallback((): void => {
|
||||
if (refocusFrame.current !== null) {
|
||||
cancelAnimationFrame(refocusFrame.current)
|
||||
refocusFrame.current = null
|
||||
}
|
||||
}, [])
|
||||
|
||||
const scheduleInputRefocus = useCallback((): void => {
|
||||
cancelRefocusFrame()
|
||||
refocusFrame.current = requestAnimationFrame(() => {
|
||||
refocusFrame.current = null
|
||||
inputRef.current?.focus()
|
||||
})
|
||||
}, [cancelRefocusFrame])
|
||||
|
||||
useEffect(() => {
|
||||
submitted.current = false
|
||||
focusSettled.current = false
|
||||
cancelRefocusFrame()
|
||||
|
||||
// Schedule focus after any pending focus-restore from menu close
|
||||
const raf = requestAnimationFrame(() => {
|
||||
|
|
@ -126,6 +143,7 @@ export function InlineInputRow({
|
|||
})
|
||||
return () => {
|
||||
cancelAnimationFrame(raf)
|
||||
cancelRefocusFrame()
|
||||
if (blurTimeout.current) {
|
||||
clearTimeout(blurTimeout.current)
|
||||
}
|
||||
|
|
@ -133,7 +151,7 @@ export function InlineInputRow({
|
|||
clearTimeout(settleTimer.current)
|
||||
}
|
||||
}
|
||||
}, [inlineInput])
|
||||
}, [cancelRefocusFrame, inlineInput])
|
||||
|
||||
const clearBlurTimeout = useCallback(() => {
|
||||
if (blurTimeout.current) {
|
||||
|
|
@ -190,14 +208,14 @@ export function InlineInputRow({
|
|||
(e.relatedTarget.closest('[data-slot="context-menu-trigger"]') ||
|
||||
e.relatedTarget.closest('[data-slot="dropdown-menu-trigger"]'))
|
||||
) {
|
||||
requestAnimationFrame(() => inputRef.current?.focus())
|
||||
scheduleInputRefocus()
|
||||
return
|
||||
}
|
||||
// During the grace period after mount, menu close focus management
|
||||
// may shift focus away (often relatedTarget is null). Re-focus
|
||||
// instead of dismissing the still-empty input.
|
||||
if (!focusSettled.current) {
|
||||
requestAnimationFrame(() => inputRef.current?.focus())
|
||||
scheduleInputRefocus()
|
||||
return
|
||||
}
|
||||
const value = e.currentTarget.value
|
||||
|
|
|
|||
Loading…
Reference in New Issue