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

@asphalt-react/data-table

v2.12.2

Published

Data Table

Readme

DataTable

npm npm version

DataTable component displays structured data in a tabular format with support for pagination. It provides an intuitive way to present large datasets with automatic or manual pagination controls. The component handles data validation, row identification, and responsive pagination controls including items per page selection.

DataTable supports two pagination modes: manual pagination where you manage the pagination state externally, and auto-pagination where the component automatically handles pagination internally using the provided data.

Usage

import React from "react"
import { DataTable } from "@asphalt-react/data-table"

const header = [
  { key: "email", value: "Email" },
  { key: "firstName", value: "First Name" },
  { key: "age", value: "Age" }
]

const data = [
  { uniqueId: "user-001", email: "[email protected]", firstName: "John", age: 28 },
  { uniqueId: "user-002", email: "[email protected]", firstName: "Jane", age: 32 },
  { uniqueId: "user-003", email: "[email protected]", firstName: "Bob", age: 45 }
]

function App() {
  return (
    <DataTable
      header={header}
      data={data}
      identifier="uniqueId"
    />
  )
}

Data Structure

Header Configuration

The header prop defines the table columns:

const header = [
  { key: "email", value: "Email" },
  { key: "firstName", value: "First Name" },
  { key: "age", value: "Age" }
]

Each header object requires:

  • key: Property name in the data objects
  • value: Display label for the column

Data Format

The data prop contains the table rows:

const data = [
  {
    uniqueId: "user-001",
    email: "[email protected]",
    firstName: "John",
    age: 28
  },
  {
    uniqueId: "user-002", 
    email: "[email protected]",
    firstName: "Jane",
    age: 32
  }
]

Requirements:

  • Each object represents a table row
  • Object keys should match header keys
  • All objects must contain the identifier field
  • Values can be strings, numbers, or React nodes

Hover

DataTable component accepts a hover prop to make it look highlighted when on hover.

Loading, Error, and Empty Data States

DataTable supports customizable states for loading, error, and empty data scenarios.

Loading State

Display a loading indicator while data is being fetched:

<DataTable
  header={header}
  data={data}
  identifier="uniqueId"
  loading={true}
/>

Custom Loading Component

Provide a custom component for the loading state:

const CustomLoader = () => (
  <div
    style={{
      display: "flex",
      flexDirection: "column",
      alignItems: "center",
      justifyContent: "center",
      padding: "10rem 0rem",
    }}
  >
    <Loader size="large" />
    <Text>Loading data...</Text>
  </div>
)

<DataTable
  header={header}
  data={data}
  identifier="uniqueId"
  loading={true}
  loadingComponent={CustomLoader}
/>

Error State

Display an error message when data fetching fails:

<DataTable
  header={header}
  data={[]}
  identifier="uniqueId"
  error={true}
/>

Custom Error Component

Provide a custom component for the error state:

const CustomError = () => (
  <div
    style={{
      display: "flex",
      flexDirection: "column",
      alignItems: "center",
      justifyContent: "center",
      padding: "10rem 0rem",
    }}
  >
    <Text>Failed to load data. Please try again.</Text>
    <Button onClick={refetch}>Retry</Button>
  </div>
)

<DataTable
  header={header}
  data={[]}
  identifier="uniqueId"
  error={true}
  errorComponent={CustomError}
/>

Empty State

DataTable will show a message if the data is empty automatically. Example use-case:

<DataTable
  header={header}
  data={[]}
  identifier="uniqueId"
/>

Custom Empty Component

Provide a custom component for the empty state:

const CustomEmpty = () => (
  <div
    style={{
      display: "flex",
      flexDirection: "column",
      alignItems: "center",
      justifyContent: "center",
      padding: "10rem 0rem",
    }}
  >
    <Text>No data available</Text>
  </div>
)

<DataTable
  header={header}
  data={[]}
  identifier="uniqueId"
  emptyComponent={CustomEmpty}
/>

Pagination Feature

DataTable supports two distinct pagination modes:

1. Auto-Pagination

When autoPaginate={true} is set, the DataTable automatically:

  • Calculates total pages based on data length
  • Manages internal pagination state
  • Slices the data for the current page
  • Handles page and per-page changes internally

This mode is ideal for client-side pagination of static datasets.

import React from "react"
import { DataTable } from "@asphalt-react/data-table"

function App() {
  return (
    <DataTable
      header={header}
      data={largeDataset}
      identifier="uniqueId"
      autoPaginate={true}
      paginationLink={false}
    />
  )
}

