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

@tronstride/datatable

v0.1.3

Published

Server-driven React DataTable for TronStride apps — sorting, filtering, pagination, row selection, and expandable rows.

Readme

@tronstride/datatable

Internal server-driven React DataTable component for TronStride applications.

@tronstride/datatable is a reusable React DataTable component designed for TronStride applications. It provides a consistent table experience across internal products while supporting server-side data fetching, sorting, filtering, pagination, row selection, expandable nested rows, and refresh functionality.

Internal Package: This package is intended for use within TronStride applications and is not intended for public distribution.


Features

  • Server-side pagination
  • Server-side sorting
  • Server-side filtering
  • Row selection
  • Expandable nested rows
  • Server-driven nested data
  • Refresh functionality
  • React Query integration
  • TanStack Table integration
  • Mantine UI integration
  • React Intl support
  • Reusable column configuration
  • Axios/request-client integration
  • Configurable API response mapping
  • Support for create/action controls
  • Shared component for multiple TronStride applications

Installation

Install the package using pnpm:

pnpm add @tronstride/datatable

If the package is hosted in an internal npm registry, make sure your npm configuration is authenticated with the TronStride registry before installing.


Peer Dependencies

The consuming application should have the required peer dependencies installed.

pnpm add react react-dom @mantine/core @mantine/hooks @tanstack/react-query @tanstack/react-table @tabler/icons-react react-intl

If your application already contains these dependencies, you do not need to install them again.


Recommended: bridge your HTTP client with DataTableContext

Most TronStride apps already expose an Axios (or similar) client through an app-level context (for example HTTPContext). Bridge that client once, then every screen can use your local wrapper without passing request each time:

// src/components/DataTable.jsx  (in your app)
import { useContext } from "react";
import {
  DataTable as PackageDataTable,
  DataTableContext,
} from "@tronstride/datatable";
import { HTTPContext } from "@/context/http";

export default function DataTable(props) {
  const request = useContext(HTTPContext);

  return (
    <DataTableContext.Provider value={request}>
      <PackageDataTable {...props} />
    </DataTableContext.Provider>
  );
}

Then screens import your local wrapper:

import DataTable from "@/components/DataTable";

<DataTable
  columns={columns}
  queryKey="invoices"
  queryFn={({ request, params }) =>
    request.get("/invoices", { params }).then((response) => response.data)
  }
  responseKey="items"
  create={false}
  refresh
/>

queryFn still receives { request, params }. The request value comes from DataTableContext (or from an explicit request prop, which takes priority).

You can also read the client inside custom cells/hooks with useDataTableRequest().


Basic Usage (explicit request prop)

import { DataTable } from "@tronstride/datatable";

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { MantineProvider } from "@mantine/core";
import { IntlProvider } from "react-intl";

import "@mantine/core/styles.css";

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <IntlProvider locale="en" messages={{}}>
        <MantineProvider>
          <DataTable
            columns={columns}
            queryKey="invoices"
            queryFn={({ request, params }) =>
              request
                .get("/invoices", { params })
                .then((response) => response.data)
            }
            request={apiClient}
            responseKey="items"
            create={false}
            refresh
          />
        </MantineProvider>
      </IntlProvider>
    </QueryClientProvider>
  );
}

export default App;

DataTable Configuration

The DataTable is designed around server-driven data.

A typical configuration looks like this:

<DataTable
  columns={columns}
  queryKey="invoices"
  queryFn={({ request, params }) =>
    request.get("/invoices", { params }).then((response) => response.data)
  }
  responseKey="items"
  create={false}
  refresh
/>

Pass request either via the prop or via DataTableContext.Provider.

Configuration Overview

| Property / export | Description | | ------------------- | --------------------------------------------------------------------------- | | columns | Table column configuration | | queryKey | Unique React Query key for the table | | queryFn | Function responsible for fetching server data (({ request, params }) =>) | | request | Optional HTTP client; falls back to DataTableContext | | DataTableContext | React context — provide your app HTTP client once at a wrapper boundary | | useDataTableRequest | Hook to read the context HTTP client | | responseKey | Property containing the table rows | | create | Controls create functionality | | refresh | Enables table refresh functionality | | expandable | Configuration for expandable nested rows |


Columns

Columns define how the table data is displayed.

Example:

const columns = [
  {
    accessorKey: "invoiceNumber",
    header: "Invoice Number",
  },
  {
    accessorKey: "customerName",
    header: "Customer",
  },
  {
    accessorKey: "status",
    header: "Status",
  },
  {
    accessorKey: "totalAmount",
    header: "Total Amount",
  },
];

