Files
webapp-conversation/app/components/base/auto-height-textarea/index.tsx
lyzno1 05dcfcf0ca feat: migrate ESLint to v9 flat config
- Replace .eslintrc.json with eslint.config.mjs
- Simplify configuration using @antfu/eslint-config
- Add necessary ESLint plugin dependencies
- Disable overly strict style rules
- Set package.json type to module for ESM support
- Fix ESLint disable comment format

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-15 10:55:10 +08:00

72 lines
1.9 KiB
TypeScript

import { forwardRef, useEffect, useRef } from 'react'
import cn from 'classnames'
interface IProps {
placeholder?: string
value: string
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void
className?: string
minHeight?: number
maxHeight?: number
autoFocus?: boolean
controlFocus?: number
onKeyDown?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void
onKeyUp?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void
}
const AutoHeightTextarea = forwardRef(
(
{ value, onChange, placeholder, className, minHeight = 36, maxHeight = 96, autoFocus, controlFocus, onKeyDown, onKeyUp }: IProps,
outerRef: any,
) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const ref = outerRef || useRef<HTMLTextAreaElement>(null)
const doFocus = () => {
if (ref.current) {
ref.current.setSelectionRange(value.length, value.length)
ref.current.focus()
return true
}
return false
}
const focus = () => {
if (!doFocus()) {
let hasFocus = false
const runId = setInterval(() => {
hasFocus = doFocus()
if (hasFocus) { clearInterval(runId) }
}, 100)
}
}
useEffect(() => {
if (autoFocus) { focus() }
}, [])
useEffect(() => {
if (controlFocus) { focus() }
}, [controlFocus])
return (
<div className='relative'>
<div className={cn(className, 'invisible whitespace-pre-wrap break-all overflow-y-auto')} style={{ minHeight, maxHeight }}>
{!value ? placeholder : value.replace(/\n$/, '\n ')}
</div>
<textarea
ref={ref}
autoFocus={autoFocus}
className={cn(className, 'absolute inset-0 resize-none overflow-hidden')}
placeholder={placeholder}
onChange={onChange}
onKeyDown={onKeyDown}
onKeyUp={onKeyUp}
value={value}
/>
</div>
)
},
)
export default AutoHeightTextarea