@@ -14,6 +14,7 @@ import ArrowDownSmall from '@spectrum-icons/ui/ArrowDownSmall';
14
14
import { chain , mergeProps , useLayoutEffect } from '@react-aria/utils' ;
15
15
import { Checkbox } from '@react-spectrum/checkbox' ;
16
16
import { classNames , useDOMRef , useStyleProps } from '@react-spectrum/utils' ;
17
+ import { ColumnResizeState , TableState , useTableColumnResizeState , useTableState } from '@react-stately/table' ;
17
18
import { DOMRef } from '@react-types/shared' ;
18
19
import { FocusRing , focusSafely , useFocusRing } from '@react-aria/focus' ;
19
20
import { GridNode } from '@react-types/grid' ;
@@ -29,8 +30,6 @@ import {SpectrumColumnProps, SpectrumTableProps} from '@react-types/table';
29
30
import styles from '@adobe/spectrum-css-temp/components/table/vars.css' ;
30
31
import stylesOverrides from './table.css' ;
31
32
import { TableLayout } from '@react-stately/layout' ;
32
- import { TableState , useTableState } from '@react-stately/table' ;
33
- import { TableView_DEPRECATED } from './TableView_DEPRECATED' ;
34
33
import { Tooltip , TooltipTrigger } from '@react-spectrum/tooltip' ;
35
34
import { useButton } from '@react-aria/button' ;
36
35
import { useHover } from '@react-aria/interactions' ;
@@ -81,7 +80,8 @@ const SELECTION_CELL_DEFAULT_WIDTH = {
81
80
82
81
interface TableContextValue < T > {
83
82
state : TableState < T > ,
84
- layout : TableLayout < T >
83
+ layout : TableLayout < T > ,
84
+ columnState : ColumnResizeState < T >
85
85
}
86
86
87
87
const TableContext = React . createContext < TableContextValue < unknown > > ( null ) ;
@@ -95,6 +95,7 @@ function TableView<T extends object>(props: SpectrumTableProps<T>, ref: DOMRef<H
95
95
let { styleProps} = useStyleProps ( props ) ;
96
96
97
97
let [ showSelectionCheckboxes , setShowSelectionCheckboxes ] = useState ( props . selectionStyle !== 'highlight' ) ;
98
+ let { direction} = useLocale ( ) ;
98
99
let { scale} = useProvider ( ) ;
99
100
100
101
const getDefaultWidth = useCallback ( ( { hideHeader, isSelectionCell, showDivider} ) => {
@@ -109,10 +110,11 @@ function TableView<T extends object>(props: SpectrumTableProps<T>, ref: DOMRef<H
109
110
let state = useTableState ( {
110
111
...props ,
111
112
showSelectionCheckboxes,
112
- selectionBehavior : props . selectionStyle === 'highlight' ? 'replace' : 'toggle' ,
113
- getDefaultWidth
113
+ selectionBehavior : props . selectionStyle === 'highlight' ? 'replace' : 'toggle'
114
114
} ) ;
115
115
116
+ const columnState = useTableColumnResizeState ( { ...props , columns : state . collection . columns , getDefaultWidth, onColumnResize : props . onColumnResize , onColumnResizeEnd : props . onColumnResizeEnd } ) ;
117
+
116
118
// If the selection behavior changes in state, we need to update showSelectionCheckboxes here due to the circular dependency...
117
119
let shouldShowCheckboxes = state . selectionManager . selectionBehavior !== 'replace' ;
118
120
if ( shouldShowCheckboxes !== showSelectionCheckboxes ) {
@@ -141,9 +143,8 @@ function TableView<T extends object>(props: SpectrumTableProps<T>, ref: DOMRef<H
141
143
} ) ,
142
144
[ props . overflowMode , scale , density ]
143
145
) ;
144
- let { direction} = useLocale ( ) ;
145
146
layout . collection = state . collection ;
146
- layout . getColumnWidth = state . getColumnWidth ;
147
+ layout . getColumnWidth = columnState . getColumnWidth ;
147
148
148
149
let { gridProps} = useTable ( {
149
150
...props ,
@@ -259,7 +260,7 @@ function TableView<T extends object>(props: SpectrumTableProps<T>, ref: DOMRef<H
259
260
}
260
261
261
262
if ( item . props . allowsResizing ) {
262
- return < ResizableTableColumnHeader item = { item } state = { state } /> ;
263
+ return < ResizableTableColumnHeader column = { item } /> ;
263
264
}
264
265
265
266
return (
@@ -303,7 +304,7 @@ function TableView<T extends object>(props: SpectrumTableProps<T>, ref: DOMRef<H
303
304
} , [ ] ) ;
304
305
305
306
return (
306
- < TableContext . Provider value = { { state, layout} } >
307
+ < TableContext . Provider value = { { state, layout, columnState } } >
307
308
< TableVirtualizer
308
309
{ ...gridProps }
309
310
{ ...styleProps }
@@ -316,7 +317,7 @@ function TableView<T extends object>(props: SpectrumTableProps<T>, ref: DOMRef<H
316
317
'spectrum-Table--quiet' : isQuiet ,
317
318
'spectrum-Table--wrap' : props . overflowMode === 'wrap' ,
318
319
'spectrum-Table--loadingMore' : state . collection . body . props . loadingState === 'loadingMore' ,
319
- 'spectrum-Table--resizingColumn' : state . isResizingColumn ,
320
+ 'spectrum-Table--resizingColumn' : columnState . isResizingColumn ,
320
321
'spectrum-Table--isVerticalScrollbarVisible' : isVerticalScrollbarVisible ,
321
322
'spectrum-Table--isHorizontalScrollbarVisible' : isHorizontalScrollbarVisible
322
323
} ,
@@ -331,11 +332,11 @@ function TableView<T extends object>(props: SpectrumTableProps<T>, ref: DOMRef<H
331
332
focusedKey = { state . selectionManager . focusedKey }
332
333
renderView = { renderView }
333
334
renderWrapper = { renderWrapper }
334
- setTableWidth = { state . setTableWidth }
335
+ setTableWidth = { columnState . setTableWidth }
335
336
onVisibleRectChange = { onVisibleRectChange }
336
337
domRef = { domRef }
337
338
bodyRef = { bodyRef }
338
- getColumnWidth = { state . getColumnWidth } />
339
+ getColumnWidth = { columnState . getColumnWidth } />
339
340
</ TableContext . Provider >
340
341
) ;
341
342
}
@@ -391,10 +392,7 @@ function TableVirtualizer({layout, collection, focusedKey, renderView, renderWra
391
392
} , [ bodyRef ] ) ;
392
393
393
394
let onVisibleRectChange = useCallback ( ( rect : Rect ) => {
394
- // setting the table width will recalculate column widths which we only want to do once the virtualizer is done initializing
395
- if ( state . virtualizer . contentSize . height > 0 ) {
396
- setTableWidth ( rect . width ) ;
397
- }
395
+ setTableWidth ( rect . width ) ;
398
396
399
397
state . setVisibleRect ( rect ) ;
400
398
@@ -477,12 +475,14 @@ function TableColumnHeader(props) {
477
475
}
478
476
479
477
let { hoverProps, isHovered} = useHover ( { } ) ;
480
-
481
- const allProps = [ columnHeaderProps , hoverProps ] ;
482
478
if ( columnProps . allowsResizing ) {
483
- allProps . push ( buttonProps ) ;
479
+ // if we allow resizing, override the usePress that useTableColumnHeader generates so that clicking brings up the menu
480
+ // instead of sorting the column immediately
481
+ columnHeaderProps = { ...columnHeaderProps , ...buttonProps } ;
484
482
}
485
483
484
+ const allProps = [ columnHeaderProps , hoverProps ] ;
485
+
486
486
return (
487
487
< FocusRing focusRingClass = { classNames ( styles , 'focus-ring' ) } >
488
488
< div
@@ -522,17 +522,18 @@ function TableColumnHeader(props) {
522
522
) ;
523
523
}
524
524
525
- function ResizableTableColumnHeader ( { item , state } ) {
525
+ function ResizableTableColumnHeader ( { column } ) {
526
526
let ref = useRef ( ) ;
527
+ let { state} = useTableContext ( ) ;
527
528
let formatMessage = useMessageFormatter ( intlMessages ) ;
528
529
529
530
const onMenuSelect = ( key ) => {
530
531
switch ( key ) {
531
532
case 'sort-asc' :
532
- state . sort ( item . key , 'ascending' ) ;
533
+ state . sort ( column . key , 'ascending' ) ;
533
534
break ;
534
535
case 'sort-desc' :
535
- state . sort ( item . key , 'descending' ) ;
536
+ state . sort ( column . key , 'descending' ) ;
536
537
break ;
537
538
case 'resize' :
538
539
// focusResizer, needs timeout so that it happens after the animation timeout for menu close
@@ -542,28 +543,43 @@ function ResizableTableColumnHeader({item, state}) {
542
543
break ;
543
544
}
544
545
} ;
546
+ let allowsSorting = column . props ?. allowsSorting ;
547
+ let items = useMemo ( ( ) => {
548
+ let options = {
549
+ sortAscending : allowsSorting && {
550
+ label : formatMessage ( 'sortAscending' ) ,
551
+ id : 'sort-asc'
552
+ } ,
553
+ sortDescending : allowsSorting && {
554
+ label : formatMessage ( 'sortDescending' ) ,
555
+ id : 'sort-desc'
556
+ } ,
557
+ resize : {
558
+ label : formatMessage ( 'resizeColumn' ) ,
559
+ id : 'resize'
560
+ }
561
+ } ;
562
+ return Object . keys ( options ) . reduce ( ( acc , key ) => {
563
+ if ( options [ key ] ) {
564
+ acc . push ( options [ key ] ) ;
565
+ }
566
+ return acc ;
567
+ } , [ ] ) ;
568
+ } , [ allowsSorting ] ) ;
545
569
546
570
return (
547
571
< >
548
572
< MenuTrigger >
549
- < TableColumnHeader column = { item } />
550
- < Menu onAction = { onMenuSelect } minWidth = "size-2000" >
551
- { item . props ?. allowsSorting &&
552
- < Item key = "sort-asc" >
553
- { formatMessage ( 'sortAscending' ) }
573
+ < TableColumnHeader column = { column } />
574
+ < Menu onAction = { onMenuSelect } minWidth = "size-2000" items = { items } >
575
+ { ( item ) => (
576
+ < Item >
577
+ { item . label }
554
578
</ Item >
555
- }
556
- { item . props ?. allowsSorting &&
557
- < Item key = "sort-desc" >
558
- { formatMessage ( 'sortDescending' ) }
559
- </ Item >
560
- }
561
- < Item key = "resize" >
562
- { formatMessage ( 'resizeColumn' ) }
563
- </ Item >
579
+ ) }
564
580
</ Menu >
565
581
</ MenuTrigger >
566
- < Resizer ref = { ref } item = { item } />
582
+ < Resizer ref = { ref } column = { column } />
567
583
</ >
568
584
) ;
569
585
}
@@ -815,27 +831,4 @@ function CenteredWrapper({children}) {
815
831
*/
816
832
const _TableView = React . forwardRef ( TableView ) as < T > ( props : SpectrumTableProps < T > & { ref ?: DOMRef < HTMLDivElement > } ) => ReactElement ;
817
833
818
- /*
819
- When ready to remove this feature flag, you can remove this whole section of code, delete the _DEPRECATED files, and just replace the export with the _TableView above.
820
- */
821
- function FeatureFlaggedTableView < T extends object > ( props : SpectrumTableProps < T > , ref : DOMRef < HTMLDivElement > ) {
822
- let state = useTableState ( {
823
- ...props
824
- } ) ;
825
-
826
- const someColumnsAllowResizing = state . collection . columns . some ( c => c . props ?. allowsResizing ) ;
827
-
828
- if ( someColumnsAllowResizing ) {
829
- return < _TableView { ...props } ref = { ref } /> ;
830
- } else {
831
- return < TableView_DEPRECATED { ...props } ref = { ref } /> ;
832
- }
833
- }
834
-
835
- /**
836
- * Tables are containers for displaying information. They allow users to quickly scan, sort, compare, and take action on large amounts of data.
837
- */
838
- const _FeatureFlaggedTableView = React . forwardRef ( FeatureFlaggedTableView ) as < T > ( props : SpectrumTableProps < T > & { ref ?: DOMRef < HTMLDivElement > } ) => ReactElement ;
839
-
840
-
841
- export { _FeatureFlaggedTableView as TableView } ;
834
+ export { _TableView as TableView } ;
0 commit comments