Get Back
December 23, 2024
Search Dialog Animation Framer Motion
tricks

SearchButton Component Documentation

The SearchButton component is a React-based UI element that allows users to initiate a search action. This component is styled with Tailwind CSS and uses Framer Motion for smooth animations. It provides a visually appealing search interaction with animations for opening and closing the search modal, as well as dynamic transitions for when the user types a query.

Here's a breakdown of how the component works, including its functionality and key sections of the code.


Functionality Overview

The component performs the following tasks:

  1. Search Button Display:

    • The SearchButton renders a button with an icon and label.
    • When clicked, it triggers the opening of a search modal.
  2. Search Modal Animation:

    • Upon clicking the search button, a modal pops up with an input field for typing search queries.
    • The modal and the input field are animated using Framer Motion for smooth transitions.
    • A translucent backdrop appears when the search modal is open, and clicking on it closes the modal.
  3. Search String Display:

    • The modal contains a search input field.
    • If the user starts typing, a message is displayed, showing the current search query.
    • The display is animated when the user types, and a smooth transition occurs if the input is cleared.

Component Structure

The SearchButton component is structured into several key parts:

1. State Management

The component uses two useState hooks to manage the following states:

  • openSearch: Boolean state to determine if the search modal is visible.
  • searchString: Stores the search query that the user types into the input field.



const [openSearch, setOpenSearch] = useState(false);
const [searchString, setSearchString] = useState("");


          

2. Search Button (Trigger)

This is the main clickable button that users interact with to open the search modal. It includes an icon and a label. When clicked, it sets the openSearch state to true, triggering the modal to appear.


<button
  onClick={() => {
    setOpenSearch(true);
  }}
>
  <div className=" px-4 py-2 rounded-full ring-2 ring-foreground opacity-50 hover:opacity-100 duration-300 transition-all ease-in-out  flex items-center gap-2">
    <div className=" text-sm">SearchButton</div>
    <div>
      <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-search">
        <circle cx="11" cy="11" r="8" />
        <path d="m21 21-4.3-4.3" />
      </svg>
    </div>
  </div>
</button>

          

3. Search Modal (Hidden Initially)

The modal is rendered only when openSearch is true. It is animated into view using Framer Motion. The modal features a translucent backdrop, and the modal content slides in with a transition. Clicking outside the modal (on the backdrop) closes it by setting openSearch to false.


<AnimatePresence mode="wait">
  {openSearch && (
    <motion.div
      key={openSearch ? "searchisOpen" : "searchisClose"}
      initial={{
        opacity: 0,
      }}
      animate={{
        opacity: 1,
      }}
      exit={{
        opacity: 0,
      }}
      className=" fixed z-40 h-full w-full top-0 left-0 flex items-center justify-center"
    >
      <div
        onClick={() => {
          setOpenSearch(false);
        }}
        className=" bg-background/60 backdrop-blur-md w-full h-full absolute z-20 "
      />
    </motion.div>
  )}
</AnimatePresence>

          

4. Search Input Field

This is the main component of the modal, where users type their search query. The input field is styled to have a search icon on the left, and as the user types, the input field displays the current search query. If the searchString is not empty, a message dynamically displays the current search term.


<motion.div
  key={openSearch ? "searchisOpen" : "searchisClose"}
  initial={{
    opacity: 0,
    y: 50,
  }}
  animate={{
    opacity: 1,
    y: 0,
    transition: {
      delay: 0.4,
      ease: [0.25, 1, 0.5, 1],
    },
  }}
  exit={{
    opacity: 0,
    y: 50,
    transition: {
      ease: [0.5, 0, 0.75, 0],
    },
  }}
  className=" p-5 rounded-md bg-foreground text-background  relative max-w-md w-full z-30 -mt-24"
>
  <div className="relative">
    <div className=" absolute left-0 top-1/2 -translate-y-1/2 ">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="20"
        height="20"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
        className="lucide lucide-search"
      >
        <circle cx="11" cy="11" r="8" />
        <path d="m21 21-4.3-4.3" />
      </svg>
    </div>
    <input
      placeholder="Search..."
      value={searchString}
      onChange={(e) => setSearchString(e.target.value)}
      className=" focus-visible:outline-none bg-foreground pl-8 w-full py-1 text-xl font-mono "
      type="text"
    />
  </div>
</motion.div>

          

5. Search Query Display

As users type, a dynamic message displays the current search string. The animation is controlled using Framer Motion's AnimatePresence and motion.div. This part of the component is only shown if the searchString is not empty.


<AnimatePresence mode="wait">
  {searchString == "" ? null : (
    <motion.div
      key={searchString == "" ? "empty" : "filled"}
      initial={{
        minHeight: "0rem",
        opacity: 0,
      }}
      animate={{
        minHeight: "11rem",
        opacity: 1,
        transition: {
          duration: 0.6,
          ease: [0.25, 1, 0.5, 1],
        },
      }}
      exit={{
        minHeight: "0rem",
        opacity: 0,
        transition: {
          duration: 0.6,
          ease: [0.5, 0, 0.75, 0],
        },
      }}
      className=" flex text-sm opacity-75 items-center justify-center py-3"
    >
      <motion.p
        key={searchString == "" ? "empty" : "filled"}
        initial={{
          y: -50,
        }}
        animate={{
          y: 0,
          transition: {
            duration: 0.6,
            ease: [0.25, 1, 0.5, 1],
          },
        }}
        exit={{
          y: -50,
          transition: {
            duration: 0.6,
            ease: [0.5, 0, 0.75, 0],
          },
        }}
      >
        searching for {searchString}
      </motion.p>
    </motion.div>
  )}
</AnimatePresence>

          

Styling and Responsiveness

  • Tailwind CSS: The component uses utility-first CSS classes from Tailwind to style the button, modal, input field, and animations.
  • Mobile-First Design: The layout adjusts to different screen sizes, with a fixed search modal that takes up the full screen on small devices.

To use this SearchButton component, you can simply import it and place it within your React component tree:


import SearchButton from "./path-to-SearchButton";

function App() {
  return (
    <div>
      <SearchButton />
    </div>
  );
}

export default App;

          

Conclusion

The SearchButton component offers a clean and interactive way for users to perform searches. Its animation-powered design makes the interaction feel modern, while the use of Tailwind CSS ensures a responsive layout. By integrating Framer Motion, the component provides smooth transitions, improving the overall user experience.

You Can Check Github Repo For Better Understanding
Made With Kisses By Mohamed Rafik