Data Table

Data Table

A powerful and flexible data table component with sorting, filtering, pagination, and row selection.

Basic Table

A simple table with automatic sorting and pagination. Toggle the style options below to explore layout variants.

ID
Name
Email
Age
1Paul Kellylaura.martin@enterprise.net50
2Sharon Parkerjimmy.thomas@business.org32
3Edward Reyesmichael.stewart@enterprise.net50
4Linda Carterpatricia.lee908@example.com24
5Steven Gutierrezchristine.ramirez252@company.com23

Row Selection

Table with multiple row selection using checkboxes.

Name
Email
Role
Paul Kellylaura.martin@enterprise.netDeveloper
Sharon Parkerjimmy.thomas@business.orgModerator
Edward Reyesmichael.stewart@enterprise.netAnalyst
Linda Carterpatricia.lee908@example.comAdmin
Steven Gutierrezchristine.ramirez252@company.comModerator

Use arrow keys to navigate rows, and Enter/Space to toggle selection. Enable keyboard navigation via the checkbox above.

Custom Cell Templates

Use custom templates to render cells with badges, buttons, and other components.

Name
Status
Role
Actions
Paul Kelly
Pending
Developer
Sharon Parker
Suspended
Moderator
Edward Reyes
Inactive
Analyst
Linda Carter
Pending
Admin
Steven Gutierrez
Suspended
Moderator

Server-Side Data

Use the ServerData callback to load, sort, filter and paginate data on the server. The component passes a DataTableRequest with the current page, page size, sort column and search text. Returns DataTableResult with the page of items and total count.

ID
Customer
Product
Status
Amount
1Customer 1Gadget LiteShipped134.33
2Customer 2Device MaxDelivered395.55
3Customer 3Widget ProCancelled156.76
4Customer 4Gadget LitePending417.97
5Customer 5Device MaxShipped179.18
6Customer 6Widget ProDelivered440.40
7Customer 7Gadget LiteCancelled201.61
8Customer 8Device MaxPending462.82
9Customer 9Widget ProShipped224.04
10Customer 10Gadget LiteDelivered485.25

Infinite Scroll (Server-Side)

Set ItemsProvider to a DataTableVirtualProvider delegate. The component renders rows via Virtualize so only visible rows are in the DOM. The delegate receives StartIndex, Count, SortDescriptors, and SearchText — no page/pageSize math needed. Sorting and search trigger a virtualizer refresh automatically.

ID
Customer
Product
Status
Amount

Virtualize (Client-Side)

Set Virtualize=true to keep all data in memory but only render visible DOM rows. Search and sort still run client-side. Useful for large in-memory datasets (500–20k rows) where you don't want pagination.

ID
Customer
Product
Status
Amount

Column Pinning

Pin columns to the left or right edge so they stay visible while scrolling horizontally. Add Pinned="ColumnPinnedSide.Left" or Pinned="ColumnPinnedSide.Right" to any column. Set an explicit Width on pinned columns so offsets can be calculated correctly.

Name
Department
Title
Location
Manager
Start Date
Salary
Status
Actions

Alice Johnson

alice@acme.com

EngineeringSenior EngineerNew YorkCarol WhiteJan 2022$145,000
Active

Bob Smith

bob@acme.com

DesignUI/UX DesignerSan FranciscoCarol WhiteMar 2022$120,000
Active

Carol White

carol@acme.com

EngineeringEngineering ManagerNew YorkHenry BrownJun 2019$180,000
Active

David Kim

david@acme.com

ProductProduct ManagerAustinHenry BrownSep 2021$155,000
Active

Eva Martinez

eva@acme.com

SalesAccount ExecutiveChicagoFrank LeeFeb 2023$95,000
Active

Self Referencing Rows (Chart of Accounts)

Set ChildrenProperty to render a self-referencing hierarchy in-place. Rows expand and collapse with chevrons. When searching, ancestor rows containing matching descendants are automatically expanded. Combined here with column pinning to keep Account Name visible while scrolling across all the accounting columns.

