From 884769f644104b59ddcfbc753a55e8952109237e Mon Sep 17 00:00:00 2001 From: Jan Vincent Hoffbauer Date: Sun, 27 Jul 2025 10:24:27 +0200 Subject: [PATCH 1/3] feat(collection): Add table type to collection primitive --- .../src/primitives/Collection/Collection.tsx | 22 ++++++++++ .../Collection/__tests__/Collection.test.tsx | 42 +++++++++++++++++++ .../react/src/primitives/types/collection.ts | 9 ++++ 3 files changed, 73 insertions(+) diff --git a/packages/react/src/primitives/Collection/Collection.tsx b/packages/react/src/primitives/Collection/Collection.tsx index c77c2177908..fec3dafd421 100644 --- a/packages/react/src/primitives/Collection/Collection.tsx +++ b/packages/react/src/primitives/Collection/Collection.tsx @@ -16,8 +16,10 @@ import type { ElementType, GridCollectionProps, ListCollectionProps, + TableCollectionProps, } from '../types'; import { getItemsAtPage, itemHasText, getPageCount } from './utils'; +import { Table, TableBody } from '../Table'; const DEFAULT_PAGE_SIZE = 10; const TYPEAHEAD_DELAY_MS = 300; @@ -41,6 +43,18 @@ const GridCollection = ({ {Array.isArray(items) ? items.map(children) : null} ); +const TableCollection = ({ + children, + items, + tableHeader: TableHeader, + ...rest +}: TableCollectionProps) => ( + + + {Array.isArray(items) ? items.map(children) : null} +
+); + const renderCollectionOrNoResultsFound = ( collection: React.JSX.Element | null, items: Item[], @@ -114,6 +128,14 @@ export const Collection = ({ items={items} {...rest} /> + ) : type === 'table' ? ( + ).tableHeader!} + {...rest} + /> ) : null; return ( diff --git a/packages/react/src/primitives/Collection/__tests__/Collection.test.tsx b/packages/react/src/primitives/Collection/__tests__/Collection.test.tsx index a7eaa2fa630..c5ba19d7f89 100644 --- a/packages/react/src/primitives/Collection/__tests__/Collection.test.tsx +++ b/packages/react/src/primitives/Collection/__tests__/Collection.test.tsx @@ -10,6 +10,7 @@ import { Flex } from '../../Flex'; import { Text } from '../../Text'; import { ComponentText } from '../../shared/constants'; import { ComponentPropsToStylePropsMap } from '../../types'; +import { TableCell, TableHead, TableRow } from '../../Table'; const emojis = [ { @@ -282,4 +283,45 @@ describe('Collection component', () => { const noResults = await screen.findByText(customText); expect(noResults).toBeDefined(); }); + + it('should render table with table header when type is table', async () => { + const borderStyle = '1px solid red'; + render( + ( + + Title + Emoji + + )} + > + {(item, _index) => ( + + {item.title} + {item.emoji} + + )} + + ); + + const collection = await screen.findByTestId(testList); + const items = getElementByClassName( + collection, + ComponentClassName.CollectionItems + ); + + expect( + items?.style.getPropertyValue( + kebabCase(ComponentPropsToStylePropsMap.border) + ) + ).toBe(borderStyle); + + const tdNode = items?.children[1].children[0].children[0]; + expect(tdNode?.nodeName).toBe('TD'); + expect(tdNode?.innerHTML).toBe('LOL'); + }); }); diff --git a/packages/react/src/primitives/types/collection.ts b/packages/react/src/primitives/types/collection.ts index e22f4704822..e5a18879283 100644 --- a/packages/react/src/primitives/types/collection.ts +++ b/packages/react/src/primitives/types/collection.ts @@ -81,6 +81,14 @@ export type ListCollectionProps = Omit & CollectionBaseProps; export type GridCollectionProps = Omit & CollectionBaseProps; +export type TableCollectionProps = Omit & + CollectionBaseProps & { + /** + * @description + * Custom table header component to be rendered at the top of the table + */ + tableHeader: () => React.ReactNode; + }; /** * Omits `React.ReactNode` as children to prevent intersection type for `children` of @@ -98,6 +106,7 @@ export type BaseCollectionProps< ( | ReplaceChildren<{ type: 'list' } & ListCollectionProps, Item> | ReplaceChildren<{ type: 'grid' } & GridCollectionProps, Item> + | ReplaceChildren<{ type: 'table' } & TableCollectionProps, Item> ); export type CollectionProps< From 1f4b7506970bc3a4acd565b6a40a5fe8c9f1dfc4 Mon Sep 17 00:00:00 2001 From: Jan Vincent Hoffbauer Date: Sun, 27 Jul 2025 14:06:45 +0200 Subject: [PATCH 2/3] chore(collection): Use partial type to avoid type parsing linter error --- packages/react/src/primitives/Collection/Collection.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react/src/primitives/Collection/Collection.tsx b/packages/react/src/primitives/Collection/Collection.tsx index fec3dafd421..321ea3d49d5 100644 --- a/packages/react/src/primitives/Collection/Collection.tsx +++ b/packages/react/src/primitives/Collection/Collection.tsx @@ -132,8 +132,7 @@ export const Collection = ({ ).tableHeader!} + tableHeader={(rest as Partial>).tableHeader!} {...rest} /> ) : null; From 2ad3cc4a4cd33e456782b3881be99d0f64c685dc Mon Sep 17 00:00:00 2001 From: jvh-aws Date: Mon, 28 Jul 2025 17:13:38 +0200 Subject: [PATCH 3/3] chore(collection): Add changeset for adding `table` type to `Collection` UI primitive --- .changeset/unlucky-otters-dress.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/unlucky-otters-dress.md diff --git a/.changeset/unlucky-otters-dress.md b/.changeset/unlucky-otters-dress.md new file mode 100644 index 00000000000..6945ff68c0a --- /dev/null +++ b/.changeset/unlucky-otters-dress.md @@ -0,0 +1,5 @@ +--- +"@aws-amplify/ui-react": minor +--- + +feat(collection): Add `table` type to `Collection` UI primitive