chore: handle Textarea component ref warning in react 19 (#16818)

This commit is contained in:
Joel 2025-03-26 14:55:02 +08:00 committed by GitHub
parent c451f54925
commit 032d849f17
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 75 additions and 74 deletions

View File

@ -3,23 +3,22 @@ import {
useRef, useRef,
useState, useState,
} from 'react' } from 'react'
import type { TextAreaRef } from 'rc-textarea'
export const useTextAreaHeight = () => { export const useTextAreaHeight = () => {
const wrapperRef = useRef<HTMLDivElement>(null) const wrapperRef = useRef<HTMLDivElement>(null)
const textareaRef = useRef<TextAreaRef>(null) const textareaRef = useRef<HTMLTextAreaElement | undefined>(undefined)
const textValueRef = useRef<HTMLDivElement>(null) const textValueRef = useRef<HTMLDivElement>(null)
const holdSpaceRef = useRef<HTMLDivElement>(null) const holdSpaceRef = useRef<HTMLDivElement>(null)
const [isMultipleLine, setIsMultipleLine] = useState(false) const [isMultipleLine, setIsMultipleLine] = useState(false)
const handleComputeHeight = useCallback(() => { const handleComputeHeight = useCallback(() => {
const textareaElement = textareaRef.current?.resizableTextArea.textArea const textareaElement = textareaRef.current
if (wrapperRef.current && textareaElement && textValueRef.current && holdSpaceRef.current) { if (wrapperRef.current && textareaElement && textValueRef.current && holdSpaceRef.current) {
const { width: wrapperWidth } = wrapperRef.current.getBoundingClientRect() const { width: wrapperWidth } = wrapperRef.current.getBoundingClientRect()
const { height: textareaHeight } = textareaElement.getBoundingClientRect() const { height: textareaHeight } = textareaElement.getBoundingClientRect()
const { width: textValueWidth } = textValueRef.current.getBoundingClientRect() const { width: textValueWidth } = textValueRef.current.getBoundingClientRect()
const { width: holdSpaceWidth } = holdSpaceRef.current.getBoundingClientRect() const { width: holdSpaceWidth } = holdSpaceRef.current.getBoundingClientRect()
if (textareaHeight > 32) { if (textareaHeight > 32) {
setIsMultipleLine(true) setIsMultipleLine(true)
} }

View File

@ -3,7 +3,7 @@ import {
useRef, useRef,
useState, useState,
} from 'react' } from 'react'
import Textarea from 'rc-textarea' import Textarea from 'react-textarea-autosize'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import Recorder from 'js-audio-recorder' import Recorder from 'js-audio-recorder'
import type { import type {
@ -174,18 +174,18 @@ const ChatInputArea = ({
{query} {query}
</div> </div>
<Textarea <Textarea
ref={textareaRef} ref={ref => textareaRef.current = ref as any}
className={cn( className={cn(
'body-lg-regular w-full bg-transparent p-1 leading-6 text-text-tertiary outline-none', 'body-lg-regular w-full resize-none bg-transparent p-1 leading-6 text-text-tertiary outline-none',
)} )}
placeholder={t('common.chat.inputPlaceholder') || ''} placeholder={t('common.chat.inputPlaceholder') || ''}
autoFocus autoFocus
autoSize={{ minRows: 1 }} minRows={1}
onResize={handleTextareaResize} onResize={handleTextareaResize}
value={query} value={query}
onChange={(e) => { onChange={(e) => {
setQuery(e.target.value) setQuery(e.target.value)
handleTextareaResize() setTimeout(handleTextareaResize, 0)
}} }}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
onPaste={handleClipboardPasteFile} onPaste={handleClipboardPasteFile}

View File

@ -3,7 +3,7 @@ import {
useCallback, useCallback,
useState, useState,
} from 'react' } from 'react'
import Textarea from 'rc-textarea' import Textarea from 'react-textarea-autosize'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
type TitleInputProps = { type TitleInputProps = {
@ -71,7 +71,7 @@ export const DescriptionInput = memo(({
<Textarea <Textarea
value={value} value={value}
onChange={e => onChange(e.target.value)} onChange={e => onChange(e.target.value)}
rows={1} minRows={1}
onFocus={handleFocus} onFocus={handleFocus}
onBlur={handleBlur} onBlur={handleBlur}
className={` className={`
@ -80,7 +80,6 @@ export const DescriptionInput = memo(({
outline-none placeholder:text-gray-400 outline-none placeholder:text-gray-400
`} `}
placeholder={t('workflow.common.addDescription') || ''} placeholder={t('workflow.common.addDescription') || ''}
autoSize
/> />
</div> </div>
) )

View File

@ -89,7 +89,6 @@
"pinyin-pro": "^3.25.0", "pinyin-pro": "^3.25.0",
"qrcode.react": "^4.2.0", "qrcode.react": "^4.2.0",
"qs": "^6.13.0", "qs": "^6.13.0",
"rc-textarea": "^1.8.2",
"react": "19.0.0", "react": "19.0.0",
"react-18-input-autosize": "^3.0.0", "react-18-input-autosize": "^3.0.0",
"react-dom": "19.0.0", "react-dom": "19.0.0",
@ -107,6 +106,7 @@
"react-slider": "^2.0.6", "react-slider": "^2.0.6",
"react-sortablejs": "^6.1.4", "react-sortablejs": "^6.1.4",
"react-syntax-highlighter": "^15.6.1", "react-syntax-highlighter": "^15.6.1",
"react-textarea-autosize": "^8.5.8",
"react-tooltip": "5.8.3", "react-tooltip": "5.8.3",
"react-window": "^1.8.10", "react-window": "^1.8.10",
"react-window-infinite-loader": "^1.0.9", "react-window-infinite-loader": "^1.0.9",

125
web/pnpm-lock.yaml generated
View File

@ -205,9 +205,6 @@ importers:
qs: qs:
specifier: ^6.13.0 specifier: ^6.13.0
version: 6.13.0 version: 6.13.0
rc-textarea:
specifier: ^1.8.2
version: 1.8.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: react:
specifier: 19.0.0 specifier: 19.0.0
version: 19.0.0 version: 19.0.0
@ -259,6 +256,9 @@ importers:
react-syntax-highlighter: react-syntax-highlighter:
specifier: ^15.6.1 specifier: ^15.6.1
version: 15.6.1(react@19.0.0) version: 15.6.1(react@19.0.0)
react-textarea-autosize:
specifier: ^8.5.8
version: 8.5.8(@types/react@18.2.79)(react@19.0.0)
react-tooltip: react-tooltip:
specifier: 5.8.3 specifier: 5.8.3
version: 5.8.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) version: 5.8.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@ -6965,30 +6965,6 @@ packages:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
rc-input@1.6.3:
resolution: {integrity: sha512-wI4NzuqBS8vvKr8cljsvnTUqItMfG1QbJoxovCgL+DX4eVUcHIjVwharwevIxyy7H/jbLryh+K7ysnJr23aWIA==}
peerDependencies:
react: '>=16.0.0'
react-dom: '>=16.0.0'
rc-resize-observer@1.4.0:
resolution: {integrity: sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==}
peerDependencies:
react: '>=16.9.0'
react-dom: '>=16.9.0'
rc-textarea@1.8.2:
resolution: {integrity: sha512-UFAezAqltyR00a8Lf0IPAyTd29Jj9ee8wt8DqXyDMal7r/Cg/nDt3e1OOv3Th4W6mKaZijjgwuPXhAfVNTN8sw==}
peerDependencies:
react: '>=16.9.0'
react-dom: '>=16.9.0'
rc-util@5.43.0:
resolution: {integrity: sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==}
peerDependencies:
react: '>=16.9.0'
react-dom: '>=16.9.0'
re-resizable@6.10.0: re-resizable@6.10.0:
resolution: {integrity: sha512-hysSK0xmA5nz24HBVztlk4yCqCLCvS32E6ZpWxVKop9x3tqCa4yAj1++facrmkOf62JsJHjmjABdKxXofYioCw==} resolution: {integrity: sha512-hysSK0xmA5nz24HBVztlk4yCqCLCvS32E6ZpWxVKop9x3tqCa4yAj1++facrmkOf62JsJHjmjABdKxXofYioCw==}
peerDependencies: peerDependencies:
@ -7146,6 +7122,12 @@ packages:
peerDependencies: peerDependencies:
react: '>= 0.14.0' react: '>= 0.14.0'
react-textarea-autosize@8.5.8:
resolution: {integrity: sha512-iUiIj70JefrTuSJ4LbVFiSqWiHHss5L63L717bqaWHMgkm9sz6eEvro4vZ3uQfGJbevzwT6rHOszHKA8RkhRMg==}
engines: {node: '>=10'}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-tooltip@5.8.3: react-tooltip@5.8.3:
resolution: {integrity: sha512-h7maAlm2Xeymc14gWKhhrzsENeB83N65EzZ+AcQIGrOpNE0yefVRJIHhNcWHEJ0FEtf7VZXxtsj5glVXKxEtvA==} resolution: {integrity: sha512-h7maAlm2Xeymc14gWKhhrzsENeB83N65EzZ+AcQIGrOpNE0yefVRJIHhNcWHEJ0FEtf7VZXxtsj5glVXKxEtvA==}
peerDependencies: peerDependencies:
@ -8142,12 +8124,39 @@ packages:
resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
use-composed-ref@1.4.0:
resolution: {integrity: sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
use-context-selector@2.0.0: use-context-selector@2.0.0:
resolution: {integrity: sha512-owfuSmUNd3eNp3J9CdDl0kMgfidV+MkDvHPpvthN5ThqM+ibMccNE0k+Iq7TWC6JPFvGZqanqiGCuQx6DyV24g==} resolution: {integrity: sha512-owfuSmUNd3eNp3J9CdDl0kMgfidV+MkDvHPpvthN5ThqM+ibMccNE0k+Iq7TWC6JPFvGZqanqiGCuQx6DyV24g==}
peerDependencies: peerDependencies:
react: '>=18.0.0' react: '>=18.0.0'
scheduler: '>=0.19.0' scheduler: '>=0.19.0'
use-isomorphic-layout-effect@1.2.0:
resolution: {integrity: sha512-q6ayo8DWoPZT0VdG4u3D3uxcgONP3Mevx2i2b0434cwWBoL+aelL1DzkXI6w3PhTZzUeR2kaVlZn70iCiseP6w==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
use-latest@1.3.0:
resolution: {integrity: sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==}
peerDependencies:
'@types/react': '*'
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@types/react':
optional: true
use-strict@1.0.1: use-strict@1.0.1:
resolution: {integrity: sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ==} resolution: {integrity: sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ==}
@ -16708,40 +16717,6 @@ snapshots:
range-parser@1.2.1: {} range-parser@1.2.1: {}
rc-input@1.6.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@babel/runtime': 7.25.7
classnames: 2.5.1
rc-util: 5.43.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
rc-resize-observer@1.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@babel/runtime': 7.25.7
classnames: 2.5.1
rc-util: 5.43.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
resize-observer-polyfill: 1.5.1
rc-textarea@1.8.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@babel/runtime': 7.25.7
classnames: 2.5.1
rc-input: 1.6.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
rc-resize-observer: 1.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
rc-util: 5.43.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
rc-util@5.43.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@babel/runtime': 7.25.7
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
react-is: 18.3.1
re-resizable@6.10.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): re-resizable@6.10.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
@ -16919,6 +16894,15 @@ snapshots:
react: 19.0.0 react: 19.0.0
refractor: 3.6.0 refractor: 3.6.0
react-textarea-autosize@8.5.8(@types/react@18.2.79)(react@19.0.0):
dependencies:
'@babel/runtime': 7.25.7
react: 19.0.0
use-composed-ref: 1.4.0(@types/react@18.2.79)(react@19.0.0)
use-latest: 1.3.0(@types/react@18.2.79)(react@19.0.0)
transitivePeerDependencies:
- '@types/react'
react-tooltip@5.8.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0): react-tooltip@5.8.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies: dependencies:
'@floating-ui/dom': 1.1.1 '@floating-ui/dom': 1.1.1
@ -18089,11 +18073,30 @@ snapshots:
punycode: 1.4.1 punycode: 1.4.1
qs: 6.13.0 qs: 6.13.0
use-composed-ref@1.4.0(@types/react@18.2.79)(react@19.0.0):
dependencies:
react: 19.0.0
optionalDependencies:
'@types/react': 18.2.79
use-context-selector@2.0.0(react@19.0.0)(scheduler@0.23.2): use-context-selector@2.0.0(react@19.0.0)(scheduler@0.23.2):
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
scheduler: 0.23.2 scheduler: 0.23.2
use-isomorphic-layout-effect@1.2.0(@types/react@18.2.79)(react@19.0.0):
dependencies:
react: 19.0.0
optionalDependencies:
'@types/react': 18.2.79
use-latest@1.3.0(@types/react@18.2.79)(react@19.0.0):
dependencies:
react: 19.0.0
use-isomorphic-layout-effect: 1.2.0(@types/react@18.2.79)(react@19.0.0)
optionalDependencies:
'@types/react': 18.2.79
use-strict@1.0.1: {} use-strict@1.0.1: {}
use-sync-external-store@1.2.2(react@19.0.0): use-sync-external-store@1.2.2(react@19.0.0):