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 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
nullif the textarea is not yet rendered.
value: A string representing the content of the textarea.
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.heightof 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
Finally, it sets
style.heightof 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
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.
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
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
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.
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.