The Pricing Card displays pricing plans with a stunning nested card design, featuring glassmorphism effects, customizable colors, and dynamic button states.
Preview
import { PricingCard } from "@/components/ui/pricing-card" ;
export default function Example () {
return (
< PricingCard
title = "Free"
price = { 0 }
description = "Perfect for trying out our platform"
features = { [
"Up to 3 projects" ,
"Basic analytics" ,
"Community support" ,
"1 GB storage"
] }
/>
);
}
Installation
npx shadcn@latest add "https://ui.heygaia.io/r/pricing-card"
Install dependencies
npm install @hugeicons/react
Copy the source code
Copy pricing-card.tsx to your components directory
Usage
Basic Pricing Card
import { PricingCard } from "@/components/ui/pricing-card" ;
< PricingCard
title = "Starter"
price = { 9.99 }
description = "Great for individuals"
features = { [
"10 projects" ,
"Basic features" ,
"Email support"
] }
/>
Monthly vs Yearly
import { PricingCard } from "@/components/ui/pricing-card" ;
import { useState } from "react" ;
function PricingTable () {
const [ isMonthly , setIsMonthly ] = useState ( true );
return (
<>
{ /* Toggle switch for monthly/yearly */ }
< PricingCard
title = "Pro"
price = { isMonthly ? 29 : 290 }
originalPrice = { isMonthly ? 29 : 348 }
isMonthly = { isMonthly }
features = { [ "All features" ] }
/>
</>
);
}
Current Plan Badge
< PricingCard
title = "Pro"
price = { 29 }
isCurrentPlan = { true }
features = { [ "Current plan features" ] }
/>
Custom Accent Color
< PricingCard
title = "Enterprise"
price = { 99 }
accentColor = "#ff6b6b"
features = { [ "Everything included" ] }
/>
With Custom Features
import { PricingCard } from "@/components/ui/pricing-card" ;
import { StarIcon } from "@/components/icons" ;
const customFeatures = [
{
text: "Premium feature 1" ,
icon: < StarIcon className = "text-yellow-500" size = { 18 } />
},
{
text: "Premium feature 2" ,
icon: < StarIcon className = "text-yellow-500" size = { 18 } />
},
"Standard feature 1" ,
"Standard feature 2"
];
< PricingCard
title = "Premium"
price = { 49 }
features = { customFeatures }
/>
Loading State
import { PricingCard } from "@/components/ui/pricing-card" ;
import { useState } from "react" ;
function PricingWithCheckout () {
const [ isLoading , setIsLoading ] = useState ( false );
const handleUpgrade = async () => {
setIsLoading ( true );
await processPayment ();
setIsLoading ( false );
};
return (
< PricingCard
title = "Pro"
price = { 29 }
features = { [ "Pro features" ] }
onButtonClick = { handleUpgrade }
isLoading = { isLoading }
/>
);
}
Props
Plan name (e.g., “Free”, “Pro”, “Enterprise”)
Price amount. Use 0 for free plans. Supports decimals (e.g., 9.99).
Currency symbol to display before the price
Original price before discount. Shows with strikethrough when provided (only for yearly plans).
Plan description/subtitle shown below the title
features
(string | PricingFeature)[]
Array of features included in the plan. Can be strings or objects with custom icons. Show PricingFeature properties
Custom icon component. Defaults to a green checkmark.
Custom heading above the features list
Whether the price is monthly or yearly. Affects the billing period text.
Shows a “Current Plan” badge and disables the button
Custom button text. Defaults to:
“Current Plan” if isCurrentPlan is true
“Get Started” if price is 0
“Upgrade” otherwise
Callback when the button is clicked
Whether the button is disabled
Whether the button shows a loading state
accentColor
string
default: "'#00bbff'"
CSS color value for the button background. Free plans always use dark gray.
Additional CSS classes to apply to the card
Features
Glassmorphism Design
The card features a stunning nested design:
Outer card with semi-transparent white background
Inner nested card with glass effect
Backdrop blur for modern appearance
Works beautifully on any background
Dynamic Button Styling
The button automatically adapts:
Free plans get a neutral dark gray button
Paid plans use the custom accent color
Current plan shows special badge and disabled state
Loading state with “Loading…” text
Price Formatting
Prices are automatically formatted:
Whole numbers: “$29”
Decimals: “$9.99”
Free: “$0”
Respects custom currency symbols
Discount Display
When originalPrice is provided and isMonthly is false:
Shows original price with strikethrough
Displays discounted price prominently
Highlights savings for annual plans
Feature Icons
Each feature can have:
Default green checkmark icon
Custom icon component
Consistent 18px size
Proper spacing and alignment
Examples
Complete Pricing Table
import { PricingCard } from "@/components/ui/pricing-card" ;
import { useState } from "react" ;
function PricingPage () {
const [ isMonthly , setIsMonthly ] = useState ( true );
const [ currentPlan , setCurrentPlan ] = useState ( "free" );
const plans = [
{
id: "free" ,
title: "Free" ,
monthlyPrice: 0 ,
yearlyPrice: 0 ,
description: "Perfect for trying out" ,
features: [
"3 projects" ,
"Basic analytics" ,
"Community support"
]
},
{
id: "pro" ,
title: "Pro" ,
monthlyPrice: 29 ,
yearlyPrice: 290 ,
originalYearlyPrice: 348 ,
description: "For professionals" ,
features: [
"Unlimited projects" ,
"Advanced analytics" ,
"Priority support" ,
"100 GB storage"
],
accentColor: "#00bbff"
},
{
id: "enterprise" ,
title: "Enterprise" ,
monthlyPrice: 99 ,
yearlyPrice: 990 ,
originalYearlyPrice: 1188 ,
description: "For large teams" ,
features: [
"Everything in Pro" ,
"Unlimited storage" ,
"Dedicated support" ,
"Custom integrations" ,
"SLA guarantee"
],
accentColor: "#8b5cf6"
}
];
return (
< div className = "grid gap-6 md:grid-cols-3" >
{ plans . map ( plan => (
< PricingCard
key = { plan . id }
title = { plan . title }
price = { isMonthly ? plan . monthlyPrice : plan . yearlyPrice }
originalPrice = { ! isMonthly ? plan . originalYearlyPrice : undefined }
description = { plan . description }
features = { plan . features }
isMonthly = { isMonthly }
isCurrentPlan = { currentPlan === plan . id }
accentColor = { plan . accentColor }
onButtonClick = { () => handleUpgrade ( plan . id ) }
/>
)) }
</ div >
);
}
With Custom Features Section
import { PricingCard } from "@/components/ui/pricing-card" ;
const featuresTitle = (
< div className = "mb-3" >
< h4 className = "font-semibold text-zinc-900 dark:text-white" >
What's included:
</ h4 >
</ div >
);
< PricingCard
title = "Premium"
price = { 49 }
features = { [ "Feature 1" , "Feature 2" ] }
featuresTitle = { featuresTitle }
/>
Styling
The pricing card uses:
Glassmorphism with backdrop blur
Nested card design for depth
White/transparent backgrounds
Rounded corners (rounded-3xl)
Shadow effects for elevation
Smooth transitions
Use the same accent color across your brand for consistency, or different colors to differentiate plan tiers.
The raised button component requires the colorUtils helper for dynamic text contrast. Make sure this is installed.