Data grid
A data grid presents rows of records that readers sort, select, and move through by keyboard, such as an order list of thousands. Its navigation mode sets whether the arrow keys step between cells or whole rows, and it stays fast on thousands of rows. The grids below are live, each on its own theme.
Reference docs
Choosing a way to show a collection
Three components show many items at once. Each suits a different job:
- List: a column of items to scan and act on, such as contacts or settings.
- Data table: read-only rows and columns to compare, such as an invoice or a price table.
- Data grid: many rows the reader sorts, selects, and moves through by keyboard, such as an order list of thousands.
One job belongs elsewhere. Splitting a long collection into pages is a paginator, used alongside any of these.
Choosing a variant
Four variants set how much a data grid stands out from the page, from most to least:
- Filled: a grid that is the main content of a page, such as a dashboard's order list, on the primary container color.
- Tonal: a grid that shares a screen with a filled element, on the secondary container color.
- Surface: a grid that needs its own ground, such as an admin list in a panel of another color, on the lowest surface container color.
- Standard: the default, with no fill, for a grid that sits directly on the page or inside a card and takes that container's color.
Built in
gives the grid one tab stop, then arrow keys that move between cells or between rows.navigation-mode- A column with
sortablesorts on a click or on Enter, cycles none, ascending, and descending, and announces the result. selects one cell or row at a time and fires an event for each selection and deselection.selectable keeps a list of thousands of rows light.virtualize keeps your place in a long list, so a sort or refresh does not send the reader back to the top.unique-identifier- Loads and errors are announced to a screen reader without any markup of your own.
Using data grids well
- Keep column titles short, and give numeric columns a numeric
typeso their values line up on the right. - Give a
currencycolumn its currency code, such as"currency": "EUR". The grid's decides how a price is written, not which currency it is in, and a column with no code shows plain numbers.locale - Design for one selected row or cell at a time; the grid has no checkbox column or select-all header.
- Put paging controls in a footer with a rows-per-page choice and a position readout such as "1–10 of 100", using a paginator that slices the data you pass in.
- Clear or reapply the selection when the page changes, because it points at an index and not at a record.
These rules follow Material 3 Expressive's guidance for data tables, on material.io.
Variants
variantfilled, tonal, surface, or standard. Omit it and the grid takes the variant from your style configuration, which is standard unless you have changed it. The overview says when to choose each.
Caption position
A child in the default slot is the grid's caption and names it for screen readers. caption-positionleading) or after them (trailing). Omit it and the caption takes the position from your style configuration, which is leading unless you have changed it.
Density
density0 to 4. Higher values draw shorter rows, from 52 pixels at 0 to 36 pixels at 4, so a screen holds more records. Omit it and the grid takes the density from your style configuration, which is 0 unless you have changed it.
Rows and borders
stripedshow-column-dividersborderless
Navigation mode
navigation-modecell mode, the default, every cell is a stop and the arrows move in four directions. In row mode, the arrows move between whole rows only. The Accessibility tab lists every key. Click a grid, then use the arrow keys.
Selection
Set selectablecell-select, cell-deselect, row-select, or row-deselect, and the demo reports the last one.
Data and columns
itemscolumnsfield, title, and options for each column. With no columnsunique-identifiergrid-label
Sorting
A column with sortable sorts when its header is activated, cycling none, ascending, descending, and none. One column sorts at a time, the input array is never changed, and each change fires sort-change. Code can call sort() and read sortDescriptors
Large data sets
Set virtualizeoverscan-countitemsProvider
Properties
| Property | Attribute | Type | Description |
|---|---|---|---|
borderless | borderless | booleandefault false | Removes the outer frame, including the header's underline. Row and cell dividers stay visible. See Rows and borders. |
captionPosition | caption-positionleading, trailing | CaptionPositionCaptionPosition.Leading, .Trailingdefault CaptionPosition.Leading, from the style configuration | The caption's position in relation to the component. See Caption position. |
columns | ColumnDefinition[]default [] | Column definitions. If not provided, columns will be auto-generated from data (if possible). See Data and columns. | |
density | density0, 1, 2, 3, 4 | DensityDensity.Standard, .Dense1, .Dense2, .Dense3, .Dense4default Density.Standard, from the style configuration | How tightly rows are spaced, from 0, the roomiest, to 4, the tightest. See Density. |
gridLabel | grid-label | string | The name a screen reader announces for the component. See Data and columns. |
items | TItem[]default [] | Data source as an array of objects. Use this for client-side data. See Data and columns. | |
itemsProvider | GridItemsProvider<TItem> | Async function to provide data. Use this for server-side operations (filtering, sorting, paging). Ignored while items has rows. See Large data sets. | |
locale | locale | string | The BCP 47 locale, such as de-DE, the component writes numbers and dates in, and translates its built-in screen-reader text into where it has a translation. Empty means the application's configured locale (AppConfiguration.locale), or the browser's preferred language when it sets none. |
navigationMode | navigation-modecell, row | GridNavigationModeGridNavigationMode.Cell, .Rowdefault GridNavigationMode.Cell | Sets how the arrow keys move focus: cell by cell in all four directions, or row by row up and down. It works independently of selectable. See Navigation mode. |
overscanCount | overscan-count | numberdefault 3 | How many rows beyond the visible ones are fetched ahead of scrolling. Keep it small to avoid over-fetching from the server. See Large data sets. |
selectable | selectable | booleandefault false | Whether selection is enabled. When true, cells or rows (depending on navigationMode) can be selected by click or Enter/Space, and a screen reader announces the selection. See Selection. |
showColumnDividers | show-column-dividers | booleandefault false | Shows vertical dividers between columns, which helps tell columns apart when there are many. See Rows and borders. |
sortDescriptorsread-only | SortDescriptor[] | The current sort, ordered by precedence, or an empty array when unsorted. Changing the returned array does not change the sort. See Sorting. | |
striped | striped | booleandefault false | Shades alternate rows. See Rows and borders. |
uniqueIdentifier | unique-identifier | string | The name of a field whose value identifies a row. Required: without it, the grid cannot restore keyboard focus to the same row after a sort, filter or page change, so it drops focus. See Data and columns. |
variant | variantfilled, standard, surface, tonal | TableVariantTableVariant.Filled, .Standard, .Surface, .Tonaldefault TableVariant.Standard, from the style configuration | The component's color scheme. filled uses the primary container color for high emphasis, tonal the secondary container color for medium emphasis, surface the lowest surface container color, and standard no fill, taking the color of whatever the table sits on. Unset, it comes from the style configuration's defaultTableVariant, which ships as standard. See Variants. |
virtualize | virtualize | booleandefault false | Shows only the rows in view, for large datasets. Every row must be the same height. See Large data sets. |
Slots
| Slot | Description |
|---|---|
| (default) | Default slot for caption content. Caption position controlled by captionPosition property. |
Events
| Event | Type | Detail | Description |
|---|---|---|---|
cell-select | CellSelectEvent | CellSelectEventDetail<TItem> | Dispatched when a cell becomes selected (cell navigation mode, selectable = true). It bubbles and is composed. |
cell-deselect | CellDeselectEvent | CellDeselectEventDetail<TItem> | Dispatched when a cell becomes deselected (cell navigation mode, selectable = true). It bubbles and is composed. |
row-select | RowSelectEvent | RowSelectEventDetail<TItem> | Dispatched when a row becomes selected (row navigation mode, selectable = true). It bubbles and is composed. |
row-deselect | RowDeselectEvent | RowDeselectEventDetail<TItem> | Dispatched when a row becomes deselected (row navigation mode, selectable = true). It bubbles and is composed. |
sort-change | SortChangeEvent | SortChangeEventDetail | Dispatched when the sort state changes (a sortable column header is activated or sort() is called). It bubbles and is composed. |
cell-activate | CellActivateEvent | CellActivateEventDetail<TItem> | Dispatched when a control rendered by ColumnDefinition.actionLabel/actionHref is activated — by pointer, Enter, or Space. It bubbles and is composed. |
A sort clears the selection and fires the matching deselect event. Selection is by position, so new items
The column options that raise cell-activate are provisional and carry no compatibility promise.
Methods
| Method | Returns | Description |
|---|---|---|
sort(field: string, direction?: string) | void | Programmatically sorts by a column field. direction omitted = cycle from the column's current state exactly as a user activation would. No-op (with a console warning) if the field is unknown or the column is not sortable. Fires sort-change like a user activation. |
Props
| Prop | Type | Description |
|---|---|---|
borderless | booleandefault false | Removes the outer frame, including the header's underline. Row and cell dividers stay visible. See Rows and borders. |
captionPosition | CaptionPositionTypeCaptionPosition.Leading, .Trailingdefault CaptionPosition.Leading, from the style configuration | The caption's position in relation to the component. See Caption position. |
columns | ColumnDefinition[]default [] | Column definitions. If not provided, columns will be auto-generated from data (if possible). See Data and columns. |
density | DensityTypeDensity.Standard, .Dense1, .Dense2, .Dense3, .Dense4default Density.Standard, from the style configuration | How tightly rows are spaced, from 0, the roomiest, to 4, the tightest. See Density. |
gridLabel | string | The name a screen reader announces for the component. See Data and columns. |
items | TItem[]default [] | Data source as an array of objects. Use this for client-side data. See Data and columns. |
itemsProvider | GridItemsProvider<TItem> | Async function to provide data. Use this for server-side operations (filtering, sorting, paging). Ignored while items has rows. See Large data sets. |
locale | string | The BCP 47 locale, such as de-DE, the component writes numbers and dates in, and translates its built-in screen-reader text into where it has a translation. Empty means the application's configured locale (AppConfiguration.locale), or the browser's preferred language when it sets none. |
navigationMode | GridNavigationModeTypeGridNavigationMode.Cell, .Rowdefault GridNavigationMode.Cell | Sets how the arrow keys move focus: cell by cell in all four directions, or row by row up and down. It works independently of selectable. See Navigation mode. |
overscanCount | numberdefault 3 | How many rows beyond the visible ones are fetched ahead of scrolling. Keep it small to avoid over-fetching from the server. See Large data sets. |
selectable | booleandefault false | Whether selection is enabled. When true, cells or rows (depending on navigationMode) can be selected by click or Enter/Space, and a screen reader announces the selection. See Selection. |
showColumnDividers | booleandefault false | Shows vertical dividers between columns, which helps tell columns apart when there are many. See Rows and borders. |
sortDescriptorsread-only (ref) | SortDescriptor[] | The current sort, ordered by precedence, or an empty array when unsorted. Changing the returned array does not change the sort. See Sorting. |
striped | booleandefault false | Shades alternate rows. See Rows and borders. |
uniqueIdentifier | string | The name of a field whose value identifies a row. Required: without it, the grid cannot restore keyboard focus to the same row after a sort, filter or page change, so it drops focus. See Data and columns. |
variant | TableVariantTypeTableVariant.Filled, .Standard, .Surface, .Tonaldefault TableVariant.Standard, from the style configuration | The component's color scheme. filled uses the primary container color for high emphasis, tonal the secondary container color for medium emphasis, surface the lowest surface container color, and standard no fill, taking the color of whatever the table sits on. Unset, it comes from the style configuration's defaultTableVariant, which ships as standard. See Variants. |
virtualize | booleandefault false | Shows only the rows in view, for large datasets. Every row must be the same height. See Large data sets. |
Children
| Child | Description |
|---|---|
children | Default slot for caption content. Caption position controlled by captionPosition prop. |
Events
| Prop | Argument | Description |
|---|---|---|
onCellSelect | CellSelectEvent<TItem> | Dispatched when a cell becomes selected (cell navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
onCellDeselect | CellDeselectEvent<TItem> | Dispatched when a cell becomes deselected (cell navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
onRowSelect | RowSelectEvent<TItem> | Dispatched when a row becomes selected (row navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
onRowDeselect | RowDeselectEvent<TItem> | Dispatched when a row becomes deselected (row navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
onSortChange | SortChangeEvent | Dispatched when the sort state changes (a sortable column header is activated or sort() is called). It bubbles and is composed. Its detail carries column, direction, and sortDescriptors. |
onCellActivate | CellActivateEvent<TItem> | Dispatched when a control rendered by ColumnDefinition.actionLabel/actionHref is activated — by pointer, Enter, or Space. It bubbles and is composed. Its detail carries item, rowIndex, field, columnIndex, value, and originalEvent. |
A sort clears the selection and fires the matching deselect event. Selection is by position, so new items
The column options that raise cell-activate are provisional and carry no compatibility promise.
Methods
Call these on the element the ref holds.
| Method | Returns | Description |
|---|---|---|
sort(field: string, direction?: string) | void | Programmatically sorts by a column field. direction omitted = cycle from the column's current state exactly as a user activation would. No-op (with a console warning) if the field is unknown or the column is not sortable. Fires sort-change like a user activation. |
Parameters
| Parameter | Type | Description |
|---|---|---|
Borderless | bool?default false | Removes the outer frame, including the header's underline. Row and cell dividers stay visible. See Rows and borders. |
CaptionPosition | CaptionPosition?CaptionPosition.Leading, .Trailingdefault CaptionPosition.Leading, from the style configuration | The caption's position in relation to the component. See Caption position. |
Columns | IEnumerable<ColumnDefinition>?default [] | Column definitions. If not provided, columns will be auto-generated from data (if possible). See Data and columns. |
Density | Density?Density.Standard, .Dense1, .Dense2, .Dense3, .Dense4default Density.Standard, from the style configuration | How tightly rows are spaced, from 0, the roomiest, to 4, the tightest. See Density. |
GridLabel | string? | The name a screen reader announces for the component. See Data and columns. |
Items | IEnumerable<TItem>?default [] | Data source as an array of objects. Use this for client-side data. See Data and columns. |
ItemsProvider | GridItemsProvider<TItem>? | Async function to provide data. Use this for server-side operations (filtering, sorting, paging). Ignored while Items has rows. See Large data sets. |
Locale | string? | The BCP 47 locale, such as de-DE, the component writes numbers and dates in, and translates its built-in screen-reader text into where it has a translation. Empty means the application's configured locale (AppConfiguration.locale), or the browser's preferred language when it sets none. |
NavigationMode | GridNavigationMode?GridNavigationMode.Cell, .Rowdefault GridNavigationMode.Cell | Sets how the arrow keys move focus: cell by cell in all four directions, or row by row up and down. It works independently of Selectable. See Navigation mode. |
OverscanCount | int?default 3 | How many rows beyond the visible ones are fetched ahead of scrolling. Keep it small to avoid over-fetching from the server. See Large data sets. |
Selectable | bool?default false | Whether selection is enabled. When true, cells or rows (depending on NavigationMode) can be selected by click or Enter/Space, and a screen reader announces the selection. See Selection. |
ShowColumnDividers | bool?default false | Shows vertical dividers between columns, which helps tell columns apart when there are many. See Rows and borders. |
Striped | bool?default false | Shades alternate rows. See Rows and borders. |
UniqueIdentifier | string? | The name of a field whose value identifies a row. Required: without it, the grid cannot restore keyboard focus to the same row after a sort, filter or page change, so it drops focus. See Data and columns. |
Variant | TableVariant?TableVariant.Filled, .Standard, .Surface, .Tonaldefault TableVariant.Standard, from the style configuration | The component's color scheme. filled uses the primary container color for high emphasis, tonal the secondary container color for medium emphasis, surface the lowest surface container color, and standard no fill, taking the color of whatever the table sits on. Unset, it comes from the style configuration's defaultTableVariant, which ships as standard. See Variants. |
Virtualize | bool?default false | Shows only the rows in view, for large datasets. Every row must be the same height. See Large data sets. |
Render fragments
| Parameter | Type | Description |
|---|---|---|
ChildContent | RenderFragment? | Default slot for caption content. Caption position controlled by CaptionPosition parameter. |
Event callbacks
| Parameter | Type | Description |
|---|---|---|
OnCellSelect | EventCallback<CellSelectEventArgs<TItem>> | Dispatched when a cell becomes selected (cell navigation mode, Selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
OnCellDeselect | EventCallback<CellDeselectEventArgs<TItem>> | Dispatched when a cell becomes deselected (cell navigation mode, Selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
OnRowSelect | EventCallback<RowSelectEventArgs<TItem>> | Dispatched when a row becomes selected (row navigation mode, Selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
OnRowDeselect | EventCallback<RowDeselectEventArgs<TItem>> | Dispatched when a row becomes deselected (row navigation mode, Selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
OnSortChange | EventCallback<SortChangeEventArgs> | Dispatched when the sort state changes (a sortable column header is activated or sort() is called). It bubbles and is composed. Its detail carries column, direction, and sortDescriptors. |
OnCellActivate | EventCallback<CellActivateEventArgs<TItem>> | Dispatched when a control rendered by ColumnDefinition.actionLabel/actionHref is activated — by pointer, Enter, or Space. It bubbles and is composed. Its detail carries item, rowIndex, field, columnIndex, value, and originalEvent. |
A sort clears the selection and fires the matching deselect event. Selection is by position, so new items
The column options that raise cell-activate are provisional and carry no compatibility promise.
Inputs
| Input | Type | Description |
|---|---|---|
borderless | booleandefault false | Removes the outer frame, including the header's underline. Row and cell dividers stay visible. See Rows and borders. |
captionPosition | CaptionPositionTypeCaptionPosition.Leading, .Trailingdefault CaptionPosition.Leading, from the style configuration | The caption's position in relation to the component. See Caption position. |
columns | ColumnDefinition[]default [] | Column definitions. If not provided, columns will be auto-generated from data (if possible). See Data and columns. |
density | DensityTypeDensity.Standard, .Dense1, .Dense2, .Dense3, .Dense4default Density.Standard, from the style configuration | How tightly rows are spaced, from 0, the roomiest, to 4, the tightest. See Density. |
gridLabel | string | The name a screen reader announces for the component. See Data and columns. |
items | TItem[]default [] | Data source as an array of objects. Use this for client-side data. See Data and columns. |
itemsProvider | GridItemsProvider<TItem> | Async function to provide data. Use this for server-side operations (filtering, sorting, paging). Ignored while items has rows. See Large data sets. |
locale | string | The BCP 47 locale, such as de-DE, the component writes numbers and dates in, and translates its built-in screen-reader text into where it has a translation. Empty means the application's configured locale (AppConfiguration.locale), or the browser's preferred language when it sets none. |
navigationMode | GridNavigationModeTypeGridNavigationMode.Cell, .Rowdefault GridNavigationMode.Cell | Sets how the arrow keys move focus: cell by cell in all four directions, or row by row up and down. It works independently of selectable. See Navigation mode. |
overscanCount | numberdefault 3 | How many rows beyond the visible ones are fetched ahead of scrolling. Keep it small to avoid over-fetching from the server. See Large data sets. |
selectable | booleandefault false | Whether selection is enabled. When true, cells or rows (depending on navigationMode) can be selected by click or Enter/Space, and a screen reader announces the selection. See Selection. |
showColumnDividers | booleandefault false | Shows vertical dividers between columns, which helps tell columns apart when there are many. See Rows and borders. |
striped | booleandefault false | Shades alternate rows. See Rows and borders. |
uniqueIdentifier | string | The name of a field whose value identifies a row. Required: without it, the grid cannot restore keyboard focus to the same row after a sort, filter or page change, so it drops focus. See Data and columns. |
variant | TableVariantTypeTableVariant.Filled, .Standard, .Surface, .Tonaldefault TableVariant.Standard, from the style configuration | The component's color scheme. filled uses the primary container color for high emphasis, tonal the secondary container color for medium emphasis, surface the lowest surface container color, and standard no fill, taking the color of whatever the table sits on. Unset, it comes from the style configuration's defaultTableVariant, which ships as standard. See Variants. |
virtualize | booleandefault false | Shows only the rows in view, for large datasets. Every row must be the same height. See Large data sets. |
Content projection
| Content | Description |
|---|---|
content with no slot | Default slot for caption content. Caption position controlled by captionPosition input. |
Outputs
| Output | Event | Description |
|---|---|---|
cwCellSelect | CellSelectEvent | Dispatched when a cell becomes selected (cell navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
cwCellDeselect | CellDeselectEvent | Dispatched when a cell becomes deselected (cell navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
cwRowSelect | RowSelectEvent | Dispatched when a row becomes selected (row navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
cwRowDeselect | RowDeselectEvent | Dispatched when a row becomes deselected (row navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
cwSortChange | SortChangeEvent | Dispatched when the sort state changes (a sortable column header is activated or sort() is called). It bubbles and is composed. Its detail carries column, direction, and sortDescriptors. |
cwCellActivate | CellActivateEvent | Dispatched when a control rendered by ColumnDefinition.actionLabel/actionHref is activated — by pointer, Enter, or Space. It bubbles and is composed. Its detail carries item, rowIndex, field, columnIndex, value, and originalEvent. |
A sort clears the selection and fires the matching deselect event. Selection is by position, so new items
The column options that raise cell-activate are provisional and carry no compatibility promise.
Props
| Prop | Type | Description |
|---|---|---|
borderless | booleandefault false | Removes the outer frame, including the header's underline. Row and cell dividers stay visible. See Rows and borders. |
captionPosition | CaptionPositionTypeCaptionPosition.Leading, .Trailingdefault CaptionPosition.Leading, from the style configuration | The caption's position in relation to the component. See Caption position. |
columns | ColumnDefinition[]default [] | Column definitions. If not provided, columns will be auto-generated from data (if possible). See Data and columns. |
density | DensityTypeDensity.Standard, .Dense1, .Dense2, .Dense3, .Dense4default Density.Standard, from the style configuration | How tightly rows are spaced, from 0, the roomiest, to 4, the tightest. See Density. |
gridLabel | string | The name a screen reader announces for the component. See Data and columns. |
items | TItem[]default [] | Data source as an array of objects. Use this for client-side data. See Data and columns. |
itemsProvider | GridItemsProvider<TItem> | Async function to provide data. Use this for server-side operations (filtering, sorting, paging). Ignored while items has rows. See Large data sets. |
locale | string | The BCP 47 locale, such as de-DE, the component writes numbers and dates in, and translates its built-in screen-reader text into where it has a translation. Empty means the application's configured locale (AppConfiguration.locale), or the browser's preferred language when it sets none. |
navigationMode | GridNavigationModeTypeGridNavigationMode.Cell, .Rowdefault GridNavigationMode.Cell | Sets how the arrow keys move focus: cell by cell in all four directions, or row by row up and down. It works independently of selectable. See Navigation mode. |
overscanCount | numberdefault 3 | How many rows beyond the visible ones are fetched ahead of scrolling. Keep it small to avoid over-fetching from the server. See Large data sets. |
selectable | booleandefault false | Whether selection is enabled. When true, cells or rows (depending on navigationMode) can be selected by click or Enter/Space, and a screen reader announces the selection. See Selection. |
showColumnDividers | booleandefault false | Shows vertical dividers between columns, which helps tell columns apart when there are many. See Rows and borders. |
striped | booleandefault false | Shades alternate rows. See Rows and borders. |
uniqueIdentifier | string | The name of a field whose value identifies a row. Required: without it, the grid cannot restore keyboard focus to the same row after a sort, filter or page change, so it drops focus. See Data and columns. |
variant | TableVariantTypeTableVariant.Filled, .Standard, .Surface, .Tonaldefault TableVariant.Standard, from the style configuration | The component's color scheme. filled uses the primary container color for high emphasis, tonal the secondary container color for medium emphasis, surface the lowest surface container color, and standard no fill, taking the color of whatever the table sits on. Unset, it comes from the style configuration's defaultTableVariant, which ships as standard. See Variants. |
virtualize | booleandefault false | Shows only the rows in view, for large datasets. Every row must be the same height. See Large data sets. |
Slots
| Slot | Description |
|---|---|
default | Default slot for caption content. Caption position controlled by captionPosition prop. |
Events
| Event | Type | Description |
|---|---|---|
cellSelect | CellSelectEvent | Dispatched when a cell becomes selected (cell navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
cellDeselect | CellDeselectEvent | Dispatched when a cell becomes deselected (cell navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
rowSelect | RowSelectEvent | Dispatched when a row becomes selected (row navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
rowDeselect | RowDeselectEvent | Dispatched when a row becomes deselected (row navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
sortChange | SortChangeEvent | Dispatched when the sort state changes (a sortable column header is activated or sort() is called). It bubbles and is composed. Its detail carries column, direction, and sortDescriptors. |
cellActivate | CellActivateEvent | Dispatched when a control rendered by ColumnDefinition.actionLabel/actionHref is activated — by pointer, Enter, or Space. It bubbles and is composed. Its detail carries item, rowIndex, field, columnIndex, value, and originalEvent. |
A sort clears the selection and fires the matching deselect event. Selection is by position, so new items
The column options that raise cell-activate are provisional and carry no compatibility promise.
Props
| Prop | Type | Description |
|---|---|---|
borderless | booleandefault false | Removes the outer frame, including the header's underline. Row and cell dividers stay visible. See Rows and borders. |
captionPosition | CaptionPositionTypeCaptionPosition.Leading, .Trailingdefault CaptionPosition.Leading, from the style configuration | The caption's position in relation to the component. See Caption position. |
columns | ColumnDefinition[]default [] | Column definitions. If not provided, columns will be auto-generated from data (if possible). See Data and columns. |
density | DensityTypeDensity.Standard, .Dense1, .Dense2, .Dense3, .Dense4default Density.Standard, from the style configuration | How tightly rows are spaced, from 0, the roomiest, to 4, the tightest. See Density. |
gridLabel | string | The name a screen reader announces for the component. See Data and columns. |
items | TItem[]default [] | Data source as an array of objects. Use this for client-side data. See Data and columns. |
itemsProvider | GridItemsProvider<TItem> | Async function to provide data. Use this for server-side operations (filtering, sorting, paging). Ignored while items has rows. See Large data sets. |
locale | string | The BCP 47 locale, such as de-DE, the component writes numbers and dates in, and translates its built-in screen-reader text into where it has a translation. Empty means the application's configured locale (AppConfiguration.locale), or the browser's preferred language when it sets none. |
navigationMode | GridNavigationModeTypeGridNavigationMode.Cell, .Rowdefault GridNavigationMode.Cell | Sets how the arrow keys move focus: cell by cell in all four directions, or row by row up and down. It works independently of selectable. See Navigation mode. |
overscanCount | numberdefault 3 | How many rows beyond the visible ones are fetched ahead of scrolling. Keep it small to avoid over-fetching from the server. See Large data sets. |
selectable | booleandefault false | Whether selection is enabled. When true, cells or rows (depending on navigationMode) can be selected by click or Enter/Space, and a screen reader announces the selection. See Selection. |
showColumnDividers | booleandefault false | Shows vertical dividers between columns, which helps tell columns apart when there are many. See Rows and borders. |
striped | booleandefault false | Shades alternate rows. See Rows and borders. |
uniqueIdentifier | string | The name of a field whose value identifies a row. Required: without it, the grid cannot restore keyboard focus to the same row after a sort, filter or page change, so it drops focus. See Data and columns. |
variant | TableVariantTypeTableVariant.Filled, .Standard, .Surface, .Tonaldefault TableVariant.Standard, from the style configuration | The component's color scheme. filled uses the primary container color for high emphasis, tonal the secondary container color for medium emphasis, surface the lowest surface container color, and standard no fill, taking the color of whatever the table sits on. Unset, it comes from the style configuration's defaultTableVariant, which ships as standard. See Variants. |
virtualize | booleandefault false | Shows only the rows in view, for large datasets. Every row must be the same height. See Large data sets. |
Snippets
| Snippet | Description |
|---|---|
children | Default slot for caption content. Caption position controlled by captionPosition prop. |
Events
| Prop | Type | Description |
|---|---|---|
onCellSelect | CellSelectEvent | Dispatched when a cell becomes selected (cell navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
onCellDeselect | CellDeselectEvent | Dispatched when a cell becomes deselected (cell navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, field, value, columnIndex, rowIndex, and originalEvent. |
onRowSelect | RowSelectEvent | Dispatched when a row becomes selected (row navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
onRowDeselect | RowDeselectEvent | Dispatched when a row becomes deselected (row navigation mode, selectable = true). It bubbles and is composed. Its detail carries item, rowIndex, and originalEvent. |
onSortChange | SortChangeEvent | Dispatched when the sort state changes (a sortable column header is activated or sort() is called). It bubbles and is composed. Its detail carries column, direction, and sortDescriptors. |
onCellActivate | CellActivateEvent | Dispatched when a control rendered by ColumnDefinition.actionLabel/actionHref is activated — by pointer, Enter, or Space. It bubbles and is composed. Its detail carries item, rowIndex, field, columnIndex, value, and originalEvent. |
A sort clears the selection and fires the matching deselect event. Selection is by position, so new items
The column options that raise cell-activate are provisional and carry no compatibility promise.
Each attribute value has its own tokens; a cell shows its token's value, and selecting the cell shows the token's fallback path, with each name and value ready to copy. For example, the standard column's error-color row is --ct-table-standard-error-color, which defaults to --ct-sys-color-error.
Variant
| Name | standard | surface | filled | tonal |
|---|---|---|---|---|
error-color | --ct-sys-color-error --ct-table-standard-error-color | --ct-sys-color-error --ct-table-surface-error-color | --ct-sys-color-error --ct-table-filled-error-color | --ct-sys-color-error --ct-table-tonal-error-color |
error-container-color | --ct-sys-color-error-container --ct-table-standard-error-container-color | --ct-sys-color-error-container --ct-table-surface-error-container-color | --ct-sys-color-error-container --ct-table-filled-error-container-color | --ct-sys-color-error-container --ct-table-tonal-error-container-color |
header-container-color | transparent --ct-table-standard-header-container-color | --ct-sys-color-surface-container-lowest --ct-table-surface-header-container-color | --ct-sys-color-primary-container --ct-table-filled-header-container-color | --ct-sys-color-secondary-container --ct-table-tonal-header-container-color |
header-headline-color | --ct-sys-color-on-surface --ct-table-standard-header-headline-color | --ct-sys-color-on-surface --ct-table-surface-header-headline-color | --ct-sys-color-on-primary-container --ct-table-filled-header-headline-color | --ct-sys-color-on-secondary-container --ct-table-tonal-header-headline-color |
header-hover-headline-color | same as row-item-label-text-color --ct-table-standard-header-hover-headline-color | same as row-item-label-text-color --ct-table-surface-header-hover-headline-color | same as row-item-label-text-color --ct-table-filled-header-hover-headline-color | same as row-item-label-text-color --ct-table-tonal-header-hover-headline-color |
header-hover-sorting-icon-button-color | same as row-item-label-text-color --ct-table-standard-header-hover-sorting-icon-button-color | same as row-item-label-text-color --ct-table-surface-header-hover-sorting-icon-button-color | same as row-item-label-text-color --ct-table-filled-header-hover-sorting-icon-button-color | same as row-item-label-text-color --ct-table-tonal-header-hover-sorting-icon-button-color |
on-error-container-color | --ct-sys-color-on-error-container --ct-table-standard-on-error-container-color | --ct-sys-color-on-error-container --ct-table-surface-on-error-container-color | --ct-sys-color-on-error-container --ct-table-filled-on-error-container-color | --ct-sys-color-on-error-container --ct-table-tonal-on-error-container-color |
outline-color | --ct-sys-color-outline-variant --ct-table-standard-outline-color | --ct-sys-color-outline-variant --ct-table-surface-outline-color | --ct-sys-color-primary --ct-table-filled-outline-color | --ct-sys-color-secondary --ct-table-tonal-outline-color |
row-item-container-color | transparent --ct-table-standard-row-item-container-color | --ct-sys-color-surface-container-lowest --ct-table-surface-row-item-container-color | --ct-sys-color-primary-container --ct-table-filled-row-item-container-color | --ct-sys-color-secondary-container --ct-table-tonal-row-item-container-color |
row-item-hover-state-layer-color | --ct-sys-color-on-surface --ct-table-standard-row-item-hover-state-layer-color | --ct-sys-color-on-surface --ct-table-surface-row-item-hover-state-layer-color | --ct-sys-color-on-primary-container --ct-table-filled-row-item-hover-state-layer-color | --ct-sys-color-on-secondary-container --ct-table-tonal-row-item-hover-state-layer-color |
row-item-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-table-standard-row-item-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-table-surface-row-item-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-table-filled-row-item-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-table-tonal-row-item-hover-state-layer-opacity |
row-item-label-text-color | --ct-sys-color-on-surface --ct-table-standard-row-item-label-text-color | --ct-sys-color-on-surface --ct-table-surface-row-item-label-text-color | --ct-sys-color-on-primary-container --ct-table-filled-row-item-label-text-color | --ct-sys-color-on-secondary-container --ct-table-tonal-row-item-label-text-color |
row-item-outline-color | --ct-sys-color-outline-variant --ct-table-standard-row-item-outline-color | --ct-sys-color-outline-variant --ct-table-surface-row-item-outline-color | --ct-sys-color-primary --ct-table-filled-row-item-outline-color | --ct-sys-color-secondary --ct-table-tonal-row-item-outline-color |
row-item-selected-hover-state-layer-color | same as row-item-hover-state-layer-color --ct-table-standard-row-item-selected-hover-state-layer-color | same as row-item-hover-state-layer-color --ct-table-surface-row-item-selected-hover-state-layer-color | same as row-item-hover-state-layer-color --ct-table-filled-row-item-selected-hover-state-layer-color | same as row-item-hover-state-layer-color --ct-table-tonal-row-item-selected-hover-state-layer-color |
row-item-selected-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-table-standard-row-item-selected-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-table-surface-row-item-selected-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-table-filled-row-item-selected-hover-state-layer-opacity | --ct-sys-state-hover-state-layer-opacity --ct-table-tonal-row-item-selected-hover-state-layer-opacity |
scrollbar-color | --ct-sys-color-outline-variant --ct-table-standard-scrollbar-color | --ct-sys-color-outline-variant --ct-table-surface-scrollbar-color | --ct-sys-color-primary --ct-table-filled-scrollbar-color | --ct-sys-color-secondary --ct-table-tonal-scrollbar-color |
scrollbar-thumb-color | --ct-sys-color-on-surface-variant --ct-table-standard-scrollbar-thumb-color | --ct-sys-color-on-surface-variant --ct-table-surface-scrollbar-thumb-color | --ct-sys-color-on-primary-container --ct-table-filled-scrollbar-thumb-color | --ct-sys-color-on-secondary-container --ct-table-tonal-scrollbar-thumb-color |
scrollbar-thumb-hover-color | --ct-sys-color-on-surface --ct-table-standard-scrollbar-thumb-hover-color | --ct-sys-color-on-surface --ct-table-surface-scrollbar-thumb-hover-color | --ct-sys-color-on-primary --ct-table-filled-scrollbar-thumb-hover-color | --ct-sys-color-on-secondary --ct-table-tonal-scrollbar-thumb-hover-color |
Other tokens
These stay the same whatever the variant.
| Token | Value |
|---|---|
--ct-table-caption-text-color | --ct-sys-color-on-surface --ct-table-caption-text-color |
--ct-table-caption-text-font | --ct-sys-typescale-title-medium-font --ct-table-caption-text-font |
--ct-table-caption-text-line-height | --ct-sys-typescale-title-medium-line-height --ct-table-caption-text-line-height |
--ct-table-caption-text-size | --ct-sys-typescale-title-medium-size --ct-table-caption-text-size |
--ct-table-caption-text-tracking | --ct-sys-typescale-title-medium-tracking --ct-table-caption-text-tracking |
--ct-table-caption-text-weight | --ct-sys-typescale-title-medium-weight --ct-table-caption-text-weight |
--ct-table-footer-container-dense-1-height | 48px --ct-table-footer-container-dense-1-height |
--ct-table-footer-container-dense-2-height | 44px --ct-table-footer-container-dense-2-height |
--ct-table-footer-container-dense-3-height | 40px --ct-table-footer-container-dense-3-height |
--ct-table-footer-container-dense-4-height | 36px --ct-table-footer-container-dense-4-height |
--ct-table-footer-container-standard-height | 52px --ct-table-footer-container-standard-height |
--ct-table-header-container-dense-1-height | 52px --ct-table-header-container-dense-1-height |
--ct-table-header-container-dense-2-height | 48px --ct-table-header-container-dense-2-height |
--ct-table-header-container-dense-3-height | 44px --ct-table-header-container-dense-3-height |
--ct-table-header-container-dense-4-height | 40px --ct-table-header-container-dense-4-height |
--ct-table-header-container-standard-height | 56px --ct-table-header-container-standard-height |
--ct-table-header-headline-font | --ct-sys-typescale-title-small-font --ct-table-header-headline-font |
--ct-table-header-headline-size | --ct-sys-typescale-title-small-size --ct-table-header-headline-size |
--ct-table-header-headline-weight | --ct-sys-typescale-title-small-weight --ct-table-header-headline-weight |
--ct-table-outline-width | 1px --ct-table-outline-width |
--ct-table-row-item-label-text-font | --ct-sys-typescale-body-medium-font --ct-table-row-item-label-text-font |
--ct-table-row-item-label-text-size | --ct-sys-typescale-body-medium-size --ct-table-row-item-label-text-size |
--ct-table-row-item-label-text-weight | --ct-sys-typescale-body-medium-weight --ct-table-row-item-label-text-weight |
--ct-table-row-item-outline-width | 1px --ct-table-row-item-outline-width |
--ct-table-row-layers-container-dense-1-height | 48px --ct-table-row-layers-container-dense-1-height |
--ct-table-row-layers-container-dense-2-height | 44px --ct-table-row-layers-container-dense-2-height |
--ct-table-row-layers-container-dense-3-height | 40px --ct-table-row-layers-container-dense-3-height |
--ct-table-row-layers-container-dense-4-height | 36px --ct-table-row-layers-container-dense-4-height |
--ct-table-row-layers-container-standard-height | 52px --ct-table-row-layers-container-standard-height |
Names and states
A screen reader announces the data grid as a grid of rows, column headers, and cells. It follows the WAI-ARIA Authoring Practices: Grid (Interactive Tabular Data and Layout Containers) Pattern.
- The accessible name comes from
, or from a caption inside the grid.grid-label - An
aria-labelset on the grid has no effect. Set or add a caption.grid-label - A screen reader announces the total row and column counts, and the position of each row counting the header, so the first data row is row 2. A virtualized grid is announced as busy while a window of rows loads.
- While
is set, a screen reader announces each cell as selected or not in cell mode, and each row in row mode. Without it, nothing is announced as selected.selectable - A sortable column header is announced with its sort state and a label such as "Name, column 1 of 4, sortable, not sorted". Each sort is announced in a live region, for example "Sorted by Name, ascending".
- Loads are announced in a polite live region: "Loading data", "Loaded 20 rows", "No data to display", and "Error loading data".
- Give every row a stable key with
. The grid logs an error without it and drops keyboard focus on every data change.unique-identifier - For read-only data that readers browse rather than navigate, a data table suits the job better.
Keyboard and focus
| Key | Action |
|---|---|
| Tab | Moves focus into the grid, which takes one Tab stop, and out of it |
| Arrow keys | Move to the adjacent cell in cell mode; Up and Down move between rows in row mode, where Left and Right do nothing |
| Home, End | Move to the first or last cell of the row (cell mode) |
| Ctrl+Home, Ctrl+End | Move to the first or last cell of the grid (cell mode) |
| PageUp, PageDown | Move by one visible page of rows (cell mode) |
| Up Arrow from the first row | Enters the header row (cell mode); Down Arrow returns to the first row |
| Enter, Space | Select the focused cell or row while selectable |
The component handles every key above itself; only Tab is the browser's own behavior.
- The grid draws a focus ring on keyboard focus.
- Row mode leaves the header out of keyboard reach, so sorting is pointer-only there. Use
navigation-modecellwhen readers need to sort by keyboard, or offer another way to callsort(). - In a selectable grid, Enter selects a cell and does not activate a cell action.
- After a refresh, a window load, or a sort, focus returns to the same record, found by
.unique-identifier
Pointer and touch
- Rows are 52 pixels tall at the default
and 36 pixels at the densest, so each row clears the 24 by 24 pixel minimum of WCAG 2.5.8 in height. The density examples show each step.density - A column can be narrower than 24 pixels. Give a column that holds an action a
minWidththat keeps its control at least 24 pixels wide.
Display settings
- Forced colors: row dividers stay visible and take a system color.
- Right-to-left: the arrow keys do not swap. Left Arrow always moves toward the first column and Right Arrow toward the last.
- Reduced motion: the sort arrow's fade and rotation run only when the reader has not asked for reduced motion.
Standards
With its defaults, the data grid meets three WCAG 2.2 success criteria:
Three more depend on how you use it:
- 2.1.1 Keyboard (A): in row mode, give readers a keyboard route to sorting, or use cell mode.
- 2.5.8 Target Size (Minimum) (AA): give action columns a
minWidththat keeps each control at least 24 pixels wide. - 4.1.2 Name, Role, Value (A): set
or add a caption so the grid has a name.grid-label