105 lines
3.9 KiB
JavaScript
105 lines
3.9 KiB
JavaScript
|
import * as React from 'react';
|
||
|
import { useControllableState } from '../hooks/useControllableState';
|
||
|
import { createSetFromIterable } from '../utils/createSetFromIterable';
|
||
|
function useSelectionState(params) {
|
||
|
const [selected, setSelected] = useControllableState({
|
||
|
initialState: new Set(),
|
||
|
defaultState: React.useMemo(()=>params.defaultSelectedItems && createSetFromIterable(params.defaultSelectedItems), [
|
||
|
params.defaultSelectedItems
|
||
|
]),
|
||
|
state: React.useMemo(()=>params.selectedItems && createSetFromIterable(params.selectedItems), [
|
||
|
params.selectedItems
|
||
|
])
|
||
|
});
|
||
|
const changeSelection = (event, nextSelectedItems)=>{
|
||
|
var _params_onSelectionChange;
|
||
|
(_params_onSelectionChange = params.onSelectionChange) === null || _params_onSelectionChange === void 0 ? void 0 : _params_onSelectionChange.call(params, event, {
|
||
|
selectedItems: nextSelectedItems
|
||
|
});
|
||
|
setSelected(nextSelectedItems);
|
||
|
};
|
||
|
return [
|
||
|
selected,
|
||
|
changeSelection
|
||
|
];
|
||
|
}
|
||
|
function useSingleSelection(params) {
|
||
|
const [selected, changeSelection] = useSelectionState(params);
|
||
|
const methods = {
|
||
|
deselectItem: (event)=>changeSelection(event, new Set()),
|
||
|
selectItem: (event, itemId)=>changeSelection(event, new Set([
|
||
|
itemId
|
||
|
])),
|
||
|
toggleAllItems: ()=>{
|
||
|
if (process.env.NODE_ENV !== 'production') {
|
||
|
throw new Error('[react-utilities]: `toggleAllItems` should not be used in single selection mode');
|
||
|
}
|
||
|
},
|
||
|
toggleItem: (event, itemId)=>changeSelection(event, new Set([
|
||
|
itemId
|
||
|
])),
|
||
|
clearItems: (event)=>changeSelection(event, new Set()),
|
||
|
isSelected: (itemId)=>{
|
||
|
var _selected_has;
|
||
|
return (_selected_has = selected.has(itemId)) !== null && _selected_has !== void 0 ? _selected_has : false;
|
||
|
}
|
||
|
};
|
||
|
return [
|
||
|
selected,
|
||
|
methods
|
||
|
];
|
||
|
}
|
||
|
function useMultipleSelection(params) {
|
||
|
const [selected, changeSelection] = useSelectionState(params);
|
||
|
const methods = {
|
||
|
toggleItem: (event, itemId)=>{
|
||
|
const nextSelectedItems = new Set(selected);
|
||
|
if (selected.has(itemId)) {
|
||
|
nextSelectedItems.delete(itemId);
|
||
|
} else {
|
||
|
nextSelectedItems.add(itemId);
|
||
|
}
|
||
|
changeSelection(event, nextSelectedItems);
|
||
|
},
|
||
|
selectItem: (event, itemId)=>{
|
||
|
const nextSelectedItems = new Set(selected);
|
||
|
nextSelectedItems.add(itemId);
|
||
|
changeSelection(event, nextSelectedItems);
|
||
|
},
|
||
|
deselectItem: (event, itemId)=>{
|
||
|
const nextSelectedItems = new Set(selected);
|
||
|
nextSelectedItems.delete(itemId);
|
||
|
changeSelection(event, nextSelectedItems);
|
||
|
},
|
||
|
clearItems: (event)=>{
|
||
|
changeSelection(event, new Set());
|
||
|
},
|
||
|
isSelected: (itemId)=>selected.has(itemId),
|
||
|
toggleAllItems: (event, itemIds)=>{
|
||
|
const allItemsSelected = itemIds.every((itemId)=>selected.has(itemId));
|
||
|
const nextSelectedItems = new Set(selected);
|
||
|
if (allItemsSelected) {
|
||
|
nextSelectedItems.clear();
|
||
|
} else {
|
||
|
itemIds.forEach((itemId)=>nextSelectedItems.add(itemId));
|
||
|
}
|
||
|
changeSelection(event, nextSelectedItems);
|
||
|
}
|
||
|
};
|
||
|
return [
|
||
|
selected,
|
||
|
methods
|
||
|
];
|
||
|
}
|
||
|
export function useSelection(params) {
|
||
|
'use no memo';
|
||
|
if (params.selectionMode === 'multiselect') {
|
||
|
// selectionMode is a static value, so we can safely ignore rules-of-hooks
|
||
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||
|
return useMultipleSelection(params);
|
||
|
}
|
||
|
// selectionMode is a static value, so we can safely ignore rules-of-hooks
|
||
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||
|
return useSingleSelection(params);
|
||
|
}
|