Sineways logoSineways
Docs@sineways/react-tablefront

Documentation

Everything you need to install, configure, and customize Tablefront.

Overview

Tablefront is a premium, zero‑configuration React DataTable with table, grid, and masonry layouts. Built on TanStack Table with TypeScript, Zustand state, and composable UI. Columns, search, and filters are auto‑generated, letting you ship faster.

  • Zero config: sensible defaults with easy overrides
  • Layouts: table, grid, masonry
  • Interactions: column drag/resize, expandable rows, structured filters
  • Performance: pagination and adaptive infinite scroll
  • Styling: presets and granular style slots

Quick Start

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

export default function UsersPage () {
  return <DataTable data={[]} />
}

Once globally:

import '@sineways/react-tablefront/styles.css'
Licensing is activated at build time. Set TABLEFRONT_LICENSE in your .env and prepend tablefront activate to your build script. No runtime network calls.

Features

  • Zero configuration: columns/search/filters auto‑generated
  • Layouts: table, grid, masonry
  • Interactions: drag/resize, expand, select
  • Search & filters: tokens, field‑aware
  • Data loading: pagination, infinite scroll
  • Styling: presets + slots

Layouts

Switch display modes or provide custom renderers.

<DataTable
  data={products}
  layout={{ displayMode: 'grid', gridColumns: 3 }}
  customRenderGridItem={(p) => (
    <div className='p-4 border rounded'>
      <h3>{p.name}</h3>
      <p>$ {p.price}</p>
    </div>
  )}
/>
<DataTable
  data={users}
  layout={{ displayMode: 'masonry', masonryColumns: 3 }}
/>

Search & Filters

  • Debounced free‑text search across searchable fields
  • Structured tokens via FilterProcessor
  • Field types: string | number | date; operators: > < >= <= = != * !*
const fieldOverrides = {
  status: { filterable: true, type: 'string', preferredValues: ['active','inactive'] },
  age: { filterable: true, type: 'number', defaultOperator: '>=', defaultNumericValue: 18 },
  createdAt: { filterable: true, type: 'date', defaultOperator: '>=' }
}

Interactions

<DataTable
  data={rows}
  enableColumnDrag
  enableColumnResize
  resizeTimingConfig={{ doubleClickDelay: 300, resetDebounce: 1000 }}
/>

Expandable Rows

Toggle row expansion and render extra content below each row. Expanded content can be width-clamped to the visible scroll container by default so it aligns with the on-screen table area.

<DataTable
  data={users}
  expandable
  renderExpandedContent={(u) => (
    <div className='p-4 bg-gray-50'>Email: {u.email}</div>
  )}
/>

Content Width Clamping (Table mode): Use these props to control how expanded content and static rows size themselves horizontally.

  • clampExpandedContentToContainer (default: true): sizes expanded content to the table's scroll container width.
  • clampStaticRowsToContainer (default: true): applies the same for customStaticRows.

Disable either to let content span the full table content width:

<DataTable
  data={rows}
  expandable
  renderExpandedContent={(r) => <div>Details...</div>}
  clampExpandedContentToContainer={false}
  clampStaticRowsToContainer={false}
/>

Pagination & Infinite Scroll

Choose traditional pagination or infinite scroll (regular/adaptive).

// Regular infinite scroll
<DataTable
  data={big}
  paginationConfig={{ pageSize: 50 }}
  infiniteScrollConfig={{ enabled: true, increment: 50 }}
/>
// Adaptive (virtualized) infinite scroll
<DataTable
  data={big}
  paginationConfig={{ pageSize: 50 }}
  infiniteScrollConfig={{ enabled: true, adaptive: true, pageSize: 50, maxItems: 150 }}
/>

Styling

Use presets or override granular style slots.

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

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

<DataTable data={rows} customStyles={{
  container: 'bg-white',
  table: { tableHeader: 'sticky top-0 bg-background' },
  pagination: { container: 'border-t' }
}} />

UI & Icon Overrides

