diff --git a/apps/client/src/common/components/input/auto-textarea/AutoTextarea.tsx b/apps/client/src/common/components/input/auto-textarea/AutoTextarea.tsx index 1c52a8126..e0f91039c 100644 --- a/apps/client/src/common/components/input/auto-textarea/AutoTextarea.tsx +++ b/apps/client/src/common/components/input/auto-textarea/AutoTextarea.tsx @@ -1,6 +1,6 @@ // @ts-expect-error no types from library import autosize from 'autosize/dist/autosize'; -import { FocusEvent, RefObject, useCallback, useEffect } from 'react'; +import { RefObject, useEffect } from 'react'; import { timeSync } from '../../../devtools/cuesheet-metrics/usePerfMark'; // PERF-METRICS import Textarea, { type TextareaProps } from '../textarea/Textarea'; @@ -10,41 +10,18 @@ interface AutoTextAreaProps extends TextareaProps { } /** - * A textarea that automatically resizes based on its content. - * - * `autosize()` forces a synchronous reflow (reads scrollHeight) and installs a MutationObserver. - * Doing that on mount makes it expensive when many of these are mounted at once (e.g. virtualised - * table rows during scroll), so we only attach autosize while the field is focused for editing and - * keep it in sync with the value during that time. + * A textarea that automatically resizes based on its content */ -export function AutoTextarea({ value, inputref, onFocus, onBlur, ...textAreaProps }: AutoTextAreaProps) { - const handleFocus = useCallback( - (event: FocusEvent) => { - timeSync('cell.autosize', () => autosize(inputref.current)); // PERF-METRICS - onFocus?.(event); - }, - [inputref, onFocus], - ); - - const handleBlur = useCallback( - (event: FocusEvent) => { - if (inputref.current) { - autosize.destroy(inputref.current); - } - onBlur?.(event); - }, - [inputref, onBlur], - ); - - // while focused, keep the height in sync as the value changes +export function AutoTextarea({ value, inputref, ...textAreaProps }: AutoTextAreaProps) { + // when the value changes, we use the ref to reapply autosize useEffect(() => { const node = inputref.current; - if (node && document.activeElement === node) { - autosize(node); - } + timeSync('cell.autosize', () => autosize(inputref.current)); // PERF-METRICS + + return () => { + autosize.destroy(node); + }; }, [inputref, value]); - return ( -