hooks.ts 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import {
  2. useCallback,
  3. useRef,
  4. useState,
  5. } from 'react'
  6. import type { TextAreaRef } from 'rc-textarea'
  7. export const useTextAreaHeight = () => {
  8. const wrapperRef = useRef<HTMLDivElement>(null)
  9. const textareaRef = useRef<TextAreaRef>(null)
  10. const textValueRef = useRef<HTMLDivElement>(null)
  11. const holdSpaceRef = useRef<HTMLDivElement>(null)
  12. const [isMultipleLine, setIsMultipleLine] = useState(false)
  13. const handleComputeHeight = useCallback(() => {
  14. const textareaElement = textareaRef.current?.resizableTextArea.textArea
  15. if (wrapperRef.current && textareaElement && textValueRef.current && holdSpaceRef.current) {
  16. const { width: wrapperWidth } = wrapperRef.current.getBoundingClientRect()
  17. const { height: textareaHeight } = textareaElement.getBoundingClientRect()
  18. const { width: textValueWidth } = textValueRef.current.getBoundingClientRect()
  19. const { width: holdSpaceWidth } = holdSpaceRef.current.getBoundingClientRect()
  20. if (textareaHeight > 32) {
  21. setIsMultipleLine(true)
  22. }
  23. else {
  24. if (textValueWidth + holdSpaceWidth >= wrapperWidth)
  25. setIsMultipleLine(true)
  26. else
  27. setIsMultipleLine(false)
  28. }
  29. }
  30. }, [])
  31. const handleTextareaResize = useCallback(() => {
  32. handleComputeHeight()
  33. }, [handleComputeHeight])
  34. return {
  35. wrapperRef,
  36. textareaRef,
  37. textValueRef,
  38. holdSpaceRef,
  39. handleTextareaResize,
  40. isMultipleLine,
  41. }
  42. }