67 lines
2.3 KiB
TypeScript
67 lines
2.3 KiB
TypeScript
import type { ColumnDef } from '@tanstack/react-table'
|
|
|
|
import type { GriddyColumn, SelectionConfig } from './types'
|
|
|
|
import { DEFAULTS, SELECTION_COLUMN_ID, SELECTION_COLUMN_SIZE } from './constants'
|
|
|
|
/**
|
|
* Retrieves the original GriddyColumn from a TanStack column's meta.
|
|
*/
|
|
export function getGriddyColumn<T>(column: { columnDef: ColumnDef<T> }): GriddyColumn<T> | undefined {
|
|
return (column.columnDef.meta as { griddy?: GriddyColumn<T> })?.griddy
|
|
}
|
|
|
|
/**
|
|
* Maps Griddy's user-facing GriddyColumn<T> definitions to TanStack Table ColumnDef<T>[].
|
|
* Optionally prepends a selection checkbox column.
|
|
*/
|
|
export function mapColumns<T>(
|
|
columns: GriddyColumn<T>[],
|
|
selection?: SelectionConfig,
|
|
): ColumnDef<T>[] {
|
|
const mapped: ColumnDef<T>[] = columns.map((col) => {
|
|
const isStringAccessor = typeof col.accessor !== 'function'
|
|
|
|
const def: ColumnDef<T> = {
|
|
id: col.id,
|
|
// Use accessorKey for string keys (enables TanStack auto-detection of sort/filter),
|
|
// accessorFn for function accessors
|
|
...(isStringAccessor
|
|
? { accessorKey: col.accessor as string }
|
|
: { accessorFn: col.accessor as (row: T) => unknown }),
|
|
enableColumnFilter: col.filterable ?? false,
|
|
enableHiding: true,
|
|
enableResizing: true,
|
|
enableSorting: col.sortable ?? true,
|
|
header: () => col.header,
|
|
maxSize: col.maxWidth ?? DEFAULTS.maxColumnWidth,
|
|
meta: { griddy: col },
|
|
minSize: col.minWidth ?? DEFAULTS.minColumnWidth,
|
|
size: col.width,
|
|
// For function accessors, TanStack can't auto-detect the sort type, so default to 'auto'
|
|
sortingFn: col.sortFn ?? (isStringAccessor ? undefined : 'auto') as any,
|
|
}
|
|
if (col.filterFn) def.filterFn = col.filterFn
|
|
return def
|
|
})
|
|
|
|
// Prepend checkbox column if selection is enabled
|
|
if (selection && selection.mode !== 'none' && selection.showCheckbox !== false) {
|
|
const checkboxCol: ColumnDef<T> = {
|
|
cell: 'select-row', // Rendered by TableCell with actual checkbox
|
|
enableColumnFilter: false,
|
|
enableHiding: false,
|
|
enableResizing: false,
|
|
enableSorting: false,
|
|
header: selection.mode === 'multi'
|
|
? 'select-all' // Rendered by TableHeader with actual checkbox
|
|
: '',
|
|
id: SELECTION_COLUMN_ID,
|
|
size: SELECTION_COLUMN_SIZE,
|
|
}
|
|
mapped.unshift(checkboxCol)
|
|
}
|
|
|
|
return mapped
|
|
}
|