shadcn.io is not affiliated with official shadcn/ui
Achievement Badges Web3 Block for React
A case of eight soulbound badges drawn as greyscale hexagons weighted by tier, earned or locked with the exact need, rarity worked out from each badge's holder share, an All, Earned and In progress filter and a reading of the chosen badge.
Installation
Overview
Show what a member has done on chain, and what is next, with this badge case for React with Base UI. It's the collection of Badgefold, an on-chain badge program. A hairline frame with a plus mark on each corner starts with a Toggle Group (All, Earned, In progress) over a grid of eight badges, two across on a phone and four on a wide screen. Each badge is a hexagon in greyscale: a heavier outline and an inner ring for a higher tier, solid when earned, dashed with a small bar and "6 of 10 votes" while locked. Rarity is worked out from each badge's typed holder share: under 2 % is Legendary, under 10 % Rare, otherwise Common. Selecting a badge, with the arrow keys or a press, reads it in the side cell: its requirement, its share of the 4,820 holders, a Progress bar with the exact need ("3 more proposals"), and the note that it is soulbound and cannot be transferred. For DAOs, games and communities that record participation as badges.
FAQ
How is rarity decided?
From the badge's holder share, in tenths of a percent in the typed data: under 2.0 % is Legendary, under 10.0 % is Rare, anything else Common. Nobody types the word, so editing a share changes the label in the reading and on the case. Founder, held by 1.6 %, is Legendary; First vote, held by 61.2 %, is Common.
What does soulbound mean here?
A soulbound badge is tied to the address that earned it and cannot be sent to another. The panel says so on every badge and offers no transfer action. Nothing is minted or read from a chain in this demo; in your app the earned state would come from the badge contract, and a locked badge's progress from your indexer.
What happens when a filter hides the chosen badge?
The selection moves to the first badge that matches, and the reading follows. The grid keeps all eight cells: the matches come first and the others stay in place, hidden from view and from the keyboard, so the panel does not change height.
How are the badges drawn?
As small inline SVG: a hexagon whose line weight grows with the tier, an inner ring on tier three, and one mark per badge, all in the text colour with a faint fill when earned. Each has a title, and the cell's text says the state in words, so nothing depends on how it looks.