Skip to content
txbrendan/ui

Form Guide

beta

A team's last results as W, D, and L on tinted squares, oldest first, with a peek that lists the scores, latest first.

Preview

results

WWLDW

with peek

Rest on it, tab to it, or tap it for the scores.

size

table

TeamPPtsForm
Rovers517
Lions514WWLWL
Bears59LDWLD

none yet

—

Install

  1. 1. Add the registry to components.json, once per app. Without it, the shadcn CLI looks up @txbrendan in a public list that txbrendan/ui does not control.

    npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"
  2. 2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.

    npx shadcn@latest add @txbrendan/theme
  3. 3. Add the component.

    npx shadcn@latest add @txbrendan/form-guide

Use it for

  • A team's recent results in a table row, a fixture card, or a team header.
  • Pass results oldest first. The latest sits on the right.
  • Add score, opponent, away, and date to each result, and the guide opens a peek that lists them, latest first.
  • In a table or list, mark each row with data-peek-row. The peek then opens beside the row, so the rows above and below stay in reach.
  • Use size='sm' in dense tables.

Avoid it for

  • A full results list. Use a table, with the date, the opponent, and the score in columns.
  • Anything that is not a win, a draw, or a loss. Use Badge.

Props

  • results

    Required. The last results, oldest first. A win is green, a loss red, a draw ink, and the letter always says it. An empty list shows a dash.

    { result: "W" | "D" | "L"; score?: string; opponent?: string; away?: boolean; date?: string }[]

  • size

    Squares of 18, 22, or 28px at the default density.

    "sm" | "md" | "lg" · default "md"

  • aria-label

    What screen readers hear before the results.

    string · default "Form"

  • className

    Extra classes for the row of squares. Later classes win.

    string

Accessibility

  • Screen readers hear 'Form, oldest to latest: won, won, lost'. The letters say the result, so color is never the only signal.
  • With no details it is role="img" with that name, and no tab stop.
  • With details it is a HoverCard trigger: a focusable role="button" with that name and aria-haspopup="dialog".
  • Focus opens the peek at once, a short rest of the pointer opens it, and so does a tap. Enter or Space moves focus into it, and Esc closes it and puts focus back.
  • ↑ and ↓ step to the peek above or below, as on every peek, and only one peek shows at a time.
  • The peek is a dialog named 'Last 5, latest first', which it also shows as its title. It lists each result as a line of text.
  • The squares use the tones' soft colors, which the theme holds to 4.5:1 with their letters.

Examples

Results only

<FormGuide results={[{ result: "W" }, { result: "W" }, { result: "L" }, { result: "D" }, { result: "W" }]} />

With a peek

<FormGuide
  results={[
    { result: "L", score: "12–19", opponent: "Bears", away: true, date: "Sat 12 Sep" },
    { result: "W", score: "31–10", opponent: "Hawks", date: "Sat 19 Sep" },
    { result: "W", score: "24–17", opponent: "Lions", date: "Sat 26 Sep" },
  ]}
/>