11import type React from 'react' ;
2- import { useEffect , useRef } from 'react' ;
2+ import { useCallback , useEffect , useRef } from 'react' ;
33
44import { Button } from '@/components/ui/button' ;
55
@@ -16,6 +16,8 @@ interface TargetPanelProps {
1616 moveToNextVerse : ( ) => void ;
1717 scrollRef : React . RefObject < HTMLDivElement > ;
1818 onScroll : ( scrollTop : number ) => void ;
19+ textareaHeights : Record < number , number > ;
20+ onHeightChange : ( verseId : number , height : number ) => void ;
1921}
2022
2123export const TargetPanel : React . FC < TargetPanelProps > = ( {
@@ -29,14 +31,21 @@ export const TargetPanel: React.FC<TargetPanelProps> = ({
2931 moveToNextVerse,
3032 scrollRef,
3133 onScroll,
34+ textareaHeights,
35+ onHeightChange,
3236} ) => {
3337 const textareaRefs = useRef < Record < number , HTMLTextAreaElement | null > > ( { } ) ;
3438 const verseRefs = useRef < Record < number , HTMLDivElement | null > > ( { } ) ;
3539
36- const autoResizeTextarea = ( textarea : HTMLTextAreaElement ) => {
37- textarea . style . height = 'auto' ;
38- textarea . style . height = Math . max ( 20 , textarea . scrollHeight ) + 'px' ;
39- } ;
40+ const autoResizeTextarea = useCallback (
41+ ( textarea : HTMLTextAreaElement , verseId : number ) => {
42+ textarea . style . height = 'auto' ;
43+ const newHeight = Math . max ( 20 , textarea . scrollHeight ) ;
44+ textarea . style . height = newHeight + 'px' ;
45+ onHeightChange ( verseId , newHeight ) ;
46+ } ,
47+ [ onHeightChange ]
48+ ) ;
4049
4150 const handleVerseClick = async ( verseId : number ) => {
4251 const verse = verses . find ( v => v . verseNumber === verseId ) ;
@@ -63,7 +72,7 @@ export const TargetPanel: React.FC<TargetPanelProps> = ({
6372
6473 const textarea = textareaRefs . current [ verseId ] ;
6574 if ( textarea ) {
66- autoResizeTextarea ( textarea ) ;
75+ autoResizeTextarea ( textarea , verseId ) ;
6776 }
6877 } ;
6978
@@ -96,9 +105,14 @@ export const TargetPanel: React.FC<TargetPanelProps> = ({
96105
97106 if ( textarea ) {
98107 textarea . focus ( ) ;
99- autoResizeTextarea ( textarea ) ;
108+ const syncHeight = textareaHeights [ activeVerseId ] ;
109+ if ( syncHeight ) {
110+ textarea . style . height = syncHeight + 'px' ;
111+ } else {
112+ autoResizeTextarea ( textarea , activeVerseId ) ;
113+ }
100114 }
101- } , [ activeVerseId , scrollRef ] ) ;
115+ } , [ activeVerseId , scrollRef , textareaHeights , autoResizeTextarea ] ) ;
102116
103117 useEffect ( ( ) => {
104118 if ( verses . length === 0 ) {
@@ -111,12 +125,17 @@ export const TargetPanel: React.FC<TargetPanelProps> = ({
111125 } else {
112126 verses . forEach ( verse => {
113127 const textarea = textareaRefs . current [ verse . verseNumber ] ;
114- if ( textarea && verse . content ) {
115- autoResizeTextarea ( textarea ) ;
128+ if ( textarea ) {
129+ const syncHeight = textareaHeights [ verse . verseNumber ] ;
130+ if ( syncHeight ) {
131+ textarea . style . height = syncHeight + 'px' ;
132+ } else if ( verse . content ) {
133+ autoResizeTextarea ( textarea , verse . verseNumber ) ;
134+ }
116135 }
117136 } ) ;
118137 }
119- } , [ setVerses , verses ] ) ;
138+ } , [ setVerses , verses , textareaHeights , autoResizeTextarea ] ) ;
120139
121140 return (
122141 < div className = 'flex h-full flex-col' >
@@ -155,6 +174,11 @@ export const TargetPanel: React.FC<TargetPanelProps> = ({
155174 ref = { el => ( textareaRefs . current [ verseId ] = el ) }
156175 className = 'h-auto min-h-[20px] w-full resize-none content-center overflow-hidden border-none bg-transparent text-base leading-relaxed leading-snug text-gray-800 outline-none'
157176 placeholder = 'Enter translation...'
177+ style = { {
178+ height : textareaHeights [ verseId ]
179+ ? `${ textareaHeights [ verseId ] } px`
180+ : 'auto' ,
181+ } }
158182 value = { TargetVerse . content }
159183 onChange = { e => handleTextChange ( verseId , e . target . value ) }
160184 onFocus = { ( ) => handleFocus ( verseId ) }
0 commit comments