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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@sineways/react-tablefront

v1.0.0-beta.4

Published

React Data Table and Data Grid for TypeScript. Zero config with fast search and filters, pagination and infinite scroll, table grid and masonry layouts. Built on TanStack Table.

Readme

@sineways/react-tablefront

A premium, feature-rich DataTable component that works out of the box with zero configuration.

For more information and licensing, visit our website. For a live demo, see demo page.

Features

  • Zero Configuration - Works out of the box
  • Multiple Display Modes - Table, Grid, and Masonry layouts
  • Advanced Interactions - Column drag-and-drop, resizing, expandable rows
  • Smart Auto-Generation - Columns, filters, and searches auto-generated
  • Responsive Design - Mobile-first approach
  • Performance Optimized - Virtual scrolling, debounced search
  • Type Safe - Full TypeScript support
  • State Persistence - User preferences saved automatically
  • Composable UI - Override UI components, icons, and styles
  • Predictable Filters - Structured search and field-level filters

Quick Start

1) Install Package

npm install @sineways/react-tablefront

2) Activate License (optional)

Tablefront works without a key, but shows a small watermark. To remove it, provide a key and run activation at build time.

Add your key to .env:

TABLEFRONT_LICENSE=your-license-key

Ensure activation runs during your build (example for Next.js):

{
  "scripts": {
    "build": "tablefront activate && next build"
  }
}

Notes:

  • If the key is missing or invalid, the build prints guidance and the library still works with a watermark.
  • No runtime calls are made; activation writes a small globals file used by the components.

3) Global Styles

Import the package stylesheet once in your app entry:

import '@sineways/react-tablefront/styles.css'

4) Basic Usage

import { DataTable } from '@sineways/react-tablefront'

function UsersPage () {
  const [users, setUsers] = React.useState([])
  const [isLoading, setIsLoading] = React.useState(true)

  return (
    <DataTable
      data={users}
      isLoading={isLoading}
      storeId='userTable'
    />
  )
}

API Reference

(props)

Required props:

{
  data: TData[]
}

Key optional props (selected):

{
  // Columns & fields
  columns?: ColumnDef<TData, any>[]
  columnOverrides?: ColumnOverrides<TData>
  // First-use default column visibility (persisted via storeId)
  initialColumnVisibility?: { hideAll?: boolean, byId?: Record<string, boolean> }
  fieldOverrides?: FieldOverrides<TData>

  // Styling & UI
  customStyles?: PartialTableStyles
  uiComponents?: DataTableUIComponents
  icons?: DataTableIcons
  storeId?: string

  // Row interaction
  onRowClick?: (row: TData) => void
  selectedRow?: TData | null
  autoSelect?: boolean

  // Expandable rows
  expandable?: boolean
  expandedRows?: Record<string, boolean>
  onToggleExpand?: (row: TData) => void
  onExpansionChange?: (expandedRows: Record<string, boolean>) => void
  renderExpandedContent?: (row: TData) => React.ReactNode
  // Width clamping (table mode)
  clampExpandedContentToContainer?: boolean // default: true
  clampStaticRowsToContainer?: boolean // default: true

  // Custom rendering
  headerRightElement?: React.ReactNode
  customRenderGridItem?: (row: TData, index: number, isSelected: boolean) => React.ReactNode
  customStaticRows?: React.ReactNode[]
  customStaticRowsSticky?: boolean

  // Text & states
  searchPlaceholder?: string
  emptyStateText?: string
  loadingText?: string
  isLoading?: boolean

  // Layout
  layout?: {
    showSearchBar?: boolean
    showHeader?: boolean
    showTableHeaders?: boolean
    showColumnVisibility?: boolean
    showFilterButton?: boolean
    displayMode?: 'table' | 'grid' | 'masonry'
    gridColumns?: number
    gridItemMinWidth?: number
    masonryColumns?: number
    masonryItemMinWidth?: number
    masonryGap?: number
  }

  // Pagination & infinite scroll
  paginationConfig?: {
    autoFit?: boolean
    pageSize?: number
  }
  infiniteScrollConfig?: {
    enabled?: boolean
    adaptive?: boolean
    loadThreshold?: number
    pageSize?: number
    increment?: number
    maxItems?: number
  }

  // Feature toggles
  enableColumnDrag?: boolean
  enableColumnResize?: boolean
  resizeTimingConfig?: ResizeTimingConfig
}

Default column visibility (first-use)

You can control which columns are shown on first use. The initial state is persisted per storeId.

<DataTable
  data={products}
  storeId='products'
  initialColumnVisibility={{
    hideAll: true,
    byId: { name: true, price: true }
  }}
/>

Notes:

  • When hideAll is true, all columns are hidden by default and only the byId entries marked true are shown.
  • Once the user changes visibility, it persists and overrides the initial defaults on subsequent renders.

Filters & Search

FilterProcessor powers structured filters and free-text search.

  • Field types: number, string, date
  • Operators: > < >= <= = != * !*
  • Field overrides support path, aliases, preferredValues, defaultOperator, defaultNumericValue, isPercentage, etc.

Examples:

- impressions:>100
- createdAt:>=2024-01-01
- status:active  (string contains)
- -status:active (negated)

UI Overrides

You can replace internal UI with your components via uiComponents:

