- Table Data
- Examples
- Data table
- Column configuration
- Hiding the checkbox column
- Text columns with formatting
- Button columns
- Input columns
- Progress bar columns
- Sortable columns
- Nested table
- Column widths
- Column alignment
- Customising built-in column widths
- Row hover and striped rows
- Table title and action slot
- Slots
- Properties
- Events
- Custom Properties
- Parts
- Dependencies
Table Data
<sl-table-data> | SlTableData
Data table component to display data in a tabular format.
Examples
Data table
The data table displays tabular data using a column configuration array. Each column is defined as an object that controls its label, cell type, alignment, width, sorting, and formatting.
By default, the table includes:
- Row selection with checkboxes
- Column sorting (when enabled per column)
- Inline editable, button, and progress bar cells via the column
type - Expandable rows for nested data
<sl-table-data id="data-table-default"></sl-table-data> <script> const dataTable = document.getElementById('data-table-default'); dataTable.chartTitle = 'Special data table'; dataTable.rowHover = true; dataTable.striped = true; dataTable.columns = [ { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Age', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'City', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'input', label: 'Editable input', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false }, { type: 'button', label: 'Action', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false } ]; dataTable.data = [ { id: 1, rows: ['Alice', 12, 'New York', 'A value that needs to be edited', 'View'] }, { id: 2, rows: ['Jim', 38, 'Victoria', 'A value that needs to be edited', 'View'] }, { id: 3, rows: ['Bob', 50, 'Western AUS', 'A value that needs to be edited', 'View'] }, { id: 4, rows: ['Peter', 29, 'TN', 'A value that needs to be edited', 'View'] }, { id: 5, rows: ['Joe', 30, 'NSW', 'A value that needs to be edited', 'View'] } ]; dataTable.addEventListener('cell-edit', (event) => { const { id, rowId, colIndex, updatedValue } = event.detail; console.log(`Cell updated record id: ${id} at row ${rowId}, column ${colIndex}: ${updatedValue}`); }); dataTable.addEventListener('selection-change', (event) => { const { selectedRowIds } = event.detail; console.log(`Ids of rows selected: ${selectedRowIds}`); }); </script>
Column configuration
Each item in the columns array supports the following properties:
| Property | Type | Description |
|---|---|---|
type |
'text' | 'button' | 'input' |
'progress-bar'
|
Determines how cell values are rendered |
label |
string |
Header label displayed in the table |
alignment |
'left' | 'center' | 'right' |
Horizontal alignment of header and cell content |
buttonVariant |
Button variants | Determine button variants |
width |
string |
Fixed column width (e.g. '200px') |
minWidth |
string |
Minimum column width |
maxWidth |
string |
Maximum column width |
formatOptions |
object |
Intl.NumberFormat options passed to toLocaleString for
text columns
|
sortable |
boolean |
When true, clicking the header sorts the column |
Hiding the checkbox column
Use hide-checkbox-column to hide the row selection checkboxes.
<sl-table-data id="data-table-hiding" hide-checkbox-column></sl-table-data> <script> const dataTable = document.getElementById('data-table-hiding'); dataTable.chartTitle = 'Data table with hidden columns'; dataTable.rowHover = true; dataTable.striped = true; dataTable.columns = [ { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Age', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'City', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true } ]; dataTable.data = [ { id: 1, rows: ['Alice', 12, 'New York'] }, { id: 2, rows: ['Jim', 38, 'Chicago'] }, { id: 3, rows: ['Bob', 50, 'Los Vegas'] } ]; </script>
Text columns with formatting
text columns render cell values using
toLocaleString('en-AU', formatOptions). Use formatOptions to control number,
currency, or date formatting.
<sl-table-data id="data-table-format" hide-checkbox-column></sl-table-data> <script> const dataTable = document.getElementById('data-table-format'); dataTable.chartTitle = 'Data table with formatted values'; dataTable.rowHover = true; dataTable.columns = [ { type: 'text', label: 'Asset', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Value', alignment: 'right', width: '', minWidth: '', maxWidth: '', formatOptions: { style: 'currency', currency: 'AUD' }, sortable: true } ]; dataTable.data = [ { id: 1, rows: ['Australian equities', 860611.01] }, { id: 2, rows: ['Global equities', 1458989] }, { id: 3, rows: ['Cash', 123130] } ]; </script>
Button columns
Set a column’s type to 'button' to render a tertiary button by default in
each cell, or specify the variant with buttonVariant. The cell value is used as the
button label; Button will not be render when empty, otherwise, the button-label attribute
value is used instead.
<sl-table-data id="data-table-button" button-label="View"></sl-table-data> <script> const dataTable = document.getElementById('data-table-button'); dataTable.chartTitle = 'Data table with button column'; dataTable.rowHover = true; dataTable.striped = true; dataTable.columns = [ { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Age', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'button', label: 'Action', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false, buttonVariant: 'primary' } ]; dataTable.data = [ { id: 1, rows: ['Alice', 12, 'Details'] }, { id: 2, rows: ['Jim', 38, 'Edit'] }, { id: 3, rows: ['Bob', 50, ''] }, { id: 4, rows: ['Peter', 58, ' '] }, { id: 5, rows: ['Jenny', 42] } ]; dataTable.addEventListener('select', (event) => { const { rowId, colIndex } = event.detail; console.log(`Button clicked at row ${rowId}, column ${colIndex}`); }); </script>
Input columns
Set a column’s type to 'input' to allow inline editing. The component emits
a cell-edit event when the user finishes editing a cell (on blur).
<sl-table-data id="data-table-input"></sl-table-data> <script> const dataTable = document.getElementById('data-table-input'); dataTable.chartTitle = 'Data table with editable column'; dataTable.rowHover = true; dataTable.columns = [ { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'input', label: 'Notes', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false } ]; dataTable.data = [ { id: 1, rows: ['Alice', 'A value that needs to be edited'] }, { id: 2, rows: ['Jim', 'Another editable value'] }, { id: 3, rows: ['Bob', 'Update me on blur'] } ]; dataTable.addEventListener('cell-edit', (event) => { const { id, rowId, colIndex, updatedValue } = event.detail; console.log(`Cell updated for id ${id}: ${updatedValue}`); }); </script>
Progress bar columns
Set a column’s type to 'progress-bar' to render an
sl-progress-bar in each cell. Cell values must be numbers from 0–100; non-numeric values
render an empty cell. The indicator color is chosen automatically based on the value: danger (≤ 70),
warning (> 70), or success (> 90). The current value is shown on the bar.
<sl-table-data id="data-table-progress-bar" hide-checkbox-column></sl-table-data> <script> const dataTable = document.getElementById('data-table-progress-bar'); dataTable.chartTitle = 'Data table with progress bar column'; dataTable.rowHover = true; dataTable.columns = [ { type: 'text', label: 'Goal', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'progress-bar', label: 'Progress', alignment: 'left', width: '200px', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true } ]; dataTable.data = [ { id: 1, rows: ['Revenue target', 95] }, { id: 2, rows: ['Client onboarding', 78] }, { id: 3, rows: ['Training completion', 45] } ]; </script>
Sortable columns
Sorting is controlled per column via the sortable property. Click a sortable header to
toggle between ascending and descending order. Columns without sortable: true are not
sortable.
<sl-table-data id="data-table-sortable"></sl-table-data> <script> const dataTable = document.getElementById('data-table-sortable'); dataTable.chartTitle = 'Data table with sortable columns'; dataTable.rowHover = true; dataTable.striped = true; dataTable.columns = [ { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Age', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'input', label: 'Editable input', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false } ]; dataTable.data = [ { id: 1, rows: ['Alice', 12, 'A value that needs to be edited'] }, { id: 2, rows: ['Jim', 38, 'A value that needs to be edited'] }, { id: 3, rows: ['Bob', 50, 'A value that needs to be edited'] } ]; </script>
Nested table
Table rows can be expanded when nestedData and nestedColumns are provided on
a row. The nested table is rendered inside the expanded row with the checkbox column hidden.
A maximum height is applied to the nested table body; content that exceeds this height scrolls vertically.
<sl-table-data id="nested-table-example" hide-checkbox-column></sl-table-data> <script> const dataTable = document.getElementById('nested-table-example'); dataTable.chartTitle = 'Nested data table'; dataTable.columns = [ { type: 'text', label: 'Code', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Quantity', alignment: 'right', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Price valuation date', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false }, { type: 'text', label: 'Gross Capital Gain/(Loss)', alignment: 'right', width: '', minWidth: '', maxWidth: '', formatOptions: { style: 'currency', currency: 'AUD' }, sortable: false } ]; const nestedColumns = [ { type: 'text', label: 'Parcel date', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false }, { type: 'text', label: 'Accounting cost base', alignment: 'right', width: '', minWidth: '', maxWidth: '', formatOptions: { style: 'currency', currency: 'AUD' }, sortable: false }, { type: 'text', label: 'Cost base', alignment: 'right', width: '', minWidth: '', maxWidth: '', formatOptions: { style: 'currency', currency: 'AUD' }, sortable: false }, { type: 'text', label: 'Market Value', alignment: 'right', width: '', minWidth: '', maxWidth: '', formatOptions: { style: 'currency', currency: 'AUD' }, sortable: false }, { type: 'text', label: 'Gross Capital Gain/(Loss)', alignment: 'right', width: '', minWidth: '', maxWidth: '', formatOptions: { style: 'currency', currency: 'AUD' }, sortable: false } ]; dataTable.data = [ { id: 1, rows: ['ANZ', 'Australia and New Zealand Banking Group', 100, '12/04/2026', 1000], nestedColumns, nestedData: [ { id: 1, rows: ['22/01/2026', 1000, 1000, 1000, 1000] }, { id: 2, rows: ['22/01/2026', 1000, 1000, 1000, 1000] }, { id: 3, rows: ['22/01/2026', 1000, 1000, 1000, 1000] } ] }, { id: 2, rows: ['APA', 'APA Group', 50, '12/04/2026', 500], nestedColumns, nestedData: [ { id: 1, rows: ['22/01/2026', 500, 500, 500, 500] }, { id: 2, rows: ['22/01/2026', 500, 500, 500, 500] } ] }, { id: 3, rows: ['CBA', 'Commonwealth Bank', 75, '12/04/2026', 750] }, { id: 4, rows: ['CH01', 'Charter Hall', 25, '12/04/2026', 250] } ]; </script>
Column widths
Set width, minWidth, and/or maxWidth on individual column
definitions to control column sizing. When any column has a width set, the table uses fixed layout.
<sl-table-data id="parent-table" hide-checkbox-column></sl-table-data> <script> const parentTable = document.getElementById('parent-table'); parentTable.chartTitle = 'Table with custom column widths'; parentTable.rowHover = true; parentTable.striped = true; parentTable.columns = [ { type: 'text', label: 'Name', alignment: 'left', width: '300px', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Age', alignment: 'left', width: '100px', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'City', alignment: 'left', width: '200px', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false } ]; parentTable.data = [ { id: 1, rows: ['Alice', 25, 'New York'] }, { id: 2, rows: ['Bob', 30, 'Los Angeles'] }, { id: 3, rows: ['Charlie', 35, 'Chicago'] } ]; </script>
Nested table column widths
Apply widths directly on each column in the nestedColumns array passed to expandable
rows.
<sl-table-data id="nested-table-custom-width" hide-checkbox-column></sl-table-data> <script> const dataTable = document.getElementById('nested-table-custom-width'); dataTable.chartTitle = 'Nested table with custom column widths'; dataTable.columns = [ { type: 'text', label: 'Code', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true } ]; const nestedColumns = [ { type: 'text', label: 'Parcel date', alignment: 'left', width: '300px', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false }, { type: 'text', label: 'Cost base', alignment: 'right', width: '300px', minWidth: '', maxWidth: '', formatOptions: { style: 'currency', currency: 'AUD' }, sortable: false }, { type: 'text', label: 'Market Value', alignment: 'right', width: '300px', minWidth: '', maxWidth: '', formatOptions: { style: 'currency', currency: 'AUD' }, sortable: false } ]; dataTable.data = [ { id: 1, rows: ['ANZ', 'Australia and New Zealand Banking Group'], nestedColumns, nestedData: [ { id: 11, rows: ['22/01/2026', 1000, 1050] }, { id: 12, rows: ['23/01/2026', 1200, 1180] } ] } ]; </script>
Column alignment
Set alignment to 'left', 'center', or 'right' on
each column definition. Alignment applies to both the header and body cells.
<sl-table-data id="data-table-alignment" hide-checkbox-column></sl-table-data> <script> const dataTable = document.getElementById('data-table-alignment'); dataTable.chartTitle = 'Data table with custom column alignment'; dataTable.rowHover = true; dataTable.striped = true; dataTable.columns = [ { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Age', alignment: 'center', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'City', alignment: 'right', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false } ]; dataTable.data = [ { id: 1, rows: ['Alice', 25, 'Sydney'] }, { id: 2, rows: ['Bob', 38, 'Melbourne'] }, { id: 3, rows: ['Charlie', 29, 'Brisbane'] } ]; </script>
Customising built-in column widths
The checkbox column can be resized using a CSS custom property on the component.
<sl-table-data id="data-table-css-widths" style="--table-data-checkbox-column-width: 56px;" ></sl-table-data> <script> const dataTable = document.getElementById('data-table-css-widths'); dataTable.chartTitle = 'Table with custom checkbox column width'; dataTable.columns = [ { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false } ]; dataTable.data = [ { id: 1, rows: ['Alice'] }, { id: 2, rows: ['Bob'] } ]; </script>
Row hover and striped rows
Use row-hover to highlight rows on hover and striped to apply alternating
row backgrounds.
<sl-table-data id="data-table-styles" row-hover striped></sl-table-data> <script> const dataTable = document.getElementById('data-table-styles'); dataTable.columns = [ { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false }, { type: 'text', label: 'Age', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: false } ]; dataTable.data = [ { id: 1, rows: ['Alice', 12] }, { id: 2, rows: ['Jim', 38] }, { id: 3, rows: ['Bob', 50] } ]; </script>
Table title and action slot
Use the table-title attribute (or chartTitle property) to display a heading
above the table. Place action buttons in the default slot to render them beside the title.
<sl-table-data id="data-table-slot" table-title="Portfolio holdings"> <sl-button size="small" variant="secondary">Export</sl-button> </sl-table-data> <script> const dataTable = document.getElementById('data-table-slot'); dataTable.columns = [ { type: 'text', label: 'Code', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true }, { type: 'text', label: 'Name', alignment: 'left', width: '', minWidth: '', maxWidth: '', formatOptions: {}, sortable: true } ]; dataTable.data = [ { id: 1, rows: ['ANZ', 'Australia and New Zealand Banking Group'] }, { id: 2, rows: ['CBA', 'Commonwealth Bank'] } ]; </script>
[component-metadata:sl-table-data]
Slots
| Name | Description |
|---|---|
| (default) | The default slot. |
Learn more about using slots.
Properties
| Name | Description | Reflects | Type | Default |
|---|---|---|---|---|
data
|
The data to be displayed in the table. |
|
TableData[]
|
[]
|
columns
|
The titles to be displayed in the table header columns. |
Column[]
|
[]
|
|
chartTitle
table-title
|
The title of the data table. |
string
|
''
|
|
rowHover
row-hover
|
Adds hover effect to the table rows. |
boolean
|
false
|
|
striped
|
Adds alternating stripes to the table rows. |
boolean
|
false
|
|
hideCheckboxColumn
hide-checkbox-column
|
Hides the checkbox selection column. |
boolean
|
false
|
|
buttonLabel
button-label
|
Default label used when button cell doesn’t override it. |
string
|
'Label'
|
|
buttonVariant
button-variant
|
Default button variant used when button cell doesn’t override it. |
SlButton['variant']
|
'tertiary'
|
|
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.
Events
| Name | React Event | Description | Event Detail |
|---|---|---|---|
cell-edit |
|
event emitted when a cell is edited. | - |
select |
|
event emitted when the selection changes. | - |
Learn more about events.
Custom Properties
| Name | Description | Default |
|---|---|---|
--table-data-checkbox-column-width |
The customisable width of the checkbox column. |
Learn more about customizing CSS custom properties.
Parts
| Name | Description |
|---|---|
base |
The component’s base wrapper. |
table |
The table element. |
Learn more about customizing CSS parts.
Dependencies
This component automatically imports the following dependencies.
<sl-checkbox><sl-icon><sl-icon-button><sl-input>