ComponentsDisplayDataTable

DataTable

DataTable presents structured enterprise data for scanning, comparison, sorting, and selection while preserving native table semantics.

Generic APISortingSelectionSticky header3 densitiesResponsive

Overview

Use DataTable when people need to compare structured values across many records and act on individual or selected rows.

Enterprise projects

Live preview

Sortable headers, selection, status, and row actions support a common operational workflow.

Enterprise projects
OwnerStatusUpdatedActions
Audit reportingPRJ-1019Sofia MartinActive2026-08-05
Billing controlsPRJ-1038Noah WilliamsAt risk2026-08-12
Enterprise migrationPRJ-1042Maya ChenActive2026-08-14
Identity refreshPRJ-1024Aarav ShahComplete2026-08-08

0 of 4 rows selected

ProjectsTable.tsx
tsx
import { DataTable, type DataTableColumn } from 'omverse-ui'
 
const columns: DataTableColumn<Project>[] = [
{ id: 'project', header: 'Project', accessor: 'project', sortable: true },
{ id: 'owner', header: 'Owner', accessor: 'owner', sortable: true },
{ id: 'status', header: 'Status', cell: (row) => <Badge>{row.status}</Badge> },
]
 
<DataTable
columns={columns}
data={projects}
getRowId={(row) => row.id}
caption="Enterprise projects"
variant="bordered"
/>

Anatomy

A data table combines a caption, column headers, rows, cells, optional selection, status, and row actions.

Enterprise projects
☐ Project  Owner  Status  Actions
☐ Migration  Maya  Active  Open
12345
  1. 1
    Header rowRequired

    Names columns and exposes sorting state.

  2. 2
    Data rowRequired

    Represents one record with a stable identifier.

  3. 3
    CellRequired

    Displays one value or a contextual action.

  4. 4
    Selection control

    Selects one row or all eligible rows.

  5. 5
    CaptionRequired

    Programmatically names the table.

When to use

Choose DataTable for structured records where column alignment materially improves comparison.

Recommended

  • Compare records

    Use when values share a consistent schema and people scan across columns.

  • Manage operational data

    Support sorting, selection, status, and row-level actions.

  • Handle changing data volumes

    Combine with filtering and Pagination at the workflow level.

When not to use

Prefer simpler structures when records are sparse, highly visual, or do not share comparable fields.

Avoid

  • Do not use for simple key-value details

    Use a description list or structured detail view for one record.

  • Do not use for media-first collections

    Use Card or List when imagery and narrative content drive recognition.

  • Do not force every action into a column

    Keep rare actions in an accessible row menu.

Variants

Surface and density variants adapt the same semantic structure to hierarchy and information volume.

Plain

Default for tables already contained by a page section.

Bordered

Creates a clear boundary on open surfaces.

Striped

Supports horizontal tracking across wide tables.

Density

Small, medium, and large preserve a minimum 44px interaction target.

States

Table state explains data availability, row interaction, selection, and active sorting.

StateTriggerVisual responseInteraction
DefaultData is availableHeaders and rows at selected densityCells and actions can be scanned
HoverPointer enters a rowRow surface is emphasizedSupports horizontal tracking
SelectedSelection checkbox changesSelection control and row surface updateBulk actions can consume selected IDs
SortedSortable header is activatedDirection icon and aria-sort updateRows reorder by the active column
LoadingData request is pendingAnnounced loading rowDuplicate operations are prevented
Empty or errorNo results or request failureMessage spans the table widthRecovery guidance remains available

Behavior

Sorting and selection support controlled and uncontrolled usage while row identity remains stable across reordering.

Sort cycle

Sortable headers cycle ascending, descending, and unsorted.

Selection

Select-all affects eligible rows and preserves disabled-row state.

Overflow

Wide tables scroll horizontally without collapsing column meaning.

Sticky header

Headers remain visible when a containing region scrolls vertically.

Accessibility

DataTable uses native table elements so header relationships and navigation remain available to browsers and assistive technology.

KeyAction
TabMoves through sortable headers, selection controls, and row actions.
EnterSpaceActivates the focused sort, selection, or row action.
ShiftTabMoves to the previous interactive table control.
  • Provide a descriptive caption.
  • Use th with scope="col" for every header.
  • Expose active sorting with aria-sort.
  • Give selection and row actions unique accessible names.
  • Do not communicate status or selection with color alone.
  • Keep horizontal overflow keyboard reachable.
  • Preserve at least 44px interactive targets.

Content guidelines

Headers and cells should make comparison fast without sacrificing precision.

Use concise headers

Name the value rather than describing the column.

ExampleUpdated

Keep formats consistent

Use one date, currency, number, and status format within a column.

Example14 Aug 2026

Align by data type

Start-align text and end-align comparable numeric values.

Example₹48,200

Explain empty results

Differentiate no data from no filter matches and loading failure.

ExampleNo projects match these filters.

Examples

Controlled sorting and selection let application state coordinate bulk actions, filters, and persistence.

Interactive selection and sorting

Live preview

Select rows and sort the Project column in the live semantic preview.

Enterprise projects
OwnerStatusUpdatedActions
Audit reportingPRJ-1019Sofia MartinActive2026-08-05
Billing controlsPRJ-1038Noah WilliamsAt risk2026-08-12
Enterprise migrationPRJ-1042Maya ChenActive2026-08-14
Identity refreshPRJ-1024Aarav ShahComplete2026-08-08

0 of 4 rows selected

ControlledProjectsTable.tsx
tsx
const [selected, setSelected] = useState<readonly Key[]>([])
const [sort, setSort] = useState<DataTableSortState | null>(null)
 
<DataTable
columns={columns}
data={projects}
getRowId={(row) => row.id}
caption="Enterprise projects"
selectable
selectedRowIds={selected}
onSelectionChange={setSelected}
sort={sort}
onSortChange={setSort}
stickyHeader
/>

Props / API

DataTable is generic over the row type and extends div attributes for its responsive container.

Props

PropTypeDefaultDescription
columnsreadonly DataTableColumn<T>[]requiredTyped header, accessor, cell, alignment, and sorting definitions.
datareadonly T[]requiredRows displayed by the table.
getRowId(row: T, index: number) => KeyrequiredReturns a stable identifier for each row.
captionstringrequiredAccessible name rendered as a visually hidden caption.
variant'plain' | 'bordered' | 'striped''plain'Sets the table surface treatment.
size'sm' | 'md' | 'lg''md'Controls row height, padding, and type size.
stickyHeaderbooleanfalseKeeps headers visible during vertical scrolling.
selectablebooleanfalseAdds select-all and row-selection checkboxes.
selectedRowIdsreadonly Key[]undefinedControlled selected row identifiers.
defaultSelectedRowIdsreadonly Key[][]Initial selection for uncontrolled usage.
onSelectionChange(rowIds: readonly Key[]) => voidundefinedRuns whenever selection changes.
isRowDisabled(row: T) => booleanundefinedPrevents selection for unavailable rows.
sortDataTableSortState | nullundefinedControlled sort column and direction.
defaultSortDataTableSortState | nullnullInitial sort for uncontrolled usage.
onSortChange(sort: DataTableSortState | null) => voidundefinedRuns whenever sorting changes.
loadingbooleanfalseReplaces rows with an announced loading state.
emptyStateReactNode'No data available.'Content displayed when data is empty.
errorStateReactNodeundefinedAssertive content displayed when loading fails.
rowClassName(row: T) => string | undefinedundefinedAdds a class based on row data.