VectorMotion
E-Commerce

Top Products Card - Best Sellers

Identify and track top-selling products. Monitor bestsellers and product popularity trends.

Top Products Card

The Top Products Card Display best-selling products with sales and revenue rankings.

Preview

Installation

ash npx shadcn@latest add https://www.vectormotion.dev/registry/top-products-card.json

Top Products Card
'use client';import React from "react";import { Trophy, Star } from "lucide-react";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 Product {    name: string;    sales: number;    revenue: number;    trend: string;    [key: string]: any;}interface TopProductsCardProps {    className?: string;    title?: string;    description?: string;    products?: Product[];}const DEFAULT_TITLE = "Top Products";const DEFAULT_DESCRIPTION = "Best Sellers";const DEFAULT_PRODUCTS: Product[] = [    { name: "Wireless Headphones", sales: 342, revenue: 25650, trend: "+15%" },    { name: "Smart Watch Pro", sales: 298, revenue: 44700, trend: "+22%" },    { name: "Laptop Stand", sales: 256, revenue: 12800, trend: "+8%" },];export const TopProductsCard: React.FC<TopProductsCardProps> = ({    className = "",    title = DEFAULT_TITLE,    description = DEFAULT_DESCRIPTION,    products = DEFAULT_PRODUCTS,}) => {    const isInteractive = true;    const index = 5;    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">                    <Trophy className="h-5 w-5 text-amber-500" />                </div>            </div>            <div className="relative z-10 flex-1 space-y-3">                {products.map((product, idx) => (                    <motion.div                        key={idx}                        initial={{ opacity: 0, x: -20 }}                        animate={{ opacity: 1, x: 0 }}                        transition={{ duration: 0.5, delay: idx * 0.1 }}                        className="bg-muted rounded-lg p-3"                    >                        <div className="flex items-start justify-between mb-2">                            <div className="flex items-center gap-2">                                <div                                    className={`w-6 h-6 rounded-full flex items-center justify-center text-xs font-bold ${idx === 0                                            ? "bg-amber-500 text-white"                                            : idx === 1                                                ? "bg-zinc-300 dark:bg-zinc-600 text-foreground"                                                : "bg-orange-400 text-white"                                        }`}                                >                                    {idx + 1}                                </div>                                <span className="text-sm font-medium text-foreground">                                    {product.name}                                </span>                            </div>                            <span className="text-xs font-medium text-emerald-500">                                {product.trend}                            </span>                        </div>                        <div className="flex justify-between items-center text-xs">                            <span className="text-muted-foreground">                                {product.sales} units sold                            </span>                            <span className="font-bold text-foreground">                                ${product.revenue.toLocaleString()}                            </span>                        </div>                    </motion.div>                ))}            </div>        </motion.div>    );};

Usage

This component is a data-rich dashboard card displaying e-commerce metrics with animated visualizations and dark mode support. Perfect for dashboards, landing pages, and analytics interfaces.

Prop

Type

On this page

Free block

Need this in production?

Unlock install commands, source access, commercial use, and AI prompts for all VectorMotion blocks.