Table Components
Overview
The Table components provide a flexible and feature-rich way to display tabular data with features like sorting, selection, pagination, and search capabilities.
Features
- Sortable columns
- Row selection with checkboxes
- Fixed column widths
- Responsive design
- Loading state
- Empty state handling
- Customizable headers and cells
- Row headers support
- Pagination support
- Search functionality (with TableWrapper)
- Action buttons support (with TableWrapper)
Components
Table Component
The core table component that handles data display and interactions.
Props
Prop | Type | Default | Description |
---|---|---|---|
data | array | Required | Array of objects containing the table data |
columns | array | Required | Array of column configuration objects |
isSelectable | boolean | false | Enables row selection functionality |
selected | array | [] | Array of selected row IDs |
setSelected | function | () => {} | Callback function for selection changes |
showRows | number | Infinity | Number of rows to display |
tableSortable | boolean | false | Enables table sorting functionality |
defaultSortedColumn | string | '' | Initial column to sort by |
defaultSortDirection | string | '' | Initial sort direction ('asc' or 'desc') |
caption | string|element | null | Table caption |
sortButtonsScreenReaderText | object | See below | Screen reader text for sort buttons |
hasFixedColumnWidths | boolean | false | Enables fixed column widths |
headingClassName | array | [] | Additional classes for the table header |
hideHeader | boolean | false | Hides the table header |
className | string | undefined | Additional classes for the table |
rowHeaderColumnKey | string | null | Key of the column to use as row header |
isLoading | boolean | false | Shows loading spinner when true |
paginatedData | array | Required | Array of paginated data |
Column Configuration
Each column in the columns
array should be an object with the following properties:
Prop | Type | Required | Description |
---|---|---|---|
key | string | Yes | Unique identifier for the column |
label | string|element | Yes | Column header text or element |
columnSortable | boolean | If tableSortable is true | Enables sorting for this column |
render | function | No | Custom render function for cell content |
hideHeader | boolean | No | Hides the header for this column |
width | string | If hasFixedColumnWidths is true | CSS class for column width |
className | string | No | Additional classes for the column |
TableWrapper Component
A wrapper component that adds search functionality and action buttons to a table.
Props
Prop | Type | Default | Description |
---|---|---|---|
children | node | Required | The table component to wrap |
actions | node | null | Action buttons or elements to display in the header |
label | string | Required | Label used for the search placeholder |
setSearch | function | Required | Callback function for search input changes |
miniTable | boolean | false | When true, displays the label as a title and applies mini-table styling |
Usage Examples
Basic Examples
Basic Table
<Table
data={[
{ name: 'John Doe', age: 30, role: 'Developer' },
{ name: 'Jane Smith', age: 25, role: 'Designer' },
]}
columns={[
{ label: 'Name', key: 'name' },
{ label: 'Age', key: 'age' },
{ label: 'Role', key: 'role' },
]}
caption="Employee List"
/>
Table with Search and Actions
() => {
const [search, setSearch] = useState('');
const [data, setData] = useState([
{ id: 1, name: 'John Doe', role: 'Developer' },
{ id: 2, name: 'Jane Smith', role: 'Designer' },
]);
const filteredData = data.filter(item =>
item.name.toLowerCase().includes(search.toLowerCase()) ||
item.role.toLowerCase().includes(search.toLowerCase())
);
return (
<TableWrapper
label="employees"
setSearch={setSearch}
actions={
<button className="btn btn-primary">Add Employee</button>
}
>
<Table
data={filteredData}
columns={[
{ label: 'Name', key: 'name' },
{ label: 'Role', key: 'role' },
]}
caption="Employee List"
/>
</TableWrapper>
);
}
Advanced Examples
Sortable Table
<Table
data={[
{ name: 'John Doe', age: 30, role: 'Developer' },
{ name: 'Jane Smith', age: 25, role: 'Designer' },
]}
columns={[
{ label: 'Name', key: 'name', columnSortable: true },
{ label: 'Age', key: 'age', columnSortable: true },
{ label: 'Role', key: 'role' },
]}
tableSortable
defaultSortedColumn="name"
defaultSortDirection="asc"
caption="Sortable Employee List"
/>
Selectable Table
() => {
const [selected, setSelected] = useState([]);
return (
<Table
data={[
{ id: 1, name: 'John Doe', age: 30, role: 'Developer' },
{ id: 2, name: 'Jane Smith', age: 25, role: 'Designer' },
]}
columns={[
{ label: 'Name', key: 'name' },
{ label: 'Age', key: 'age' },
{ label: 'Role', key: 'role' },
]}
isSelectable
selected={selected}
setSelected={setSelected}
caption="Selectable Employee List"
/>
);
}
TableWrapper with Multiple Actions
() => {
const [search, setSearch] = useState('');
return (
<TableWrapper
label="employees"
setSearch={setSearch}
actions={
<>
<button className="btn btn-outline-primary">Import</button>
<button className="btn btn-primary">Add New</button>
</>
}
>
<Table
data={[
{ id: 1, name: 'John Doe', role: 'Developer' },
{ id: 2, name: 'Jane Smith', role: 'Designer' },
]}
columns={[
{ label: 'Name', key: 'name' },
{ label: 'Role', key: 'role' },
]}
caption="Employee List with Multiple Actions"
/>
</TableWrapper>
);
}
Styling Examples
Table-striped
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
className="table-striped"
/>
Default heading
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
headingClassName={['thead-default']}
/>
Responsive
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
className="table-responsive"
/>
Fixed Column Widths
<Table
data={[
{ name: 'John Doe', age: 30, role: 'Developer' },
{ name: 'Jane Smith', age: 25, role: 'Designer' },
]}
columns={[
{ label: 'Name', key: 'name', width: 'col-4' },
{ label: 'Age', key: 'age', width: 'col-2' },
{ label: 'Role', key: 'role', width: 'col-6' },
]}
hasFixedColumnWidths
caption="Fixed Width Columns"
/>
Feature Examples
Loading State
<Table
data={[]}
columns={[
{ label: 'Name', key: 'name' },
{ label: 'Age', key: 'age' },
{ label: 'Role', key: 'role' },
]}
isLoading
caption="Loading Employees"
/>
Custom Cell Rendering
<Table
data={[
{ name: 'John Doe', age: 30, role: 'Developer', status: 'active' },
{ name: 'Jane Smith', age: 25, role: 'Designer', status: 'inactive' },
]}
columns={[
{ label: 'Name', key: 'name' },
{ label: 'Age', key: 'age' },
{ label: 'Role', key: 'role' },
{
label: 'Status',
key: 'status',
render: ({ value }) => (
<span className={`badge bg-${value === 'active' ? 'success' : 'danger'}`}>
{value}
</span>
),
},
]}
caption="Custom Cell Rendering"
/>
Row header
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
rowHeaderColumnKey="name"
/>
Accessibility
- Uses semantic HTML table elements
- Includes ARIA attributes for sortable columns
- Provides screen reader text for sort buttons
- Supports row headers for better accessibility
- Maintains proper table structure with
thead
andtbody
Deprecation Notice
This component is marked for deprecation and will be replaced by the DataTable component. Please plan to migrate to the new component when available.
Unstyled
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
/>
Table-striped
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
className="table-striped"
/>
Default heading
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
headingClassName={['thead-default']}
/>
Responsive
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
className="table-responsive"
/>
Sortable
() => {
const catData = [
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
];
const catColumns = [
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
];
const sort = function sort(firstElement, secondElement, key, direction) {
const directionIsAsc = direction === 'asc';
if (firstElement[key] > secondElement[key]) {
return directionIsAsc ? 1 : -1;
} else if (firstElement[key] < secondElement[key]) {
return directionIsAsc ? -1 : 1;
}
return 0;
};
const catDataSortable = catData.slice();
return (
<Table
data={catDataSortable.sort((firstElement, secondElement) =>
sort(firstElement, secondElement, catColumns[0].key, 'desc'),
)}
columns={catColumns.map(column => ({
...column,
onSort(direction) {
catDataSortable.sort((firstElement, secondElement) =>
sort(firstElement, secondElement, column.key, direction),
);
},
}))}
caption="Famous Internet Cats"
tableSortable
defaultSortedColumn={catColumns[0].key}
defaultSortDirection="desc"
/>
);
};
Fixed
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
hasFixedColumnWidths
/>
Row header
<Table
data={[
{
name: 'Lil Bub',
color: 'brown tabby',
famous_for: 'weird tongue',
},
{
name: 'Grumpy Cat',
color: 'siamese',
famous_for: 'serving moods',
},
{
name: 'Smoothie',
color: 'orange tabby',
famous_for: 'modeling',
},
{
name: 'Maru',
color: 'brown tabby',
famous_for: 'being a lovable oaf',
},
{
name: 'Keyboard Cat',
color: 'orange tabby',
famous_for: 'piano virtuoso',
},
{
name: 'Long Cat',
color: 'russian white',
famous_for:
'being loooooooooooooooooooooooooooooooooooooooooooooooooooooong',
},
]}
columns={[
{
label: 'Name',
key: 'name',
columnSortable: true,
onSort: () => {},
width: 'col-3',
},
{
label: 'Famous For',
key: 'famous_for',
columnSortable: false,
onSort: () => {},
width: 'col-6',
},
{
label: 'Coat Color',
key: 'color',
columnSortable: false,
hideHeader: true,
onSort: () => {},
width: 'col-3',
},
]}
caption="Famous Internet Cats"
rowHeaderColumnKey="name"
/>
Mini Table Example
() => {
const [search, setSearch] = useState('');
const data = [
{ id: 1, name: 'John Doe', role: 'Developer' },
{ id: 2, name: 'Jane Smith', role: 'Designer' },
];
const filteredData = data.filter(item =>
item.name.toLowerCase().includes(search.toLowerCase()) ||
item.role.toLowerCase().includes(search.toLowerCase())
);
return (
<TableWrapper
label="Team Members"
setSearch={setSearch}
miniTable
actions={
<button className="btn btn-primary btn-sm">Add Member</button>
}
>
<Table
data={filteredData}
columns={[
{ label: 'Name', key: 'name' },
{ label: 'Role', key: 'role' },
]}
caption="Team Members List"
/>
</TableWrapper>
);
}
Dependencies
Repository | Usage Count |
---|---|
frontend-app-staff-dashboard | 18 |
frontend-app-dashboard | 2 |
frontend-app-course-authoring | 5 |
frontend-app-learning | 2 |
frontend-app-profile | 1 |
Detailed usage locations:
frontend-app-staff-dashboard
src/components/MiniTable.jsx
src/components/TablePage.jsx
src/pages/program-single/attendance/index.jsx
src/pages/program-single/enrollment/EnrollDrawer.jsx
src/pages/program-single/enrollment/index.jsx
src/pages/program-single/fee-statistics/index.jsx
src/pages/program-single/program-team/AddUserDrawer.jsx
src/pages/program-single/program-team/index.jsx
src/pages/support/index.jsx
src/pages/users/AddUsersDrawer.jsx
src/pages/users/index.jsx
src/pages/users/learners/index.jsx
src/pages/users/staffs/index.jsx
src/pages/users/teams/AddUsersToTeamDrawer.jsx
src/pages/users/teams/TeamSingle.jsx
src/pages/users/teams/index.jsx
src/pages/utilities/notifications/NotificationsDrawer.jsx
src/pages/utilities/notifications/index.jsx
frontend-app-dashboard
src/components/MiniTable.jsx
src/pages/support/index.jsx
frontend-app-course-authoring
src/attendance/index.jsx
src/cohorts/CohortList.jsx
src/enrollments/EnrollDrawer.jsx
src/enrollments/index.jsx
src/fee-statistics/index.jsx
frontend-app-learning
src/course-home/progress-tab/grades/detailed-grades/DetailedGradesTable.jsx
src/course-home/progress-tab/grades/grade-summary/GradeSummaryTable.jsx
frontend-app-profile
src/BlendxProfile/tabs/Purchases.jsx