59 lines
1.4 KiB
TypeScript
59 lines
1.4 KiB
TypeScript
import React from 'react';
|
|
|
|
interface FilterDropdownOption {
|
|
value: string | number | null;
|
|
label: string;
|
|
}
|
|
|
|
interface FilterDropdownProps {
|
|
label: string;
|
|
value: string | number | null;
|
|
options: FilterDropdownOption[];
|
|
onChange: (value: string | number | null) => void;
|
|
icon?: string;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
const FilterDropdown: React.FC<FilterDropdownProps> = ({
|
|
label,
|
|
value,
|
|
options,
|
|
onChange,
|
|
icon,
|
|
disabled = false,
|
|
}) => {
|
|
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
const val = e.target.value;
|
|
if (val === '') {
|
|
onChange(null);
|
|
} else if (!isNaN(Number(val))) {
|
|
onChange(Number(val));
|
|
} else {
|
|
onChange(val);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
|
{icon && <i className={`${icon} mr-2`}></i>}
|
|
{label}
|
|
</label>
|
|
<select
|
|
value={value === null ? '' : value}
|
|
onChange={handleChange}
|
|
disabled={disabled}
|
|
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-red-500 focus:border-red-500 bg-white text-gray-900 disabled:bg-gray-100 disabled:cursor-not-allowed"
|
|
>
|
|
{options.map((opt, idx) => (
|
|
<option key={idx} value={opt.value === null ? '' : opt.value}>
|
|
{opt.label}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default FilterDropdown;
|