# XP bar

XP bar is a neobrutalist React component from Cruise UI. A segmented game bar: level badge, XP / health / mana fill and the value.

Install (with the @cruiseui registry in components.json, see Installation):

```bash
npx shadcn@latest add @cruiseui/xp-bar
```

Import: `import { CruiseXpBar } from "@/components/cruise/xp-bar";`

## When to use

Game HUDs and gamified apps: experience, health, mana, streaks.

## When not to

Uploads or task progress (use Progress).

## Example (React)

```tsx
"use client";

import { useState } from "react";
import { CruiseButton } from "@/components/cruise/button";
import { CruiseXpBar } from "@/components/cruise/xp-bar";

export default function XpBarExample() {
  const [health, setHealth] = useState(80);
  return (
    <div className="flex flex-col gap-5">
      <CruiseXpBar kind="xp" level={7} value={1240} max={2000} />
      <CruiseXpBar kind="health" value={health} max={100} />
      <CruiseXpBar kind="mana" value={45} max={60} />
      <div className="flex flex-wrap gap-3">
        <CruiseButton variant="danger" onClick={() => setHealth((h) => Math.max(0, h - 20))}>
          Take a hit
        </CruiseButton>
        <CruiseButton variant="success" onClick={() => setHealth(100)}>
          Heal
        </CruiseButton>
      </div>
    </div>
  );
}
```

## HTML

Needs theme.css (https://cruiseui.dev/theme.css).

```html
<div class="xp-bar" data-kind="health" data-low>
  <span class="xp-level">LV 7</span>
  <div class="xp-track" role="progressbar" aria-label="Health" aria-valuemin="0" aria-valuemax="100" aria-valuenow="24" aria-valuetext="24 / 100 HP, low">
    <div class="xp-fill" style="width: 24%"></div>
    <div class="xp-segments" aria-hidden="true"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>
  </div>
  <span class="xp-value" aria-hidden="true">24 / 100 HP</span>
</div>
<!-- XP: data-kind="xp" and class="xp-fill on-primary". Mana: data-kind="mana". -->
```

## Props: CruiseXpBar

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `kind?` | `"xp" \| "health" \| "mana"` | `"xp"` | — |
| `value` | `number` | — | — |
| `max` | `number` | — | — |
| `level?` | `number` | — | Shows "LV 7" on the left. |
| `label?` | `string` | — | Accessible name; defaults to "Experience", "Health" or "Mana". |
| `segments?` | `number` | `10` | Number of segments (ink dividers). |
| `className?` | `string` | — | — |

## Accessibility

- role="progressbar" with aria-valuenow / max and a value text ("1,240 / 2,000 XP").
- Low health also says "low", not only red.
- The fill animates in 300ms; none under reduced motion.
