Table

The Table component displays rows of structured data in a tabular format.

Basic usage

A Table displays a list of data rows for each column.
Each column must contain an accessor. An accessor indicates which field of the data should be rendered under the column. For example, the following table has a column with accessor name, so row["name"] appears in the column.
You can also specify deeply nested values in accessors like info.hobbies or even address[0].street.

Task backed

A Table can be backed by an Airplane Task rather than hardcoding the columns and data. Set the task prop to call an Airplane task. The columns and data are automatically inferred from the output of the task.

Customizing data and columns

The columns of a Task backed Table can be customized. Any column information provided via the column prop overrides the column information inferred from the Task output.
The data of a Task backed Table can be transformed with the outputTransform prop. This prop is a function that receives the Table data and returns new data.
The following example illustrates customizing both the data and columns of a Task backed Table.
The column name gets a custom label so that the column is titled with Cat Name rather than name.
We then use outputTransform to capitalize the name of the cat in each data row.

Row selection

Row selection allows the user to select one or more Table rows. You can then use component state to access the selected rows. Selected rows can be passed as task parameters or used elsewhere in the view.

Single selection

Single row selection is enabled by setting the rowSelection prop to single. The selected row can be accessed using the selectedRow field on the component state.

Multi selection

Multi row selection is enabled by setting the rowSelection prop to checkbox. The selected rows can be accessed using the selectedRows field on the component state.

Programmatic selection

If row selection is enabled, you can also set which rows are initially selected by setting the isDefaultSelectedRow prop to a selection function.

Row actions

Row actions are buttons (or other UI) that appear on each row and can take action on that row.
Specify the rowActions prop to add one or more actions to every row. A row action is a React component that has a prop row that contains the row data of the action.
If your row actions call Airplane tasks, create Task backed row actions.
As a shortcut, you can create row action buttons by just providing label and onClick. You can also customize preset, variant, disabled, and color. The above can be rewritten as follows.

Task backed row actions

Row actions can automatically call Airplane tasks. Use a task on the row action to generate a button that calls a task.
When the row action button is clicked, the task will be executed with the data of the row passed in as parameters. You can optionally include additional parameters that are merged with the row data.
In the following example, we create two row actions that execute the tasks pet_cat and feed_cat when clicked. Each task execution includes the row data as task params—we can assume that both tasks take in a param name.
When row action in a task backed table executes successfully, the table automatically refreshes, calling its backing task. This ensures that the table is up to date even if the row action mutates data.

Row action menu

Row actions can be put in a kebab menu using the rowActionsMenu prop. This can be useful when there are too many row actions to render in one column. Here, we move the feed_cat task to the overflow menu.

Transforming parameters in row actions

If a row's data doesn't match the parameters for a task backed row action, you can use the rowTransform parameter to make it match.
In the following example, the task with slug feed_cat takes in two params: cat and food. We use rowTransform to convert the row data field name to cat and then calculate the food param.

Row action confirmation dialog

To show a confirmation dialog before the row action's action (onClick or task) is executed, set the confirm prop.
The dialog title, body, and buttons can be customized.

Column types

The type of a table column specifies how data in that column is rendered, edited and sorted.
Each column of a table is typed. Column types are automatically inferred from the data in the column. You can also manually specify the type of a column if it cannot be inferred.

Supported column types

TypeDisplayEdit Display
string (default)StringTextInput
numberNumberNumberInput
booleanCheckboxCheckbox
dateFormatted date stringDatePicker
datetimeFormatted date-time stringDateTimePicker
selectStringSelect
jsonCodeJSON editor

Column type options

Some column types can be configured with additional information using the typeOptions prop to customize how they are rendered or edited.
For example, to bound the min and/or max of a column of type number, set the numberMin and numberMax options respectively. To set the options for a column of type select, set the selectData option.

Custom components

Use a custom component when you want to display something that is not included as a built in column type.
Use the component field in the column definition to render a custom component.
When using custom components, make sure that they are defined outside of the component you are using them in. Components defined inline will be re-created on every render, causing performance issues.

