Skip to content

ShoppingListOverview

Pure presentation for the multi-list overview — the stable extension seam (§6). It never fetches. Unlike the detail view it holds no context: the overview shares no single datum, so the pieces (ShoppingListOverviewHeader / ShoppingListOverviewTitle / ShoppingListOverviewCreateButton / ShoppingListOverviewItems / ShoppingListOverviewEmpty) take props. Compose them as children for a bespoke layout, or omit children (plus lists + renderItem) for the standard one.

import { ShoppingListOverview } from "@evolve-storefront/feature-shopping-list/shopping-list-overview";

Renders inside ShoppingListProvider.

Preview

DefaultOpen in Storybook ↗

Usage

const { data } = useQuery(
shoppingListsQueryOptions({ gqlClient, scope, enabled: true, page }),
);
<ShoppingListOverview
lists={data?.items ?? []}
pagination={data?.pagination}
page={page}
onPageChange={setPage}
renderItem={(list) => <MyListCard list={list} />}
/>;

Props

No props of its own.

Change the layout

Pass children to ShoppingListOverview to arrange its parts yourself. Every part is exported from @evolve-storefront/feature-shopping-list/shopping-list-overview.

<ShoppingListOverview>
<ShoppingListOverviewHeader>
<ShoppingListOverviewTitle />
<ShoppingListOverviewCreateButton>Add a list</ShoppingListOverviewCreateButton>
</ShoppingListOverviewHeader>
<MyBanner />
<ShoppingListOverviewItems
lists={data.lists}
pagination={data.pagination}
page={page}
onPageChange={setPage}
renderItem={(list) => <MyListCard list={list} />}
/>
</ShoppingListOverview>;
ShoppingListOverviewCreateButtonThe "new shopping list" action.
PropTypeDescription
type?"reset" | "button" | "submit"
isPending?boolean

The action is running. The button keeps its label, so its width and accessible name hold, shows a spinner and is aria-busy. It stays focusable rather than disabled, so focus is not dropped mid-save; clicks and the form submit it would trigger are ignored. Not supported with asChild.

variant?ButtonVariant
tone?ButtonTone
isIconOnly?boolean

The button has no visible label, so it is square. Structural rather than a size: it says the button has nothing to be wide for, and says nothing about how big — the brand's control tokens still decide that.

More

Not inferred from the children. A kebab menu is as often a glyph or an SVG as an <Icon>, and a visually-hidden label — the accessible thing to add — would break any :only-child predicate silently.

asChild?boolean
data-component?undefined

A button's identity is not a caller's to rename — see buttonProps. Typed away so a call site renaming it fails to compile rather than passing an attribute that is silently discarded.

children?ReactNode

Override the button label. Defaults to the overview.new message.

icon?ReactNode

Replace the leading icon (rung 3). Defaults to the add icon.

Any other props go to the root element, like on a plain HTML element.

ShoppingListOverviewHeaderPure layout shell for the overview header (holds no data).
PropTypeDescription
children?ReactNode

Any other props go to the root element, like on a plain HTML element.

ShoppingListOverviewItemsThe overview grid plus its pager.

No props of its own.

ShoppingListOverviewTitleThe overview title.
PropTypeDescription
headingLevel?HeadingLevel

Document level. Defaults to 1 — the overview is a whole page.

Any other props go to the root element, like on a plain HTML element.

Loading and empty states

Render these while the data loads or when there is nothing to show, so the page does not jump when it arrives.

EmptyShoppingListOverviewEmptyThe overview empty state, rendered by ShoppingListOverviewItems when there are no lists.
LoadingShoppingListOverviewSkeletonLoading state for ShoppingListOverview.

Examples

EmptyNo lists → the built-in empty block (title + create action) shows.
<ShoppingListOverview lists={[]} renderItem={renderItem} />;
Open in Storybook ↗
Custom EmptyCustom empty state: pass a branded node to empty to replace the built-in block (content + markup, so it's composition, not CSS).
<ShoppingListOverview
lists={[]}
renderItem={renderItem}
empty={<MyBrandedEmptyState />}
/>;
Open in Storybook ↗