Photonix

DataTable

A feature-rich data grid with sorting, selection, resizing, and responsive layouts.

Preview

Name
Email
Role
Status
John Smith
Admin
active
Sarah Johnson
Editor
active
Mike Wilson
Viewer
inactive
Usage
import { DataTable } from '@photonix/ultimate';

const columns = [
  { key: 'name', title: 'Name', width: '250px' },
  { key: 'email', title: 'Email' },
  { key: 'role', title: 'Role', width: '150px' },
];

const data = [...];

<DataTable columns={columns} data={data} rowKey="id" />

Component API

DataTable

Prop
Type
Default
Description
columns
Column<T>[]
-
Array of column definitions
data
T[]
-
Array of data rows
rowKey
keyof T | ((row: T) => string | number)
-
Unique key accessor for each row
selectable
boolean
false
Enable row selection
selectedKeys
(string | number)[]
[]
Selected row keys
onSelectionChange
((keys: (string | number)[]) => void)
-
Callback when selection changes
sortKey
string | null
null
Current sort column key
sortDirection
SortDirection
null
Current sort direction
onSortChange
((key: string, direction: SortDirection) => void)
-
Callback when sort changes
loading
boolean
false
Loading state
emptyContent
React.ReactNode
-
Empty state content
stickyHeader
boolean
false
Sticky header
height
string | number
-
Table height (enables vertical scroll)
striped
boolean
false
Show alternating row colors
hoverable
boolean
true
Show row hover effect
bordered
boolean
false
Show borders between cells
compact
boolean
false
Compact row height (deprecated, use size="small")
tableLayout
"auto" | "fixed"
'fixed'
Table layout algorithm
size
"small" | "large" | "medium"
'medium'
Table density/size
className
string
-
Optional class name
style
React.CSSProperties
-
Optional style
pagination
{ current: number; pageSize: number; total: number; onChange: (page: number) => void; onPageSizeChange?: (pageSize: number) => void; pageSizeOptions?: number[]; showSizeChanger?: boolean; }
-
Pagination config
onRowClick
((row: T, rowIndex: number) => void)
-
Row click handler
flush
boolean
false
Remove border and border-radius for embedding inside containers like Card
rowActions
((row: T, rowIndex: number) => React.ReactNode)
-
Floating row actions rendered on hover at the right edge of each row

Column

Prop
Type
Default
Description
key
string
Unique identifier for the column.
title
string
Header text.
width
string
CSS width value.
sortable
boolean
Enable sorting for this column.
sticky
boolean
Fix column to the left.
align
'left' | 'center' | 'right'
Text alignment.
cellVariant
string
Preset styles (avatar, money, date, id, actions, nowrap).
render
(val, row, index) => ReactNode
Custom cell renderer.

Showcase

Row Selection

Enable individual and bulk selection with simple props.

Row Selection
const [selectedKeys, setSelectedKeys] = useState<Key[]>(['1']);

<DataTable
  columns={columns}
  data={data}
  selectable
  selectedKeys={selectedKeys}
  onSelectionChange={setSelectedKeys}
/>

Sorting

Professional sorting with active states and dimmed inactive icons.

Name
Role
Revenue
David Brown
Admin
$22,100
Emily Davis
Editor
$15,800
John Smith
Admin
$12,500
Sarah Johnson
Editor
$8,900
Sorting
const [sortKey, setSortKey] = useState('revenue');
const [sortDir, setSortDir] = useState('desc');

const handleSort = (key, dir) => {
  setSortKey(key);
  setSortDir(dir);
};

<DataTable
  columns={[
    { key: 'name', title: 'Name', sortable: true },
    { key: 'revenue', title: 'Revenue', sortable: true, align: 'right' },
  ]}
  sortKey={sortKey}
  sortDirection={sortDir}
  onSortChange={handleSort}
/>

Pagination

Integrated pagination with page size controls.

Pagination
<DataTable
  columns={columns}
  data={displayData}
  pagination={{
    current: currentPage,
    pageSize: 10,
    total: totalItems,
    onChange: setCurrentPage,
  }}
/>

Loading State

A smooth spinner overlay blocks interaction while fetching data.

Loading State
<DataTable
  columns={columns}
  data={data}
  loading={isLoading}
/>

Sticky Columns

Fix columns to the left to maintain context while scrolling horizontally.

Sticky Columns
const columns = [
  { key: 'name', title: 'Name', width: '200px', sticky: true },
  { key: 'email', title: 'Email', width: '300px' },
  { key: 'status', title: 'Status', width: '150px', sticky: true },
];

<DataTable columns={columns} data={data} />

Floating Row Actions

When the last column is an actions column, DataTable can mirror it as floating row actions while the right edge is clipped. Hover a row before scrolling horizontally to see the actions stay accessible.

Floating Row Actions
<DataTable
  columns={[
    { key: 'name', title: 'Name', width: '220px' },
    { key: 'email', title: 'Email', width: '260px' },
    { key: 'role', title: 'Role', width: '140px' },
    {
      key: 'actions',
      title: '',
      width: '92px',
      cellVariant: 'actions',
      render: (_value, row) => (
        <Flex gap="4xs">
          <IconButton variant="tertiary" size="small" icon={<PenOutline />} aria-label={`Edit ${row.name}`} />
          <IconButton variant="tertiary" size="small" icon={<TrashOutline />} aria-label={`Delete ${row.name}`} />
        </Flex>
      ),
    },
  ]}
  data={data}
  rowKey="id"
/>

Contextual Actions

Render different actions based on row status or role. This example mixes text buttons and icon buttons inside the same floating action bar.

Contextual Actions
<DataTable
  rowActions={(row) => {
    if (row.role === 'Admin') {
      return (
        <Flex gap="4xs">
          <Button variant="secondary" size="small">Manage</Button>
          <IconButton variant="tertiary" size="small" icon={<SettingsOutline />} aria-label="Settings" />
        </Flex>
      );
    }
    return (
      <Flex gap="4xs">
        <Button variant="secondary" size="small">Review</Button>
        {row.status === 'pending' && (
          <Button variant="secondary" size="small">Approve</Button>
        )}
        <IconButton variant="tertiary" size="small" icon={<PenOutline />} aria-label="Edit" />
      </Flex>
    );
  }}
/>

Cell Variants

Use cellVariant to automatically format common data types (ID, Money, Date, etc.).

User
ID
Revenue
Last Active
J

John Smith

Admin

1
12500
15/03/2024, 10:00:00
S

Sarah Johnson

Editor

2
8900
14/03/2024, 11:30:00
M

Mike Wilson

Viewer

3
3200
13/03/2024, 09:15:00
E

Emily Davis

Editor

4
15800
12/03/2024, 14:45:00
Cell Variants
const columns = [
  { key: 'user', title: 'User', cellVariant: 'avatar' },
  { key: 'id', title: 'ID', cellVariant: 'id' },
  { key: 'total', title: 'Revenue', cellVariant: 'money' },
  { key: 'actions', title: '', cellVariant: 'actions' },
];

Sizes & Density

Choose the density that best fits your interface.

Sizes & Density
<DataTable size="small" ... />
<DataTable size="medium" ... />
<DataTable size="large" ... />

Style Variations

Combine different props to achieve the look you need.

Style Variations
<DataTable striped hoverable ... />
<DataTable bordered ... />
<DataTable emptyContent={<EmptyState />} ... />

On this page

Preview
Component API
Showcase
Row Selection
Sorting
Pagination
Loading State
Sticky Columns
Floating Row Actions
Contextual Actions
Cell Variants
Sizes & Density
Style Variations
Photonix UI - React Components, Templates & Figma Design System