From 7e41f190b285974aeb8fbf20230dce7f228d03d9 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 29 Mar 2024 20:51:24 +0100 Subject: [PATCH] StricterDOM: Fix several component errors (#4374) Co-authored-by: zubiden <19638254+zubiden@users.noreply.github.com> --- src/components/common/Picker.tsx | 4 ++-- src/components/ui/TextArea.tsx | 31 ++++++++++++++++++-------- src/hooks/useKeyboardListNavigation.ts | 5 +++-- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/components/common/Picker.tsx b/src/components/common/Picker.tsx index dfaecaaef..ceddd980c 100644 --- a/src/components/common/Picker.tsx +++ b/src/components/common/Picker.tsx @@ -3,7 +3,7 @@ import React, { memo, useEffect, useMemo, useRef, } from '../../lib/teact/teact'; -import { requestMutation } from '../../lib/fasterdom/fasterdom'; +import { requestMeasure } from '../../lib/fasterdom/fasterdom'; import { isUserId } from '../../global/helpers'; import buildClassName from '../../util/buildClassName'; import { MEMO_EMPTY_ARRAY } from '../../util/memo'; @@ -77,7 +77,7 @@ const Picker: FC = ({ useEffect(() => { if (!isSearchable) return; setTimeout(() => { - requestMutation(() => { + requestMeasure(() => { inputRef.current!.focus(); }); }, FOCUS_DELAY_MS); diff --git a/src/components/ui/TextArea.tsx b/src/components/ui/TextArea.tsx index a8f1952ee..5fcad37a9 100644 --- a/src/components/ui/TextArea.tsx +++ b/src/components/ui/TextArea.tsx @@ -1,12 +1,14 @@ import type { ChangeEvent, FormEvent, RefObject } from 'react'; import type { FC } from '../../lib/teact/teact'; import React, { - memo, useCallback, useEffect, useRef, + memo, useCallback, useLayoutEffect, useRef, } from '../../lib/teact/teact'; +import { requestForcedReflow, requestMutation } from '../../lib/fasterdom/fasterdom'; import buildClassName from '../../util/buildClassName'; import useLang from '../../hooks/useLang'; +import useLastCallback from '../../hooks/useLastCallback'; type OwnProps = { ref?: RefObject; @@ -75,22 +77,33 @@ const TextArea: FC = ({ className, ); - useEffect(() => { + const resizeHeight = useLastCallback((element: HTMLTextAreaElement) => { + requestMutation(() => { + element.style.height = '0'; + requestForcedReflow(() => { + const newHeight = element.scrollHeight; + return () => { + element.style.height = `${newHeight}px`; + }; + }); + }); + }); + + useLayoutEffect(() => { const textarea = textareaRef.current; if (!textarea) return; - textarea.style.height = '0'; - textarea.style.height = `${textarea.scrollHeight}px`; + resizeHeight(textarea); }, []); const handleChange = useCallback((e: ChangeEvent) => { + const target = e.currentTarget; if (!noReplaceNewlines) { - const previousSelectionEnd = e.currentTarget.selectionEnd; + const previousSelectionEnd = target.selectionEnd; // TDesktop replaces newlines with spaces as well - e.currentTarget.value = e.currentTarget.value.replace(/\n/g, ' '); - e.currentTarget.selectionEnd = previousSelectionEnd; + target.value = target.value.replace(/\n/g, ' '); + target.selectionEnd = previousSelectionEnd; } - e.currentTarget.style.height = '0'; - e.currentTarget.style.height = `${e.currentTarget.scrollHeight}px`; + resizeHeight(target); onChange?.(e); }, [noReplaceNewlines, onChange]); diff --git a/src/hooks/useKeyboardListNavigation.ts b/src/hooks/useKeyboardListNavigation.ts index bc0b07a9d..090726ac2 100644 --- a/src/hooks/useKeyboardListNavigation.ts +++ b/src/hooks/useKeyboardListNavigation.ts @@ -1,6 +1,7 @@ import type { RefObject } from 'react'; import { useEffect, useState } from '../lib/teact/teact'; +import { requestMeasure, requestMutation } from '../lib/fasterdom/fasterdom'; import useLastCallback from './useLastCallback'; const useKeyboardListNavigation = ( @@ -17,8 +18,8 @@ const useKeyboardListNavigation = ( const element = elementRef.current; if (isOpen && element && !noCaptureFocus) { - element.tabIndex = -1; - element.focus(); + requestMutation(() => { element.tabIndex = -1; }); + requestMeasure(() => element.focus()); } }, [elementRef, isOpen, noCaptureFocus]);