1
1
import { css } from '@linaria/core' ;
2
2
3
3
import { useRovingTabIndex } from './hooks' ;
4
- import { clampColumnWidth , getCellClassname , getCellStyle } from './utils' ;
4
+ import { clampColumnWidth , getCellClassname , getCellStyle , stopPropagation } from './utils' ;
5
5
import type { CalculatedColumn , SortColumn } from './types' ;
6
6
import type { HeaderRowProps } from './HeaderRow' ;
7
7
import defaultRenderHeaderCell from './renderHeaderCell' ;
8
8
9
+ const cellSortableClassname = css `
10
+ @layer rdg.HeaderCell {
11
+ cursor : pointer;
12
+ }
13
+ ` ;
14
+
9
15
const cellResizable = css `
10
16
@layer rdg.HeaderCell {
11
17
touch-action : none;
12
-
13
- & ::after {
14
- content : '' ;
15
- cursor : col-resize;
16
- position : absolute;
17
- inset-block-start : 0 ;
18
- inset-inline-end : 0 ;
19
- inset-block-end : 0 ;
20
- inline-size : 10px ;
21
- }
22
18
}
23
19
` ;
24
20
25
21
const cellResizableClassname = `rdg-cell-resizable ${ cellResizable } ` ;
26
22
23
+ export const resizeHandleClassname = css `
24
+ @layer rdg.HeaderCell {
25
+ cursor : col-resize;
26
+ position : absolute;
27
+ inset-block-start : 0 ;
28
+ inset-inline-end : 0 ;
29
+ inset-block-end : 0 ;
30
+ inline-size : 10px ;
31
+ }
32
+ ` ;
33
+
27
34
type SharedHeaderRowProps < R , SR > = Pick <
28
35
HeaderRowProps < R , SR , React . Key > ,
29
36
| 'sortColumns'
@@ -62,6 +69,7 @@ export default function HeaderCell<R, SR>({
62
69
sortDirection && ! priority ? ( sortDirection === 'ASC' ? 'ascending' : 'descending' ) : undefined ;
63
70
64
71
const className = getCellClassname ( column , column . headerCellClass , {
72
+ [ cellSortableClassname ] : column . sortable ,
65
73
[ cellResizableClassname ] : column . resizable
66
74
} ) ;
67
75
@@ -73,18 +81,14 @@ export default function HeaderCell<R, SR>({
73
81
}
74
82
75
83
const { currentTarget, pointerId } = event ;
76
- const { right, left } = currentTarget . getBoundingClientRect ( ) ;
84
+ const headerCell = currentTarget . parentElement ! ;
85
+ const { right, left } = headerCell . getBoundingClientRect ( ) ;
77
86
const offset = isRtl ? event . clientX - left : right - event . clientX ;
78
87
79
- if ( offset > 11 ) {
80
- // +1px to account for the border size
81
- return ;
82
- }
83
-
84
88
function onPointerMove ( event : PointerEvent ) {
85
89
// prevents text selection in Chrome, which fixes scrolling the grid while dragging, and fixes re-size on an autosized column
86
90
event . preventDefault ( ) ;
87
- const { right, left } = currentTarget . getBoundingClientRect ( ) ;
91
+ const { right, left } = headerCell . getBoundingClientRect ( ) ;
88
92
const width = isRtl ? right + offset - event . clientX : event . clientX + offset - left ;
89
93
if ( width > 0 ) {
90
94
onColumnResize ( column , clampColumnWidth ( width , column ) ) ;
@@ -138,19 +142,15 @@ export default function HeaderCell<R, SR>({
138
142
}
139
143
}
140
144
141
- function onClick ( ) {
145
+ function onClick ( event : React . MouseEvent < HTMLSpanElement > ) {
142
146
selectCell ( column . idx ) ;
143
- }
144
-
145
- function onDoubleClick ( event : React . MouseEvent < HTMLDivElement > ) {
146
- const { right, left } = event . currentTarget . getBoundingClientRect ( ) ;
147
- const offset = isRtl ? event . clientX - left : right - event . clientX ;
148
147
149
- if ( offset > 11 ) {
150
- // +1px to account for the border size
151
- return ;
148
+ if ( column . sortable ) {
149
+ onSort ( event . ctrlKey || event . metaKey ) ;
152
150
}
151
+ }
153
152
153
+ function onDoubleClick ( ) {
154
154
onColumnResize ( column , 'max-content' ) ;
155
155
}
156
156
@@ -162,6 +162,14 @@ export default function HeaderCell<R, SR>({
162
162
}
163
163
}
164
164
165
+ function onKeyDown ( event : React . KeyboardEvent < HTMLSpanElement > ) {
166
+ if ( event . key === ' ' || event . key === 'Enter' ) {
167
+ // prevent scrolling
168
+ event . preventDefault ( ) ;
169
+ onSort ( event . ctrlKey || event . metaKey ) ;
170
+ }
171
+ }
172
+
165
173
return (
166
174
< div
167
175
role = "columnheader"
@@ -175,16 +183,23 @@ export default function HeaderCell<R, SR>({
175
183
style = { getCellStyle ( column , colSpan ) }
176
184
onFocus = { handleFocus }
177
185
onClick = { onClick }
178
- onDoubleClick = { column . resizable ? onDoubleClick : undefined }
179
- onPointerDown = { column . resizable ? onPointerDown : undefined }
186
+ onKeyDown = { column . sortable ? onKeyDown : undefined }
180
187
>
181
188
{ renderHeaderCell ( {
182
189
column,
183
190
sortDirection,
184
191
priority,
185
- onSort,
186
192
tabIndex : childTabIndex
187
193
} ) }
194
+
195
+ { column . resizable && (
196
+ < div
197
+ className = { resizeHandleClassname }
198
+ onClick = { stopPropagation }
199
+ onDoubleClick = { onDoubleClick }
200
+ onPointerDown = { onPointerDown }
201
+ />
202
+ ) }
188
203
</ div >
189
204
) ;
190
205
}
0 commit comments