Componentmedia0.77 KB gzipZero dependencies
Xp Bar
Experience track with level badge and animated fill.
Preview
Live Preview
12
XP780/1000
Installation
Tokens guide →Add to your project via CLI (zero dependencies, code you own):
npx bigbullui add xp-barOr install the full npm package:
npm install bigbulluiUsage
Open in StackBlitzimport { XpBar } from "@/components/ui/xp-bar";
<XpBar value={780} max={1000} level={12} />Usage guidance
Use Xp Bar when a ticket stub surface needs Experience track with level badge and animated fill. Keep props minimal and prefer composition with sibling stubs.
Avoid Xp Bar for long form flows or dense data grids where a dedicated layout block fits better.
Source code
xp-bar.tsxZero dependencies (only React + utils). Copy and paste directly into your project:
"use client";
import * as React from "react";
import { cn } from "./lib/utils";
export interface XpBarProps extends React.HTMLAttributes<HTMLDivElement> {
value: number;
max?: number;
level?: number;
}
/** XP bar: slim experience track with level badge and animated fill. */
export function XpBar({ value, max = 100, level = 1, className, ...props }: XpBarProps) {
const pct = Math.max(0, Math.min(100, (value / Math.max(1, max)) * 100));
return (
<div className={cn("flex min-h-11 w-full min-w-44 select-none items-center gap-2", className)} {...props}>
<span className="flex size-11 shrink-0 items-center justify-center rounded-md border-2 border-accent bg-accent/10 font-mono text-xs font-black text-accent" aria-label={`Level ${level}`}>
{level}
</span>
<div className="min-w-0 flex-1">
<div className="mb-1 flex items-center justify-between font-mono text-[10px] uppercase tracking-[0.15em]">
<span className="text-muted-foreground">XP</span>
<span className="font-bold tabular-nums text-foreground" role="status" aria-label={`Experience ${value} of ${max}`}>
{value}/{max}
</span>
</div>
<div
role="progressbar"
aria-valuemin={0}
aria-valuemax={max}
aria-valuenow={Math.max(0, Math.min(max, value))}
aria-label="Experience"
className="h-3 overflow-hidden rounded-full border border-border bg-secondary"
>
<div
className="h-full rounded-full bg-accent transition-[width] duration-300 motion-reduce:transition-none"
style={{ width: `${pct}%` }}
/>
</div>
</div>
</div>
);
}
Props
| Prop | Type | Description |
|---|---|---|
| value | number | Current experience (required). |
| max | number | Level threshold (default 100). |
| level | number | Badge level (default 1). |