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"))