Table
A feature-rich data table with sorting, pagination, custom rendering, style variants, and responsive design.
Basic Usage
Basic Table
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
import { Table } from 'fluxo-ui';
const columns = [
{ title: 'ID', field: 'id', sortable: true },
{ title: 'Name', field: 'name', sortable: true },
{ title: 'Email', field: 'email', sortable: true },
{ title: 'Role', field: 'role', sortable: true },
];
<Table columns={columns} rows={data} totalRows={data.length} pagination={false} />Style Variants
Bordered
All cell borders visible
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
Striped
Alternating row background colors
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
| 6 | Frank Wilson | frank@example.com | Analyst |
| 7 | Grace Lee | grace@example.com | Developer |
| 8 | Henry Taylor | henry@example.com | Designer |
Compact
Reduced padding for dense data display
| ID | Name | Role | Department | Join Date | |
|---|---|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin | Engineering | 2023-01-15 |
| 2 | Bob Smith | bob@example.com | Developer | Engineering | 2023-03-22 |
| 3 | Carol White | carol@example.com | Designer | Design | 2023-02-10 |
| 4 | David Brown | david@example.com | Manager | Operations | 2022-11-05 |
| 5 | Emma Davis | emma@example.com | Developer | Engineering | 2023-04-18 |
| 6 | Frank Wilson | frank@example.com | Analyst | Analytics | 2023-05-30 |
| 7 | Grace Lee | grace@example.com | Developer | Engineering | 2023-06-12 |
| 8 | Henry Taylor | henry@example.com | Designer | Design | 2022-09-25 |
Comfortable
Increased padding for readability
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
Borderless
No borders or shadow for a clean look
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
Hoverable
Primary-color row hover highlight
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
Card Style
Each row rendered as an individual card
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
Minimal Header
Subtle uppercase header with no background
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
Sticky Header
Header stays fixed when scrolling (resize container to see)
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
| 6 | Frank Wilson | frank@example.com | Analyst |
| 7 | Grace Lee | grace@example.com | Developer |
| 8 | Henry Taylor | henry@example.com | Designer |
Combined: Striped + Compact + Bordered
Multiple variants can be combined
| ID | Name | Role | Department | Join Date | |
|---|---|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin | Engineering | 2023-01-15 |
| 2 | Bob Smith | bob@example.com | Developer | Engineering | 2023-03-22 |
| 3 | Carol White | carol@example.com | Designer | Design | 2023-02-10 |
| 4 | David Brown | david@example.com | Manager | Operations | 2022-11-05 |
| 5 | Emma Davis | emma@example.com | Developer | Engineering | 2023-04-18 |
| 6 | Frank Wilson | frank@example.com | Analyst | Analytics | 2023-05-30 |
| 7 | Grace Lee | grace@example.com | Developer | Engineering | 2023-06-12 |
| 8 | Henry Taylor | henry@example.com | Designer | Design | 2022-09-25 |
<Table bordered columns={columns} rows={data} totalRows={data.length} pagination={false} />
<Table striped columns={columns} rows={data} totalRows={data.length} pagination={false} />
<Table compact columns={columns} rows={data} totalRows={data.length} pagination={false} />
<Table comfortable columns={columns} rows={data} totalRows={data.length} pagination={false} />
<Table borderless columns={columns} rows={data} totalRows={data.length} pagination={false} />
<Table hoverable columns={columns} rows={data} totalRows={data.length} pagination={false} />
<Table cardStyle columns={columns} rows={data} totalRows={data.length} pagination={false} />
<Table minimalHeader columns={columns} rows={data} totalRows={data.length} pagination={false} />
<Table stickyHeader columns={columns} rows={data} totalRows={data.length} pagination={false} />
<Table striped compact bordered columns={columns} rows={data} totalRows={data.length} pagination={false} />Sortable Columns
Table with Sorting
Click column headers to sort
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
| 6 | Frank Wilson | frank@example.com | Analyst |
| 7 | Grace Lee | grace@example.com | Developer |
| 8 | Henry Taylor | henry@example.com | Designer |
<Table
columns={columns}
rows={data}
totalRows={data.length}
onSort={(column, asc) => console.log('Sort by:', column.field, asc)}
pagination={false}
/>Custom Cell Rendering
Table with Custom Templates
Custom cell rendering with badges
| ID | Name | Status | Join Date | |
|---|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | active | 2023-01-15 |
| 2 | Bob Smith | bob@example.com | active | 2023-03-22 |
| 3 | Carol White | carol@example.com | active | 2023-02-10 |
| 4 | David Brown | david@example.com | inactive | 2022-11-05 |
| 5 | Emma Davis | emma@example.com | active | 2023-04-18 |
| 6 | Frank Wilson | frank@example.com | active | 2023-05-30 |
| 7 | Grace Lee | grace@example.com | active | 2023-06-12 |
| 8 | Henry Taylor | henry@example.com | inactive | 2022-09-25 |
{
title: 'Status',
field: 'status',
template: (row) => (
<span className={row.status === 'active' ? 'badge-green' : 'badge-red'}>
{row.status}
</span>
),
}With Pagination
Table with Pagination
| ID | Name | Status | Join Date | |
|---|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | active | 2023-01-15 |
| 2 | Bob Smith | bob@example.com | active | 2023-03-22 |
| 3 | Carol White | carol@example.com | active | 2023-02-10 |
| 4 | David Brown | david@example.com | inactive | 2022-11-05 |
| 5 | Emma Davis | emma@example.com | active | 2023-04-18 |
<Table
columns={columns}
rows={data}
totalRows={data.length}
rowsPerPage={5}
rowCounts={[5, 10, 15]}
onChange={(params) => console.log(params)}
/>Row Selection
Table with Row Click
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
<Table
columns={columns}
rows={data}
totalRows={data.length}
onRowClick={({ row }) => setSelectedRow(row)}
pagination={false}
/>Responsive Columns
Responsive Columns
Resize the browser to see columns hide at breakpoints
| ID | Name | Role | Department | Join Date | |
|---|---|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin | Engineering | 2023-01-15 |
| 2 | Bob Smith | bob@example.com | Developer | Engineering | 2023-03-22 |
| 3 | Carol White | carol@example.com | Designer | Design | 2023-02-10 |
| 4 | David Brown | david@example.com | Manager | Operations | 2022-11-05 |
| 5 | Emma Davis | emma@example.com | Developer | Engineering | 2023-04-18 |
const columns = [
{ title: 'ID', field: 'id' },
{ title: 'Name', field: 'name' },
{ title: 'Email', field: 'email', hideBelow: 'md' },
{ title: 'Role', field: 'role', hideBelow: 'sm' },
{ title: 'Department', field: 'department', hideBelow: 'lg' },
{ title: 'Join Date', field: 'joinDate', hideBelow: 'xl' },
];With Action Buttons
Table with Row Actions
| Name | Role | Actions | |
|---|---|---|---|
| Alice Johnson | alice@example.com | Admin | |
| Bob Smith | bob@example.com | Developer | |
| Carol White | carol@example.com | Designer | |
| David Brown | david@example.com | Manager | |
| Emma Davis | emma@example.com | Developer |
{
title: 'Actions',
field: 'id',
template: (row) => (
<div className="flex gap-2">
<Button size="xs" variant="primary" onClick={() => handleEdit(row)}>Edit</Button>
<Button size="xs" variant="danger" layout="outlined" onClick={() => handleDelete(row)}>Delete</Button>
</div>
),
}Loading & Empty States
Loading State
Shimmer skeleton while data loads
| ID | Name | Role | |
|---|---|---|---|
| 1 | Alice Johnson | alice@example.com | Admin |
| 2 | Bob Smith | bob@example.com | Developer |
| 3 | Carol White | carol@example.com | Designer |
| 4 | David Brown | david@example.com | Manager |
| 5 | Emma Davis | emma@example.com | Developer |
| 6 | Frank Wilson | frank@example.com | Analyst |
| 7 | Grace Lee | grace@example.com | Developer |
| 8 | Henry Taylor | henry@example.com | Designer |
Empty State
Custom message when no data
| ID | Name | Role | |
|---|---|---|---|
| No users found. Try adjusting your filters. | |||
<Table
columns={columns}
rows={data}
totalRows={data.length}
isLoading={isLoading}
expectedRows={5}
/><Table
columns={columns}
rows={[]}
totalRows={0}
noRowsMessage="No users found. Try adjusting your filters."
pagination={false}
/>Import
import { Table } from 'fluxo-ui';
import type { Column, OnChangeParams } from 'fluxo-ui';Table Props
columnsreqColumn[]Array of column definitions
columnsreqColumn[]Array of column definitions
rowsreqany[]Array of data objects to display
rowsreqany[]Array of data objects to display
totalRowsreqnumberTotal number of rows (for pagination)
totalRowsreqnumberTotal number of rows (for pagination)
idstringHTML id for the table container
idstringHTML id for the table container
isLoadingboolean"false"Show shimmer loading state
isLoadingboolean"false"Show shimmer loading state
expectedRowsnumberNumber of shimmer rows when loading
expectedRowsnumberNumber of shimmer rows when loading
onSort(column: Column, asc: boolean) => voidCallback when a sortable column is clicked
onSort(column: Column, asc: boolean) => voidCallback when a sortable column is clicked
onChange(params: OnChangeParams) => voidCallback for sort, pagination, or row count changes
onChange(params: OnChangeParams) => voidCallback for sort, pagination, or row count changes
noRowsMessagestring"'No records found.'"Message when no rows exist
noRowsMessagestring"'No records found.'"Message when no rows exist
rowCountsnumber[]"[10, 20, 25, 50, 75, 100]"Options for rows per page dropdown
rowCountsnumber[]"[10, 20, 25, 50, 75, 100]"Options for rows per page dropdown
rowsPerPagenumber"rowCounts[0]"Initial rows per page
rowsPerPagenumber"rowCounts[0]"Initial rows per page
sortColumnColumnInitially sorted column
sortColumnColumnInitially sorted column
sortAscboolean"true"Initial sort direction
sortAscboolean"true"Initial sort direction
pagenumber"1"Initial page number
pagenumber"1"Initial page number
paginationboolean"true"Show pagination footer
paginationboolean"true"Show pagination footer
containerClassNamestringCSS class for the table container
containerClassNamestringCSS class for the table container
onRowClick(arg: { row, index, event }) => voidCallback when a row is clicked
onRowClick(arg: { row, index, event }) => voidCallback when a row is clicked
borderedboolean"false"Show all cell borders
borderedboolean"false"Show all cell borders
stripedboolean"false"Alternate row background colors
stripedboolean"false"Alternate row background colors
compactboolean"false"Reduced padding for dense display
compactboolean"false"Reduced padding for dense display
comfortableboolean"false"Increased padding for readability
comfortableboolean"false"Increased padding for readability
borderlessboolean"false"Remove all borders and shadow
borderlessboolean"false"Remove all borders and shadow
hoverableboolean"false"Primary-color row hover highlight
hoverableboolean"false"Primary-color row hover highlight
cardStyleboolean"false"Render each row as a card
cardStyleboolean"false"Render each row as a card
minimalHeaderboolean"false"Subtle uppercase header
minimalHeaderboolean"false"Subtle uppercase header
stickyHeaderboolean"false"Fixed header on scroll
stickyHeaderboolean"false"Fixed header on scroll
Column Configuration
titlereqstringColumn header text
titlereqstringColumn header text
fieldreqstringProperty name in the data object
fieldreqstringProperty name in the data object
helpTextstringTooltip text on the column header
helpTextstringTooltip text on the column header
headerClassNamestringCSS class for the column header
headerClassNamestringCSS class for the column header
cellClassNamestringCSS class for cells in this column
cellClassNamestringCSS class for cells in this column
sortableboolean"false"Enable sorting for this column
sortableboolean"false"Enable sorting for this column
hideBelow'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'Hide column below breakpoint
hideBelow'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'Hide column below breakpoint
template(row: any) => React.ReactNodeCustom render function for cell content
template(row: any) => React.ReactNodeCustom render function for cell content
Features
Style Variants
Nine composable styles: bordered, striped, compact, comfortable, borderless, hoverable, card, minimal header, sticky header.
Column Sorting
Click headers to sort — supports client-side and server-side sorting.
Pagination
Built-in footer with configurable rows-per-page and page navigation.
Custom Cell Rendering
Template functions per column for badges, buttons, or any React element.
Responsive Columns
Hide columns on smaller screens using hideBelow breakpoints.
Loading State
Animated shimmer skeleton while data is being fetched.
Row Click Handler
Attach onRowClick callbacks for selection or navigation.
Theming
Dark/light mode and all brand themes via CSS custom properties.