Demo
Usage
Import the Collection component and provide your own repeating component as a function. Here's an example using the list collection type.
Fiordland National Park
This national park includes the famous fjords of Milford, Dusky and Doubtful Sounds.
Bay of Islands, North Island
Three hours north of Auckland, this area features over 144 islands to explore.
Queenstown, South Island
This hopping town is New Zealand's adventure capital and is located right on Lake Wakatipu.
import { Collection, Card, Heading, Text } from '@aws-amplify/ui-react';
export const DefaultCollectionExample = () => {
return (
<Collection
type="list"
items={[
{
title: 'Fiordland National Park',
description:
'This national park includes the famous fjords of Milford, Dusky and Doubtful Sounds.',
},
{
title: 'Bay of Islands, North Island',
description:
'Three hours north of Auckland, this area features over 144 islands to explore.',
},
{
title: 'Queenstown, South Island',
description:
"This hopping town is New Zealand's adventure capital and is located right on Lake Wakatipu.",
},
]}
gap="1.5rem"
>
{(item, index) => (
<Card key={index} padding="1rem">
<Heading level={4}>{item.title}</Heading>
<Text>{item.description}</Text>
</Card>
)}
</Collection>
);
};
Collection types
Collection type options include list and grid.
List
The list collection type can be customized with any of following Flex props: alignItems, alignContent, direction, gap, justifyContent, wrap.
Fiordland National Park
This national park includes the famous fjords of Milford, Dusky and Doubtful Sounds.
Bay of Islands, North Island
Three hours north of Auckland, this area features over 144 islands to explore.
Queenstown, South Island
This hopping town is New Zealand's adventure capital and is located right on Lake Wakatipu.
import {
Collection,
Card,
Heading,
Text,
useTheme,
} from '@aws-amplify/ui-react';
export const ListCollectionExample = () => {
const { tokens } = useTheme();
const items = [
{
title: 'Fiordland National Park',
description:
'This national park includes the famous fjords of Milford, Dusky and Doubtful Sounds.',
},
{
title: 'Bay of Islands, North Island',
description:
'Three hours north of Auckland, this area features over 144 islands to explore.',
},
{
title: 'Queenstown, South Island',
description:
"This hopping town is New Zealand's adventure capital and is located right on Lake Wakatipu.",
},
];
return (
<Collection
type="list"
items={items}
direction="row"
justifyContent="space-between"
wrap="wrap"
>
{(item, index) => (
<Card
key={index}
padding={tokens.space.medium}
maxWidth="180px"
fontSize={tokens.fontSizes.xs}
>
<Heading level={4}>{item.title}</Heading>
<Text>{item.description}</Text>
</Card>
)}
</Collection>
);
};
Grid
The grid collection type can be customized with the following Grid props: templateColumns and templateRows. Then the Collection children can use the Grid props to control their size and placement such as row and column.
Fiordland National Park
This national park includes the famous fjords of Milford, Dusky and Doubtful Sounds.
Bay of Islands
Three hours north of Auckland, this area features over 144 islands to explore.
Queenstown, South Island
This hopping town is New Zealand's adventure capital and is located right on Lake Wakatipu.
import {
Collection,
Card,
Heading,
Text,
useTheme,
} from '@aws-amplify/ui-react';
export const GridCollectionExample = () => {
const { tokens } = useTheme();
const items = [
{
title: 'Fiordland National Park',
description:
'This national park includes the famous fjords of Milford, Dusky and Doubtful Sounds.',
},
{
title: 'Bay of Islands',
description:
'Three hours north of Auckland, this area features over 144 islands to explore.',
},
{
title: 'Queenstown, South Island',
description:
"This hopping town is New Zealand's adventure capital and is located right on Lake Wakatipu.",
},
];
return (
<Collection
type="grid"
items={items}
templateColumns="1fr 1fr 1fr"
templateRows="12rem 12rem 12rem"
>
{(item, index) => {
return (
<Card
key={index}
padding={tokens.space.medium}
maxWidth="180px"
fontSize={tokens.fontSizes.xs}
backgroundColor={tokens.colors.background.secondary}
row={index + 1}
column={index + 1}
>
<Heading level={4}>{item.title}</Heading>
<Text>{item.description}</Text>
</Card>
);
}}
</Collection>
);
};
Pagination
A Collection can be paginated by adding a special isPaginated property. Change the page size by passing a itemsPerPage property (default: 10).
import { Collection, Button } from '@aws-amplify/ui-react';
import { countries } from 'countries-list';
export const PaginationCollectionExample = () => {
return (
<Collection
type="list"
direction="row"
wrap="wrap"
items={Object.values(countries).map(({ name, emoji }) => ({
name,
emoji,
}))}
isPaginated
itemsPerPage={12}
>
{(regions, index) => (
<Button grow="1" key={index}>
{regions.emoji} {regions.name}
</Button>
)}
</Collection>
);
};
Search
Collections can also be filtered, adding a isSearchable property. Pass a custom searchFilter function to enhance your search experience (default search filter looks for any string-like property inside of items)
import { Collection, Button } from '@aws-amplify/ui-react';
import { countries } from 'countries-list';
export const SearchCollectionExample = () => {
return (
<Collection
type="grid"
templateColumns="1fr 1fr 1fr"
gap="15px"
items={Object.values(countries).map(({ name, emoji }) => ({
name,
emoji,
}))}
isSearchable
isPaginated
itemsPerPage={9}
searchPlaceholder="Type to search..."
searchFilter={(regions, keyword) =>
(regions as any).name.toLowerCase().startsWith(keyword.toLowerCase())
}
>
{(regions, index) => (
<Button grow="1" key={index}>
{regions.emoji} {regions.name}
</Button>
)}
</Collection>
);
};
No Results Found
To handle the case when no results are found from the search, you can pass a custom ReactNode (includes string) to the searchNoResultsFound prop. By default, Collection renders the text "No results found".
import { Collection, Button, Text, Flex } from '@aws-amplify/ui-react';
import { countries } from 'countries-list';
export const SearchNoResultsFoundCollectionExample = () => {
return (
<Collection
type="grid"
templateColumns="1fr 1fr 1fr"
gap="15px"
items={Object.values(countries).map(({ name, emoji }) => ({
name,
emoji,
}))}
isSearchable
isPaginated
itemsPerPage={9}
searchNoResultsFound={
<Flex justifyContent="center">
<Text color="purple.80" fontSize="1rem">
Nothing found, please try again
</Text>
</Flex>
}
searchPlaceholder="Type to search..."
searchFilter={(regions, keyword) =>
(regions as any).name.toLowerCase().startsWith(keyword.toLowerCase())
}
>
{(regions, index) => (
<Button grow="1" key={index}>
{regions.emoji} {regions.name}
</Button>
)}
</Collection>
);
};
Customization
Theme
You can customize the appearance of all Collection components in your application with a Theme.
Collection Theme Source
import {
Button,
Collection,
ThemeProvider,
Theme,
} from '@aws-amplify/ui-react';
import { countries } from 'countries-list';
const theme: Theme = {
name: 'collection-theme',
tokens: {
components: {
collection: {
pagination: {
current: {
color: { value: 'white' },
backgroundColor: {
value: '{colors.blue.80}',
},
},
button: {
color: { value: '{colors.blue.60}' },
_hover: {
backgroundColor: {
value: '{colors.blue.10}',
},
color: { value: '{colors.blue.60}' },
},
},
},
search: {
input: {
color: { value: '{colors.blue.60}' },
},
button: {
color: { value: '{colors.blue.60}' },
_focus: {
backgroundColor: {
value: '{colors.blue.60}',
},
color: {
value: 'white',
},
},
_hover: {
backgroundColor: {
value: '{colors.blue.80}',
},
color: {
value: 'white',
},
},
},
},
},
},
},
};
export const CollectionThemeExample = () => {
return (
<ThemeProvider theme={theme} colorMode="light">
<Collection
type="grid"
templateColumns="1fr 1fr 1fr"
gap="15px"
items={Object.values(countries).map(({ name, emoji }) => ({
name,
emoji,
}))}
isSearchable
isPaginated
itemsPerPage={9}
searchPlaceholder="Type to search..."
searchFilter={(regions, keyword) =>
(regions as any).name.toLowerCase().startsWith(keyword.toLowerCase())
}
>
{(regions, index) => (
<Button grow="1" key={index}>
{regions.emoji} {regions.name}
</Button>
)}
</Collection>
</ThemeProvider>
);
};
Target classes
| Class | Description |
|---|---|
amplify-collection | Top level element that wraps the Collection primitive |
amplify-collection-items | Class applied to the element that wraps all the items in a collection |
amplify-collection-search | Class applied to the element that wraps the collection search box |
amplify-collection-pagination | Class applied to the element that wraps the pagination component in a collection |
--amplify-components-collection-pagination-button-color--amplify-components-collection-pagination-button-disabled-color--amplify-components-collection-pagination-button-hover-background-color--amplify-components-collection-pagination-button-hover-color--amplify-components-collection-pagination-current-background-color--amplify-components-collection-pagination-current-color--amplify-components-collection-search-button-active-background-color--amplify-components-collection-search-button-active-border-color--amplify-components-collection-search-button-active-color--amplify-components-collection-search-button-color--amplify-components-collection-search-button-disabled-background-color--amplify-components-collection-search-button-disabled-border-color--amplify-components-collection-search-button-disabled-color--amplify-components-collection-search-button-focus-background-color--amplify-components-collection-search-button-focus-border-color--amplify-components-collection-search-button-focus-color--amplify-components-collection-search-button-hover-background-color--amplify-components-collection-search-button-hover-border-color--amplify-components-collection-search-button-hover-color--amplify-components-collection-search-input-color
Global Styling
To override the styling on all Collections you can use the built in .amplify-collection class.
.amplify-collection {
--amplify-components-collection-pagination-current-color: var(
--amplify-colors-secondary-20
);
--amplify-components-collection-pagination-current-background-color: var(
--amplify-colors-teal-80
);
}
Local Styling
To override styling on a specific Collection, you can use a class selector or style props.
Using a class selector:
import { Collection, Button } from '@aws-amplify/ui-react';
import { countries } from 'countries-list';
export const LocalCollectionClassExample = () => {
const items = Object.values(countries)
.map(({ name, emoji }) => ({
name,
emoji,
}))
.splice(0, 20);
return (
<Collection
type="list"
className="collection-local-styling-example"
direction="row"
items={items}
>
{(regions, index) => (
<Button grow="1" key={index}>
{regions.emoji}
</Button>
)}
</Collection>
);
};
.collection-local-styling-example {
flex-wrap: wrap;
gap: 20px;
padding: 5px;
}
.collection-local-styling-example .amplify-collection-items {
flex-wrap: wrap;
gap: 20px;
}
.collection-local-styling-example .amplify-button {
background-color: var(--amplify-colors-neutral-60);
}
Using style props:
import { Collection, Button, useTheme } from '@aws-amplify/ui-react';
import { countries } from 'countries-list';
export const CollectionStylePropExample = () => {
const { tokens } = useTheme();
const items = Object.values(countries)
.map(({ name, emoji }) => ({
name,
emoji,
}))
.splice(0, 20);
return (
<Collection
type="list"
border={`${tokens.borderWidths.medium} solid ${tokens.colors.red[60]}`}
direction="row"
wrap="wrap"
padding="5px"
gap="20px"
items={items}
>
{(regions, index) => (
<Button grow="1" key={index}>
{regions.emoji}
</Button>
)}
</Collection>
);
};