Account Name
Code
Type
Description
Currency
Balance
Status
Actions
Assets1000
Asset
All asset accounts
Liabilities2000
Liability
All liability accounts
Equity3000
Equity
Owner's equity and retained earnings
Revenue4000
Revenue
All revenue and income accounts
Expenses5000
Expense
All operating and non-operating expense accounts

Column Resizing & Reordering

Enable Resizable to add drag handles on column headers for width adjustment. Enable Reorderable to let users drag columns into a new order — columns shift smoothly into place as you drag. Both work independently or together. Per-column Resizable/Reorderable overrides the table-level default.

Name
Department
Title
Location
Salary
Status
Alice JohnsonEngineeringSenior EngineerNew York$145,000
Active
Bob SmithDesignUI/UX DesignerSan Francisco$120,000
Active
Carol WhiteEngineeringEngineering ManagerNew York$180,000
Active
David KimProductProduct ManagerAustin$155,000
Active
Eva MartinezSalesAccount ExecutiveChicago$95,000
Active

Row Context Menu

Right-click any row to open a context menu scoped to that row. The RowContextMenu render fragment receives a DataTableRowMenuContext with the row's item, current selection, and visible column IDs. Use any ContextMenuItem, ContextMenuSeparator, or sub-menu components inside it.

Name
Department
Title
Salary
Status
Alice JohnsonEngineeringSenior Engineer$145,000
Active
Bob SmithDesignUI/UX Designer$120,000
Active
Carol WhiteEngineeringEngineering Manager$180,000
Active
David KimProductProduct Manager$155,000
Active
Eva MartinezSalesAccount Executive$95,000
Active

Sortable Row Reorder

Use AdditionalRowAttributes to attach data-sortable-id to each table row. Wrap the DataTable in a Sortable root and SortableContent, then add a drag handle column via CellTemplate.

Task
Assignee
Status
Design wireframesAlice
Done
Write unit testsBob
In Progress
Implement APICarol
To Do
Code reviewDavid
In Progress
Deploy to stagingEva
To Do

Global Search & Column Visibility

Search across all columns and toggle column visibility.

ID
Name
Email
Age
Role
Status
1Paul Kellylaura.martin@enterprise.net50Developer
Pending
2Sharon Parkerjimmy.thomas@business.org32Moderator
Suspended
3Edward Reyesmichael.stewart@enterprise.net50Analyst
Inactive
4Linda Carterpatricia.lee908@example.com24Admin
Pending
5Steven Gutierrezchristine.ramirez252@company.com23Moderator
Suspended
6Scott Floresjimmy.white@enterprise.net32Guest
Pending
7Donna Moralesmelissa.sanchez@business.org35Admin
Active
8John Stewartjason.brooks@company.com52Developer
Inactive
9Emily Morganmichael.miller@organization.com32Manager
Active
10Melissa Wilsonchristopher.wright779@company.com35Designer
Inactive

Empty State

Displays a message when there's no data to show.

No results found

Loading State

Shows a loading indicator while data is being fetched.

Name
Email
Role
Paul Kellylaura.martin@enterprise.netDeveloper
Sharon Parkerjimmy.thomas@business.orgModerator
Edward Reyesmichael.stewart@enterprise.netAnalyst
Linda Carterpatricia.lee908@example.comAdmin
Steven Gutierrezchristine.ramirez252@company.comModerator

Without Toolbar

A minimal table without the toolbar (no search or column visibility).

Name
Email
Age
Paul Kellylaura.martin@enterprise.net50
Sharon Parkerjimmy.thomas@business.org32
Edward Reyesmichael.stewart@enterprise.net50
Linda Carterpatricia.lee908@example.com24
Steven Gutierrezchristine.ramirez252@company.com23

Custom Toolbar Actions

Add custom action buttons to the toolbar.

