| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 | import { useEffect, useRef } from 'react'import cn from '@/utils/classnames'import { sleep } from '@/utils'type IProps = {  placeholder?: string  value: string  onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void  className?: string  wrapperClassName?: string  minHeight?: number  maxHeight?: number  autoFocus?: boolean  controlFocus?: number  onKeyDown?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void  onKeyUp?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void}const AutoHeightTextarea = (  {    ref: outerRef,    value,    onChange,    placeholder,    className,    wrapperClassName,    minHeight = 36,    maxHeight = 96,    autoFocus,    controlFocus,    onKeyDown,    onKeyUp,  }: IProps & {    ref: React.RefObject<unknown>;  },) => {  // 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 = async () => {    if (!doFocus()) {      let hasFocus = false      await sleep(100)      hasFocus = doFocus()      if (!hasFocus)        focus()    }  }  useEffect(() => {    if (autoFocus)      focus()  }, [])  useEffect(() => {    if (controlFocus)      focus()  }, [controlFocus])  return (    (<div className={`relative ${wrapperClassName}`}>      <div className={cn(className, 'invisible overflow-y-auto whitespace-pre-wrap  break-all')} style={{        minHeight,        maxHeight,        paddingRight: (value && value.trim().length > 10000) ? 140 : 130,      }}>        {!value ? placeholder : value.replace(/\n$/, '\n ')}      </div>      <textarea        ref={ref}        autoFocus={autoFocus}        className={cn(className, 'absolute inset-0 resize-none overflow-auto')}        style={{          paddingRight: (value && value.trim().length > 10000) ? 140 : 130,        }}        placeholder={placeholder}        onChange={onChange}        onKeyDown={onKeyDown}        onKeyUp={onKeyUp}        value={value}      />    </div>)  )}AutoHeightTextarea.displayName = 'AutoHeightTextarea'export default AutoHeightTextarea
 |