Skip to content

Commit a81fa41

Browse files
committed
convert remaining useElementTypes
1 parent 500c564 commit a81fa41

File tree

1 file changed

+69
-48
lines changed

1 file changed

+69
-48
lines changed

packages/react-aria-components/src/Table.tsx

Lines changed: 69 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -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

388395
function 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-
541542
export 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

Comments
 (0)