@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
95 lines (94 loc) • 3.57 kB
JavaScript
import * as React from 'react';
import { useContext, useRef } from 'react';
import useProperty from '../utils/useProperty';
const SelectableListContext = React.createContext({
clickInfoRef: null,
selected: {},
getItemId: (index) => index,
toggleOnSimpleClick: false,
setSelected: (x) => { },
});
export const useSelectionEvent = () => {
const { selected, setSelected, toggleOnSimpleClick, clickInfoRef, getItemId } = useContext(SelectableListContext);
return (event, { index }) => {
if (index === undefined) {
return;
}
const { lastClickIndexWithoutShift, lastShiftSelectionRange } = clickInfoRef.current;
let { shiftKey, metaKey, ctrlKey } = event;
if (ctrlKey) {
metaKey = true;
}
if (metaKey) {
// as if shift key is not pressed
shiftKey = false;
}
let itemId = `${getItemId(index)}`;
let newSelection;
if (!shiftKey) {
clickInfoRef.current.lastClickIndexWithoutShift = index;
if (!metaKey && !toggleOnSimpleClick) {
// a simple click, no key modifiers
// so reset the selection
// and only add one item, the currently clicked item
newSelection = { [itemId]: true };
}
else {
const currentRowSelected = selected[itemId];
newSelection = { ...selected };
if (currentRowSelected) {
// unselected the current row
delete newSelection[itemId];
// also, when unselecting, the click position should not be remembered, so need to revert it back
clickInfoRef.current.lastClickIndexWithoutShift = lastClickIndexWithoutShift;
}
else {
newSelection[itemId] = true;
}
}
clickInfoRef.current.lastShiftSelectionRange = null;
setSelected(newSelection);
}
else {
let prevClickIndex = lastClickIndexWithoutShift;
let currentClickIndex = index;
newSelection = { ...selected };
if (lastShiftSelectionRange) {
let { start, end } = lastShiftSelectionRange;
// clear previous shift selection
for (; start <= end; start++) {
delete newSelection[getItemId(start)];
}
}
let [start, end] = [
Math.min(prevClickIndex, currentClickIndex),
Math.max(prevClickIndex, currentClickIndex),
];
clickInfoRef.current.lastShiftSelectionRange = { start, end };
for (; start <= end; start++) {
newSelection[getItemId(start)] = true;
}
setSelected(newSelection);
}
};
};
const SelectableList = (props) => {
const [selected, setSelected] = useProperty(props, 'selected', {});
const clickInfoRef = useRef({
lastClickIndexWithoutShift: 0,
});
const getItemId = (index) => {
if (props.getItemId) {
return props.getItemId(index);
}
return index;
};
return (React.createElement(SelectableListContext.Provider, { value: {
clickInfoRef,
toggleOnSimpleClick: props.toggleOnSimpleClick || false,
selected,
setSelected,
getItemId,
} }, props.children));
};
export default SelectableList;