SiPhox Health - Multiselect
by Victor
HTML
<div id="app"></div>
CSS
.container {
width: 300px;
margin: 20px;
}
.select {
border: 1px solid gray;
padding: 8px;
border-radius: 8px;
cursor: pointer;
}
.select:hover {
border-color: blue;
}
.select p:hover {
background-color: #e7e7e7;
}
.select__options div {
opacity: 0.8;
}
.select__options div:hover {
opacity: 1;
}
React
// Your task is to implement multiselect from scratch (styling is not required)
// While closed it should show selected items separated by coma,
// on click it should open a list where you can check/uncheck items
const Component = () => {
const [items, setItems] = React.useState([])
const [selected, setSelected] = React.useState([])
const [isSelecting, setIsSelecting] = React.useState(false);
React.useEffect(() => {
setItems([{ label: 'd', value: 'd' }, { label: 'a', value: 'a' }, { label: 'b', value: 'b' }, { label: 'c', value: 'c' }])
}, []);
const selectHandler = (item) =>{
let matchingObjects = selected.filter(obj => obj.value === item.value);
if(!matchingObjects.length) {
setSelected(prev => {
return [...prev, item]
})
} else if (matchingObjects.length) {
setSelected(prev => {
return [...prev.filter(obj => obj.value !== item.value)]
})
}
};
return (
<div className="container">
<div className="select" onClick={()=>{
if (!isSelecting){
setIsSelecting(true);
}
}}>
{isSelecting && <div className="select__options">
<div onClick={()=>{setIsSelecting(false)}}>Close Select</div>
{items.map(item => (
<p key={item.value} onClick={() => {selectHandler(item)}} >
{selected.filter(obj => obj.value === item.value).length === 0 && '0' } {selected.filter(obj => obj.value === item.value).length === 1 && 'X' }
{item.label}</p>
))}
</div>
}
{!isSelecting && !selected.length && <div onClick={()=>{
setIsSelecting(true);
}}>Click to Start Selecting</div>}
{!isSelecting && selected.length > 0 && <div>
Selected: {selected.map(item => item.label).join(', ')}
</div>}
</div>
</div>
)
}
ReactDOM.render(<Component />, document.querySelector("#app"))