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

chs-real-data-grid

v0.0.7

Published

A lightweight, customizable React data grid with MUI integration, fast virtualization, sorting, filtering, pagination, selection, and XLSX/PDF export.

Readme

chs-real-data-grid

A customizable React Data Grid built with Material UI. Designed for real-world apps with controlled state, async workflows, and TypeScript. Supports sorting, filtering, pagination, row selection, column search, and export helpers (XLSX/PDF).


Features

  • Sorting: global and per-column sorting.
  • Filtering: column and global filtering with enum and range filters.
  • Pagination: client-side and server-side support.
  • Row Selection: select/deselect rows and bulk delete.
  • Column Search: per-column search toggles.
  • Export Helpers: Excel (XLSX) and PDF export helpers.
  • Material UI theming and responsive layout using Box, Typography.
  • TypeScript types for data and grid configuration.
  • Server-side pagination and actions supported.

Installation

Install peer dependencies and the grid package. Material UI packages are peer dependencies — ensure compatible versions are installed.

npm install chs-real-data-grid

Minimal usage

import DataTable from "chs-real-data-grid";

<DataTable data={myRows} gridMaster={myGridMaster} />
  • data: array of rows (objects).
  • gridMaster: configuration object (GridMaster) with columns, flags, and callBacks (handlers).
  • Optional: children can be used as a fallback for gridMaster.
  • Optional: onStatusMessageChange — callback to receive status messages.

Quick Start

  1. Define your data types (e.g. Customer).
  2. Create a GridMaster configuration (columns, paging, flags, callbacks). You can reuse the provided customerGrid default object.
  3. Render DataTable inside a Material UI container and pass data + gridMaster props.

Usage example

import React, { useEffect, useState } from "react";
import { Box } from "@mui/material";
import DataTable from "chs-real-data-grid";
import { Customer } from "./models/customer";
import { GridMaster } from "./models/gridMaster";
import { dumpData, validateInput } from "./data/validateInput";
import { customerGrid as customerGridDefault } from "./screens/data/data";

const Customers: React.FC = () => {
  const [customData, setCustomData] = useState<Customer[]>(dumpData);

  const [customerGrid, setCustomerGrid] = useState<GridMaster>({
    ...validateInput,
    ...customerGridDefault,
    callBacks: {
      onSelect: (row) => console.log("Selected:", row),
      onDelete: (row) => console.log("Deleted:", row),
      onRowView: (row) => console.log("View:", row),
      onRowEdit: (row) => console.log("Edit:", row),
      onRowDelete: (row) => console.log("Delete Cell:", row),
      onSearch: (query) => console.log("Search:", query),
      onSort: (sort) => console.log("Sort:", sort),
      onColumnSearch: (col) => console.log("Column Search:", col),
      onFilter: (filter) => console.log("Filter:", filter),
      onClearSort: () => console.log("Clear Sort"),
      onClearFilter: () => console.log("Clear Filter"),
      onClearAll: () => console.log("Clear All"),
      onColumnSort: (col) => console.log("Column Sort:", col),
      onDownload: (format) => console.log("Download:", format),
      onPagination: (page) => console.log("Pagination:", page),
    },
  });

  useEffect(() => {
    // fetch initial data if needed
    setCustomData(dumpData);
  }, []);

  return (
    <Box sx={{ width: "100%", p: 2 }}>
      <DataTable data={customData} gridMaster={customerGrid} />
    </Box>
  );
};

export default Customers;

Default customerGrid (example)

import { DataType } from "../models/dataType";
import { GridMaster } from "../models/gridMaster";
import { PageState } from "../models/pageState";

