Collection hooks package
Use the Cloudscape collection hooks package to handle data operations in collection components.
On this page
Did this page help you?
Tell us more - optional
Overview
Cloudscape provides table and cards components to display collections of resources. These components display static datasets. Operations on these datasets (such as filtering, sorting, and pagination) should happen outside of these components.
Client-side collections
The @cloudscape-design/collection-hooks
package provides utilities to handle filtering, sorting, or pagination operations when the full dataset describing the collection can be fetched on the client side, without requiring further asynchronous calls. This use case is called client-side collection.
Server-side collections
If your dataset has to be fetched asynchronously upon filtering, sorting, and pagination operations, don’t use the @cloudscape-design/collection-hooks
package. Instead, implement the fetching, filtering, selection, pagination, and sorting yourself. This use case is called server-side collection.
Install the package
This package is published to NPM as @cloudscape-design/collection-hooks .
For more information, see the package installation guide.
Using with React
This package exports the useCollection
React hook . It takes the original collection items and a configuration, and returns filtered, sorted, and paginated content, according to your configuration.
Code example
Example below uses text filtering. Check out the official demo that uses property filtering feature of the collection hooks.
Preview
Instances (25)
ID | Availability zone | State | |
---|---|---|---|
O4DMYB22MWEYROBVNSRAN | us-east-1c | Healthy | |
S4JE6P56MI4XBCMD63GQP | us-east-1a | Healthy | |
7U59ZZLQYGXZFHTKZF7UI | us-east-1d | Healthy | |
LF2QRGQR73UA8I4HOJXGP | us-east-1b | Unhealthy | |
8WYHUA2A03V71YQMM5VYN | us-east-1a | Healthy | |
PJVCIGWWP24XF6168QDR9 | us-east-1c | Healthy | |
DLBTSDMY30151I1B3Q77B | us-east-1e | Healthy | |
EEIX26WFY6YA56R2BER2E | us-east-1b | Healthy | |
8JMC1H9LIKCKGCXS6FT3Y | us-east-1c | Healthy | |
KPG0CDOTQRF830MWRDIA5 | us-east-1d | Healthy |
Code
The following code uses React and JSX syntax.
import React, { useState } from 'react';
import { useCollection } from '@cloudscape-design/collection-hooks';
import {
Box,
Button,
CollectionPreferences,
Header,
Pagination,
Table,
TextFilter,
} from '@cloudscape-design/components';
import allItems from './data';
import { columnDefinitions, getMatchesCountText, paginationLabels, collectionPreferencesProps } from './table-config';
function EmptyState({ title, subtitle, action }) {
return (
<Box textAlign="center" color="inherit">
<Box variant="strong" textAlign="center" color="inherit">
{title}
</Box>
<Box variant="p" padding={{ bottom: 's' }} color="inherit">
{subtitle}
</Box>
{action}
</Box>
);
}
export default function CollectionHooksTable() {
const [preferences, setPreferences] = useState({ pageSize: 10, visibleContent: ['id', 'availabilityZone', 'state'] });
const { items, actions, filteredItemsCount, collectionProps, filterProps, paginationProps } = useCollection(
allItems,
{
filtering: {
empty: <EmptyState title="No instances" action={<Button>Create instance</Button>} />,
noMatch: (
<EmptyState
title="No matches"
action={<Button onClick={() => actions.setFiltering('')}>Clear filter</Button>}
/>
),
},
pagination: { pageSize: preferences.pageSize },
sorting: {},
selection: {},
}
);
const { selectedItems } = collectionProps;
return (
<Table
{...collectionProps}
selectionType="multi"
header={
<Header
counter={selectedItems.length ? `(${selectedItems.length}/${allItems.length})` : `(${allItems.length})`}
>
Instances
</Header>
}
columnDefinitions={columnDefinitions}
visibleColumns={preferences.visibleContent}
items={items}
pagination={<Pagination {...paginationProps} ariaLabels={paginationLabels} />}
filter={
<TextFilter
{...filterProps}
countText={getMatchesCountText(filteredItemsCount)}
filteringAriaLabel="Filter instances"
/>
}
preferences={
<CollectionPreferences
{...collectionPreferencesProps}
preferences={preferences}
onConfirm={({ detail }) => setPreferences(detail)}
/>
}
/>
);
}
Using custom operator matchers
If you want to override the default filtering logic, use a match function on the extended operator notation:
const { items, propertyFilterProps, ... } = useCollection({
propertyFiltering: {
filteringProperties: [
// Using custom matcher to support searching with a comma-separated list
{
key: 'status',
operators: [
{ operator: '=', match: (itemValue, tokenValue) => tokenValue.split(',').includes(itemValue) },
{ operator: '!=', match: (itemValue, tokenValue) => !tokenValue.split(',').includes(itemValue) },
],
...
},
// Using predefined date matcher
{
key: 'launchDate',
operators: [
{ operator: '=', match: 'date' },
{ operator: '!=', match: 'date' },
{ operator: '<', match: 'date' },
{ operator: '<=', match: 'date' },
{ operator: '>', match: 'date' },
{ operator: '>=', match: 'date' },
],
...
},
// Using predefined datetime matcher
{
key: 'lastEventAt',
operators: [
{ operator: '=', match: 'datetime' },
{ operator: '!=', match: 'datetime' },
{ operator: '<', match: 'datetime' },
{ operator: '<=', match: 'datetime' },
],
...
},
]
}
});
Note that overrides are done per operator.
Intercepting event listeners
If you want to define a custom behavior upon user actions, ensure you always call the method created by the collection hook:
const { ..., paginationProps } = useCollection(...);
return (
<Table
...
pagination={
<Pagination
{...paginationProps}
onChange={event => {
myCustomFunction(event);
paginationProps.onChange(event);
}}
/>
}
/>
);
API
useCollection(allItems: Array, configuration: Configuration): Result
Configuration
Name | Type | Description |
---|---|---|
filtering | Object | Filtering configuration. If you want to activate filtering with default settings, provide an empty object. |
filteringFunction | (item: T, text: string, fields?: string[]) => boolean | Custom function to filter items. The default value is a function that loops through all items keys (unless |
fields | string[] | Array of keys within the item object whose values are taken into account by the default filteringFunction. |
defaultFilteringText | string | Initial filtering value on the first render. |
empty | React.ReactNode | Content to display in the table/cards empty slot when there are no items initially provided. |
noMatch | React.ReactNode | Content to display in the table/cards empty slot when filtering returns no matched items. |
propertyFiltering | Object | Configuration for property filtering. |
filteringProperties | readonly PropertyFilterProperty[] | Array of properties by which the data set is going to be filtered. Individual items have following properties:
|
filteringFunction | (item: T, query: PropertyFilterQuery) => boolean; | Custom function to filter items. The default value is a function that takes values under the |
defaultQuery | PropertyFilterQuery | Initial query on the first render. |
empty | React.ReactNode | Content to display in the table/cards empty slot when there are no items initially provided. |
noMatch | React.ReactNode | Content to display in the table/cards empty slot when filtering returns no matched items. |
sorting | Object | Sorting configuration. If you want to use sorting with default settings, provide an empty object. This feature is only applicable for the table component. |
defaultState | Object | Initial sorting state on the first render. This is an object with two properties:
|
pagination | Object | Pagination configuration. If you want to paginate items using default settings, provide an empty object. |
pageSize | number | Value of the desired page size. |
defaultPage | number | Page number for the initial render. |
selection | Object | Selection configuration. If you want to use the selection feature with default settings, provide an empty object. |
defaultSelectedItems | ReadonlyArray<T> | Items selected on the initial render. |
keepSelection | boolean | If set to |
trackBy | string | ((item: T) => string) | Property of an item that uniquely identifies it. It is used for matching the objects in |
Result
Name | Type | Description |
---|---|---|
items | ReadOnlyArray<T> | Processed items to display in the table. |
allPageItems | ReadOnlyArray<T> | |
filteredItemsCount | number | Total numbers of items matching the current filter, ignoring the pagination. Use this value for creating the localized matches count text for the TextFilter component. |
actions | Object | An object with functions to perform different actions. |
setFiltering | (filteringText: string): void | Sets new filtering text. |
setPropertyFiltering | (query: Query): void | Sets new filtering query. |
setSorting | (state: SortingState): void | Sets new sorting state. |
setCurrentPage | (currentPageIndex: number): void | Sets current page in pagination. |
setSelectedItems | (selectedItems: ReadonlyArray): void | Sets the list of currently selected items. |
collectionProps | Object | Props object to spread on the table/cards component. For more details see the table component API documentation. |
empty | React.ReactNode | |
sortingColumn | SortingColumn<T> | |
sortingDescending | boolean | |
onSortingChange | (event: CustomEvent<SortingState>) => void | |
selectedItems | ReadonlyArray<T> | |
onSelectionChange | (event: CustomEvent<SelectionChangeDetail<T>>) => void | |
trackBy | string | ((item: T) => string) | |
ref | React.RefObject<CollectionRef> | |
filterProps | Object | Props object to spread on the TextFilter component. |
disabled | boolean | |
filteringText | string | |
onChange | (event: CustomEvent<ChangeDetail>) => void | |
propertyFilterProps | Object | Props object to spread on the PropertyFilter component. |
query | PropertyFilterQuery | |
onChange | (event: CustomEvent<Query>) => void | |
filteringProperties | readonly PropertyFilterProperty[] | |
filteringOptions | readonly PropertyFilterOption[] | |
paginationProps | Object | Props object to spread on the Pagination component. |
disabled | boolean | |
currentPageIndex | number | |
pagesCount | number | |
onChange | (event: CustomEvent<ChangeDetail>) => void |