DocsBlog
  • 1.0.0

  • light

    dark

    system

    Switch mode
  • Cerberus

    Acheron

    Elysium

Get Started
Components
Data Grid
Styling
Theming

Get Started

OverviewQuick StartColumnsContext

Layout

DimensionsSizingToolbarPagination

Features

PinningSorting

Reference

API

On this page

  • Edit this page on Github

Column Sorting

Learn about the column sorting feature in the Data Grid component.

  • source

Overview

Sorting allows users to list the data in ascending or descending order. There are three ways for a user to sort:

  1. Clicking on the header-cell icon: This will toggle the order from ascending to descending and vice versa.
  2. Using the sort menu: Users can also use the sort menu to strictly determine the order of the data.
  3. Multi-column sorting: Hold the Shift key while clicking on the second sort button.

Implementing column sorting

You must opt-in to column sorting by setting the features.sort prop to true or utilzing the options object. Doing so will display the sorting options in the column menu.

Multi-column Sorting

Multi-column sorting is enabled by default on the toggle sort button. To use multi-column sorting hold the Shift key while clicking on the second sort button.

Custom Comparator

A comparator determines how two cell values should be sorted. The default comparator uses the vanilla JavaScript basic comparison of a and b.

When using the accessorFn method, the comparator uses the value returned from the accessorFn callback provided as the first argument.

To provide a custom comparator, you can pass a function as the features.sort.comparator option.

Note

Dates will naturally sort in order without any customization. This example just shows how to customize the sorting behavior.

Options

The sort feature accepts either a boolean or an object with the following properties:

ParamsRequiredDescription
firstSortDirectionfalseThe initial sort direction for the column.
comparatorfalseA custom comparator function for sorting.
Cerberus Design System | Docs
Copy
'use client'

import { DataGrid } from '@cerberus/data-grid'
import { Box } from 'styled-system/jsx'
import { useFakeQuery } from '../quick-start/data'
import { columns } from './columns'

export function BasicDemo() {
  // Normally this would be from useQuery or a server-side API call
  const data = useFakeQuery(1000)

  return (
    <Box h="20rem" w="90%">
      <DataGrid columns={columns} data={data} />
    </Box>
  )
}

// columnHelper.accessorFn((row) => `${row.firstName} ${row.lastName}`, {
//   id: 'fullName',
//   header: 'Employee',
//   minWidth: 300,
//   features: {
//     sort: true,
//   },
//   cell: ({ row, value }) => (
//     <VStack alignItems="flex-start" gap="0">
//       <Text textStyle="body-md">{value}</Text>
//       <Text color="page.text.100" textStyle="label-sm">
//         {row.email}
//       </Text>
//     </VStack>
//   ),
// }),
Copy
'use client'

import { DataGrid } from '@cerberus/data-grid'
import { Box } from 'styled-system/jsx'
import { useFakeQuery } from '../quick-start/data'
import { columns } from './columns'

export function MultiDemo() {
  // Normally this would be from useQuery or a server-side API call
  const data = useFakeQuery(500)

  return (
    <Box h="20rem" w="90%">
      <DataGrid columns={columns} data={data} />
    </Box>
  )
}

// columnHelper.accessorFn((row) => `${row.firstName} ${row.lastName}`, {
//   id: 'fullName',
//   header: 'Employee',
//   minWidth: 300,
//   features: {
//     sort: true,
//   },
//   cell: ({ row, value }) => (
//     <VStack alignItems="flex-start" gap="0">
//       <Text textStyle="body-md">{value}</Text>
//       <Text color="page.text.100" textStyle="label-sm">
//         {row.email}
//       </Text>
//     </VStack>
//   ),
// }),
Copy
'use client'

import { DataGrid } from '@cerberus/data-grid'
import { Box } from 'styled-system/jsx'
import { useFakeQuery } from '../quick-start/data'
import { columns } from './compare-columns'

export function ComparatorDemo() {
  // Normally this would be from useQuery or a server-side API call
  const data = useFakeQuery(100)

  return (
    <Box h="20rem" w="90%">
      <DataGrid columns={columns} data={data} />
    </Box>
  )
}

// columnHelper.accessor('lastLogin', {
//   header: 'Last Login',
//   features: {
//     sort: {
//       comparator: (a, b) =>
//         new Date(a as string).getTime() - new Date(b as string).getTime(),
//     },
//   },
//   cell: ({ value }) => {
//     const formatter = new DateFormatter('en-US', {
//       dateStyle: 'short',
//       timeZone: 'America/New_York',
//     })
//     return (
//       <Text textStyle="label-md">{formatter.format(new Date(value))}</Text>
//     )
//   },
// })
Copy
'use client'

import { DataGrid } from '@cerberus/data-grid'
import { Box } from 'styled-system/jsx'
import { useFakeQuery } from '../quick-start/data'
import { columns } from './columns'

export function BasicDemo() {
  // Normally this would be from useQuery or a server-side API call
  const data = useFakeQuery(1000)

  return (
    <Box h="20rem" w="90%">
      <DataGrid columns={columns} data={data} />
    </Box>
  )
}

// columnHelper.accessorFn((row) => `${row.firstName} ${row.lastName}`, {
//   id: 'fullName',
//   header: 'Employee',
//   minWidth: 300,
//   features: {
//     sort: true,
//   },
//   cell: ({ row, value }) => (
//     <VStack alignItems="flex-start" gap="0">
//       <Text textStyle="body-md">{value}</Text>
//       <Text color="page.text.100" textStyle="label-sm">
//         {row.email}
//       </Text>
//     </VStack>
//   ),
// }),
export type SortOptions<TData, TKey extends keyof TData> = {
  firstSortDirection?: SortDirection
  comparator?: Comparator<TData[TKey]>
}

export type SortDirection = 'asc' | 'desc' | null
export type Comparator<TValue> = (a: TValue, b: TValue) => number