mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #13130 from overleaf/td-history-add-label-autofocus
History migration: Autofocus input in add label dialog GitOrigin-RevId: b51187e735414cd4b027413dfe57a0ba332c7b1a
This commit is contained in:
parent
82d7264c32
commit
80a5f4594e
2 changed files with 39 additions and 7 deletions
|
@ -1,5 +1,5 @@
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Modal, FormGroup, FormControl } from 'react-bootstrap'
|
||||
import ModalError from './modal-error'
|
||||
import AccessibleModal from '../../../../shared/components/accessible-modal'
|
||||
|
@ -9,6 +9,7 @@ import useAddOrRemoveLabels from '../../hooks/use-add-or-remove-labels'
|
|||
import { useHistoryContext } from '../../context/history-context'
|
||||
import { addLabel } from '../../services/api'
|
||||
import { Label } from '../../services/types/label'
|
||||
import { useRefWithAutoFocus } from '../../../../shared/hooks/use-ref-with-auto-focus'
|
||||
|
||||
type AddLabelModalProps = {
|
||||
show: boolean
|
||||
|
@ -32,6 +33,17 @@ function AddLabelModal({ show, setShow, version }: AddLabelModalProps) {
|
|||
const { signal } = useAbortController()
|
||||
const { addUpdateLabel } = useAddOrRemoveLabels()
|
||||
|
||||
const { autoFocusedRef, resetAutoFocus } =
|
||||
useRefWithAutoFocus<HTMLInputElement>()
|
||||
|
||||
// Reset the autofocus when `show` changes so that autofocus still happens if
|
||||
// the dialog is shown, hidden and then shown again
|
||||
useEffect(() => {
|
||||
if (show) {
|
||||
resetAutoFocus()
|
||||
}
|
||||
}, [resetAutoFocus, show])
|
||||
|
||||
const handleModalExited = () => {
|
||||
setComment('')
|
||||
|
||||
|
@ -71,7 +83,9 @@ function AddLabelModal({ show, setShow, version }: AddLabelModalProps) {
|
|||
<Modal.Body>
|
||||
{isError && <ModalError error={responseError} />}
|
||||
<FormGroup>
|
||||
<FormControl
|
||||
<input
|
||||
ref={autoFocusedRef}
|
||||
className="form-control"
|
||||
type="text"
|
||||
placeholder={t('history_new_label_name')}
|
||||
required
|
||||
|
@ -79,7 +93,6 @@ function AddLabelModal({ show, setShow, version }: AddLabelModalProps) {
|
|||
onChange={(
|
||||
e: React.ChangeEvent<HTMLInputElement & FormControl>
|
||||
) => setComment(e.target.value)}
|
||||
autoFocus // eslint-disable-line jsx-a11y/no-autofocus
|
||||
/>
|
||||
</FormGroup>
|
||||
</Modal.Body>
|
||||
|
|
|
@ -1,17 +1,36 @@
|
|||
import { useRef, useEffect } from 'react'
|
||||
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) {
|
||||
window.requestAnimationFrame(() => {
|
||||
request = window.requestAnimationFrame(() => {
|
||||
if (autoFocusedRef.current) {
|
||||
autoFocusedRef.current.focus()
|
||||
setHasFocused(true)
|
||||
request = null
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
return { autoFocusedRef }
|
||||
// Cancel a pending autofocus prior to autofocus actually happening on
|
||||
// render, and on unmount
|
||||
return () => {
|
||||
if (request !== null) {
|
||||
window.cancelAnimationFrame(request)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return { autoFocusedRef, resetAutoFocus }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue