@@ -16,6 +16,7 @@ import {
16
16
Collection ,
17
17
ColumnRenderProps ,
18
18
ColumnResizer ,
19
+ ContextValue ,
19
20
Key ,
20
21
Provider ,
21
22
Cell as RACCell ,
@@ -46,7 +47,7 @@ import {Checkbox} from './Checkbox';
46
47
import Chevron from '../ui-icons/Chevron' ;
47
48
import { colorMix , fontRelative , lightDark , size , style } from '../style/spectrum-theme' with { type : 'macro' } ;
48
49
import { ColumnSize } from '@react-types/table' ;
49
- import { DOMRef , LoadingState , Node } from '@react-types/shared' ;
50
+ import { DOMRef , DOMRefValue , forwardRefType , LoadingState , Node } from '@react-types/shared' ;
50
51
import { GridNode } from '@react-types/grid' ;
51
52
import { IconContext } from './Icon' ;
52
53
// @ts -ignore
@@ -65,6 +66,7 @@ import {useDOMRef} from '@react-spectrum/utils';
65
66
import { useLoadMore } from '@react-aria/utils' ;
66
67
import { useLocalizedStringFormatter } from '@react-aria/i18n' ;
67
68
import { useScale } from './utils' ;
69
+ import { useSpectrumContextProps } from './useSpectrumContextProps' ;
68
70
import { VisuallyHidden } from 'react-aria' ;
69
71
70
72
interface S2TableProps {
@@ -251,7 +253,10 @@ export class S2TableLayout<T> extends UNSTABLE_TableLayout<T> {
251
253
}
252
254
}
253
255
256
+ export const TableContext = createContext < ContextValue < TableViewProps , DOMRefValue < HTMLDivElement > > > ( null ) ;
257
+
254
258
function TableView ( props : TableViewProps , ref : DOMRef < HTMLDivElement > ) {
259
+ [ props , ref ] = useSpectrumContextProps ( props , ref , TableContext ) ;
255
260
let {
256
261
UNSAFE_style,
257
262
UNSAFE_className,
@@ -351,11 +356,9 @@ const centeredWrapper = style({
351
356
352
357
export interface TableBodyProps < T > extends Omit < RACTableBodyProps < T > , 'style' | 'className' | 'dependencies' > { }
353
358
354
- /**
355
- * The body of a `<Table>`, containing the table rows.
356
- */
357
- export function TableBody < T extends object > ( props : TableBodyProps < T > ) {
359
+ function TableBody < T extends object > ( props : TableBodyProps < T > , ref : DOMRef < HTMLDivElement > ) {
358
360
let { items, renderEmptyState, children} = props ;
361
+ let domRef = useDOMRef ( ref ) ;
359
362
let { loadingState} = useContext ( InternalTableContext ) ;
360
363
let emptyRender ;
361
364
let renderer = children ;
@@ -410,6 +413,8 @@ export function TableBody<T extends object>(props: TableBodyProps<T>) {
410
413
411
414
return (
412
415
< RACTableBody
416
+ // @ts -ignore
417
+ ref = { domRef }
413
418
className = { style ( { height : 'full' } ) }
414
419
{ ...props }
415
420
renderEmptyState = { emptyRender }
@@ -419,6 +424,12 @@ export function TableBody<T extends object>(props: TableBodyProps<T>) {
419
424
) ;
420
425
}
421
426
427
+ /**
428
+ * The body of a `<Table>`, containing the table rows.
429
+ */
430
+ let _TableBody = /*#__PURE__*/ ( forwardRef as forwardRefType ) ( TableBody ) ;
431
+ export { _TableBody as TableBody } ;
432
+
422
433
const cellFocus = {
423
434
outlineStyle : {
424
435
default : 'none' ,
@@ -493,14 +504,15 @@ export interface ColumnProps extends RACColumnProps {
493
504
/**
494
505
* A column within a `<Table>`.
495
506
*/
496
- export function Column ( props : ColumnProps ) {
507
+ export const Column = forwardRef ( function Column ( props : ColumnProps , ref : DOMRef < HTMLDivElement > ) {
497
508
let { isHeaderRowHovered} = useContext ( InternalTableHeaderContext ) ;
498
509
let { isQuiet} = useContext ( InternalTableContext ) ;
499
510
let { allowsResizing, children, align = 'start' } = props ;
511
+ let domRef = useDOMRef ( ref ) ;
500
512
let isColumnResizable = allowsResizing ;
501
513
502
514
return (
503
- < RACColumn { ...props } style = { { borderInlineEndColor : 'transparent' } } className = { renderProps => columnStyles ( { ...renderProps , isColumnResizable, align, isQuiet} ) } >
515
+ < RACColumn { ...props } ref = { domRef } style = { { borderInlineEndColor : 'transparent' } } className = { renderProps => columnStyles ( { ...renderProps , isColumnResizable, align, isQuiet} ) } >
504
516
{ ( { allowsSorting, sortDirection, isFocusVisible, sort, startResize, isHovered} ) => (
505
517
< >
506
518
{ /* Note this is mainly for column's without a dropdown menu. If there is a dropdown menu, the button is styled to have a focus ring for simplicity
@@ -522,7 +534,7 @@ export function Column(props: ColumnProps) {
522
534
) }
523
535
</ RACColumn >
524
536
) ;
525
- }
537
+ } ) ;
526
538
527
539
const columnContentWrapper = style ( {
528
540
minWidth : 0 ,
@@ -823,18 +835,20 @@ let InternalTableHeaderContext = createContext<{isHeaderRowHovered?: boolean}>({
823
835
824
836
export interface TableHeaderProps < T > extends Omit < RACTableHeaderProps < T > , 'style' | 'className' | 'dependencies' | 'onHoverChange' | 'onHoverStart' | 'onHoverEnd' > { }
825
837
826
- /**
827
- * A header within a `<Table>`, containing the table columns.
828
- */
829
- export function TableHeader < T extends object > ( { columns, children} : TableHeaderProps < T > ) {
838
+ function TableHeader < T extends object > ( { columns, children} : TableHeaderProps < T > , ref : DOMRef < HTMLDivElement > ) {
830
839
let scale = useScale ( ) ;
831
840
let { selectionBehavior, selectionMode} = useTableOptions ( ) ;
832
841
let { isQuiet} = useContext ( InternalTableContext ) ;
833
842
let [ isHeaderRowHovered , setHeaderRowHovered ] = useState ( false ) ;
843
+ let domRef = useDOMRef ( ref ) ;
834
844
835
845
return (
836
846
< InternalTableHeaderContext . Provider value = { { isHeaderRowHovered} } >
837
- < RACTableHeader onHoverChange = { setHeaderRowHovered } className = { tableHeader } >
847
+ < RACTableHeader
848
+ // @ts -ignore
849
+ ref = { domRef }
850
+ onHoverChange = { setHeaderRowHovered }
851
+ className = { tableHeader } >
838
852
{ /* Add extra columns for selection. */ }
839
853
{ selectionBehavior === 'toggle' && (
840
854
// Also isSticky prop is applied just for the layout, will decide what the RAC api should be later
@@ -863,6 +877,12 @@ export function TableHeader<T extends object>({columns, children}: TableHeaderPr
863
877
) ;
864
878
}
865
879
880
+ /**
881
+ * A header within a `<Table>`, containing the table columns.
882
+ */
883
+ let _TableHeader = /*#__PURE__*/ ( forwardRef as forwardRefType ) ( TableHeader ) ;
884
+ export { _TableHeader as TableHeader } ;
885
+
866
886
function VisuallyHiddenSelectAllLabel ( ) {
867
887
let checkboxProps = useSlottedContext ( RACCheckboxContext , 'selection' ) ;
868
888
@@ -972,13 +992,15 @@ export interface CellProps extends RACCellProps, Pick<ColumnProps, 'align' | 'sh
972
992
/**
973
993
* A cell within a table row.
974
994
*/
975
- export function Cell ( props : CellProps ) {
995
+ export const Cell = forwardRef ( function Cell ( props : CellProps , ref : DOMRef < HTMLDivElement > ) {
976
996
let { children, isSticky, showDivider = false , align, textValue, ...otherProps } = props ;
997
+ let domRef = useDOMRef ( ref ) ;
977
998
let tableVisualOptions = useContext ( InternalTableContext ) ;
978
999
textValue ||= typeof children === 'string' ? children : undefined ;
979
1000
980
1001
return (
981
1002
< RACCell
1003
+ ref = { domRef }
982
1004
// Also isSticky prop is applied just for the layout, will decide what the RAC api should be later
983
1005
// @ts -ignore
984
1006
isSticky = { isSticky }
@@ -997,7 +1019,7 @@ export function Cell(props: CellProps) {
997
1019
) }
998
1020
</ RACCell >
999
1021
) ;
1000
- }
1022
+ } ) ;
1001
1023
1002
1024
// Use color-mix instead of transparency so sticky cells work correctly.
1003
1025
const selectedBackground = lightDark ( colorMix ( 'gray-25' , 'informative-900' , 10 ) , colorMix ( 'gray-25' , 'informative-700' , 10 ) ) ;
@@ -1076,15 +1098,15 @@ const row = style<RowRenderProps & S2TableProps>({
1076
1098
1077
1099
export interface RowProps < T > extends Pick < RACRowProps < T > , 'id' | 'columns' | 'children' | 'textValue' > { }
1078
1100
1079
- /**
1080
- * A row within a `<Table>`.
1081
- */
1082
- export function Row < T extends object > ( { id, columns, children, ...otherProps } : RowProps < T > ) {
1101
+ function Row < T extends object > ( { id, columns, children, ...otherProps } : RowProps < T > , ref : DOMRef < HTMLDivElement > ) {
1083
1102
let { selectionBehavior, selectionMode} = useTableOptions ( ) ;
1084
1103
let tableVisualOptions = useContext ( InternalTableContext ) ;
1104
+ let domRef = useDOMRef ( ref ) ;
1085
1105
1086
1106
return (
1087
1107
< RACRow
1108
+ // @ts -ignore
1109
+ ref = { domRef }
1088
1110
id = { id }
1089
1111
className = { renderProps => row ( {
1090
1112
...renderProps ,
@@ -1103,6 +1125,12 @@ export function Row<T extends object>({id, columns, children, ...otherProps}: Ro
1103
1125
) ;
1104
1126
}
1105
1127
1128
+ /**
1129
+ * A row within a `<Table>`.
1130
+ */
1131
+ let _Row = /*#__PURE__*/ ( forwardRef as forwardRefType ) ( Row ) ;
1132
+ export { _Row as Row } ;
1133
+
1106
1134
/**
1107
1135
* Tables are containers for displaying information. They allow users to quickly scan, sort, compare, and take action on large amounts of data.
1108
1136
*/
0 commit comments