{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "price-input",
  "type": "registry:ui",
  "title": "PriceInput",
  "description": "فیلد مبلغ: جداکنندهٔ هزارگان، واحد پول و نمایش مبلغ به حروف برای اطمینان کاربر",
  "dependencies": [
    "@kashi-ui/persian@^1.8.0"
  ],
  "registryDependencies": [
    "https://kashi.sepantapouya.com/r/cx.json",
    "https://kashi.sepantapouya.com/r/input.json",
    "https://kashi.sepantapouya.com/r/kashi-provider.json",
    "https://kashi.sepantapouya.com/r/use-digits-input.json",
    "https://kashi.sepantapouya.com/r/utils.json"
  ],
  "files": [
    {
      "path": "registry/kashi/PriceInput.tsx",
      "type": "registry:ui",
      "target": "components/kashi/PriceInput.tsx",
      "content": "\"use client\";\n\nimport { forwardRef, useState, type ReactNode } from \"react\";\nimport { formatNumber, numberToWords, toFaDigits } from \"@kashi-ui/persian\";\nimport { Input, type InputProps } from \"./Input\";\nimport { useDigitsInput } from \"./useDigitsInput\";\nimport { mergeRefs } from \"./utils\";\nimport { useKashi } from \"./KashiProvider\";\n\ntype Base = Omit<InputProps, \"value\" | \"defaultValue\" | \"onChange\" | \"type\" | \"inputMode\" | \"addonEnd\" | \"min\" | \"max\">;\n\nexport interface PriceInputProps extends Base {\n  value?: number | null;\n  defaultValue?: number | null;\n  onValueChange?: (value: number | null) => void;\n  /** واحد پول کنار فیلد @default \"تومان\" */\n  unit?: ReactNode;\n  /** نمایش مبلغ به حروف زیر فیلد @default true */\n  showWords?: boolean;\n  /** @default \"fa\" */\n  digits?: \"fa\" | \"latin\";\n  min?: number;\n  max?: number;\n  /** پیام خطای بیرون از محدوده */\n  rangeMessage?: (min?: number, max?: number) => ReactNode;\n}\n\nconst toRaw = (n?: number | null) => (n === null || n === undefined ? undefined : String(Math.trunc(Math.abs(n))));\n\n/** فیلد مبلغ: جداکنندهٔ هزارگان، واحد پول و نمایش مبلغ به حروف برای اطمینان کاربر */\nexport const PriceInput = forwardRef<HTMLInputElement, PriceInputProps>(function PriceInput(\n  {\n    value, defaultValue, onValueChange, unit, showWords = true, digits, min, max,\n    rangeMessage,\n    error, hint, name, onBlur, placeholder, ...rest\n  },\n  ref,\n) {\n  const { messages: M, digits: D, locale } = useKashi();\n  digits ??= D;\n  unit ??= M.money.toman;\n  const money = (v: number) => (digits === \"fa\" ? toFaDigits(formatNumber(v)) : formatNumber(v, { digits: \"latin\" }));\n  rangeMessage ??= (lo, hi) => (lo !== undefined && hi !== undefined ? M.invalid.priceRange(money(lo), money(hi)) : lo !== undefined ? M.invalid.priceMin(money(lo)) : M.invalid.priceMax(money(hi!)));\n  const [touched, setTouched] = useState(false);\n  const { raw, shown, inputRef, handleChange } = useDigitsInput({\n    value: value === undefined ? undefined : (toRaw(value) ?? \"\"),\n    defaultValue: toRaw(defaultValue),\n    maxDigits: 15,\n    normalize: (d) => d.replace(/^0+(?=\\d)/, \"\"),\n    format: (d) => (d ? formatNumber(d, { digits: \"latin\" }).replace(/,/g, digits === \"fa\" ? \"٬\" : \",\") : \"\"),\n    digits,\n  });\n  const n = raw ? Number(raw) : null;\n  const outOfRange = n !== null && ((min !== undefined && n < min) || (max !== undefined && n > max));\n  const words = showWords && n !== null ? `${numberToWords(n, { locale })}${typeof unit === \"string\" ? ` ${unit}` : \"\"}` : null;\n\n  return (\n    <>\n      <Input\n        ref={mergeRefs(ref, inputRef)}\n        type=\"text\"\n        inputMode=\"numeric\"\n        autoComplete=\"off\"\n        dir=\"ltr\"\n        placeholder={placeholder ?? (digits === \"fa\" ? \"۰\" : \"0\")}\n        value={shown}\n        onChange={(e) => {\n          const next = handleChange(e);\n          onValueChange?.(next ? Number(next) : null);\n        }}\n        onBlur={(e) => {\n          setTouched(true);\n          onBlur?.(e);\n        }}\n        addonEnd={unit ? <span className=\"k-input__meta\">{unit}</span> : undefined}\n        hint={words ?? hint}\n        error={error ?? (touched && outOfRange ? rangeMessage(min, max) : undefined)}\n        {...rest}\n      />\n      {name && <input type=\"hidden\" name={name} value={raw} />}\n    </>\n  );\n});\n"
    }
  ]
}