@@ -384,6 +384,13 @@ interface TableInnerProps {
384384 collection : ITableCollection < Node < object > >
385385}
386386
387+ let TableElementType = forwardRef ( function TableElementType ( props : any , ref : ForwardedRef < Element > ) {
388+ let { isVirtualized} = useContext ( CollectionRendererContext ) ;
389+ if ( isVirtualized ) {
390+ return < div { ...props } ref = { ref } /> ;
391+ }
392+ return < table { ...props } ref = { ref } /> ;
393+ } ) ;
387394
388395function TableInner ( { props, forwardedRef : ref , selectionState, collection} : TableInnerProps ) {
389396 [ props , ref ] = useContextProps ( props , ref , SelectableCollectionContext ) ;
@@ -496,7 +503,6 @@ function TableInner({props, forwardedRef: ref, selectionState, collection}: Tabl
496503 }
497504 }
498505
499- let ElementType = useElementType ( 'table' ) ;
500506 let DOMProps = filterDOMProps ( props , { global : true } ) ;
501507
502508 return (
@@ -510,7 +516,7 @@ function TableInner({props, forwardedRef: ref, selectionState, collection}: Tabl
510516 [ FieldInputContext , null ]
511517 ] } >
512518 < FocusScope >
513- < ElementType
519+ < TableElementType
514520 { ...mergeProps ( DOMProps , renderProps , gridProps , focusProps , droppableCollection ?. collectionProps ) }
515521 style = { style }
516522 ref = { ref as RefObject < HTMLTableElement > }
@@ -526,18 +532,13 @@ function TableInner({props, forwardedRef: ref, selectionState, collection}: Tabl
526532 scrollRef = { tableContainerContext ?. scrollRef ?? ref }
527533 persistedKeys = { useDndPersistedKeys ( selectionManager , dragAndDropHooks , dropState ) } />
528534 </ SharedElementTransition >
529- </ ElementType >
535+ </ TableElementType >
530536 </ FocusScope >
531537 { dragPreview }
532538 </ Provider >
533539 ) ;
534540}
535541
536- function useElementType < E extends keyof JSX . IntrinsicElements > ( element : E ) : E | 'div' {
537- let { isVirtualized} = useContext ( CollectionRendererContext ) ;
538- return isVirtualized ? 'div' : element ;
539- }
540-
541542export interface TableOptionsContextValue {
542543 /** The type of selection that is allowed in the table. */
543544 selectionMode : SelectionMode ,
@@ -744,6 +745,14 @@ class TableColumnNode extends CollectionNode<unknown> {
744745 static readonly type = 'column' ;
745746}
746747
748+ let ColumnElementType = forwardRef ( function ColumnElementType ( props : any , ref : ForwardedRef < Element > ) {
749+ let { isVirtualized} = useContext ( CollectionRendererContext ) ;
750+ if ( isVirtualized ) {
751+ return < div { ...props } ref = { ref } /> ;
752+ }
753+ return < th { ...props } ref = { ref } /> ;
754+ } ) ;
755+
747756/**
748757 * A column within a `<Table>`.
749758 */
@@ -804,12 +813,11 @@ export const Column = /*#__PURE__*/ createLeafComponent(TableColumnNode, (props:
804813 style = { ...style , width : layoutState . getColumnWidth ( column . key ) } ;
805814 }
806815
807- let TH = useElementType ( 'th' ) ;
808816 let DOMProps = filterDOMProps ( props as any , { global : true } ) ;
809817 delete DOMProps . id ;
810818
811819 return (
812- < TH
820+ < ColumnElementType
813821 { ...mergeProps ( DOMProps , columnHeaderProps , focusProps , hoverProps ) }
814822 { ...renderProps }
815823 style = { style }
@@ -827,7 +835,7 @@ export const Column = /*#__PURE__*/ createLeafComponent(TableColumnNode, (props:
827835 ] } >
828836 { renderProps . children }
829837 </ Provider >
830- </ TH >
838+ </ ColumnElementType >
831839 ) ;
832840} ) ;
833841
@@ -994,6 +1002,14 @@ class TableBodyNode<T> extends FilterableNode<T> {
9941002 static readonly type = 'tablebody' ;
9951003}
9961004
1005+ let TableBodyElementType = forwardRef ( function TableBodyElementType ( props : any , ref : ForwardedRef < Element > ) {
1006+ let { isVirtualized} = useContext ( CollectionRendererContext ) ;
1007+ if ( isVirtualized ) {
1008+ return < div { ...props } ref = { ref } /> ;
1009+ }
1010+ return < tbody { ...props } ref = { ref } /> ;
1011+ } ) ;
1012+
9971013/**
9981014 * The body of a `<Table>`, containing the table rows.
9991015 */
@@ -1020,8 +1036,6 @@ export const TableBody = /*#__PURE__*/ createBranchComponent(TableBodyNode, <T e
10201036 } ) ;
10211037
10221038 let emptyState ;
1023- let TR = useElementType ( 'tr' ) ;
1024- let TD = useElementType ( 'td' ) ;
10251039 let numColumns = collection . columnCount ;
10261040
10271041 if ( isEmpty && props . renderEmptyState && state ) {
@@ -1036,23 +1050,22 @@ export const TableBody = /*#__PURE__*/ createBranchComponent(TableBodyNode, <T e
10361050 }
10371051
10381052 emptyState = (
1039- < TR role = "row" { ...rowProps } style = { style } >
1040- < TD role = "rowheader" { ...rowHeaderProps } style = { style } >
1053+ < TableRowElementType role = "row" { ...rowProps } style = { style } >
1054+ < TableCellElementType role = "rowheader" { ...rowHeaderProps } style = { style } >
10411055 { props . renderEmptyState ( renderValues ) }
1042- </ TD >
1043- </ TR >
1056+ </ TableCellElementType >
1057+ </ TableRowElementType >
10441058 ) ;
10451059 }
10461060
10471061 let { rowGroupProps} = useTableRowGroup ( ) ;
1048- let TBody = useElementType ( 'tbody' ) ;
10491062
10501063 let DOMProps = filterDOMProps ( props , { global : true } ) ;
10511064
10521065 // TODO: TableBody doesn't support being the scrollable body of the table yet, to revisit if needed. Would need to
10531066 // call useLoadMore here and walk up the DOM to the nearest scrollable element to set scrollRef
10541067 return (
1055- < TBody
1068+ < TableBodyElementType
10561069 { ...mergeProps ( DOMProps , renderProps , rowGroupProps ) }
10571070 ref = { ref as any }
10581071 data-empty = { isEmpty || undefined } >
@@ -1062,7 +1075,7 @@ export const TableBody = /*#__PURE__*/ createBranchComponent(TableBodyNode, <T e
10621075 parent = { collection . body }
10631076 renderDropIndicator = { useRenderDropIndicator ( dragAndDropHooks , dropState ) } />
10641077 { emptyState }
1065- </ TBody >
1078+ </ TableBodyElementType >
10661079 ) ;
10671080} ) ;
10681081
@@ -1117,6 +1130,14 @@ class TableRowNode<T> extends CollectionNode<T> {
11171130 }
11181131}
11191132
1133+ let TableRowElementType = forwardRef ( function TableRowElementType ( props : any , ref : ForwardedRef < Element > ) {
1134+ let { isVirtualized} = useContext ( CollectionRendererContext ) ;
1135+ if ( isVirtualized ) {
1136+ return < div { ...props } ref = { ref } /> ;
1137+ }
1138+ return < tr { ...props } ref = { ref } /> ;
1139+ } ) ;
1140+
11201141/**
11211142 * A row within a `<Table>`.
11221143 */
@@ -1196,22 +1217,20 @@ export const Row = /*#__PURE__*/ createBranchComponent(
11961217 }
11971218 } ) ;
11981219
1199- let TR = useElementType ( 'tr' ) ;
1200- let TD = useElementType ( 'td' ) ;
12011220 let DOMProps = filterDOMProps ( props as any , { global : true } ) ;
12021221 delete DOMProps . id ;
12031222 delete DOMProps . onClick ;
12041223
12051224 return (
12061225 < >
12071226 { dropIndicator && ! dropIndicator . isHidden && (
1208- < TR role = "row" style = { { height : 0 } } >
1209- < TD role = "gridcell" colSpan = { state . collection . columnCount } style = { { padding : 0 } } >
1227+ < TableRowElementType role = "row" style = { { height : 0 } } >
1228+ < TableCellElementType role = "gridcell" colSpan = { state . collection . columnCount } style = { { padding : 0 } } >
12101229 < div role = "button" { ...visuallyHiddenProps } { ...dropIndicator . dropIndicatorProps } ref = { dropIndicatorRef } />
1211- </ TD >
1212- </ TR >
1230+ </ TableCellElementType >
1231+ </ TableRowElementType >
12131232 ) }
1214- < TR
1233+ < TableRowElementType
12151234 { ...mergeProps ( DOMProps , renderProps , rowProps , focusProps , hoverProps , draggableItem ?. dragProps , focusWithinProps ) }
12161235 ref = { ref as any }
12171236 data-disabled = { states . isDisabled || undefined }
@@ -1248,7 +1267,7 @@ export const Row = /*#__PURE__*/ createBranchComponent(
12481267 ] } >
12491268 < CollectionBranch collection = { state . collection } parent = { item } />
12501269 </ Provider >
1251- </ TR >
1270+ </ TableRowElementType >
12521271 </ >
12531272 ) ;
12541273 } ,
@@ -1311,6 +1330,14 @@ class TableCellNode extends CollectionNode<unknown> {
13111330 static readonly type = 'cell' ;
13121331}
13131332
1333+ let TableCellElementType = forwardRef ( function TableCellElementType ( props : any , ref : ForwardedRef < Element > ) {
1334+ let { isVirtualized} = useContext ( CollectionRendererContext ) ;
1335+ if ( isVirtualized ) {
1336+ return < div { ...props } ref = { ref } /> ;
1337+ }
1338+ return < td { ...props } ref = { ref } /> ;
1339+ } ) ;
1340+
13141341/**
13151342 * A cell within a table row.
13161343 */
@@ -1343,13 +1370,11 @@ export const Cell = /*#__PURE__*/ createLeafComponent(TableCellNode, (props: Cel
13431370 }
13441371 } ) ;
13451372
1346- // TODO: Lint doesn't catch these, it thinks we're not in a component render cycle here?
1347- let TD = useElementType ( 'td' ) ;
13481373 let DOMProps = filterDOMProps ( props as any , { global : true } ) ;
13491374 delete DOMProps . id ;
13501375
13511376 return (
1352- < TD
1377+ < TableCellElementType
13531378 { ...mergeProps ( DOMProps , renderProps , gridCellProps , focusProps , hoverProps ) }
13541379 ref = { ref as any }
13551380 data-focused = { isFocused || undefined }
@@ -1358,7 +1383,7 @@ export const Cell = /*#__PURE__*/ createLeafComponent(TableCellNode, (props: Cel
13581383 < CollectionRendererContext . Provider value = { DefaultCollectionRenderer } >
13591384 { renderProps . children }
13601385 </ CollectionRendererContext . Provider >
1361- </ TD >
1386+ </ TableCellElementType >
13621387 ) ;
13631388} ) ;
13641389
@@ -1449,25 +1474,23 @@ function RootDropIndicator() {
14491474 } , dropState ! , ref ) ;
14501475 let isDropTarget = dropState ! . isDropTarget ( { type : 'root' } ) ;
14511476 let { visuallyHiddenProps} = useVisuallyHidden ( ) ;
1452- let TR = useElementType ( 'tr' ) ;
1453- let TD = useElementType ( 'td' ) ;
14541477
14551478 if ( ! isDropTarget && dropIndicatorProps [ 'aria-hidden' ] ) {
14561479 return null ;
14571480 }
14581481
14591482 return (
1460- < TR
1483+ < TableRowElementType
14611484 role = "row"
14621485 aria-hidden = { dropIndicatorProps [ 'aria-hidden' ] }
14631486 style = { { height : 0 } } >
1464- < TD
1487+ < TableCellElementType
14651488 role = "gridcell"
14661489 colSpan = { state . collection . columnCount }
14671490 style = { { padding : 0 } } >
14681491 < div role = "button" { ...visuallyHiddenProps } { ...dropIndicatorProps } ref = { ref } />
1469- </ TD >
1470- </ TR >
1492+ </ TableCellElementType >
1493+ </ TableRowElementType >
14711494 ) ;
14721495}
14731496
@@ -1509,8 +1532,6 @@ export const TableLoadMoreItem = createLeafComponent(LoaderNode, function TableL
15091532 defaultClassName : 'react-aria-TableLoadingIndicator' ,
15101533 values : null
15111534 } ) ;
1512- let TR = useElementType ( 'tr' ) ;
1513- let TD = useElementType ( 'td' ) ;
15141535 let rowProps = { } ;
15151536 let rowHeaderProps = { } ;
15161537 let style = { } ;
@@ -1529,21 +1550,21 @@ export const TableLoadMoreItem = createLeafComponent(LoaderNode, function TableL
15291550 < >
15301551 { /* Alway render the sentinel. For now onus is on the user for styling when using flex + gap (this would introduce a gap even though it doesn't take room) */ }
15311552 { /* @ts -ignore - compatibility with React < 19 */ }
1532- < TR style = { { height : 0 } } inert = { inertValue ( true ) } >
1533- < TD style = { { padding : 0 , border : 0 } } >
1553+ < TableRowElementType style = { { height : 0 } } inert = { inertValue ( true ) } >
1554+ < TableCellElementType style = { { padding : 0 , border : 0 } } >
15341555 < div data-testid = "loadMoreSentinel" ref = { sentinelRef } style = { { position : 'relative' , height : 1 , width : 1 } } />
1535- </ TD >
1536- </ TR >
1556+ </ TableCellElementType >
1557+ </ TableRowElementType >
15371558 { isLoading && renderProps . children && (
1538- < TR
1559+ < TableRowElementType
15391560 { ...mergeProps ( filterDOMProps ( props , { global : true } ) , rowProps ) }
15401561 { ...renderProps }
15411562 role = "row"
15421563 ref = { ref as ForwardedRef < HTMLTableRowElement > } >
1543- < TD role = "rowheader" { ...rowHeaderProps } style = { style } >
1564+ < TableCellElementType role = "rowheader" { ...rowHeaderProps } style = { style } >
15441565 { renderProps . children }
1545- </ TD >
1546- </ TR >
1566+ </ TableCellElementType >
1567+ </ TableRowElementType >
15471568 ) }
15481569 </ >
15491570 ) ;
0 commit comments