-
Notifications
You must be signed in to change notification settings - Fork 186
/
header.tsx
144 lines (124 loc) · 3.66 KB
/
header.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import React, {ChangeEventHandler, PureComponent, ReactNode, SyntheticEvent} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Checkbox from '../checkbox/checkbox';
import getUID from '../global/get-uid';
import style from './table.css';
import HeaderCell, {Column, SortParams} from './header-cell';
export interface HeaderProps {
columns: readonly Column[]
selectable: boolean
draggable: boolean
checked: boolean
sticky: boolean
topStickOffset: string
onSort: (params: SortParams) => void
onCheckboxChange: ChangeEventHandler<HTMLInputElement>
sortKey: string
sortOrder: boolean
caption?: string | null | undefined
checkboxDisabled?: boolean | undefined
}
declare module 'react-waypoint' {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Waypoint {
interface WaypointProps {
children?: ReactNode
}
}
}
export default class Header extends PureComponent<HeaderProps> {
static propTypes = {
caption: PropTypes.string,
selectable: PropTypes.bool,
draggable: PropTypes.bool,
checked: PropTypes.bool,
checkboxDisabled: PropTypes.bool,
sticky: PropTypes.bool,
topStickOffset: PropTypes.string,
onCheckboxChange: PropTypes.func,
columns: PropTypes.array.isRequired,
onSort: PropTypes.func,
sortKey: PropTypes.string,
sortOrder: PropTypes.bool
};
static defaultProps = {
selectable: true,
draggable: false,
checked: true,
sticky: true,
topStickOffset: '0px',
onSort: () => {},
onCheckboxChange: () => {},
sortKey: 'id',
sortOrder: true
};
id = getUID('table-header-');
onCheckboxFocus = (event: SyntheticEvent<HTMLElement>) => {
event.currentTarget.blur();
};
createCells(widths = []) {
const {
selectable, draggable, columns, checked, checkboxDisabled,
onCheckboxChange, onSort, sortKey, sortOrder
} = this.props;
const metaColumnClasses = classNames(style.metaColumn, style.headerMetaColumn);
const metaColumn = (
<div className={metaColumnClasses}>
{selectable &&
(
<Checkbox
aria-labelledby={this.id}
disabled={checkboxDisabled}
checked={checked}
onChange={onCheckboxChange}
onFocus={this.onCheckboxFocus}
/>
)}
</div>
);
return columns.map((column, index) => {
const columnStyle = widths[index] ? {width: widths[index]} : undefined;
const props = {column, onSort, sortKey, sortOrder, style: columnStyle};
return (
<HeaderCell
key={column.id}
data-test={column.id}
{...props}
>
{index === 0 && (draggable || selectable) && metaColumn}
</HeaderCell>
);
});
}
render() {
const {caption, sticky, topStickOffset} = this.props;
const regularCells = this.createCells();
return (
<thead
id={this.id}
data-test="ring-table-header"
style={{top: topStickOffset}}
className={classNames({
[style.tableHead]: true,
[style.subHeaderSticky]: sticky
})}
>
{caption && (
<tr data-test="ring-table-header-row">
<th
className={classNames(style.headerCell, style.caption)}
colSpan={regularCells.length + 1}
data-test="ring-table-header-cell"
>{caption}</th>
</tr>
)}
<tr
className={style.subHeader}
data-test="ring-table-header-row"
>{regularCells}</tr>
</thead>
);
}
}
export type HeaderAttrs = JSX.LibraryManagedAttributes<typeof Header, HeaderProps>