A Griddy AI prototype

This commit is contained in:
2026-02-12 22:02:39 +02:00
parent e45a4d70f6
commit 7ecafc8461
19 changed files with 1835 additions and 13 deletions

View File

@@ -0,0 +1,66 @@
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
}