{"$schema":"https://ui.shadcn.com/schema/registry-item.json","author":"Eduardo Calvo <edu@smoothui.dev>","css":{},"dependencies":["@base-ui/react"],"description":"Number Field for SmoothUI with steppers, Base UI twin and Radix-parity twin.","devDependencies":[],"files":[{"content":"\"use client\";\n\nimport { NumberField as NumberFieldPrimitive } from \"@base-ui/react/number-field\";\nimport { cn } from \"@/lib/utils\";\nimport type { ComponentProps, ReactNode, SVGProps } from \"react\";\nimport { useId } from \"react\";\n\nexport interface NumberFieldProps {\n  /** Accessible name when there is no visible `label` */\n  \"aria-label\"?: string;\n  /** Optional CSS class for the root */\n  className?: string;\n  /** Uncontrolled initial value */\n  defaultValue?: number;\n  /** Disable the field */\n  disabled?: boolean;\n  /** Visible label (also enables scrub on the label) */\n  label?: string;\n  /** Maximum value */\n  max?: number;\n  /** Minimum value */\n  min?: number;\n  /** Form name */\n  name?: string;\n  /** Called when the numeric value changes */\n  onValueChange?: (value: number | null) => void;\n  /** Step increment */\n  step?: number;\n  /** Controlled value */\n  value?: number | null;\n}\n\nexport type NumberFieldRootProps = Omit<\n  ComponentProps<typeof NumberFieldPrimitive.Root>,\n  \"className\"\n> & { className?: string };\nexport type NumberFieldGroupProps = Omit<\n  ComponentProps<typeof NumberFieldPrimitive.Group>,\n  \"className\"\n> & { className?: string };\nexport type NumberFieldInputProps = Omit<\n  ComponentProps<typeof NumberFieldPrimitive.Input>,\n  \"className\"\n> & { className?: string };\nexport type NumberFieldIncrementProps = Omit<\n  ComponentProps<typeof NumberFieldPrimitive.Increment>,\n  \"className\"\n> & { className?: string; children?: ReactNode };\nexport type NumberFieldDecrementProps = Omit<\n  ComponentProps<typeof NumberFieldPrimitive.Decrement>,\n  \"className\"\n> & { className?: string; children?: ReactNode };\nexport type NumberFieldScrubAreaProps = Omit<\n  ComponentProps<typeof NumberFieldPrimitive.ScrubArea>,\n  \"className\"\n> & { className?: string };\n\nconst STEPPER_CLASS =\n  \"flex size-8 shrink-0 items-center justify-center border border-foreground/25 bg-background text-foreground outline-none state-transition hover:bg-muted focus-visible:z-10 focus-ring disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50\";\n\nconst INPUT_CLASS =\n  \"h-8 w-[7ch] min-w-0 border border-foreground/25 bg-background px-2 text-center font-medium text-base md:text-sm tabular-nums outline-none state-transition focus-visible:z-10 focus-visible:border-ring focus-ring disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground\";\n\nconst MinusIcon = (props: SVGProps<SVGSVGElement>) => (\n  <svg\n    fill=\"none\"\n    height=\"14\"\n    stroke=\"currentColor\"\n    strokeLinecap=\"round\"\n    strokeWidth=\"2\"\n    aria-hidden=\"true\"\n    focusable=\"false\"\n    viewBox=\"0 0 16 16\"\n    width=\"14\"\n    {...props}\n  >\n    <path d=\"M3 8h10\" />\n  </svg>\n);\n\nconst PlusIcon = (props: SVGProps<SVGSVGElement>) => (\n  <svg\n    fill=\"none\"\n    height=\"14\"\n    stroke=\"currentColor\"\n    strokeLinecap=\"round\"\n    strokeWidth=\"2\"\n    aria-hidden=\"true\"\n    focusable=\"false\"\n    viewBox=\"0 0 16 16\"\n    width=\"14\"\n    {...props}\n  >\n    <path d=\"M8 3v10M3 8h10\" />\n  </svg>\n);\n\nexport const NumberFieldRoot = ({\n  className,\n  ...props\n}: NumberFieldRootProps) => (\n  <NumberFieldPrimitive.Root\n    className={cn(\"flex flex-col items-start gap-1.5\", className)}\n    data-slot=\"number-field\"\n    {...props}\n  />\n);\n\nexport const NumberFieldGroup = ({\n  className,\n  ...props\n}: NumberFieldGroupProps) => (\n  <NumberFieldPrimitive.Group\n    className={cn(\"flex h-8 items-stretch\", className)}\n    data-slot=\"number-field-group\"\n    {...props}\n  />\n);\n\nexport const NumberFieldInput = ({\n  className,\n  ...props\n}: NumberFieldInputProps) => (\n  <NumberFieldPrimitive.Input\n    className={cn(INPUT_CLASS, className)}\n    data-slot=\"number-field-input\"\n    {...props}\n  />\n);\n\nexport const NumberFieldDecrement = ({\n  children,\n  className,\n  ...props\n}: NumberFieldDecrementProps) => (\n  <NumberFieldPrimitive.Decrement\n    aria-label=\"Decrement\"\n    className={cn(STEPPER_CLASS, \"rounded-l-md border-r-0\", className)}\n    data-slot=\"number-field-decrement\"\n    {...props}\n  >\n    {children ?? <MinusIcon />}\n  </NumberFieldPrimitive.Decrement>\n);\n\nexport const NumberFieldIncrement = ({\n  children,\n  className,\n  ...props\n}: NumberFieldIncrementProps) => (\n  <NumberFieldPrimitive.Increment\n    aria-label=\"Increment\"\n    className={cn(STEPPER_CLASS, \"rounded-r-md border-l-0\", className)}\n    data-slot=\"number-field-increment\"\n    {...props}\n  >\n    {children ?? <PlusIcon />}\n  </NumberFieldPrimitive.Increment>\n);\n\nexport const NumberFieldScrubArea = ({\n  className,\n  ...props\n}: NumberFieldScrubAreaProps) => (\n  <NumberFieldPrimitive.ScrubArea\n    className={cn(\"cursor-ew-resize select-none\", className)}\n    data-slot=\"number-field-scrub-area\"\n    {...props}\n  />\n);\n\n/**\n * SmoothUI Number Field — Base UI twin (default).\n * Convenience API with label + steppers; use compounds for custom layouts.\n */\nexport default function NumberField({\n  \"aria-label\": ariaLabel,\n  className,\n  defaultValue,\n  disabled,\n  label,\n  max,\n  min,\n  name,\n  onValueChange,\n  step,\n  value,\n}: NumberFieldProps) {\n  const id = useId();\n\n  return (\n    <NumberFieldRoot\n      className={className}\n      defaultValue={defaultValue}\n      disabled={disabled}\n      id={id}\n      max={max}\n      min={min}\n      name={name}\n      onValueChange={(next) => {\n        onValueChange?.(next);\n      }}\n      step={step}\n      value={value}\n    >\n      {label ? (\n        <NumberFieldScrubArea>\n          <label\n            className=\"cursor-ew-resize font-medium text-sm leading-none\"\n            htmlFor={id}\n          >\n            {label}\n          </label>\n        </NumberFieldScrubArea>\n      ) : null}\n      <NumberFieldGroup>\n        <NumberFieldDecrement />\n        <NumberFieldInput aria-label={label ? undefined : ariaLabel} />\n        <NumberFieldIncrement />\n      </NumberFieldGroup>\n    </NumberFieldRoot>\n  );\n}\n","path":"index.tsx","target":"components/smoothui/number-field/index.tsx","type":"registry:ui"}],"name":"number-field","registryDependencies":["https://smoothui.dev/r/tokens.json"],"title":"Number Field","type":"registry:ui"}