Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

@asphalt-react/data-table

Package Overview
Dependencies
Maintainers
7
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@asphalt-react/data-table

Data Table

latest
npmnpm
Version
2.15.0
Version published
Maintainers
7
Created
Source

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: "john@example.com", firstName: "John", age: 28 },
  { uniqueId: "user-002", email: "jane@example.com", firstName: "Jane", age: 32 },
  { uniqueId: "user-003", email: "bob@example.com", 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", sortable: true },
  { key: "age", value: "Age", sortable: true, customSort: (a, b, {ascending: asc}) => asc ? a - b : b - a }
]

Each header object requires:

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

Optional sorting properties:

  • sortable: Boolean to enable sorting for this column
  • customSort: Function (valueA, valueB, {ascending}) => number to override default sorting behavior

Data Format

The data prop contains the table rows:

const data = [
  {
    uniqueId: "user-001",
    email: "john@example.com",
    firstName: "John",
    age: 28
  },
  {
    uniqueId: "user-002", 
    email: "jane@example.com",
    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.

Sticky Header

DataTable component accepts a stickyHeader prop to keep the dataTable header row sticky while scrolling through the dataTable body.

Columns Pinning

DataTable supports pinning a column to the left or right edge of the dataTable so it remains visible while scrolling horizontally. Pass a pinnedColumns object with left and/or right keys set to the column's key value.

<DataTable
  header={header}
  data={data}
  identifier="uniqueId"
  pinnedColumns={{ left: "email" }}
/>

Pin both edges simultaneously:

<DataTable
  header={header}
  data={data}
  identifier="uniqueId"
  pinnedColumns={{ left: "email", right: "age" }}
/>

Constraints:

  • The left and right keys must each exist in the header array
  • left and right cannot refer to the same column
  • On screens narrower than 600px, right pinned columns revert to normal flow automatically
  • If a pinned column's rendered width exceeds 75% of the viewport width, pinning is disabled for that column

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()}
    />
  )
}

Sorting Feature

DataTable supports column sorting with two modes: auto-sorting (client-side) and manual sorting (server-side).

Header Configuration for Sorting

To enable sorting on a column, set sortable: true in the header configuration:

const header = [
  { key: "email", value: "Email" },
  { key: "firstName", value: "First Name", sortable: true },
  {
    key: "age",
    value: "Age",
    sortable: true,
    // customSort is optional
    customSort: (valueA, valueB, {ascending}) => {
      const diff = valueA - valueB
      return ascending ? diff : -diff
    }
  }
]

1. Auto-Sorting (Client-Side)

When autoSort={true}, the DataTable handles sorting internally:

<DataTable
  header={header}
  data={data}
  identifier="uniqueId"
  autoSort={true}
  activeSort={{ columnKey: "firstName", ascending: true }}
/>

2. Manual Sorting (Server-Side)

For server-side sorting, use the onSort callback:

function App() {
  const [sortConfig, setSortConfig] = useState({ columnKey: null, ascending: null })

  const handleSort = (event, columnKey, ascending) => {
    setSortConfig({ columnKey, ascending })
    // Fetch sorted data from server
  }

  return (
    <DataTable
      header={header}
      data={data}
      identifier="uniqueId"
      activeSort={sortConfig}
      onSort={handleSort}
    />
  )
}

Custom Sort Props

Use getSortTileProps to add custom attributes to sortable header cells:

<DataTable
  header={header}
  data={data}
  identifier="uniqueId"
  autoSort={true}
  getSortTileProps={({ columnKey, ascending }) => ({
    'data-column': columnKey,
    'aria-sort': ascending === true ? 'ascending' : ascending === false ? 'descending' : 'none'
  })}
/>

Accessibility

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

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",
    sortable: true,
  },
  {
    key: "age",
    value: "Age",
    sortable: true,
    customSort: (valueA, valueB, {ascending}) => {
      const diff = valueA - valueB
      return ascending ? diff : -diff
    }
  }
]

