کاستومایز
ستارههای امتیازPeek Rating
ردیفِ ستارهای که ستارهی زیرِ نشانگر بالا میآد و بزرگ میشه و حبابی برچسبِ همون پله رو نشون میده؛ کلیک ثبت میکنه و کلیکِ دوباره پاک.
وابستگیها
نوع تعامل
نشانگر رو روی ردیف ببر تا ستارهی زیرش بالا بیاد و حباب برچسبِ اون پله رو نشون بده. با فشردن و کشیدنِ افقی مقدار پیشنمایش میگیره و موقعِ رهاکردن همون دمی ثبت میشه؛ روی لمس، کشیدنِ عمودی صفحه رو اسکرول میکنه و انتخاب فقط با فشارِ افقی رخ میده. با کلیکِ دوباره روی ستارهی فعلی مقدار صفر میشه. کلیدهای جهت، Home/End، Space/Enter و Backspace/Delete هم کار میکنن.
پراپها
گزینههایی که میتونی به کامپوننت بدی؛ ستارهدارها اجباریاند.
valuenumberحالتِ controlled؛ اگه بدی مالکیتِ مقدار با توئه.
defaultValuenumberپیشفرض: 0مقدارِ اولیه توی حالتِ uncontrolled.
onChange(value: number) => voidبا هر ثبت صدا زده میشه؛ صفر یعنی پاکشده.
onPreview(value: number | null) => voidبا هر جابهجاییِ نشانگر پلهی زیرِ اون رو میده؛ خروج `null`.
countnumberپیشفرض: 5شمارِ ستارهها.
shape"star" | "heart" | "bolt"پیشفرض: "star"star · heart · boltگلیفِ آماده.
نصب
۱. این آدرس رو یکبار توی components.json بذار تا shadcn مخزن فارسیفای رو بشناسه.
{
"registries": {
"@farsify": "https://farsify.ir/r/{name}.json"
}
}۲. بعد با دستورِ زیر کامپوننت رو نصب کن.
npx shadcn@latest add @farsify/peek-ratingپیشنیاز: Tailwind CSS v4 و صفحهٔ راستبهچپ dir="rtl".
نمونه
"use client";
import { useState } from "react";
import { PeekRating } from "@/components/farsify/peek-rating";
const LABELS = ["ضعیف", "نسبتاً خوب", "خوب", "خیلی خوب", "عالی"];
export function ProductScore() {
const [score, setScore] = useState(0);
return (
<div className="flex flex-col items-center gap-3">
<PeekRating
value={score}
onChange={setScore}
labels={LABELS}
size={36}
/>
{/* برچسبِ کنارِ فرم از onPreview میآید و با خروجِ نشانگر
به مقدارِ ثبتشده برمیگردد */}
<span className="text-sm">{LABELS[score - 1] ?? "امتیازی ندادهاید"}</span>
</div>
);
}
// بدون کنترل — مقدارِ اولیهی ۳ از ۵
<PeekRating defaultValue={3} labels={LABELS} />
// فقط نمایش: ستارهها دکمه نیستند و ریشه نقشِ img میگیرد
<PeekRating value={4} readOnly ariaLabel="امتیازِ این محصول" />
// قلبِ صورتی، ده پله، بدونِ حبابِ راهنما
<PeekRating
shape="heart"
count={10}
activeColor="#e5484d"
showTip={false}
lift={9}
magnify={1.25}
/>نکتهها
- برای فرمِ امتیازدهی، `onChange` رو به state وصل کن و `defaultValue` بده؛ برای نمایشِ امتیازِ ثبتشده فقط `readOnly` با `value` بذار — توی اون حالت ستارهها دکمه نیستن و ریشه یه تصویرِ قابلِ خواندن میشه («۳ از ۵»).
- `onPreview` برای چیزیه که صفحهخوان یا برچسبِ کنارِ فرم لازم داره؛ با خروجِ نشانگر `null` میگیره، پس میتونی متنِ کمکی رو همون لحظه به مقدارِ ثبتشده برگردونی.
- برچسبها **فارسی** بده و تعدادشون رو دستِکم برابرِ `count` بگیر: متنِ حباب از `labels` میآد و نامِ دسترسپذیرِ هر ستاره «۲ از ۵، نسبتاً خوب» میشه. اگه ندی، فقط رقمِ فارسیِ پله نشون داده میشه.
- این پورت راستبهچپ نمیشه چون لازم نیست: خودِ مرجع آینهسازی رو توی JS انجام میده (هم اندیسِ ستاره و هم جای حباب)، پس توی فارسی ستارهی اول از سمتِ راست شروع میشه و همهچیز سرِ جاشه.
- گلیفها درونخطیان و از `@hugeicons/core-free-icons` کپی شدن تا وابستگیِ UI بیرونی اضافه نشه؛ `fill="currentColor"` دارن، پس گلیف توپُر میآد و رنگ رو از `activeColor`/`idleColor` میگیره.
- با `prefers-reduced-motion` برخاستن و بزرگنمایی کامل حذف میشن ولی رنگِ پیشنمایش سرِ جاش میمونه — بازخورد از دست نمیره، فقط حرکتش کم میشه.
مجوز
کد بعد از نصب مالِ خودته؛ هر تغییری خواستی بده و توی پروژهی خودت نگهش دار. برای پروژههای شخصی و تجاری آزاده، حتی اگه کدت بسته باشه. فقط اسم و لینک فارسیفای رو یه جا توی پروژه نگه دار.