Merge pull request #16700 from overleaf/td-scroll-comment-input-into-view

Scroll comment textarea into view after autofocus

GitOrigin-RevId: c8542f40d25772a14e7511702c0e47b7001be275
This commit is contained in:
Tim Down 2024-02-02 11:54:26 +00:00 committed by Copybot
parent 473e74ecf1
commit 3a88a60e23
2 changed files with 34 additions and 1 deletions

View file

@ -88,6 +88,22 @@ function AddCommentEntry() {
}
}
const handleCommentAutoFocus = (textarea: HTMLTextAreaElement) => {
// Sometimes the comment textarea is scrolled out of view once focussed,
// so this checks for that and scrolls it into view if necessary. It
// seems we sometimes need to allow time for the dust to settle after
// focussing the textarea before scrolling.
window.setTimeout(() => {
const observer = new IntersectionObserver(([entry]) => {
if (entry.intersectionRatio < 1) {
textarea.scrollIntoView({ block: 'center' })
}
observer.disconnect()
})
observer.observe(textarea)
}, 500)
}
return (
<EntryContainer id="add-comment">
<EntryCallout className="rp-entry-callout-add-comment" />
@ -109,6 +125,7 @@ function AddCommentEntry() {
onChange={e => setContent(e.target.value)}
onKeyPress={handleCommentKeyPress}
onResize={handleLayoutChange}
onAutoFocus={handleCommentAutoFocus}
placeholder={t('add_your_comment_here')}
value={content}
autoFocus // eslint-disable-line jsx-a11y/no-autofocus

View file

@ -6,6 +6,7 @@ type AutoExpandingTextAreaProps = MergeAndOverride<
React.ComponentProps<'textarea'>,
{
onResize?: () => void
onAutoFocus?: (textarea: HTMLTextAreaElement) => void
}
>
@ -13,6 +14,7 @@ function AutoExpandingTextArea({
onChange,
onResize,
autoFocus,
onAutoFocus,
...rest
}: AutoExpandingTextAreaProps) {
const ref = useRef<HTMLTextAreaElement>(null)
@ -102,6 +104,13 @@ function AutoExpandingTextArea({
}
}, [onResize])
// Maintain a copy onAutoFocus in a ref for use in the autofocus effect
// below so that the effect doesn't run when onAutoFocus changes
const onAutoFocusRef = useRef(onAutoFocus)
useEffect(() => {
onAutoFocusRef.current = onAutoFocus
}, [onAutoFocus])
// Implement autofocus manually so that the cursor is placed at the end of
// the textarea content
useEffect(() => {
@ -113,10 +122,17 @@ function AutoExpandingTextArea({
resetHeight()
if (autoFocus) {
const cursorPos = el.value.length
window.setTimeout(() => {
const timer = window.setTimeout(() => {
el.focus()
el.setSelectionRange(cursorPos, cursorPos)
if (onAutoFocusRef.current) {
onAutoFocusRef.current(el)
}
}, 100)
return () => {
window.clearTimeout(timer)
}
}
}, [autoFocus, resetHeight])