Token Icon Group
Stacked, overlapping token icons for displaying LP pairs, multi-token groups, or collateral baskets
+2
import { TokenIconGroup } from "@/components/sol/token-icon-group";
const SOL_ICON =
"https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png";
const USDC_ICON =
"https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png";
export function TokenIconGroupDemo() {
return (
<TokenIconGroup
tokens={[
{ src: SOL_ICON, alt: "SOL" },
{ src: USDC_ICON, alt: "USDC" },
]}
size={36}
/>
);
}Installation
pnpm dlx shadcn@latest add @solanaui/token-icon-group
npx shadcn@latest add @solanaui/token-icon-group
yarn dlx shadcn@latest add @solanaui/token-icon-group
Usage
LP Pair
<TokenIconGroup
tokens={[
{ src: SOL_ICON, alt: "SOL" },
{ src: USDC_ICON, alt: "USDC" },
]}
/>With Overflow Badge
When there are more tokens than max (defaults to 4), a +N badge is shown at the end.
<TokenIconGroup
tokens={[
{ src: SOL_ICON, alt: "SOL" },
{ src: USDC_ICON, alt: "USDC" },
{ src: BONK_ICON, alt: "BONK" },
{ src: JITOSOL_ICON, alt: "JitoSOL" },
{ src: MSOL_ICON, alt: "mSOL" },
]}
max={3}
/>Source Code
import { TokenIcon } from "@/registry/sol/token-icon";import { cn } from "@/lib/utils";interface TokenIconGroupProps { tokens: { src: string; alt?: string }[]; size?: number; overlap?: number; max?: number; className?: string;}const TokenIconGroup = ({ tokens, size = 24, overlap = -10, max = 4, className,}: TokenIconGroupProps) => { const visible = tokens.slice(0, max); const remaining = tokens.length - max; const hasOverlap = visible.length > 1 || remaining > 0; return ( <div className={cn("flex items-center", className)}> {visible.map((token, i) => ( <div key={`${token.src}-${i}`} className={cn( "rounded-full relative leading-[0]", hasOverlap && "ring-2 ring-background", )} style={{ marginLeft: i === 0 ? 0 : overlap, zIndex: visible.length + 1 - i, }} > <TokenIcon src={token.src} alt={token.alt ?? "Token"} width={size} height={size} /> </div> ))} {remaining > 0 && ( <div className="relative flex items-center justify-center rounded-full bg-muted text-muted-foreground ring-2 ring-background font-medium" style={{ width: size, height: size, marginLeft: overlap, fontSize: size * 0.35, zIndex: visible.length + 2, }} > +{remaining} </div> )} </div> );};export type { TokenIconGroupProps };export { TokenIconGroup };