PremiumNew

ComparisonTable

Feature comparison grid with check/x marks and category grouping

Data Displaycomparisonpricingfeaturesgrid

Dependencies

shadcn/ui components needed:

npx shadcn@latest add cardnpx shadcn@latest add badge

How to use this component

Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.

Code

1"use client"
2
3import * as React from "react"
4import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
5import { Badge } from "@/components/ui/badge"
6import { cn } from "@/lib/utils"
7
8interface ComparisonTableProps {
9 className?: string
10}
11
12interface Feature {
13 category: string
14 name: string
15 basic: string | boolean
16 pro: string | boolean
17 enterprise: string | boolean
18}
19
20const features: Feature[] = [
21 { category: "Core Features", name: "Projects", basic: true, pro: true, enterprise: true },
22 { category: "Core Features", name: "Team Members", basic: "5", pro: "25", enterprise: "Unlimited" },
23 { category: "Core Features", name: "Storage", basic: "10 GB", pro: "100 GB", enterprise: "Unlimited" },
24 { category: "Advanced", name: "API Access", basic: false, pro: true, enterprise: true },
25 { category: "Advanced", name: "Custom Integrations", basic: false, pro: true, enterprise: true },
26 { category: "Advanced", name: "Advanced Analytics", basic: false, pro: true, enterprise: true },
27 { category: "Support", name: "Email Support", basic: true, pro: true, enterprise: true },
28 { category: "Support", name: "Priority Support", basic: false, pro: true, enterprise: true },
29 { category: "Support", name: "Dedicated Manager", basic: false, pro: false, enterprise: true },
30]
31
32const categories = Array.from(new Set(features.map(f => f.category)))
33
34export function ComparisonTable({ className }: ComparisonTableProps) {
35 return (
36 <Card className={cn("w-full", className)}>
37 <CardHeader>
38 <CardTitle>Compare Plans</CardTitle>
39 </CardHeader>
40 <CardContent>
41 <div className="grid grid-cols-4 gap-4">
42 <div />
43 <div className="text-center">
44 <h3 className="font-semibold">Basic</h3>
45 <Badge variant="outline" className="mt-2">$9/mo</Badge>
46 </div>
47 <div className={cn("text-center relative p-4 rounded-lg bg-primary/5 ring-2 ring-primary")}>
48 <Badge className="absolute -top-2 left-1/2 -translate-x-1/2 text-xs">Popular</Badge>
49 <h3 className="font-semibold mt-2">Pro</h3>
50 <Badge variant="outline" className="mt-2 bg-primary text-primary-foreground border-primary">$29/mo</Badge>
51 </div>
52 <div className="text-center">
53 <h3 className="font-semibold">Enterprise</h3>
54 <Badge variant="outline" className="mt-2">$99/mo</Badge>
55 </div>
56
57 {categories.map((category) => (
58 <React.Fragment key={category}>
59 <div className="col-span-4 py-2 mt-2 bg-muted/50 rounded-md px-4">
60 <span className="font-semibold text-sm">{category}</span>
61 </div>
62 {features.filter(f => f.category === category).map((feature) => (
63 <React.Fragment key={feature.name}>
64 <div className="py-3 px-2 text-sm font-medium">{feature.name}</div>
65 <div className="py-3 px-2 text-center">
66 {typeof feature.basic === "boolean" ? (
67 <span className={cn("text-lg", feature.basic ? "text-emerald-500" : "text-red-500")}>
68 {feature.basic ? "✓" : "✗"}
69 </span>
70 ) : (
71 <span className="text-sm text-muted-foreground">{feature.basic}</span>
72 )}
73 </div>
74 <div className="py-3 px-2 text-center">
75 {typeof feature.pro === "boolean" ? (
76 <span className={cn("text-lg", feature.pro ? "text-emerald-500" : "text-red-500")}>
77 {feature.pro ? "✓" : "✗"}
78 </span>
79 ) : (
80 <span className="text-sm font-medium">{feature.pro}</span>
81 )}
82 </div>
83 <div className="py-3 px-2 text-center">
84 {typeof feature.enterprise === "boolean" ? (
85 <span className={cn("text-lg", feature.enterprise ? "text-emerald-500" : "text-red-500")}>
86 {feature.enterprise ? "✓" : "✗"}
87 </span>
88 ) : (
89 <span className="text-sm font-medium">{feature.enterprise}</span>
90 )}
91 </div>
92 </React.Fragment>
93 ))}
94 </React.Fragment>
95 ))}
96 </div>
97 </CardContent>
98 </Card>
99 )
100}

Related Data Display Components

Command Palette

Search for a command to run...