import type { ColumnDef } from "../components/data-table/types" import { resolveColumnFilter } from "./column-filter" import { computeNumericColumnBounds, defaultRangeStep, } from "./column-filter-range-policy" import { derivePersonFilterOptions, isPersonSelectFilter, type PersonFilterOption, } from "./column-filter-person-options" export type FilterFieldRuntimeContext = { /** Person avatar pickers — derived from rows when `cellKind` is person / people-rail. */ personOptions?: PersonFilterOption[] /** Data-derived numeric bounds for range sliders. */ rangeMin?: number rangeMax?: number rangeStep?: number } export function buildFilterFieldContextMap>( rows: T[], columns: ColumnDef[], ): Record { const out: Record = {} for (const col of columns) { const resolved = resolveColumnFilter(col) if (!resolved) continue const ctx: FilterFieldRuntimeContext = {} if (isPersonSelectFilter(col.cellKind)) { ctx.personOptions = derivePersonFilterOptions(rows, col.key, col.cellKind) } if (resolved.type === "range") { const explicitMin = resolved.rangeMin const explicitMax = resolved.rangeMax const useDataBounds = explicitMin === undefined && explicitMax === undefined && (resolved.dataBounds === true || col.cellKind === "currency" || col.cellKind === "numeric") if (useDataBounds) { const { min, max } = computeNumericColumnBounds(rows, col.key) ctx.rangeMin = min ctx.rangeMax = max ctx.rangeStep = resolved.rangeStep ?? defaultRangeStep(min, max, resolved.rangeUnit) } else { ctx.rangeMin = explicitMin ?? 0 ctx.rangeMax = explicitMax ?? 100 ctx.rangeStep = resolved.rangeStep ?? defaultRangeStep(ctx.rangeMin, ctx.rangeMax, resolved.rangeUnit) } } if (Object.keys(ctx).length > 0) { out[col.key] = ctx } } return out }