2. Manual Pagination

When autoPaginate is false (default), you have full control:

  • Provide pre-sliced data for the current page
  • Manage pagination state externally
  • Handle server-side pagination or complex data fetching
  • Control the total pages and records count

This mode is ideal for server-side pagination or when you need custom pagination logic.

import React, { useState } from "react"
import { Link } from "gatsby" // or any other router like react-router
import { DataTable, usePagination } from "@asphalt-react/data-table"

function App() {
  const [currentPage, setCurrentPage] = useState(1)
  const [currentPerPage, setCurrentPerPage] = useState(10)

  const handlePaginationChange = ({ event, page, record }) => {
    event.preventDefault()

    if (page && page !== currentPage) {
      setCurrentPage(page)
    }

    if (record && record !== currentPerPage) {
      setCurrentPerPage(record)
      setCurrentPage(1)
    }
  }

  const handleTileProps = ({ page, record }) => ({
    to: `?page=${page}&perPage=${record}`,
  })

  const { getPaginationProps, getSlicedData } = usePagination({
    activePage: currentPage,
    activePerPage: currentPerPage,
    onChange: handlePaginationChange,
    getTileProps: handleTileProps,
    data: tableData,
    as: Link,
    link: true,
  })

  const currentData = getSlicedData(tableData)

  return (
    <DataTable
      header={tableHeader}
      data={currentData}
      identifier="uniqueID"
      {...getPaginationProps()}
    />
  )
}

Accessibility

  • Use tab or shift+tab to navigate among pages.

Custom Link Components

Use router link components for client-side navigation:

import { Link } from "gatsby" // or any other router like react-router
import { DataTable, usePagination } from "@asphalt-react/data-table"
  
const handleTileProps = ({ page, record }) => ({
  to: `?page=${page}&perPage=${record}`,
})

const { getPaginationProps } = usePagination({
  activePage: currentPage,
  activePerPage: currentPerPage,
  getTileProps: handleTileProps,
  as: Link,
  link: true,
})

<DataTable
  // ... other props
  {...getPaginationProps()}
/>

Hooks

usePagination

Internal hook that provides unified pagination event handlers and prop getters for DataTable components. This hook normalizes the interaction between pagination controls and per-page controls, ensuring consistent event handling across both auto and manual pagination modes.

Returns:

An object with:

  • getPaginationProps: Object containing all pagination state and handlers to spread onto DataTable
    • activePage: Current active page number
    • activePerPage: Current items per page count
    • totalPages: Total number of pages
    • totalRecords: Total number of records
    • paginationLink: Whether pagination items render as links
    • paginationElement: Element type for pagination items
    • onPaginationChange: Unified handler for both page and per-page changes
    • getTileProps: Unified prop getter for pagination tiles
  • getSlicedData: Function that slices data array to return only current page items

Parameters

const { getPaginationProps, getSlicedData } = usePagination({
  activePage: 1,            // Currently active page number
  activePerPage: 25,        // Current items per page count
  data: myData,             // Data array to calculate totals from
  totalPages: 10,           // Optional: Override calculated total pages
  totalRecords: 250,        // Optional: Override calculated total records
  as: Link,                 // Custom element/component for pagination items
  link: true,               // Whether pagination items render as links
  onChange: ({ event, page, record }) => {
    // Unified change handler for both page and per-page changes
    console.log('Event:', event, 'Page:', page, 'Record:', record);
  },
  getTileProps: ({ page, record }) => ({
    to: `/users?page=${page}&perPage=${record}`,
    'data-testid': `tile-${page}-${record}`
  })
});

Key Features

  • Unified Event Handling: Both page navigation and per-page selection changes call the same onChange callback with consistent parameters { event, page, record }
  • Prop Getters: Returns specialized prop getter functions that inject proper page/record context based on the control type
  • Centralized Props: getPaginationProps() returns all pagination state and handlers in a single object for easy spreading onto DataTable
  • Link Integration: Supports custom link components through as parameter and the getTileProps function
  • Flexible Totals: Can calculate totals from data array or accept explicit totalPages and totalRecords for server-side pagination
  • State Normalization: Ensures consistent state management between auto and manual pagination modes

Usage

const [currentPage, setCurrentPage] = useState(1)
const [currentPerPage, setCurrentPerPage] = useState(10)

const handlePaginationChange = ({ event, page, record }) => {
  event.preventDefault()

  if (page && page !== currentPage) {
    setCurrentPage(page)
  }

  if (record && record !== currentPerPage) {
    setCurrentPerPage(record)
    setCurrentPage(1)
  }
}

