import { createSelector } from '../utils' import { flatten } from '../../data-tools' import type { StoreSimpleSelectors } from '../selectors' import type { SelectFilterMatchesShowOnly } from './filter' import type { SelectSortFn } from './sort' import type { GridRowId } from '../../types' import type { GridState } from '../reducer' import { getColumnSpanByRowId } from '../../utils/column-span' import type { SelectColSpanConfig, SelectStickyColumnIds } from './column' export default function generateSelectors( selectors: Pick< StoreSimpleSelectors, | 'selectRowCollection' | 'selectRowsExpanded' | 'selectIsTreeGrid' | 'selectHeaderHierarchy' | 'selectRow' | 'selectRowMeta' >, selectSortFn: SelectSortFn, selectFilterMatchesShowOnly: SelectFilterMatchesShowOnly, selectColSpanConfig: SelectColSpanConfig, selectStickyColumnIds: SelectStickyColumnIds ) { const selectRowDetails = createSelector( [ selectors.selectRowCollection, selectors.selectRowsExpanded, selectSortFn, selectFilterMatchesShowOnly, ], (rows, expanded, sortFn, matchedIds) => { const res = flatten(rows, expanded, sortFn, matchedIds) return res } ) const selectRowIds = createSelector( [selectRowDetails], (rowDetails) => rowDetails.ids ) const selectColumnSpanByRowId = (state: GridState, rowId: GridRowId) => { const { colSpanFunctions, columnIds } = selectColSpanConfig(state) const row = selectors.selectRow(state, rowId) const rowMeta = selectors.selectRowMeta(state, rowId) const stickyColumnIds = selectStickyColumnIds(state) if (!row || !colSpanFunctions.length) { return null } return getColumnSpanByRowId({ row, rowMeta, colSpanFunctions, columnIds, stickyColumnIds, }) } const selectRowIndex = (state: GridState, rowId: GridRowId) => { const rowDetails = selectRowDetails(state) return rowDetails.indexes.get(rowId) || 0 } const selectHeaderRowCount = (state: GridState) => selectors.selectHeaderHierarchy(state).levels + 1 const selectHeaderRowIds = createSelector([selectHeaderRowCount], (count) => Array.from({ length: count }).map((_, i) => `${i}`) ) const selectAriaRowCount = (state: GridState) => { const rowDetails = selectRowDetails(state) const headerRowCount = selectHeaderRowCount(state) return rowDetails.indexes.size + headerRowCount } const selectAriaSetSize = (state: GridState, rowId: GridRowId) => { const isTreeGrid = selectors.selectIsTreeGrid(state) if (!isTreeGrid) { return 0 } const rowDetails = selectRowDetails(state) const { setSize } = rowDetails.setDetails.get(rowId) || { setSize: 0 } return setSize } const selectAriaPosInset = (state: GridState, rowId: GridRowId) => { const isTreeGrid = selectors.selectIsTreeGrid(state) if (!isTreeGrid) { return 0 } const rowDetails = selectRowDetails(state) const { posInset } = rowDetails.setDetails.get(rowId) || { posInset: 0 } return posInset } return { selectRowIds, selectRowIndex, selectHeaderRowIds, selectAriaRowCount, selectAriaSetSize, selectAriaPosInset, selectHeaderRowCount, selectColumnSpanByRowId, } } export type SelectRowIds = ReturnType['selectRowIds'] export type SelectRowIndex = ReturnType< typeof generateSelectors >['selectRowIndex'] export type SelectAriaRowCount = ReturnType< typeof generateSelectors >['selectAriaRowCount'] export type SelectAriaSetSize = ReturnType< typeof generateSelectors >['selectAriaSetSize'] export type SelectAriaPosInset = ReturnType< typeof generateSelectors >['selectAriaPosInset'] export type SelectHeaderRowCount = ReturnType< typeof generateSelectors >['selectHeaderRowCount'] export type selectHeaderRowIds = ReturnType< typeof generateSelectors >['selectHeaderRowIds'] export type SelectColumnSpanByRowId = ReturnType< typeof generateSelectors >['selectColumnSpanByRowId']