Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
File size: 3,667 Bytes
3f70191 bd7ca0d 3f70191 bd7ca0d 3f70191 bd7ca0d 3f70191 bd7ca0d 3f70191 bd7ca0d 3f70191 bd7ca0d 3f70191 3962b04 3f70191 3962b04 3f70191 bd7ca0d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | import Select, { MultiValue, components, OptionProps, MultiValueGenericProps } from 'react-select'
interface OptionType {
value: string
label: string
count?: number
}
interface MultiSelectProps {
label: string
options: OptionType[]
selected: string[]
onChange: (selected: string[]) => void
placeholder?: string
className?: string
}
// Custom option component to show counts
const CustomOption = (props: OptionProps<OptionType>) => {
const { data } = props
return (
<components.Option {...props}>
<div className="flex items-center justify-between w-full">
<span>{data.label}</span>
{data.count !== undefined && (
<span className="text-xs text-gray-500 ml-2">
({data.count.toLocaleString()})
</span>
)}
</div>
</components.Option>
)
}
// Custom multi-value label to show abbreviated text
const CustomMultiValueLabel = (props: MultiValueGenericProps<OptionType>) => {
return (
<components.MultiValueLabel {...props}>
<span className="truncate max-w-[100px]" title={props.data.label}>
{props.data.label}
</span>
</components.MultiValueLabel>
)
}
export default function MultiSelect({
label,
options,
selected,
onChange,
placeholder = 'Select...',
className = ''
}: MultiSelectProps) {
const selectedOptions = options.filter(opt => selected.includes(opt.value))
const handleChange = (newValue: MultiValue<OptionType>) => {
onChange(newValue.map(opt => opt.value))
}
return (
<div className={className}>
<label className="block text-sm font-medium text-gray-700 mb-1">
{label}
</label>
<Select<OptionType, true>
isMulti
options={options}
value={selectedOptions}
onChange={handleChange}
placeholder={placeholder}
components={{
Option: CustomOption,
MultiValueLabel: CustomMultiValueLabel
}}
className="react-select-container"
classNamePrefix="react-select"
styles={{
control: (base, state) => ({
...base,
minHeight: '38px',
borderColor: state.isFocused ? '#3b82f6' : '#d1d5db',
boxShadow: state.isFocused ? '0 0 0 1px #3b82f6' : 'none',
'&:hover': {
borderColor: state.isFocused ? '#3b82f6' : '#9ca3af'
}
}),
placeholder: (base) => ({
...base,
color: '#9ca3af'
}),
singleValue: (base) => ({
...base,
color: '#111827'
}),
input: (base) => ({
...base,
color: '#111827'
}),
menu: (base) => ({
...base,
zIndex: 50
}),
menuList: (base) => ({
...base,
maxHeight: '320px'
}),
option: (base, state) => ({
...base,
color: '#111827',
backgroundColor: state.isFocused ? '#f3f4f6' : 'white',
'&:active': {
backgroundColor: '#e5e7eb'
}
}),
multiValue: (base) => ({
...base,
backgroundColor: '#dbeafe',
borderRadius: '4px'
}),
multiValueLabel: (base) => ({
...base,
color: '#1e40af',
fontSize: '0.875rem'
}),
multiValueRemove: (base) => ({
...base,
color: '#1e40af',
':hover': {
backgroundColor: '#bfdbfe',
color: '#1e3a8a'
}
})
}}
/>
</div>
)
}
|