

<Preview name="BasicDataTableExample" />

## Overview [#overview]

Columns are the contract between your row data and `DataTable`. Cubitt accepts standard TanStack `ColumnDef` objects, then reads a small set of additional metadata for features like loading states and inline edit.

## Stable Column Ids [#stable-column-ids]

Features like column visibility, filtering, pinning, and controlled state all work best when every interactive column has a stable id.

```tsx
const columns: ColumnDef<Employee>[] = [
  {
    id: "name",
    header: "Name",
    accessorKey: "name",
    enableHiding: false,
  },
  {
    id: "status",
    header: "Status",
    accessorKey: "status",
  },
];
```

If you omit `id`, TanStack can often infer one from a string `accessorKey`. That is fine for simple cases, but explicit ids are easier to reason about once the table grows.

## Accessors and Renderers [#accessors-and-renderers]

Use `accessorKey` for direct field access, `accessorFn` when the displayed value is derived, and `cell` when the rendered output needs custom UI.

```tsx
const columns: ColumnDef<Employee>[] = [
  {
    id: "name",
    header: "Name",
    accessorKey: "name",
    cell: ({ row }) => <span className="font-medium">{row.getValue("name")}</span>,
  },
  {
    id: "status",
    header: "Status",
    accessorKey: "status",
    cell: ({ row }) => (
      <Badge variant={row.getValue("status") === "Active" ? "brand" : "secondary"}>
        {String(row.getValue("status"))}
      </Badge>
    ),
  },
];
```

## DataTable Column Metadata [#datatable-column-metadata]

`DataTable` reads two `ColumnDef.meta` fields directly:

* `meta.skeleton` customizes the loading skeleton for that column
* `meta.editable` marks a column editable when inline edit mode is enabled

```tsx
const columns: ColumnDef<Employee>[] = [
  {
    id: "name",
    header: "Name",
    accessorKey: "name",
    meta: {
      skeleton: () => <Skeleton className="h-4 w-24" />,
      editable: true,
    },
  },
];
```

<Callout type="info">
  This page only covers the `ColumnDef` fields that matter most when using
  Cubitt's `DataTable`. For the full upstream surface, see TanStack's
  [Column Def guide](https://tanstack.com/table/latest/docs/guide/column-defs),
  [Column Def API](https://tanstack.com/table/latest/docs/api/core/column-def),
  [Column Sizing API](https://tanstack.com/table/latest/docs/api/features/column-sizing),
  and
  [Column Visibility API](https://tanstack.com/table/latest/docs/api/features/column-visibility).
</Callout>

## API Reference [#api-reference]

### Common `ColumnDef` Fields [#common-columndef-fields]

| Field            | Type                               | Description                                                                  |
| ---------------- | ---------------------------------- | ---------------------------------------------------------------------------- |
| `id`             | `string`                           | Stable column id used by controlled table features                           |
| `header`         | `string \| ReactNode \| render fn` | Header content                                                               |
| `accessorKey`    | `keyof TData`                      | Read a value directly from the row object                                    |
| `accessorFn`     | `(row: TData) => unknown`          | Derive a value from the row object                                           |
| `cell`           | render fn                          | Custom cell renderer                                                         |
| `columns`        | `ColumnDef<TData>[]`               | Nested child columns for grouped headers                                     |
| `size`           | `number`                           | Initial column width                                                         |
| `minSize`        | `number`                           | Minimum column width. Defaults to `50` in `DataTable`                        |
| `maxSize`        | `number`                           | Maximum column width for TanStack sizing                                     |
| `enableHiding`   | `boolean`                          | TanStack column-visibility flag. Set `false` to keep a column always visible |
| `enableSorting`  | `boolean`                          | Override whether a specific column can be sorted                             |
| `enableResizing` | `boolean`                          | Override whether a specific column can be resized                            |
| `enablePinning`  | `boolean`                          | Override whether a specific column can be pinned                             |

### DataTable-specific `meta` [#datatable-specific-meta]

| Field           | Type              | Description                                    |
| --------------- | ----------------- | ---------------------------------------------- |
| `meta.skeleton` | `() => ReactNode` | Custom loading skeleton for that column        |
| `meta.editable` | `boolean`         | Marks the column editable for inline edit mode |

### Related DataTable Props [#related-datatable-props]

| Prop      | Type                 | Description                                         |
| --------- | -------------------- | --------------------------------------------------- |
| `data`    | `TData[]`            | Row objects rendered against the column definitions |
| `columns` | `ColumnDef<TData>[]` | Column definitions passed into `DataTable`          |
