@microsoft/fabric-datagrid
v1.1.0
Published
A lightweight, high-performance React data grid component for Fabric Apps - Analytics
Downloads
4,005
Readme
@microsoft/fabric-datagrid
High-performance React data grid for Fabric Apps - Analytics
Quick Reference
Package:
@microsoft/fabric-datagridPurpose: High-performance React data grid component with sorting, filtering, tree rows, pagination, and virtualization. Use when: You need to display tabular data from aDataTableorRow[]as an interactive grid. Do NOT use when: You need charts/visualizations (use@microsoft/fabric-visuals), or you only need shared types/tokens (use@microsoft/fabric-visuals-core). Key exports:DataGrid,ImageCell,DataGridProps,GridColumnDef,Row,CellValue,SortConfig,SortDirection,CellRangePeer dependencies:@microsoft/fabric-visuals-coreInstall:npm install @microsoft/fabric-datagrid @microsoft/fabric-visuals-core
Ecosystem Context
@microsoft/fabric-datagrid is the tabular companion to the Fabric Apps - Analytics visualization stack:
- It consumes
DataTableandColumnDefcontracts from@microsoft/fabric-visuals-core. - It is a sibling package to
@microsoft/fabric-visuals, which provides Vega-Lite chart rendering. - In typical apps, grid data originates from
@microsoft/fabric-app-dataqueries, then gets shaped into aDataTablefor display.
Installation
npm install @microsoft/fabric-datagrid @microsoft/fabric-visuals-core@microsoft/fabric-visuals-core is required at runtime because DataGrid consumes its DataTable/VisualTheme types and injects shared design tokens.
Public API
All exports come from the package entry point:
export { DataGrid } from './components/data-grid';
export { ImageCell } from './components/image-cell/image-cell';
export type { DataGridProps, GridColumnDef, Row, CellValue, SortConfig, SortDirection } from './types';
export type { CellRange } from './hooks/use-selection';DataGrid
import type { DataTable, VisualTheme } from '@microsoft/fabric-visuals-core';
import type { ReactNode } from 'react';
declare function DataGrid(props: DataGridProps): JSX.Element;DataGrid accepts three data sources through props.data:
DataTable: derives grid columns frominput.columnsRow[]: renders caller-provided row objects directlystring: fetches JSON from a URL and expects aRow[]payload
ImageCell
A memoized cell renderer component for displaying image thumbnails with a click-to-expand lightbox overlay.
interface ImageCellProps {
src: string;
alt?: string;
className?: string;
}
declare const ImageCell: React.MemoExoticComponent<(props: ImageCellProps) => JSX.Element | null>;Use as a cellRenderer in a GridColumnDef:
import { ImageCell } from '@microsoft/fabric-datagrid';
const columns: GridColumnDef[] = [
{ id: 'photo', header: 'Photo', cellRenderer: (value) => <ImageCell src={String(value)} alt="thumbnail" /> },
];Props (DataGridProps)
interface DataGridProps {
columns?: GridColumnDef[];
data?: DataTable | Row[] | string;
defaultSort?: SortConfig[];
rowHeight?: number;
theme?: VisualTheme;
onColumnsChange?: (columns: GridColumnDef[]) => void;
onRowToggle?: (rowId: string) => void;
onFilterChange?: (columnId: string, selectedValues: CellValue[]) => void;
onInteraction?: (events: InteractionEvent[]) => void;
pageSize?: number;
capabilities?: DataGridCapabilities;
}| Prop | Type | Required | Description |
|------|------|----------|-------------|
| data | DataTable \| Row[] \| string | no | Data source. A DataTable auto-derives columns and rows. A Row[] array provides data directly. A string URL triggers a fetch for JSON Row[]. |
| columns | GridColumnDef[] | no | Column definitions. Auto-derived when data is a DataTable; required otherwise. |
| defaultSort | SortConfig[] | no | Initial sort state (e.g. [{ columnId, direction }]). |
| rowHeight | number | no | When set, enables row virtualization via @tanstack/react-virtual. Mutually exclusive with pageSize. |
| pageSize | number | no | When set (> 0), enables pagination instead of virtualization. |
| theme | VisualTheme | no | Visual theme from @microsoft/fabric-visuals-core. Maps to CSS custom properties. When omitted, the grid falls back to CSS variable defaults. |
| onColumnsChange | (columns: GridColumnDef[]) => void | no | Fired after column resize or reorder. |
| onRowToggle | (rowId: string) => void | no | Fired when a hierarchical row is expanded or collapsed. |
| onFilterChange | (columnId: string, selectedValues: CellValue[]) => void | no | Fired when a column filter is applied or cleared. |
| onInteraction | (events: InteractionEvent[]) => void | no | Fired when the user clicks a data row (select) or re-clicks the selected row (clear/deselect). See Interactivity. |
| capabilities | DataGridCapabilities | no | Controls which built-in behaviors are active. See Capabilities. |
Exported types
type CellValue = ReactNode;
interface GridColumnDef {
id: string;
header: string;
width?: number;
minWidth?: number;
children?: GridColumnDef[];
sortable?: boolean;
filterable?: boolean;
cellRenderer?: (value: CellValue, row: Row) => ReactNode;
numeric?: boolean;
}
interface Row {
_id?: string;
_children?: Row[];
_expanded?: boolean;
[columnId: string]: CellValue | Row[] | undefined;
}
type SortDirection = 'asc' | 'desc';
interface SortConfig {
columnId: string;
direction: SortDirection;
}
interface CellRange {
startRow: number;
startCol: number;
endRow: number;
endCol: number;
}Type notes
| Export | Notes |
| --- | --- |
| DataGridProps.columns | Optional when data is a DataTable; the grid derives id from ColumnDef.name and header from ColumnDef.displayName ?? ColumnDef.name. |
| GridColumnDef.children | Enables grouped headers. Groups render as <th> with colSpan; only leaf columns render data cells. |
| GridColumnDef.sortable | Default: true for leaf columns. |
| GridColumnDef.filterable | Default: true for leaf columns. |
| GridColumnDef.cellRenderer | Receives the resolved cell value and the full Row. |
| GridColumnDef.numeric | Right-aligns cells (headers stay left-aligned) and uses tabular digits so numbers line up by place. true forces it, false opts out, undefined (default) auto-detects from a bounded ~100-row sample (head + evenly-spaced tail) — set explicitly if a column's type boundary may fall between samples. Columns with a cellRenderer skip auto-detection. |
| Row._children | Enables tree rows with expand/collapse toggles and per-level indentation. |
| Row._expanded | Seeds the initial expanded state for tree rows. |
| SortConfig[] | Supports multi-column default sort order. Interactive multi-sort uses Shift+click. Sort cycling: unsorted → asc → desc → unsorted. |
| CellRange | Rectangular selection coordinates expressed in visible row/column indexes. |
Capabilities
DataGrid supports an optional capabilities prop that lets consumers selectively disable built-in interactions or opt into pagination/virtualization without setting explicit pageSize/rowHeight props. Pass a partial DataGridCapabilities object — omitted keys use defaults.
Interface
import type { DataGridCapabilities } from '@microsoft/fabric-datagrid';
interface DataGridCapabilities {
disableSorting?: boolean;
disableFiltering?: boolean;
disableColumnResize?: boolean;
disableColumnReorder?: boolean;
disableSelection?: boolean;
pagination?: boolean | number;
virtualization?: boolean | number;
}Capability flags
| Flag | Default | Effect |
|------|---------|--------|
| disableSorting | false | When true, removes sort-on-click from all column headers. The header cursor reverts to default. |
| disableFiltering | false | When true, hides filter icons and prevents the filter overlay from opening. |
| disableColumnResize | false | When true, removes resize handles between column headers. |
| disableColumnReorder | false | When true, disables drag-to-reorder columns. |
| disableSelection | false | When true, disables cell/row selection, Shift+arrow range, and Ctrl+C copy. |
| pagination | false | true enables pagination with a default page size of 50. A number sets the exact page size. Lower priority than the pageSize prop. |
| virtualization | false | true enables virtualized rendering with a default 36px row height. A number sets the row height. Lower priority than the rowHeight prop. |
Usage
import { DataGrid } from '@microsoft/fabric-datagrid';
import type { DataGridCapabilities } from '@microsoft/fabric-datagrid';
const capabilities: DataGridCapabilities = {
disableSorting: true,
disableColumnReorder: true,
pagination: 25,
};
export function ReadOnlyTable() {
return <DataGrid data={data} capabilities={capabilities} />;
}Explicit props (pageSize, rowHeight) always take priority over capability values. For example, if pageSize={10} is set on the component, capabilities.pagination is ignored.
Rendering Modes
| Mode | Trigger | Behavior |
|------|---------|----------|
| Standard | No rowHeight or pageSize | Renders all rows in a plain <tbody>. |
| Virtualized | rowHeight is set | Only visible rows are in the DOM (@tanstack/react-virtual, overscan: 5). Uses table-layout: fixed with flex rows. |
| Paginated | pageSize is set | Shows pageSize rows per page with a pagination bar (first/prev/input/next/last). Page resets to 1 when data changes. |
Features
- Sorting: Click a header to cycle (unsorted → asc → desc → unsorted). Shift+click for multi-column sort. Handles numbers, strings, booleans, and nulls (nulls sort last).
- Column Filtering: Filter icon in header opens a portal overlay with search, "Select all" toggle, and virtualized checkbox list. Filtering by exclusion (unchecked values are hidden).
- Column Resizing: Drag resize handles between headers. Uses direct DOM mutation during drag for 60fps, commits to React state on
mouseup. Default width: 150px, min: 50px. - Column Reordering: Native HTML drag-and-drop with visual drop indicators.
- Hierarchical Rows: Rows with
_childrenrender expand/collapse toggles (▸/▾) with 20px per-level indentation. - Grouped Headers:
GridColumnDef.childrenenables multi-level header groups. - Data Fetching: Pass a URL string as
datato auto-fetch JSONRow[]. Shows "Loading…" / "Error: ..." states. - Tooltip Truncation: Cells use CSS text-overflow ellipsis with native
titletooltip only when content is actually truncated. - Interaction: Click rows to emit
InteractionEvents. Click a row to emit aselectevent and click an already-selected row to emit aclearevent.
Theming
Colors, typography, spacing, and border are controlled via a VisualTheme object from @microsoft/fabric-visuals-core. The theme prop is optional — when omitted, the grid falls back to its CSS variable defaults.
Color mapping (theme prop → CSS variables)
| VisualTheme field | CSS variable | Default | Description |
|---|---|---|---|
| foreground | --dg-text-color | var(--color-foreground) | Text color for body cells |
| foreground | --dg-header-color | var(--color-card-foreground) | Text color for header cells |
| brandForeground | --dg-highlight-color | var(--color-brand-foreground) | Color for drop indicators, active filter icons, resize handle hover |
| background | --dg-bg-color | var(--color-card) | Body background color |
| backgroundSecondary | --dg-header-bg | var(--color-muted) | Background color for header rows |
| backgroundHover | --dg-hover-color | var(--color-hover) | Background color on row/header hover |
| stroke | --dg-border-color | var(--color-border) | Border color for cell and header borders |
Layout CSS variables
| CSS variable | Default | Description |
|---|---|---|
| --dg-font-family | var(--font-base) | Font face for the grid |
| --dg-font-size | var(--text-200) | Font size for cells and headers |
| --dg-cell-padding | var(--spacing-s-nudge) var(--spacing-m) | Padding inside <th> and <td> cells |
Key Constraints & Gotchas
DataTable auto-derives columns; Row[] does not
// ✅ DO: Pass a DataTable — columns are auto-derived from ColumnDef[]
<DataGrid data={dataTable} />
// ✅ DO: When using Row[], provide explicit columns
<DataGrid data={rows} columns={columnDefs} />
// ❌ DON'T: Pass Row[] without columns — headers will be missing
<DataGrid data={rows} />Container must have a bounded height for scrolling and virtualization
DataGrid renders to fit its parent. To engage scrolling and sticky headers, the parent must resolve to a definite height. Use design tokens for the bound (e.g., a flex/grid cell or a tokenized max-height). Do not use hardcoded pixel values.
// ✅ DO: Wrap DataGrid in a sized container
<div style={{ height: 400 }}>
<DataGrid data={data} rowHeight={40} />
</div>
// ❌ DON'T: Render without a height constraint — virtualization won't activate and no scroll bar appears
<DataGrid data={data} rowHeight={40} />Virtualized mode (rowHeight set) always requires a bounded parent — without one the virtualizer cannot determine the visible window and will render only overscan rows.
Virtualization and pagination are mutually exclusive
- Virtualization activates when
rowHeightis set andpageSizeis NOT set. - Pagination activates when
pageSizeis set — the grid renders the full page without virtualization.
Tree rows are data-driven
// ✅ DO: Use _children and _expanded in row data
const rows: Row[] = [
{ _id: "1", name: "Parent", _expanded: true, _children: [
{ _id: "1.1", name: "Child" }
]},
];DataTable format
DataTableuses column-major schema (columns: ColumnDef[]) with row-major values (rows: unknown[][]).- Row values are aligned to columns by index.
- Missing row entries are normalized to
null.
Theme is optional
theme?: VisualThemecan be provided to map theme values to CSS custom properties for foreground, background, borders, typography, etc. When omitted, the grid falls back to its CSS variable defaults.
// ✅ DO: Pass a theme for explicit control
import { useCssTheme } from '@microsoft/fabric-visuals';
const theme = useCssTheme();
<DataGrid data={data} theme={theme} />
// ✅ Also OK: Omit theme — the grid uses CSS variable defaults
<DataGrid data={data} />Minimal Usage Examples
Render a DataTable
import { DataGrid } from '@microsoft/fabric-datagrid';
import type { DataTable } from '@microsoft/fabric-visuals-core';
const data: DataTable = {
columns: [
{ name: 'category', displayName: 'Category' },
{ name: 'sales', displayName: 'Sales', format: '$#,##0.00' },
],
rows: [
['Bikes', 1250.5],
['Accessories', 420.25],
],
};
export function Example() {
return <DataGrid data={data} />;
}Manual columns with Row[] and sorting
import { DataGrid } from '@microsoft/fabric-datagrid';
import type { GridColumnDef, Row, SortConfig } from '@microsoft/fabric-datagrid';
import { useCssTheme } from '@microsoft/fabric-visuals';
const columns: GridColumnDef[] = [
{ id: 'name', header: 'Name', sortable: true, filterable: true },
{ id: 'score', header: 'Score', width: 100 },
];
const rows: Row[] = [
{ name: 'Alice', score: 95 },
{ name: 'Bob', score: 87 },
];
const theme = useCssTheme();
<DataGrid columns={columns} data={rows} theme={theme} defaultSort={[{ columnId: 'score', direction: 'desc' }]} />Virtualized with theming
import { DataGrid } from '@microsoft/fabric-datagrid';
import { lightThemeColors, type DataTable, type VisualTheme } from '@microsoft/fabric-visuals-core';
const theme: VisualTheme = {
...lightThemeColors,
backgroundHover: '#f0f6ff',
};
export function Example() {
return (
<div style={{ height: 320 }}>
<DataGrid data={data} rowHeight={40} theme={theme} />
</div>
);
}Interaction events
import { DataGrid } from '@microsoft/fabric-datagrid';
import type { DataTable, InteractionEvent } from '@microsoft/fabric-visuals-core';
import { useCssTheme } from '@microsoft/fabric-visuals';
function handleInteraction(events: InteractionEvent[]) {
for (const event of events) {
if (event.action === 'select') {
console.log('Selected:', event.selections);
} else if (event.action === 'clear') {
console.log('Deselected');
}
}
}
export function Example() {
const theme = useCssTheme();
return <DataGrid data={data} theme={theme} onInteraction={handleInteraction} />;
}Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.
Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories in our GitHub organizations.
Please do not report security vulnerabilities through public GitHub issues.
For security reporting information, locations, contact information, and policies, please review the latest guidance for Microsoft repositories at https://aka.ms/SECURITY.md.
Code of conduct
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
