Table
Table
presents structured data for viewing, sorting, selection, and interaction.Key features:
- Data integration: Load data from APIs via DataSource or use static arrays
- Virtualization: Only renders visible rows for smooth performance with large datasets
- Row selection: Support single or multi-row selection for bulk operations
- Pagination: Built-in pagination controls for managing large datasets
Use
Column
to define headers, data binding, sorting behavior, and custom cell content.In the following sections the examples use data with the structure outlined below:
Id | Name | Quantity | Unit | Category |
---|---|---|---|---|
0 | Apples | 5 | pieces | fruits |
1 | Bananas | 6 | pieces | fruits |
2 | Carrots | 100 | grams | vegetables |
3 | Spinach | 1 | bunch | vegetables |
4 | Milk | 10 | liter | diary |
5 | Cheese | 200 | grams | diary |
The data is provided as JSON. In the source code samples, the
data={[...]}
declaration represents the data above.All samples use table columns with the following definition unless noted otherwise
(The
...
declaration nested into <Table>
represents this column definition):<Table data='{[...]}'>
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
Note: SeeColumn
to learn more about table columns.
Properties
alwaysShowSelectionHeader
(default: false)
This property indicates when the row selection header is displayed. When the value is
true,
the selection header is always visible. Otherwise, it is displayed only when hovered.autoFocus
(default: false)
If this property is set to
true
, the component gets the focus automatically when displayed.buttonRowPosition
(default: "center")
Determines where to place the pagination button row in the layout. It works the same as the Pagination component property.
Available values:
start
, center
(default), end
cellVerticalAlign
(default: "center")
This property controls the vertical alignment of cell content. It can be set to
top
, center
, or bottom
.Available values:
top
, center
(default), bottom
data
The component receives data via this property. The
data
property is a list of items that the Table
can display.<App>
<Table data='{[...]}'>
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: data
You can also provide the
Table
with data directly from an API via this property.
Here, the component displays rocket information coming from the official SpaceX API.<App>
<Table data='https://api.spacexdata.com/v3/rockets'>
<Column header="Image" size="140px">
<Image height="100px" fit="cover" src="{$item.flickr_images[0]}"/>
</Column>
<Column canSort="true" bindTo="country"/>
<Column canSort="true" bindTo="company"/>
</Table>
</App>
Example: data API Call
<App>
<Table data='https://api.spacexdata.com/v3/rockets'>
<Column header="Image" size="140px">
<Image height="100px" fit="cover" src="{$item.flickr_images[0]}"/>
</Column>
<Column canSort="true" bindTo="country"/>
<Column canSort="true" bindTo="company"/>
</Table>
</App>
enableMultiRowSelection
(default: true)
This boolean property indicates whether you can select multiple rows in the table. This property only has an effect when the rowsSelectable property is set. Setting it to
false
limits selection to a single row.This boolean property indicates whether you can select multiple rows in the table.
This property only has an effect when the
rowsSelectable
property is set.
Setting it to false
limits selection to a single row.By default, the value of this property is
true
.<App>
<Table data='{[...]}'
rowsSelectable="true"
enableMultiRowSelection="false">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: enableMultiRowSelection
headerHeight
This optional property is used to specify the height of the table header.
It accepts common size values.
<App>
<Table data='{[...]}' headerHeight="60px">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: headerHeight
hideHeader
(default: false)
Set the header visibility using this property. Set it to
true
to hide the header.Set the header visibility using this property. Set it to
true
to hide the header.
The default value is false
.<App>
<Table data='{[...]}' hideHeader="true">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: hideHeader
iconNoSort
Allows setting an alternate icon displayed in the Table column header when sorting is enabled, but the column remains unsorted. You can change the default icon for all Table instances with the "icon.nosort:Table" declaration in the app configuration file.
Allows the customization of the icon displayed in a Table column header when when sorting is enabled
and sorting is not done according to the column. Use the "-" (dash) value to sign that you do not want to display an icon when a table column is not sorted.
<App>
<Table data='{[...]}' sortBy="quantity" iconNoSort="close">
<Column bindTo="name" canSort="true" />
<Column bindTo="quantity" canSort="true" />
<Column bindTo="unit" canSort="true" />
</Table>
</App>
Example: iconNoSort
iconSortAsc
Allows setting an alernate icon displayed in the Table column header when sorting is enabled, and the column is sorted in ascending order. You can change the default icon for all Table instances with the "icon.sortasc:Table" declaration in the app configuration file.
Allows the customization of the icon displayed in a Table column header when sorting is enabled,
sorting is done according to the column, and the column is sorted in ascending order.
<App>
<Table data='{[...]}' sortBy="quantity" iconSortAsc="chevronup">
<Column bindTo="name" canSort="true" />
<Column bindTo="quantity" canSort="true" />
<Column bindTo="unit" canSort="true" />
</Table>
</App>
Example: iconSortAsc
iconSortDesc
Allows setting an alternate icon displayed in the Table column header when sorting is enabled, and the column is sorted in descending order. You can change the default icon for all Table instances with the "icon.sortdesc:Table" declaration in the app configuration file.
Allows the customization of the icon displayed in a Table column header when sorting is enabled,
sorting is done according to the column, and the column is sorted in descending order.
<App>
<Table data='{[...]}' sortBy="quantity" iconSortDesc="chevrondown">
<Column bindTo="name" canSort="true" />
<Column bindTo="quantity" canSort="true" />
<Column bindTo="unit" canSort="true" />
</Table>
</App>
Select a column header and set it to descending ordering.
Example: iconSortDesc
isPaginated
(default: false)
This property adds pagination controls to the
Table
.<App>
<Table data='{[...]}' isPaginated="true" pageSizeOptions="{[3, 6, 12]}">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: isPaginated
loading
This boolean property indicates if the component is fetching (or processing) data. This property is useful when data is loaded conditionally or receiving it takes some time.
This boolean property indicates if the component is fetching (or processing) data.
This property is useful when data is loaded conditionally or receiving it takes some time.
<App>
<Table loading="true">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
</Table>
</App>
Example: loading
<App>
<Table loading="true">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
</Table>
</App>
noBottomBorder
(default: false)
This property indicates whether the table should have a bottom border. When set to
true
, the table does not have a bottom border. Otherwise, it has a bottom border.noDataTemplate
A property to customize what to display if the table does not contain any data.
<App>
<Table>
<property name="noDataTemplate">
<Text value="No data loaded" variant="strong" />
</property>
<Column bindTo="name"/>
<Column bindTo="quantity"/>
</Table>
</App>
Example: noDataTemplate
<App>
<Table>
<property name="noDataTemplate">
<Text value="No data loaded" variant="strong" />
</property>
<Column bindTo="name"/>
<Column bindTo="quantity"/>
</Table>
</App>
pageInfoPosition
Determines where to place the page information in the layout. It works the same as the Pagination component property.
pageSize
This property defines the number of rows to display per page when pagination is enabled.
Options
Page sizes are only accepted in an array, even if the array contains one item.
Note that this property only works if the
isPaginated
property is set to true
.<App>
<Table data='{[...]}' isPaginated="true" pageSizeOptions="{[3, 6, 12]}">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: pageSizeOptions
pageSizeOptions
This property holds an array of page sizes (numbers) the user can select for pagination. If this property is not defined, the component allows only a page size of 10 items.
Page sizes are only accepted in an array, even if the array contains one item.
Note that this property only works if the
isPaginated
property is set to true
.<App>
<Table data='{[...]}' isPaginated="true" pageSizeOptions="{[3, 6, 12]}">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: pageSizeOptions
pageSizeSelectorPosition
Determines where to place the page size selector in the layout. It works the same as the Pagination component property.
paginationControlsLocation
(default: "bottom")
This property determines the location of the pagination controls. It can be set to
top
, bottom
, or both
.Available values:
top
, bottom
(default), both
rowDisabledPredicate
This property defines a predicate function with a return value that determines if the row should be disabled. The function retrieves the item to display and should return a Boolean-like value.
The following example disables all table rows where the item's quantity exceeds 6:
<App>
<Table data='{[...]}'
rowDisabledPredicate="{(item) => item.quantity > 6}">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Disabled items are rendered with a different color.
Example: rowDisabledPredicate
rowsSelectable
Indicates whether the rows are selectable (
true
) or not (false
).The default value is
false
.<App>
<Table data='{[...]}' rowsSelectable="true">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: rowsSelectable
showCurrentPage
(default: true)
Whether to show the current page indicator. It works the same as the Pagination component property.
showPageInfo
(default: true)
Whether to show page information. It works the same as the Pagination component property.
showPageSizeSelector
(default: true)
Whether to show the page size selector. It works the same as the Pagination component property.
sortBy
This property is used to determine which data property to sort by. If not defined, the data is not sorted
<App>
<Table data='{[...]}' sortBy="quantity">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: sortBy
sortDirection
This property determines the sort order to be
ascending
or descending
. This property only works if the sortBy
property is also set. By default ascending order is used.<App>
<Table data='{[...]}' sortBy="quantity" sortDirection="descending">
<Column bindTo="name"/>
<Column bindTo="quantity"/>
<Column bindTo="unit"/>
</Table>
</App>
Example: sortDirection
Events
selectionDidChange
This event is triggered when the table's current selection (the rows selected) changes. Its parameter is an array of the selected table row items.
Of course, if multiple-row selection is not allowed (
enableMultipleRowSelection
is false), this array will contain zero or one item.<App var.selection="">
<Text>Current selection (row IDs): [{selection}]</Text>
<Table data='{[...]}'
rowsSelectable="true"
enableMultiRowSelection="true"
onSelectionDidChange="(newSel) => selection = newSel.map(item => item.id).join()" >
<Column bindTo="name" canSort="true"/>
<Column bindTo="quantity" canSort="true"/>
<Column bindTo="unit" canSort="true"/>
</Table>
</App>
Click on any of the column headers to trigger a new sorting:
Example: selectionDidChange
sortingDidChange
This event is fired when the table data sorting has changed. It has two arguments: the column's name and the sort direction. When the column name is empty, the table displays the data list as it received it.
Note the
canSort
properties on the Column
components which enable custom ordering.<App var.sortedBy="">
<Heading level="h4" value="Table is sorted by: {sortedBy || ''}" paddingLeft="1rem"/>
<Table data='{[...]}'
onSortingDidChange="(by, dir) => sortedBy = (by && dir) ? by + ' | ' + dir : '' " >
<Column bindTo="name" canSort="true"/>
<Column bindTo="quantity" canSort="true"/>
<Column bindTo="unit" canSort="true"/>
</Table>
</App>
Click on any of the column headers to trigger a new sorting:
Example: sortingDidChange
willSort
This event is fired before the table data is sorted. It has two arguments: the column's name and the sort direction. When the method returns a literal
false
value (and not any other falsy one), the method indicates that the sorting should be aborted.The following example uses the
willSort
event to refuse sorting by name:<App var.sortedBy="">
<Heading level="h4" value="Table is sorted by: {sortedBy || ''}" paddingLeft="1rem"/>
<Table data='{[...]}'
onWillSort="(by, dir) => by !== 'name'"
onSortingDidChange="(by, dir) => sortedBy = (by && dir) ? by + ' | ' + dir : '' " >
<Column bindTo="name" canSort="true"/>
<Column bindTo="quantity" canSort="true"/>
<Column bindTo="unit" canSort="true"/>
</Table>
</App>
Click on any of the column headers to trigger the event.
Though sorting is enabled in the
TableColumnnDef
component of the "name" column via canSort
,
clicking that column header still does not sort because willSort
prevents it:Example: willSort
Exposed Methods
clearSelection
This method clears the list of currently selected table rows.
Signature:
clearSelection(): void
<App>
<HStack>
<Button label="Select all" onClick="table.selectAll()" />
<Button label="Clear all" onClick="table.clearSelection()" />
<Button label="Select 1" onClick="table.selectId(1)" />
<Button label="Select 2, 4" onClick="table.selectId([2, 4])" />
</HStack>
<Table id="table" data='{[...]}'
rowsSelectable="true"
enableMultiRowSelection="true">
<Column bindTo="name" canSort="true"/>
<Column bindTo="quantity" canSort="true"/>
<Column bindTo="unit" canSort="true"/>
</Table>
</App>
Example: clearSelection
getSelectedIds
This method returns the list of currently selected table rows IDs.
Signature:
getSelectedIds(): Array<string>
(See the example at the
clearSelection
method)getSelectedItems
This method returns the list of currently selected table rows items.
Signature:
getSelectedItems(): Array<TableRowItem>
(See the example at the
clearSelection
method)selectAll
This method selects all the rows in the table. This method has no effect if the rowsSelectable property is set to
false
.Signature:
selectAll(): void
(See the example at the
clearSelection
method)selectId
This method selects the row with the specified ID. This method has no effect if the
rowsSelectable
property is set to false
. The method argument can be a single id or an array of them.Signature:
selectId(id: string | Array<string>): void
id
: The ID of the row to select, or an array of IDs to select multiple rows.
(See the example at the
clearSelection
method)Styling
Theme Variables
Variable | Default Value (Light) | Default Value (Dark) |
---|---|---|
backgroundColor-heading-Table | $color-surface-100 | $color-surface-100 |
backgroundColor-heading-Table--active | $color-surface-300 | $color-surface-300 |
backgroundColor-heading-Table--hover | $color-surface-200 | $color-surface-200 |
backgroundColor-pagination-Table | $backgroundColor-Table | $backgroundColor-Table |
backgroundColor-row-Table | none | none |
backgroundColor-row-Table--hover | $color-primary-50 | $color-primary-50 |
backgroundColor-selected-Table | $color-primary-100 | $color-primary-100 |
backgroundColor-selected-Table--hover | $backgroundColor-row-Table--hover | $backgroundColor-row-Table--hover |
backgroundColor-Table | none | none |
border-cell-Table | 1px solid $borderColor | 1px solid $borderColor |
borderBottom-cell-Table | none | none |
borderBottomColor-cell-Table | none | none |
borderBottomStyle-cell-Table | none | none |
borderBottomWidth-cell-Table | none | none |
borderColor-cell-Table | none | none |
borderEndEndRadius-cell-Table | none | none |
borderEndStartRadius-cell-Table | none | none |
borderHorizontal-cell-Table | none | none |
borderHorizontalColor-cell-Table | none | none |
borderHorizontalStyle-cell-Table | none | none |
borderHorizontalWidth-cell-Table | none | none |
borderLeft-cell-Table | none | none |
color-cell-Table | none | none |
borderLeftStyle-cell-Table | none | none |
borderLeftWidth-cell-Table | none | none |
borderRight-cell-Table | none | none |
color-cell-Table | none | none |
borderRightStyle-cell-Table | none | none |
borderRightWidth-cell-Table | none | none |
borderStartEndRadius-cell-Table | none | none |
borderStartStartRadius-cell-Table | none | none |
borderStyle-cell-Table | none | none |
borderTop-cell-Table | none | none |
borderTopColor-cell-Table | none | none |
borderTopStyle-cell-Table | none | none |
borderTopWidth-cell-Table | none | none |
borderHorizontal-cell-Table | none | none |
borderVerticalColor-cell-Table | none | none |
borderVerticalStyle-cell-Table | none | none |
borderVerticalWidth-cell-Table | none | none |
borderWidth-cell-Table | none | none |
fontSize-heading-Table | $fontSize-tiny | $fontSize-tiny |
fontSize-row-Table | $fontSize-small | $fontSize-small |
fontWeight-heading-Table | $fontWeight-bold | $fontWeight-bold |
fontWeight-row-Table | none | none |
outlineColor-heading-Table--focus | $outlineColor--focus | $outlineColor--focus |
outlineOffset-heading-Table--focus | $outlineOffset--focus | $outlineOffset--focus |
outlineStyle-heading-Table--focus | $outlineStyle--focus | $outlineStyle--focus |
outlineWidth-heading-Table--focus | $outlineWidth--focus | $outlineWidth--focus |
padding-cell-Table | $space-2 $space-0 $space-2 $space-2 | $space-2 $space-0 $space-2 $space-2 |
padding-heading-Table | $space-2 $space-0 $space-2 $space-2 | $space-2 $space-0 $space-2 $space-2 |
paddingBottom-cell-Table | none | none |
paddingBottom-heading-Table | none | none |
paddingHorizontal-cell-first-Table | $space-5 | $space-5 |
paddingHorizontal-cell-last-Table | $space-0 | $space-0 |
paddingHorizontal-cell-Table | none | none |
paddingHorizontal-heading-Table | none | none |
paddingLeft-cell-Table | none | none |
paddingLeft-heading-Table | none | none |
paddingRight-cell-Table | none | none |
paddingRight-heading-Table | none | none |
paddingTop-cell-Table | none | none |
paddingTop-heading-Table | none | none |
paddingVertical-cell-Table | none | none |
paddingVertical-heading-Table | none | none |
textColor-heading-Table | $color-surface-500 | $color-surface-500 |
textColor-pagination-Table | $color-secondary | $color-secondary |
textColor-Table | none | none |
textTransform-heading-Table | uppercase | uppercase |