Finance
Cap Table Card - Equity Structure
Monitor capitalization table and ownership structure. Track equity allocation and shareholder information.
Finance Cap Table Card
The Finance Cap Table Card displays the company's capitalization table, showing ownership percentages and equity distribution among stakeholders.
Preview
Installation
npx shadcn@latest add https://vectormotion.vercel.app/registry/finance-cap-table-card.jsonFinance Cap Table Card
'use client';'use client';import React from 'react';import { PieChart } from 'lucide-react';import { ResponsiveContainer, PieChart as RePie, Pie, Cell, Tooltip } from 'recharts';import { motion } from 'motion/react';import { clsx, type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs))}interface CapTableData { name: string; value: number; color: string; [key: string]: any;}interface CapTableCardProps { isInteractive?: boolean; className?: string; title?: string; description?: string; data?: CapTableData[];}const DEFAULT_TITLE = "Cap Table";const DEFAULT_DESCRIPTION = "Ownership Structure";const DEFAULT_DATA: CapTableData[] = [ { name: 'Founders', value: 45, color: '#10b981' }, // Emerald { name: 'Investors', value: 35, color: '#3b82f6' }, // Blue { name: 'ESOP', value: 20, color: '#f59e0b' }, // Amber];export const CapTableCard: React.FC<CapTableCardProps> = ({ isInteractive = true, className = "", title = DEFAULT_TITLE, description = DEFAULT_DESCRIPTION, data = DEFAULT_DATA,}) => { const index = 35; return ( <motion.div layoutId={isInteractive ? `card-${index}-${title}` : undefined} transition={{ duration: 0.4, ease: "easeOut" }} className={cn( "relative overflow-hidden rounded-xl border border-border bg-card text-card-foreground p-6 shadow-sm transition-all flex flex-col group", isInteractive ? "cursor-pointer hover:border-zinc-300 dark:hover:border-zinc-700" : "", className )} > <div className="mb-4 flex items-start justify-between relative z-10"> <div> <h3 className="font-semibold text-lg tracking-tight text-foreground"> {title} </h3> {description && ( <p className="text-sm text-muted-foreground mt-1"> {description} </p> )} </div> <div className="rounded-full bg-zinc-100 dark:bg-zinc-800 p-2 text-foreground flex items-center justify-center"> <PieChart className="h-5 w-5" /> </div> </div> <div className="relative z-10 flex-1"> <div className="flex items-center gap-4"> <div className="h-32 w-32"> <ResponsiveContainer width="100%" height="100%"> <RePie> <Pie data={data} dataKey="value" innerRadius={40} outerRadius={60} paddingAngle={2}> {data.map((entry, index) => ( <Cell key={`cell-${index}`} fill={entry.color} className="stroke-white dark:stroke-zinc-900" /> ))} </Pie> <Tooltip contentStyle={{ backgroundColor: 'var(--tooltip-bg)', borderRadius: '8px', border: 'none', color: 'var(--tooltip-text)' }} /> </RePie> </ResponsiveContainer> </div> <div className="flex flex-col gap-2 text-xs"> {data.map(item => ( <div key={item.name} className="flex items-center gap-2"> <div className="w-2.5 h-2.5 rounded-full border border-zinc-100 dark:border-zinc-700" style={{ backgroundColor: item.color }} /> <span className="text-zinc-600 dark:text-muted-foreground">{item.name}</span> <span className="font-bold text-foreground ml-auto">{item.value}%</span> </div> ))} </div> </div> </div> </motion.div> );};Props
Prop
Type