- Accordion
- Action Bar
- Action Toast
- Alert Banner
- Alert Dialog
- Alert
- Alphabet Index
- Amount Field
- Aspect Ratio
- Attachment
- Availability List
- Avatar
- Badge
- Bank Card
- Breadcrumb
- Bubble
- Button Group
- Button
- Calendar
- Camera Frame
- Card Design Picker
- Card Details
- Card Peek
- Card Stack
- Card
- Carousel
- Chart
- Chat Thread
- Checkbox
- Chip Group
- Choice Tile
- Code Block
- Code Dots
- Collapsible
- Combobox
- Command
- Context Menu
- Copy Field
- Countdown
- Country Select
- Data Table
- Date Field
- Date Picker
- Date Range Picker
- Dialog
- Direction
- Document Paper
- Drawer
- Dropdown Menu
- Empty
- Entity Avatar
- Field
- File Trigger
- File Upload Item
- Hover Card
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Key Value
- Keypad
- Label
- Live Region
- Marker
- Message Scroller
- Message
- Money Amount
- Native Select
- Number Field
- Pagination
- Percent Split Editor
- Phone Field
- Popover
- Progress
- QR Code
- Questionnaire
- Radio Group
- Range Histogram
- Rating
- Resizable
- Scroll Area
- Search Field
- Select
- Separator
- Share Bar
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Sortable List
- Spinner
- Status Timeline
- Step Header
- Steps List
- Swipe Row
- Switch
- Table
- Tabs
- Text Field
- Textarea
- Tier Ladder
- Toggle Group
- Toggle
- Token Search Field
- Tooltip
- Trace
- Transaction Row
- Usage Meter
Basic, Completed
Phone number · $250 a monthVerified, Current level
ID card and selfieCurrent- Spend a month
- $10,000$10,000
- Send a day
- $2,500$2,500
- Withdraw a day
- $1,000$1,000
Extended, Not reached
Proof of income and addressNextSteps done1 of 3
"use client"
import { Button } from "@/components/ui/button"The TierLadder component lays out levels in order, lowest first: verification tiers, referral levels or plans. Each level shows a number or a check, a name, one line of detail and an optional tag, and can hold its limits, perks, progress and an action. Use it when the order of the levels matters and the user needs to see where they are. For one limit on its own, use UsageMeter; for a pick between plans, use a choice tile group.
Installation#
pnpm dlx shadcn@latest add @dots/tier-ladder
Usage#
import {
TierLadder,
TierLadderItem,
TierLadderLimit,
TierLadderLimits,
} from "@/components/ui/tier-ladder"<TierLadder aria-label="Verification levels">
<TierLadderItem status="done" name="Basic" description="Phone number" />
<TierLadderItem
status="current"
name="Verified"
description="ID card and selfie"
badge="Current"
>
<TierLadderLimits>
<TierLadderLimit label="Spend a month" value="$10,000" />
<TierLadderLimit label="Send a day" value="$2,500" />
</TierLadderLimits>
</TierLadderItem>
<TierLadderItem name="Extended" description="Proof of income" />
</TierLadder>Composition#
Use the following composition to build a tier ladder:
TierLadder
└── TierLadderItem
├── TierLadderProgress
├── TierLadderLimits
│ └── TierLadderLimit
├── TierLadderPerks
│ └── TierLadderPerk
└── any action, such as a ButtonFeatures#
- Three statuses:
doneshows a check,currentmarks the user's level,upcomingshows the level number - A tag at the end of each header, filled on the current level
- Limits as a grid of label and value tiles, perks as a short list
TierLadderProgressfor steps or referrals toward a level, without the warning color of a spending limit- A level with no children stays a single collapsed row
- Customizable styling through the
classNameprop on every part
Perks and progress#
Use TierLadderPerks for what a level adds, and TierLadderProgress for how far the user is from it.
Friend, Completed
1 inviteAmbassador, Current level
5 invitesCurrent- $10 for each friend who joins
- Free transfers abroad
Partner, Not reached
20 invitesInvites8 of 2012 more to reach Partner- $20 for each friend who joins
- Priority support
"use client"
import {In review#
When the next level is waiting on a check, keep it upcoming, tag it with badge, and set statusLabel so screen readers hear the same thing.
Verified, Current level
ID card and selfieCurrentExtended, In review
Proof of income and addressIn reviewDocuments received. Usually takes up to 1 day.
Business, Not reached
Company documents
"use client"
import {Level numbers#
The marker shows the position in the list by default. Pass level when the list starts mid-ladder, for example plans from the user's current one up.
- 2
Plus, Current level
$4.99 a monthCurrent - 3
Premium, Not reached
$9.99 a month - 4
Metal, Not reached
$19.99 a month
"use client"
import {Accessibility#
TierLadder renders an ordered list and each TierLadderItem a list item, so the order and count of levels are announced.
Name the ladder#
The list has no visible title of its own. Give TierLadder an aria-label, or point aria-labelledby at a nearby heading.
<TierLadder aria-label="Verification levels">{/* ... */}</TierLadder>Status#
The marker is hidden from assistive tech. The level name is a heading that ends with its status for screen readers only: "Completed", "Current level" or "Not reached". The current level also gets aria-current="step". When badge says something else, such as "In review", pass the same text as statusLabel.
Headings#
Each level name is an h3 by default. Set headingLevel so it fits the page outline.
Progress#
TierLadderProgress is a meter. Screen readers hear its value from value and max, such as "8 of 20", never from valueText. Pass a valueLabel to add what the numbers lack, such as "8 of 20 invites" or "1 of 3 steps done".
API Reference#
TierLadder#
The ordered list of levels. Accepts all props of <ol>.
| Prop | Type | Default | Description |
|---|---|---|---|
aria-label | string | - | Names the ladder for screen readers. |
className | string | - | Additional classes to apply to the list. |
TierLadderItem#
One level. Accepts all props of <li> except title.
| Prop | Type | Default | Description |
|---|---|---|---|
name | ReactNode | - | Name of the level. Required. |
description | ReactNode | - | One line under the name. |
status | "done" | "current" | "upcoming" | "upcoming" | Reached, the user's level, or ahead. |
level | ReactNode | position in the list | What the marker shows for a level not yet reached. |
badge | ReactNode | - | Short tag at the end of the header. |
statusLabel | string | from status | Overrides the status read by screen readers. |
headingLevel | 2 | 3 | 4 | 5 | 6 | 3 | Heading level of the name. |
children | ReactNode | - | Limits, perks, progress or an action. Leave empty for a single row. |
TierLadderLimits#
A grid of key figures for a level. Accepts all props of <dl>.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the grid. |
TierLadderLimit#
One figure. Accepts all props of <div> except children.
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | - | What the figure is, such as "Spend a month". Required. |
value | ReactNode | - | The figure. Pass a MoneyAmount for money. Required. |
TierLadderPerks#
A list of what a level adds. Accepts all props of <ul>.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the list. |
TierLadderPerk#
One perk. Accepts all props of <li>.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional classes to apply to the item. |
TierLadderProgress#
Progress toward a level. Renders a UsageMeter and accepts all of its props, with different defaults.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "default" | "sm" | "sm" | The meter size. |
warnAt | number | false | false | The meter does not turn to warning by default. |
...props | UsageMeterProps | - | Props spread to the underlying UsageMeter. |