{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"amount-input","type":"registry:ui","title":"Amount Input","description":"Controlled decimal string input for token amounts. Preserves precision and incomplete edits, with an optional fractional digit limit.","dependencies":[],"devDependencies":[],"registryDependencies":["input"],"files":[{"path":"registry/onchain-ui/amount-input.tsx","type":"registry:ui","target":"components/ui/amount-input.tsx","content":"\"use client\";\n\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { Input } from \"@/components/ui/input\";\n\nexport interface AmountInputProps\n  extends Omit<\n    ComponentProps<\"input\">,\n    \"type\" | \"inputMode\" | \"value\" | \"defaultValue\" | \"onChange\" | \"min\" | \"max\" | \"step\"\n  > {\n  /** Unformatted decimal string. Empty and incomplete values are valid while editing. */\n  value: string;\n  /** Receives accepted edits without numeric conversion or rounding. */\n  onValueChange?: (value: string) => void;\n  /** Maximum fractional digits. Omit for unrestricted precision; 0 allows integers only. */\n  decimals?: number;\n}\n\n/** Checks editing syntax, not whether an amount is ready for a transaction. */\nexport function isAmountInputValue(value: string, decimals?: number): boolean {\n  if (decimals !== undefined && (!Number.isInteger(decimals) || decimals < 0)) {\n    return false;\n  }\n  if (!/^[0-9]*(\\.[0-9]*)?$/.test(value)) return false;\n  const point = value.indexOf(\".\");\n  return point === -1 || decimals === undefined ||\n    (decimals > 0 && value.length - point - 1 <= decimals);\n}\n\nexport function AmountInput({\n  value,\n  onValueChange,\n  decimals,\n  readOnly = !onValueChange,\n  disabled,\n  className,\n  placeholder = \"0\",\n  ...props\n}: AmountInputProps) {\n  return (\n    <Input\n      autoComplete=\"off\"\n      spellCheck={false}\n      size={1}\n      {...props}\n      data-slot=\"amount-input\"\n      type=\"text\"\n      inputMode=\"decimal\"\n      value={value}\n      placeholder={placeholder}\n      readOnly={readOnly}\n      disabled={disabled}\n      onChange={(event) => {\n        const next = event.target.value;\n        if (!disabled && !readOnly && isAmountInputValue(next, decimals)) {\n          onValueChange?.(next);\n        }\n      }}\n      className={cn(\n        \"font-mono tabular-nums\",\n        className\n      )}\n    />\n  );\n}\n"}]}