import type { ApplyPropsAction, UpdateFocusAction } from '../actions' import type { GridRowId } from '../../types' import { createReducer } from '../utils/createReducer' import { ROW_FOCUS_ID } from '../../constants' import { produce } from 'immer' export type GridFocusArea = 'header' | 'body' | 'footer' export type GridFocusState = { initialized: boolean loopHorizontally?: boolean focus: { columnId: string rowId: GridRowId area: GridFocusArea subFocus: number | 'first' | 'last' } } const initialState: GridFocusState = { initialized: false, loopHorizontally: false, focus: { columnId: '', rowId: '0', area: 'header', subFocus: 'first', }, } export default createReducer({ initialState, reducers: { applyProps(state, action: ApplyPropsAction) { return produce(state, (draft) => { if (!state.initialized) { draft.initialized = true draft.focus.area = action.payload.hideHeaders ? 'body' : 'header' draft.focus.columnId = action.payload.initialFocusMode === 'row' ? ROW_FOCUS_ID : '' draft.focus.subFocus = action.payload.initialFocusMode === 'row' ? 'last' : 'first' } draft.loopHorizontally = action.payload.loopHorizontally ?? false }) }, updateFocus(state, action: UpdateFocusAction) { /* The immutable object currentFocus should only be recreated if one of its individual properties have changed */ const { area, columnId, rowId, subFocus } = action.payload if ( area !== state.focus.area || columnId !== state.focus.columnId || rowId !== state.focus.rowId || subFocus !== state.focus.subFocus ) { return { ...state, focus: action.payload, } } return state }, }, }) export const selectRawCurrentFocus = (state: GridFocusState) => state.focus export const selectSubFocus = (state: GridFocusState) => state.focus.subFocus export const selectCanLoopHorizontally = (state: GridFocusState) => state.loopHorizontally