{"id":13421860,"url":"https://github.com/sematext/sematable","last_synced_at":"2025-08-11T04:15:27.328Z","repository":{"id":48034012,"uuid":"65480564","full_name":"sematext/sematable","owner":"sematext","description":"ReactJS / Redux Data Table","archived":false,"fork":false,"pushed_at":"2023-10-10T21:47:05.000Z","size":1017,"stargazers_count":160,"open_issues_count":0,"forks_count":25,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-08-09T15:46:23.719Z","etag":null,"topics":["no-maintenance-intended"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sematext.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-08-11T15:29:23.000Z","updated_at":"2024-08-26T08:25:36.000Z","dependencies_parsed_at":"2024-04-17T11:03:16.100Z","dependency_job_id":null,"html_url":"https://github.com/sematext/sematable","commit_stats":{"total_commits":193,"total_committers":19,"mean_commits":"10.157894736842104","dds":"0.46632124352331605","last_synced_commit":"8bde8824a5e7c2a3310861347796ab8f4b3aac5c"},"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"purl":"pkg:github/sematext/sematable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sematext%2Fsematable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sematext%2Fsematable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sematext%2Fsematable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sematext%2Fsematable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sematext","download_url":"https://codeload.github.com/sematext/sematable/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sematext%2Fsematable/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269794091,"owners_count":24476738,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["no-maintenance-intended"],"created_at":"2024-07-30T23:00:33.004Z","updated_at":"2025-08-11T04:15:26.235Z","avatar_url":"https://github.com/sematext.png","language":"JavaScript","readme":"# Sematable\n\n[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)\n\n⛔️ DEPRECATED This repository isn't mantained by Sematext any more.\n\nSematable wraps a table component, and provides:\n\n - filtering by column value\n - search with text\n - sorting\n - row selection\n - pagination\n\n... with the ability to persist the table state in application state with\nRedux, so filters, sort info, selected rows, and pagination info survives route\nnavigations.\n\n![image](https://cloud.githubusercontent.com/assets/497926/24330201/a156edec-1219-11e7-877b-e0c4c49fd947.png)\n\n- [More About Sematable](https://sematext.com/blog/2016/12/07/reactjs-redux-table-sematable/)\n- [Live Sematable examples](https://apps.sematext.com/demo)\n\n\n### ⚠ CSS Dependencies\n\nSematable 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`.\n\n## Reducer\n\nBefore using the sematable wrapper, you need to setup the reducer. You should\ncombine the provided reducer in your root reducer like this:\n\n```javascript\nimport { reducer as sematable } from 'sematable';\n\nconst reducer = combineReducers({\n  sematable,\n  ...\n});\n```\n\n## Usage\n\nThe most frequent use case for sematable is to show tabular data with some\nactions (edit, delete, etc.). See the below example for that.\n\nFor information on how to get selected rows and other table state, check out\nthe [section about selectors](#selectors).\n\nAppsTable.js:\n```javascript\nimport React, { Component, PropTypes } from 'react';\nimport sematable, { Table } from 'sematable';\nimport AppsTableActions from './AppsTableActions';\n\nconst columns = [\n  { key: 'id', header: 'ID', sortable: true, searchable: true, primaryKey: true },\n  { key: 'name', header: 'Application', sortable: true, searchable: true },\n  { key: 'token', header: 'Token' },\n  { key: 'plan', header: 'Plan', sortable: true },\n  { key: 'role', header: 'Role', sortable: true },\n  { key: 'actions', header: 'Actions', Component: AppsTableActions },\n];\n\nconst propTypes = {\n  headers: PropTypes.object.isRequired,\n  data: PropTypes.array.isRequired,\n  primaryKey: PropTypes.string.isRequired,\n};\n\nclass AppsTable extends Component {\n  render() {\n    return (\n      \u003cTable\n        {...this.props}\n        selectable\n        columns={columns}\n      /\u003e\n    );\n  }\n}\n\nAppsTable.propTypes = propTypes;\nexport default sematable('allApps', AppsTable, columns);\n```\n\n`AppsTableActions.js`:\n```javascript\nimport React, { Component, PropTypes } from 'react';\nimport { Link } from 'react-router';\n\nconst propTypes = {\n  row: PropTypes.object.isRequired,\n};\n\nclass AppsTableActions extends Component {\n  render() {\n    const row = this.props.row;\n    return (\n      \u003cLink to={`/settings/${row.id}`}\u003e\n        Settings\n      \u003c/Link\u003e\n    );\n  }\n}\nAppsTableActions.propTypes = propTypes;\nexport default AppsTableActions;\n```\n\nThe `sematable` function will wrap your component and add filter, pagination,\nand other sematable functionality. The first argument is name of this table. It\nshould be unique across your app. The second argument is your component, and\nthe third are the column definitions.\n\n- You can omit the `selectable` property to hide the row selection controls.\n- You can use the `className` property to set the table class (`table-sm table-striped table-hover` is the default).\n\nColumns definitions have the following properties:\n\n - _key_ is the name of the property used in row objects\n - _header_ is the header label that will be used for this column\n - _title_ is the title that will be used when column header is hovered\n - _className_ is the css class to use for the column `\u003ctd\u003e` element\n - _sortable_ defines if user should be able to sort by this column\n - _searchable_ defines if user should be able to text-search by this column (simple case-insensitive substring search)\n - _primaryKey_ defines if this column is the primary key\n - _hidden_ defines if we should hide this column (useful if you don't want to show primary key column)\n - _Component_ defines which component should be used to render cell contents\n - _filterable_ defines if user should be able to filter rows by distinct values of this column\n - _filterValues_ can be provided to define distinct filter values for this\n   column. If not provided, unique values will be extracted from provided data.\n - _getFilterTitle_ is a function with `(value)` signature that can be provided to customize the filter title\n - _getFilterLabel_ is a function with `(value)` signature that can be provided to customize the filter label\n - _getFilterClassName_ is a function with `(value)` signature that can be provided to customize the filter css class\n\nAt least one column definition should have `primaryKey: true`.\n\nCheck out `stories/UsersTable.js` to see how these properties can be used.\n\n## Advanced Usage\n\nIf you just need to show tabular data, with some actions for each row, you can\nuse the provided `Table` component in combination with the `sematable` wrapper\nas shown above.  Otherwise, you can write the table structure yourself.\n\nThe `sematable(tableName, component, columns, configs)` wrapper accepts four parameters:\n\n - _tableName_ is a unique name for this table (used to store state)\n - _component_ is the table component you want to wrap\n - _columns_ is an array of column definitions\n - _configs_ is an optional object where you can specify configuration properties\n\n### Showing page size and filter somewhere else\n\nIf you want to show the page size and filter somewhere else in your\napplication, you can use the provided PageSizeContainer, and FilterContainer\ncomponent. Like this:\n\n```javascript\nimport { PageSizeContainer, FilterContainer } from 'sematable';\n\nexport default props =\u003e (\n    \u003cdiv\u003e\n      \u003cFilterContainer tableName=\"myTable\" /\u003e\n      \u003cPageSizeContainer tableName=\"myTable\" /\u003e\n    \u003c/div\u003e\n);\n```\n\nYou can style these components with `style` or `className`.\n\n### Configuration properties:\n\n - _plain_ if you want only the table component to be returned without page size, pagination, or filter (will not use bootstrap grid)\n - _showPageSize_ if page size select should be shown\n - _showFilter_ if text filter field should be shown\n - _defaultPageSize_ overrides the default page size (if not specified 5 will be used)\n - _autoHidePagination_ if pagination should be hidden if the number of pages is 1 (default is true, which means pagination is hidden if the number of pages is equal to 1)\n - _filterClassName_ css class for the filter component\n - _filterClassNamePrefix_ css class prefix forwarded to [react-select](https://react-select.com/styles#using-classnames) ('Select' by default)\n - _filterContainerClassName_ css class for the filter component container element ('col-md-6' by default)\n - _filterPlaceholder_ filter placeholder text\n - _pageSizeClassName_ css class for the page size component ('col-md-6' by default)\n - _pageSizeContainerClassName_ css class for the page size component container element ('col-md-6' by default)\n - _sortKey_ default column to sort by (not sorted by default)\n - _sortDirection_ default sort direction, `asc` or `desc` (`asc` by default)\n\nThere's no requirement that the wrapped component needs to be a table, it could\nbe a list, a div, an image gallery, or anything else.\n\nWe will pass the following props to the wrapped `component`:\n\n - _data_ is the filtered, sorted, and paginated data (the current view)\n - _headers_ contains callbacks for sorting and selection\n - _primaryKey_ is the name of the primary key field\n\nHere's how you would implement the same example shown above without the\nprovided Table component.\n\nAppsTable.js:\n```javascript\nimport React, { Component, PropTypes } from 'react';\nimport { Link } from 'react-router';\nimport sematable, {\n  SortableHeader,\n  SelectAllHeader,\n  SelectRow,\n} from 'sematable';\n\nconst columns = [\n  { key: 'id', header: 'ID', searchable: true, sortable: true, primaryKey: true },\n  { key: 'name', header: 'Name', searchable: true, sortable: true },\n];\n\nconst propTypes = {\n  headers: PropTypes.object.isRequired,\n  data: PropTypes.array.isRequired,\n};\n\nclass AppsTable extends Component {\n  render() {\n    const {\n      headers: { select, id, name },\n      data,\n    } = this.props;\n    return (\n      \u003cdiv className=\"table-responsive\"\u003e\n        \u003ctable className=\"table table-sm table-striped table-hover\"\u003e\n          \u003cthead\u003e\n            \u003ctr\u003e\n              \u003cSelectAllHeader {...select} /\u003e\n              \u003cSortableHeader {...id} /\u003e\n              \u003cSortableHeader {...name} /\u003e\n              \u003cth\u003eActions\u003c/th\u003e\n            \u003c/tr\u003e\n          \u003c/thead\u003e\n          \u003ctbody\u003e\n            {data.map((app) =\u003e (\n              \u003ctr\n                key={app.id}\n                className={`${select.isSelected(app) ? 'table-info' : ''}`}\n              \u003e\n                \u003ctd\u003e\n                  \u003cSelectRow row={app} {...select} /\u003e\n                \u003c/td\u003e\n                \u003ctd\u003e{app.id}\u003c/td\u003e\n                \u003ctd\u003e{app.name}\u003c/td\u003e\n                \u003ctd\u003e\n                  \u003cLink to={`/settings/${app.id}`}\u003e\n                    Settings\n                  \u003c/Link\u003e\n                \u003c/td\u003e\n              \u003c/tr\u003e\n            ))}\n          \u003c/tbody\u003e\n        \u003c/table\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n\nAppsTable.propTypes = propTypes;\nexport default sematable('allApps', AppsTable, columns);\n```\n\n## Selectors\n\nWe provide a few selectors that can be useful when working with sematable:\n\n```\ngetSelectedRows\ngetInitialData\ngetIsInitialized\ngetFiltered\ngetFilter\ngetFilterText\ngetColumns\ngetSortInfo\ngetPageInfo\ngetVisible\ngetSelectAll\ngetPrimaryKey\n```\n\nThese are exposed with `makeSelectors(tableName)`. You should use them like\nthis:\n\n```javascript\nimport { makeSelectors } from 'sematable';\n\nconst selectors = makeSelectors('myTable');\nconst mapStateToProps = (state) =\u003e ({\n  selectedRows: selectors.getSelectedRows(state)\n});\n```\n\n## Actions\n\nYou can use the below actions to alter the state of the table:\n\n - `tableDestroyState(tableName)` resets/destroys the current state of the\n   table. This can be used in `componentWillUnmount()` to reset the related\n   redux state.\n - `tableSetFilter(tableName, filterValue)` sets the table filters where\n   `filterValue` is an array of filter objects.\n\nYou can import actions from the sematable module like this:\n\n```javascript\nimport { tableDestroyState } from 'sematable';\n```\n\n## Filters\n\nYou can set the list of filters by passing `filterValue` to your sematable\ncomponent, or by using the `tableSetFilter` action. In either case, the\nprovided value should be an array of two types of objects:\n\n - text filter defined simply as a string\n - value filter defined as object with properties `key` and `value`, where\n   `key` is the column key you want to filter, and `value` is the value you\n   want to filter by.\n\nFor example:\n\n```javascript\n\u003cUsersTable\n  data={users}\n  filterValue={[\n    'Bob',\n    { key: 'confirmed', value: true },\n  ]}\n/\u003e\n```\nOr with `tableSetFilter`:\n\n```javascript\ndispatch(tableSetFilter('usersTable', [\n  'Bob',\n  { key: 'confirmed', value: true },\n]));\n```\n\n## Custom components\n\n`CheckboxComponent` for SelectAllHeader, accepting properties\n```javascript\n{\n  onChange: PropTypes.func,\n  checked: PropTypes.bool,\n  disabled: PropTypes.bool,\n  children: PropTypes.node,\n  className: PropTypes.string,\n  id: PropTypes.string,\n}\n```\n\n`NoDataComponent` for rendering custom messages when there is no data available, accepting properties:\n\n```javascript\n{\n  filter: PropTypes.array // List of applied filters for table\n}\n```\n","funding_links":[],"categories":["UI Components","Demos","\u003csummary\u003eUI Components\u003c/summary\u003e"],"sub_categories":["Table","Table / Data Grid","Openshift"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsematext%2Fsematable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsematext%2Fsematable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsematext%2Fsematable/lists"}