Created
February 12, 2024 18:23
-
-
Save tomasz-stefaniak/d27c9696c1131ad7997a10897249fcbf to your computer and use it in GitHub Desktop.
Custom hook for dynamically resizing a textarea to fit its content.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Custom hook for dynamically resizing a textarea to fit its content. | |
* @param {React.RefObject<HTMLTextAreaElement>} textareaRef - Reference to the textarea element. | |
* @param {string} textContent - Current text content of the textarea. | |
* @param {number} maxHeight - Optional: maxHeight of the textarea in pixels. | |
*/ | |
import { useEffect } from "react"; | |
export const useDynamicTextareaSize = ( | |
textareaRef: React.RefObject<HTMLTextAreaElement>, | |
textContent: string, | |
maxHeight?: number, | |
): void => { | |
useEffect(() => { | |
const currentTextarea = textareaRef.current; | |
if (currentTextarea) { | |
// Create an invisible clone of the textarea to measure content height without affecting the original textarea | |
const clone = currentTextarea.cloneNode(true) as HTMLTextAreaElement; | |
const style = clone.style; | |
// Apply styles to make the clone invisible and avoid affecting the layout | |
style.position = "absolute"; | |
style.visibility = "hidden"; | |
style.height = "auto"; | |
style.zIndex = "-1"; | |
// Reset the height to auto to ensure the clone expands to fit the content | |
style.height = "auto"; | |
// Append the clone to the body to measure its height | |
document.body.appendChild(clone); | |
// Calculate the height based on the scrollHeight of the clone | |
const contentHeight = clone.scrollHeight; | |
document.body.removeChild(clone); // Remove the clone after measurement | |
if (maxHeight) { | |
// Set max-height and adjust overflow behavior if maxHeight is provided | |
currentTextarea.style.maxHeight = `${maxHeight}px`; | |
currentTextarea.style.overflowY = | |
contentHeight > maxHeight ? "scroll" : "hidden"; | |
currentTextarea.style.height = `${Math.min(contentHeight, maxHeight)}px`; | |
} else { | |
// Adjust height without max height constraint | |
currentTextarea.style.height = `${contentHeight}px`; | |
// Ensure there's a minimum height | |
currentTextarea.style.minHeight = "75px"; | |
} | |
} | |
}, [textareaRef, textContent, maxHeight]); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment