Table
Table
component displays rows of structured data in a tabular format.Basic usage
Table
displays a list of data
rows for each column
.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.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={[5{6label: "Name",7accessor: "name",8},9{10label: "Breed",11accessor: "breed",12},13]}14data={[15{ name: "Graham Cracker", breed: "British Shorthair" },16{ name: "Bootz", breed: "American Wirehair" },17{ name: "Hazel", breed: "Taby" },18{ name: "Xiaohuang", breed: "Abyssinian" },19{ name: "Peaches", breed: "Birman" },20{ name: "Baosky", breed: "British Shorthair" },21]}22/>
Task backed
Table
can be backed by an Airplane Task rather than by the columns
and data
props. Set the
task
prop to call an Airplane task. The columns and data are
automatically inferred from the output of the task.tsxCopied1<Table title="Cats" defaultPageSize={3} task="list_cats" />
Customizing data and columns
columns
prop sets the column configuration for both task-backed and non-task-backed tables. If
columns
and task
are both set, then the column information inferred from the task output is
ignored.columnsTransform
prop. columnsTransform
is a
function that takes the table columns as args and returns the new, transformed columns.outputTransform
is like columnsTransform
but for the table data. It is a function that takes the
table data as args and returns the new, transformed data.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.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4task="list_cats"5columnsTransform={(cols) =>6cols.map((c) => (c.accessor === "name" ? { ...c, label: "Cat Name" } : c))7}8outputTransform={(data) => data.map((d) => ({ ...d, name: d.name.toUpperCase() }))}9/>
Filtering columns
columnsTransform
, but you can use hiddenColumns
for a more concise filtering syntax.tsxCopied1<Table title="Cats" defaultPageSize={3} task="list_cats" hiddenColumns={["breed"]} />
Column width
width
and minWidth
respectively.tsxCopied1<Table2title="Cats"3columns={[4{5label: "Name",6accessor: "name",7width: 50,8},9{10label: "Born",11accessor: "born",12type: "date",13minWidth: 200,14},15{16label: "Polydactyl",17accessor: "polydactyl",18width: 70,19},20]}21data={data}22/>
Column types
tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={[5// Automatically typed as a string6{7label: "Name",8accessor: "name",9},10// Manually typed as a date11{12label: "Born",13accessor: "born",14type: "date",15},16// Automatically typed as a boolean17{18label: "Polydactyl",19accessor: "polydactyl",20},21// Automatically typed as json22{23label: "Notes",24accessor: "notes",25},26]}27data={data}28/>
Supported column types
Type | Display | Edit Display |
---|---|---|
string (default) | String | TextInput |
number | Number | NumberInput |
boolean | Checkbox | Checkbox |
date | Formatted date string | DatePicker |
datetime | Formatted date-time string | DateTimePicker |
select | String | Select |
json | Code | JSON editor |
Column type options
typeOptions
prop to
customize how they are rendered or edited.number
, set the numberMin
and
numberMax
options respectively. To set the options for a column of type select
, set the
selectData
option.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={[5{6label: "Name",7accessor: "name",8},9{10label: "Age",11accessor: "age",12canEdit: true,13typeOptions: { numberMin: 0, numberMax: 100 },14},15{16label: "Mood",17accessor: "mood",18type: "select",19typeOptions: {20selectData: ["happy", "sad", "neutral"],21},22canEdit: true,23},24]}25data={data}26rowActions={[27({ row }) => (28<Button variant="subtle" compact onClick={() => alert(`Meow ${row.name}`)}>29Pet30</Button>31),32]}33/>
Custom column components
Component
field in the column definition to render a custom component.tsxCopied1// This is a custom component rendered in the `breed` column of the table.2const CatBreedLink = ({ value }) => {3const catString = value.replace(/ /g, "_") + "_cat";4return <Link href={`https://en.wikipedia.org/wiki/${catString}`}>{value}</Link>;5};67const TableWithCustomComponent = () => {8return (9<Table10title="Cats"11defaultPageSize={3}12task="list_cats"13columns={[14{ accessor: "name", label: "Cat Name" },15{ accessor: "breed", label: "Breed", Component: CatBreedLink },16]}17/>18);19};
Row selection
Table
. 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
rowSelection
prop to single
. The selected row can
be accessed using the selectedRow
field on the component state.tsxCopied1<Table2title="Cats"3id="catsTable"4defaultPageSize={3}5columns={columns}6data={data}7rowSelection="single"8/>
Multi selection
rowSelection
prop to checkbox
. The selected rows
can be accessed using the selectedRows
field on the component state.tsxCopied1<Table2title="Cats"3id="catsTable"4defaultPageSize={3}5columns={columns}6data={data}7rowSelection="checkbox"8/>
Default selection
isDefaultSelectedRow
prop to a selection function.tsxCopied1<Table2title="Cats"3id="catsTable"4defaultPageSize={3}5columns={columns}6data={data}7rowSelection="single"8isDefaultSelectedRow={(row, index) => index === 0}9/>
Controlled selection
isSelectedRow
prop to a selection function, and
using the onToggleRow
and onToggleAllRows
props to update the row selection state.tsxCopied1<Table2title="Cats"3id="catsTable"4defaultPageSize={3}5columns={columns}6data={data}7rowSelection="single"8isSelectedRow={(row, index) => index === selectedIndex}9onToggleRow={(row, index) => setSelectedIndex(index)}10/>11<Button12onClick={() =>13setSelectedIndex(selectedIndex % 3 === 2 ? selectedIndex - 2 : selectedIndex + 1)14}15>16Change selection17</Button>
Setting a row ID
id
field on the row data, or the index of the row if there is no id
field. To customize the row ID, set the rowID
prop to the name of a field that uniquely identifies
the row.Row actions
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.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={columns}5data={data}6rowActions={(props) => (7<Button variant="subtle" compact onClick={() => alert(`Meow ${props.row.name}`)}>8Pet9</Button>10)}11/>
label
and onClick
. The above can be
rewritten as follows.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={columns}5data={data}6rowActions={{7label: "Pet",8onClick: (row) => alert(`Meow ${row.name}`),9}}10/>
onClick
, but are rather created when label
and href
are
provided.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={columns}5data={data}6rowActions={{7label: "Wiki page",8href: (row) => `https://en.wikipedia.org/wiki/${row.breed.replace(/ /g, "_")}_cat`,9}}10/>
Task backed row actions
task
on the row action to generate a
button that calls a task.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
.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={columns}5data={data}6rowActions={["pet_cat", { slug: "feed_cat", label: "Feed" }]}7/>
Row action menu
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.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={columns}5data={data}6rowActions="pet_cat"7rowActionsMenu={{ slug: "feed_cat", label: "Feed" }}8/>
Transforming parameters in row actions
rowTransform
parameter to make it match.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.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={columns}5data={data}6rowActions={[7{8slug: "feed_cat",9label: "Feed",10rowTransform: (row) => ({11cat: row.name,12food: favoriteFoods.get(row.name),13}),14},15]}16/>
Row action confirmation dialog
onClick
or task
) is executed, set
the confirm
prop.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={columns}5data={data}6rowActions={{ slug: "pet_cat", confirm: true }}7/>
tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={columns}5data={data}6rowActions={{7slug: "pet_cat",8confirm: {9title: "Are you sure you want to pet the cat?",10body: "The cat may not want to be pet",11confirmText: "Pet",12cancelText: "Take me back",13},14}}15/>
Editing rows
Table
can be edited by setting a column's canEdit
field to true
. When a cell is
editable, clicking on the edit icon will toggle the cell into edit mode based on the
Column type. Cells that have been edited will have a small dirty indicator in the
upper right corner.Update
which calls the
update_cat
task. The edited row is passed in as task parameters.tsxCopied1<Table2title="Cats"3defaultPageSize={3}4columns={[5{6label: "Name",7accessor: "name",8canEdit: true,9},10{11label: "Born",12accessor: "born",13type: "date",14canEdit: true,15},16{17label: "Mood",18accessor: "mood",19type: "select",20typeOptions: {21selectData: ["happy", "sad", "neutral"],22},23canEdit: true,24},25{26label: "Polydactyl",27accessor: "polydactyl",28canEdit: true,29},30]}31data={data}32rowActions={{ slug: "update_cat", label: "Update" }}33/>
Editing custom column components
Component
and an EditComponent
.- The
Component
accepts avalue
prop and astartEditing
callback.Component
must callstartEditing
to toggle into edit mode. - The
EditComponent
accepts adefaultValue
prop and afinishEditing
callback.EditComponent
must callfinishEditing
to toggle back into presentation mode.
tsxCopied1const TableEditCustom = () => {2return (3<Table4title="Cats"5defaultPageSize={3}6columns={[7{8label: "Name",9accessor: "name",10canEdit: true,11},12{13label: "Mood",14accessor: "mood",15Component: Mood,16EditComponent: EditMood,17canEdit: true,18},19]}20data={data}21rowActions={{ slug: "update_cat", label: "Update" }}22/>23);24};2526const Mood = (props: { value: string; startEditing?: () => void }) => {27return (28<Stack direction="row" justify="space-between" grow>29<Label>{props.value}</Label>30<Button variant="subtle" compact onClick={props.startEditing}>31Edit32</Button>33</Stack>34);35};3637const EditMood = (props: { defaultValue: string; finishEditing: (newValue: string) => void }) => {38return (39<Select40data={["happy", "sad", "neutral"]}41defaultValue={props.defaultValue}42onChange={(v: string) => props.finishEditing(v)}43withinPortal44initiallyOpened45autoFocus46/>47);48};
Component API
Callback used to modify the table columns.
The data, or rows, to display in the table.
Sets the page size on initial render.
Adds a "download as CSV button" to the table footer.
If a string is provided, it will be used as the file name with a .csv
extension appended.
Renders an error message.
Freezes the row actions column when true.
If true, the element will grow to fill available space.
This prop works only if the element is a direct child of a Stack.
Columns to hide in the table. Reference columns using the column accessor, or the inferred output field for task backed tables.
The ID referenced by the global component state.
Function to choose selected rows on initial render.
Function for controlled row selection.
Renders a loading indicator when true.
The message to display when the table has no data.
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.
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.
Callback to transform the task output.
- Use
TaskRowAction
to add a task-backed button that uses the row contents as task parameters. - Use
BasicRowAction
to add a link button or a regular button, depending on whetherhref
oronClick
is provided. - Use
ComponentRowAction
if you want to fully customize your row action.
rowActions
for details on each type.If set, the row actions column will be set to this width, in pixels.
A consistent, unique field used to identify a row. This is used to ensure that row selection is consistent even when the data changes (e.g. when a row is added or deleted).
If not provided, defaults to an "id" field on the row, or the index of the row if there is no id.
"single" enables selection of single row while "checkbox" adds a checkbox one each row and enables selection of multiple rows.
If true, a select all checkbox is shown that allows selecting all rows. Only applicable if rowSelection="checkbox".
Allows for global filtering when true.
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 does require parameters or special options, pass the task as an object. If you are using a slug, specify the slug
prop to pass the task configuration as a SlugQuery
. If you are using an AirplaneFunc
, specify the fn
prop to pass the task configuration as a FunctionQuery
.
Sets the title above the table.
State API
Clears all selected rows
The result of the latest executed row action
Rows that have been selected