@dataverse-kit/grid-kit
v0.15.0
Published
Shared, registry-driven grid / detail-list components for Dynamics 365. The default (Fluent UI v8) entry wraps @khester/dynamics-cell-renderers behind one cell-renderer registry usable by both a DetailsList grid and a Grid Customizer; the ./v9 subpath is
Downloads
2,970
Readme
@dataverse-kit/grid-kit
Registry-driven grid and detail-list hosts for Dynamics 365, built on Fluent UI v8 — with a Fluent UI v9 read grid on the ./v9 subpath.
What it does
@dataverse-kit/grid-kit provides a single cell-renderer registry (createCellRegistry) that maps a column's rendererType to a memoized cell component from @khester/dynamics-cell-renderers, plus a family of React hosts that render with it: <DataGrid> (flat and editable), <ReadOnlyGrid>, <CardGrid>, <GroupedGrid>, <NestedGrid>, and <FocusedViewGrid>. The same registry serves both a Fluent v8 DetailsList and a Microsoft Grid Customizer via host adapters (toDetailsListColumns, toGridCustomizerOverrides), so a column definition renders identically across hosts. It also ships toolbar/column-chooser/filter-builder UI, CSV/JSON export (exportGrid, GridExportDialog), client-side filtering and aggregates, file-drop primitives, and an Xrm.Navigation wrapper.
When to use it
Reach for grid-kit when you need a grid, detail list, or editable subgrid in a custom page, PCF control, or Grid Customizer — anything that displays tabular Dataverse data with typed cell rendering, inline editing, grouping, or master-detail layouts. For form shells, page containers, and layout chrome use surface-kit; for general custom-page UI controls use reusable-components. If you only need the individual cell renderers without a grid host, depend on @khester/dynamics-cell-renderers directly — grid-kit wraps that package and adds the registry, adapters, and hosts on top.
Install
npm install @dataverse-kit/grid-kitPeer dependencies: react, react-dom (^18.2) and @fluentui/react (^8.115.6, Fluent UI v8).
Minimal example
import { DataGrid, createCellRegistry, type ColumnDef } from '@dataverse-kit/grid-kit';
const registry = createCellRegistry();
const columns: ColumnDef[] = [
{ key: 'name', fieldName: 'name', name: 'Account', rendererType: 'text' },
{
key: 'progress',
fieldName: 'completion',
name: 'Progress',
rendererType: 'progress',
rendererConfig: { max: 100, showLabel: true },
aggregate: 'avg',
},
{ key: 'revenue', fieldName: 'revenue', name: 'Revenue', rendererType: 'currency' },
];
const items = [
{ key: '1', name: 'Contoso', completion: 80, revenue: 1_200_000 },
{ key: '2', name: 'Fabrikam', completion: 45, revenue: 540_000 },
];
export function AccountGrid() {
return (
<DataGrid
items={items}
columns={columns}
registry={registry}
selectionMode="multiple"
onSelectionChanged={(rows) => console.log(rows)}
/>
);
}Key exports
| Export | Purpose |
|--------|---------|
| createCellRegistry | Builds the rendererType → cell-component registry; override or add types with registry.register(...). |
| DataGrid | The flat / editable Fluent v8 DetailsList host (selection, click-to-edit, toolbar, pagination footer). |
| ReadOnlyGrid, CardGrid, GroupedGrid, NestedGrid, FocusedViewGrid | Hosts for the Grid Customizer grid types (read-only, card layout, collapsible groups, expandable rows, master-detail). |
| ColumnDef (type) | The column contract — fieldName, rendererType, rendererConfig, editorType, aggregates, callbacks. |
| GridProps / GridRegistry (types) | Host props contract and the registry interface. |
| toDetailsListColumns, toGridCustomizerOverrides | Adapters that drive a Fluent DetailsList or a Grid Customizer from the same registry. |
| resolveGridFromDefinition | Maps a duck-typed Grid Customizer definition (gridType + config) to the right host + props. |
| exportGrid, GridExportDialog | Turnkey CSV / JSON export and an opt-in format + column-picker dialog. |
| GridToolbar, GridColumnChooser, GridFilterBuilder | Toolbar command bar, show/hide-reorder column panel, and client-side filter builder. |
| applyFilters, computeAggregates, computeFormattedValue | Framework-agnostic core helpers for filtering, footer aggregates, and value formatting. |
| useGridContext, useEditState, useFileDrop | Hooks: the custom-host extension seam, edit-state management, and HTML5 file-drop. |
Fluent UI v9 (./v9 subpath)
The default entry above is Fluent UI v8. A Fluent UI v9 skin ships under the ./v9
subpath — a flat read + inline-editable <DataGrid> (over @fluentui/react-components) with
the 13 read cell types re-skinned + 5 editable cells (text / number / currency / date / datetime /
optionset / rating, per-cell click-to-edit or editTrigger="always"), plus selection, controlled
sort, loading, pagination, an aggregate footer, responsive column shedding, and a lean toolbar. It
shares the SAME framework-agnostic core (the ColumnDef contract, formatters/color/aggregate/
responsive helpers, the render context, and the useEditState buffer) with the v8 skin — only the
cell JSX and the host are v9.
import { FluentProvider } from '@fluentui/react-components';
import { DataGrid, createDynamicsV9Theme, type ColumnDef } from '@dataverse-kit/grid-kit/v9';
const columns: ColumnDef[] = [
{ key: 'name', fieldName: 'name', name: 'Account', rendererType: 'text', isSortable: true },
{ key: 'revenue', fieldName: 'revenue', name: 'Revenue', rendererType: 'currency', aggregate: 'sum' },
];
export function V9AccountGrid() {
return (
<FluentProvider theme={createDynamicsV9Theme()}>
<DataGrid items={items} columns={columns} selectionMode="multiple" />
</FluentProvider>
);
}Beyond the flat <DataGrid>, the ./v9 skin ships the full grid-host set — <CardGrid> (a v9
Card layout with responsive minCardWidth reflow), <FocusedViewGrid> (a master-detail rail +
detail pane), <GroupedGrid> (a v9 Accordion of per-group <DataGrid>s with cross-group
selection + opt-in per-group subtotals), and <NestedGrid> (inline chevron-expand via a manual v9
Table, plus side-panel = OverlayDrawer and hover-callout = Popover modes) — all rendering
cells through the same shared v9 registry.
The v9 Fluent packages (@fluentui/react-components ^9.46.2, @fluentui/react-icons ^2.0.239)
are optional peers — install them only if you use ./v9; v8-only consumers are unaffected.
Editable lookup and the nested parentLayout:'cards' variant are v8-only today (follow-on v9
increments).
See
CLAUDE.mdfor the full architecture / contributor reference.