Name
Email
Role
Paul Kellylaura.martin@enterprise.netDeveloper
Sharon Parkerjimmy.thomas@business.orgModerator
Edward Reyesmichael.stewart@enterprise.netAnalyst
Linda Carterpatricia.lee908@example.comAdmin
Steven Gutierrezchristine.ramirez252@company.comModerator

Accessibility Features

Built-in accessibility features following WAI-ARIA design patterns.

ARIA Attributes

  • role="grid" for screen readers
  • aria-sort indicates column sort direction
  • aria-selected indicates row selection state
  • aria-label on checkboxes for selection
  • Focusable rows with visible focus indicator

Keyboard Shortcuts

Navigate and interact with the table using keyboard.

Navigate to next row ArrowDown
Navigate to previous row ArrowUp
Toggle row selection
Enter / Space
Sort column (click header) Click

DataTable API

DataTable component parameters and their types.

Prop Type Default Description
Data IEnumerable<TData> Required. The data source for the table.
Columns RenderFragment? null Slot for DataTableColumn child components.
SelectionMode DataTableSelectionMode None Row selection mode: None, Single, Multiple.
SelectedItems IReadOnlyCollection<TData> [ ] Currently selected items. Use @bind-SelectedItems for two-way binding.
EnableKeyboardNavigation bool true Arrow key navigation and Enter/Space row selection.
ShowToolbar bool true Whether to show the toolbar (search + column visibility).
ShowPagination bool true Whether to show pagination controls.
ColumnsVisibility bool true Whether to show the column visibility toggle button in the toolbar.
IsLoading bool false Shows a loading indicator instead of table content.
InitialPageSize int 5 The initial number of rows per page.
PageSizes int[] [5,10,20,50,100] Available page size options in the pagination selector.
Dense bool true Compact cell padding (header h-9, body py-2 px-4). When false, uses h-12 / p-4.
HeaderBackground bool true Applies bg-muted/50 to the header row.
HeaderBorder bool false Vertical dividers between header cells (divide-x divide-border).
CellBorder bool false Vertical dividers between body cells (divide-x divide-border).
HeaderClass string? null Extra CSS classes on the <thead> element.
HeaderRowClass string? null Extra CSS classes on the header <tr>.
BodyRowClass string? null Extra CSS classes on each body <tr>.
ToolbarActions RenderFragment? null Custom action buttons rendered inside the toolbar.
EmptyTemplate RenderFragment? null Custom content shown when the table has no rows.
LoadingTemplate RenderFragment? null Custom content shown when IsLoading is true.
AriaLabel string? null ARIA label applied to the <table> element.
Class string? null Extra CSS classes on the outer container div.
ServerData Func<DataTableRequest, Task<DataTableResult<TData>>>? null Server-side paged data callback. Request carries Page, PageSize, SortDescriptors, and SearchText.
ItemsProvider DataTableVirtualProvider<TData>? null Server-side virtualised provider for infinite scroll. Request carries StartIndex, Count, SortDescriptors, SearchText, and CancellationToken. Overrides Data and ServerData when set.
Virtualize bool false Client-side DOM-windowing via Virtualize. All rows stay in memory; only visible nodes are rendered. Pagination is hidden.
ItemHeight float 40 Row height in px passed to the virtualizer as ItemSize. Must match your actual row height when Virtualize=true or ItemsProvider is set.
Height string "400px" CSS height of the scroll container. Required when Virtualize=true or ItemsProvider is set.
VirtualizeOverscanCount int 3 Extra rows rendered beyond the viewport to reduce blank flicker during fast scrolling.
OnSort EventCallback<(string, SortDirection)> Fires when the user changes the sort column or direction.
OnFilter EventCallback<string?> Fires when the global search value changes.
PreprocessData Func<IEnumerable<TData>, Task<IEnumerable<TData>>>? null Async hook to transform data before filtering and sorting.
ChildrenProperty Func<TData, IEnumerable<TData>?>? null Returns child items for each row, activating tree mode. Children render inline with depth indentation. Incompatible with ItemsProvider (virtualised server mode).
LoadChildrenAsync Func<TData, Task<IEnumerable<TData>>>? null Lazy async child loader — called on first expand of a node. Activates tree mode. Use with HasChildrenField to control whether the expander is shown before loading.
HasChildrenField Func<TData, bool>? null Hints whether a node has children without loading them. In lazy mode, the expander is shown for all nodes unless this is provided.
ValueField Func<TData, string>? null Returns a stable unique key per item for tracking expanded state. Strongly recommended in tree mode; falls back to RuntimeHelpers.GetHashCode when omitted.
ExpandedValues HashSet<string>? null Two-way bindable set of expanded row keys. Use @bind-ExpandedValues to persist or restore the expand state across renders.
Resizable bool false Adds drag handles on column headers so users can adjust widths at runtime. Activates table-layout:fixed automatically. Per-column Resizable on DataTableColumn overrides this.
MinColumnWidth int 80 Minimum column width in pixels enforced during drag-to-resize.
SyncWidthOnResize bool false When true, the table's total width is updated to match the sum of all column widths during and after resize. Pair with TableContainerClass="border-0" for the best visual result.
Striped bool false Enables alternating row background (zebra striping).
StripeClass string? odd:bg-muted/30 Tailwind class for the stripe. Override to change colour or swap odd/even, e.g. even:bg-muted/30.
OnColumnResize EventCallback<(string, string)> Fires when the user finishes resizing a column. Provides (ColumnId, NewCssWidth).
Reorderable bool false Lets users drag column headers to reorder them. Columns animate into place as you drag. Pinned and selection columns are excluded. Per-column Reorderable overrides this.
OnColumnReorder EventCallback<(string, int)> Fires when the user drops a column into a new position. Provides (ColumnId, NewIndex).
RowContextMenu RenderFragment<DataTableRowMenuContext<TData>>? null Template for the context menu shown on row right-click. Receives DataTableRowMenuContext with Item, SelectedItems, and VisibleColumns.
AdditionalRowAttributes Func&lt;TData, Dictionary&lt;string, object&gt;?&gt;? null Callback supplying extra HTML attributes per body <tr>. E.g. supply data-sortable-id for Sortable row reorder, or arbitrary data-* / aria-* attributes.

