Vector Motion
Finance

Investment Card - Investment Portfolio

Monitor investment portfolio and asset allocation. Track investment returns and performance.

Finance Investment Card

The Finance Investment Card displays investment holdings and performance metrics, helping investors monitor their investment portfolio.

Preview

Installation

npx shadcn@latest add https://vectormotion.vercel.app/registry/finance-investment-card.json
Finance Investment Card
'use client'import React from 'react';import { TrendingUp, ArrowUpRight } from 'lucide-react';import { AreaChart, Area, Tooltip, ResponsiveContainer, XAxis, YAxis } 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 InvestmentData {  month: string;  value: number;  [key: string]: any;}interface InvestmentCardProps {  isInteractive?: boolean;  className?: string;  title?: string;  totalValue?: string;  change?: string;  ytdReturn?: string;  data?: InvestmentData[];}const DEFAULT_TITLE = "Investment Growth";const DEFAULT_TOTAL_VALUE = "$24.6k";const DEFAULT_CHANGE = "12.5%";const DEFAULT_YTD_RETURN = "+$2,780";const DEFAULT_DATA: InvestmentData[] = [  { month: 'Jan', value: 4000 },  { month: 'Feb', value: 3000 },  { month: 'Mar', value: 5000 },  { month: 'Apr', value: 4500 },  { month: 'May', value: 6000 },  { month: 'Jun', value: 5500 },  { month: 'Jul', value: 8000 },];export const InvestmentCard: React.FC<InvestmentCardProps> = ({  isInteractive = true,  className = "",  title = DEFAULT_TITLE,  totalValue = DEFAULT_TOTAL_VALUE,  change = DEFAULT_CHANGE,  ytdReturn = DEFAULT_YTD_RETURN,  data = DEFAULT_DATA,}) => {  const index = 28;  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-5 shadow-sm transition-all flex flex-col h-full group",        isInteractive ? "cursor-pointer hover:border-primary/50 hover:shadow-md" : "",        className      )}    >      <div className="mb-2 flex items-start justify-between relative z-10">        <div>          <h3 className="font-semibold text-lg text-foreground">            {title}          </h3>          <div className="flex items-center gap-2 mt-1">            <span className="text-2xl font-bold text-foreground">{totalValue}</span>            <span className="flex items-center gap-1 text-xs text-emerald-600 bg-emerald-500/10 px-1.5 py-0.5 rounded">              <ArrowUpRight className="w-3 h-3" /> {change}            </span>          </div>        </div>        <div className="rounded-lg bg-emerald-500/10 p-2 text-emerald-500">          <TrendingUp className="h-5 w-5" />        </div>      </div>      <div className="relative z-10 flex-1 min-h-[140px]">        <div className="absolute inset-0 -ml-4">          <ResponsiveContainer width="100%" height="100%">            <AreaChart data={data}>              <defs>                <linearGradient id="colorInvest" x1="0" y1="0" x2="0" y2="1">                  <stop offset="5%" stopColor="#10b981" stopOpacity={0.3} />                  <stop offset="95%" stopColor="#10b981" stopOpacity={0} />                </linearGradient>              </defs>              <Tooltip                cursor={{ stroke: '#10b981', strokeWidth: 1, strokeDasharray: '4 4' }}                contentStyle={{ backgroundColor: 'var(--tooltip-bg)', borderRadius: '8px', border: 'none', boxShadow: '0 4px 12px rgba(0,0,0,0.1)', color: 'var(--tooltip-text)' }}              />              <Area                type="monotone"                dataKey="value"                stroke="#10b981"                strokeWidth={2}                fillOpacity={1}                fill="url(#colorInvest)"                animationDuration={1500}              />              <XAxis dataKey="month" hide />              <YAxis hide domain={['dataMin - 1000', 'dataMax + 1000']} />            </AreaChart>          </ResponsiveContainer>        </div>      </div>      <div className="z-10 mt-2 flex items-center justify-between text-xs pt-2 border-t border-border">        <span className="text-muted-foreground">YTD Return</span>        <span className="font-medium text-foreground">{ytdReturn}</span>      </div>    </motion.div>  );};

Props

Prop

Type