در نوبت

چارچوبِ پالایشRefine Frame

قابِ رسانه که تصویر رو با هرمِ مورییک از مرحله‌ی خام تا کامل می‌بره — بدونِ هیچ جابه‌جاییِ چیدمان.

محمدجواد

ساخته شده توسط محمدجواد

سازنده فارسی‌فای، بچه دولوپر

وابستگی‌ها

بدون وابستگی

نوع تعامل

یه نمایشگرِ وضعیته، نه کنترل. `status` رو می‌گیره و تصویر رو روی یه canvas با پشته‌ای از نسخه‌های بلوکی جلو می‌بره: هر پله کم‌وضوح‌تر از بعدیه و لبه‌ی بین دو پله با نوارهایی نرم می‌شه تا عبورِ جلو دیده شه. توی حالتِ خطا، دکمه‌ی «تلاش مجدد» (اگه `onRetry` داده شه) کوچیک و وسطِ قاب می‌نشینه.

پراپ‌ها

گزینه‌هایی که می‌تونی به کامپوننت بدی؛ ستاره‌دارها اجباری‌اند.

status
"queued" | "generating" | "refining" | "complete" | "error"پیش‌فرض: "generating"queued · generating · refining · complete · error

مرحله‌ی فعلی؛ مورییک رو تا نقطه‌ی متناظر جلو می‌بره.

children
ReactNode

تصویرِ محتوا. باید یه `<img>` با `src` باشه تا هرم ساخته شه.

aspectRatio
stringپیش‌فرض: "4 / 3"

نسبتِ ابعادِ قاب، به شکلِ CSS.

width
numberپیش‌فرض: 320

عرضِ قاب، پیکسل.

radius
numberپیش‌فرض: 16

گردیِ گوشه، پیکسل.

background
stringپیش‌فرض: "#27272a"

پس‌زمینه‌ی قاب و قرصِ وضعیت (قرص همون رو کدرشده روی تصویر می‌ریزه).

نصب

۱. این آدرس رو یک‌بار توی components.json بذار تا shadcn مخزن فارسی‌فای رو بشناسه.

components.jsonjson
{
  "registries": {
    "@farsify": "https://farsify.ir/r/{name}.json"
  }
}

۲. بعد با دستورِ زیر کامپوننت رو نصب کن.

npx shadcn@latest add @farsify/refine-frame

پیش‌نیاز: Tailwind CSS v4 و صفحهٔ راست‌به‌چپ dir="rtl".

نمونه

refine-frame.tsxtsx
"use client";

import RefineFrame from "@/components/farsify/refine-frame";

export function ImageResult() {
  const status = "generating"; // queued | generating | refining | complete | error

  return (
    <RefineFrame status={status} width={360} aspectRatio="4 / 3">
      <img src="/my-image.jpg" alt="نتیجه‌ی تولید" />
    </RefineFrame>
  );
}

// قابِ بزرگ‌تر، بدونِ قرصِ وضعیت، با متنِ دلخواه
<RefineFrame
  status="refining"
  width={480}
  showStatus={false}
  labels={{ refining: "در حال جزئیات" }}
>
  <img src="/hero.jpg" alt="" />
</RefineFrame>

// حالتِ خطا با دکمه‌ی تلاشِ مجدد
<RefineFrame status="error" onRetry={() => refetch()} retryLabel="دوباره بساز">
  <img src="/failed.jpg" alt="" />
</RefineFrame>

نکته‌ها

  • این کامپوننت هیچ‌وقت خودش وضعیت رو عوض نمی‌کنه — `status` رو تو می‌دی. اگه مقدارش رو از یه درخواستِ واقعی (مثلاً polling وضعیتِ تولیدِ تصویر) بگیری، دقیقاً همون چیزیه که براش ساخته شده.
  • فرزند باید یه `<img>` واقعی باشه: هرمِ مورییک از `naturalWidth`/`naturalHeight` تصویر ساخته می‌شه. یه div یا ویدیو کار نمی‌کنه.
  • ترتیبِ مراحل `queued → generating → refining → complete`ـه و هر پله توی `TARGET` سهمِ مشخصی از پشته داره؛ پریدن از `queued` به `complete` یه‌دفعه کلِ هرم رو می‌گذرونه، که موقعِ خطا و بازیابی هم مفیده.
  • توی `status="error"` تصویر با `opacity: 0.28` و بلور می‌نشینه تا محتوا دیده شه ولی صحنه‌ی «نشد» منتقل شه.
  • با `prefers-reduced-motion` پرش مستقیم انجام می‌شه (`rate = 1e9`) و نوار و درخشش خاموش می‌شن.

مجوز

کد بعد از نصب مالِ خودته؛ هر تغییری خواستی بده و توی پروژه‌ی خودت نگهش دار. برای پروژه‌های شخصی و تجاری آزاده، حتی اگه کدت بسته باشه. فقط اسم و لینک فارسی‌فای رو یه جا توی پروژه نگه دار.