How to Dynamically Adjust the Height of a Textarea in ReactJS

Sachin Chaurasiya - Oct 26 '23 - - Dev Community

Introduction

Have you ever been curious about how platforms like Notion, Hashnode, and others dynamically adjust the height of their page or article titles (text areas)? If you've noticed, as you type content into a textarea, the height is dynamically calculated based on the content on these platforms.

I wanted to achieve the same behavior on the OpenMetadata Knowledge articles page. In this blog post, I will share how I tackled this challenge using a custom hook.

Custom hook

Custom hooks in ReactJS are reusable pieces of code that encapsulate logic and state management.

Alright, let's move further with the useAutoSizeTextArea custom hook which will dynamically adjust the height of the textarea based on its content.

It takes three parameters as input

  • id: A string representing the unique identifier of the textarea element.

  • textAreaRef: A reference to the HTMLTextAreaElement that you want to resize. This can be null if the textarea is not yet rendered.

  • value: A string representing the content of the textarea.

Inside the useLayoutEffect hook, it checks if the textAreaRef is available. If it's not, it tries to find the textarea element using the provided id by querying the document's DOM.

If a valid textarea element is found (either through textAreaRef or by querying the DOM with the provided id), it proceeds to adjust the height of the textarea to fit its content. It does this by following these steps.

  • Initially, it sets the style.height of the textarea to 0px. This temporarily hides the textarea to avoid flickering when calculating the scroll height.

  • It then calculates the scrollHeight of the textarea, which represents the full content height, even if it's not currently visible due to the height being set to 0px.

  • Finally, it sets style.height of the textarea to the calculated scrollHeight, effectively resizing the textarea to fit its content.

The hook is set to run whenever any of the dependencies ([textAreaRef, id, value]) change. This means that if the textAreaRef, id, or value of the textarea changes, the hook will recalculate the textarea's height to ensure it fits the new content.

Now, let's incorporate this custom hook into an example application.

Example

For the purpose of this example, I will be using CodeSandbox to avoid local setup and focus on the topic of this blog.

Here we have a simple App component that renders the h2 and textarea.

const textAreaRef = useRef<HTMLTextAreaElement>(null);
Enter fullscreen mode Exit fullscreen mode

This code creates a reference for the textarea element and then passes it to the textarea element at line 24.

useAutoSizeTextArea("title-input", textAreaRef.current, value);
Enter fullscreen mode Exit fullscreen mode

The magic piece is this: using the useAutoSizeTextArea custom hook and passing the id, textarea element from the textAreaRef, and, finally, the value.

Feel free to experiment with the example to observe how it dynamically calculates the height as you modify the content. Additionally, try commenting out line number 12 to see how the textarea becomes vertically scrollable, and the height remains static.

Conclusion

In this blog post, I have demonstrated how I addressed the challenge of dynamically adjusting the height of a textarea element based on its content, preventing the need for vertical scrolling in the title section of the OpenMetadata Knowledge article page.

And that’s it for this topic. Thank you for reading.

If you found this article useful, please consider liking and sharing it with others. If you have any questions, feel free to comment, and I will do my best to respond.

Resource 💡

Connect with me 👋

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player