const { getPaginationProps, getSlicedData } = usePagination({
  activePage: currentPage,
  activePerPage: currentPerPage,
  onChange: handlePaginationChange,
  data: tableData,
  link: false,
})

const currentData = getSlicedData(tableData)

return (
  <DataTable
    header={tableHeader}
    data={currentData}
    identifier="uniqueID"
    {...getPaginationProps()}
  />
)

Props

header

Data table header configuration.

Example:

[
  {
    key: "email",
    value: "Email",
  },
  {
    key: "firstName",
    value: "First Name",
  },
  {
    key: "age",
    value: "Age",
  }
]

Each header object must contain:

  • key: string identifier matching data object properties
  • value: string display label for the column header

| type | required | default | | ------- | -------- | ------- | | arrayOf | true | N/A |

identifier

Field name in each data row used as the unique row identifier. This property name must exist in every data object and contain unique values for proper row identification and React key generation.

Example:

identifier="uniqueId"

// With data like:
[
  {
    uniqueId: "user-001",
    name: "John",
    email: "[email protected]"
  },
  {
    uniqueId: "user-002",
    name: "Jane",
    email: "[email protected]"
  }
]

| type | required | default | | ------ | -------- | ------- | | string | true | N/A |

data

Table data rows to be displayed. Each object represents a row, with keys matching the header configuration. Property names should correspond to header.key values for proper column mapping.

Example:

[
  {
    uniqueId: "user-001",
    email: "[email protected]",
    firstName: "John",
    age: 28
  },
  {
    uniqueId: "user-002",
    email: "[email protected]",
    firstName: "Jane",
    age: 32
  },
  {
    uniqueId: "user-003",
    email: "[email protected]",
    firstName: "Bob",
    age: 45
  }
]

Each data object should contain properties that match the keys defined in the header configuration. Values can be strings, numbers, or React nodes for custom cell content.

| type | required | default | | ------- | -------- | ------- | | arrayOf | true | N/A |

autoPaginate

Enable auto pagination logic.

| type | required | default | | ---- | -------- | ------- | | bool | false | false |

hover

Makes the row highlight on hover.

| type | required | default | | ---- | -------- | ------- | | bool | false | false |

loading

Whether the table is in a loading state. When true, a loading component will be displayed.

| type | required | default | | ---- | -------- | ------- | | bool | false | false |

loadingComponent

HTML element or React component to replace default loading display component.

| type | required | default | | ----------- | -------- | ------- | | elementType | false | N/A |

error

Whether the table is in an error state. When true, an error component will be displayed.

| type | required | default | | ---- | -------- | ------- | | bool | false | false |

errorComponent

HTML element or React component to replace default error display component.

| type | required | default | | ----------- | -------- | ------- | | elementType | false | N/A |

emptyComponent

HTML element or React component to replace default empty state display component.

| type | required | default | | ----------- | -------- | ------- | | elementType | false | N/A |

activePage

Current active page number for pagination. Used with pagination to control the currently displayed page.

| type | required | default | | ------ | -------- | ------- | | number | false | 1 |

activePerPage

Number of records to display per page. Controls how many table rows are shown on each page.

| type | required | default | | ------ | -------- | ------- | | number | false | 10 |

totalRecords

Total number of records in the dataset. Used to calculate pagination information and display record counts.

| type | required | default | | ------ | -------- | ------- | | number | false | N/A |

totalPages

Total number of pages available. Used by pagination component to render page navigation.

| type | required | default | | ------ | -------- | ------- | | number | false | N/A |

onPaginationChange

Callback function triggered when page or per-page selection changes.

Receives an object with:

  • event: browser event
  • page: new active page number
  • record: new per-page value

| type | required | default | | ---- | -------- | ------- | | func | false | N/A |

paginationElement

HTML element or React component to replace default pagination elements. Useful for integrating with routing libraries like react-router-dom's Link.

| type | required | default | | ----------- | -------- | ------- | | elementType | false | "a" |

paginationLink

Whether pagination tiles should render as links. When true, pagination items will be rendered as anchor elements.

| type | required | default | | ---- | -------- | ------- | | bool | false | true |

getTileProps

Function to generate additional props for pagination tiles. Used to add custom attributes like href, id, data-attributes, etc.

Receives an object with:

  • page: new active page number
  • record: new per-page value

| type | required | default | | ---- | -------- | ------- | | func | false | N/A |