react-datatable
Reference

Column API

Use this page when you need the exact meaning of a column field. For the higher-level setup flow, start with Define columns.

Main type

interface DatatableColumn<TData, TValue = unknown> {
  id: string
  header: string
  order?: number
  defaultVisible?: boolean
  width?: number
  minWidth?: number
  maxWidth?: number
  resizable?: boolean
  accessorKey?: keyof TData
  accessorFn?: (row: TData) => TValue
  cell?: ColumnDef<TData, TValue>["cell"]
  enableSorting?: boolean
  sortingFn?: ColumnDef<TData, TValue>["sortingFn"]
  showSortInHeader?: boolean
  enableFiltering?: boolean
  enableGlobalFilter?: boolean
  filterType?: FilterType
  filterOptions?: FilterOptions
  enableGrouping?: boolean
  groupingSpec?: ColumnGroupingSpec
  meta?: {
    displayName?: string
    filterName?: string
    filterIcon?: React.ComponentType<{ className?: string }>
    [key: string]: unknown
  }
}

Identity and labels

id

Stable machine-readable column ID.

This is the contract key used by:

  • filters
  • sorting
  • grouping
  • saved views
  • persisted current-view state
  • URL state
  • online query inputs

Do not derive it from visible text.

Primary visible column label in the shipped grid header.

meta.displayName

Optional friendlier display label for product surfaces that should not reuse the raw header text.

meta.filterName

Optional label override for filter UI.

meta.filterIcon

Optional custom icon for filter affordances.

Visibility and order

order

Initial relative column order.

Use it when the source order of your array should not be the rendered default.

defaultVisible

Whether the column starts visible.

Hidden-by-default columns can still be surfaced later through display options, views, or persisted state if your table exposes those controls.

Width and resizing

width

Initial resolved width in pixels.

minWidth

Minimum allowed width.

maxWidth

Maximum allowed width.

resizable

Per-column override for whether the user can resize this column.

Use fixed sizing for structural columns that should not be dragged into unusable widths.

Data access

accessorKey

Direct field access for simple columns.

{
  id: "company",
  accessorKey: "company",
  header: "Company",
}

Prefer this when the rendered value maps directly to a row property.

accessorFn

Derived value accessor.

{
  id: "accountHealth",
  header: "Health",
  accessorFn: (row) => `${row.status}:${row.seats}`,
}

Use this only when the column value is intentionally computed. In online mode, make sure your backend query semantics still match the column ID and intended sort/filter behavior.

cell

Custom cell renderer.

The table provides TanStack-style cell context in both local and online modes, so normal cell patterns still work when online rows are server-shaped.

For broader guidance, see:

Sorting fields

enableSorting

Whether the column participates in sorting.

sortingFn

TanStack-compatible local sorting function override.

Use this only when the default sort semantics for the accessed value are wrong for local mode.

showSortInHeader

Whether sort state should render in the header for this column.

This is useful when sorting is still active but should stay out of the primary header presentation.

Filtering fields

enableFiltering

Whether the column participates in column-filter workflows.

enableGlobalFilter

Whether the column is included in the shipped quick-search/global-search behavior.

See Add global search.

filterType

"text" | "number" | "date" | "boolean" | "text-list" | "id-list" | "custom"

This controls the filter payload shape and the intended user query semantics.

Common uses:

  • text: names, titles, identifiers
  • number: counts, amounts, scores
  • date: machine-readable date fields
  • boolean: yes/no state
  • text-list: finite visible labels such as status or plan
  • id-list: related entity IDs such as assignee or project
  • custom: product-owned custom filter payload

filterOptions

Optional configuration for the selected filterType.

Option-list filters support a shared presentation hook:

renderOption?: (option: { value: string | boolean; label: string }) => React.ReactNode

Use renderOption when the built-in option editor should show richer rows, such as avatars, icons, color dots, or status badges. The selected filter payload still stores the option value; renderOption only changes presentation.

Text-list options

{
  options: string[] | { value: string; label: string }[]
  renderOption?: (option: { value: string; label: string }) => React.ReactNode
}

ID-list options

{
  options: { value: string; label: string }[]
  isLoading?: boolean
  emptyText?: string
  searchPlaceholder?: string
  renderOption?: (option: { value: string; label: string }) => React.ReactNode
}

Boolean options

{
  options?: [{ value: true; label: string }, { value: false; label: string }]
  renderOption?: (option: { value: boolean; label: string }) => React.ReactNode
}

Date options

{
  presets?: ("today" | "yesterday" | "last7days" | "last30days" | "thisMonth" | "lastMonth")[]
}

Reference note: the type system supports more filter shapes than every shipped filter UI currently exposes. Document the product surface you actually ship.

See:

Grouping fields

enableGrouping

Whether the column can be used in grouping controls.

groupingSpec

Controls how values group when raw values are not the right product bucket.

interface ColumnGroupingSpec {
  supportsOffline?: boolean
  supportsOnline?: boolean
  variants: Record<string, GroupingVariant>
  defaultVariant: string
}

supportsOffline

Set to false when a grouping model should only be handled by your backend.

supportsOnline

Set to false when a grouping model only makes sense in local mode.

variants

Named grouping strategies.

type GroupingVariant =
  | { kind: "raw"; emptyLabel?: string }
  | { kind: "date_trunc"; granularity: "day" | "week" | "month" | "year"; emptyLabel?: string }
  | { kind: "bucket"; buckets: GroupingBucket[]; emptyLabel?: string }

Raw grouping

Groups by the raw value directly.

Date truncation

Useful for month, week, or year buckets built from a machine-readable date.

Buckets

Useful for numeric ranges such as seat tiers, deal size bands, or SLA buckets.

interface GroupingBucket {
  id: string
  label: string
  min?: number
  max?: number
}

defaultVariant

The variant key used unless the grouping flow explicitly chooses another one.

See Add grouping.

Runtime column metadata

The source also defines a lower-level ColumnMetadata interface used inside the resolved table model:

interface ColumnMetadata {
  width?: number
  showSortInHeader?: boolean
  isSticky?: boolean
  isLastStickyColumn?: boolean
  stickyLeftOffset?: number
  filterType?: FilterType
  isSpacer?: boolean
  [key: string]: unknown
}

This is mostly useful when extending internal rendering behavior on the copied source, not for normal table setup.

Practical reminders

  • Keep column IDs stable over time.
  • Choose filter and grouping semantics from the data model, not from the badge or cell styling.
  • Treat cell as a rendering seam, not a place to hide behavioral rules.
  • In online mode, remember that your backend still owns the real sorting, filtering, grouping, and facet behavior.

On this page