import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import DataType from './DataType';
import SortDirection from './SortDirection';
const propTypes = {
column: PropTypes.object.isRequired,
columnGroup: PropTypes.object,
highlightedColumn: PropTypes.bool,
onClick: PropTypes.func,
sortableTable: PropTypes.bool,
sortDirection: PropTypes.bool,
};
const defaultProps = {
};
/**
* React component for rendering table headers, uses `<th>`.
*
* @prop {Object} column The column definition
* @prop {Object} columnGroup Column group definition:
* `{ header:String, columns:[colId1, colId2, ...], className:String}`
* @prop {Boolean} highlightedColumn Whether this column is highlighted or not
* @prop {Function} onClick Callback when clicked. Gets passed `column.id`
* @prop {Boolean} sortableTable Whether the table is sortable or not
* @prop {Boolean} sortDirection The current sort direction of this column --
* null or undefined if not sorted
* @extends React.Component
*/
class TacoTableHeader extends React.PureComponent {
/**
* @param {Object} props React props
*/
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
/**
* Handler for when the header is clicked. Calls `onClick(column.id)`.
* @private
*/
handleClick() {
const { column, onClick } = this.props;
if (onClick) {
onClick(column.id);
}
}
/**
* Main render method
* @return {React.Component}
*/
render() {
const { column, sortableTable, highlightedColumn, columnGroup,
sortDirection } = this.props;
const { className, thClassName, header, id, width, type } = column;
const contents = header == null ? id : header;
// this is a sortable column if it is in a sortable table and it has a datatype and
// sortValue isn't explicitly set to null (undefined is ok).
const sortable = sortableTable && column.type !== DataType.None && column.sortValue !== null;
let onClick;
let sortIndicator;
if (sortable) {
onClick = this.handleClick;
sortIndicator = (
<span
className={classNames('sort-indicator', {
'sort-ascending': sortDirection === SortDirection.Ascending,
'sort-descending': sortDirection === SortDirection.Descending,
})}
/>
);
}
// add in a fixed width if specified
let style;
if (width != null) {
style = { width };
}
// get classes based on column group
let columnGroupClass;
if (columnGroup) {
columnGroupClass = [columnGroup.className];
const columnGroupIndex = columnGroup.columns.indexOf(column.id);
// first column in group
if (columnGroupIndex === 0) {
columnGroupClass.push('group-first');
}
// last column in group
if (columnGroupIndex === columnGroup.columns.length - 1) {
columnGroupClass.push('group-last');
}
}
return (
<th
className={classNames(className, thClassName, columnGroupClass,
`data-type-${type}`, {
sortable,
'column-highlight': highlightedColumn,
'sort-ascending': sortDirection === SortDirection.Ascending,
'sort-descending': sortDirection === SortDirection.Descending,
sorted: sortDirection != null,
})}
onClick={onClick}
style={style}
>
{contents}
{sortIndicator}
</th>
);
}
}
TacoTableHeader.propTypes = propTypes;
TacoTableHeader.defaultProps = defaultProps;
export default TacoTableHeader;