Skip to main content

Sorting

Sorting is type-aware and supports ordered multi-column models through headers, menus, the toolbar, initial options, and the API.

Loading interactive example…
React
<Grid
rowData={rows}
columnDefs={columns}
initialSort={[
{ colId: "region", dir: "asc" },
{ colId: "revenue", dir: "desc" },
]}
showSortPriority="always"
toolbar={{ sorting: true }}
/>

Sort behavior​

initialSort applies once during setup. A column's own sort and sortIndex take precedence. showSortPriority controls the numeric priority indicator.

Ctrl/Cmd or Shift makes a header sort additive, adding the column to a multi-column sort instead of replacing it — on the sort icon, on the header body, and on Ctrl/Cmd+Enter from the keyboard. Shift+Enter sorts every column in the current column selection at once.

Set a custom order such as ["desc", "asc", null] through a column or defaultColDef.sortingOrder. sortIconVisibility may be "hover", "always", or "never"; hiding the icon does not disable menu or API sorting.

The grid derives comparison from ColumnType. Use comparator(a, b, nodeA, nodeB) for domain-specific orders such as severity or workflow stage.

Under pagination, sorting keeps the user's current page by default. Add "sort" to resetPageOn to jump back to page 1 on every sort change — the policy applies to header clicks and API sorting alike. A sort change also clears the row selection unless selectionPersistence: "keep" is set.

Configure the sort cycle​

const options = {
showSortPriority: "always",
defaultColDef: {
sortable: true,
sortingOrder: ["asc", "desc", null],
sortIconVisibility: "hover",
},
} satisfies GridOptions;

A column can override the defaultColDef sorting cycle and icon visibility. The toolbar can expose ordered sort chips with toolbar: { sorting: true }.

Initial multi-column sort​

const options = {
initialSort: [
{ colId: "region", dir: "asc" },
{ colId: "revenue", dir: "desc" },
],
} satisfies GridOptions;

Or place the initial state directly on columns:

const columnDefs: ColDef[] = [
{ colId: "region", key: "region", label: "Region", sort: "asc", sortIndex: 0 },
{ colId: "revenue", key: "revenue", label: "Revenue", sort: "desc", sortIndex: 1 },
];

initialSort applies once during setup; a column's own sort/sortIndex take precedence.

Custom comparator​

const priorityOrder = ["critical", "high", "normal", "low"];

const column = {
key: "priority",
label: "Priority",
sortable: true,
comparator: (a, b) => priorityOrder.indexOf(a) - priorityOrder.indexOf(b),
} satisfies ColDef;

Without a comparator, the grid derives type-aware string, number, date, boolean, or currency comparison automatically.

Set or toggle sorting through the API​

// Replace the whole sort model, in priority order (entry 0 sorts first).
api.setSortModel([
{ colId: "region", dir: "asc" },
{ colId: "revenue", dir: "desc" },
]);

api.getSortModel();
// → [{ colId: "region", dir: "asc" }, { colId: "revenue", dir: "desc" }]

// Cycle one column asc → desc → unsorted, keeping the other sorts (it moves to last priority).
const toggle = (colId: string) => {
const model = api.getSortModel();
const current = model.find((item) => item.colId === colId)?.dir ?? null;
const next = current === null ? "asc" : current === "asc" ? "desc" : null;
api.setSortModel([
...model.filter((item) => item.colId !== colId),
...(next ? [{ colId, dir: next }] : []),
]);
};

api.setSortModel([]); // clear every sort

Columns are addressed by their public colId — the auto-group column and generated pivot columns by theirs. setSortModel replaces the model; unknown and non-sortable columns are skipped, and a model equal to the current one does nothing. Otherwise it behaves exactly like a header click: columnsChanged (reason: "sort") and onSortChanged fire, the page follows resetPageOn, and selection follows selectionPersistence.

Sort also round-trips through column state: getColumnState() reports each column's sort (null when unsorted) and sortIndex (its position in the sort model), and applyColumnState() applies the entries that carry a sort field — null clears that column's sort, and defaultState: { sort: null } clears every column the state does not name.

api.applyColumnState([{ colId: "revenue", sort: "desc", sortIndex: 0 }]);
api.applyColumnState([{ colId: "region", sort: "asc" }], { defaultState: { sort: null } });