DEV Community

poshiya parth s
poshiya parth s

Posted on

4

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

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs