قیمتگذاری، تیره و رنگکد
پیشنمایش تمامصفحهقیمتگذاری روی صفحهٔ تیره: هر پلن نوارِ رنگیِ خودش را دارد و پلنِ پیشنهادی درخشش و قابِ روشن؛ سوییچِ ماهانه/سالانه، فهرستِ دارد/ندارد و ردیفِ سازمانی با تماس با فروش.
۱. نصب کامپوننتها
این بلاک از ۵ آیتم دیگ استفاده میکند: buttoncontrol-sizeiconsrevealtoggle-group
پکیجمنیجر پیشفرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیجمنیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.jsonpnpm dlx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.jsonyarn dlx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.jsonbunx --bun digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.json۲. کد صفحه
کد را در app/<route>/page.tsx بگذارید و متنها، داده و هندلرها را با محصول خودتان عوض کنید.
pricing-dark.tsx
"use client"
import * as React from "react"
import { ArrowUpIcon, CheckIcon, MinusIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Reveal } from "@/components/ui/reveal"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { cn } from "@/lib/utils"
const PLANS = [
{
name: "پایه",
text: "برای فریلنسرها و پروژههای شخصی",
month: 0,
band: "bg-[var(--dig-cyan-400)]",
accent: "text-[var(--dig-cyan-300)]",
features: [["۳ پروژه", true], ["۱ گیگابایت فضا", true], ["دامنهٔ اختصاصی", false], ["گزارشِ پیشرفته", false]],
},
{
name: "رشد",
text: "برای تیمهای کوچکِ در حالِ رشد",
month: 390,
band: "bg-[linear-gradient(90deg,var(--dig-violet-500),var(--dig-pink-500))]",
accent: "text-[var(--dig-violet-300)]",
featured: true,
features: [["پروژهٔ نامحدود", true], ["۵۰ گیگابایت فضا", true], ["دامنهٔ اختصاصی", true], ["گزارشِ پیشرفته", false]],
},
{
name: "حرفهای",
text: "برای کسبوکارهایی با ترافیکِ بالا",
month: 990,
band: "bg-[var(--dig-orange-400)]",
accent: "text-[var(--dig-orange-300)]",
features: [["پروژهٔ نامحدود", true], ["۵۰۰ گیگابایت فضا", true], ["دامنهٔ اختصاصی", true], ["گزارشِ پیشرفته", true]],
},
] as const
/**
* قیمتگذاری روی صفحهٔ تیره با پلنهای رنگکد: هر پلن نوارِ رنگیِ خودش را بالای کارت دارد و
* پلنِ پیشنهادی گرادیان و قابِ روشن میگیرد؛ سوییچِ ماهانه/سالانه، فهرستِ «دارد/ندارد» و ردیفِ
* سازمانی با دکمهٔ تماس با فروش. همیشه تیره است.
*/
export default function PricingDarkBlock() {
const [billing, setBilling] = React.useState("year")
return (
<ControlSizeProvider size="xl" asChild>
<main className="w-full bg-[var(--dig-graphite-950)] px-4 py-24 text-[var(--dig-white)] [--border:var(--dig-graphite-800)] [--muted-foreground:var(--dig-neutral-400)] sm:px-6">
<div className="mx-auto flex w-full max-w-6xl flex-col gap-12">
<header className="flex flex-col items-center gap-5 text-center">
<h1 className="max-w-2xl text-4xl leading-tight font-black text-balance sm:text-6xl sm:leading-tight">قیمتی که با شما بزرگ میشود</h1>
<p className="max-w-md text-muted-foreground">رایگان شروع کنید؛ هر وقت تیمتان بزرگ شد، پلن را عوض کنید.</p>
<ToggleGroup
type="single"
variant="segmented"
value={billing}
onValueChange={(value) => value && setBilling(value as string)}
aria-label="دورهٔ پرداخت"
className="[--background:var(--dig-graphite-700)] [--foreground:var(--dig-white)] [--muted:var(--dig-graphite-900)]"
>
<ToggleGroupItem value="month">ماهانه</ToggleGroupItem>
<ToggleGroupItem value="year">سالانه، ۲ ماه رایگان</ToggleGroupItem>
</ToggleGroup>
</header>
<ul className="grid grid-cols-1 gap-4 md:grid-cols-3">
{PLANS.map((plan, index) => {
const price = billing === "year" ? Math.round((plan.month * 10) / 12) : plan.month
const featured = "featured" in plan && plan.featured
return (
<Reveal asChild key={plan.name} delay={index * 100}>
<li className={cn("flex flex-col overflow-hidden rounded-xl border bg-[var(--dig-graphite-900)]", featured ? "border-[var(--dig-violet-400)] shadow-[0_0_60px_-20px_var(--dig-violet-500)]" : "border-[var(--dig-graphite-800)]")}>
<span aria-hidden className={cn("h-1.5", plan.band)} />
<div className="flex flex-1 flex-col gap-6 p-6">
<div className="flex flex-col gap-1">
<span className={cn("flex items-center justify-between font-bold", plan.accent)}>
{plan.name}
{featured && <span className="rounded-full bg-[var(--dig-violet-600)] px-2.5 py-0.5 text-xs text-[var(--dig-white)]">پیشنهادِ ما</span>}
</span>
<span className="text-sm text-muted-foreground">{plan.text}</span>
</div>
<span className="flex items-baseline gap-1.5">
<span className="text-4xl font-black tabular-nums">{price === 0 ? "رایگان" : price.toLocaleString("fa-IR")}</span>
{price > 0 && <span className="text-sm text-muted-foreground">هزار تومان / ماه</span>}
</span>
<Button
fullWidth
variant={featured ? "default" : "outline"}
className={cn(featured ? "[--primary-foreground:var(--dig-graphite-950)] [--primary:var(--dig-white)]" : "border-[var(--dig-graphite-700)] bg-transparent text-[var(--dig-white)] hover:bg-[var(--dig-graphite-800)]")}
>
{plan.month === 0 ? "شروعِ رایگان" : "انتخابِ پلن"}
</Button>
<ul className="flex flex-col gap-3 border-t border-border pt-5 text-sm">
{plan.features.map(([label, included]) => (
<li key={label} className={cn("flex items-center gap-2.5", !included && "text-[var(--dig-neutral-400)]")}>
{included ? <CheckIcon aria-label="دارد" className={cn("size-4", plan.accent)} /> : <MinusIcon aria-label="ندارد" className="size-4" />}
{label}
</li>
))}
</ul>
</div>
</li>
</Reveal>
)
})}
</ul>
<div className="flex flex-col items-start justify-between gap-4 rounded-xl border border-[var(--dig-graphite-800)] bg-[linear-gradient(90deg,var(--dig-graphite-900),var(--dig-graphite-950))] p-6 sm:flex-row sm:items-center">
<div className="flex flex-col gap-1">
<span className="text-lg font-bold">سازمانی</span>
<span className="text-sm text-muted-foreground">قراردادِ اختصاصی، سرورِ جدا، پشتیبانیِ ۲۴ ساعته و مدیرِ حساب.</span>
</div>
<Button variant="outline" className="shrink-0 border-[var(--dig-graphite-700)] bg-transparent text-[var(--dig-white)] hover:bg-[var(--dig-graphite-800)]">
تماس با فروش
<ArrowUpIcon aria-hidden className="-rotate-45" />
</Button>
</div>
</div>
</main>
</ControlSizeProvider>
)
}