@carbon/ibm-products
Version:
Carbon for IBM Products
191 lines (189 loc) • 7.16 kB
JavaScript
/**
* Copyright IBM Corp. 2020, 2026
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
import { pkg } from "../../../settings.js";
import uuidv4 from "../../../global/js/utils/uuidv4.js";
import { deepCloneObject } from "../../../global/js/utils/deepCloneObject.js";
import { removeCellSelections } from "./removeCellSelections.js";
import { handleMultipleKeys, includesResourceKey, includesShift } from "./handleMultipleKeys.js";
import { checkForHoldingKey } from "./checkForHoldingKey.js";
import { handleHeaderCellSelection } from "./handleHeaderCellSelection.js";
import { handleActiveCellInSelectionEnter } from "./handleActiveCellInSelectionEnter.js";
import { handleActiveCellInSelectionTab } from "./handleActiveCellInSelectionTab.js";
import { handleCellDeletion } from "./handleCellDeletion.js";
//#region src/components/DataSpreadsheet/utils/commonEventHandlers.js
/**
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
const blockClass = `${pkg.prefix}--data-spreadsheet`;
const handleBodyCellClick = (cell, columnIndex, event, ...rest) => {
const [currentMatcher, activeCellCoordinates, selectionAreas, setActiveCellCoordinates, setSelectionAreas, setContainerHasFocus, setClickAndHoldActive, setCurrentMatcher, ref, setSelectionAreaData, setActiveCellInsideSelectionArea, activeCellRef, setValidStartingPoint] = rest;
event.preventDefault();
setValidStartingPoint(event.target.closest(`.${blockClass}__body--td`).classList.contains(`${blockClass}__body--td`));
const isHoldingCommandKey = checkForHoldingKey(event, "cmd");
const isHoldingShiftKey = checkForHoldingKey(event, "shiftKey");
setContainerHasFocus(true);
const activeCoordinates = {
row: cell.row.index,
column: columnIndex
};
const tempMatcher = uuidv4();
setClickAndHoldActive(true);
if (isHoldingCommandKey) {
ref.current.querySelector(`.${blockClass}__active-cell--highlight`).setAttribute("data-selection-id", tempMatcher);
setActiveCellInsideSelectionArea(true);
setActiveCellCoordinates(activeCoordinates);
setCurrentMatcher(tempMatcher);
setSelectionAreas((prev) => [...prev, {
point1: activeCoordinates,
matcher: tempMatcher
}]);
} else if (isHoldingShiftKey) {
setContainerHasFocus(true);
const selectionAreaClone = deepCloneObject(selectionAreas);
const indexOfItemToUpdate = selectionAreaClone.findIndex((item) => item.matcher === currentMatcher);
if (indexOfItemToUpdate === -1) return;
else {
selectionAreaClone[indexOfItemToUpdate].point1 = activeCellCoordinates;
selectionAreaClone[indexOfItemToUpdate].point2 = activeCoordinates;
selectionAreaClone[indexOfItemToUpdate].areaCreated = false;
selectionAreaClone[indexOfItemToUpdate].matcher = currentMatcher;
setSelectionAreas(selectionAreaClone);
}
} else {
activeCellRef.current.style.display = "none";
setActiveCellInsideSelectionArea(false);
setActiveCellCoordinates(activeCoordinates);
removeCellSelections({ spreadsheetRef: ref });
setSelectionAreas([{
point1: activeCoordinates,
matcher: tempMatcher
}]);
setCurrentMatcher(tempMatcher);
setSelectionAreaData([]);
}
};
const handleBodyCellHover = (cell, columnIndex, ...rest) => {
const [clickAndHoldActive, currentMatcher, setSelectionAreas] = rest;
if (clickAndHoldActive) {
const cellCoordinates = {
row: cell.row.index,
column: columnIndex
};
setSelectionAreas((prev) => {
const selectionAreaClone = deepCloneObject(prev);
const indexOfItemToUpdate = selectionAreaClone.findIndex((item) => item.matcher === currentMatcher);
if (indexOfItemToUpdate === -1) return prev;
if (selectionAreaClone[indexOfItemToUpdate].point2?.row === cellCoordinates.row && selectionAreaClone[indexOfItemToUpdate].point2?.column === cellCoordinates.column) return prev;
selectionAreaClone[indexOfItemToUpdate].point2 = cellCoordinates;
selectionAreaClone[indexOfItemToUpdate].areaCreated = false;
return selectionAreaClone;
});
}
};
const handleRowHeaderClick = (index, event, ...rest) => {
const [columns, ref, setSelectionAreas, setCurrentMatcher, setActiveCellCoordinates, activeCellCoordinates, rows, setSelectionAreaData] = rest;
handleHeaderCellSelection({
type: "row",
activeCellCoordinates,
rows,
columns,
setActiveCellCoordinates,
setCurrentMatcher,
setSelectionAreas,
spreadsheetRef: ref,
index,
setSelectionAreaData,
isHoldingCommandKey: checkForHoldingKey(event, "cmd")
});
};
const handleKeyPress = (event, ...rest) => {
const [activeCellInsideSelectionArea, updateActiveCellCoordinates, activeCellCoordinates, removeActiveCell, columns, rows, spreadsheetRef, currentMatcher, removeCellEditor, selectionAreas, handleHomeEndKey, keysPressedList, usingMac, updateData, checkForReturnCondition, handleArrowKeyPress, setSelectionAreas, setSelectionAreaData, setCurrentMatcher, activeCellRef, setActiveCellCoordinates, setContainerHasFocus, setActiveCellContent] = rest;
const { key } = event;
if (checkForReturnCondition(key)) return;
if ([
"ArrowLeft",
"ArrowUp",
"ArrowRight",
"ArrowDown"
].indexOf(key) > -1) {
if (selectionAreas?.length && keysPressedList.length < 2 && !includesShift(keysPressedList)) {
setSelectionAreas([]);
setSelectionAreaData([]);
removeCellSelections({ spreadsheetRef });
}
}
if (keysPressedList?.length > 1) handleMultipleKeys({
activeCellCoordinates,
event,
keysPressedList,
selectionAreas,
currentMatcher,
rows,
setSelectionAreas,
columns,
updateActiveCellCoordinates,
spreadsheetRef,
removeCellSelections,
blockClass,
setCurrentMatcher,
usingMac
});
if (keysPressedList.length < 2 && !includesShift(keysPressedList) || activeCellCoordinates.row === "header" || activeCellCoordinates.column === "header") switch (key) {
case "Backspace":
case "Delete":
handleCellDeletion({
selectionAreas,
currentMatcher,
rows,
setActiveCellContent,
updateData,
activeCellCoordinates
});
break;
case "Enter":
handleActiveCellInSelectionEnter({
activeCellInsideSelectionArea,
activeCellCoordinates,
activeCellRef,
selectionAreas,
updateActiveCellCoordinates
});
break;
case "Home":
case "End":
event.preventDefault();
if (includesResourceKey(keysPressedList, usingMac)) return;
handleHomeEndKey({ type: key });
break;
case "Tab":
if (activeCellInsideSelectionArea) {
event.preventDefault();
return handleActiveCellInSelectionTab({
activeCellInsideSelectionArea,
activeCellCoordinates,
activeCellRef,
selectionAreas,
updateActiveCellCoordinates
});
}
setSelectionAreas([]);
removeActiveCell();
removeCellEditor();
setContainerHasFocus(false);
setActiveCellCoordinates(null);
break;
case "ArrowLeft":
case "ArrowUp":
case "ArrowRight":
case "ArrowDown": handleArrowKeyPress(key);
}
};
//#endregion
export { handleBodyCellClick, handleBodyCellHover, handleKeyPress, handleRowHeaderClick };