DEV Community

poshiya parth s
poshiya parth s

Posted on

Implementing Autosize Textarea in React: A Complete Guide

Introduction
Creating a seamless user experience often hinges on the small details, such as a well-designed text area for user input. In this blog post, we’ll dive into the implementation of a dynamic text area using React, which adjusts its height based on the input content and provides a smooth user experience.

Component Breakdown
CommonTextArea Component
The CommonTextArea component is a reusable component that encapsulates the logic for a dynamic text area. Here’s a detailed look at its structure and functionality:

import clsx from "clsx";
import { useLayoutEffect, useState } from "react";

export default function CommonTextArea({
  inputRef,
  isFocuse,
  isInputError,
  onChangeInput,
  handleKeyDown,
  setIsFocuse,
  textBoxValue,
  parentClassName,
  textAreaClassName,
  placeHolder,
}: {
  inputRef: React.RefObject<HTMLTextAreaElement>;
  isFocuse?: boolean;
  isInputError?: boolean;
  onChangeInput: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
  handleKeyDown: (event: React.KeyboardEvent<HTMLTextAreaElement>) => void;
  setIsFocuse: React.Dispatch<React.SetStateAction<boolean>>;
  textBoxValue?: string;
  parentClassName?: string;
  textAreaClassName?: string;
  placeHolder?: string;
}) {
  const [scrollBar, setScrollBar] = useState<boolean>(false);

  useLayoutEffect(() => {
    const textArea: any =
      inputRef.current ?? document.getElementById("text_area_input");

    if (textArea) {
      textArea.style.height = "0px";
      const scrollHeight = textArea.scrollHeight;
      textArea.style.height = scrollHeight + "px";
      if (scrollHeight >= 200) {
        setScrollBar(true);
      } else {
        setScrollBar(false);
      }
    }
  }, [inputRef, textBoxValue]);

  return (
    <div
      className={clsx(
        {
          "form-input-error": isInputError,
          "ask-question-input-focus": isFocuse,
        },
        parentClassName
      )}
      onClick={() => {
        setIsFocuse(true);
      }}
    >
      <textarea
        id="text_area_input"
        ref={inputRef}
        className={clsx(textAreaClassName, "textarea_design", {
          "overflow-y-auto": scrollBar,
        })}
        placeholder={placeHolder}
        value={textBoxValue}
        onClick={() => {
          setIsFocuse(true);
        }}
        onKeyDown={handleKeyDown}
        style={{ height: "57px" }}
        onChange={onChangeInput}
      />
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Key Features
Dynamic Height Adjustment: The text area dynamically adjusts its height based on the input content, ensuring that users have a comfortable and responsive typing experience.
Conditional Styling: The component uses the clsx library to conditionally apply styles based on the component's state, such as focus or error states.
Scrollable Content: When the content exceeds a certain height, a scrollbar appears, ensuring that the text area remains user-friendly and does not overflow.
App Component Integration
The CommonTextArea component can be easily integrated into any React application. Here’s how you can use it:

const inputRef = useRef<HTMLTextAreaElement | null>(null);
const [isFocuse, setIsFocuse] = useState<boolean>(false);
const [isInputError, setIsInputError] = useState<boolean>(false);

const onChangeInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
  setChatPrompt(e.target.value);
  setIsInputError(false);
};

const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
  setIsFocuse(true);

  if (e.key === "Enter" && !e.shiftKey) {
    e.preventDefault();
    onSubmitdata(); // submit event
  }
};

useEffect(() => {
  inputRef?.current?.focus();
}, [inputRef]);

return (
  <CommonTextArea
    inputRef={inputRef}
    isFocuse={isFocuse}
    isInputError={isInputError}
    onChangeInput={onChangeInput}
    handleKeyDown={handleKeyDown}
    setIsFocuse={setIsFocuse}
    textBoxValue={"default text box value"}
    parentClassName={"text_area_parent "}
    textAreaClassName={"ask-question-input caret-raisinblack"}
  />
);

Enter fullscreen mode Exit fullscreen mode

CSS Styling
Proper styling is crucial for a great user experience. Here are the styles used in this implementation:

.form-input-error {
  border-color: red;
  background-color: #f5f5f5;
}

.ask-question-input-focus {
  outline: none;
  border-color: #0f9d58;
  color: #2d2d2d;
  background-color: #e6f4ea;
}

.text_area_parent {
  width: 100%;
  background-color: #f5f5f5;
  display: flex;
  justify-content: start;
  align-items: center;
  padding: 5px;
  border-radius: 10px;
  font-size: 16px;
  border: 1px solid transparent;
  transition: border-color 0.3s, background-color 0.3s;
}

.ask-question-input {
  width: 100%;
  background-color: transparent;
  font-size: 16px;
  border: none;
  outline: none;
  resize: none;
  overflow: hidden;
  max-height: 230px;
  padding: 14px;
}

.ask-question-input::-webkit-scrollbar-thumb {
  background-color: #d9d9d9;
}

Enter fullscreen mode Exit fullscreen mode

Conclusion
By implementing a dynamic text area in your React application, you can significantly enhance user experience, making text inputs more user-friendly and visually appealing. The CommonTextArea component is highly customizable and can be adapted to various use cases, ensuring a consistent and responsive design throughout your application.

[(https://andarist.github.io/react-textarea-autosize/)]
[https://www.npmjs.com/package/react-textarea-autosize]

also you dont want to custom then you can use this package

Top comments (0)