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

table-for-react

v1.0.1

Published

Framework-flexible React data table — optional Tailwind presets, semantic CSS hooks, and swappable primitives (Ant Design-friendly).

Readme

table-for-react

A React table/card component that stays easy to pair with Tailwind, Ant Design, your own CSS, or plain variables — without locking you into one styling system.

Do give me a star on github : Table for React

Demo you can try on local: Demo

Examples: Here

Install

npm install table-for-react react react-dom

Overall tabvle view

Primary Demo

Card view with Grid layout

Card view with Grid layout

Card view with list layout

Card view with Grid layout

Column filter option using contains

column filter option

column filter option using select

column filter option

Select columns on runtime.

select columns on runtime

export specific columns as CSV

export selected

Render additional actions buttons

render action buttons

Quick patterns

1. Semantic CSS (works with vanilla CSS / any preprocessor)

Uses BEM-ish class names (smart-table, smart-table__th, …). Import the minimal layout stylesheet and override with --smart-table-* variables or plain CSS selectors.

import { SmartTable } from "table-for-react";
import "table-for-react/base.css";

<SmartTable appearance="minimal" columns={columns} data={rows} />;

Tune colors / borders globally:

:root .smart-table {
  --smart-table-border: var(--antd-color-border-secondary, #eee);
}

2. Tailwind utility preset

Uses the bundled slot map tailwindClassNames (utilities as strings).

import { SmartTable } from "table-for-react";

<SmartTable appearance="tailwind" columns={columns} />;

Ensure your Tailwind scanner sees the utilities (often already does if you @source package sources or reuse the preset in your outer app). Prefer adding the package folder to @source in Tailwind v4 if classes are purged unexpectedly — e.g. in your global CSS alongside @import "tailwindcss":

@import "tailwindcss";
@source "../../node_modules/table-for-react/src/**/*.{js,jsx}";

Important for card view: with appearance="tailwind", also import table-for-react/base.css. Responsive grid/list layout for cards uses semantic classes (smart-table__card-grid, …); that keeps cards working even when Tailwind does not scan the library.

Per-slot replace (classNames):

<SmartTable
  appearance="tailwind"
  classNames={{
    root: "w-full max-w-screen-lg rounded-xl border mx-auto shadow-sm",
    searchInput: "rounded-md border-orange-400",
  }}
/>

Append more utilities everywhere without copying the full preset:

<SmartTable
  appearance="tailwind"
  appendClassNames={{
    root: "backdrop-blur-sm",
    pagination: "sticky bottom-0 bg-white pt-4",
  }}
/>

Build a reusable map with composeClassNames (chains cx() per slot; often used with appearance="minimal" and your Tailwind snippets):

import {
  composeClassNames,
  defaultClassNames,
} from "table-for-react";

const mySlots = composeClassNames(defaultClassNames, {
  root: "rounded-2xl border-dashed shadow-none",
});

<SmartTable appearance="minimal" classNames={mySlots} />;

3. Ant Design (component swap)

Plug in primitives so buttons/inputs/checkboxes render as Antd components:

import { Button, Checkbox, Input } from "antd";
import { SmartTable } from "table-for-react";
import "table-for-react/base.css";

<SmartTable
  appearance="minimal"
  components={{
    Button: (p) => <Button {...p} size="middle" type="primary" />,
    Input: (p) => <Input {...p} allowClear />,
    Checkbox: ({ className, ...p }) => (
      <Checkbox {...p} className={className} />
    ),
  }}
/>

If Ant Design and the preset both style buttons, replace those slots—for example classNames={{ exportPrimaryButton: "!min-h-0 rounded-md" }}—or appendClassNames to layer utilities.

Map Antd Typography/Table-level styling separately if you mirror their typography around the widget.

Slots API

Exported helpers:

| Export | Purpose | |--------|---------| | defaultClassNames | appearance="minimal" slot map | | tailwindClassNames | Tailwind utility slot map | | composeClassNames() | Concatenate partial slot overrides | | mergeSlots(), appendSlots(), cx | Merge / concatenate class lists |

Inspect src/defaultClassNames.js / tailwindClassNames.js for slot keys (toolbar, th, pageButton, …).

Props (styling subset)

| Prop | Purpose | |------|---------| | appearance | "minimal" (default) semantic classes · "tailwind" preset | | classNames | Partial slot overrides (replace preset per key) | | appendClassNames | Concatenate utilities after classNames | | components | { Button, Input, Checkbox } custom elements |

Sorting

  • Column def: { key, label, sort: true } enables sorting for that column.
  • sortAll: when true, every column is sortable; when false, none. Ignores sort on columns when this is a boolean.
  • If sortAll is omitted: use legacy sortColumns={['key']} if non-empty, otherwise use each column’s sort.
  • Headers show and ; the active direction is emphasized. Rows are sorted client-side (including the current page when using server pagination).

Column value formats (format)

When a column has no render, format controls how row[column.key] is shown (table cells and the default card view). Sorting still uses the raw row[key] value.

  • { type: "number", locale?, …Intl.NumberFormatOptions } — decimals, grouping, notation, etc.
  • { type: "currency", currency: "USD", locale?, currencyDisplay?, customSymbol?, minimumFractionDigits?, maximumFractionDigits? }currencyDisplay is passed to Intl (symbol, narrowSymbol, code, name). customSymbol overrides the Intl currency prefix/suffix with a literal string plus formatted digits.
  • { type: "percentage", valueScale?: "ratio" | "percent", locale?, decimals? | minimumFractionDigits? / maximumFractionDigits? }valueScale: "ratio" (default): store 0–1 (e.g. 0.4242%). valueScale: "percent": store whole percents (0–100, e.g. 12.512.5%).

Optional nullDisplay replaces empty / null / undefined.

You can import { formatDisplayValue } from "table-for-react" for previews or tooling.

Synthetic / action columns (not in API)

Use a key that your rows do not have (e.g. __actions) and render: (row) => … for buttons or links — the cell ignores row[key] when render is set.

  • Do not set sort: true on pure UI columns unless you also store a comparable value under key.
  • exportable: false omits that column from CSV export (otherwise the file would export an empty cells column).

Card view (viewMode="card")

  • cardLayout"grid" (default): responsive CSS grid of cards (repeat(auto-fill, minmax(...)) in base.css). "list": flex column of full‑width stacked cards.
  • Slot styling — override classNames.cardGrid, cardGrid_list, cardItem, cardFields, card, etc., or use appendClassNames to layer utilities (e.g. your own Tailwind grid).
  • Whole cardcardRenderer={(row, isSelected, toggleSelect) => …} replaces the built-in card body (you control layout and content).
  • Outer / per-item shell — keep the built-in card body but change how cards are arranged:
    • renderCardGrid={({ children, className, layout }) => …} — replace the outer wrapper that holds all cards. You usually spread className onto your root (or drop it and use your own). layout is "grid" or "list" (same as cardLayout).
    • renderCardItem={({ row, index, rowKey, className, children }) => …} — replace each card’s outer wrapper (default: div + cardItem). Use with renderCardGrid for a semantic list, e.g. ul / li.
<SmartTable
  viewMode="card"
  renderCardGrid={({ children, className }) => (
    <ul className={className} role="list">
      {children}
    </ul>
  )}
  renderCardItem={({ className, children }) => (
    <li className={className}>{children}</li>
  )}
  /* … */
/>

Column filters (table view only, enableColumnFilters)

Per-column filtering is driven by column.filter ("select" or "text") or the legacy filterColumns prop (those keys behave like select). enableColumnFilters must be true.

  • Predicate + UI apply only when viewMode !== "card". In card view active filters stay in state but are not applied to rows; the header filter panel is hidden. Closing the panel when switching modes is handled internally (openFilter reset).
  • "select" — distinct primitive values from the current dataset (after search / show-selected narrowing, before column filters); multi-select equality on row[key].
  • "text" — substring match, case-insensitive, on String(row[key] ?? '').
  • Always client-side: filters are applied only to orderedData—whatever is currently in memory. With enableServerData, that is typically one server page, so select options and matching rows reflect that slice only (search can still hit the server via serverConfig.searchParam if configured).

Helpers (optional tooling or custom export pipelines):

  • import { serializeColumnFiltersPayload, applyColumnFiltersToRows } from "table-for-react".

Pagination (enablePagination, pageSize)

Set pageSize from your own state and pass pageSizeOptions (number[]) plus onPageSizeChange={(n) => …} to show a Rows per page <select> beside Prev / Next. Slots: paginationPageSizeWrap, paginationPageSizeLabel, pageSizeSelect, paginationNav.

Search (enableSearch)

  • Local rows (enableServerData off): searches the dataset in-memory.
  • Server mode: set serverConfig.searchParam (e.g. "q") so the trimmed query is sent on each fetch. Omit searchParam to keep search client-side only over the loaded page.
  • Backend should read that param (e.g. ?q=...) filter the full list, then paginate and return total for that filtered list.

Other table props (columns, data, enableServerData, serverConfig, …) work as before.

License

MIT