Column Definitions
A column def a configuration object that defines various aspects of a column in a table. It specifies how the data should be accessed, displayed, and interacted with in that column. They are responsible for:
- Building the underlying data model that will be used for everything including sorting, filtering, grouping, etc.
- Formatting the data model into what will be displayed in the table.
- Creating header groups, headers, and footers.
Column Definition Categories
Column definitions are organized into three categories that describe and categorize different kinds of column definitions:
Accessor Columns
- Accessor columns have an underlying data model which means they can be sorted, filtered, grouped, etc. This is the most common type of column.
Display Columns
- Display columns do not have a data model which means they cannot be sorted, filtered, etc., but they can be used to display arbitrary content in the table like a row action button, checkbox, or expander.
Grouping Columns
- Group columns are used to group other columns together. Since they don't have a data model, they can't be sorted or filtered. It's common to define a header or footer for a column group.
Column Helpers
At the end of the day, column definitions are just objects.
We export a createColumnHelper
utility that simplifies the creation and configuration of column definitions. It provides a more structured and type-safe way to define columns, making your code cleaner and easier to manage, especially in TypeScript. If you set up your data and types correctly, the table will be able to infer the shape of your data and enforce that your column definitions are made correctly.
Here's an example of creating and using a column helper:
import {createColumnHelper, ColumnDef} from "@qui/react-table"interface Person {name: stringage: numberaddress: string}const columnHelper = createColumnHelper<Partial<Person>>()const columns: ColumnDef<Partial<Person>, any>[] = [columnHelper.accessor("name", {header: "Name",cell: (info) => <span>{info.getValue()}</span>,}),columnHelper.accessor("age", {header: "Age",cell: (info) => <span>{info.getValue()}</span>,enableSorting: true,}),columnHelper.accessor("address", {header: "Address",cell: (info) => <span>{info.getValue()}</span>,}),]
Detailed Breakdown
Name Column
- Header: The text "Name" will be displayed in the header of this column.
- Accessor: Uses the
name
key from the data objects to determine what to display in each cell. - Cell: Renders the value of
name
inside a<span>
element for each cell.
Age Column
- Header: The text "Age" will be displayed in the header of this column.
- Accessor: Uses the
age
key from the data objects. - Cell: Renders the value of
age
inside a<span>
element for each cell. - Enable Sorting: Sorting is enabled, allowing users to sort the table by age.
Address Column
- Header: The text "Address" will be displayed in the header of this column.
- Accessor: Uses the
address
key from the data objects. - Cell: Renders the value of
address
inside a<span>
element for each cell.
Creating Accessor Columns
Data columns are unique in that they must be configured to extract primitive values for each item in your data
array.
There are three ways to do this:
- If your items are objects, use an object-key that corresponds to the value you want to extract.
- If your items are nested arrays, use an array index that corresponds to the value you want to extract.
- Use an accessor function that returns the value you want to extract.
Object Keys
If each of your items is an object with the following shape:
interface Person {firstName: stringlastName: stringage: numbervisits: numberstatus: stringprogress: number}
You could extract the firstName value like so:
columnHelper.accessor("firstName")// ORconst column = {accessorKey: "firstName",}
Deep Keys
If each of your items is an object with the following shape:
interface Person {name: {first: stringlast: string}info: {age: numbervisits: number}}
You could extract the first
value like so:
columnHelper.accessor("name.first", {id: "firstName",})// ORconst column = {accessorKey: "name.first",id: "firstName",}
Accessor Functions
If each of your items is an object with the following shape:
interface Person {firstName: stringlastName: stringage: numbervisits: numberstatus: stringprogress: number}
You could extract a computed full-name value like so:
columnHelper.accessor((row) => `${row.firstName} ${row.lastName}`, {id: "fullName",})// ORconst column = {id: "fullName",accessorFn: (row) => `${row.firstName} ${row.lastName}`,}
TIP
Remember, the accessed value is crucial for sorting, filtering, and other operations. Ensure your accessor function returns a primitive value that can be effectively manipulated. If you return a non-primitive value, such as an object or array, you'll need the appropriate filter, sort, or grouping functions to handle it.