esfiles / frontend /src /components /Select.tsx
Besjon Cifliku
feat: initial project setup
db764ae
import { useState, useRef, useEffect } from "react";
interface Option {
value: string;
label: string;
}
interface Props {
options: Option[];
value: string;
onChange: (value: string) => void;
placeholder?: string;
}
export default function Select({ options, value, onChange, placeholder }: Props) {
const [open, setOpen] = useState(false);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
function handleClickOutside(e: MouseEvent) {
if (ref.current && !ref.current.contains(e.target as Node)) {
setOpen(false);
}
}
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
const selected = options.find((o) => o.value === value);
return (
<div className="custom-select" ref={ref}>
<button
className="custom-select-trigger"
onClick={() => setOpen(!open)}
type="button"
>
<span>{selected?.label || placeholder || "Select..."}</span>
<span className="custom-select-arrow">{open ? "\u25b4" : "\u25be"}</span>
</button>
{open && (
<div className="custom-select-dropdown">
{options.map((opt) => (
<button
key={opt.value}
className={`custom-select-option ${opt.value === value ? "custom-select-option-active" : ""}`}
onClick={() => {
onChange(opt.value);
setOpen(false);
}}
type="button"
>
{opt.label}
</button>
))}
</div>
)}
</div>
);
}