# Leaderboard

> Ranked people for one number, on DataTable: the place, the person, and the value. Ties share a place, and your row follows a Your place line.

- Name: `leaderboard`
- Status: beta
- Categories: sport, display
- File: the install writes `leaderboard.tsx` to your `ui` alias, `@/components/ui` by default.
- Other registry items: `@arbokui/data-table`, `@arbokui/person`. The install adds them.
- Gallery: https://arbokui.com/components/leaderboard
- Registry item: https://arbokui.com/r/leaderboard.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/leaderboard
   ```

## Use it for

- One number per person: tickets closed, sales, minutes, a test score. Put it in a Card with className="px-0", and name it with the card's title through aria-labelledby.
- Equal values share a place, like "=3", and the next place skips them. People with no value are left out.
- you marks your row with a blue bar and its own wash. Outside the top limit, your row follows a Your place line.
- better="lower" ranks times and the like. format draws the value, like seconds as 12:34.

## Avoid it for

- Many numbers per person, or a sort the reader picks. Use DataTable.
- Teams in a league. Use Standings.

## Props

- `items`: `{ id: string; person: string; photo?: string; meta?: string; value: number | null }[]`. Required. The people, in any order. meta shows under the name, like a team or a position.
- `unit`: `string`. Default `"score"`. Names the value column, like "tickets". Its first letter is made a capital.
- `better`: `"higher" | "lower"`. Default `"higher"`. Which way ranks first.
- `you`: `string`. Your item's id.
- `limit`: `number`. Default `5`. How many rows show before your own place.
- `format`: `(value: number) => string`. Draws a value. Ties still compare the numbers.
- `label`: `string`. Default `"Player"`. The people column's header.
- `caption`: `ReactNode`. Names the table, under it.
- `aria-label`: `string`. Names the table when it has no caption.
- `aria-labelledby`: `string`. Names the table by another element, like the Card's title.
- `loading`: `boolean`. Default `false`. Holds the space with placeholder rows.
- `empty`: `ReactNode`. Default `"No scores yet"`. What shows when no one has a value.
- `className`: `string`. Extra classes on the wrapper. Later classes win.

## Accessibility

- A real \<table>. Each person's name is the row header, so the place and the value are read with it.
- Your row starts with "You," for screen readers. Its bar is a border, so it stays in forced colors.
- The Your place line is a row of its own, with words, so it is read in order.

## Examples

### Your row after the top 5, with a tie

```tsx
<Leaderboard
  aria-label="Tickets closed"
  unit="tickets"
  label="Name"
  you="p6"
  items={[
    { id: "p1", person: "Mia Okafor", meta: "Support", value: 9 },
    { id: "p2", person: "Cal Nash", meta: "Sales", value: 7 },
    { id: "p3", person: "Tom Hale", meta: "Support", value: 7 },
    { id: "p4", person: "Ana Ruiz", meta: "Design", value: 4 },
    { id: "p5", person: "Sam Carter", meta: "Engineering", value: 3 },
    { id: "p6", person: "Josh Tait", meta: "Support", value: 2 },
  ]}
/>
```
