/** @format */ /** * External dependencies */ import { __, sprintf } from '@wordpress/i18n'; import { Component, createRef } from '@wordpress/element'; import classnames from 'classnames'; import { IconButton } from '@wordpress/components'; import PropTypes from 'prop-types'; import { isEqual, uniqueId } from 'lodash'; /** * Internal dependencies */ import './style.scss'; const ASC = 'ascending'; const DESC = 'descending'; class Table extends Component { constructor( props ) { super( props ); this.state = { tabIndex: null, rows: props.rows || [], sortedBy: null, sortDir: 'none', }; this.container = createRef(); this.sortBy = this.sortBy.bind( this ); this.captionID = uniqueId( 'caption-' ); } componentDidUpdate( prevProps ) { if ( ! isEqual( this.props.rows, prevProps.rows ) ) { /* eslint-disable react/no-did-update-set-state */ this.setState( { rows: this.props.rows, } ); /* eslint-enable react/no-did-update-set-state */ } } componentDidMount() { const { scrollWidth, clientWidth } = this.container.current; const scrollable = scrollWidth > clientWidth; /* eslint-disable react/no-did-mount-set-state */ this.setState( { tabIndex: scrollable ? '0' : null, } ); /* eslint-enable react/no-did-mount-set-state */ } sortBy( col ) { this.setState( prevState => { // Set the sort direction as inverse of current state const sortDir = prevState.sortDir === ASC ? DESC : ASC; return { rows: prevState.rows .slice( 0 ) .sort( ( a, b ) => ( sortDir === ASC ? a[ col ] > b[ col ] : a[ col ] < b[ col ] ) ), sortedBy: col, sortDir, }; } ); } isColSortable( col ) { const { sortable, rows: [ first ] } = this.props; if ( ! first ) { return false; } // The table is not set to be sortable, we don't need to check cols. if ( ! sortable ) { return false; } return 'object' !== typeof first[ col ]; } render() { const { caption, classNames, headers, rowHeader } = this.props; const { rows, sortedBy, sortDir, tabIndex } = this.state; const classes = classnames( 'woocommerce-table', classNames ); return (
{ headers.map( ( header, i ) => ( ) ) } { rows.map( ( row, i ) => ( { row.map( ( cell, j ) => rowHeader === j ? ( ) : ( ) ) } ) ) }
{ caption } { tabIndex === '0' && { __( '(scroll to see more)', 'wc-admin' ) } }
{ this.isColSortable( i ) && ( this.sortBy( i ) } /> ) } { header }
{ cell } { cell }
); } } Table.propTypes = { caption: PropTypes.string.isRequired, className: PropTypes.string, headers: PropTypes.arrayOf( PropTypes.node ), rows: PropTypes.arrayOf( PropTypes.arrayOf( PropTypes.node ) ).isRequired, rowHeader: PropTypes.oneOfType( [ PropTypes.number, PropTypes.bool ] ), sortable: PropTypes.bool, }; Table.defaultProps = { headers: [], rowHeader: 0, sortable: true, }; export default Table;