Alpha: Ships on npm at 7.0.0-alpha.07.0.0-alpha.0

product-list

A directory list: one linked row per listing, as a list or as Tiles.

View as JSON
Variant
From Benchlist › homedirectoryOpen the frame

When to use

Use a product list for a directory index or a category page. It holds up to 50 rows, each a link with a mark, a name of 32 characters, a summary of 120, a tag and a note, under an optional title, sort links, view links and a pager.

list sets one row per listing; cards sets each as a Tile in a grid. Every control is a link, so sorting and paging need no script. For posts, use post-list.

Write each summary as what the listing does, so a reader chooses from the list without opening every row.

Use instead

The record

pages/benchlist/home.json, section 3
{
  "kind": "section",
  "shell": { "inset": "contained", "density": "section" },
  "block": {
    "type": "product-list",
    "title": "Benches in Duluth, by kind",
    "note": "8 kinds",
    "view": "cards",
    "views": [
      { "href": "/", "label": "Kinds", "icon": "layout-grid", "on": true },
      { "href": "/city/duluth", "label": "List", "icon": "list" }
    ],
    "rows": [
      {
        "href": "/city/duluth?kind=kiln",
        "mark": "sparkles",
        "name": "Kiln rooms",
        "summary": "Electric kilns to cone 10, with shelves and posts. Bisque or glaze.",
        "tag": "Clay",
        "note": "2 listed, from $18 an hour"
      },
      {
        "href": "/city/duluth?kind=wood",
        "mark": "blocks",
        "name": "Woodshop benches",
        "summary": "Hardwood benches beside a cabinet saw, jointer and planer.",
        "tag": "Wood",
        "note": "2 listed, from $16 an hour"
      },
      {
        "href": "/city/duluth?kind=metal",
        "mark": "gauge",
        "name": "Metal bays",
        "summary": "A metal lathe with tooling, or a ventilated welding booth.",
        "tag": "Metal",
        "note": "2 listed, from $24 an hour"
      },
      {
        "href": "/city/duluth?kind=print",
        "mark": "files",
        "name": "Print presses",
        "summary": "A tabletop letterpress with type, or a four-color screen press.",
        "tag": "Print",
        "note": "2 listed, from $14 an hour"
      },
      {
        "href": "/city/duluth?kind=textile",
        "mark": "layers",
        "name": "Looms",
        "summary": "A four-shaft floor loom, warped on request a day ahead.",
        "tag": "Textile",
        "note": "1 listed, $12 an hour"
      },
      {
        "href": "/city/duluth?kind=jewelry",
        "mark": "badge-check",
        "name": "Jewelry benches",
        "summary": "A bench pin, flex shaft and torch, in a room with a safe.",
        "tag": "Jewelry",
        "note": "1 listed, $9 an hour"
      },
      {
        "href": "/list-a-bench",
        "mark": "sparkles",
        "name": "Glass studios",
        "summary": "No glass kiln or torch bench is listed yet. A host who lists one sets its rate.",
        "tag": "Glass",
        "note": "0 listed"
      },
      {
        "href": "/list-a-bench",
        "mark": "film",
        "name": "Darkrooms",
        "summary": "No darkroom is listed yet. Enlargers, trays and a sink by the hour.",
        "tag": "Photo",
        "note": "0 listed"
      }
    ]
  }
}

Smallest that parses

{
  "type": "product-list",
  "title": "Benches in Duluth, by kind",
  "rows": []
}

Fields and bounds

From @mdxui/site@7.0.0-alpha.0. A count reads as min–max × item; a string bound is its maximum length in characters, and links its refusal.

PropType and boundRequired
titlestring ≤48no
notestring ≤24no
railobjectno
rail.groups1–4 × objectyes
rail.groups[].labelstring ≤20yes
rail.groups[].links1–12 × objectyes
sort0–4 × objectno
sort[].hrefstring ≤160yes
sort[].labelstring ≤16yes
sort[].onbooleanno
view"list" | "cards"no
views0–2 × objectno
views[].hrefstring ≤160yes
views[].labelstring ≤16yes
views[].iconicon or mark name (52)no
views[].onbooleanno
rows0–50 × objectyes
rows[].hrefstring ≤160yes
rows[].markicon or mark name (52)no
rows[].namestring ≤32yes
rows[].summarystring ≤120yes
rows[].tagstring ≤24no
rows[].notestring ≤32no
pagerobjectno
pager.prevstring ≤160no
pager.nextstring ≤160no
pager.pageinteger 1–10000yes
pager.pagesinteger 1–10000yes
emptystring ≤80no

Variants and counts

Two views, list and cards. A record names the view it renders and links to the other.

product-listopen
listopen
cardsopen

One record in five Themes

directoryBenchlist’s ownopen
certificateopen
vaultlineopen
quaypointopen
callboardopen

Shells

paperopen
tintopen
plateopen
glassopen

In three Businesses

Carried by the article and directory-list Templates. Seen on pages/benchlist/home.json, section 3.

Benchlist › home · directoryA directory lists the benches of one city, sorted, with pages.
Harbor tides › integrations · quaypointAn API product lists its integrations, with one row inviting a new one.
Ledgerhouse › services · vaultlineA bookkeeping firm lists the bank feeds it reads.

Do and do not

Doopen
A summary that says what the listing does.
Don’topen
A summary that repeats the name tells the reader nothing to choose on.
Doopen
A name of one or two words.
Don’trefused
"name": "Chartplot for every chart plotter"
SectionSchema.safeParse(record)block.rows.0.name33 charactersToo big: expected string to have <=32 characters
A name written as a pitch runs past 32 characters and is refused.

Accessibility

Check, on the exemplar renderLimitNowPass
Skipped heading levels00yes
Unnamed nav landmarks00 of 1yes
Scroll regions a keyboard cannot reach00 of 0yes
Copy controls that announce the resultall0 of 0yes
Images and icons with no text alternative00yes

Text pairs below AA across the 5 Themes and every scheme they emit: 5. See Render checks.

  • Landmark The list sits in main. Sort, view and pager are each a nav with its own name.
  • Heading level The title renders as an h2; the listings are a list, ul.
  • Focus order Tab runs sort, view, each listing link, then the pager. The current sort and view carry aria-current.