Each header object must contain:

  • key: string identifier matching data object properties
  • value: string display label for the column header
  • sortable (optional): boolean to enable sorting for this column
  • customSort (optional): function (valueA, valueB, {ascending}) => number to override default sorting
typerequireddefault
arrayOftrueN/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: "john@example.com"
  },
  {
    uniqueId: "user-002",
    name: "Jane",
    email: "jane@example.com"
  }
]
typerequireddefault
stringtrueN/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: "john@random.com",
    firstName: "John",
    age: 28
  },
  {
    uniqueId: "user-002",
    email: "jane@random.com",
    firstName: "Jane",
    age: 32
  },
  {
    uniqueId: "user-003",
    email: "bob@random.com",
    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.

typerequireddefault
arrayOftrueN/A

autoPaginate

Enables auto pagination logic. Defaults to false.

typerequireddefault
boolfalsefalse

hover

Makes the row highlight on hover. Defaults to false.

typerequireddefault
boolfalsefalse

loading

Displays a loading component when set to true. Defaults to false.

typerequireddefault
boolfalsefalse

loadingComponent

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

typerequireddefault
elementTypefalseN/A

error

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

typerequireddefault
boolfalsefalse

errorComponent

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

typerequireddefault
elementTypefalseN/A

emptyComponent

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

typerequireddefault
elementTypefalseN/A

activePage

Current active page number for pagination. Defaults to 1.

typerequireddefault
numberfalse1

activePerPage

Current number of records to display per page. Controls how many table rows are shown on each page. Defaults to 10.

typerequireddefault
numberfalse10

totalRecords

Specifies the total number of records in the dataset for pagination calculations and record count display.

typerequireddefault
numberfalseN/A

totalPages

Specifies the total number of pages available for pagination navigation.

typerequireddefault
numberfalseN/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
typerequireddefault
funcfalseN/A

paginationElement

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

typerequireddefault
elementTypefalse"a"

Renders pagination tiles as anchor elements when set to true. Defaults to true.

typerequireddefault
boolfalsetrue

getTileProps

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

Receives an object with:

  • page: new active page number
  • record: new per-page value
typerequireddefault
funcfalseN/A

autoSort

Enables auto (client-side) sorting. Sorts data on the client side when set to true. When false, sorting must be handled externally via onSort callback. Defaults to false.

typerequireddefault
boolfalsefalse

activeSort

Applies initial sorting configuration when the table first renders. Specifies which column to sort by default and the sort direction.

Object properties:

  • columnKey: string - Must match a header key with sortable: true
  • ascending: boolean - true for ascending order, false for descending order

Example:

activeSort={{ columnKey: "firstName", ascending: true }}
typerequireddefault
shapefalseN/A

onSort

Callback function for remote/server-side sorting. Fires when a sortable header is clicked for remote/server-side sorting. Provides the column key and the sort direction in an object.

Object properties:

  • columnKey: string - The key of the column being sorted
  • ascending: boolean - True for ascending order, false for descending

Example:

onSort={({ columnKey, ascending }) => {
  console.log(`Sort ${columnKey} in ${ascending ? 'ascending' : 'descending'} order`);
  // Fetch sorted data from server
}}
typerequireddefault
funcfalseN/A

getSortTileProps

Function to generate additional props for sortable header cells. Adds custom attributes like data-attributes, aria-labels, etc. Use this prop together with activeSort to ensure correct sort state is passed.

Object properties:

  • columnKey: string - The key of the column
  • ascending: boolean | null - True for ascending, false for descending, null for unsorted

Example:

getSortTileProps={({ columnKey, ascending }) => ({
  'data-column': columnKey,
  'aria-sort': ascending === true ? 'ascending' : ascending === false ? 'descending' : 'none'
})}
typerequireddefault
funcfalseN/A

stickyHeader

Enables sticky behaviour for header row

typerequireddefault
boolfalsefalse

pinnedColumns

Pins columns to the left or right edge of the table. Must provide at least one of left or right, or both. Specify the column key for each side.

typerequireddefault
shapefalseN/A

Keywords

asphalt

FAQs

Package last updated on 13 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts