From b02effad815aff174560125acb5a3f3a60238bac Mon Sep 17 00:00:00 2001 From: Tal Koren Date: Sun, 5 Jan 2025 16:36:24 +0200 Subject: [PATCH] fix(EditableTypography): improve performance [prerelease] --- .../EditableTypography.module.scss | 5 ++++- .../EditableTypography/EditableTypography.tsx | 22 ++++++++----------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/core/src/components/EditableTypography/EditableTypography.module.scss b/packages/core/src/components/EditableTypography/EditableTypography.module.scss index cd2fcd9a38..253b68cb28 100644 --- a/packages/core/src/components/EditableTypography/EditableTypography.module.scss +++ b/packages/core/src/components/EditableTypography/EditableTypography.module.scss @@ -9,7 +9,9 @@ overflow: hidden; position: relative; - .input,.textarea { + .input, + .textarea { + width: var(--input-width); display: inline-block; max-width: 100%; min-width: 64px; @@ -28,6 +30,7 @@ .textarea { resize: none; + height: var(--input-height); } .typography { diff --git a/packages/core/src/components/EditableTypography/EditableTypography.tsx b/packages/core/src/components/EditableTypography/EditableTypography.tsx index d69be1c3f0..d5b7772acc 100644 --- a/packages/core/src/components/EditableTypography/EditableTypography.tsx +++ b/packages/core/src/components/EditableTypography/EditableTypography.tsx @@ -1,4 +1,4 @@ -import React, { ElementType, forwardRef, useEffect, useRef, useState } from "react"; +import React, { ElementType, forwardRef, useEffect, useRef, useState, useLayoutEffect } from "react"; import cx from "classnames"; import useMergeRef from "../../hooks/useMergeRef"; import VibeComponentProps from "../../types/VibeComponentProps"; @@ -79,8 +79,6 @@ const EditableTypography: VibeComponent = const [isEditing, setIsEditing] = useState(isEditMode || false); const [inputValue, setInputValue] = useState(value); - const [inputWidth, setInputWidth] = useState(0); - const [inputHeight, setInputHeight] = useState(0); const textareaBorderBoxSizing = useRef(0); const textareaLineHeight = useRef(0); @@ -183,7 +181,7 @@ const EditableTypography: VibeComponent = function resizeTextarea() { if (inputRef.current) { // Temporarily set the height to "auto" to accurately measure the scroll height of the content inside the textarea. - setInputHeight("auto"); + inputRef?.current?.style.setProperty("--input-height", "auto"); requestAnimationFrame(() => { const textarea = inputRef.current as HTMLTextAreaElement; @@ -193,12 +191,11 @@ const EditableTypography: VibeComponent = } // Ensure we at least have 1 line - setInputHeight( - Math.max( - textarea.scrollHeight + textareaBorderBoxSizing.current, - textareaLineHeight.current + textareaBorderBoxSizing.current - ) + const height = Math.max( + textarea.scrollHeight + textareaBorderBoxSizing.current, + textareaLineHeight.current + textareaBorderBoxSizing.current ); + inputRef?.current?.style.setProperty("--input-height", `${height}px`); }); } } @@ -215,13 +212,13 @@ const EditableTypography: VibeComponent = } }, [autoSelectTextOnEditMode, isEditing]); - useEffect(() => { + useLayoutEffect(() => { if (!typographyRef.current) { return; } const { width } = typographyRef.current.getBoundingClientRect(); - setInputWidth(width); + inputRef?.current?.style.setProperty("--input-width", `${width}px`); }, [inputValue, isEditing]); /* Calculate the minimual textarea height, taking its applied styles (padding, border width) into consideration @@ -273,7 +270,7 @@ const EditableTypography: VibeComponent = onBlur={handleBlur} aria-label={ariaLabel} placeholder={placeholder} - style={{ width: inputWidth, height: inputHeight }} + // style={{ width: inputWidth, height: inputHeight }} role="textbox" rows={1} /> @@ -287,7 +284,6 @@ const EditableTypography: VibeComponent = onBlur={handleBlur} aria-label={ariaLabel} placeholder={placeholder} - style={{ width: inputWidth }} role="input" /> ))}