import { DataTable } from '@uhg-abyss/web/ui/DataTable';import { useDataTable } from '@uhg-abyss/web/hooks/useDataTable';Column properties
Header
You can modify the displayed header by using the header property in the column configuration. This accepts either a string, for a basic header, or a function, for more customization.
Note: If header (or the function return value) is not a string value, you must also use the headerLabel property for accessibility and configuration reasons.
{ header: () => { return ( <React.Fragment> <IconSymbol icon="home" size="24px" /> Home Column </React.Fragment> ); }, accessorKey: 'col1', meta: { headerLabel: 'Home Column', },}Row headers (accessibility requirement)
For accessibility purposes, you will need to define which column best labels the contents of its row. This changes cells in that column from <th> to <th scope="row"> to help screen reader users more clearly understand data in that row.
const dataTableProps = useDataTable({ // ... initialColumns: [ { header: 'Name', accessorKey: 'name', meta: { isRowHeader: true, }, }, // ... ], // ...});Cell
Use the cell property to modify the display value of the cells in a column. If the cell property is not used, the cell will simply display the data value.
Note: By default, all built-in sorting and filtering is performed on the underlying data itself. Refer to the Cell filtering and sorting section for more information.
{ header: 'Column 1', accessorKey: 'col1', cell: (props) => { const value = props.getValue(); return ( <React.Fragment> <IconSymbol icon="home" size="24px" /> {value} </React.Fragment> ); },}Footer
Use the footer property to add a footer to the column. Like header, this accepts either a string, for a basic footer, or a function, for more customization.
{ header: 'Column 1', accessorKey: 'col1', footer: 'Footer 1',}By default, the column footer is not sticky. To enable this behavior, set the stickyFooter prop to true on the table component.
return ( // ... <DataTable.Table stickyFooter={false} /> // ...);Cell filtering and sorting
When using only the cell property to format display values, all built-in sorting and filtering operations will still use the original underlying data. For formatted values (like dates or currency) to work properly with sorting and filtering, use the accessorFn property to transform the data at the source level.
Here are two examples that show it being used and working correctly and the other not working correctly (not using accessorFn).
Note: cell should primarily be used for display purposes only. If you need to format the data for sorting or filtering, use accessorFn instead.
// Correct setup{ header: 'Formatted Date', accessorKey: 'col2', accessorFn: (row) => dayjs(row.col2).format('MMMM D, YYYY'),},// Incorrect setup{ header: 'Formatted Date', accessorKey: 'col2', cell: ({ getValue }) => { return dayjs(getValue()).format('MMMM D, YYYY'); },},Still need more control over filtering and sorting? Refer to our custom sorting and filtering examples
Column configuration
Column width
By default, all columns have a width of 175px. To override this default value and/or to specify minimum or maximum widths, use the tableConfig.defaultColumn property. This property accepts an object with the following properties:
minSize: The minimum width of the column.size: The default width of the column.maxSize: The maximum width of the column.
const dataTableProps = useDataTable({ // ... tableConfig: { defaultColumn: { size: 200, minSize: 100, maxSize: 300, }, }, // ...});maxSize, size, and minSize can also be provided to individual columns for more granular adjustment.
{ header: 'Column 1', accessorKey: 'col1', minSize: 100, size: 150, maxSize: 300,}Customizing column order
To change the order of the columns, use the initialColumnOrder property of the initialStateConfig object.
Note: initialColumnOrder should be an array of ALL column IDs. Columns managed by Abyss will be prefixed with 'abyss-'.
const dataTableProps = useDataTable({ // ... initialStateConfig: { initialColumnOrder: ['col4', 'abyss-reorder-row', 'col3', 'col2', 'col1'], // ... },});To programmatically change the column order, use the setColumnOrder method.
const dataTableProps = useDataTable({ // ...});
const reorderColumns = () => { const newOrder = ['col4', 'col3', 'col2', 'abyss-reorder-row', 'col1']; dataTableProps.columnOrderState.setColumnOrder(newOrder);};
// ...
return <Button onClick={reorderColumns}>Reorder Columns</Button>;Note: Sticky/pinned columns will always appear to the left or right of the table regardless of the specified column order. For instance, in the example below, the abyss-reorder-row column will always be the first column in the table.
Resizing columns
The ability to resize columns is disabled by default. To enable resizing for all columns, set tableConfig.enableResizing to true.
const dataTableProps = useDataTable({ // ... tableConfig: { enableColumnResizing: true; } // ...});enableResizing can also be set on individual columns for more granular control.
{ header: 'Column 1', accessorKey: 'col1', enableResizing: true,}With the default setting, columnResizeMode: 'onChange', columns resize in real time as you drag the resizer handle.
Note: 'onChange' mode can cause performance issues with large tables, so it is recommended to set tableConfig.columnResizeMode to 'onEnd' for better performance.
Sticky/pinned columns
Sticky (or pinned) columns are columns that remain fixed in place while the rest of the table scrolls. This is useful for keeping important information visible while scrolling through large data sets. To pin columns, use the initialStateConfig.initialPinnedColumns property. This property accepts a left and right array of column accessors.
Note: All Abyss-managed columns are pinned internally, so there is no need to include them in the initialPinnedColumns array. However, they can be included to override the default order and placement.
const dataTableProps = useDataTable({ // ... initialStateConfig: { initialPinnedColumns: { left: ['abyss-reorder-row', 'abyss-select', 'abyss-expand'], right: ['abyss-edit-action', 'abyss-action'], }, // ... },});To programmatically change the pinned column order, use the setColumnPinning method.
const dataTableProps = useDataTable({ //...});
const pinNewColumns = () => { const newPinning = { left: ['col1'], right: ['col4', 'col5'], }; dataTableProps.columnPinningState.setColumnPinning(newPinning);};
//...
return <Button onClick={pinNewColumns}>Pin Col1, Col4, and Col5</Button>;Column display
Table settings dropdown
The DataTable.TableSettingsDropdown subcomponent provides a dropdown menu for editing column visibility and order as well as table density.
<DataTable.TableSettingsDropdown />By default, empty columns—columns with no content in the cells—are visible by default. This can be changed by setting defaultSettingsConfig.hideEmptyColumns to true.
const dataTableProps = useDataTable({ // ... defaultSettingsConfig: { hideEmptyColumns: true, }, // ...});Note: It is not required to use DataTable.TableSettingsDropdown to take advantage of defaultSettingsConfig.hideEmptyColumns. Currently, DataTable.TableSettingsDropdown does not contain a way for users to toggle the visibility of empty columns, so this must be done programmatically.
Programmatically change column visibility
To programmatically change the visibility of columns, provide a function to the tableConfig.onColumnVisibilityChange property and set the state.columnVisibility property; we recommend using useState for this, as shown below.
const [columnVisibility, setColumnVisibility] = useState({ columnId1: true, columnId2: false, columnId3: true,});
const dataTableProps = useDataTable({ //... tableConfig: { onColumnVisibilityChange: setColumnVisibility, state: { columnVisibility, }, }, // ...});The enableHiding property can also be provided to individual columns for more granular adjustment.
{ header: 'Column 4', accessorKey: 'col4', enableHiding: false,}Note: When enableHiding is set to false, the column visibility checkbox in the table settings dropdown will be disabled. However, it is still possible to hide the column programmatically. To prevent this, you will need to ensure that the column is not included in the columnVisibility state when updating it.
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) |