Bar ListPro
Displays a ranked list of items with proportional horizontal bars to compare values, metrics, or rankings across categories.
Bar List Playground
Installation
You can add the bar list component to your project manually:
Install the following dependencies:
npm install class-variance-authority clsx tailwind-merge @phosphor-icons/react @react-aria/focusCopy and paste the following code into your project.
Update the import paths to match your project setup.
Update the import aliases (e.g. @/components, @/utils) in the copied files to match your project's path configuration.
Basic Usage
Data-Driven List
The simplest way to render a bar list is by providing a data array. Percentages are automatically computed relative to the highest value in the list if not explicitly provided:
import { BarList } from '@versaui/ui/components/BarList';
const countryData = [
{ id: 'us', label: 'United States', value: 320, country: 'us' },
{ id: 'in', label: 'India', value: 180, country: 'in' },
{ id: 'gb', label: 'United Kingdom', value: 48, country: 'gb' },
{ id: 'au', label: 'Australia', value: 42, country: 'au' },
{ id: 'fr', label: 'France', value: 38, country: 'fr' },
{ id: 'de', label: 'Germany', value: 16, country: 'de' },
];
export function CountryRankings() {
return (
<BarList
data={countryData}
defaultLeadingItem="country"
/>
);
}Bar List Item Component
BarListItem represents an individual row within a bar list. It can be used directly as a standalone row or composed declaratively inside a <BarList> container.
import { BarList, BarListItem } from '@versaui/ui/components/BarList';
<BarList>
<BarListItem
label="United States"
value={320}
percentage={32}
leadingItem="country"
country="us"
/>
<BarListItem
label="Adam Smith"
value={180}
percentage={20}
leadingItem="avatar"
avatar={{ person: 'adam-smith' }}
active
/>
<BarListItem
label="Facebook"
value={48}
percentage={18}
leadingItem="brand"
brand="facebook"
/>
</BarList>Leading Item Variants
BarListItem supports 5 leading accessory options configured via the leadingItem prop:
Country Flags
Pass leadingItem="country" with an ISO 3166-1 alpha-2 country code:
<BarListItem
label="United States"
value={320}
percentage={32}
leadingItem="country"
country="us"
/>Avatars
Pass leadingItem="avatar" with an avatar person key, initials, or custom Avatar props:
<BarListItem
label="Adam Smith"
value={320}
percentage={32}
leadingItem="avatar"
avatar={{ person: 'adam-smith' }}
/>Brand Icons
Pass leadingItem="brand" with a platform identifier:
<BarListItem
label="Facebook"
value={320}
percentage={32}
leadingItem="brand"
brand="facebook"
/>Icons
Pass leadingItem="icon" with any custom icon component (defaults to an outlined circle):
import { Globe } from '@phosphor-icons/react';
<BarListItem
label="Global Traffic"
value={320}
percentage={32}
leadingItem="icon"
icon={<Globe size={20} weight="regular" />}
/>None (Plain Text)
Pass leadingItem="none" for clean, text-only items:
<BarListItem
label="Organic Search"
value={320}
percentage={32}
leadingItem="none"
/>Custom Leading Node
Override accessories completely using the leading slot prop:
<BarListItem
label="Rank #1"
value={500}
percentage={100}
leading={<span className="text-b5 font-semibold">1st</span>}
/>Interactive Selection & Active State
When a row is active or selected, the border transitions to --color-brand-secondary-subtle (#e9d5ff), the progress bar shifts to --color-brand-secondary-subtler (#f3e8ff), and the item receives elevation shadow:
const [selectedId, setSelectedId] = useState('us');
<BarList
data={countryData}
defaultLeadingItem="country"
selectedValue={selectedId}
onValueChange={(id) => setSelectedId(id)}
/>Accessibility
- Container renders semantic
role="list"orrole="listbox"(when selectable). - Each item renders
role="listitem"orrole="option". - Keyboard navigation: Arrow Up / Arrow Down, Home, and End key support between items.
- Focus rings conform to standard design system accessibility guidelines.
- The proportional horizontal fill layer provides accessible
role="meter"witharia-valuenow,aria-valuemin, andaria-valuemax. - All text styles strictly use design system composite classes (
text-b3,text-h7).
BarList Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | BarListItemData[] | undefined | Array of data items to render automatically. |
children | ReactNode | undefined | Declarative child BarListItem components. |
selectedValue | string | number | undefined | Currently active or selected item ID or value. |
onValueChange | (idOrValue, item) => void | undefined | Callback fired when an item is clicked/selected. |
defaultLeadingItem | 'none' | 'icon' | 'avatar' | 'brand' | 'country' | 'none' | Default leading accessory type for child items. |
maxValue | number | undefined | Maximum value used to auto-calculate percentages. |
showValue | boolean | true | Whether to show the numeric value labels. |
showPercentage | boolean | true | Whether to show the percentage labels. |
animated | boolean | true | Whether horizontal bars animate on reveal. |
staggerAnimation | boolean | true | Whether consecutive items animate with staggered delays. |
staggerDelay | number | 40 | Stagger delay in milliseconds per item. |
gap | 'compact' | 'default' | 'relaxed' | number | 'default' | Vertical spacing between bar rows. |
className | string | '' | Additional CSS classes for container. |
BarListItem Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | number | undefined | Unique identifier for the item. |
label | ReactNode | required | Primary label / title of the bar item. |
value | number | string | required | Raw or numeric value of the data point. |
percentage | number | undefined | Fill width percentage (0 to 100). |
formattedValue | string | undefined | Custom formatted string override for value display. |
formattedPercentage | string | undefined | Custom formatted string override for percentage display. |
leadingItem | 'none' | 'icon' | 'avatar' | 'brand' | 'country' | 'none' | Type of leading accessory to render. |
country | CountryCode | ReactNode | undefined | Country code for CountryFlag accessory. |
avatar | AvatarConfig | ReactNode | undefined | Avatar props or custom node for Avatar accessory. |
brand | BrandPlatform | ReactNode | undefined | Brand platform identifier for BrandIcon accessory. |
icon | ReactNode | undefined | Custom icon node when leadingItem is "icon". |
leading | ReactNode | undefined | Custom leading accessory (overrides leadingItem). |
active | boolean | false | Whether the item is currently active or selected. |
valueLabel | boolean | true | Whether to show the numeric value. |
percentageLabel | boolean | true | Whether to show the percentage. |
animated | boolean | true | Whether the bar animates horizontally on reveal. |
animationDelay | number | 0 | Delay before horizontal animation triggers in milliseconds. |
onClick | (event) => void | undefined | Click handler for interactive selection. |
href | string | undefined | Optional link destination URL. |
disabled | boolean | false | Whether the item is disabled. |
className | string | '' | Additional CSS classes for row. |
barClassName | string | '' | Additional CSS classes for progress bar element. |