Vector Motion
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.json
Finance 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