import { ACTIONS_COLUMN_ID, SELECTION_COLUMN_ID } from '../constants' import type { GridRangeSelection } from '../types' import { healSpannedRange, isRangeEqual } from '../utils/range' import type { ApiSection } from './types' export type GridRangeSelectionApi = { select: (range: null | GridRangeSelection) => void move: (direction: 'left' | 'right' | 'up' | 'down') => void } export const createRangeSelectionApi: ApiSection = ( store, events ) => ({ select(range) { events.emit('onRangeSelectionChange', range) }, move: (direction: 'left' | 'right' | 'up' | 'down') => { const state = store.getState() const rangeSelection = store.selectors.selectRangeSelection(state) const currentFocus = store.selectors.selectCurrentFocus(state) if (!rangeSelection) return const ids = store.selectors.selectRangeIds(state) if ( !ids.rowIds.includes(currentFocus.rowId) || !ids.columnIds.includes(currentFocus.columnId) ) { return } const flatIds = store.selectors.selectRowIds(state) const columnIds = store.selectors.selectColumnIds(state) const rowIndex = flatIds.indexOf(rangeSelection.to.rowId) const columnIndex = columnIds.indexOf(rangeSelection.to.columnId) const newTo = { ...rangeSelection.to } if (direction === 'left') { const newColumnId = columnIds[columnIndex - 1] if (newColumnId && newColumnId !== SELECTION_COLUMN_ID) { newTo.columnId = newColumnId } } else if (direction === 'right') { const newColumnId = columnIds[columnIndex + 1] if (newColumnId && newColumnId !== ACTIONS_COLUMN_ID) { newTo.columnId = newColumnId } } else if (direction === 'up') { const newRowId = flatIds[rowIndex - 1] if (newRowId) { newTo.rowId = newRowId } } else if (direction === 'down') { const newRowId = flatIds[rowIndex + 1] if (newRowId) { newTo.rowId = newRowId } } const newRange = healSpannedRange( { from: { rowId: currentFocus.rowId, columnId: currentFocus.columnId, }, to: newTo, }, store ) if (!isRangeEqual(rangeSelection, newRange)) { events.emit('onRangeSelectionChange', newRange) } }, })