export const customerGrid: GridMaster = {
  id: 1,
  targetObject: "customer",
  title: "Customer List",
  filterReqd: true,
  searchReqd: true,
  sortReqd: true,
  paginationReqd: true,
  primaryColour: "#1E90FF",
  secondaryColour: "#F0F8FF",
  actionReqd: true,
  actionCheckboxReqd: true,
  actionEditReqd: true,
  actionViewReqd: true,
  actionDeleteReqd: true,
  actionAddReqd: true,
  indexReqd: true,
  dynamicLoad: true,
  recordsPerPage: 10,
  actionKey: "firstName",
  sortActionKey: "code",
  gridPagination: {
    reqd: true,
    pageCount: 10,
    recordPerPage: [5, 10, 25, 50],
    dynamicLoad: true,
  },
  gridColumns: [
    { id: 2, code: "firstName", title: "First Name", sortable: true, searchReqd: true, filterable: true, displayable: true, formElementType: "text", type: DataType.STRING },
    { id: 3, code: "middleName", title: "Middle Name", sortable: false, searchReqd: false, filterable: false, displayable: true, formElementType: "image", type: DataType.STRING },
    { id: 4, code: "lastName", title: "Last Name", sortable: true, searchReqd: true, filterable: false, displayable: true, formElementType: "text", type: DataType.STRING },
    { id: 5, code: "username", title: "Username", sortable: true, searchReqd: true, filterable: false, displayable: true, formElementType: "text", type: DataType.STRING },
    { id: 6, code: "gender", title: "Gender", sortable: false, searchReqd: false, filterable: true, displayable: true, enumValues: ["MALE", "FEMALE"], formElementType: "radio", type: DataType.STRING },
    { id: 7, code: "dob", title: "Date of Birth", sortable: false, searchReqd: false, filterable: false, displayable: true, formElementType: "range", type: DataType.INTEGER },
    { id: 8, code: "anniversary", title: "Anniversary", sortable: false, searchReqd: false, filterable: false, displayable: false, formElementType: "text", type: DataType.INTEGER },
    { id: 9, code: "mobileNumber", title: "Mobile Number", sortable: false, searchReqd: true, filterable: false, displayable: true, formElementType: "phone", type: DataType.STRING },
    { id: 10, code: "emailId", title: "Email ID", sortable: false, searchReqd: true, filterable: false, displayable: true, formElementType: "email", type: DataType.STRING },
    { id: 11, code: "referredBy", title: "Referred By", sortable: true, searchReqd: false, filterable: false, displayable: false, formElementType: "text", type: DataType.LONG },
    { id: 12, code: "prefLang", title: "Preferred Lang.", sortable: false, searchReqd: true, filterable: true, displayable: true, enumValues: ["Telugu", "English"], formElementType: "checkbox", type: DataType.STRING },
    { id: 13, code: "registeredOn", title: "Registered On", sortable: true, searchReqd: false, filterable: true, displayable: true, formElementType: "range", type: DataType.DATE_AND_TIME },
    { id: 14, code: "currency", title: "Currency", sortable: true, searchReqd: false, filterable: true, displayable: false, enumValues: ["SUCCESS", "FAILED", "PENDING"], formElementType: "radio", type: DataType.STRING },
  ],
  callBacks: {
    onSelect: (row) => console.log("Selected row:", row),
    onDelete: (row) => console.log("Deleted row:", row),
    onSearch: (key) => console.log("Searching with key:", key),
    onRowView: (key) => console.log("Viewing row with key:", key),
    onRowEdit: (key) => console.log("Editing row with key:", key),
    onRowDelete: (key) => console.log("Deleting row with key:", key),
    onSort: (key) => console.log("Sorting by key:", key),
    onClearSort: (key) => console.log("Clear sort for key:", key),
    onFilter: (key) => console.log("Filtering by key:", key),
    onClearFilter: (key) => console.log("Clear filter for key:", key),
    onColumnSort: (key) => console.log("Column sort by key:", key),
    onDownload: (key) => console.log("Download for key:", key),
    onPagination: (value) => console.log("Pagination:", value),
  },
  serverSide: true,
  serverSidePagination: true,
  pageState: PageState.IDLE,
  gridActions: {
    ep_data: { uri: "/customer/get", method: "GET" },
    ep_update: { uri: "/customer/update", method: "PUT" },
    ep_delete: { uri: "/customer/delete", method: "DELETE" },
    ep_toggle: { uri: "/customer/status", method: "PUT" },
  },
};

