UNPKG

@carbon/ibm-products

Version:
191 lines (189 loc) 7.16 kB
/** * 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 };