@carbon/ibm-products
Version:
Carbon for IBM Products
202 lines (200 loc) • 8.07 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 uuidv4 from "../../../global/js/utils/uuidv4.js";
import { deepCloneObject } from "../../../global/js/utils/deepCloneObject.js";
import { selectAllCells } from "./selectAllCells.js";
//#region src/components/DataSpreadsheet/utils/handleMultipleKeys.js
/**
* Copyright IBM Corp. 2022, 2022
*
* 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 includesResourceKey = (arr, usingMac) => {
if (usingMac) return includesMeta(arr);
if (!usingMac) return includesControl(arr);
};
const includesShift = (arr) => {
if (arr.includes("ShiftLeft") || arr.includes("ShiftRight")) return true;
return false;
};
const includesMeta = (arr) => {
if (arr.includes("MetaLeft") || arr.includes("MetaRight")) return true;
return false;
};
const includesControl = (arr) => {
if (arr.includes("ControlLeft") || arr.includes("ControlRight")) return true;
return false;
};
const handleMultipleKeys = ({ activeCellCoordinates, event, keysPressedList, selectionAreas, currentMatcher, rows, setSelectionAreas, columns, updateActiveCellCoordinates, spreadsheetRef, removeCellSelections, blockClass, setCurrentMatcher, usingMac }) => {
const selectionAreasClone = deepCloneObject(selectionAreas);
const indexOfCurrentArea = selectionAreasClone.findIndex((item) => item.matcher === currentMatcher);
const pointToUpdate = selectionAreasClone[indexOfCurrentArea]?.point2 ? selectionAreasClone[indexOfCurrentArea]?.point2 : selectionAreasClone[indexOfCurrentArea]?.point1;
if (includesShift(keysPressedList) && keysPressedList.includes("ArrowDown") && keysPressedList.length === 2) {
if (rows.length - 1 === pointToUpdate?.row || activeCellCoordinates?.row === "header" || activeCellCoordinates?.column === "header") return;
const newPoint = {
row: pointToUpdate.row + 1,
column: pointToUpdate.column
};
selectionAreasClone[indexOfCurrentArea].point2 = newPoint;
selectionAreasClone[indexOfCurrentArea].areaCreated = false;
setSelectionAreas(selectionAreasClone);
}
if (includesShift(keysPressedList) && keysPressedList.includes("ArrowRight") && keysPressedList.length === 2) {
if (columns.length - 1 === pointToUpdate?.column || activeCellCoordinates?.row === "header" || activeCellCoordinates?.column === "header") return;
const newPoint = {
row: pointToUpdate.row,
column: pointToUpdate.column + 1
};
selectionAreasClone[indexOfCurrentArea].point2 = newPoint;
selectionAreasClone[indexOfCurrentArea].areaCreated = false;
setSelectionAreas(selectionAreasClone);
}
if (includesShift(keysPressedList) && keysPressedList.includes("ArrowUp") && keysPressedList.length === 2) {
if (pointToUpdate?.row === 0 || activeCellCoordinates?.row === "header" || activeCellCoordinates?.column === "header") return;
const newPoint = {
row: pointToUpdate.row - 1,
column: pointToUpdate.column
};
selectionAreasClone[indexOfCurrentArea].point2 = newPoint;
selectionAreasClone[indexOfCurrentArea].areaCreated = false;
setSelectionAreas(selectionAreasClone);
}
if (includesShift(keysPressedList) && keysPressedList.includes("ArrowLeft") && keysPressedList.length === 2) {
if (pointToUpdate?.column === 0 || activeCellCoordinates?.row === "header" || activeCellCoordinates?.column === "header") return;
const newPoint = {
row: pointToUpdate.row,
column: pointToUpdate.column - 1
};
selectionAreasClone[indexOfCurrentArea].point2 = newPoint;
selectionAreasClone[indexOfCurrentArea].areaCreated = false;
setSelectionAreas(selectionAreasClone);
}
if (includesResourceKey(keysPressedList, usingMac) && keysPressedList.includes("KeyA")) {
event.preventDefault();
const selectionPoint1 = {
row: 0,
column: 0
};
const selectionPoint2 = {
row: rows.length - 1,
column: columns.length - 1
};
if (indexOfCurrentArea === -1) selectAllCells({
ref: spreadsheetRef,
setCurrentMatcher,
setSelectionAreas,
rows,
columns,
activeCellCoordinates,
updateActiveCellCoordinates
});
selectionAreasClone[indexOfCurrentArea].point1 = selectionPoint1;
selectionAreasClone[indexOfCurrentArea].point2 = selectionPoint2;
selectionAreasClone[indexOfCurrentArea].areaCreated = false;
setSelectionAreas(selectionAreasClone);
}
if (includesControl(keysPressedList) && keysPressedList.includes("Space")) {
const selectionPoint1 = {
row: 0,
column: activeCellCoordinates?.column === "header" ? 0 : activeCellCoordinates?.column
};
const selectionPoint2 = {
row: rows.length - 1,
column: activeCellCoordinates?.column === "header" ? 0 : activeCellCoordinates?.column
};
if (indexOfCurrentArea === -1) {
const tempMatcher = uuidv4();
const newSelectionArea = {
point1: selectionPoint1,
point2: selectionPoint2,
areaCreated: false,
matcher: tempMatcher
};
updateActiveCellCoordinates({
coords: { ...activeCellCoordinates },
updatedValue: {
column: activeCellCoordinates?.column === "header" ? 0 : activeCellCoordinates?.column,
row: activeCellCoordinates?.row === "header" ? 0 : activeCellCoordinates?.row
}
});
setCurrentMatcher(tempMatcher);
return setSelectionAreas([newSelectionArea]);
}
selectionAreasClone[indexOfCurrentArea].point1 = selectionPoint1;
selectionAreasClone[indexOfCurrentArea].point2 = selectionPoint2;
selectionAreasClone[indexOfCurrentArea].areaCreated = false;
setSelectionAreas(selectionAreasClone);
}
if (includesShift(keysPressedList) && keysPressedList.includes("Space")) {
const selectionPoint1 = {
row: activeCellCoordinates?.row === "header" ? 0 : activeCellCoordinates?.row,
column: 0
};
const selectionPoint2 = {
row: activeCellCoordinates?.row === "header" ? 0 : activeCellCoordinates?.row,
column: columns.length - 1
};
if (indexOfCurrentArea === -1) {
const tempMatcher = uuidv4();
const newSelectionArea = {
point1: selectionPoint1,
point2: selectionPoint2,
areaCreated: false,
matcher: tempMatcher
};
updateActiveCellCoordinates({
coords: { ...activeCellCoordinates },
updatedValue: {
column: activeCellCoordinates?.column === "header" ? 0 : activeCellCoordinates?.column,
row: activeCellCoordinates?.row === "header" ? 0 : activeCellCoordinates?.row
}
});
setCurrentMatcher(tempMatcher);
return setSelectionAreas([newSelectionArea]);
}
selectionAreasClone[indexOfCurrentArea].point1 = selectionPoint1;
selectionAreasClone[indexOfCurrentArea].point2 = selectionPoint2;
selectionAreasClone[indexOfCurrentArea].areaCreated = false;
setSelectionAreas(selectionAreasClone);
}
if (includesResourceKey(keysPressedList, usingMac) && keysPressedList.includes("Home")) {
const scrollElement = spreadsheetRef.current.querySelector(`.${blockClass}__list--container`);
scrollElement.scrollTop = 0;
const coordinatesClone = { ...activeCellCoordinates };
removeCellSelections({ spreadsheetRef });
updateActiveCellCoordinates({
coords: coordinatesClone,
updatedValue: {
column: 0,
row: 0
}
});
}
if (includesResourceKey(keysPressedList, usingMac) && keysPressedList.includes("End")) {
const scrollElement = spreadsheetRef.current.querySelector(`.${blockClass}__list--container`);
scrollElement.scrollTop = scrollElement.scrollHeight;
const coordinatesClone = { ...activeCellCoordinates };
removeCellSelections({ spreadsheetRef });
const lastCellExists = !!rows[rows?.length - 1].cells[columns?.length - 1];
const updateToLastCell = () => {
updateActiveCellCoordinates({
coords: coordinatesClone,
updatedValue: {
column: columns.length - 1,
row: rows.length - 1
}
});
};
if (lastCellExists) updateToLastCell();
else setTimeout(() => {
updateToLastCell();
}, 1e3);
}
};
//#endregion
export { handleMultipleKeys, includesResourceKey, includesShift };