Skip to main content

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

PropTypeDefaultDescription
dataarrayRequiredArray of objects containing the table data
columnsarrayRequiredArray of column configuration objects
isSelectablebooleanfalseEnables row selection functionality
selectedarray[]Array of selected row IDs
setSelectedfunction() => {}Callback function for selection changes
showRowsnumberInfinityNumber of rows to display
tableSortablebooleanfalseEnables table sorting functionality
defaultSortedColumnstring''Initial column to sort by
defaultSortDirectionstring''Initial sort direction ('asc' or 'desc')
captionstring|elementnullTable caption
sortButtonsScreenReaderTextobjectSee belowScreen reader text for sort buttons
hasFixedColumnWidthsbooleanfalseEnables fixed column widths
headingClassNamearray[]Additional classes for the table header
hideHeaderbooleanfalseHides the table header
classNamestringundefinedAdditional classes for the table
rowHeaderColumnKeystringnullKey of the column to use as row header
isLoadingbooleanfalseShows loading spinner when true
paginatedDataarrayRequiredArray of paginated data

Column Configuration

Each column in the columns array should be an object with the following properties:

PropTypeRequiredDescription
keystringYesUnique identifier for the column
labelstring|elementYesColumn header text or element
columnSortablebooleanIf tableSortable is trueEnables sorting for this column
renderfunctionNoCustom render function for cell content
hideHeaderbooleanNoHides the header for this column
widthstringIf hasFixedColumnWidths is trueCSS class for column width
classNamestringNoAdditional classes for the column

TableWrapper Component

A wrapper component that adds search functionality and action buttons to a table.

Props

PropTypeDefaultDescription
childrennodeRequiredThe table component to wrap
actionsnodenullAction buttons or elements to display in the header
labelstringRequiredLabel used for the search placeholder
setSearchfunctionRequiredCallback function for search input changes
miniTablebooleanfalseWhen 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 and tbody

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

RepositoryUsage Count
frontend-app-staff-dashboard18
frontend-app-dashboard2
frontend-app-course-authoring5
frontend-app-learning2
frontend-app-profile1

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