diff --git a/.changeset/quiet-carpets-arrive.md b/.changeset/quiet-carpets-arrive.md new file mode 100644 index 0000000000..e0104cc286 --- /dev/null +++ b/.changeset/quiet-carpets-arrive.md @@ -0,0 +1,22 @@ +--- +'@backstage/ui': minor +--- + +**BREAKING**: The `cell` and `header` properties in `ColumnConfig` now return `ReactElement` instead of `ReactNode`. + +This fixes an issue where React Aria's Collection component would inject an `id` prop into Fragment wrappers, causing "Invalid prop `id` supplied to `React.Fragment`" errors on render. + +Migration: + +```diff +const columns: ColumnConfig[] = [ + { + id: 'name', + label: 'Name', +- cell: (item) => item.name, ++ cell: (item) => , +- header: () => 'Name', ++ header: () => Name, + }, +]; +``` diff --git a/packages/ui/report.api.md b/packages/ui/report.api.md index fa50111cde..47d306fefb 100644 --- a/packages/ui/report.api.md +++ b/packages/ui/report.api.md @@ -479,11 +479,11 @@ export const Column: (props: ColumnProps) => JSX_2.Element; // @public (undocumented) export interface ColumnConfig { // (undocumented) - cell: (item: T) => ReactNode; + cell: (item: T) => ReactElement; // (undocumented) defaultWidth?: ColumnSize | null; // (undocumented) - header?: () => ReactNode; + header?: () => ReactElement; // (undocumented) id: string; // (undocumented) diff --git a/packages/ui/src/components/Table/components/Table.tsx b/packages/ui/src/components/Table/components/Table.tsx index f417063e74..c65340c026 100644 --- a/packages/ui/src/components/Table/components/Table.tsx +++ b/packages/ui/src/components/Table/components/Table.tsx @@ -29,7 +29,7 @@ import type { RowRenderFn, TablePaginationType, } from '../types'; -import { Fragment, useMemo } from 'react'; +import { useMemo } from 'react'; import { VisuallyHidden } from '../../VisuallyHidden'; import { Flex } from '../../Flex'; @@ -158,7 +158,7 @@ export function Table({ {column => column.header ? ( - <>{column.header()} + column.header() ) : ( ({ : undefined } > - {column => ( - {column.cell(item)} - )} + {column => column.cell(item)} ); }} diff --git a/packages/ui/src/components/Table/types.ts b/packages/ui/src/components/Table/types.ts index 6ba44b6697..6d94d58fe6 100644 --- a/packages/ui/src/components/Table/types.ts +++ b/packages/ui/src/components/Table/types.ts @@ -19,7 +19,7 @@ import { ColumnProps as ReactAriaColumnProps, TableProps as ReactAriaTableProps, } from 'react-aria-components'; -import type { ReactNode } from 'react'; +import type { ReactElement, ReactNode } from 'react'; import type { SortDescriptor as ReactStatelySortDescriptor } from 'react-stately'; import type { ColumnSize, ColumnStaticSize } from '@react-types/table'; import type { TextColors } from '../../types'; @@ -89,8 +89,8 @@ export type TablePaginationType = NoPagination | PagePagination; export interface ColumnConfig { id: string; label: string; - cell: (item: T) => ReactNode; - header?: () => ReactNode; + cell: (item: T) => ReactElement; + header?: () => ReactElement; isSortable?: boolean; isHidden?: boolean; width?: ColumnSize | null;