Editing rows

Table rows can be edited by setting a column's canEdit field to true.
Once a row is edited, you will commonly use a Row action to persist the edit by calling a task with the edited row.
In the following example, once a row is edited, the user clicks Update which calls the update_cat task. The edited row is passed in as task parameters.
Use a more specific Column type to customize the editable UI.

Component API

NameDescriptionDefault
task
string | { slug: string; params?: Record<string, any>; refetchInterval?: number; onSuccess?: (output?: TOutput) => void; onFailure?: (output?: TOutput, error?: TError) => void; executeOnMount?: boolean; executeOnWindowFocus?: boolean; executeOnReconnect?: boolean; } | AirplaneFunc | { fn: AirplaneFunc; params?: Record<string, any>; refetchInterval?: number; onSuccess?: (output?: TOutput) => void; onFailure?: (output?: TOutput, error?: TError) => void; executeOnMount?: boolean; executeOnWindowFocus?: {boolean; executeOnReconnect?: boolean; }

The task query to execute when this component loads. The component's data will be populated by the task's output and loading and error states will be handled automatically.

If the task doesn't require any parameters or special options, you can just pass the task slug (task="my_task") or an AirplaneFunc—the return value of airplane.task() (task={myTask}).

If the task requires parameters, these can be passed in via params.

The refetchInterval param represents how often (in milliseconds) the task query should be rerun to refetch data automatically.

The onSuccess and onFailure callbacks will run on task success or failure.

The executeOnMount, executeOnWindowFocus, and executeOnReconnect params control when the task is (re)run - on component mount, when the window is (re)focused, and if the network reconnects. All of these options are true by default.

outputTransform
(output: TOutput) => TRowData[]
Callback to transform the task output.
id
string
The ID referenced by the global component state.
rowActions
( string | { slug: string; label?: string; rowTransform?: (row: TRowData) => TParams; confirm?: boolean | { title?: React.ReactNode | string; cancelText?: string; confirmText?: string; body: React.ReactNode | string; }; preset?: "primary" | "secondary" | "tertiary" | "danger"; variant?: "filled" | "outline" | "light" | "subtle"; disabled?: boolean; color?: Color; onSuccess?: () => void; onFailure?: (error?: TError) => void; refetchTasks?: RefetchQuery | RefetchQuery[]; } | { label: string; onClick: (row: TRowData) => void; confirm?: boolean | { title?: React.ReactNode | string; cancelText?: string; confirmText?: string; body: React.ReactNode | string; }; preset?: "primary" | "secondary" | "tertiary" | "danger"; variant?: "filled" | "outline" | "light" | "subtle"; disabled?: boolean; color?: Color; } | (props: { row: TRowData }) => JSX.Element )[]
Adds custom components to the end of each row.
rowActionsMenu
( string | { slug: string; label?: string; rowTransform?: (row: TRowData) => TParams; confirm?: boolean | { title?: React.ReactNode | string; cancelText?: string; confirmText?: string; body: React.ReactNode | string; }; preset?: "primary" | "secondary" | "tertiary" | "danger"; variant?: "filled" | "outline" | "light" | "subtle"; disabled?: boolean; color?: Color; onSuccess?: () => void; onFailure?: (error?: TError) => void; refetchTasks?: RefetchQuery | RefetchQuery[]; } | { label: string; onClick: (row: TRowData) => void; confirm?: boolean | { title?: React.ReactNode | string; cancelText?: string; confirmText?: string; body: React.ReactNode | string; }; preset?: "primary" | "secondary" | "tertiary" | "danger"; variant?: "filled" | "outline" | "light" | "subtle"; disabled?: boolean; color?: Color; } )[]
Adds custom components to an overflow menu at the end of each row.
columns
Column<TRowData>[]
Columns that are merged into columns inferred from the data.
columnsTransform
(columns: Column<TRowData>[]) => Column<TRowData>[]
Callback to transform the columns. This can be used to customize any inferred columns.
rowSelection
"checkbox" | "single"
"single" enables selection of single row while "checkbox" adds a checkbox one each row and enables selection of multiple rows.
selectAll
boolean
If true, a select all checkbox is shown that allows selecting all rows. Only applicable if rowSelection="checkbox".
true
loading
boolean
Renders a loading indicator when true.
defaultPageSize
number
Sets the page size on initial render.
10
error
string
Renders an error message.
noData
string
The message to display when the table has no data.
title
string
Sets the title above the table.
hiddenColumns
string[]
Columns to hide in the table. Reference columns using the column accessor, or the inferred output field for task backed tables.
shownColumns
string[]
If set, only columns in this list are shown. Columns that are in both hiddenColumns and shownColumns are hidden. Reference columns using the column accessor, or the inferred output field for task backed tables.
showFilter
boolean
Allows for global filtering when true.
true
isDefaultSelectedRow
(row: TRowData, rowIndex: number) => boolean
Function to choose selected rows on initial render.
isSelectedRow
(row: TRowData, rowIndex: number) => boolean
Function for controlled row selection.
freezeRowActions
boolean
Freezes the row actions column when true.
true
rowActionsWidth
number
If set, the row actions column will be set to this width, in pixels.
enableCSVDownload
boolean
Adds a "download as CSV button" to the table footer.
onToggleRow
(row: TRowData, idx: number) => void
This is called when the selection state of a row is toggled. Passes in the row data as well as the index of the row in the table.
onToggleAllRows
(value: boolean) => void
This is called when the toggle-all-selected-rows checkbox is pressed when rowSelection is set to "checkbox", with the value of the resulting checkbox. If isSelectedRow is set, and this is not provided, the toggle-all-selected-rows checkbox will not be shown.
width
number | "content" | "auto" | `${number}%` | `${number}/${number}` | { xs?: ColWidth; sm?: ColWidth; md?: ColWidth; lg?: ColWidth; xl?: ColWidth; }
Width of the component. This component must be a direct child of a <Stack> for this prop to take effect. If an integer is specified, signifies the width in a 12 item grid. 12 means that the component takes up the entire row, 6 is half, 1 is 1/12. If a decimal or fraction is specified, signifies the fractional share of the row. e.g. 1/2 takes up half of the row. If a percentage is specified, signifies the percentage share of the row. e.g. "50%" takes up half of the row. content indicates that the component should take up as much space as its content. auto indicates that the component should take any leftover space on the row. To set width based on the screen size, use an object with a specific width for each breakpoint. e.g. {xs: "100%", md: "50%"} sets the width on xs-md screens to 100% and md and larger screens to 50%.
content
offset
number | `${number}%` | `${number}/${number}` | { xs?: ColOffset; sm?: ColOffset; md?: ColOffset; lg?: ColOffset; xl?: ColOffset; }
Creates a gap to the left of the component. Has the same units as width. This component must be a direct child of a <Stack> for this prop to take effect. If an integer is specified, signifies the offset in a 12 item grid. 6 means the component is offset by half a row, 1 is 1/12 of a row. If a decimal or fraction is specified, signifies the fractional share of the row. e.g. 1/2 offsets a component by half of the row. If a percentage is specified, signifies the percentage share of the row. e.g. "50%" offsets a component by half of the row. To set offset based on the screen size, use an object with a specific offset for each breakpoint. e.g. {xs: "50%", md: "0%"} sets the offset on xs-md screens to 50% and md and larger screens to 0%.
data
TRowData[]
The data, or rows, to display in the table.

State API

NameDescription
selectedRows
TRowData[]
Rows that have been selected
selectedRow
TRowData
A single row that has been selected. Only applicable for rowSelection="single"
rowActionResult
{ output?: TOutput; loading?: boolean; error?: ExecuteTaskError }
The result of the latest executed row action
clearSelection
() => void
Clears all selected rows