overleaf/services/web/frontend/js/shared/hooks/use-ref-with-auto-focus.ts
Tim Down 80a5f4594e Merge pull request #13130 from overleaf/td-history-add-label-autofocus
History migration: Autofocus input in add label dialog

GitOrigin-RevId: b51187e735414cd4b027413dfe57a0ba332c7b1a
2023-05-26 08:04:04 +00:00

36 lines
1,016 B
TypeScript

import { useRef, useEffect, useCallback, useState } from 'react'
export function useRefWithAutoFocus<T extends HTMLElement = HTMLElement>() {
const autoFocusedRef = useRef<T>(null)
const [hasFocused, setHasFocused] = useState(false)
const resetAutoFocus = useCallback(() => setHasFocused(false), [])
// Run on every render but use hasFocused to ensure that the autofocus only
// happens once
useEffect(() => {
if (hasFocused) {
return
}
let request: number | null = null
if (autoFocusedRef.current) {
request = window.requestAnimationFrame(() => {
if (autoFocusedRef.current) {
autoFocusedRef.current.focus()
setHasFocused(true)
request = null
}
})
}
// Cancel a pending autofocus prior to autofocus actually happening on
// render, and on unmount
return () => {
if (request !== null) {
window.cancelAnimationFrame(request)
}
}
})
return { autoFocusedRef, resetAutoFocus }
}