Ranking

A leaderboard card for the tops of a dashboard: products, customers or countries. Read it as stacked rows or a vertical bar chart, each row carrying a position chip, a value and a relative-share bar.

Top products
By units sold this month
  1. 1
    Trail Runner GTX
    1,284
  2. 2
    Merino Base Tee
    968
  3. 3
    Field Watch 38mm
    742
  4. 4
    Studio Headphones
    511
  5. 5
    Weekender Bag
    388

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add ranking

Usage#

Ranking is composed from named parts, like Card and Stat. The Ranking root owns the surface and variant; RankingList is a semantic <ol> so assistive tech announces the positions, and each RankingItem lays out a rank, content, and value.

top-categories.tsxTSX
import {  Ranking,  RankingHeader,  RankingTitle,  RankingList,  RankingItem,  RankingRank,  RankingContent,  RankingLabel,  RankingValue,} from "@/components/ui/ranking"export function TopCategories({ rows }: { rows: { name: string; revenue: string }[] }) {  return (    <Ranking>      <RankingHeader>        <RankingTitle>Top categories</RankingTitle>      </RankingHeader>      <RankingList>        {rows.map((r, i) => (          <RankingItem key={r.name}>            <RankingRank highlight={i === 0}>{i + 1}</RankingRank>            <RankingContent>              <RankingLabel>{r.name}</RankingLabel>            </RankingContent>            <RankingValue>{r.revenue}</RankingValue>          </RankingItem>        ))}      </RankingList>    </Ranking>  )}
Top categories
  1. 1
    Footwear
    $24,180
  2. 2
    Apparel
    $18,640
  3. 3
    Accessories
    $12,920
  4. 4
    Audio
    $9,310

Media and meta#

Give a row a face. RankingMedia is a tinted icon tile for things (products, countries); for people, drop an Avatar in the same slot. RankingMeta adds a muted second line under the label (a category, an order count) and RankingValue holds the figure in tabular-nums so the column stays aligned.

Top customers
By lifetime spend
  1. 1J
    Jordi Espinosa
    42 orders
    $8,420
  2. 2M
    Mara Devlin
    38 orders
    $7,180
  3. 3L
    Liang Wei
    31 orders
    $5,960
  4. 4P
    Priya Nair
    27 orders
    $5,210

Relative bars#

RankingBar draws each row’s share of the leader from a value of 0–100, so the list reads as a chart at a glance. The fill width is a runtime value, so it rides a CSS variable (never a generated class) and animates when the data changes.

Top products
+12% MoM
  1. 1
    Trail Runner GTX
    1,284
  2. 2
    Merino Base Tee
    968
  3. 3
    Field Watch 38mm
    742
  4. 4
    Studio Headphones
    511
  5. 5
    Weekender Bag
    388

Vertical bars#

Set layout="bars" to read the same list as a vertical bar chart: RankingList turns into a row of full-height columns and each RankingBar grows from the bottom to its share. The columns are narrow, so lean on the Tooltip and wrap each RankingItem and surface the full detail on hover instead of squeezing it under the bar.

Top products
+12% MoM
  1. 1,284
    Runner
  2. 968
    Tee
  3. 742
    Watch
  4. 511
    Audio
  5. 388
    Bag

Inline bars#

Set layout="inline" for a horizontal bar chart: the name holds a fixed column and a thick bar runs beside it. The bars rest neutral and the brand is the hover: the bar under the pointer lights up, and so does a bar that takes keyboard focus as a tooltip trigger. Nothing is lit at rest. highlight on a RankingBar pins the brand on one bar, for a row that really is selected; it works in the other layouts too.

Best seller products
  1. Burgers
  2. Water
  3. Tobacco
  4. Beer
  5. Coconut

Bar tones#

tone sets a bar’s fill: blue, brand, neutral, success, warning, destructive or info, the same names and inks as the Chart’s series, so a Ranking beside a chart can carry its key. Put the leader in the brand and the rest in neutral when the list is about one row, or let a status tone report each row’s health. Set tone on the Ranking to paint every bar at once; a bar’s own tone wins over it, and highlight wins over both. In the inline layout the hovered bar still lights up in the brand.

Top products
  1. 1
    Trail Runner GTX
    1,284
  2. 2
    Merino Base Tee
    968
  3. 3
    Field Watch 38mm
    742
  4. 4
    Studio Headphones
    511
  5. 5
    Weekender Bag
    388
Warehouse capacity
  1. Valencia
    94%
  2. Lyon
    81%
  3. Rotterdam
    66%
  4. Porto
    38%

Headline figure#

When the list breaks down a total, lead with the total. Ranking has no figure part of its own on purpose: the figure is the Stat’s StatValue, which renders outside a Stat, with a StatTrend beside it. Set them between the header and the list, so every card in a dashboard leads with the same figure and the same chip, and the description is free to say what the number counts.

Country visitors
Visits this week, by country
12,480
+8.2%
  1. Spain
    4,120
  2. United States
    3,380
  3. Germany
    2,210
  4. France
    1,640
  5. Portugal
    1,130

Interactive rows#

Pass interactive to a RankingItem for a clickable row: pointer, a hover wash that bleeds to the card edge, and a focus ring. The wash sits close to the rank chip, media tile, and bar track, so those nested surfaces step down to the card surface on hover to keep their definition instead of dissolving into the wash, while the highlighted leader chip holds its primary fill. Wire it with onClick and add a trailing chevron to signal the affordance.

Top products
Tap a row to open the product
  1. 1
    Trail Runner GTX
    1,284 units
  2. 2
    Merino Base Tee
    968 units
  3. 3
    Field Watch 38mm
    742 units
  4. 4
    Studio Headphones
    511 units

Variants#

default sits on a hairline border with a soft shadow; outline drops the shadow for flat, gridded dashboards; elevated trades the border for a lifted shadow.

Default
  1. 1
    Trail Runner GTX
    1,284
  2. 2
    Merino Base Tee
    968
  3. 3
    Field Watch 38mm
    742
Outline
  1. 1
    Trail Runner GTX
    1,284
  2. 2
    Merino Base Tee
    968
  3. 3
    Field Watch 38mm
    742
Elevated
  1. 1
    Trail Runner GTX
    1,284
  2. 2
    Merino Base Tee
    968
  3. 3
    Field Watch 38mm
    742

API reference#

Ranking forwards all div props and adds variant (default | outline | elevated), layout (list | bars | inline), tone (every bar’s default hue) and asChild. RankingList renders an <ol>; RankingItem renders an <li> and adds interactive. RankingRank adds highlight for the leader; RankingBar takes a value (0–100), tone (blue | brand | neutral | success | warning | destructive | info) and highlight (a brand fill that wins over the tone). The rest: RankingHeader, RankingTitle, RankingDescription, RankingAction, RankingMedia, RankingContent, RankingLabel, RankingMeta, RankingValue, forward their element props. Every part accepts className, merged last.

FAQ#

RankingList renders a semantic ordered list so assistive tech announces the positions. Each RankingItem (an `<li>`) lays out a RankingRank, optional RankingMedia or an Avatar, a RankingContent (RankingLabel plus RankingMeta), and a RankingValue.