Skip to content
buttery

v1.0.0

Source on GitHub

Version 1.0.0

Catalog page

A page of things to browse, with a filter column beside featured items and grids of cards.

A catalog page lays out things to browse, such as add-ons or products: a filter column with a search, categories and checkboxes, beside a featured block and grids of cards. Use CatalogPage when people pick from many items by kind.

The parts

  • The filter column

    filters holds a SearchField, CatalogPage.Categories, a list of links to each category, and a CatalogPage.Group for each set of checkboxes, then an action.

  • The featured block

    CatalogPage.Featured is the catalog's featured block: its title and its items on a tinted surface.

  • Sections

    CatalogPage.Section is a titled section of items, such as one category's.

  • Items

    CatalogPage.Item is one thing in the catalog, a plain Catalog.Card: its tile, its name as a link, what it is, its offer and its tags.

The filter column sits beside the catalog from 900px of the page's column in a shell at least 1100px wide, and above it otherwise. The featured block and each section show their items two to a row from 560px of room.

Other catalogs

CatalogPage is one arrangement of Catalog's parts. For a shop's product grid, a gallery of templates or an app's add-ons, use Catalog on its own: a toolbar with a search, filters, a sort and a grid or list toggle, over cards in a grid, a list or rows. CatalogPage.Item takes the card's variant, mediaPosition and size for a look other than its plain one.

CatalogPage

When to use it

Use it for

  • Add-ons, integrations, templates or perks someone browses and picks from
  • A catalog with categories and a few filters, each item leading to its own page

Not for

  • Records someone works through, such as orders: use AppPage with a DataTable and a FilterBar
  • A handful of links: use SettingsIndex

Examples

Add on catalog

A catalog whose search and checkbox filter narrow its grid, with a count of what's left.

Add-ons

3 add-ons

All add-ons

Bookkeeping

Sales and payouts in your books every night.
Free trial

Categories

Categories that switch the section shown, the current one marked.

Variants and states

Add-ons

The filter column sits beside the catalog from 900px of column, and above it below that.

Add-ons

Tools that work with the roastery.

Featured

Label printing

Print shipping labels at the counter, straight from an order.

First month free

New

Bookkeeping

Sales, refunds and payouts in your books every night.

Free for 30 days

PopularFree trial

Props

CatalogPage

PropTypeDefaultDescription
title

required

stringThe catalog's title, its h1.
breadcrumbsReactNodeThe trail of pages above it, a Breadcrumbs.
descriptionReactNodeOne line under the title saying what's in the catalog.
actionsReactNodeActions at the end of the title's row: PageHeader.Actions.
filtersReactNodeThe filter column at the start: a SearchField, CatalogPage.Categories, CatalogPage.Groups of checkboxes and an action.
filtersLabelstring"Filters"Names the filter column's landmark. Defaults to "Filters".
asideLabelstring"Details"Names the right rail's landmark, such as "Customer details". Defaults to "Details".
fillbooleanfalseGives the page's last block the rest of the height, so a table scrolls inside it with its header sticky while the header and filters stay put; the table's pagination then keeps floating lanes above it. Defaults to false.
footerReactNodeA small footer that ends the page under a hairline, such as a feedback link and the keyboard shortcuts, in body-sm and text-secondary.

It also takes Omit<ComponentPropsWithRef<"main">, "title">.

CatalogPage.Categories

PropTypeDefaultDescription
titlestring"Categories"The list's heading, an h2 in title-sm, which names its navigation. Defaults to "Categories".
categories

required

readonly CatalogCategory[]The categories, in order.
currentstringThe href of the category shown, marked current and drawn in primary.
onNavigate((href: string, event: MouseEvent<HTMLAnchorElement>) => void)Runs as a link is followed, where a router can take over. A click that opens the page elsewhere, in a new tab or window, is left to the browser.

It also takes Omit<ComponentPropsWithRef<"nav">, "title" | "children">.

CatalogPage.Group

PropTypeDefaultDescription
title

required

stringThe group's heading, an h2 in title-sm, which names it.
childrenReactNodeWhat's in it, 8 apart, such as Checkboxes.

It also takes Omit<ComponentPropsWithRef<"section">, "title">.

CatalogPage.Item

PropTypeDefaultDescription
title

required

stringThe item's name, a link in primary to its page.
href

required

stringThe item's page, such as a DetailPage.
descriptionstringWhat it is, in body-sm, wrapping.
notestringA line about its offer, such as "First month free", in italic text-secondary.
mediaReactNodeIts picture or tile at the start, 48px, such as an InitialsTile.
tagsReactNodeIts TagChips, under the rest.
variant"elevated" | "outline" | "soft" | "plain""plain"How it draws its surface, as a Catalog.Card does. Defaults to "plain".
mediaPosition"top" | "start" | "background""start"Where its media sits, as on a Catalog.Card. Defaults to "start".
onNavigate((href: string, event: MouseEvent<HTMLAnchorElement>) => void)Runs as its link is followed, where a router can take over. A click that opens the page elsewhere, in a new tab or window, is left to the browser.
mediaRationumber4 / 3The media's width ÷ height at the top, or the whole card's with the media behind it, such as 1 for a square. Defaults to 4 / 3 at the top and 3 / 4 behind.
eyebrowReactNodeA short line over the title, such as where it's from or what kind it is, in caption.
badgesReactNodeSmall marks at the end of the eyebrow's line, such as a StatusBadge or TagChips.
metaReactNodeOne line under the title, such as what it tastes of or who made it, in body-sm.
priceReactNodeWhat it costs, at the start of its foot, in tabular figures.
actionsReactNodeWhat can be done with it, at the end of its foot, such as an Add button.
size"sm" | "md" | "lg""md""sm": 12 of padding, a 40px start tile and a label title. "md" (the default): 16, 48px and label. "lg": 20, 64px and title-md.

It also takes Omit<MotionElementProps<"article">, "title">.

CatalogPage.Section

PropTypeDefaultDescription
title

required

stringThe block's heading, an h2 in title-md, which names it.
childrenReactNodeIts CatalogPage.Items, two columns from 560px of room.

It also takes Omit<ComponentPropsWithRef<"section">, "title">.

CatalogPage.Featured

PropTypeDefaultDescription
title

required

stringThe block's heading, an h2 in title-md, which names it.
childrenReactNodeIts CatalogPage.Items, two columns from 560px of room.

It also takes Omit<ComponentPropsWithRef<"section">, "title">.

CatalogCategory

One category in `CatalogPage.Categories`.

FieldTypeDefaultDescription
label

required

stringIts name, such as "Shipping".
href

required

stringWhere its link goes.

Accessibility

The page's main landmark, its title the h1. The filter column is a complementary landmark named by filtersLabel; the categories are a navigation named by their h2, the shown one marked aria-current="page". The featured block and each section are regions named by their h2s; each item is an article whose title is a link at least 24px tall.

KeysWhat they do
EnterFollows the focused category or item's title

Motion

It doesn't move.

With reduced motion: Nothing changes.

Layout

It's an AppPage, at most 1280px wide (--bt-w-app-page). Its 220px filter column sits beside the catalog, 32 apart, from 900px of column in a shell at least 1100 wide, and above it otherwise; the items go two to a row from 560px of room, their text wraps, and every category and item title is a link at least 24px tall.

  • FilterBar

    A row of filter pills over a list that wrap as they're applied, with Clear filters and actions, folding into one button on a phone.

  • Detail page

    A page about one thing, with its main column and an aside holding its one primary action.