Mudasir Fayaz

Amazing Dropdowns

Smooth, intuitive dropdown menus that make navigation and selection effortless.

Amazing Dropdowns Showcase

React Code
1import React, { useState, useRef, useEffect } from "react";
2
3interface DropdownItem {
4  label: string;
5  icon?: React.ReactNode;
6  onClick?: () => void;
7}
8
9interface DropdownProps {
10  label: string;
11  items: DropdownItem[];
12  variant?: "light" | "dark" | "gradient";
13}
14
15const Dropdown: React.FC<DropdownProps> = ({ label, items, variant = "dark" }) => {
16  const [open, setOpen] = useState(false);
17  const ref = useRef<HTMLDivElement>(null);
18
19  useEffect(() => {
20    const handleClickOutside = (e: MouseEvent) => {
21      if (ref.current && !ref.current.contains(e.target as Node)) {
22        setOpen(false);
23      }
24    };
25    document.addEventListener("mousedown", handleClickOutside);
26    return () => document.removeEventListener("mousedown", handleClickOutside);
27  }, []);
28
29  const variantStyles = {
30    light: {
31      button: "bg-white text-black border border-gray-300 hover:bg-gray-100",
32      menu: "bg-white text-gray-900 border border-gray-200 shadow-lg",
33      item: "hover:bg-gray-100",
34    },
35    dark: {
36      button: "bg-gray-800 text-white border border-gray-700 hover:bg-gray-700",
37      menu: "bg-gray-900 text-white border border-gray-800 shadow-lg",
38      item: "hover:bg-gray-800",
39    },
40    gradient: {
41      button: "bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 text-white hover:opacity-90",
42      menu: "bg-gradient-to-b from-gray-900 to-black text-white border border-gray-800 shadow-lg",
43      item: "hover:bg-white/10",
44    },
45  }[variant];
46
47  return (
48    <div ref={ref} className="relative inline-block text-left">
49      <button
50        onClick={() => setOpen(!open)}
51        onKeyDown={(e) => e.key === "Escape" && setOpen(false)}
52        className={`px-5 py-3 rounded-lg font-medium transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 ${variantStyles.button}`}
53      >
54        {label}
55        <span className={`ml-2 inline-block transform transition-transform ${open ? "rotate-180" : "rotate-0"}`}>
5657        </span>
58      </button>
59
60      {open && (
61        <div
62          className={`absolute mt-2 w-56 rounded-xl overflow-hidden ${variantStyles.menu} animate-fadeSlide`}
63          role="menu"
64        >
65          {items.map((item, i) => (
66            <button
67              key={i}
68              onClick={() => {
69                item.onClick?.();
70                setOpen(false);
71              }}
72              className={`w-full text-left px-4 py-2.5 text-sm flex items-center gap-3 transition-colors duration-200 ${variantStyles.item}`}
73            >
74              {item.icon && <span>{item.icon}</span>}
75              {item.label}
76            </button>
77          ))}
78        </div>
79      )}
80
81      <style jsx>{`
82        @keyframes fadeSlide {
83          from {
84            opacity: 0;
85            transform: translateY(-10px);
86          }
87          to {
88            opacity: 1;
89            transform: translateY(0);
90          }
91        }
92        .animate-fadeSlide {
93          animation: fadeSlide 0.25s ease-out;
94        }
95      `}</style>
96    </div>
97  );
98};
99
100return function AmazingDropdowns() {
101  return (
102    <section className="min-h-screen flex flex-col items-center justify-center bg-gradient-to-b from-gray-900 to-black text-white px-4">
103      <h2 className="text-3xl md:text-4xl font-bold mb-10">Amazing Dropdowns Showcase</h2>
104
105      <div className="flex flex-wrap justify-center gap-10">
106        <Dropdown
107          label="Dark Dropdown"
108          variant="dark"
109          items={[
110            { label: "Profile", onClick: () => alert("Profile clicked") },
111            { label: "Settings", onClick: () => alert("Settings clicked") },
112            { label: "Logout", onClick: () => alert("Logout clicked") },
113          ]}
114        />
115
116        <Dropdown
117          label="Light Dropdown"
118          variant="light"
119          items={[
120            { label: "Dashboard" },
121            { label: "Projects" },
122            { label: "Reports" },
123          ]}
124        />
125
126        <Dropdown
127          label="Gradient Dropdown"
128          variant="gradient"
129          items={[
130            { label: "Home" },
131            { label: "Features" },
132            { label: "Contact" },
133          ]}
134        />
135      </div>
136    </section>
137  );
138}
139
140

MUDASIR