Files
tripwithbonus/frontend/components/ui/Selector.tsx
2025-05-21 17:36:10 +03:00

114 lines
3.1 KiB
TypeScript

import React from 'react'
import Select from 'react-select'
import { MultiSelectProps } from '@/app/types'
const MultiSelect = ({
value,
handleChange,
label,
placeholder = 'Выберите опции',
name,
options,
className = '',
noOptionsMessage = 'Нет доступных опций',
}: MultiSelectProps) => {
return (
<div className={className}>
{label && (
<label className="my-2 block text-sm font-medium text-gray-500" htmlFor={name}>
{label}
</label>
)}
<Select
isMulti
name={name}
id={name}
options={options}
value={options.filter(option => value.includes(option.id))}
onChange={selectedOptions => {
handleChange({
target: {
id: name,
value: selectedOptions ? selectedOptions.map(opt => opt.id) : [],
},
})
}}
getOptionValue={option => option.id.toString()}
className="rounded-lg"
classNamePrefix="select"
placeholder={placeholder}
noOptionsMessage={() => noOptionsMessage}
styles={{
control: base => ({
...base,
borderRadius: '0.75rem',
backgroundColor: '#F3F4F6',
border: '1px solid #E5E7EB',
padding: '2px',
'&:hover': {
borderColor: '#E5E7EB',
},
'&:focus-within': {
backgroundColor: '#FFFFFF',
borderColor: '#E5E7EB',
boxShadow: '0 0 0 2px rgba(59, 130, 246, 0.5)',
},
}),
menu: base => ({
...base,
position: 'absolute',
width: '100%',
zIndex: 9999,
marginTop: '4px',
borderRadius: '0.75rem',
overflow: 'hidden',
}),
menuList: base => ({
...base,
padding: '4px',
}),
multiValue: base => ({
...base,
backgroundColor: '#EFF6FF',
borderRadius: '0.5rem',
}),
multiValueLabel: base => ({
...base,
color: '#2563EB',
}),
multiValueRemove: base => ({
...base,
color: '#2563EB',
':hover': {
backgroundColor: '#DBEAFE',
color: '#1E40AF',
},
}),
menuPortal: base => ({
...base,
zIndex: 9999,
}),
option: (base, state) => ({
...base,
fontSize: '0.875rem',
padding: '8px 12px',
backgroundColor: state.isSelected ? '#EFF6FF' : state.isFocused ? '#F3F4F6' : 'white',
color: state.isSelected ? '#2563EB' : '#1F2937',
cursor: 'pointer',
'&:active': {
backgroundColor: '#DBEAFE',
},
'&:hover': {
backgroundColor: state.isSelected ? '#EFF6FF' : '#F3F4F6',
},
}),
}}
menuPortalTarget={document.body}
menuPosition="fixed"
/>
</div>
)
}
export default MultiSelect