tharikida-ui
Version:
A modern, lightweight React UI component library with built-in theming, accessibility, and full TypeScript support. Create beautiful, responsive, and customizable web apps faster with ready-to-use components for any project.
75 lines (74 loc) • 3.92 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useRef, useState } from "react";
import { useTheme } from "../../theme/ThemeProvider";
const Dropdown = ({ options, defaultOption, onChange, width, styles, cornerRadius, }) => {
const theme = useTheme();
const [selected, setSelected] = useState(defaultOption || options[0]);
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef(null);
const borderRadius = typeof cornerRadius === "number"
? cornerRadius
: theme.cornerRadius ?? theme.spacingfactor;
const handleSelect = (value) => {
setSelected(value);
setIsOpen(false);
onChange && onChange(value);
};
useEffect(() => {
if (isOpen && dropdownRef.current) {
const selectedOptionIndex = options.indexOf(selected);
const selectedOptionElement = dropdownRef.current?.children[selectedOptionIndex];
if (selectedOptionElement) {
selectedOptionElement.scrollIntoView({
behavior: "smooth",
block: "center", // Ensures the selected item is vertically centered
});
}
}
// Only depend on isOpen and selected for stability
}, [isOpen, selected]);
return (_jsxs("div", { style: { position: "relative", width: width || "100%", ...styles }, children: [_jsxs("div", { style: {
transition: "0.3s ease",
boxShadow: isOpen ? "1px 1px 0px black" : "2px 2px 0px black",
fontFamily: "montserrat",
width: "100%",
boxSizing: "border-box",
padding: "6px 10px",
border: "2px solid black",
borderRadius: borderRadius,
cursor: "pointer",
justifyContent: "space-between",
alignItems: "center",
display: "inline-flex",
height: "40px",
...styles, // Apply the custom styles here
}, onClick: () => setIsOpen(!isOpen), children: [selected, _jsx("svg", { style: {
transform: isOpen ? "rotate(180deg)" : "rotate(0deg)",
transition: "transform 0.3s",
}, width: "14", height: "8", viewBox: "0 0 14 8", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M1.37565 0.499999L7.43782 6.5L13.5 0.5", stroke: "black", strokeLinecap: "round" }) })] }), isOpen && (_jsx("ul", { ref: dropdownRef, style: {
boxSizing: "border-box",
zIndex: 1000,
margin: 0,
padding: "10px",
listStyle: "none",
background: "white",
border: "2px solid black",
borderRadius: borderRadius,
position: "absolute",
top: "100%",
left: 0,
width: "100%",
maxHeight: "300px",
overflowY: "auto",
}, children: options.map((option, index) => (_jsx("li", { style: {
fontFamily: "montserrat",
padding: "8px 10px",
cursor: "pointer",
background: selected === option ? "#e6e6e6" : "white",
borderRadius: borderRadius,
transition: "background 0.2s",
}, onClick: () => handleSelect(option), onMouseEnter: (e) => (e.currentTarget.style.background = "#f5f5f5"), onMouseLeave: (e) => (e.currentTarget.style.background =
selected === option ? "#e6e6e6" : "white"), children: option }, index))) }))] }));
};
export default Dropdown;