-
Notifications
You must be signed in to change notification settings - Fork 181
/
header-cell.tsx
104 lines (88 loc) · 2.93 KB
/
header-cell.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import React, {PureComponent, ReactNode, SyntheticEvent, ThHTMLAttributes} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import sortableIcon from '@jetbrains/icons/unsorted-10px';
import sortedIcon from '@jetbrains/icons/chevron-10px';
import Icon from '../icon/icon';
import dataTests from '../global/data-tests';
import style from './table.css';
export interface Column<T = never> {
id: string
sortable?: boolean | null | undefined
className?: string | null | undefined
headerClassName?: string | null | undefined
rightAlign?: boolean | null | undefined
getHeaderValue?: (() => ReactNode) | null | undefined
title?: ReactNode
getValue?: ((item: T, column: Column) => ReactNode) | null | undefined
getDataTest?: ((item: T, column: Column) => string) | null | undefined
}
export interface SortParams {
column: Column
order: boolean
}
export interface HeaderCellProps extends ThHTMLAttributes<HTMLTableHeaderCellElement> {
column: Column
onSort: (params: SortParams) => void
sortKey?: string | null | undefined
sortOrder?: boolean | null | undefined
'data-test'?: string | null | undefined
}
export default class HeaderCell extends PureComponent<HeaderCellProps> {
static propTypes = {
children: PropTypes.any,
className: PropTypes.string,
column: PropTypes.object.isRequired,
onSort: PropTypes.func,
sortKey: PropTypes.string,
sortOrder: PropTypes.bool,
'data-test': PropTypes.string
};
static defaultProps = {
onSort: () => {}
};
sortable?: boolean;
sorted?: boolean;
onClick = () => {
if (this.sortable) {
const {column, onSort, sortOrder} = this.props;
onSort({column, order: !(this.sorted && sortOrder)});
}
};
onChildrenClick(e: SyntheticEvent) {
e.stopPropagation();
}
render() {
const {
className, column, onSort, sortKey, sortOrder,
'data-test': dataTest, ...restProps
} = this.props;
this.sortable = column.sortable === true;
this.sorted = sortKey === column.id;
const glyph = this.sorted ? sortedIcon : sortableIcon;
const classes = classNames(className, column.headerClassName, {
[style.headerCell]: true,
[style.headerCellSortable]: this.sortable,
[style.headerCellSorted]: this.sorted,
[style.sortedUp]: sortOrder && this.sorted,
[style.cellRight]: column.rightAlign
});
return (
<th
{...restProps}
className={classes}
onClick={this.onClick}
data-test={dataTests('ring-table-header-cell', dataTest)}
>
{/* onClick only used to stop propagation */}
<span onClick={this.onChildrenClick} role="presentation">{this.props.children}</span>
{column.getHeaderValue ? column.getHeaderValue() : column.title}
{this.sortable && (
<span className={style.sorter}>
<Icon glyph={glyph} className={style.icon}/>
</span>
)}
</th>
);
}
}