import React from 'react'; import Select, { components } from 'react-select'; import { SortableContainer, SortableElement } from 'react-sortable-hoc'; import { colourOptions } from '../data'; function arrayMove(array, from, to) { array = array.slice(); array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]); return array; } const SortableMultiValue = SortableElement(props => { // this prevents the menu from being opened/closed when the user clicks // on a value to begin dragging it. ideally, detecting a click (instead of // a drag) would still focus the control and toggle the menu, but that // requires some magic with refs that are out of scope for this example const onMouseDown = e => { e.preventDefault(); e.stopPropagation(); }; const innerProps = { onMouseDown }; return ; }); const SortableSelect = SortableContainer(Select); export default function MultiSelectSort() { const [selected, setSelected] = React.useState([ colourOptions[4], colourOptions[5], ]); const onChange = selectedOptions => setSelected(selectedOptions); const onSortEnd = ({ oldIndex, newIndex }) => { const newValue = arrayMove(selected, oldIndex, newIndex); setSelected(newValue); console.log('Values sorted:', newValue.map(i => i.value)); }; return ( node.getBoundingClientRect()} // react-select props: isMulti options={colourOptions} value={selected} onChange={onChange} components={{ MultiValue: SortableMultiValue, }} closeMenuOnSelect={false} /> ); }