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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@jjmyers/datatable

v1.0.13

Published

A datatable that comes with the most popular features.

Downloads

20

Readme

React Datatable

The styling of the datatable can be customized using CSS.

Check out the DEMO WEBSITE

A datatable equiped with every commonly used filter. The demo has an array of 1,000 records. Not all features are active here. If you find a bug or want a feature, raise an issue on GitHub.

☕ Support My Work

Hey there! 👋 If my npm libraries have made your coding journey easier or sparked creativity, consider supporting my work with a virtual coffee. Your generosity keeps the code flowing and inspires more innovations! ☕🚀

"Buy Me A Coffee"

Quick Features

  • Sorting
  • Multi Sorting
  • Number filter
  • Text filter
  • Boolean filter
  • Set filter
  • Pagination
  • Toggleable columns
  • A Seperate controller from component, to allow customization.
  • Added client sided data manipulation
  • Editable cells
  • Cell validation on edit

Example usage

To import styles you need to add this to the top

You can copy the contents of this css file and customize it to suit your theme

import "@jjmyers/datatable/build/styles/default.css"

import { useDatatable, type Datatable } from "@jjmyers/datatable";
import "@jjmyers/datatable/build/styles/default.css" // OR elegance.css

const status = ["online", "offline", "available", "unavailable", "dnd"]

type Data = {
  id: number;
  status: string;
  fullName: string;
  // ...more fields
}


function MyListOfData() {

  const [isFetching, setIsFetching] = useState(false);

  const onSaveChanges = (dirtyRows: Data[]) => new Promise((resolve) => {
    console.log({ dirtyRows })
    setTimeout(() => resolve(true), 3000)
  })

  const { Datatable, ...controller } = useDatatable<Data>({
    data: data,         // An array of objects
    count: data.length, // This is the total number of records in the database
    serverSide: false,  // If this is false, data manipulation will be handled client sided. DEFAULT: true
    onFilter: console.log, // If serverSide is true, you need to handle the filters here and update data.
    onSaveChanges: onSaveChanges,
    validateChanges: {
      lastName: (value, field, dirtyRow, columns, originalRow) => {
        if (!value) return null;
        if (value.length > 3) return "Max 3 characters"
        if (value === dirtyRow.middleName || value === originalRow?.middleName) return "Middle name and lastname cannot be the same"
        return null
      },
      // A special field in validateChanges, used to perform validation on all fields, regardless wheather they were edited or not.
      // If any field in the row is edited, all fields in that row will go through this validator.
      // A good place to check for required fields if the data comes in empty and on edit you need to make sure the fields were filled.
      __allRows__: (value, field, dirtyRow, columns, originalRow) => {
        if (!value && field === "firstName") return "First name is required"
        if(value && field === "firstName" && value.length < 2)  return "Minimum 2 characters is required"
        // Check all other fields...
        return null
      },
    },
    initialSortOrder: {
      id: { orderIndex: 1, sortDirection: "desc" }
    },
    columns: [
      // There are more props
      // You'll have to check them yourself
      { field: "id", width: 85, datatype: "number", editable: false },
      { field: "status", editable: val => val !== "dnd" setOptions: status, multiFilter: true },
      { field: "fullName", editable: false, width: 250 },
      { field: "firstName" },
      { field: "middleName" },
      { field: "lastName" },
      { field: "email", width: 250, datatype: "email", sortable: false, filterable: false },
      { field: "phone", datatype: "phone" },
      { field: "isActive", datatype: "boolean" },
      { field: "profileImage", datatype: "image", omit: true },
      { field: "website", width: 250, datatype: "link" },
      { field: "loginTime", datatype: "time" },
      { field: "dateOfBirth", width: 180, datatype: "date" },
      { field: "about", width: 500, datatype: "paragraph" },
      { field: "createdAt", width: 250, datatype: "datetime" },
      { field: "customField" },
    ],
  })
  
  // Just an example of how you can add buttons here and manipulate the datatable if needed.
  const AppsPanel = ({ OmitColumns }: Datatable.AppsPanelProps) => (
    <>
      <button className="elegance-button" onClick={() => controller.reset(true)} style={{ padding: 8 }}>Reset Filters</button>
      <button className="elegance-button" onClick={() => controller.reset()} style={{ padding: 8 }}>Clear Filters</button>
      {OmitColumns}
    </>
  )

  // Just an exmple of adding options to rows
  const RowOptionMenu = ({ row, rowIndex }: Datatable.RowOptionMenuProps<Data>) => (
    <>
      <button className="elegance-button" onClick={() => setIsFetching(true)} style={{ padding: 8 }}>Fetching On</button>
      <button className="elegance-button" onClick={() => setIsFetching(false)} style={{ padding: 8 }}>Fetching Off</button>
    </>
  );


  return (
    <Datatable
      isFetching={isFetching}
      RowOptionMenu={RowOptionMenu}
      AppsPanel={AppsPanel}

      // If this is not passed, select option will go, otherwise it uses this fn to determine if a row is selectable
      isSelectable={row => row.is_active}

      // Sometimes we want the row options to show when you click on a row, mostly when you have many columns and have to scroll to click options.
      showOptionsOnRowClick

      // To auto-size the column
      columnNameFontSize={16}
      {...controller}
    />
  )

}