DataTableColumn API

DataTableColumn parameters and their types.

Prop Type Default Description
Property Func<TData, TValue> Required. Expression that returns the column value from a row.
Header string Required. Column header label text.
Id string? null Unique column ID. Auto-generated from Header when omitted.
Sortable bool false Whether clicking the header sorts by this column.
Filterable bool false Whether this column is searched by the global search filter.
Alignment ColumnAlignment Left Cell alignment: Left, Center, Right.
CellTemplate RenderFragment<TData>? null Custom cell render template. Receives the row item as context.
Visible bool true Whether the column is shown. Can be toggled via the column visibility menu.
Width string? null Fixed column width (e.g. "200px", "20%").
MinWidth string? null Minimum column width CSS value.
MaxWidth string? null Maximum column width CSS value.
CellClass string? null Extra CSS classes on every body cell in this column.
HeaderClass string? null Extra CSS classes on this column's header cell.
Pinned ColumnPinnedSide None Sticks the column to the Left or Right edge during horizontal scroll. A shadow separator marks the boundary. Requires an explicit px Width for reliable offset calculation.
Resizable bool? null Per-column resize override. null inherits the table-level Resizable setting.
Reorderable bool? null Per-column reorder override. null inherits the table-level Reorderable setting. Pinned columns and the selection column are always excluded.

Reconnecting...

Attempting to rejoin the server

Connection Lost

Retrying in seconds

Connection Failed

Failed to rejoin the server.
Please retry or reload the page.

Session Paused

The session has been paused by the server

Resume Failed

Failed to resume the session.
Please reload the page.