Skip to main content

CardGrid

Implemented

Responsive grid wrapper that renders an array of items as cards via a caller-supplied render function. Supports 1–4 columns and three gap scales, with an empty-state message when the list is empty.

Categorymolecules
Sourcepatterns/molecules/cardgrid.html
AI HintGeneric responsive card grid when YOU supply the card markup via renderItem. For stat tiles use StatGrid (organism); for event cards use EventGrid; for form field columns use FormRow/ResponsiveFieldGroup. No ariaLabel prop — the list relies on context for its accessible name.

Responsive render-prop grid for homogeneous card lists — 1–4 columns, three gap scales, empty-state message.

CardGrid

design-system

Default 3-column grid with medium gap.

Revenue

$12,450

Orders

342

Refunds

$210

AOV

$36.40

Tickets

89

Visitors

1,204

Props

Preview

CardGrid

Prop
Type
Required
Default
Description
items
T[]
Required
—

Data array — generic over the item type T.

renderItem
(item: T, index: number) => React.ReactNode
Required
—

Renders each item — cards are caller-supplied (CardGrid composes no Card atom).

keyExtractor
(item: T, index: number) => string
Required
—

Stable React key per item.

columns
1 | 2 | 3 | 4
Optional
3

Column count (responsive down-stack handled by the caller's cards).

gap
'sm' | 'md' | 'lg'
Optional
'md'

Gap scale between cells.

emptyMessage
string
Optional
—

Message rendered when items is empty — omit it and the grid renders nothing (silent empty).

className
string
Optional
—

Additional CSS classes on the grid root.

Quick use:<CardGrid />

Accessibility

ARIA rolelist

ARIA

1 rule

WCAG 1.3.1

root is role='list' and each cell a role='listitem' — pass semantic children from renderItem

Type

1 rule

NASA Rule 5

empty list without emptyMessage renders nothing (no fallback message is invented)

Usage

Import

tsxSnippet
import { CardGrid } from "@epasslive/design-system"

Example 1

tsxSnippet
<CardGrid items={tickets} renderItem={(t) => <TicketCard ticket={t} />} keyExtractor={(t) => t.id} columns={3} />

Example 2

tsxSnippet
<CardGrid items={[]} columns={2} emptyMessage="No tickets yet." />

Anti-patterns

— Do not expect Card surfaces from the grid itself — it wraps caller-supplied cards

— Do not assume an empty-state renders — without emptyMessage an empty list is silent

Design System v4.1.0 | ePassLive