The column configuration is based on the TanStack Table column model supported by the component.


Server-Side Data Fetching

The DataTable expects the consuming application to provide a queryFn.

Example:

queryFn={({ request, params }) =>
  request
    .get('/invoices', { params })
    .then((response) => response.data)
}

The component provides the request parameters through params.

The application is responsible for sending these parameters to the backend API.


Expected API Response

The default API response should contain the table data and pagination metadata.

Example:

{
  "items": [
    {
      "id": 1,
      "invoiceNumber": "INV-001",
      "customerName": "ABC Trading",
      "status": "PAID",
      "totalAmount": 1250
    },
    {
      "id": 2,
      "invoiceNumber": "INV-002",
      "customerName": "XYZ LLC",
      "status": "PENDING",
      "totalAmount": 2500
    }
  ],
  "meta": {
    "totalCount": 100
  }
}

responseKey

responseKey tells the DataTable which property contains the table rows.

For example:

responseKey = "items";

expects the API response to contain:

{
  "items": []
}

If the backend returns a different property:

{
  "data": []
}

configure:

responseKey = "data";

Pagination

Pagination is server-driven.

The DataTable sends the required pagination information through the params argument.

Example:

queryFn={({ request, params }) =>
  request
    .get('/invoices', {
      params,
    })
    .then((response) => response.data)
}

The backend should return the total number of available records through:

{
  "meta": {
    "totalCount": 100
  }
}

The DataTable uses totalCount to calculate the pagination state.


Sorting

Sorting is handled through the server-driven query mechanism.

When the user changes the sorting configuration, the DataTable updates the request parameters and triggers the query again.

Example:

queryFn={({ request, params }) =>
  request
    .get('/invoices', {
      params,
    })
    .then((response) => response.data)
}

The backend should read the sorting parameters and return the appropriately sorted records.


Filtering

The DataTable supports server-driven filtering.

Filter values are included in the request parameters passed to queryFn.

Example:

queryFn={({ request, params }) =>
  request
    .get('/invoices', {
      params,
    })
    .then((response) => response.data)
}

The backend should process the filter parameters and return the filtered dataset.


Refresh

Enable refresh functionality using:

refresh;

Example:

<DataTable
  columns={columns}
  queryKey="invoices"
  queryFn={queryFn}
  request={apiClient}
  responseKey="items"
  refresh
/>

This allows users to manually refresh the table data.


Row Selection

The DataTable supports row selection for use cases such as:

  • Bulk actions
  • Delete operations
  • Export
  • Status updates
  • Approval workflows
  • Batch processing

Example:

<DataTable
  columns={columns}
  queryKey="invoices"
  queryFn={queryFn}
  request={apiClient}
  responseKey="items"
/>

Selection behavior should be configured according to the supported DataTable API.


Expandable Rows

The DataTable supports expandable nested rows for displaying related server-side data.

A common example is displaying invoice lines under an invoice.

<DataTable
  columns={columns}
  queryKey="invoices"
  queryFn={({ request, params }) =>
    request.get("/invoices", { params }).then((response) => response.data)
  }
  request={apiClient}
  responseKey="items"
  expandable={{
    queryKey: "invoice-lines",
    key: "lines",
    parentParamKey: "eInvoiceEntryId",
    nestedColumns,
    queryFn: ({ request, params }) =>
      request.get("/lines", { params }).then((response) => response.data),
  }}
/>

Expandable Configuration

| Property | Description | | ---------------- | -------------------------------------------- | | queryKey | React Query key used for nested data | | key | Property/key associated with nested data | | parentParamKey | Parameter used to identify the parent record | | nestedColumns | Column configuration for nested rows | | queryFn | Function used to fetch nested records |


Example: Invoice DataTable

const invoiceColumns = [
  {
    accessorKey: "invoiceNumber",
    header: "Invoice Number",
  },
  {
    accessorKey: "customerName",
    header: "Customer",
  },
  {
    accessorKey: "status",
    header: "Status",
  },
  {
    accessorKey: "totalAmount",
    header: "Total Amount",
  },
];

const invoiceLineColumns = [
  {
    accessorKey: "itemName",
    header: "Item",
  },
  {
    accessorKey: "quantity",
    header: "Quantity",
  },
  {
    accessorKey: "unitPrice",
    header: "Unit Price",
  },
  {
    accessorKey: "amount",
    header: "Amount",
  },
];