const ui = {
  Button: MyButton,
  Popover: MyPopover,
  PopoverTrigger: MyPopover.Trigger,
  PopoverContent: MyPopover.Content,
  Tooltip: MyTooltip,
  TooltipTrigger: MyTooltip.Trigger,
  TooltipContent: MyTooltip.Content,
  ScrollArea: MyScrollArea,
  Switch: MySwitch,
  Label: MyLabel,
  Separator: MySeparator,
  Settings02Icon: MySettingsIcon
}

<DataTable data={rows} uiComponents={ui} />
const icons = {
  Search: MySearchIcon,
  Filter: MyFilterIcon,
  SortAscending: MySortAsc,
  SortDescending: MySortDesc,
  SortUnsorted: MySortDefault,
  PaginationPrevious: MyPrev,
  PaginationNext: MyNext,
  ExpandIcon: MyExpand,
  CollapseIcon: MyCollapse,
  ClearFilters: MyClear,
  X: MyX,
  ColumnSettings: MyColumnSettings
}

<DataTable data={rows} icons={icons} />

Columns & Fields

const columnOverrides = {
  name: {
    visible: true,
    header: () => <span>Name</span>,
    cell: (info) => <strong>{info.getValue?.() ?? ''}</strong>,
    headerAlignment: 'left',
    meta: { className: 'min-w-40' }
  }
}

Default Column Visibility

Control which columns are visible on first render. Applied only when there is no persisted state for the provided storeId.

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

API Reference

Primary component props:

type DataTableProps<T> = {
  data: T[]
  columns?: ColumnDef<T, any>[]
  columnOverrides?: ColumnOverrides<T>
  fieldOverrides?: FieldOverrides<T>
  customStyles?: PartialTableStyles
  uiComponents?: DataTableUIComponents
  icons?: DataTableIcons
  storeId?: string
  // Initial state (first-use only if no persisted state)
  initialColumnVisibility?: { hideAll?: boolean, byId?: Record<string, boolean> }

  // Interactions
  onRowClick?: (row: T) => void
  selectedRow?: T | null
  autoSelect?: boolean

  // Expandable
  expandable?: boolean
  expandedRows?: Record<string, boolean>
  onToggleExpand?: (row: T) => void
  onExpansionChange?: (rows: Record<string, boolean>) => void
  renderExpandedContent?: (row: T) => React.ReactNode
  clampExpandedContentToContainer?: boolean
  clampStaticRowsToContainer?: boolean

  // Rendering & labels
  headerRightElement?: React.ReactNode
  customRenderGridItem?: (row: T, index: number, isSelected: boolean) => React.ReactNode
  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
  }

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

  // Column interactions
  enableColumnDrag?: boolean
  enableColumnResize?: boolean
  resizeTimingConfig?: ResizeTimingConfig
}

Exports overview:

  • Core: DataTable
  • Subcomponents: SmartHeader, DataGrid, DataMasonry, DataTableHeader, DataTableBody, DataTablePagination, DataTableStates
  • Icons: DefaultIcons, useDataTableIcons
  • Builders: applyColumnOverrides, applyColumnVisibilityOverrides, quickColumns, applySmartSizing, autoGenerateFields, applyFieldOverrides, buildFields
  • Stores: createDataTable, createAutoDataTable, createSimpleDataTable
  • Styling: useTableStyles, presets & helpers
  • Utils: cn, table utils, resize constants
  • Licensing: useLicense, LicenseProvider, useLicenseContext

Licensing

Commercial license required. Activation uses a build-time step and makes no runtime network calls. The library still works with a watermark if the key is missing or invalid.

Licenses: coming soon
Configure your environment and build script:
# .env
TABLEFRONT_LICENSE=your-license-key
"scripts": {
  "build": "tablefront activate && next build"
}
Notes: If the key is missing or invalid, the build logs guidance and the library still works with a watermark. No network calls are made at runtime; activation writes a tiny globals file consumed by the package.
Ready to try it?
Install now or email us — we reply fast.