react-multiselect-listbox
Version:
A multiple selection list box component for React
155 lines (142 loc) • 5.29 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import React, { memo, useState, useMemo, useCallback } from 'react';
import { DragDropContext } from 'react-beautiful-dnd';
import { defaultStrings } from './defaults';
import Button from './components/Button';
import SelectedListHeader from './components/SelectedListHeader';
import OptionListHeader from './components/OptionListHeader';
import ListBox from './components/ListBox';
import styles from './styles.module.scss';
var MultiSelectListBox = function MultiSelectListBox(_ref) {
var _ref$overrideStrings = _ref.overrideStrings,
overrideStrings = _ref$overrideStrings === void 0 ? defaultStrings : _ref$overrideStrings,
_ref$boxHeight = _ref.boxHeight,
boxHeight = _ref$boxHeight === void 0 ? 175 : _ref$boxHeight,
_ref$rowHeight = _ref.rowHeight,
rowHeight = _ref$rowHeight === void 0 ? 25 : _ref$rowHeight,
_ref$textField = _ref.textField,
textField = _ref$textField === void 0 ? 'text' : _ref$textField,
_ref$valueField = _ref.valueField,
valueField = _ref$valueField === void 0 ? 'value' : _ref$valueField,
sortable = _ref.sortable,
options = _ref.options,
value = _ref.value,
onSelect = _ref.onSelect,
onRemove = _ref.onRemove,
onSelectAll = _ref.onSelectAll,
onRemoveAll = _ref.onRemoveAll,
onSort = _ref.onSort,
onSearch = _ref.onSearch;
var search = overrideStrings.search,
selectAll = overrideStrings.selectAll,
removeAll = overrideStrings.removeAll,
selectedInfo = overrideStrings.selectedInfo;
var _useState = useState(''),
_useState2 = _slicedToArray(_useState, 2),
query = _useState2[0],
setQuery = _useState2[1];
var availableOptions = useMemo(function () {
var items = options.filter(function (item) {
return !value.includes(item[valueField]);
});
return onSearch ? onSearch({
items: items,
query: query,
textField: textField
}) : items.filter(function (item) {
return item[textField].includes(query);
});
}, [options, query, textField, value, valueField, onSearch]);
var selectedOptions = useMemo(function () {
return options.filter(function (item) {
return value.includes(item[valueField]);
}).sort(function (a, b) {
return value.indexOf(a[valueField]) - value.indexOf(b[valueField]);
});
}, [options, value, valueField]);
var handleSelectAll = useCallback(function () {
if (onSelectAll) {
onSelectAll(_toConsumableArray(availableOptions));
setQuery('');
}
}, [availableOptions, onSelectAll]);
var onItemAdd = useCallback(function (item, sortedList) {
if (!sortedList) {
sortedList = selectedOptions.slice();
sortedList.push(item);
}
onSelect && onSelect({
item: item,
sortedList: sortedList
});
}, [onSelect, selectedOptions]);
var onItemRemove = useCallback(function (item) {
onRemove && onRemove({
item: item
});
}, [onRemove]);
var onDragEnd = useCallback(function (result) {
var source = result.source,
destination = result.destination;
if (destination && source && source.droppableId !== destination.droppableId) {
var _item = availableOptions[source.index];
var _sortedList = selectedOptions.slice();
_sortedList.splice(destination.index, 0, _item);
onItemAdd(_item, _sortedList);
return;
}
if (!result.destination) {
return;
}
var sortedList = selectedOptions.slice();
var _sortedList$splice = sortedList.splice(source.index, 1),
_sortedList$splice2 = _slicedToArray(_sortedList$splice, 1),
item = _sortedList$splice2[0];
sortedList.splice(destination.index, 0, item);
onSort && onSort({
sortedList: sortedList
});
}, [availableOptions, onItemAdd, onSort, selectedOptions]);
return /*#__PURE__*/React.createElement("div", {
className: "".concat(styles.root)
}, /*#__PURE__*/React.createElement(DragDropContext, {
onDragEnd: onDragEnd
}, /*#__PURE__*/React.createElement(ListBox, {
id: 'options',
height: boxHeight,
rowHeight: rowHeight,
textField: textField,
valueField: valueField,
data: availableOptions,
onItemClick: onItemAdd,
sortable: sortable
}, /*#__PURE__*/React.createElement(OptionListHeader, {
searchPlaceHolder: search,
query: query,
onQueryChange: function onQueryChange(e) {
return setQuery(e.target.value);
},
actionButton: /*#__PURE__*/React.createElement(Button, {
onClick: handleSelectAll,
type: "add"
}, selectAll)
})), /*#__PURE__*/React.createElement(ListBox, {
id: 'selected',
height: boxHeight,
rowHeight: rowHeight,
textField: textField,
valueField: valueField,
data: selectedOptions,
onItemClick: onItemRemove,
sortable: sortable
}, /*#__PURE__*/React.createElement(SelectedListHeader, {
count: value.length,
label: selectedInfo,
actionButton: /*#__PURE__*/React.createElement(Button, {
onClick: onRemoveAll,
type: "remove"
}, removeAll)
}))));
};
export default memo(MultiSelectListBox);