Sematable wraps a table component, and provides:
… with the ability to persist the table state in application state with Redux, so filters, sort info, selected rows, and pagination info survives route navigations.
If you would like to simply test the table alone in your browser, we have included React Storybook.
npm install
npm run storybook
Then open your browser to http://localhost:6006/. Try to delete the search filters and watch how the table responds. There are several stories featuring Filters, Bootstrap, and Editable cells.
Sematable assumes that Bootstrap CSS, Font Awesome CSS, and react-select CSS are already loaded, so please make sure that’s the case. Sematable should work with either Bootstrap 3 or Bootstrap 4. You can find the css for react-select in node_modules/react-select/dist/react-select.css
.
Before using the sematable wrapper, you need to setup the reducer. You should combine the provided reducer in your root reducer like this:
import { reducer as sematable } from 'sematable';
const reducer = combineReducers({
sematable,
...
});
The most frequent use case for sematable is to show tabular data with some actions (edit, delete, etc.). See the below example for that.
For information on how to get selected rows and other table state, check out the section about selectors.
AppsTable.js:
import React, { Component, PropTypes } from 'react';
import sematable, { Table } from 'sematable';
import AppsTableActions from './AppsTableActions';
const columns = [
{ key: 'id', header: 'ID', sortable: true, searchable: true, primaryKey: true },
{ key: 'name', header: 'Application', sortable: true, searchable: true },
{ key: 'token', header: 'Token' },
{ key: 'plan', header: 'Plan', sortable: true },
{ key: 'role', header: 'Role', sortable: true },
{ key: 'actions', header: 'Actions', Component: AppsTableActions },
];
const propTypes = {
headers: PropTypes.object.isRequired,
data: PropTypes.array.isRequired,
primaryKey: PropTypes.string.isRequired,
};
class AppsTable extends Component {
render() {
return (
<Table
{...this.props}
selectable
columns={columns}
/>
);
}
}
AppsTable.propTypes = propTypes;
export default sematable('allApps', AppsTable, columns);
AppsTableActions.js:
import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
const propTypes = {
row: PropTypes.object.isRequired,
};
class AppsTableActions extends Component {
render() {
const row = this.props.row;
return (
<Link to={`/settings/${row.id}`}>
Settings
</Link>
);
}
}
AppsTableActions.propTypes = propTypes;
export default AppsTableActions;
The sematable
function will wrap your component and add filter, pagination, and other sematable functionality. The first argument is name of this table. It should be unique across your app. The second argument is your component, and the third are the column definitions.
selectable
property to hide the row selection controls.className
property to set the table class (table-sm table-striped table-hover
is the default).Columns definitions have the following properties:
<td>
element(value)
signature that can be provided to customize the filter title(value)
signature that can be provided to customize the filter label(value)
signature that can be provided to customize the filter css classAt least one column definition should have primaryKey: true
.
Check out stories/UsersTable.js
to see how these properties can be used.
If you just need to show tabular data, with some actions for each row, you can use the provided Table
component in combination with the sematable
wrapper as shown above. Otherwise, you can write the table structure yourself.
The sematable(tableName, component, columns, configs)
wrapper accepts four parameters:
If you want to show the page size and filter somewhere else in your application, you can use the provided PageSizeContainer, and FilterContainer component. Like this:
import { PageSizeContainer, FilterContainer } from 'sematable';
export default props => (
<div>
<FilterContainer tableName="myTable" />
<PageSizeContainer tableName="myTable" />
</div>
);
You can style these components with style
or className
.
asc
or desc
(asc
by default)There’s no requirement that the wrapped component needs to be a table, it could be a list, a div, an image gallery, or anything else.
We will pass the following props to the wrapped component
:
Here’s how you would implement the same example shown above without the provided Table component.
AppsTable.js:
import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import sematable, {
SortableHeader,
SelectAllHeader,
SelectRow,
} from 'sematable';
const columns = [
{ key: 'id', header: 'ID', searchable: true, sortable: true, primaryKey: true },
{ key: 'name', header: 'Name', searchable: true, sortable: true },
];
const propTypes = {
headers: PropTypes.object.isRequired,
data: PropTypes.array.isRequired,
};
class AppsTable extends Component {
render() {
const {
headers: { select, id, name },
data,
} = this.props;
return (
<div className="table-responsive">
<table className="table table-sm table-striped table-hover">
<thead>
<tr>
<SelectAllHeader {...select} />
<SortableHeader {...id} />
<SortableHeader {...name} />
<th>Actions</th>
</tr>
</thead>
<tbody>
{data.map((app) => (
<tr
key={app.id}
className={`${select.isSelected(app) ? 'table-info' : ''}`}
>
<td>
<SelectRow row={app} {...select} />
</td>
<td>{app.id}</td>
<td>{app.name}</td>
<td>
<Link to={`/settings/${app.id}`}>
Settings
</Link>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
AppsTable.propTypes = propTypes;
export default sematable('allApps', AppsTable, columns);
We provide a few selectors that can be useful when working with sematable:
getSelectedRows
getInitialData
getIsInitialized
getFiltered
getFilter
getFilterText
getColumns
getSortInfo
getPageInfo
getVisible
getSelectAll
getPrimaryKey
These are exposed with makeSelectors(tableName)
. You should use them like this:
import { makeSelectors } from 'sematable';
const selectors = makeSelectors('myTable');
const mapStateToProps = (state) => ({
selectedRows: selectors.getSelectedRows(state)
});
You can use the below actions to alter the state of the table:
tableDestroyState(tableName)
resets/destroys the current state of the table. This can be used in componentWillUnmount()
to reset the related redux state.tableSetFilter(tableName, filterValue)
sets the table filters where filterValue
is an array of filter objects.You can import actions from the sematable module like this:
import { tableDestroyState } from 'sematable';
You can set the list of filters by passing filterValue
to your sematable component, or by using the tableSetFilter
action. In either case, the provided value should be an array of two types of objects:
key
and value
, where key
is the column key you want to filter, and value
is the value you want to filter by.For example:
<UsersTable
data={users}
filterValue={[
'Bob',
{ key: 'confirmed', value: true },
]}
/>
Or with tableSetFilter
:
dispatch(tableSetFilter('usersTable', [
'Bob',
{ key: 'confirmed', value: true },
]));
CheckboxComponent
for SelectAllHeader, accepting properties
{
onChange: PropTypes.func,
checked: PropTypes.bool,
disabled: PropTypes.bool,
children: PropTypes.node,
className: PropTypes.string,
id: PropTypes.string,
}
NoDataComponent
for rendering custom messages when there is no data available, accepting properties:
{
filter: PropTypes.array // List of applied filters for table
}
Author: sematext
Source Code: https://github.com/sematext/sematable
#react #reactjs #javascript