import { produce } from 'immer' import type { ApplyPropsAction, SetSelectionAnchor, UpdateSelectionAction, } from '../actions' import type { GridRowId } from '../../types' import { createReducer } from '../utils/createReducer' export type GridSelectionState = { controlled: boolean mode: 'single' | 'multi' | 'none' selection: Set anchor: GridRowId | null } const initialState: GridSelectionState = { controlled: false, mode: 'single', selection: new Set(), anchor: null, } export default createReducer({ initialState, reducers: { applyProps(state, action: ApplyPropsAction) { return produce(state, (draft) => { draft.controlled = !!action.payload.selection if (action.payload.selection !== undefined) { draft.selection = action.payload.selection } if (action.payload.selectionMode !== undefined) { draft.mode = action.payload.selectionMode if (!draft.controlled) { if (draft.mode === 'none') { draft.selection = new Set() } else if ( draft.mode === 'single' && draft.selection.size > 1 ) { /* Reduce selection to last one chosen */ draft.selection = new Set( [...draft.selection].slice(-1) ) } } } }) }, updateSelection(state, action: UpdateSelectionAction) { return { ...state, selection: action.payload, } }, setSelectionAnchor(state, action: SetSelectionAnchor) { return { ...state, anchor: action.payload, } }, }, }) export const selectSelection = (state: GridSelectionState) => state.selection export const selectSelectionMode = (state: GridSelectionState) => state.mode export const selectSelectionAnchor = ( state: GridSelectionState ): GridRowId | null => state.anchor