function InvoiceTable() {
  return (
    <DataTable
      columns={invoiceColumns}
      queryKey="invoices"
      queryFn={({ request, params }) =>
        request.get("/invoices", { params }).then((response) => response.data)
      }
      request={apiClient}
      responseKey="items"
      refresh
      expandable={{
        queryKey: "invoice-lines",
        key: "lines",
        parentParamKey: "eInvoiceEntryId",
        nestedColumns: invoiceLineColumns,
        queryFn: ({ request, params }) =>
          request.get("/lines", { params }).then((response) => response.data),
      }}
    />
  );
}

React Query

The DataTable uses TanStack React Query for server-side data management.

The consuming application should provide a QueryClientProvider.

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <AppContent />
    </QueryClientProvider>
  );
}

The DataTable should be rendered inside the provider.


Mantine

The DataTable uses Mantine components and requires the Mantine styles.

import { MantineProvider } from "@mantine/core";

import "@mantine/core/styles.css";

Wrap the application with:

<MantineProvider>
  <App />
</MantineProvider>

React Intl

The DataTable uses react-intl for toolbar, pagination, and empty-state labels. Wrap the application with IntlProvider (messages can be empty — every string has a defaultMessage).

import { IntlProvider } from "react-intl";

<IntlProvider locale="en" messages={{}}>
  <App />
</IntlProvider>

For applications supporting multiple languages, provide the appropriate locale and messages.


Request Client

Provide your existing HTTP client in either of these ways:

  1. Context (recommended for apps) — wrap once with DataTableContext.Provider
  2. Prop — pass request={apiClient} on a specific table (overrides context)

For example, using Axios:

import axios from "axios";

const apiClient = axios.create({
  baseURL: "/api",
});
import { DataTable, DataTableContext } from "@tronstride/datatable";

<DataTableContext.Provider value={apiClient}>
  <DataTable
    columns={columns}
    queryKey="invoices"
    queryFn={({ request, params }) =>
      request.get("/invoices", { params }).then((response) => response.data)
    }
    responseKey="items"
  />
</DataTableContext.Provider>

This allows the application to keep its existing:

  • Authentication
  • Base URL
  • Headers
  • Interceptors
  • Error handling
  • Token refresh logic

Complete Example

import { DataTable } from "@tronstride/datatable";

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { MantineProvider } from "@mantine/core";

import "@mantine/core/styles.css";

const queryClient = new QueryClient();

const columns = [
  {
    accessorKey: "invoiceNumber",
    header: "Invoice Number",
  },
  {
    accessorKey: "customerName",
    header: "Customer",
  },
  {
    accessorKey: "status",
    header: "Status",
  },
  {
    accessorKey: "totalAmount",
    header: "Total Amount",
  },
];

const nestedColumns = [
  {
    accessorKey: "itemName",
    header: "Item",
  },
  {
    accessorKey: "quantity",
    header: "Quantity",
  },
  {
    accessorKey: "amount",
    header: "Amount",
  },
];

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <MantineProvider>
        <DataTable
          columns={columns}
          queryKey="invoices"
          queryFn={({ request, params }) =>
            request
              .get("/invoices", { params })
              .then((response) => response.data)
          }
          request={apiClient}
          responseKey="items"
          create={false}
          refresh
          expandable={{
            queryKey: "invoice-lines",
            key: "lines",
            parentParamKey: "eInvoiceEntryId",
            nestedColumns,
            queryFn: ({ request, params }) =>
              request
                .get("/lines", { params })
                .then((response) => response.data),
          }}
        />
      </MantineProvider>
    </QueryClientProvider>
  );
}

export default App;

Development

Clone the repository:

git clone <internal-repository-url>

Navigate to the project:

cd tronstride-datatable

Install dependencies:

pnpm install

Start Development Playground

Run:

pnpm dev

This starts the Vite development environment and opens the DataTable demo/playground.

The playground can be used to:

  • Test new DataTable features
  • Test API integrations
  • Test filtering
  • Test sorting
  • Test pagination
  • Test expandable rows
  • Verify UI changes
  • Validate component behavior before releasing a new version

Build

Build the package using:

pnpm build

The compiled package will be generated in:

dist/

Before creating a release, verify that the generated dist directory contains the expected package files.


Project Structure

A recommended project structure is:

tronstride-datatable/
│
├── src/
│   ├── components/
│   │   └── DataTable/
│   ├── hooks/
│   ├── utils/
│   └── index.js
│
├── demo/
│   ├── src/
│   └── index.html
│
├── dist/
│
├── package.json
├── vite.config.js
├── README.md
└── pnpm-lock.yaml

The src directory contains the reusable package code.

The demo directory contains the internal development/playground application.

The dist directory contains the production build output.


Internal Package Guidelines

This package is shared across TronStride applications.

When modifying the DataTable:

  1. Avoid application-specific logic inside the shared component.
  2. Prefer configurable props over hard-coded business rules.
  3. Maintain backward compatibility whenever possible.
  4. Do not introduce dependencies unless they are required.
  5. Reuse existing project dependencies where possible.
  6. Test pagination, filtering, sorting, selection, and expandable rows after major changes.
  7. Test the component in the demo application before creating a release.
  8. Update this README when adding or changing public component APIs.

Adding New Features

Before adding a feature, determine whether it is:

Generic functionality

If the functionality can be used by multiple TronStride applications, it is a good candidate for the shared DataTable.

Examples:

  • Column filtering
  • Sorting
  • Pagination
  • Row selection
  • Expandable rows
  • Refresh
  • Generic actions
  • Loading states
  • Empty states

Application-specific functionality

If functionality belongs to only one application or business domain, it should generally remain in the consuming application.

Examples:

  • Invoice-specific approval rules
  • Application-specific permissions
  • Company-specific business calculations
  • Domain-specific API transformations

Keep business logic outside the shared DataTable whenever possible.


Versioning

The package follows Semantic Versioning:

MAJOR.MINOR.PATCH

Example:

1.0.0
1.1.0
1.1.1

MAJOR

Breaking changes to the public API.

Example:

1.x.x → 2.x.x

MINOR

New backward-compatible functionality.

Example:

1.1.0 → 1.2.0

PATCH

Bug fixes and backward-compatible improvements.

Example:

1.1.0 → 1.1.1

Release Process

Before releasing a new version:

1. Update the version

pnpm version patch

or:

pnpm version minor

or:

pnpm version major

2. Install dependencies

pnpm install

3. Run the build

pnpm build

4. Test the demo

pnpm dev

Verify the main DataTable functionality.

5. Commit changes

git add .
git commit -m "release: update datatable"

6. Push the changes

git push

7. Publish

If the package is distributed through the company's internal npm registry:

pnpm publish

Follow the company's internal package publishing and access-control process.


Consuming the Package

After a new version is released, update the package in a TronStride application:

pnpm update @tronstride/datatable

Or install a specific version:

pnpm add @tronstride/[email protected]

Troubleshooting

Package Not Found

If pnpm cannot find the package:

ERR_PNPM_FETCH_404

verify that:

  • The package exists in the internal registry.
  • Your npm registry is configured correctly.
  • You are authenticated.
  • You have permission to access the package.

Check the configured registry:

npm config get registry

Build Issues

Run:

rm -rf node_modules
pnpm install
pnpm build

On Windows PowerShell:

Remove-Item -Recurse -Force node_modules
pnpm install
pnpm build

React Version Issues

Make sure the consuming application and DataTable package use compatible React versions.

Check:

pnpm list react react-dom

Mantine Issues

Make sure Mantine styles are imported:

import "@mantine/core/styles.css";

and that the application is wrapped with:

<MantineProvider>
  <App />
</MantineProvider>

React Query Issues

Make sure the DataTable is rendered inside:

<QueryClientProvider client={queryClient}>
  <App />
</QueryClientProvider>

Recommended Application Setup

A TronStride application using the DataTable should generally have a structure similar to:

Application
│
├── QueryClientProvider
│   │
│   ├── IntlProvider
│   │   │
│   │   └── MantineProvider
│   │       │
│   │       └── DataTable
│   │
│   └── Other Application Components
│
└── API / Request Client

The DataTable should use the application's existing API client instead of creating a separate HTTP client.


Design Principles

@tronstride/datatable follows these principles:

Reusable

The component should work across different TronStride applications and business domains.

Server-Driven

Large datasets should be handled by the backend rather than loading the complete dataset into the browser.

Configurable

Application-specific behavior should be controlled through props and configuration.

Consistent

Common table functionality should behave consistently across TronStride applications.

Lightweight

Avoid unnecessary dependencies and application-specific logic inside the shared package.

Backward Compatible

Changes to the shared component should avoid breaking existing applications whenever possible.


Support

For issues, feature requests, or changes to the shared DataTable:

  1. Check the existing implementation and README.
  2. Reproduce the issue in the demo playground.
  3. Verify whether the issue is package-specific or application-specific.
  4. Create an issue or communicate with the TronStride frontend team.
  5. Include the package version and reproduction steps.

Internal Use Notice

@tronstride/datatable is an internal TronStride frontend component.

The package is intended to be consumed by authorized TronStride applications and team members.

Do not distribute the package outside the company's approved repositories, registries, or development environments without authorization.


License

Internal Use Only — TronStride

Copyright © TronStride.

This package is proprietary/internal software and is intended solely for authorized TronStride use.