sushilideaclan01's picture
..
fe48c70
import React, { useState } from "react";
import { cn } from "@/lib/utils/cn";
interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
label?: string;
error?: string;
options: Array<{ value: string; label: string }>;
}
export const Select: React.FC<SelectProps> = ({
label,
error,
options,
className,
...props
}) => {
const [focused, setFocused] = useState(false);
const hasValue = props.value !== undefined && props.value !== "";
return (
<div className="w-full">
{label && (
<label className="block text-sm font-semibold text-gray-700 mb-2">
{label}
</label>
)}
<div className="relative">
<select
className={cn(
"w-full px-4 py-3 rounded-xl border-2 transition-all duration-250 focus:outline-none focus:ring-2 focus:ring-offset-2",
"bg-white/80 backdrop-blur-sm appearance-none cursor-pointer",
"hover:border-gray-400",
error
? "border-red-400 focus:border-red-500 focus:ring-red-500"
: focused || hasValue
? "border-blue-400 focus:border-blue-500 focus:ring-blue-500"
: "border-gray-300 focus:border-blue-500 focus:ring-blue-500",
className
)}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
{...props}
>
{options.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
{/* Custom arrow */}
<div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
<svg className="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</div>
{(focused || hasValue) && !error && (
<div className="absolute inset-0 rounded-xl border-2 border-blue-500 pointer-events-none animate-pulse-glow opacity-50"></div>
)}
</div>
{error && (
<p className="mt-2 text-sm text-red-600 font-medium animate-slide-in">{error}</p>
)}
</div>
);
};