GitHub
Core
Glass
Brutal
Humanist

Bar List
Pro

Displays a ranked list of items with proportional horizontal bars to compare values, metrics, or rankings across categories.

Bar List Playground

Bar List Playground
Preview
Code
US flag
United States
320(32%)
IN flag
India
180(20%)
GB flag
United Kingdom
48(18%)
AU flag
Australia
42(11%)
FR flag
France
38(10%)
DE flag
Germany
16(9%)
Controls
Leading Item:
Country
Avatar
Brand
Icon
None
Values:
Percentages:

Installation

You can add the bar list component to your project manually:

1

Install the following dependencies:

npm install class-variance-authority clsx tailwind-merge @phosphor-icons/react @react-aria/focus
2

Copy and paste the following code into your project.

Loading...
3

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" or role="listbox" (when selectable).
  • Each item renders role="listitem" or role="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" with aria-valuenow, aria-valuemin, and aria-valuemax.
  • All text styles strictly use design system composite classes (text-b3, text-h7).

BarList Props

PropTypeDefaultDescription
dataBarListItemData[]undefinedArray of data items to render automatically.
childrenReactNodeundefinedDeclarative child BarListItem components.
selectedValuestring | numberundefinedCurrently active or selected item ID or value.
onValueChange(idOrValue, item) => voidundefinedCallback fired when an item is clicked/selected.
defaultLeadingItem'none' | 'icon' | 'avatar' | 'brand' | 'country''none'Default leading accessory type for child items.
maxValuenumberundefinedMaximum value used to auto-calculate percentages.
showValuebooleantrueWhether to show the numeric value labels.
showPercentagebooleantrueWhether to show the percentage labels.
animatedbooleantrueWhether horizontal bars animate on reveal.
staggerAnimationbooleantrueWhether consecutive items animate with staggered delays.
staggerDelaynumber40Stagger delay in milliseconds per item.
gap'compact' | 'default' | 'relaxed' | number'default'Vertical spacing between bar rows.
classNamestring''Additional CSS classes for container.

BarListItem Props

PropTypeDefaultDescription
idstring | numberundefinedUnique identifier for the item.
labelReactNoderequiredPrimary label / title of the bar item.
valuenumber | stringrequiredRaw or numeric value of the data point.
percentagenumberundefinedFill width percentage (0 to 100).
formattedValuestringundefinedCustom formatted string override for value display.
formattedPercentagestringundefinedCustom formatted string override for percentage display.
leadingItem'none' | 'icon' | 'avatar' | 'brand' | 'country''none'Type of leading accessory to render.
countryCountryCode | ReactNodeundefinedCountry code for CountryFlag accessory.
avatarAvatarConfig | ReactNodeundefinedAvatar props or custom node for Avatar accessory.
brandBrandPlatform | ReactNodeundefinedBrand platform identifier for BrandIcon accessory.
iconReactNodeundefinedCustom icon node when leadingItem is "icon".
leadingReactNodeundefinedCustom leading accessory (overrides leadingItem).
activebooleanfalseWhether the item is currently active or selected.
valueLabelbooleantrueWhether to show the numeric value.
percentageLabelbooleantrueWhether to show the percentage.
animatedbooleantrueWhether the bar animates horizontally on reveal.
animationDelaynumber0Delay before horizontal animation triggers in milliseconds.
onClick(event) => voidundefinedClick handler for interactive selection.
hrefstringundefinedOptional link destination URL.
disabledbooleanfalseWhether the item is disabled.
classNamestring''Additional CSS classes for row.
barClassNamestring''Additional CSS classes for progress bar element.

On this page