diff --git a/doc/src/components/common/componentData/Table/index.js b/doc/src/components/common/componentData/Table/index.js index edd6a5ae..13782bdb 100644 --- a/doc/src/components/common/componentData/Table/index.js +++ b/doc/src/components/common/componentData/Table/index.js @@ -64,6 +64,12 @@ export const componentData = { defaultValue: 'false', description: 'Prop to be sent, If sorting functionality is required.', }, + { + prop: 'sortByTitle', + type: 'Boolean', + defaultValue: 'false', + description: 'Prop to be sent, If sorting functionality by clicking column header is required.', + }, ], themesData: [ { @@ -106,6 +112,10 @@ export const componentData = { name: 'sortArrow', description: 'Class used for the sorting arrows in table header cells.', }, + { + name: 'sortableTitle', + description: 'Class used for the title when sortByTitle is enabled.', + }, ], basicComponent: ` class Demo extends React.Component { @@ -163,7 +173,7 @@ export const componentData = { render() { const columns = [ { title: 'Name', key: 'name', colWidth: '150px' }, - { title: 'Default Value', key: 'defaultValue' }, + { title: 'Default Value', key: 'defaultValue', colWidth: '180px' }, { title: 'Description', key: 'description' }, ]; const data = [ @@ -194,12 +204,20 @@ export const componentData = { }, ]; return ( - +
+ - {/* Default table component with sort functionality */} - - - + {/* Default table component with sort functionality */} +
+ + + + + {/* Default table component with sort functionality on clicking header */} +
+ + + ) } } diff --git a/lib/table/index.js b/lib/table/index.js index 7f361e32..f61560f6 100644 --- a/lib/table/index.js +++ b/lib/table/index.js @@ -1,6 +1,8 @@ +/* eslint-disable react/destructuring-assignment */ import React from 'react'; import classnames from 'classnames'; import { themr } from 'react-css-themr'; +import { FaArrowDown } from 'react-icons/fa'; import PropTypes from 'prop-types'; import defaultTheme from './theme.module.scss'; @@ -12,6 +14,14 @@ class Table extends React.Component { }; } + componentDidMount() { + const { columns } = this.props; + this.setState({ + sortTitle: columns[0].key, + [`${columns[0].key}Ascending`]: true, + }); + } + componentDidUpdate() { const { data } = this.props; const { tableData } = this.state; @@ -80,13 +90,57 @@ class Table extends React.Component { ); } + handleTitleSort = (key) => { + // eslint-disable-next-line react/destructuring-assignment + this.setState(prevState => ({ + [`${key}TitleToggle`]: !prevState[[`${key}TitleToggle`]], + })); + if (this.state[`${key}TitleToggle`]) { + this.sortAscending(key); + } else { + this.sortDescending(key); + } + } + + renderArrowIcon = (isCurrentKey, key) => { + const { theme } = this.props; + return ( + + ); + } + + renderSortableTitle = (title, key) => { + const { sortTitle } = this.state; + const { theme } = this.props; + const isCurrentKey = sortTitle === key; + return ( +
this.handleTitleSort(key)} + > + {title} + + {this.renderArrowIcon(isCurrentKey, key)} + +
+ ); + } + /* * the table header content will be rendered from accepting columns prop as array, * the number of columns in table is directly proportional to * length of columns array from prop */ renderTableHeader = () => { - const { columns, theme, sort } = this.props; + const { + columns, theme, sort, sortByTitle, + } = this.props; return (
{ columns && columns.map(({ @@ -99,7 +153,7 @@ class Table extends React.Component { {...other} >
- {title} + {sortByTitle ? this.renderSortableTitle(title, key) : title} {sort && this.renderSortArrow(key)}
@@ -170,11 +224,13 @@ Table.propTypes = { columns: PropTypes.oneOfType([PropTypes.array]).isRequired, data: PropTypes.oneOfType([PropTypes.array]).isRequired, sort: PropTypes.bool, + sortByTitle: PropTypes.bool, }; Table.defaultProps = { theme: defaultTheme, sort: false, + sortByTitle: false, }; export default themr('CBTable', defaultTheme)(Table); diff --git a/lib/table/theme.module.scss b/lib/table/theme.module.scss index 513ffb10..6a5fb839 100644 --- a/lib/table/theme.module.scss +++ b/lib/table/theme.module.scss @@ -45,7 +45,35 @@ } :local(.tableHeadCellContent) { justify-content: space-between; + :local(.sortableTitle) { + cursor: pointer; + :local(.hidden) { + opacity: 0; + } + &:hover { + :local(.hidden) { + opacity: 1; + } + } + } + :local(.sortableTitleIcon) { + font-size: 0.8em; + margin-left: 0.7em; + } +} + +:local(.arrow) { + transition: all 0.2s linear; +} + +:local(.upArrow) { + transform: rotate(0deg); } + +:local(.downArrow) { + transform: rotate(180deg); +} + :local(.sortArrow) { position: relative; width: 12px;