Last active
May 8, 2022 12:43
-
-
Save edgarasben/98054b5197b7ff355b77735f65640d2f to your computer and use it in GitHub Desktop.
SelectMultiple.tsx component bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useState } from 'react' | |
import Badge from '@/components/Badge' | |
interface SelectProps { | |
className?: string | |
id?: string | |
label?: string | |
hint?: string | |
options: any | |
defaultPlaceholder?: string | |
value: string[] | |
onChange: (value: string[]) => void | |
} | |
export default function Select({ | |
id, | |
label, | |
className, | |
hint, | |
options, | |
value, | |
defaultPlaceholder = 'Select...', | |
onChange, | |
}: SelectProps) { | |
const [placeholder, setPlaceholder] = useState(defaultPlaceholder) | |
const remainingOptions = (options || []).filter( | |
(option) => value.indexOf(option.value) === -1 | |
) | |
const handleChange = (e) => { | |
onChange([...value, e.target.value]) | |
} | |
const handleDeselect = (item) => { | |
onChange(value.filter((option) => option !== item)) | |
} | |
useEffect(() => { | |
setPlaceholder( | |
value.length > 0 ? `${value.length} selected` : defaultPlaceholder | |
) | |
}, [value, setPlaceholder, defaultPlaceholder]) | |
return ( | |
<> | |
<div className='flex w-full flex-col space-y-1.5'> | |
{label && ( | |
<label | |
htmlFor={id} | |
className='block text-sm font-medium text-gray-700' | |
> | |
{label} | |
</label> | |
)} | |
<select | |
className={`${ | |
value.length > 0 ? 'text-gray-700' : 'text-gray-500' | |
} 'text-gray-700' : 'text-gray-500'} focus:border-primary-300 focus:ring-primary-100 mt-1.5 h-11 w-full cursor-pointer rounded border border-gray-300 shadow-sm focus:ring-4 ${ | |
className ? className : '' | |
}`.trim()} | |
id={id} | |
onChange={handleChange} | |
> | |
<option value=''>{placeholder}</option> | |
{remainingOptions.map((option) => ( | |
<option key={option.value} value={option.value}> | |
{option.text} | |
</option> | |
))} | |
</select> | |
<span className='text-sm text-gray-500'>{hint}</span> | |
{value && ( | |
<> | |
<div className='flex flex-wrap gap-3'> | |
{value.map((item) => ( | |
<Badge | |
key={item} | |
size='md' | |
color='primary' | |
className='cursor-pointer' | |
onClick={() => handleDeselect(item)} | |
rightIcon='X' | |
> | |
{item} | |
</Badge> | |
))} | |
</div> | |
</> | |
)} | |
</div> | |
</> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Fixed