41 lines
1.8 KiB
TypeScript
41 lines
1.8 KiB
TypeScript
|
|
import React from 'react';
|
|
|
|
interface SelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
|
|
label: string;
|
|
options: { value: string; label: string }[];
|
|
helperText?: string;
|
|
}
|
|
|
|
export const Select: React.FC<SelectProps> = ({ label, options, helperText, className = '', ...props }) => {
|
|
return (
|
|
<div className="flex flex-col gap-1.5 w-full">
|
|
<div className="flex justify-between items-baseline">
|
|
<label className="block text-sm font-semibold text-gray-700 tracking-tight">
|
|
{label}
|
|
</label>
|
|
{helperText && (
|
|
<span className="text-xs text-gray-500 italic">{helperText}</span>
|
|
)}
|
|
</div>
|
|
<div className="relative group">
|
|
<select
|
|
className={`appearance-none block w-full rounded-md border border-gray-300 bg-white py-2.5 pl-3 pr-10 text-sm leading-5 text-gray-900 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:text-sm transition-colors duration-200 ease-in-out group-hover:border-indigo-300 cursor-pointer ${className}`}
|
|
{...props}
|
|
>
|
|
{options.map((opt) => (
|
|
<option key={opt.value} value={opt.value}>
|
|
{opt.label}
|
|
</option>
|
|
))}
|
|
</select>
|
|
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-400 group-hover:text-indigo-500 transition-colors duration-200">
|
|
<svg className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
<path fillRule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clipRule="evenodd" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|