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 benull
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 to0px
. 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);
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);
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.