| import { forwardRef, useEffect, useRef } from 'react' | |
| import cn from '@/utils/classnames' | |
| type AutoHeightTextareaProps = | |
| & React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement> | |
| & { outerClassName?: string } | |
| const AutoHeightTextarea = forwardRef<HTMLTextAreaElement, AutoHeightTextareaProps>( | |
| ( | |
| { | |
| outerClassName, | |
| value, | |
| className, | |
| placeholder, | |
| autoFocus, | |
| disabled, | |
| ...rest | |
| }, | |
| outRef, | |
| ) => { | |
| const innerRef = useRef<HTMLTextAreaElement>(null) | |
| const ref = outRef || innerRef | |
| useEffect(() => { | |
| if (autoFocus && !disabled && value) { | |
| if (typeof ref !== 'function') { | |
| ref.current?.setSelectionRange(`${value}`.length, `${value}`.length) | |
| ref.current?.focus() | |
| } | |
| } | |
| }, [autoFocus, disabled, ref]) | |
| return ( | |
| <div className={outerClassName}> | |
| <div className='relative'> | |
| <div className={cn(className, 'invisible whitespace-pre-wrap break-all')}> | |
| {!value ? placeholder : `${value}`.replace(/\n$/, '\n ')} | |
| </div> | |
| <textarea | |
| ref={ref} | |
| placeholder={placeholder} | |
| className={cn(className, 'disabled:bg-transparent absolute inset-0 outline-none border-none appearance-none resize-none w-full h-full')} | |
| value={value} | |
| disabled={disabled} | |
| {...rest} | |
| /> | |
| </div> | |
| </div> | |
| ) | |
| }, | |
| ) | |
| export default AutoHeightTextarea | |