{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "number-input",
  "type": "registry:ui",
  "title": "NumberInput",
  "description": "Conservative native numeric-entry primitive that defaults to text input semantics with decimal input mode and token-backed FormField-compatible styling.",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [
    "https://components.dethink.co.uk/r/dethink-base.json"
  ],
  "files": [
    {
      "path": "packages/components/src/components/number-input/number-input.tsx",
      "type": "registry:file",
      "target": "~/components/dethink/components/number-input/number-input.tsx",
      "content": "import { forwardRef, type InputHTMLAttributes } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\nexport type NumberInputControlSize = \"sm\" | \"md\" | \"lg\";\nexport type NumberInputMode = \"decimal\" | \"numeric\";\n\nexport interface NumberInputProps extends Omit<\n  InputHTMLAttributes<HTMLInputElement>,\n  \"inputMode\" | \"type\"\n> {\n  controlSize?: NumberInputControlSize;\n  invalid?: boolean;\n  numberMode?: NumberInputMode;\n  type?: \"text\" | \"number\";\n}\n\nconst numberInputBaseClasses =\n  \"w-full min-w-0 rounded-md border border-input bg-background text-foreground tabular-nums shadow-sm outline-none motion-safe:transition-[border-color,box-shadow,background-color] motion-safe:duration-[var(--dt-motion-fast)] motion-safe:ease-control placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-60 read-only:bg-muted/40 read-only:text-muted-foreground aria-[invalid=true]:border-destructive aria-[invalid=true]:ring-2 aria-[invalid=true]:ring-destructive/15 data-[invalid=true]:border-destructive data-[invalid=true]:ring-2 data-[invalid=true]:ring-destructive/15\";\n\nconst numberInputControlSizeClasses: Record<NumberInputControlSize, string> = {\n  sm: \"h-8 px-[var(--dt-space-2-5)] text-base sm:text-sm\",\n  md: \"h-density-control px-[var(--dt-space-3)] text-base sm:text-sm\",\n  lg: \"h-11 px-[var(--dt-space-4)] text-base\",\n};\n\nfunction isAriaInvalid(value: NumberInputProps[\"aria-invalid\"]) {\n  return (\n    value === true ||\n    value === \"true\" ||\n    value === \"grammar\" ||\n    value === \"spelling\"\n  );\n}\n\nexport function numberInputClassNames({\n  className,\n  controlSize = \"md\",\n}: Pick<NumberInputProps, \"className\" | \"controlSize\"> = {}) {\n  return cn(\n    numberInputBaseClasses,\n    numberInputControlSizeClasses[controlSize],\n    className,\n  );\n}\n\nexport const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(\n  (\n    {\n      \"aria-invalid\": ariaInvalid,\n      className,\n      controlSize = \"md\",\n      disabled,\n      invalid = false,\n      numberMode = \"decimal\",\n      readOnly,\n      required,\n      type = \"text\",\n      ...props\n    },\n    ref,\n  ) => {\n    const resolvedInvalid = invalid || isAriaInvalid(ariaInvalid);\n\n    return (\n      <input\n        data-slot=\"number-input\"\n        data-size={controlSize}\n        data-number-mode={numberMode}\n        data-disabled={disabled ? \"true\" : undefined}\n        data-invalid={resolvedInvalid ? \"true\" : undefined}\n        data-readonly={readOnly ? \"true\" : undefined}\n        data-required={required ? \"true\" : undefined}\n        {...props}\n        ref={ref}\n        aria-invalid={invalid ? true : ariaInvalid}\n        disabled={disabled}\n        inputMode={numberMode}\n        readOnly={readOnly}\n        required={required}\n        type={type}\n        className={numberInputClassNames({ className, controlSize })}\n      />\n    );\n  },\n);\n\nNumberInput.displayName = \"NumberInput\";\n"
    },
    {
      "path": "packages/components/src/components/number-input/index.ts",
      "type": "registry:file",
      "target": "~/components/dethink/components/number-input/index.ts",
      "content": "export {\n  NumberInput,\n  numberInputClassNames,\n  type NumberInputControlSize,\n  type NumberInputMode,\n  type NumberInputProps,\n} from \"./number-input\";\n"
    },
    {
      "path": "packages/components/src/utils/cn.ts",
      "type": "registry:file",
      "target": "~/components/dethink/utils/cn.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}\n"
    }
  ]
}
