A customizable, responsive data table component for React with sorting, filtering, and pagination.
Prop | Type | Description |
---|---|---|
columns | ColumnDef<any, any>[] |
An array of column definitions. Each column must have a header (column title) and accessorKey (key to access the column data). |
data | Record<string, any>[] |
An array of data objects to be displayed in the table. |
onRowSelect | (selectedIndices: string[] | number[]) => void |
Callback function to handle row selection. |
filterOptions | any[] |
List of filter options available for use in the table filtering. |
clearFilters | () => void |
Function to clear all filters applied to the table. |
onClickNext | () => void |
Callback function to handle 'Next' button click in pagination. |
onClickPrevious | () => void |
Callback function to handle 'Previous' button click in pagination. |
totalCount | number |
Total number of items in the table. |
pageSize | number |
Number of items per page for pagination. |
page | number |
Current page number for pagination. |
tabs | ITabs |
List of tabs to display for segmenting the data (e.g., for filtering or categorizing). |
onTabChange | (index: number, tab: any) => void |
Callback when a tab is selected. Receives the index of the tab and the tab object. |
onDownload | (event: any) => void |
Callback for downloading the data in the table. |
headerConfig | HeaderConfig |
Configuration for the table header, which includes heading, description, and label. |
classNames | IClassName |
Custom class names for styling different parts of the table, header, filter, etc. |
disablePagination (New ✨) | boolean |
Determines whether pagination is disabled for the table. |
disableDownload (New ✨) | boolean |
Controls whether the "Download" button should be displayed. |
filterContent | ReactNode |
Optional content that can be added to the filter toolbar (e.g., a button). |
errorMessage (New ✨) | string |
An optional error message to display when there's no data. |
showClearFiltersButton (New ✨) | boolean |
Controls whether the "Clear Filters" button should be displayed. |
showSearchInput (New ✨) | boolean |
Controls whether the search input box should be displayed in the toolbar. |
Section | Customization (className) | Description |
---|---|---|
Filter Chip | filterChip |
Class for customizing the appearance of the filter chips. |
Filter Chip Icon | filterChipIcon |
Class for customizing the icon inside the filter chip. |
Filter Chip Label | filterChipLabel |
Class for customizing the label inside the filter chip. |
Filter Chip Dropdown (New ✨) | filterChipDropdown |
Class for customizing the dropdown of the filter chip. |
Table Wrapper | tableWrapper |
Class for customizing the wrapper around the table. |
DataTable | dataTable |
Class for customizing the main data table container. |
Table Header Cell | tableHeaderCell |
Class for customizing the header cells. |
Table Row Cell | tableRowCell |
Class for customizing the individual row cells. |
Sorting Arrow Icon | sortingArrowIcon |
Class for customizing the sorting arrow icon in the header cells. |
Header Wrapper | headerWrapper |
Class for customizing the wrapper around the table header. |
Heading | heading |
Class for customizing the main heading (title). |
Subheading | subHeading |
Class for customizing the subheading under the title. |
Badge | badge |
Class for customizing the badges, if used. |
Download Button | downloadButton |
Class for customizing the download button. |
Download Button Icon | downloadButtonIcon |
Class for customizing the icon inside the download button. |
Tabs Panel | tabsPanel |
Class for customizing the panel of tabs. |
Tab Item | tabItem |
Class for customizing the individual tab items. |
Selected Tab | selectedTab |
Class for customizing the selected tab. |
Pagination Wrapper | paginationWrapper |
Class for customizing the pagination wrapper. |
Pagination Info | paginationInfo |
Class for customizing the pagination information display. (1-10 of 100 items) |
Pagination Button Wrapper | paginationButtonWrapper |
Class for customizing the pagination button container. |
Pagination Button Previous | paginationButtonPrevious |
Class for customizing the "Previous" button in pagination. |
Pagination Button Next | paginationButtonNext |
Class for customizing the "Next" button in pagination. |
Pagination Button Previous | paginationButtonPrevious |
Class for customizing the "Previous" button in pagination. |
Spinner (New ✨) | spinner |
Class for customizing the loading spinner. |
import React, { useState, useEffect, useCallback } from "react";
import { DataTable, DataTableColumn, ITabs } from "@earnest-data/earnest-table";
import styles from "./index.module.scss";
const pageSize = 10;
export interface OrderRecord {
id: string;
orderAmount: number;
orderStatus: string;
city: string;
state: string;
processed: boolean;
}
export default function Home() {
const [data, setData] = useState<OrderRecord[]>([]);
const [loading, setLoading] = useState(true);
const [count, setCount] = useState(0);
const [page, setPage] = useState(1);
const [count, setCount] = useState(0);
const [page, setPage] = useState(1);
const [filters, setFilters] = useState<any>({});
const [selectedRows, setSelectedRows] = useState<number[]>([]);
const fetchData = useCallback(async () => {
// API call to fetch data here
}, []);
useEffect(() => {
fetchData();
}, [fetchData]);
const columns: DataTableColumn[] = [
{ header: "ID", accessorKey: "id" },
{ header: "Order Status", accessorKey: "orderStatus" },
{ header: "City", accessorKey: "city", size: 20 },
{ header: "Processed", accessorFn: (row) => (row.processed ? "Yes" : "No") },
];
const orderData = useMemo(() => data, [data]);
const handleApiDownload = async () => {
// Make API call for downloading or use default download functionality
};
const filterOptions = useMemo(() => [
{
label: "Order Status",
options: ["success", "inprogress", "pending", "failed", "paid"],
id: "orderStatus",
value: filters.orderStatus,
onOptionChange: (value: any) =>
setFilters((prev: any) => ({ ...prev, orderStatus: value })),,
},
{
label: "Processed",
id: "processed",
options: ["true", "false"],
value: filters.processed,
onOptionChange: (value: any) =>
setFilters((prev: any) => ({ ...prev, processed: value === "true" })),
},
{
label: "City",
id: "city",
options: ["Delhi", "BOM", "Patna"],
value: filters.city,
onOptionChange: (value) =>
setFilters((prev: any) => ({ ...prev, city: value })),
},
], [filters]);
const tabs: ITabs = [
{ label: "All", value: undefined },
{ label: "Processed", value: "true" },
{ label: "Not Processed", value: "false" },
];
const onTabChange = (index: number, tab: any) => {
setFilters((p: any) => ({ ...p, processed: tab.value }));
};
const handleRowSelect = (selectedIndices: any) => {
setSelectedRows(selectedIndices);
};
const handleNext = () => {
setPage((p) => p + 1);
};
const handlePrevious = () => {
setPage((p) => Math.max(p - 1, 1));
};
const clearFilters = () => setFilters({});
const handleDelete = () => {
console.log("Deleting selected rows:", selectedRows);
};
const headerConfig: HeaderConfig = {
headline: "My Data Table",
label: "Company Orders",
description: "Default description text comes here.",
};
return (
<div>
<DataTable
columns={columns}
data={orderData}
onRowSelect={handleRowSelect}
filterOptions={filterOptions}
tabs={tabs}
onDownload={handleApiDownload}
clearFilters={clearFilters}
onTabChange={onTabChange}
onClickNext={handleNext}
onClickPrevious={handlePrevious}
page={page}
totalCount={count}
pageSize={pageSize}
headerConfig={headerConfig}
classNames={{
filterChip: styles.filterChip,
filterChipIcon: styles.filterChipIcon,
filterChipLabel: styles.filterChipLabel,
tableWrapper: styles.tableWrapper,
dataTable: styles.dataTable,
tableHeaderCell: styles.tableHeaderCell,
tableRowCell: styles.tableRowCell,
headerWrapper: styles.headerWrapper,
heading: styles.heading,
subHeading: styles.subHeading,
badge: styles.badge,
downloadButton: styles.downloadButton,
downloadButtonIcon: styles.downloadButtonIcon,
tabsPanel: styles.tabsPanel,
tabItem: styles.tabItem,
selectedTab: styles.selectedTab,
paginationWrapper: styles.paginationWrapper,
paginationInfo: styles.paginationInfo,
paginationButtonWrapper: styles.pagintaionButtonWrapper,
paginationButtonPrevious: styles.paginationButtonPrevious,
paginationButtonNext: styles.paginationButtonNext,
filterChipDropdown: styles.filterChipDropdown,
spinner: styles.spinner
}}
filterContent={
selectedRows.length > 0 && (
<button onClick={handleDelete} style={{ marginLeft: "auto" }}>
Delete Selected
</button>
)
}
disablePagination={false}
disableDownload={true}
errorMessage="No data to display"
showClearFiltersButton={false}
showSearchInput={true}
/>
</div>
);
}