PG02▸📐 Layout · 版型▸定價
Pricing
定價方案
難度 ★★★★★標籤 pricing · tier · feature3 min read
模式簡述
Pricing:定價方案比較。3 欄是最常見,highlight 中間方案促使選擇。月年切換要清楚省多少。
免費
$0/月
- 10 個元件
- 社群支援
- 個人專案
熱門
Pro
$12/月
- 所有元件
- Email 支援
- 商業使用
- 新元件搶先看
Team
$49/月
- 所有元件
- 5 位成員
- 私有元件庫
- 優先支援
Claude Code Prompt
參考:PG02 pricing 組件:Pricing.tsx Pricing:定價方案比較。3 欄是最常見,highlight 中間方案促使選擇。月年切換要清楚省多少。 限制: - 沒 highlight 推薦方案 - 年付沒寫省多少 - 功能列表用 ✓/✗
完整程式碼
"use client";
import { useState, useEffect } from "react";
import { Check } from "lucide-react";
import { cn } from "@/lib/utils";
type State = "monthly" | "yearly";
const PLANS = [
{ name: "免費", priceM: 0, priceY: 0, features: ["10 個元件", "社群支援", "個人專案"] },
{ name: "Pro", priceM: 12, priceY: 120, features: ["所有元件", "Email 支援", "商業使用", "新元件搶先看"], popular: true },
{ name: "Team", priceM: 49, priceY: 490, features: ["所有元件", "5 位成員", "私有元件庫", "優先支援"] },
];
export function Pricing({ state = "monthly" }: { state?: State }) {
const [yearly, setYearly] = useState(state === "yearly");
useEffect(() => setYearly(state === "yearly"), [state]);
return (
<div className="w-full">
<div className="mb-4 flex justify-center">
<div className="inline-flex rounded-full bg-muted p-0.5 text-xs">
<button
onClick={() => setYearly(false)}
className={cn("rounded-full px-3 py-1", !yearly && "bg-background shadow")}
>
月付
</button>
<button
onClick={() => setYearly(true)}
className={cn("rounded-full px-3 py-1", yearly && "bg-background shadow")}
>
年付 <span className="text-lab-accent">-17%</span>
</button>
</div>
</div>
<div className="grid grid-cols-3 gap-3">
{PLANS.map((p) => (
<div
key={p.name}
className={cn(
"rounded-xl border p-4",
p.popular ? "border-lab-accent bg-lab-accent/5" : "border-border bg-background/30",
)}
>
{p.popular && (
<span className="mb-2 inline-block rounded-full bg-lab-accent px-2 py-0.5 font-mono text-[9px] text-background">
熱門
</span>
)}
<h3 className="text-sm font-medium">{p.name}</h3>
<p className="mt-2 text-2xl font-medium">
${yearly ? p.priceY : p.priceM}
<span className="text-xs text-muted-foreground">/{yearly ? "年" : "月"}</span>
</p>
<ul className="mt-3 space-y-1.5">
{p.features.map((f) => (
<li key={f} className="flex items-center gap-1.5 text-[11px] text-muted-foreground">
<Check className="h-3 w-3 shrink-0 text-lab-accent" /> {f}
</li>
))}
</ul>
</div>
))}
</div>
</div>
);
}何時用
- ✅ SaaS 訂閱定價頁
- ✅ 產品 tier 比較
- ✅ 服務方案頁
何時別用
- ❌ 只有一個方案(直接寫價)
- ❌ 價格因人而異(contact us)
- ❌ 免費產品(不需要 pricing)
我踩過的坑
-
沒 highlight 推薦方案:使用者陷入選擇癱瘓。中間或推薦的方案用 accent 邊框 + popular badge。
-
年付沒寫省多少:使用者不會自己算。寫 ‘save 17%’ 或 ‘2 months free’。
-
功能列表用 ✓/✗:差異太細看不清。用「✓ vs 灰 -」對比清楚。
相關模式
- PG01
- PG04