import { DataTable } from '@uhg-abyss/web/ui/DataTable';import { useDataTable } from '@uhg-abyss/web/hooks/useDataTable';Sorting is disabled by default. To enable sorting for all columns, set tableConfig.enableSorting to true.
const dataTableProps = useDataTable({ // ... tableConfig: { enableSorting: true, }, // ...});The enableSorting property can also be provided to individual columns for more granular adjustment.
{ header: 'Column 1', accessorKey: 'col1', enableSorting: true,}To manage the sorting state, provide a function to the tableConfig.onSortingChange property and set the state.sorting property; we recommend using useState for this, as shown below.
const [sorting, setSorting] = useState([]);
const dataTableProps = useDataTable({ // ... tableConfig: { enableSorting: true, onSortingChange: setSorting, state: { sorting, }, }, // ...});Built-in sorting
By default, there are six built-in sorting functions to choose from:
'alphanumeric': Sorts by mixed alphanumeric values without case-sensitivity. Slower, but more accurate if your strings contain numbers that need to be naturally sorted.'alphanumericCaseSensitive': Sorts by mixed alphanumeric values with case-sensitivity. Slower, but more accurate if your strings contain numbers that need to be naturally sorted.'text': Sorts by text/string values without case-sensitivity. Faster, but less accurate if your strings contain numbers that need to be naturally sorted.'textCaseSensitive': Sorts by text/string values with case-sensitivity. Faster, but less accurate if your strings contain numbers that need to be naturally sorted.'datetime': Sorts by time; use this if your values areDateobjects.'basic': Sorts using basic JavaScript value comparison. This is the fastest sorting function, but may not be the most accurate.
To specify the sorting function for a column, use the sortingFn property.
{ header: 'Column 1', accessorKey: 'col1', sortingFn: 'alphanumeric',}Custom sorting
There may be times when the built-in sorting functions do not meet your needs. In these cases, you can create your own custom sorting functions.
const myCustomSortingFn = (rowA, rowB, columnId) => { /* * This is just a simple example to show how to create a custom sorting function, * but it is generally not recommended to allocate new objects in sorting functions. * Especially when working with large data sets, this can cause a noticeable performance hit. * In this example, it would be best if the row data contained `dayjs` objects instead of strings. */ const dateA = dayjs(rowA.original[columnId]); const dateB = dayjs(rowB.original[columnId]); return dateA.diff(dateB);};
// ...
{ header: 'Date', accessorKey: 'col2', sortingFn: myCustomSortingFn,},See the TanStack Table sorting docs for more details.
The example below demonstrates the 'datetime' sorting function not working correctly when the leading zeros are removed from the months and days in the dates and a custom sorting function to sort the dates correctly.
Note: We recommend not using what's in this example to display dates (i.e., directly formatting the date as a string in the column data). Instead, use the cell property of the column to format the date for display. The 'datetime' sorting function works on the underlying data, not the displayed value, so it will sort correctly regardless of how the date is displayed.
Multi-column sorting
Multi-column sorting is disabled by default. To enable multi-column sorting, set tableConfig.enableMultiSort to true. This requires tableConfig.enableSorting to be true as well.
const dataTableProps = useDataTable({ // ... tableConfig: { enableSorting: true, enableMultiSort: true, }, // ...});The enableMultiSort property can also be provided to individual columns for more granular adjustment.
{ header: 'Column 1', accessorKey: 'col1', enableMultiSort: true}By default, the Shift key is used to trigger multi-column sorting. You can change this behavior with the tableConfig.isMultiSortEvent function. This function receives the event as an argument and should return a boolean value indicating whether the event should trigger multi-column sorting.
const dataTableProps = useDataTable({ // ... tableConfig: { isMultiSortEvent: (e) => { return true; // Always trigger multi-column sorting }, // or isMultiSortEvent: (e) => { return e.ctrlKey || e.shiftKey; // Use the Control or Shift keys to trigger multi-column sorting }, }, // ...});By default, there is no limit to the number of columns that can be sorted at once. Use the tableConfig.maxMultiSortColCount property to specify a limit.
const dataTableProps = useDataTable({ // ... tableConfig: { maxMultiSortColCount: 2, // Only allow up to two columns to be sorted at once }, // ...});Here is an advanced multi-column sorting example with a limit of two columns and with multi-column sorting enabled on click.
Component Tokens
Note: Click on the token row to copy the token to your clipboard.
DataTable Tokens
| Token Name | Value | |
|---|---|---|
| data-table.color.border.column-header.drag | #002677 | |
| data-table.color.border.root | #CBCCCD | |
| data-table.color.border.row.drag | #002677 | |
| data-table.color.border.table | #CBCCCD | |
| data-table.color.icon.column-header-menus.grouping.active | #002677 | |
| data-table.color.icon.column-header-menus.grouping.hover | #004BA0 | |
| data-table.color.icon.column-header-menus.grouping.rest | #196ECF | |
| data-table.color.icon.column-header-menus.sorting.active | #002677 | |
| data-table.color.icon.column-header-menus.sorting.hover | #004BA0 | |
| data-table.color.icon.column-header-menus.sorting.rest | #196ECF | |
| data-table.color.icon.drag-handle.active | #002677 | |
| data-table.color.icon.drag-handle.hover | #004BA0 | |
| data-table.color.icon.drag-handle.rest | #196ECF | |
| data-table.color.icon.expander.active | #002677 | |
| data-table.color.icon.expander.disabled | #7D7F81 | |
| data-table.color.icon.expander.hover | #004BA0 | |
| data-table.color.icon.expander.rest | #196ECF | |
| data-table.color.icon.utility.drag-alternative.active | #000000 | |
| data-table.color.icon.utility.drag-alternative.disabled | #7D7F81 | |
| data-table.color.icon.utility.drag-alternative.hover | #323334 | |
| data-table.color.icon.utility.drag-alternative.rest | #4B4D4F | |
| data-table.color.icon.utility.filter.active | #002677 | |
| data-table.color.icon.utility.filter.hover | #004BA0 | |
| data-table.color.icon.utility.filter.rest | #196ECF | |
| data-table.color.surface.column-header.active | #E5F8FB | |
| data-table.color.surface.column-header.default | #F3F3F3 | |
| data-table.color.surface.column-header.drag | #E5F8FB | |
| data-table.color.surface.footer | #F3F3F3 | |
| data-table.color.surface.header | #FFFFFF | |
| data-table.color.surface.root | #FFFFFF | |
| data-table.color.surface.row.drag | #E5F8FB | |
| data-table.color.surface.row.even | #FAFCFF | |
| data-table.color.surface.row.highlighted | #E5F8FB | |
| data-table.color.surface.row.hover | #F3F3F3 | |
| data-table.color.surface.row.odd | #FFFFFF | |
| data-table.color.surface.table | #FFFFFF | |
| data-table.color.text.cell | #4B4D4F | |
| data-table.color.text.column-header | #4B4D4F | |
| data-table.color.text.header.heading | #002677 | |
| data-table.color.text.header.paragraph | #4B4D4F | |
| data-table.border-radius.all.container | 8px | |
| data-table.border-width.all.column-header.drag | 2px | |
| data-table.border-width.all.root | 1px | |
| data-table.border-width.all.row.drag | 2px | |
| data-table.border-width.all.table | 1px | |
| data-table.sizing.all.icon.column-header-menus | 20px | |
| data-table.sizing.all.icon.drag-handle-row | 24px | |
| data-table.sizing.all.icon.expander-column | 24px | |
| data-table.sizing.all.icon.utility.drag-alternative | 20px | |
| data-table.sizing.all.icon.utility.filter | 20px | |
| data-table.sizing.height.cell.comfortable | 48px | |
| data-table.sizing.height.cell.compact | 32px | |
| data-table.sizing.height.cell.cozy | 40px | |
| data-table.spacing.gap.horizontal.button-group | 8px | |
| data-table.spacing.gap.horizontal.cell | 4px | |
| data-table.spacing.gap.horizontal.drag-alternative | 8px | |
| data-table.spacing.gap.horizontal.input-container | 8px | |
| data-table.spacing.gap.horizontal.slot-wrapper | 24px | |
| data-table.spacing.gap.vertical.column-header | 2px | |
| data-table.spacing.gap.vertical.header | 4px | |
| data-table.spacing.gap.filter-two-inputs | 16px | |
| data-table.spacing.padding.all.column-header | 8px | |
| data-table.spacing.padding.all.column-header-menus | 2px | |
| data-table.spacing.padding.all.header | 16px | |
| data-table.spacing.padding.all.result-text | 16px | |
| data-table.spacing.padding.all.slot-wrapper | 16px | |
| data-table.spacing.padding.horizontal.cell | 8px | |
| data-table.spacing.padding.vertical.button-group | 8px | |
| data-table.spacing.padding.vertical.cell | 4px | |
| data-table.elevation.column.pinned.left | 6px 0px 8px -2px rgba(0,0,0,0.16) | |
| data-table.elevation.column.pinned.right | -6px 0px 8px -2px rgba(0,0,0,0.16) | |
| data-table.elevation.column-header | 0px 6px 8px -2px rgba(0,0,0,0.16) | |
| data-table.elevation.table-settings-dropdown.section-header | 0px 2px 4px -2px rgba(0,0,0,0.16) |