Theme

Component properties

Mantine DataTable component is written in TypeScript and its properties are well documented with additional JSDoc annotations, so you can harness the full power of your IDE to build type safe applications with confidence.
Here are the type definitions:
DataTableProps.ts
import type { DefaultProps, MantineShadow, MantineTheme, ScrollAreaProps, Sx, TableProps } from '@mantine/core';
import type { CSSProperties, Key, MouseEvent, ReactNode, RefObject } from 'react';
import type {
DataTableCellClickHandler,
DataTableContextMenuProps,
DataTableDefaultColumnProps,
DataTableEmptyStateProps,
DataTableOuterBorderProps,
DataTablePaginationProps,
DataTableRowExpansionProps,
DataTableSelectionProps,
DataTableSortProps,
DataTableVerticalAlignment,
} from './';
import type { DataTableColumnProps } from './DataTableColumnProps';
import type { DataTableLoaderProps } from './DataTableLoaderProps';
export type DataTableProps<T> = {
/**
* Table height; defaults to `100%`
*/
height?: string | number;
/**
* Minimum table height
*/
minHeight?: string | number;
/**
* `DataTable` component shadow
*/
shadow?: MantineShadow;
/**
* If true, columns will have vertical borders
*/
withColumnBorders?: boolean;
/**
* Table border color, applied to the outer border, the header bottom border, and the pagination
* footer top border; defaults to
* `(theme) => (theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[3])`
*/
borderColor?: string | ((theme: MantineTheme) => string);
/**
* Row border color; defaults to
* `(theme) => (theme.fn.rgba(theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[3], 0.65))`
*/
rowBorderColor?: string | ((theme: MantineTheme) => string);
/**
* If true, the user will not be able to select text
*/
textSelectionDisabled?: boolean;
/**
* Vertical alignment for row cells; defaults to `center`
*/
verticalAlignment?: DataTableVerticalAlignment;
/**
* If true, will show a loader with semi-transparent background, centered over the table
*/
fetching?: boolean;
/**
* If true, the last column will be pinned to the right side of the table.
*/
pinLastColumn?: boolean;
/**
* Default column props; will be merged with column props provided to each column
*/
defaultColumnProps?: DataTableDefaultColumnProps<T>;
/**
* If you want to use drag and drop as well as toggle to reorder and toggle columns
* provide a unique key which will be used to store the column order in localStorage.
*/
storeColumnsKey?: string | undefined;
/**
* A default render function for all columns; accepts the current record, its index in `records`
* and the column accessor
*/
defaultColumnRender?: (record: T, index: number, accesor: string) => ReactNode;
/**
* Accessor to use as unique record key; can be a string representing a property name
* or a function receiving the current record and returning a unique value.
* If you're providing a string, you can use dot-notation for nested objects property drilling
* (i.e. `department.name` or `department.company.name`);
* defaults to `id`
*/
idAccessor?: string | ((record: T) => Key);
/**
* Visible records; the `DataTable` component will try to infer its row type from here
*/
records?: T[];
/**
* Text to show on empty state and pagination footer when no records are available
*/
noRecordsText?: string;
/**
* If true, the table will not show the header with column titles
*/
noHeader?: boolean;
/**
* Function to call when a row cell is clicked
*/
onCellClick?: DataTableCellClickHandler<T>;
/**
* Function to call when a row is clicked, receiving the current record, its index in `records` and the click event
*/
onRowClick?: (record: T, recordIndex: number, event: MouseEvent) => void;
/**
* Function to call when the DataTable is scrolled to top
*/
onScrollToTop?: () => void;
/**
* Function to call when the DataTable is scrolled to bottom
*/
onScrollToBottom?: () => void;
/**
* Function to call when the DataTable is scrolled to left
*/
onScrollToLeft?: () => void;
/**
* Function to call when the DataTable is scrolled to right
*/
onScrollToRight?: () => void;
/**
* Defines a context-menu to show when user right-clicks or clicks on a row
*/
rowContextMenu?: DataTableContextMenuProps<T>;
/**
* Defines the row expansion behavior
*/
rowExpansion?: DataTableRowExpansionProps<T>;
/**
* Optional class name passed to each row; can be a string or a function
* receiving the current record and its index as arguments and returning a string
*/
rowClassName?: string | ((record: T, recordIndex: number) => string | undefined);
/**
* Optional style passed to each row; can be a CSS properties object or
* a function receiving the current record and its index as arguments and returning a CSS properties object
*/
rowStyle?: CSSProperties | ((record: T, recordIndex: number) => CSSProperties | undefined);
/**
* Optional style passed to each row; see https://mantine.dev/styles/sx/
*/
rowSx?: Sx;
/**
* Optional function returning an object of custom attributes to be applied to each row in the table.
* Receives the current record and its index as arguments.
* Useful for adding data attributes, handling middle-clicks, etc.
*/
customRowAttributes?: (record: T, recordIndex: number) => Record<string, unknown>;
/**
* Ref pointing to the scrollable viewport element; useful for imperative scrolling
*/
scrollViewportRef?: RefObject<HTMLDivElement>;
/**
* Additional props passed to the underlying `ScrollArea` element
*/
scrollAreaProps?: Omit<ScrollAreaProps, 'classNames' | 'styles' | 'onScrollPositionChange'>;
/**
* Ref pointing to the table body element
*/
bodyRef?: ((instance: HTMLTableSectionElement | null) => void) | RefObject<HTMLTableSectionElement>;
} & Pick<TableProps, 'striped' | 'highlightOnHover' | 'horizontalSpacing' | 'verticalSpacing' | 'fontSize'> &
Omit<
DefaultProps<'root' | 'header' | 'footer' | 'pagination', CSSProperties>,
'unstyled' | 'p' | 'px' | 'py' | 'pt' | 'pb' | 'pl' | 'pr'
> &
DataTableColumnProps<T> &
DataTableOuterBorderProps &
DataTableLoaderProps &
DataTableEmptyStateProps &
DataTablePaginationProps &
DataTableSortProps &
DataTableSelectionProps<T>;
DataTableColumnProps.ts
import type { DataTableColumn } from './DataTableColumn';
import type { DataTableColumnGroup } from './DataTableColumnGroup';
export type DataTableColumnProps<T> =
| {
/**
* Grouped columns
*/
groups: readonly DataTableColumnGroup<T>[];
columns?: never;
}
| {
/**
* Visible columns
*/
columns: DataTableColumn<T>[];
groups?: never;
};
DataTableDefaultColumnProps.ts
import type { DataTableColumn } from './DataTableColumn';
export type DataTableDefaultColumnProps<T> = Omit<
DataTableColumn<T>,
'accessor' | 'hidden' | 'visibleMediaQuery' | 'render'
>;
DataTableColumn.ts
import type { MantineTheme, Sx } from '@mantine/core';
import type { CSSProperties, ReactNode } from 'react';
import type { DataTableColumnTextAlignment } from './DataTableColumnTextAlignment';
export type DataTableColumn<T> = {
/**
* Column accessor; you can use dot-notation for nested objects property drilling
* (i.e. `department.name` or `department.company.name`)
*/
accessor: string;
/**
* Optional column header title; if not present, one will be generated by "humanizing"
* the provided column accessor
* (i.e. `firstName` -> `First name`; `user.firstName` -> `User first name`)
*/
title?: ReactNode;
/**
* Custom cell data render function accepting the current record and its index in `records`
*/
render?: (record: T, index: number) => ReactNode;
/**
* Column text alignment; defaults to `left`
*/
textAlignment?: DataTableColumnTextAlignment;
/**
* If true, column will be sortable
*/
sortable?: boolean;
/**
* If set to true, the column can be dragged.
*/
draggable?: boolean;
/**
* If set to true, the column can be toggled.
*/
toggleable?: boolean;
/**
* If set to true, the column can be resized.
*/
resizable?: boolean;
/**
* If set to true, the column will be toggled by default.
*/
defaultToggle?: boolean;
/**
* Optional node providing the user with filtering options.
* If present, a filter button will be added to the column's header. Upon clicking that button,
* a pop-over showing the provided node will be opened.
*
* Alternatively, a function returning a node can be provided. The function receives props with a `close`
* method which allows programmatically closing the pop-over.
*
* ```tsx
* // …
* columns={[
* {
* accessor: 'name',
* filter: ({ close }) => {
* return <Stack>
* <Button onClick={() => { setFilter(undefined); close(); }}>Reset</Button>
* </Stack>
* },
* }
* ]}
* // …
* ```
*
* Note: this property only takes care of rendering the node which provides the filtering options.
* It is assumed that the actual filtering is performed somewhere in user code.
*/
filter?: ReactNode | ((filterProps: { close: () => void }) => ReactNode);
/**
* If true, filter icon will be styled differently to indicate the filter is in effect.
*/
filtering?: boolean;
/**
* Desired column width
*/
width?: string | number;
/**
* If true, column will not be visible
*/
hidden?: boolean;
/**
* If set, the column will only be visible according to the specified media query
*/
visibleMediaQuery?: string | ((theme: MantineTheme) => string);
/**
* Optional class name passed to the column title
*/
titleClassName?: string;
/**
* Optional style passed to the column title
*/
titleStyle?: CSSProperties;
/**
* Optional style passed to the column title; see https://mantine.dev/styles/sx/
*/
titleSx?: Sx;
/**
* Optional class name passed to each data cell in the column; can be a string or a function
* receiving the current record and its index as arguments and returning a string
*/
cellsClassName?: string | ((record: T, recordIndex: number) => string | undefined);
/**
* Optional style passed to each data cell in the column; can be a CSS properties object or
* a function receiving the current record and its index as arguments and returning a CSS properties object
*/
cellsStyle?: CSSProperties | ((record: T, recordIndex: number) => CSSProperties | undefined);
/**
* Optional style passed to each data cell in the column; see https://mantine.dev/styles/sx/
*/
cellsSx?: Sx;
/**
* Optional function returning an object of custom attributes to be applied to each cell in the column.
* Receives the current record and its index as arguments.
* Useful for adding data attributes, handling middle-clicks, etc.
*/
customCellAttributes?: (record: T, recordIndex: number) => Record<string, unknown>;
/**
* Optional column footer content; if at least one column has a footer, the table will display a footer row
*/
footer?: ReactNode;
/**
* Optional class name passed to the column footer
*/
footerClassName?: string;
/**
* Optional style passed to the column footer
*/
footerStyle?: CSSProperties;
/**
* Optional style passed to the column footer; see https://mantine.dev/styles/sx/
*/
footerSx?: Sx;
} & (
| {
/**
* If true, cell content in this column will be truncated with ellipsis as needed and will not wrap
* to multiple lines.
* (i.e. `overflow: hidden; text-overflow: ellipsis`; `white-space: nowrap`)
* On a column you can either set this property or `noWrap` but not both.
*/
ellipsis?: boolean;
noWrap?: never;
}
| {
ellipsis?: never;
/**
* If true, cell content in this column will not wrap to multiple lines
* (i.e. `white-space: nowrap`)
* On a column you can either set this property or `ellipsis` but not both.
*/
noWrap?: boolean;
}
);
DataTableColumnGroup.ts
import type { Sx } from '@mantine/core';
import type { CSSProperties, ReactNode } from 'react';
import type { DataTableColumn } from './DataTableColumn';
export type DataTableColumnGroup<T> = {
/**
* Used as the `key` prop for the created `<th />`.
*/
id: string;
/**
* Component to render inside the column group header
*/
title?: ReactNode;
/**
* Columns which are part of the group.
*/
columns: readonly DataTableColumn<T>[];
className?: string;
sx?: Sx;
style?: CSSProperties;
};
DataTableColumnTextAlignment.ts
export type DataTableColumnTextAlignment = 'left' | 'center' | 'right';
DataTableVerticalAlignment.ts
export type DataTableVerticalAlignment = 'top' | 'center' | 'bottom';
DataTableOuterBorderProps.ts
import type { MantineNumberSize } from '@mantine/core';
export type DataTableOuterBorderProps =
| {
withBorder?: never;
borderRadius?: never;
}
| {
/**
* If true, table will have border
*/
withBorder: boolean;
/**
* Table border radius
*/
borderRadius?: MantineNumberSize;
};
DataTableEmptyStateProps.ts
import type { ReactNode } from 'react';
export type DataTableEmptyStateProps =
| {
/**
* Content to show when no records are available; the provided content
* will be overlaid and centered automatically
*/
emptyState?: ReactNode;
noRecordsIcon?: never;
}
| {
emptyState?: never;
/**
* Icon to show when no records are available
*/
noRecordsIcon?: ReactNode;
};
DataTableLoaderProps.ts
import type { DefaultMantineColor, MantineNumberSize, MantineTheme } from '@mantine/core';
import type { ReactNode } from 'react';
export type DataTableLoaderProps = {
/**
* Loader background blur (in pixels)
*/
loaderBackgroundBlur?: number;
} & (
| {
loaderSize?: never;
loaderVariant?: never;
loaderColor?: never;
/**
* Custom loader component to use instead of default one
*/
customLoader?: ReactNode;
}
| {
/**
* Loader size; defaults to `lg`
*/
loaderSize?: MantineNumberSize;
/**
* Loader variant
*/
loaderVariant?: MantineTheme['loader'];
/**
* Loader color
*/
loaderColor?: DefaultMantineColor;
customLoader?: never;
}
);
DataTablePaginationProps.ts
import type { MantineColor, MantineNumberSize, MantineSize } from '@mantine/core';
import type { ReactNode } from 'react';
import type { DataTablePageSizeSelectorProps } from './DataTablePageSizeSelectorProps';
export type DataTablePaginationProps = (
| {
page?: never;
onPageChange?: never;
totalRecords?: never;
recordsPerPage?: never;
paginationColor?: never;
paginationSize?: never;
loadingText?: never;
paginationText?: never;
paginationWrapBreakpoint?: never;
getPaginationControlProps?: never;
}
| {
/**
* Current page number (1-based); if provided, a pagination component is shown
*/
page: number;
/**
* Callback fired after change of each page
*/
onPageChange: (page: number) => void;
/**
* Total number of records in the dataset
*/
totalRecords: number | undefined;
/**
* Number of records per page
*/
recordsPerPage: number;
/**
* Pagination component size; defaults to `sm`
*/
paginationSize?: MantineSize;
/**
* Pagination component color; defaults to primary theme color
*/
paginationColor?: MantineColor;
/**
* Text to show while records are loading
*/
loadingText?: string;
/**
* Pagination text; defaults to ```({ from, to, totalRecords }) => `${from}-${to}/${totalRecords}`
* ```
*/
paginationText?: (options: { from: number; to: number; totalRecords: number }) => ReactNode;
/**
* Pagination wrap breakpoints; defaults to `sm`.
* Below this breakpoint the content will be displayed on multiple lines;
* above it the content will be displayed on a single line.
*/
paginationWrapBreakpoint?: MantineNumberSize;
/**
* Function that returns props object for pagination control; useful for improving accessibility
*/
getPaginationControlProps?: (control: 'previous' | 'next') => Record<string, unknown>;
}
) &
DataTablePageSizeSelectorProps;
DataTablePageSizeSelectorProps.ts
export type DataTablePageSizeSelectorProps =
| {
onRecordsPerPageChange?: never;
recordsPerPageOptions?: never;
recordsPerPageLabel?: never;
}
| {
/**
* Callback fired a new page size is selected
*/
onRecordsPerPageChange: (recordsPerPage: number) => void;
/**
* Array of options to show in records per page selector
*/
recordsPerPageOptions: number[];
/**
* Label for records per page selector
*/
recordsPerPageLabel?: string;
};
DataTableSortProps.ts
import type { ReactNode } from 'react';
import type { DataTableSortStatus } from './DataTableSortStatus';
export type DataTableSortProps =
| {
sortStatus?: never;
onSortStatusChange?: never;
sortIcons?: never;
}
| {
/**
* Current sort status (sort column accessor & direction)
*/
sortStatus: DataTableSortStatus;
/**
* Callback fired after change of sort status
*/
onSortStatusChange?: (sortStatus: DataTableSortStatus) => void;
/**
* Custom sort icons
*/
sortIcons?: {
/**
* Icon to display when column is sorted ascending;
* will be rotated 180deg for descending sort
*/
sorted: ReactNode;
/**
* Icon to display when column is not sorted
*/
unsorted: ReactNode;
};
};
DataTableSortStatus.ts
export type DataTableSortStatus = {
/**
* Sort column accessor; you can use dot-notation for nested objects property drilling
* (i.e. `department.name` or `department.company.name`)
*/
columnAccessor: string;
/**
* Sort direction; `asc` for ascending or `desc` for descending
*/
direction: 'asc' | 'desc';
};
DataTableSelectionProps.ts
export type DataTableSelectionProps<T> =
| {
selectedRecords?: never;
onSelectedRecordsChange?: never;
isRecordSelectable?: never;
getRecordSelectionCheckboxProps?: never;
allRecordsSelectionCheckboxProps?: never;
}
| {
/**
* Currently-selected records
*/
selectedRecords?: T[];
/**
* Callback fired when selected records change
*/
onSelectedRecordsChange?: (selectedRecords: T[]) => void;
/**
* A function used to determine whether a certain record is selectable;
* if the function returns false, the row selection checkbox is disabled
*/
isRecordSelectable?: (record: T, index: number) => boolean;
/**
* A function used to determine additional props of the row selection checkbox
*/
getRecordSelectionCheckboxProps?: (record: T, index: number) => Record<string, unknown>;
/**
* Additional props for the header checkbox that toggles selection of all records
*/
allRecordsSelectionCheckboxProps?: Record<string, unknown>;
};
DataTableContextMenuProps.ts
import type { MantineNumberSize, MantineShadow } from '@mantine/core';
import type { DataTableContextMenuItemProps } from './DataTableContextMenuItemProps';
export type DataTableContextMenuProps<T> = {
/**
* Context menu trigger; defaults to `rightClick` for classic behavior
*/
trigger?: 'rightClick' | 'click';
/**
* Menu z-index; defaults to `3`
*/
zIndex?: number;
/**
* Menu border radius; defaults to `xs`
*/
borderRadius?: MantineNumberSize;
/**
* Menu shadow; defaults to `sm`
*/
shadow?: MantineShadow;
/**
* Boolean or a function accepting the current record and its index as arguments and returning a boolean value;
* if true, the menu will not be shown
*/
hidden?: boolean | ((record: T, recordIndex: number) => boolean);
/**
* Function accepting the current record and its index as arguments and returning the row menu items
*/
items: (record: T, recordIndex: number) => DataTableContextMenuItemProps[];
};
DataTableContextMenuItemProps.ts
import type { MantineColor } from '@mantine/core';
import type { ReactNode } from 'react';
export type DataTableContextMenuItemProps =
| {
/**
* Unique item key
*/
key: string;
} & (
| {
/**
* If true, insert an actions divider
*/
divider: true;
icon?: never;
title?: never;
color?: never;
hidden?: never;
disabled?: never;
onClick?: never;
}
| {
divider?: never;
/**
* Item icon
*/
icon?: ReactNode;
/**
* Item title; if not present, one will be generated by "humanizing"
* the provided item key
* (i.e. `viewRecord` -> `View record`)
*/
title?: ReactNode;
/**
* Item color
*/
color?: MantineColor;
/**
* if true, the menu item will not be shown
*/
hidden?: boolean;
/**
* if true, the menu item will be disabled
*/
disabled?: boolean;
/**
* Function to call when the menu item is clicked
*/
onClick: () => void;
}
);
DataTableRowExpansionProps.ts
import type { Dispatch, ReactNode, SetStateAction } from 'react';
import type { DataTableRowExpansionCollapseProps } from './DataTableRowExpansionCollapseProps';
export type DataTableRowExpansionProps<T> = {
/**
* Defines when rows should expand; defaults to `click`
*/
trigger?: 'click' | 'always' | 'never';
/**
* If true, multiple rows can be expanded at the same time
*/
allowMultiple?: boolean;
/**
* Function defining which records will be initially expanded;
* does nothing if `trigger === 'always'`
*/
initiallyExpanded?: (record: T, recordIndex: number) => boolean;
/**
* Additional properties passed to the Mantine Collapse component wrapping the custom content
*/
collapseProps?: DataTableRowExpansionCollapseProps;
/**
* An object defining the row expansion behavior in controlled mode
*/
expanded?: {
/**
* Currently expanded record IDs
*/
recordIds: unknown[];
/**
* Callback fired when expanded records change;
* receives an array containing the newly expanded record IDs
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onRecordIdsChange?: Dispatch<SetStateAction<any[]>> | ((recordIds: unknown[]) => void);
};
/**
* Function returning the custom content to be lazily rendered for an expanded row;
* accepts the current record and a `collapse()` callback that can be used to collapse the expanded row
*/
content: (props: { record: T; recordIndex: number; collapse: () => void }) => ReactNode;
};
DataTableRowExpansionCollapseProps.ts
import type { CollapseProps } from '@mantine/core';
export type DataTableRowExpansionCollapseProps = Pick<
CollapseProps,
'animateOpacity' | 'transitionDuration' | 'transitionTimingFunction'
>;
DataTableCellClickHandler.ts
import type { MouseEvent } from 'react';
import type { DataTableColumn } from './DataTableColumn';
export type DataTableCellClickHandler<T> = (params: {
/**
* Click event
*/
event: MouseEvent;
/**
* Clicked record
*/
record: T;
/**
* Clicked record index
*/
recordIndex: number;
/**
* Clicked column information
*/
column: DataTableColumn<T>;
/**
* Clicked column index
*/
columnIndex: number;
}) => void;

Mantine DataTable is trusted by

MIT LicenseSponsor the author
Built by Ionut-Cristian Florescu and these awesome people.
Please sponsor the project if you find it useful.
GitHub StarsNPM Downloads