بلاک‌ها · بخش‌های صفحه

مراحل با کارتِ عکس

پیش‌نمایش تمام‌صفحه

بخشِ روندِ کار در چهار کارتِ عکس‌دارِ عمودی با شمارهٔ قدم، تیتر و یک جمله؛ در موبایل ریلِ افقی.

۱. نصب کامپوننت‌ها

این بلاک از ۳ آیتم دیگ استفاده می‌کند: control-sizepersianreveal

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.json
bunx --bun digdesign@latest add https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.json

۲. کد صفحه

کد را در app/<route>/page.tsx بگذارید و متن‌ها، داده و هندلرها را با محصول خودتان عوض کنید.

process-cards.tsx
"use client"

import { ControlSizeProvider } from "@/components/ui/control-size"
import { Reveal } from "@/components/ui/reveal"
import { toFaDigits } from "@/lib/persian"
import { stockImages, type StockImageName } from "@/lib/stock-images"

const STEPS: { title: string; text: string; photo: StockImageName }[] = [
  { title: "مشاورهٔ مصرف", text: "قبض‌های یک سال را می‌خوانیم و نیازِ واقعیِ خانه را می‌سنجیم.", photo: "coverCalculator" },
  { title: "طراحیِ سفارشی", text: "چیدمانِ پنل‌ها را برای بیشترین نورِ بامِ شما طراحی می‌کنیم.", photo: "projectDashboard" },
  { title: "نصبِ حرفه‌ای", text: "تیمِ دارای گواهی در یک روز نصب را تمام و تحویل می‌دهد.", photo: "studioSunlit" },
  { title: "روشن‌کردن و پایش", text: "از همان شب تولیدِ برق را لحظه‌به‌لحظه در اپ می‌بینید.", photo: "projectMobileApp" },
]

/**
 * روندِ کار در چهار کارتِ عکس‌دار: هر کارت عکسِ عمودی با شمارهٔ قدم روی آن، تیتر و یک
 * جمله؛ کارت‌ها پله‌پله وارد می‌شوند و در موبایل ریلِ افقیِ قابلِ کشیدن‌اند.
 */
export default function ProcessCardsBlock() {
  return (
    <ControlSizeProvider size="xl" asChild>
      <section aria-labelledby="pc-title" className="mx-auto flex w-full max-w-6xl flex-col gap-12 py-24">
        <div className="mx-auto flex max-w-2xl flex-col items-center gap-3 px-4 text-center sm:px-6">
          <span className="rounded-full border border-border px-3 py-1 text-sm font-semibold">چطور کار می‌کند</span>
          <h2 id="pc-title" className="text-3xl leading-snug font-black text-balance sm:text-4xl">
            برنامه‌ریزیِ ما، برقِ خانهٔ شما
          </h2>
        </div>
        <ol className="flex snap-x snap-mandatory gap-4 overflow-x-auto px-4 pb-2 [scrollbar-width:none] sm:px-6 md:grid md:grid-cols-4 md:overflow-visible [&::-webkit-scrollbar]:hidden">
          {STEPS.map((step, index) => (
            <Reveal asChild key={step.title} delay={index * 100}>
              <li className="group flex w-64 shrink-0 snap-start flex-col gap-4 md:w-auto">
                <div className="relative overflow-hidden rounded-xl">
                  {/* eslint-disable-next-line @next/next/no-img-element -- عکس از کتابخانهٔ تصویرِ دیگ */}
                  <img src={stockImages[step.photo].src} alt="" className="aspect-[4/5] w-full object-cover transition-transform duration-700 group-hover:scale-105" />
                  <span className="absolute start-3 top-3 rounded-full bg-card px-3 py-1 text-sm font-bold tabular-nums shadow-sm">{toFaDigits(String(index + 1).padStart(2, "0"))}</span>
                </div>
                <div className="flex flex-col gap-1.5">
                  <h3 className="text-lg font-bold">{step.title}</h3>
                  <p className="text-sm leading-6 text-muted-foreground">{step.text}</p>
                </div>
              </li>
            </Reveal>
          ))}
        </ol>
      </section>
    </ControlSizeProvider>
  )
}