Skip to content

Data Grid

Data Grid is a pure logic provider: it renders no element at all, and cascades a DataGridContext<TItem> that the consumer’s own table markup reads. It owns five independent state slices, each following the controlled/uncontrolled contract (X + XChanged / @bind-X, or DefaultX): sorting, global filter, pagination, row selection and column visibility. A slice only becomes controlled when a non-null value is supplied, so a present-but-null bind stays uncontrolled instead of freezing; XChanged still fires as an observer in the uncontrolled case.

Derivation order is global filter, then sort, then page. Sorting is single-column and cycles ascending, descending, cleared. The default global filter stringifies each column’s Accessor value and matches case-insensitively, unless that column supplies its own FilterFn. Columns without an Accessor are skipped by both sort and filter.

@using Navius.Primitives.Components.DataGrid
<NaviusDataGrid TItem="Person" Items="_people" Columns="_columns">
@* Consumer markup reads the cascaded DataGridContext<Person>. *@
</NaviusDataGrid>

Owns every state slice and cascades a DataGridContext<TItem>. Renders no DOM of its own.

Prop Type Default Description
Items IEnumerable<TItem>? - The rows. Filtering, sorting and paging derive from this; pass a stable reference.
Columns IReadOnlyList<DataGridColumn<TItem>>? - Column descriptors: Key, Header, Accessor, CellTemplate, Sortable, EnableHiding, FilterFn.
RowKey Func<TItem, object>? - Row identity for selection. Defaults to the row object itself.
Sorting DataGridSort? null Controlled single-column sort state. Pair with SortingChanged (@bind-Sorting).
SortingChanged EventCallback<DataGridSort?> - Fires when the sort state should change.
DefaultSorting DataGridSort? null Initial sort when uncontrolled. Defaults to DataGridSort.None.
GlobalFilter string? null Controlled global filter text. Pair with GlobalFilterChanged (@bind-GlobalFilter).
GlobalFilterChanged EventCallback<string?> - Fires when the global filter should change.
DefaultGlobalFilter string? null Initial global filter when uncontrolled. Defaults to empty.
Pagination DataGridPagination? null Controlled page index and page size. Pair with PaginationChanged (@bind-Pagination).
PaginationChanged EventCallback<DataGridPagination?> - Fires when pagination should change.
DefaultPagination DataGridPagination? null Initial pagination when uncontrolled. Defaults to page 0, size 10.
RowSelection IEnumerable<object>? null Controlled set of selected row keys. Pair with RowSelectionChanged (@bind-RowSelection).
RowSelectionChanged EventCallback<IEnumerable<object>> - Fires when the selection should change.
DefaultRowSelection IEnumerable<object>? null Initial selected row keys when uncontrolled.
ColumnVisibility IEnumerable<string>? null Controlled set of HIDDEN column keys. Pair with ColumnVisibilityChanged (@bind-ColumnVisibility).
ColumnVisibilityChanged EventCallback<IEnumerable<string>> - Fires when column visibility should change.
DefaultColumnVisibility IEnumerable<string>? null Initial hidden column keys when uncontrolled.
ChildContent RenderFragment? - The consumer’s table markup.

Because the Root renders no markup, the contract the consumer binds against is the cascaded DataGridContext<TItem> rather than a part tree. A part can inherit DataGridPart<TItem> to consume it and re-render on every change.

Member Type Description
Columns IReadOnlyList<DataGridColumn<TItem>> The declared columns, in order.
VisibleColumns IReadOnlyList<DataGridColumn<TItem>> The columns not currently hidden, in declared order.
AllFilteredRows IReadOnlyList<TItem> Rows after global filter and sort, before paging.
PageRows IReadOnlyList<TItem> The rows on the current page.
FilteredCount int Total rows matching the current global filter.
PageCount int Number of pages for the filtered rows; 0 when there are none.
Sorting / GetSort(columnKey) DataGridSort / SortDirection The sort state, globally or for one column.
ToggleSortAsync(columnKey) Task Cycles that column ascending, descending, cleared. No-op when the column is not Sortable.
GlobalFilter / SetGlobalFilterAsync(value) string / Task The filter text; null is treated as empty.
Pagination, PageIndex, PageSize DataGridPagination, int, int The current page state.
CanPrev / CanNext bool Whether a previous or next page exists.
PrevPageAsync() / NextPageAsync() / SetPageIndexAsync(index) Task Page navigation.
GetRowKey(item) object The selection identity for a row.
SelectedKeys / SelectedCount / IsRowSelected(key) IReadOnlyCollection<object> / int / bool The current row selection.
ToggleRowSelectedAsync(key) Task Toggles one row’s selection.
IsAllPageSelected / IsSomePageSelected bool Whether all, or only some, rows on the page are selected (the indeterminate header checkbox).
ToggleAllOnPageAsync() Task Selects every row on the page, or clears them when all are already selected.
IsColumnVisible(columnKey) / ToggleColumnVisibleAsync(columnKey) bool / Task Column visibility. Toggling is a no-op for columns with EnableHiding = false.
Changed event Func<Task>? Raised after any state change so subscribed parts re-render.

Data Grid renders no element, so it emits no roles, no ARIA attributes and no data-* attributes, and it implements no APG pattern of its own: the table semantics (role="grid" or native table markup, aria-sort on sortable headers, the indeterminate select-all checkbox) belong to the consumer’s markup, which reads them from the cascaded context. Having no DOM, it also owns no keyboard map. The state machine is covered by the Playwright browser test suite (filtering, header sorting, pagination and column hiding), and the page rendering it is gated by axe-core in CI.