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
Componentaccepts avalueprop and astartEditingcallback.Componentmust callstartEditingto toggle into edit mode. - The
EditComponentaccepts adefaultValueprop and afinishEditingcallback.EditComponentmust callfinishEditingto 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
TaskRowActionto add a task-backed button that uses the row contents as task parameters. - Use
BasicRowActionto add a link button or a regular button, depending on whetherhreforonClickis provided. - Use
ComponentRowActionif 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