npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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/table

Requires 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 displays true as "Yes" and false as "No".
  • date: dateFormat displays a Date as DD/MM/YYYY HH:mm:ss, using local date and time. The cells use background #e7e7e7 and 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: moneyFormat adds $ and groups characters in threes with periods: 5264000 becomes $ 5.264.000, 954000 becomes $ 954.000, and 36255002 becomes $ 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 ... 100

With 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";