UNPKG

ahooks

Version:
90 lines (89 loc) 3.2 kB
import isPlainObject from 'lodash/isPlainObject'; import useMemoizedFn from '../useMemoizedFn'; import { isFunction, isString } from '../utils'; import { useMemo, useState } from 'react'; function useSelections(items, options) { var _a, _b; let defaultSelected = []; let itemKey; if (Array.isArray(options)) { defaultSelected = options; } else if (isPlainObject(options)) { defaultSelected = (_a = options === null || options === void 0 ? void 0 : options.defaultSelected) !== null && _a !== void 0 ? _a : defaultSelected; itemKey = (_b = options === null || options === void 0 ? void 0 : options.itemKey) !== null && _b !== void 0 ? _b : itemKey; } const getKey = (item) => { if (isFunction(itemKey)) { return itemKey(item); } if (isString(itemKey) && isPlainObject(item)) { return item[itemKey]; } return item; }; const [selected, setSelected] = useState(defaultSelected); const selectedMap = useMemo(() => { const keyToItemMap = new Map(); if (!Array.isArray(selected)) { return keyToItemMap; } selected.forEach((item) => { keyToItemMap.set(getKey(item), item); }); return keyToItemMap; }, [selected]); const isSelected = (item) => selectedMap.has(getKey(item)); const select = (item) => { selectedMap.set(getKey(item), item); setSelected(Array.from(selectedMap.values())); }; const unSelect = (item) => { selectedMap.delete(getKey(item)); setSelected(Array.from(selectedMap.values())); }; const toggle = (item) => { if (isSelected(item)) { unSelect(item); } else { select(item); } }; const selectAll = () => { items.forEach((item) => { selectedMap.set(getKey(item), item); }); setSelected(Array.from(selectedMap.values())); }; const unSelectAll = () => { items.forEach((item) => { selectedMap.delete(getKey(item)); }); setSelected(Array.from(selectedMap.values())); }; const noneSelected = useMemo(() => items.every((item) => !selectedMap.has(getKey(item))), [items, selectedMap]); const allSelected = useMemo(() => items.every((item) => selectedMap.has(getKey(item))) && !noneSelected, [items, selectedMap, noneSelected]); const partiallySelected = useMemo(() => !noneSelected && !allSelected, [noneSelected, allSelected]); const toggleAll = () => (allSelected ? unSelectAll() : selectAll()); const clearAll = () => { selectedMap.clear(); setSelected([]); }; return { selected, noneSelected, allSelected, partiallySelected, setSelected, isSelected, select: useMemoizedFn(select), unSelect: useMemoizedFn(unSelect), toggle: useMemoizedFn(toggle), selectAll: useMemoizedFn(selectAll), unSelectAll: useMemoizedFn(unSelectAll), clearAll: useMemoizedFn(clearAll), toggleAll: useMemoizedFn(toggleAll), }; } export default useSelections;