@tevui/table
v1.0.1
Published
A React table component with configurable columns, cell formatting, row actions, an empty-state message, and link-based pagination.
Readme
Table
A React table component with configurable columns, cell formatting, row actions, an empty-state message, and link-based pagination.
Installation
npm install @tevui/tableRequires React and React DOM 18 or 19.
Using the component in this repository
The package imports shown below assume @tevui/table is installed in the consuming application. When using the source directly in this repository, use its local entry point instead:
import { Table } from "@/tevui/Table/src";
import type { TableProps } from "@/tevui/Table/src";The @/ alias maps to this repository's src directory. TableProps is a TypeScript type; use import type when importing it separately, or import { Table, type TableProps } for a combined import.
If a consuming application reports Module not found: Can't resolve '@tevui/table', check that the package is installed in that application and that its installed files include the dist entry points. For package usage, import the component and type as follows:
import { Table } from "@tevui/table";
import type { TableProps } from "@tevui/table";Usage
Testing a copied build in another project
Run npm run build from this component's directory and copy the complete generated dist folder into the consuming project. The build generates index.js, index.umd.js, index.d.ts, and the lib declaration files, so the folder can be imported directly without creating an entry file manually.
For a copy located at app/components/dist, with @/ mapped to the consuming project's root, use:
import { Table, type TableProps } from "@/app/components/dist";Adjust the path to match the copied folder and the consuming project's alias configuration. If replacing an older build, copy the new complete dist folder, including index.js and the declaration files.
TableBase example
This example uses the configuration from the TableBase story, available in Storybook under Example/Structure/Table.
"use client";
import { Table } from "@tevui/table";
import type { TableProps } from "@tevui/table";
const tableProps = {
title: "Table Tile",
headers: [
{ id: "name", title: "Name" },
{ id: "surname", title: "surname" },
{ id: "active", title: "Active" },
{ id: "date", title: "Date" },
{ id: "age", title: "Age" },
{ id: "amount", title: "Amount" },
],
data: [
{
name: "Lara",
surname: "Croft",
active: true,
date: new Date("2001-07-01"),
age: 25,
amount: 5264000,
},
{
name: "Jill",
surname: "Valentine",
active: true,
date: new Date("2000-01-10"),
age: 26,
amount: 954000,
},
{
name: "Leon",
surname: "Kennedy",
active: false,
date: new Date("1993-12-15"),
age: 32,
amount: 36255002,
},
],
actions: [
{
id: "action_1",
label: "Action",
onClick: (data: string) => console.log(data),
},
{
id: "action_2",
label: "AAAA",
onClick: (data: string) => console.log(data),
},
],
showPagination: true,
paginationProps: {
maxShowNumbers: 10,
urlBase: "?page=###",
currentPage: 57,
lastPage: 100,
},
textNoContent: "No content",
dataprops: [
{
ids: [`active`],
props: {
converter: (field) => {
return field ? "Yes" : "No";
},
},
},
{
ids: [`date`],
props: {
defaultFunction: "dateFormat",
backgroundColor: "#e7e7e7",
color: "#01810c",
},
},
{
ids: [`amount`],
props: {
defaultFunction: "moneyFormat",
},
},
],
} satisfies TableProps;
export default function Example() {
return <Table {...tableProps} />;
}The example displays Lara Croft, Jill Valentine, and Leon Kennedy across six data columns, followed by two action columns. Column order follows headers, and each header's id selects the matching field from each data record. Action columns follow the order of actions.
Props
| Prop | Type | Runtime default | Description |
| --- | --- | --- | --- |
| title | string | undefined | Optional heading displayed above the table. |
| id | string | "tevui-table-id" | HTML identifier for the table. |
| dataTestId | string | "tevui-table-datatestid" | Value of the table's data-testid attribute. |
| headers | TableHeaderProps[] | [] | Required by the type. Defines column labels, field keys, and order. |
| data | Record<string, string \| number \| Date \| boolean>[] | [] | Required by the type. Each object represents one row. |
| dataprops | TableDataProps[] | undefined | Optional formatting and styles for selected columns. |
| showPagination | boolean | undefined | Shows pagination when true, paginationProps is provided, and data is not empty. |
| paginationProps | TablePaginationProps | undefined | Optional pagination configuration. |
| actions | TableActionProps[] | [] | Required by the type. Adds an action column for each entry, with buttons or empty placeholders depending on disabled. |
| textNoContent | string | "No content" | Required by the type. Message displayed below the table when data is empty. |
TableHeaderProps
| Property | Type | Description |
| --- | --- | --- |
| id | string | Required. Field key in each data record; also used as the header's HTML identifier. |
| title | string | Required. Column heading. |
Cell formatting
Each dataprops entry applies to the columns listed in ids.
TableDataProps
| Property | Type | Description |
| --- | --- | --- |
| ids | string[] | Required. Field keys to format. |
| props | object | Optional formatting and style settings. |
| props.converter | (field: string \| number \| boolean \| Date) => string | Converts the original cell value into display text. |
| props.defaultFunction | "dateFormat" \| "moneyFormat" | Selects a built-in formatter. |
| props.color | string | Text color, applied alongside a converter or built-in formatter. |
| props.backgroundColor | string | Background color, applied alongside a converter or built-in formatter. |
The TableBase story demonstrates three configurations:
active: a custom converter displaystrueas"Yes"andfalseas"No".date:dateFormatdisplays aDateasDD/MM/YYYY HH:mm:ss, using local date and time. The cells use background#e7e7e7and text color#01810c. The story's ISO date strings are parsed as UTC dates, so their displayed date and time depend on the user's timezone.amount:moneyFormatadds$and groups characters in threes with periods:5264000becomes$ 5.264.000,954000becomes$ 954.000, and36255002becomes$ 36.255.002.
Unformatted values are displayed using String(value). The money formatter does not handle decimals or locale-specific currency rules. If both converter and defaultFunction are provided, the built-in formatter overwrites the custom converter's result. If multiple entries format the same column, the last conversion determines its value and styles.
Pagination
TablePaginationProps
All four properties are required when providing paginationProps.
| Property | Type | Description |
| --- | --- | --- |
| currentPage | number | Current page, starting at 1. |
| lastPage | number | Total number of pages. |
| maxShowNumbers | number | Maximum number of displayed items, including each ellipsis. |
| urlBase | string | URL template. Each ### is replaced with the page number without leading zeros. |
The story uses page 57, 100 total pages, and a limit of 10 items:
01 ... 55 56 57 58 59 60 ... 100With urlBase: "?page=###", page 57 links to ?page=57. Page labels below 10 receive a leading zero. Ellipses are non-clickable spans with no URL.
Additional examples with maxShowNumbers: 10:
| Current page | Total pages | Display |
| --- | --- | --- |
| 6 | 20 | 01 ... 04 05 06 07 08 09 ... 20 |
| 6 | 10 | 01 02 03 04 05 06 07 08 09 10 |
| 18 | 20 | 01 ... 13 14 15 16 17 18 19 20 |
| 1 | 20 | 01 02 03 04 05 06 07 08 ... 20 |
When all pages fit, every page is shown. For limits of at least 5, larger page sets preserve the first and last pages and use ellipses for omitted ranges. Smaller limits display a consecutive range containing the current page without ellipses.
Pagination generates navigation links. The component displays all records passed in data; the application must load the requested page and update data and currentPage.
Actions and empty state
The TableBase story supplies two actions, labeled "Action" and "AAAA". Each action adds a header with its label and, when enabled, a button in every data row. Clicking a button calls onClick with the complete original row object, including its unformatted values. Both actions in the story are enabled because disabled is omitted.
Although the story annotates the callback argument as string, the component passes a row object. In application code, use the row's object type when annotating this argument.
TableActionProps
| Property | Type | Description |
| --- | --- | --- |
| id | string | Required. Action identifier. |
| label | string | Required. Action label. |
| onClick | (data: any) => void | Required. Called with the complete original row object when its button is clicked. |
| disabled | boolean | Optional. Defaults to enabled when omitted. When true, replaces the action's buttons with empty spans in every row. |
Disabled actions
Set disabled: true to hide an action's buttons while preserving its column header and cells. Each cell contains an empty <span> with the tevui-table-action-button class, so no label or clickable control is displayed in that cell and onClick cannot be triggered there. The setting applies to every row for that action.
The following configuration adapts the actions from TableBase, disabling the second action:
import type { TableActionProps, TableProps } from "@tevui/table";
const actions: TableActionProps[] = [
{
id: "action_1",
label: "Action",
onClick: (row: TableProps["data"][number]) => console.log(row),
},
{
id: "action_2",
label: "AAAA",
disabled: true,
onClick: (row: TableProps["data"][number]) => console.log(row),
},
];Pass this array as the table's actions prop. Set disabled to false or omit it to display the buttons again. id, label, and onClick remain required for disabled actions.
Empty state
The TableNoContent story uses an empty data array and no actions. The table headers remain visible, and textNoContent is rendered below the table in an <h5> element. Pagination is hidden whenever data is empty, even if pagination props are provided.
"use client";
import { Table } from "@tevui/table";
export default function EmptyTableExample() {
return (
<Table
title="Table Tile"
headers={[
{ id: "name", title: "Name" },
{ id: "surname", title: "surname" },
{ id: "active", title: "Active" },
{ id: "date", title: "Date" },
{ id: "age", title: "Age" },
{ id: "amount", title: "Amount" },
]}
data={[]}
actions={[]}
textNoContent="No content"
/>
);
}Styles
The package includes CSS in its JavaScript bundle and injects it in the browser. No separate CSS import is needed. With SSR, styles are added when JavaScript runs in the browser rather than included automatically in server-generated HTML.
Use .tevui-table, .tevui-table-pagination, .tevui-table-action-button, and .tevui-table-no-content to customize the table, pagination, action buttons, and empty-state message.
Exported types
import type {
TableProps,
TableHeaderProps,
TableDataProps,
TableActionProps,
TablePaginationProps,
} from "@tevui/table";