Vertical React achievement list with icons, descriptions, and optional progress for dense achievement UI. Complements grids and cards in gamification dashboards. Open source, built on shadcn/ui + Tailwind.
Achievement List is built for dense gamification layouts where each row carries a title, supporting text, and progress—ideal for onboarding missions, quest logs, and checklist-style achievement gamification.
10 Day Streak
Open app for 10 days
5,000 Calorie Burn
Burn 5K calories total
Weekend Warrior
Complete challenges on weekends
Installation
npx shadcn@latest add https://ui.trophy.so/achievement-listUsage
import { AchievementList } from "@/components/ui/achievement-list"<AchievementList
achievements={[
{
id: "list-1",
name: "10 Day Streak",
description: "Open app for 10 days",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 60,
},
{
id: "list-2",
name: "5,000 Calorie Burn",
description: "Burn 5K calories total",
trigger: "metric",
achievedAt: "2024-01-01T00:00:00Z",
progress: 32,
},
]}
/>Examples
Basic Usage
10 Day Streak
Open app for 10 days
5,000 Calorie Burn
Burn 5K calories total
Weekend Warrior
Complete challenges on weekends
<AchievementList
achievements={[
{
id: "list-1",
name: "10 Day Streak",
description: "Open app for 10 days",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 60,
},
{
id: "list-2",
name: "5,000 Calorie Burn",
description: "Burn 5K calories total",
trigger: "metric",
achievedAt: "2024-01-01T00:00:00Z",
progress: 32,
},
]}
/>With Trophy
Use the Trophy SDK to fetch a user's achievements server-side:
import { TrophyApiClient } from '@trophyso/node';
const trophy = new TrophyApiClient({
apiKey: 'YOUR_API_KEY'
});
const response = await trophy.users.achievements("user-id");
Then pass the response into AchievementList props in your UI layer:
<AchievementList achievements={response} />API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
achievements | UserAchievement[] | Required | Array of achievements to render in list rows |
badgeSize | "sm" | "default" | "lg" | "default" | Size of badge in each row |
lockedStyle | "grayscale" | "silhouette" | "hidden" | "grayscale" | Locked achievement visual treatment |
onAchievementClick | (achievement) => void | - | Row click handler |
columns | 2 | 3 | 4 | "auto" | "auto" | Supported for compatibility with AchievementGrid |
gap | "sm" | "default" | "lg" | "default" | Vertical spacing between rows |
Types
interface Achievement {
id: string
name: string
description?: string | null
trigger: "metric" | "api" | "streak"
badgeUrl?: string | null
progress?: number // optional, unlocked only
rarity?: number // accepted but not rendered in list rows
}
interface UserAchievement extends Achievement {
achievedAt: string | null
}