Points Levels List
trophy/points-levels-listFreeComponent
React levels list with optional progress bar between tiers. Built on shadcn/ui + Tailwind. Open source.
Live preview
live · rendered by the registry
Rendered by trophy on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.trophy.so/r/points-levels-list.jsonSource
1"use client"23import * as React from "react"4import {5 BadgeCheck,6 Medal,7 Shield,8 ShieldCheck,9 ShieldHalf,10 Sparkles,11 Trophy,12 type LucideIcon,13} from "lucide-react"1415import { cn } from "@/lib/utils"1617export type PointsLevelListIconType =18 | "beginner"19 | "novice"20 | "intermediate"21 | "professional"22 | "expert"23 | "master"24 | "grand-master"25 | "enlightened"2627export interface PointsSubLevelList {28 name: string29 points: number30}3132export interface PointsLevelList {33 id: string34 key?: string35 name: string36 description?: string37 badgeUrl?: string | null38 points: number39 iconType?: PointsLevelListIconType40 subLevels?: PointsSubLevelList[]41}4243interface PointsLevelsListProps extends React.HTMLAttributes<HTMLDivElement> {44 levels: PointsLevelList[]45 currentPoints?: number46 showProgressBar?: boolean47 currentLevelLabel?: string48 formatPoints?: (value: number) => string49}5051const pointsLevelListIconMap: Record<PointsLevelListIconType, LucideIcon> = {52 beginner: Shield,53 novice: ShieldHalf,54 intermediate: BadgeCheck,55 professional: ShieldCheck,56 expert: Medal,57 master: Trophy,58 "grand-master": Trophy,59 enlightened: Sparkles,60}6162function formatRange(63 points: number,64 nextLevelPoints: number | null | undefined,65 formatPoints?: (value: number) => string66) {67 const format = formatPoints ?? ((value: number) => value.toLocaleString())68 if (typeof nextLevelPoints === "number") {69 return `${format(points)}-${format(nextLevelPoints - 1)}`70 }71 return `${format(points)}+`72}7374const PointsLevelsList = React.forwardRef<75 HTMLDivElement,76 PointsLevelsListProps77>(78 (79 {80 className,81 levels,82 currentPoints,83 showProgressBar = false,84 currentLevelLabel = "Your current level",85 formatPoints,86 ...props87 },88 ref89 ) => {90 const currentLevelIndex =91 typeof currentPoints === "number"92 ? levels.reduce((matchedIndex, level, index) => {93 if (currentPoints >= level.points) {94 return index95 }96 return matchedIndex97 }, -1)98 : -199 const currentLevel =100 currentLevelIndex >= 0 ? levels[currentLevelIndex] : undefined101 const nextLevel =102 currentLevelIndex >= 0 && currentLevelIndex < levels.length - 1103 ? levels[currentLevelIndex + 1]104 : undefined105 const shouldShowProgressBar =106 showProgressBar &&107 typeof currentPoints === "number" &&108 Boolean(currentLevel && nextLevel)109110// … truncated
What it pulls in
npm packages
Files it writes
More from trophy
All 18 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Achievement Badgeachievement-badge | trophy | Components | Free | 1 dep | |
| Achievement Cardachievement-card | trophy | Components | Free | no deps | |
| Achievement Gridachievement-grid | trophy | Components | Free | 2 deps | |
| Achievement Listachievement-list | trophy | Components | Free | 2 deps | |
| Achievement Unlockedachievement-unlocked | trophy | Components | Free | 1 dep | |
| Leaderboard Cardleaderboard-card | trophy | Components | Free | no deps | |
| Leaderboard Podiumleaderboard-podium | trophy | Components | Free | 2 deps | |
| Leaderboard Rankingsleaderboard-rankings | trophy | Components | Free | 2 deps |
