Skip to content
txbrendan/ui

Standings

beta

A league table or a tournament pool, on DataTable: the place, the team and its kit, the counts, points difference, points, and form, with zones.

Preview

league, zones, you, form

League
PlaceTeamPlayedWonDrawnLostPoints differenceBonus pointsPointsForm
Lions10802+96638WWLWW
You, Rovers10712+64535WDWWW
3Wolves10514+12426LWWLD
4Hawks104060319WLLWL
5Tigers United10307−51416LLWLL
Falcons10109−12126LLLLW

pool, form false, one zone

Pool A
PlaceTeamPlayedWonDrawnLostPoints forPoints againstPoints differencePoints
You, Rovers33007431+439
Lions32015840+186
3Hawks31023655−193
4Falcons30032264−420

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/standings

Use it for

  • A league table or a tournament pool. Put it in a Card with className="px-0", and name it with the card's title through aria-labelledby.
  • The app works out the numbers and the order. The table only shows them.
  • layout league shows P W D L PD BP Pts. pool shows P W D L PF PA PD Pts.
  • zones mark places that mean something: promotion from the top in success, relegation from the bottom in danger. Give each a note, so its peek says what it means.
  • you marks your team: a blue bar, its own wash, and its name in the strong weight.
  • In a narrow card the counts give way, PF and PA first, then form, then D and BP, and under 20rem W and L, so the team keeps its room.

Avoid it for

  • A row inserted between zones. A zone's edge is its 2px rule.
  • Real club colors in a demo. Pass theme tokens, like var(--chart-1).
  • Ranking people. Use Leaderboard.

Props

  • rows

    Required, in table order. Each: { id, team: { name, colors?: KitColors, pattern? }, position?, played, won, drawn, lost, pointsFor?, pointsAgainst?, diff?, bonus?, points, form?: FormResult[] }.

    StandingsRow[]

  • layout

    Which counts show.

    "league" | "pool" · default "league"

  • you

    Your team's id.

    string

  • zones

    Places counted from the top or the bottom. tone defaults to success from the top and danger from the bottom.

    { label: string; top?: number; bottom?: number; tone?: "success" | "danger" | "warning" | "brand"; note?: string }[]

  • form

    The form column, when any row has form.

    boolean · default true

  • caption

    Names the table, under it.

    ReactNode

  • aria-label

    Names the table when it has no caption.

    string

  • aria-labelledby

    Names the table by another element, like the Card's title.

    string

  • loading

    Holds the space with placeholder rows.

    boolean · default false

  • className

    Extra classes on the wrapper. Later classes win.

    string

Accessibility

  • A real <table>. Each team's name is the row header, so every count is read with it.
  • Short headers, like P, are read as their full words, like Played, and show them on a mouse rest.
  • A zone's place number is read with its label, like "1, Promotion". Its peek says what the zone means.
  • Points difference uses a true minus sign, which screen readers read as minus.
  • A zone's edges and your team's bar are borders, so they stay in forced colors.

Examples

League with promotion and relegation zones

<Standings
  aria-label="League"
  you="rov"
  zones={[
    { label: "Promotion", top: 1, note: "The top team goes up." },
    { label: "Relegation", bottom: 1, note: "The bottom team goes down." },
  ]}
  rows={[
    { id: "lio", team: { name: "Lions", colors: ["var(--chart-1)", "var(--background)"] }, played: 10, won: 8, drawn: 0, lost: 2, diff: 96, bonus: 6, points: 38 },
    { id: "rov", team: { name: "Rovers", colors: ["var(--foreground)", "var(--chart-3)"], pattern: "hoops" }, played: 10, won: 6, drawn: 1, lost: 3, diff: 41, bonus: 5, points: 31 },
    { id: "fal", team: { name: "Falcons" }, played: 10, won: 1, drawn: 1, lost: 8, diff: -120, bonus: 2, points: 8 },
  ]}
/>