{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "rating",
  "type": "registry:ui",
  "title": "Rating",
  "description": "امتیاز ستاره‌ای؛ قابل‌انتخاب با رادیوهای بومی (←→) یا فقط‌خواندنی",
  "dependencies": [
    "@kashi-ui/persian@^1.8.0"
  ],
  "registryDependencies": [
    "https://kashi.sepantapouya.com/r/cx.json",
    "https://kashi.sepantapouya.com/r/kashi-provider.json"
  ],
  "files": [
    {
      "path": "registry/kashi/Rating.tsx",
      "type": "registry:ui",
      "target": "components/kashi/Rating.tsx",
      "content": "\"use client\";\n\nimport { useId, useState } from \"react\";\nimport { toFaDigits } from \"@kashi-ui/persian\";\nimport { cx } from \"./cx\";\nimport { useKashi } from \"./KashiProvider\";\n\nexport interface RatingProps {\n  value?: number;\n  defaultValue?: number;\n  onChange?: (value: number) => void;\n  /** @default 5 */\n  max?: number;\n  /** فقط نمایش؛ مقدار اعشاری مثل ۴٫۵ نیم‌ستاره نشان می‌دهد */\n  readOnly?: boolean;\n  /** نمایش عدد کنار ستاره‌ها */\n  showValue?: boolean;\n  /** @default \"md\" */\n  size?: \"sm\" | \"md\" | \"lg\";\n  /** @default \"امتیاز\" */\n  label?: string;\n  name?: string;\n  disabled?: boolean;\n  className?: string;\n  /** نام هر ستاره برای صفحه‌خوان @default (n, max) => «n از max» */\n  starLabel?: (n: number, max: number) => string;\n}\n\nconst Star = () => (\n  <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n    <path fill=\"currentColor\" d=\"M12 2.8l2.8 5.9 6.4.8-4.7 4.4 1.2 6.3L12 17.1l-5.7 3.1 1.2-6.3L2.8 9.5l6.4-.8z\" />\n    {/* نیمهٔ ابتدایی ستاره برای امتیاز اعشاری؛ در RTL سمت راست */}\n    <path className=\"k-rating__half\" fill=\"none\" d=\"M12 2.8v14.3l-5.7 3.1 1.2-6.3L2.8 9.5l6.4-.8z\" />\n  </svg>\n);\n\n\n/** امتیاز ستاره‌ای؛ قابل‌انتخاب با رادیوهای بومی (←→) یا فقط‌خواندنی */\nexport function Rating({\n  value, defaultValue = 0, onChange, max = 5, readOnly, showValue, size = \"md\", label, name, disabled, className,\n  starLabel,\n}: RatingProps) {\n  const { messages: M, n: N } = useKashi();\n  const fa = (x: number) => N(x).replace(\".\", M.common.decimal);\n  label ??= M.rating.label;\n  starLabel ??= (a: number, b: number) => M.common.of(fa(a), fa(b));\n  const id = useId();\n  const [inner, setInner] = useState(defaultValue);\n  const [hover, setHover] = useState<number | null>(null);\n  const current = value ?? inner;\n  const shown = hover ?? current;\n  const stars = Array.from({ length: max }, (_, i) => i + 1);\n  const cls = cx(\"k-rating\", size !== \"md\" && `k-rating--${size}`, className);\n\n  if (readOnly) {\n    return (\n      <span className={cls} data-readonly=\"\" role=\"img\" aria-label={`${label}: ${starLabel(current, max)}`}>\n        {stars.map((n) => (\n          <span key={n} className=\"k-rating__star\" data-filled={n <= Math.floor(current) ? \"\" : undefined} data-half={n === Math.ceil(current) && current % 1 >= 0.25 ? \"\" : undefined}>\n            <Star />\n          </span>\n        ))}\n        {showValue && <span className=\"k-rating__value\" aria-hidden=\"true\">{fa(current)}</span>}\n      </span>\n    );\n  }\n\n  return (\n    <fieldset className={cls} onPointerLeave={() => setHover(null)}>\n      <legend className=\"k-sr-only\">{label}</legend>\n      {stars.map((n) => (\n        <label key={n} className=\"k-rating__star\" data-filled={n <= shown ? \"\" : undefined} onPointerEnter={() => !disabled && setHover(n)}>\n          <input\n            type=\"radio\"\n            className=\"k-sr-only\"\n            name={name ?? id}\n            value={n}\n            checked={current === n}\n            disabled={disabled}\n            aria-label={starLabel(n, max)}\n            onChange={() => {\n              if (value === undefined) setInner(n);\n              onChange?.(n);\n            }}\n          />\n          <Star />\n        </label>\n      ))}\n      {showValue && <span className=\"k-rating__value\" aria-hidden=\"true\">{fa(current)}</span>}\n    </fieldset>\n  );\n}\n"
    }
  ]
}