export type DataTableUIComponents = {
  Button?: ComponentType<ButtonHTMLAttributes<HTMLButtonElement>>
  FilterButton?: ComponentType<ButtonHTMLAttributes<HTMLButtonElement>>
  ColumnButton?: ComponentType<ButtonHTMLAttributes<HTMLButtonElement>>
  ClearButton?: ComponentType<ButtonHTMLAttributes<HTMLButtonElement>>
  ClearSearchButton?: ComponentType<ButtonHTMLAttributes<HTMLButtonElement>>
  PaginationButton?: ComponentType<ButtonHTMLAttributes<HTMLButtonElement>>
  FilterItemButton?: ComponentType<ButtonHTMLAttributes<HTMLButtonElement>>
  ScrollArea?: ComponentType<{ className?: string; children?: ReactNode }>
  Popover?: ComponentType<{ children: ReactNode; open?: boolean; onOpenChange?: (open: boolean) => void }>
  PopoverTrigger?: ComponentType<{ children: ReactNode; asChild?: boolean }>
  PopoverContent?: ComponentType<{ children: ReactNode; className?: string; align?: 'center' | 'start' | 'end'; sideOffset?: number }>
  Tooltip?: ComponentType<{ children: ReactNode }>
  TooltipTrigger?: ComponentType<{ children: ReactNode; asChild?: boolean }>
  TooltipContent?: ComponentType<{ children: ReactNode; className?: string }>
  Switch?: ComponentType<{ checked?: boolean; onCheckedChange?: (v: boolean) => void; className?: string; id?: string }>
  Label?: ComponentType<{ children?: ReactNode; htmlFor?: string; className?: string }>
  Separator?: ComponentType<{ className?: string }>
  Settings02Icon?: ComponentType<{ className?: string }>
}

Icon Overrides

Override any default icon:

export type DataTableIcons = {
  Loader?: ComponentType<IconProps>
  PaginationPrevious?: ComponentType<IconProps>
  PaginationNext?: ComponentType<IconProps>
  SortAscending?: ComponentType<IconProps>
  SortDescending?: ComponentType<IconProps>
  SortUnsorted?: ComponentType<IconProps>
  ExpandIcon?: ComponentType<IconProps>
  CollapseIcon?: ComponentType<IconProps>
  ClearFilters?: ComponentType<IconProps>
  Search?: ComponentType<IconProps>
  X?: ComponentType<IconProps>
  Filter?: ComponentType<IconProps>
  ColumnSettings?: ComponentType<IconProps>
}

Also available: DefaultIcons, useDataTableIcons() hook.

Styling

  • Pass customStyles to override any style slot. See PartialTableStyles in variants for structure.
  • Presets: defaultTableStyles, modernTableStyles, compactTableStyles
  • Helpers: useTableStyles(customStyles), tableStylePresets, getTableStylePreset('modern')
  • Optional global defaults: import '@sineways/react-tablefront/tailwind.css'

Example preset usage:

import { DataTable, modernTableStyles } from '@sineways/react-tablefront'

<DataTable data={rows} customStyles={modernTableStyles} />

Layout Modes

  • Table: default rich table with sorting, resizing, column visibility
  • Grid: card-like layout via customRenderGridItem
  • Masonry: variable height multi-column layout

Grid example:

<DataTable
  data={products}
  layout={{ displayMode: 'grid', gridColumns: 3 }}
  customRenderGridItem={(p) => (
    <div className='product-card'>
      <img src={p.image} alt={p.name} />
      <h3>{p.name}</h3>
      <p>${p.price}</p>
    </div>
  )}
/>

Expandable rows:

<DataTable
  data={users}
  expandable
  renderExpandedContent={(u) => (
    <div className='p-4 bg-gray-50'>
      <h3>User Details</h3>
      <p>Email: {u.email}</p>
    </div>
  )}
  // Expanded content and custom static rows are clamped to the scroll container
  // width by default. Disable if you want them to span the full table content width.
  clampExpandedContentToContainer
  clampStaticRowsToContainer
/>

Content width clamping (table mode):

  • By default, expanded row content and custom static rows are sized to the table's scroll container width, so they align with the container instead of the full table content width.
  • To allow full-width content, set clampExpandedContentToContainer={false} and/or clampStaticRowsToContainer={false}.

Named Exports

// Core
export { DataTable }

// Subcomponents
export { SmartHeader }
export { DataTableStates, LoadingState, EmptyState }
export { DataTablePagination, PaginationInfo, PaginationControls }
export { DataTableHeader, ClearFiltersButton, SearchInput }
export { DataTableBody, TableRow, TableCell, ExpandButton }
export { DataGrid, GridItem, GridField }
export { DataMasonry, MasonryItem, MasonryField }

// Icons
export { DefaultIcons, useDataTableIcons }

// Column & field tools
export { applyColumnOverrides, applyColumnVisibilityOverrides }
export { quickColumns, applySmartSizing }
export { autoGenerateFields, applyFieldOverrides, buildFields }

// Stores
export { createDataTable, createAutoDataTable, createSimpleDataTable }

// Styles
export { useTableStyles }
export { defaultTableStyles, modernTableStyles, compactTableStyles, tableStylePresets, getTableStylePreset }

// Utils
export { cn }
export { generateStableStoreId, getFirstField, isValidId, safeStringId, safeEquals }
export { DEFAULT_RESIZE_DOUBLE_CLICK_DELAY, DEFAULT_RESIZE_RESET_DEBOUNCE }

Key types are exported from types/DataTableTypes (e.g., DataTableProps, DataTableLayout, DataTableUIComponents, DataTableIcons, PartialTableStyles, ResizeTimingConfig, etc.).

Licensing

This is a commercial product.

Simplified activation:

  • Add TABLEFRONT_LICENSE to your .env
  • Run tablefront activate as part of your build (e.g., "build": "tablefront activate && next build")

Behavior:

  • Missing/invalid key: library works with a small watermark; build and browser consoles show helpful messages
  • Valid key: watermark is removed automatically

Support

License

Commercial license required. See LICENSE.md for details.