Props

  • data: An array of row objects matching the consumer's model (e.g., Customer[]).
  • gridMaster: The grid configuration object, containing columns, paging, sorting, filter state, UI options, and callback handlers.
  • children: Optional ReactNode for advanced composition; can pass grid state for debugging or developer tools.

Callbacks / Grid Event Callbacks

These functions are triggered by user interactions within the grid and allow you to implement custom logic for data manipulation and state updates.

Row Actions

  • onSelect: Triggered on row select/deselect.
  • onRowView: Triggered on a single row “view” action.
  • onRowEdit: Triggered on a single row “edit” action.
  • onRowDelete: Triggered on a single row “delete” action.
  • onDelete: Triggered for bulk delete actions.

Search and Filter

  • onSearch: Triggered for global search / filter submit; implement server or local filtering here.
  • onColumnSearch: Triggered for per-column search; receives { column, searchText }.
  • onFilter: Triggered when filter UI is applied.
  • onClearFilter: Clears current filter state.

Sorting

  • onSort: Triggered for global sort; receives { column, direction }.
  • onColumnSort: Triggered when sorting is invoked from a header context.
  • onClearSort: Clears current sort state.

Pagination

  • onPagination: Triggered on page change; receives { page, rowsPerPage, isFilter, filteredData }.

Other Actions

  • onClearAll: Clears all grid state.
  • onDownload: Triggered for export; receives "xlsx" or "pdf".

Grid Types

Customer

  • Customer: The consumer's record shape; must at least include a unique id.

GridMaster

  • GridMaster: Configuration object for the grid.
    • gridColumns: Columns configuration.
    • paging: Paging info, including currentPage, currentPageSize, totalPages.
    • sortBy, sortDirection.
    • pageState: Current UI state (see PageState).
    • callBacks: Event callbacks like onSelect, onDelete, etc.

PageState

  • PageState enum values:
    • LOADING
    • SUCCESS
    • ERROR

Column Configuration

Each entry in gridColumns can include:

  • code: string — field key in data.
  • title: string — header label.
  • displayable: boolean — controls visibility/export.
  • width, align, sortable, filterable, searchable: optional flags.
  • renderCell: optional custom renderer.
  • formElementType: e.g., "text", "radio", "range".
  • type: e.g., DataType.STRING, DataType.INTEGER, DataType.DATE_AND_TIME.
  • enumValues: predefined options for the column (e.g., "MALE", "FEMALE").

Export Helpers

  • exportToExcel(data, columns, fileName): Exports selected columns to XLSX.
  • exportToPDF(data, columns, fileName): Exports selected columns to PDF.

Tip: Map displayable columns and exclude internal fields before export.


Styling & Theming

  • The component uses MUI theming. Wrap your app with ThemeProvider and createTheme to customize palette, typography, and shape.
  • Layout is responsive via Box props — adjust container width/height based on your use case.

Best practices

  • Keep data immutable: create new arrays on sort/filter to avoid stale renders.
  • Prefer server-side operations for large datasets. Wire network calls inside onSearch / onPagination and use pageState to control loaders and errors.
  • Keep gridColumns stable (memoize) to avoid re-mounting cells.

Error handling

  • Use pageState to show loading spinners and error banners.
  • In callbacks, wrap async calls with try/catch and update pageState accordingly.

Accessibility

  • Keyboard navigation and focus rely on MUI/X Grid behavior — ensure row id is stable and unique.
  • Provide clear header names and adequate contrast via theme.

Versioning & peer requirements

  • React 18+
  • Material UI v5 (@mui/material, @emotion/react, @emotion/styled)
  • @mui/x-data-grid for base grid primitives
  • Icons via @mui/icons-material

Contributing

  • Open issues with minimal reproductions.
  • Propose API sketches for new features before submitting PRs.
  • Run type checks and linting before submitting.

License

ISC