UNPKG

react-dual-listbox

Version:
99 lines (83 loc) 3.13 kB
import React, { useCallback } from 'react'; import DualListBox, { propTypes } from './DualListBox'; /** * Flatten an array of options to a simple list of values. * * @param {Array} options * @param {function} getOptionValue * * @returns {Array} */ function flattenOptions(options, getOptionValue) { const flattened = []; options.forEach((option) => { const value = getOptionValue(option); if (value !== undefined) { // Flatten single-level options flattened.push(value); } else if (option.options !== undefined) { // Flatten optgroup options option.options.forEach((subOption) => { flattened.push(getOptionValue(subOption)); }); } }); return flattened; } function ObjectValueWrapper(props) { const { available, getOptionValue, options, selected, onChange, } = props; const simpleAvailable = available ? flattenOptions(available, getOptionValue) : undefined; const simpleSelected = flattenOptions(selected, getOptionValue); const simpleOnChange = useCallback((newSelected, userSelection, controlKey) => { const sourceValues = { selected: newSelected }; const complexValues = { selected: [] }; // Reconstruct option objects for both the selected values and user selection Object.keys(sourceValues).forEach((key) => { // Note that complex values become expensive if there are several options sourceValues[key].forEach((value) => { options.forEach((option) => { const optionValue = getOptionValue(option); if (optionValue) { // Reconstruct single-level option if (optionValue === value) { complexValues[key].push(option); } } else { // Reconstruct optgroup options with those children const subSelected = []; option.options.forEach((subOption) => { if (getOptionValue(subOption) === value) { subSelected.push(subOption); } }); if (subSelected.length > 0) { complexValues[key].push({ ...option, options: subSelected, }); } } }); }); }); onChange(complexValues.selected, userSelection, controlKey); }, [getOptionValue, options]); /* eslint-disable react/jsx-props-no-spreading */ return ( <DualListBox {...props} available={simpleAvailable} selected={simpleSelected} onChange={simpleOnChange} /> ); /* eslint-enable */ } ObjectValueWrapper.propTypes = propTypes; export default ObjectValueWrapper;