@earnest-data/earnest-table
v0.2.6
Published
A customizable, responsive data table component for React with sorting, filtering, and pagination.
Readme
earnest-table
A customizable, responsive data table component for React with sorting, filtering, and pagination.
Table of Contents
Prop Definitions
| 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. |
| onRowClick | (rowData: Record<string, any>, event: MouseEvent<HTMLTableRowElement>) => void | Callback function triggered when a row is clicked, receiving the row's data and the click event. |
| 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. |
| headerActions (New ✨) | ReactNode | Optional content that can be added to the header wrapper (e.g., a button). |
| classNames | IClassName | Custom class names for styling different parts of the table, header, filter, etc. |
| disablePagination | boolean | Determines whether pagination is disabled for the table.|
| disableDownload | 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 | string | An optional error message to display when there's no data.|
| showClearFiltersButton | boolean | Controls whether the "Clear Filters" button should be displayed.|
| showSearchInput | boolean | Controls whether the search input box should be displayed in the toolbar.|
| enableCheckboxSelection | boolean | Controls whether the checkbox column should be displayed.|
Customization (classNames)
| 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 | tableRow | Class for customizing the individual table rows. |
| 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. |
| Header Actions Wrapper (New ✨) | headerActionsWrapper | Class for customizing the container that holds additional actions in 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. |
| Toolbar | toolbar | Class for customizing the toolbar under the header wrapper. |
| Tabs Wrapper | tabsWrapper | Class for customizing the wrapper around the tabs. |
| 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 | spinner | Class for customizing the loading spinner. |
Example Usage
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}
onRowClick={(rowData, event) => {
console.log("Row clicked:", rowData);
}}
clearFilters={clearFilters}
onTabChange={onTabChange}
onClickNext={handleNext}
onClickPrevious={handlePrevious}
page={page}
totalCount={count}
pageSize={pageSize}
headerConfig={headerConfig}
headerActions={<button>Add New</button>}
classNames={{
filterChip: styles.filterChip,
filterChipIcon: styles.filterChipIcon,
filterChipLabel: styles.filterChipLabel,
tableWrapper: styles.tableWrapper,
dataTable: styles.dataTable,
tableHeaderCell: styles.tableHeaderCell,
tableRow: styles.tableRow,
tableRowCell: styles.tableRowCell,
headerWrapper: styles.headerWrapper,
headerActionsWrapper: styles.headerActionsWrapper,
heading: styles.heading,
subHeading: styles.subHeading,
badge: styles.badge,
downloadButton: styles.downloadButton,
downloadButtonIcon: styles.downloadButtonIcon,
toolbar: styles.toolbar,
tabsWrapper: styles.tabsWrapper,
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}
enableCheckboxSelection={true}
/>
</div>
);
}