Spaces:
Sleeping
Sleeping
| "use client"; | |
| import { forwardRef } from "react"; | |
| import { cn } from "@/lib/utils"; | |
| import { ChevronDown } from "lucide-react"; | |
| interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> { | |
| label?: string; | |
| options: { value: string | number; label: string }[]; | |
| error?: string; | |
| } | |
| export const Select = forwardRef<HTMLSelectElement, SelectProps>( | |
| ({ className, label, options, error, id, ...props }, ref) => { | |
| return ( | |
| <div className="flex flex-col gap-1"> | |
| {label && ( | |
| <label htmlFor={id} className="text-[10px] font-medium text-neutral-500 uppercase tracking-wide"> | |
| {label} | |
| </label> | |
| )} | |
| <div className="relative"> | |
| <select | |
| ref={ref} | |
| id={id} | |
| className={cn( | |
| "w-full appearance-none rounded-md border border-neutral-200 bg-white pl-2.5 pr-7 py-1 text-xs text-neutral-800", | |
| "transition-all duration-200 outline-none cursor-pointer", | |
| "focus:border-brand-green focus:ring-2 focus:ring-brand-green/10", | |
| "disabled:opacity-50 disabled:cursor-not-allowed", | |
| error && "border-red-400", | |
| className | |
| )} | |
| {...props} | |
| > | |
| {options.map((opt) => ( | |
| <option key={opt.value} value={opt.value}> | |
| {opt.label} | |
| </option> | |
| ))} | |
| </select> | |
| <ChevronDown className="absolute right-2 top-1/2 -translate-y-1/2 h-3 w-3 text-neutral-400 pointer-events-none" /> | |
| </div> | |
| {error && <p className="text-xs text-red-500">{error}</p>} | |
| </div> | |
| ); | |
| } | |
| ); | |
| Select.displayName = "Select"; | |