Procházet zdrojové kódy

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

Scroll comment textarea into view after autofocus

GitOrigin-RevId: c8542f40d25772a14e7511702c0e47b7001be275
Tim Down před 2 roky
rodič
revize
3a88a60e23

+ 17 - 0
services/web/frontend/js/features/source-editor/components/review-panel/entries/add-comment-entry.tsx

@@ -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

+ 17 - 1
services/web/frontend/js/shared/components/auto-expanding-text-area.tsx

@@ -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])