Skip to main content

Design system components

ProjectList

A compact project index: one row per project, the whole row a link to its case study. Narrow, a thumbnail, the title and one meta line; wide, aligned columns for project, client, discipline and period.

Status: beta. Group: content. Markdown version: /design-system/components/project-list.md

When to use

ProjectList is the fast way through a portfolio: every project in a row, scannable by name and client. Use it as the list view beside a card grid, behind a Cards and List toggle, with the same filter and order.

When not to use

  • Do not use as the only view of a visual portfolio's first impression; pair it with the card grid and a view toggle.
  • Do not use for tabular data the reader sorts or compares; that is a Table.

Look-alikes

  • Table: Do not use for tabular data the reader sorts or compares; that is a Table.

Props

ProjectList props
PropTypeDefaultDescriptionRequired
itemsProjectListItem[]noneProjects in display order; items without href (or marked comingSoon) render as muted teaser rows.Yes
ariaLabelstringnoneAccessible name for the list.Yes
comingSoonLabelstringnoneLabel on teaser rows; defaults to the translated "Coming soon".No
contentLanguagestringnoneLanguage of titles and clients when it differs from the page.No
classNamestringnoneAdditional className for the root element.No

Variants

No variant dimensions and no props with a fixed set of values.

Invalid combinations

The contract records no invalid combinations.

Keyboard

ProjectList keyboard behaviour
KeyBehaviour
TabMoves through the project links in list order; teaser rows without a page hold no control.
EnterFollows the focused row's link.

Rules

Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.

ProjectList rules
LevelRuleHow it is checked
MUSTARIA: The rows are a list named by ariaLabel; each project is a list item.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Each row with a page is a single link whose name is its visible text in reading order, so the name starts with the project title (WCAG 2.5.3).Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: The wide layout's column labels are visual only (aria-hidden); every row's cells carry their own text.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Thumbnails are decorative (empty alt); the title names the project.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Teaser rows are not links and state their coming-soon label in text.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTRequired stories produce no axe violations at the configured severity.Automated by npm run test:stories:matrix:ci. WCAG 2.5.8.
MUSTThe accessibility tree (role, name, state) matches the committed snapshot for every required story.Automated by npm run test:stories:matrix:ci. WCAG 1.3.1, 4.1.2.
MUSTThe component remains legible and operable under a real browser forced-colors: active pass.Automated by npm run test:stories:hc.
MUSTEvery documented keyboard interaction works as specified.Not yet verified: no evidence record. WCAG 2.1.1, 2.1.2.
MUSTA human completed an end-to-end accessibility review of this component.Manual review, last on 2026-10-17.
SHOULDCopy client and period verbatim from the project record; leave a field empty rather than inventing one.Not stated in the contract.
SHOULDKeep the order and filter identical to the card view so switching views keeps the reader's place.Not stated in the contract.
SHOULD NOTDo not put a second link or button inside a row; the row is one link.Not stated in the contract.

Install and import

  • Install: npm install @digitaltableteur/react (version 0.9.1, restricted access on npm).
  • Import: import { ProjectList } from "@digitaltableteur/react";
  • Entry point: @digitaltableteur/react/content exports it too.
  • Styles: import @digitaltableteur/react/style.css once at the app boundary.