React Bootstrap Datatable
Inspired by react-data-components. This library uses react-bootstrap stylesheets and javascripts. In addition, this library also uses font-awesome for the table header, clear filter, and other stuffs.
What's new in v2?
- TypeScript! The Table comes out with the
*.d.tsfiles. You should be more type-safe now. - Async capability for huge amount of data. Filtering, sorting, and pagination all support this feature.
- Custom table components. Tired of using Bootstrap? I know the lib name is Bootstrap, but maybe you want to change it to something else!
- Of course, there may be some breaking changes. Please see the updated docs and Storybook demo for the most up-to-date usages.
Table of Contents
Installation
# With NPM.
npm install --save react-bs-datatable bootstrap-sass font-awesome
# With Yarn.
yarn add react-bs-datatable bootstrap-sass font-awesome
Usage
import React from 'react';
import Datatable from 'react-bs-datatable';
// Create table headers consisting of 4 columns.
const header = [
{ title: 'Username', prop: 'username' },
{ title: 'Name', prop: 'realname' },
{ title: 'Location', prop: 'location' }
];
// Randomize data of the table columns.
// Note that the fields are all using the `prop` field of the headers.
const body = Array.from(new Array(57), () => {
const rd = (Math.random() * 10).toFixed(1);
if (rd > 0.5) {
return {
username: 'i-am-billy',
realname: `Billy ${rd}`,
location: 'Mars'
};
}
return {
username: 'john-nhoj',
realname: `John ${rd}`,
location: 'Saturn'
};
});
// Then, use it in a component.
function Component() {
return <Datatable tableHeaders={header} tableBody={body} />;
}
Storybook Demo.
Head to https://imballinst.github.io/react-bs-datatable to see all of the features in action.
- Sort
- Filter
- Pagination
- Custom Labels
- Presentational and raw data separation
- Custom column sort and column filter function
- Custom classes
- Create your own table by extending the existing features
- Async
- Custom Table Components (e.g. using Material UI Components)
Props
| Prop | Type | Description | Default |
|---|---|---|---|
tableHeaders* |
Array |
Table headers. See tableHeaders prop. | - |
tableBody* |
Array |
Table body. See tableBody prop. | - |
initialSort |
Object |
Initial sort. See initialSort prop. | - |
onSort |
Object |
Object containing custom sort functions. See onSort prop. | - |
onFilter |
Object |
Object containing custom filter functions. See onFilter prop. | - |
classes |
Object |
Custom classes. See classes prop. | - |
async |
Object |
Enable asynchronous actions. See async prop. | - |
labels |
Object |
Custom labels inside the table. See labels prop. | {} |
rowsPerPage |
number |
Initial rows per page. | - |
rowsPerPageOption |
number[] |
Pagination options. | - |
Components |
Object |
Custom table components. | - |
onRowClick |
(data: any) => void |
Row click event. See onRowClick prop. | - |
cellProps |
Object |
Props passed to the cells. See cellProps prop. | - |
tableHeaders
| Field | Type | Description |
|---|---|---|
prop* |
string |
Column name for the table body. |
headerCell |
(icon: React.ReactNode, sortedProp: SortType) => React.ReactNode |
Render a custom header cell. Overrides title prop. |
cell |
(row: any) => React.ReactNode |
Render a custom column cell. |
filterable |
boolean |
Enable/disable filtering on the column. |
sortable |
boolean |
Enable/disable sorting on the column. |
title |
string |
Text for the header column. |
tableBody
The table body prop consists of key-value mapping of the headers that we already define in tableHeaders. For example:
const tableHeaders = [
{ prop: 'name', title: 'Name' },
{ prop: 'score', title: 'Score' }
];
// Here, `tableBody` consists of object with the key "name" and "score".
const tableBody = [
{ name: 'Jack', score: 100 },
{ name: 'Sam', score: 55 }
];
initialSort
| Field | Type | Description |
|---|---|---|
prop* |
string |
Currently sorted prop. |
isAscending* |
boolean |
true if ascending, otherwise false. |
onSort
The onSort prop consists of key-value mapping of the headers that we already define in tableHeaders, as well. This function is mostly used to sort columns that don't represent its actual value. For example:
const tableHeaders = [
{ prop: 'name', title: 'Name' },
// The format of the date here is, say, dd MMM YYYY.
{ prop: 'date', title: 'Test date' },
{ prop: 'score', title: 'Score' }
];
// Here, `onSort` consists of columns that we want to have a custom filter function.
const onSort = {
date: (value: any) => {
// This will convert the string to integer.
// Otherwise, the date will be sorted by date-month-year instead of year-month-date (in order).
return moment(value, 'dd MMM YYYY').valueOf();
}
};
onFilter
onFilter's usage is the same as onSort. It allows us to filter columns that don't represent their actual values.
classes
This prop is used to add custom styles to the table.
| Field | Type | Description |
|---|---|---|
controlRow |
string |
Control row (filter, pagination options, and pagination). |
filterCol |
string |
Filter column. |
filterInputGroup |
string |
Filter Input.Group. |
filterFormControl |
string |
Filter Form.Control. |
filterClearButton |
string |
Filter Button. |
paginationOptsCol |
string |
Pagination options column. |
paginationOptsForm |
string |
Pagination options Form. |
paginationOptsFormGroup |
string |
Pagination options Form.Group. |
paginationOptsFormText |
string |
Pagination options form text (the "Show ... rows"). |
paginationOptsFormControl |
string |
Pagination options Form.Control. |
paginationCol |
string |
Pagination column. |
paginationButtonGroup |
string |
Pagination ButtonGroup. |
paginationButton |
string |
Pagination Button. |
table |
string |
table element. |
thead |
string |
thead element. |
theadRow |
string |
tr element inside thead. |
theadCol |
string |
th element. |
tbody |
string |
tbody element. |
tbodyRow |
string |
tr element inside tbody. |
tbodyCol |
string |
td element. |
async
| Field | Type | Description |
|---|---|---|
filterText |
string |
The value of the filter input field. |
sortedProp |
SortType |
See initialSort prop. |
rowsPerPage |
number |
Value of the rows per page |
currentPage |
number |
Value of the current page shown. |
maxPage |
number |
Total numbers of page. |
onSort |
(nextProp: string) => void |
Event fired when a column is sorted. |
onPaginate |
(nextPage: number) => void |
Event fired when the table page updates. |
onFilter |
(text: string) => void |
Event fired when the filter text updates. |
onRowsPerPageChange |
(numOfPage: RowsPerPageType) => void |
Event fired when rows per page updates. |
labels
| Field | Type | Description |
|---|---|---|
first |
string |
First page label button. |
last |
string |
Last page label button. |
prev |
string |
Previous page label button. |
next |
string |
Next page label button. |
show |
string |
The text before rows per page option. |
entries |
string |
The text after rows per page option. |
noResults |
string |
Displayed text if tableBody is []. |
filterPlaceholder |
string |
Placeholder text for filter input field. |
Components
We can override Bootstrap's components when we want to, with the types defined as the following:
// Primitive types.
type FilterGroupProps = {
filterText: string;
onChangeFilter: (event: any) => void;
onClearFilter?: () => void;
placeholder?: string;
classes: TableClasses;
};
type PaginationOptsGroupProps = {
labels: LabelType;
value?: number;
options: number[];
onChange: any;
classes: TableClasses;
};
// Component types.
type TableComponentType = React.ElementType<any> | string;
type PaginationOptsGroupFunctionComponent = (
props: PaginationOptsGroupProps
) => JSX.Element;
type FilterGroupFunctionComponent = (props: FilterGroupProps) => JSX.Element;
// Type of the `Components` prop.
type TableComponents = {
// Global.
Row: TableComponentType;
Col: TableComponentType;
Button: TableComponentType;
// Table.
Table: TableComponentType;
TableHead: TableComponentType;
TableBody: TableComponentType;
TableRow: TableComponentType;
TableCell: TableComponentType;
// Filter.
FilterGroup?: FilterGroupFunctionComponent;
// Pagination.
ButtonGroup: TableComponentType;
// Pagination options.
PaginationOptsGroup?: PaginationOptsGroupFunctionComponent;
// Icons.
SortIcon: TableComponentType;
};
To see its usage, see the example in the Storybook.
onRowClick
When we want to add a click event to the table rows, we can use this prop.
function onRowClick(row) {
alert(`You clicked on the row ${JSON.stringify(row)}`);
}
// This will trigger an alert, containing the notification text and the JSON string of the row data.
<Datatable onRowClick={onRowClick} />;
cellProps
Currently, the only available props are className and style. The type of this prop is:
export type HeaderType = {
// ...
cellProps?: {
className?: string | ((row: any) => string);
style?: CSSProperties | ((row: any) => CSSProperties);
};
};
The className can be either a string or a function with single parameter, row. This row is the row's data. This is useful if we want to change a cell's className based on the data inside the row.
The same goes for the style prop. The difference is, instead of a string, it returns CSSProperties instead. We use it just like we use the style prop on JSX.
Next Features or Improvements
- Automated documentation change on code updates
- Analyze code size
Contributing
Feel free to contribute by creating issues and/or pull requests. I will do my best to address them as fast as I can.
