We are working on new components <3
HextaUIHextaUI
ApplicationFeedback

Feedback

Animated Feedback component with icons and textarea.

Preview

Code

Feedback.tsx
"use client";
 
import { FaRegSmileBeam } from "react-icons/fa";
import { FaRegSmile } from "react-icons/fa";
import { FaRegSadTear } from "react-icons/fa";
import { FaRegSadCry } from "react-icons/fa";
 
import { useRef, useEffect, useState } from "react";
 
import { Button } from "@/components/ui/button";
 
export const FeedbackRating = () => {
  const [rating, setRating] = useState<number | null>(0);
  const [feedbackActive, setFeedbackActive] = useState(false);
  const node = useRef<HTMLDivElement>(null);
 
  useEffect(() => {
    if (feedbackActive === true) {
      const handleClickOutside = (e: MouseEvent) => {
        if (node.current && !node.current.contains(e.target as Node)) {
          setFeedbackActive(false);
          setRating(null);
        }
      };
      document.addEventListener("mousedown", handleClickOutside);
      return () => {
        document.removeEventListener("mousedown", handleClickOutside);
      };
    }
  }, [feedbackActive]);
 
  return (
    <>
      <div
        ref={node}
        className={`flex gap-4 px-6 py-3 bg-secondary/50 border-opacity-10 shadow-sm border border-primary/10 items-start transition-all ease-in-out overflow-hidden flex-col max-[315px]:scale-95 ${
          feedbackActive ? "rounded-md" : "rounded-full"
        } ${
          feedbackActive ? "max-[374px]:h-[16rem] h-[13rem]" : "h-[3.5rem]"
        } ${
          feedbackActive ? "w-[19rem] max-[374px]:w-[15rem]" : "w-[12.3rem]"
        } ${feedbackActive ? "max-[374px]:justify-center" : "justify-end"}`}
        style={{
          transition: feedbackActive
            ? "border-radius 0.2s ease-in-out, width 0.2s ease-in-out 0.2s, height 0.2s ease-in-out 0.2s"
            : "border-radius 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out",
        }}
      >
        <div className="w-full">
          <textarea
            className="w-full h-[8rem] p-2 rounded-md border border-primary/10 border-opacity-10 resize-none -mb-1 text-primary outline-none text-sm transition-all duration-500"
            style={{
              filter: feedbackActive ? "blur(0px)" : "blur(100px)",
            }}
            placeholder="Your feedback..."
          />
        </div>
        <div
          className={`flex justify-between w-full ${
            feedbackActive && "max-[374px]:flex-col"
          } ${feedbackActive ? "gap-4" : "gap-8"}`}
        >
          <div
            className={`flex items-center mt-1.5 ${
              feedbackActive && "justify-center"
            } gap-4`}
          >
            {" "}
            <button
              onClick={() => {
                setRating(1);
                setFeedbackActive(true);
              }}
              className="active:scale-[.95] hover:scale-105 transition-all duration-400 text-primary"
            >
              <FaRegSadCry
                size={25}
                className={`${rating === 1 ? "opacity-100" : "opacity-50"}`}
                fill={`${rating === 1 ? "red" : "currentColor"}`}
              />
            </button>{" "}
            <button
              onClick={() => {
                setRating(2);
                setFeedbackActive(true);
              }}
              className="active:scale-[.95] hover:scale-105 transition-all duration-400 text-primary"
            >
              <FaRegSadTear
                size={25}
                className={`${rating === 2 ? "opacity-100" : "opacity-50"}`}
                fill={`${rating === 2 ? "orange" : "currentColor"}`}
              />
            </button>{" "}
            <button
              onClick={() => {
                setRating(3);
                setFeedbackActive(true);
              }}
              className="active:scale-[.95] hover:scale-105 transition-all duration-400 text-primary"
            >
              <FaRegSmile
                size={25}
                className={`${rating === 3 ? "opacity-100" : "opacity-50"}`}
                fill={`${rating === 3 ? "white" : "currentColor"}`}
              />
            </button>
            <button
              onClick={() => {
                setRating(4);
                setFeedbackActive(true);
              }}
              className="active:scale-[.95] hover:scale-105 transition-all duration-400 text-primary"
            >
              <FaRegSmileBeam
                size={25}
                className={`${rating === 4 ? "opacity-100" : "opacity-50"}`}
                fill={`${rating === 4 ? "lightgreen" : "currentColor"}`}
              />
            </button>
          </div>
          <div>
            <Button className="text-sm px-2 py-1 max-[374px]:w-full max-[374px]:py-2 flex items-center justify-center">
              Send
            </Button>
          </div>
        </div>
      </div>
    </>
  );
};
Edit on GitHub

Last updated on

On this page