{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "number-field",
  "title": "Number Field",
  "description": "A number-field component.",
  "dependencies": [
    "class-variance-authority",
    "@hugeicons/react",
    "@hugeicons/core-free-icons"
  ],
  "files": [
    {
      "path": "registry/default/number-field/number-field.tsx",
      "content": "\"use client\";\r\n\r\nimport { cva, type VariantProps } from \"class-variance-authority\";\r\nimport { NumberField as BaseNumberField } from \"@base-ui/react/number-field\";\r\nimport { HugeiconsIcon } from \"@hugeicons/react\";\r\nimport { ArrowDown01Icon, ArrowUp01Icon } from \"@hugeicons/core-free-icons\";\r\n\r\nimport { cn } from \"@/lib/utils\";\r\n\r\nconst numberFieldGroupVariants = cva(\r\n  [\r\n    \"flex rounded-lg\",\r\n    // Outline on the wrapper so focus/invalid rings wrap the full cluster, not just the input.\r\n    \"outline-0 outline-offset-0 outline-transparent transition-[outline-width,outline-offset,outline-color] duration-100 ease-out outline-solid\",\r\n    \"has-[[data-slot=number-field-input]:focus-visible]:outline-ring/50 has-[[data-slot=number-field-input]:focus-visible]:outline-2 has-[[data-slot=number-field-input]:focus-visible]:outline-offset-2\",\r\n    \"has-[[data-slot=number-field-input][aria-invalid=true]]:outline-destructive/50 has-[[data-slot=number-field-input][aria-invalid=true]]:outline-2 has-[[data-slot=number-field-input][aria-invalid=true]]:outline-offset-2\",\r\n    // With a stacked stepper (no decrement capping the left edge), the input\r\n    // rounds and borders its own left side automatically.\r\n    \"has-[[data-slot=number-field-stepper]]:[&>[data-slot=number-field-input]]:rounded-l-lg has-[[data-slot=number-field-stepper]]:[&>[data-slot=number-field-input]]:border-l\",\r\n  ],\r\n  {\r\n    variants: {\r\n      variant: {\r\n        // Opaque base: --outline-hover is a -5% darken, giving a sharp hover delta.\r\n        default:\r\n          \"[--number-field-bg:var(--input)] [--number-field-hover:var(--outline-hover)]\",\r\n        // Translucent base: --surface-hover is an alpha overlay, preserving translucency.\r\n        elevated:\r\n          \"[--number-field-bg:var(--input-elevated)] [--number-field-hover:var(--surface-hover)]\",\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: \"default\",\r\n    },\r\n  },\r\n);\r\n\r\nfunction NumberField({ className, ...props }: BaseNumberField.Root.Props) {\r\n  return (\r\n    <BaseNumberField.Root\r\n      data-slot=\"number-field\"\r\n      className={cn(\"flex flex-col items-start gap-1\", className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction NumberFieldGroup({\r\n  className,\r\n  variant,\r\n  ...props\r\n}: BaseNumberField.Group.Props &\r\n  VariantProps<typeof numberFieldGroupVariants>) {\r\n  return (\r\n    <BaseNumberField.Group\r\n      data-slot=\"number-field-group\"\r\n      className={cn(numberFieldGroupVariants({ variant }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction NumberFieldInput({\r\n  className,\r\n  ...props\r\n}: BaseNumberField.Input.Props) {\r\n  return (\r\n    <BaseNumberField.Input\r\n      data-slot=\"number-field-input\"\r\n      className={cn(\r\n        \"placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground\",\r\n        // border-y only — left/right edges come from the adjacent buttons, fusing into one cluster.\r\n        \"border-y bg-(--number-field-bg) bg-clip-padding\",\r\n        \"h-10 w-24 text-center text-base font-normal tabular-nums transition-colors duration-200 outline-none sm:h-9 md:text-sm\",\r\n        \"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-60\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction NumberFieldIncrement({\r\n  className,\r\n  ...props\r\n}: BaseNumberField.Increment.Props) {\r\n  return (\r\n    <BaseNumberField.Increment\r\n      data-slot=\"number-field-increment\"\r\n      className={cn(\r\n        // No left border — fuses seamlessly with the input's right edge.\r\n        \"rounded-r-lg border-y border-r bg-(--number-field-bg) bg-clip-padding\",\r\n        \"hover:bg-(--number-field-hover)\",\r\n        \"flex size-10 items-center justify-center select-none sm:size-9\",\r\n        \"disabled:pointer-events-none disabled:opacity-60\",\r\n        \"focus-visible:outline-ring/50 outline-0 outline-offset-0 outline-transparent transition-[outline-width,outline-offset,outline-color,scale] duration-100 ease-out outline-solid focus-visible:outline-2 focus-visible:outline-offset-2\",\r\n        \"origin-left active:scale-[0.98]\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction NumberFieldDecrement({\r\n  className,\r\n  ...props\r\n}: BaseNumberField.Decrement.Props) {\r\n  return (\r\n    <BaseNumberField.Decrement\r\n      data-slot=\"number-field-decrement\"\r\n      className={cn(\r\n        // No right border — fuses seamlessly with the input's left edge.\r\n        \"rounded-l-lg border-y border-l bg-(--number-field-bg) bg-clip-padding\",\r\n        \"hover:bg-(--number-field-hover)\",\r\n        \"flex size-10 items-center justify-center select-none sm:size-9\",\r\n        \"disabled:pointer-events-none disabled:opacity-60\",\r\n        \"focus-visible:outline-ring/50 outline-0 outline-offset-0 outline-transparent transition-[outline-width,outline-offset,outline-color,scale] duration-100 ease-out outline-solid focus-visible:outline-2 focus-visible:outline-offset-2\",\r\n        \"origin-right active:scale-[0.98]\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\n// Vertically-stacked increment (top) / decrement (bottom) cluster for the\r\n// right edge of the group — the styled equivalent of a native number spinner.\r\n// The group detects it and rounds/borders the input's left edge automatically.\r\nfunction NumberFieldStepper({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<\"div\">) {\r\n  const stepClassName = cn(\r\n    \"hover:bg-(--number-field-hover) flex flex-1 items-center justify-center px-2 select-none\",\r\n    \"focus-visible:outline-ring/50 outline-0 outline-offset-0 outline-transparent transition-[outline-width,outline-offset,outline-color] duration-100 ease-out outline-solid focus-visible:outline-2 focus-visible:-outline-offset-2\",\r\n    \"disabled:pointer-events-none disabled:opacity-60\",\r\n  );\r\n\r\n  return (\r\n    <div\r\n      data-slot=\"number-field-stepper\"\r\n      className={cn(\r\n        // `border` (all four sides): the left edge is the divider against the input.\r\n        \"flex flex-col self-stretch overflow-hidden rounded-r-lg border bg-(--number-field-bg) bg-clip-padding\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <BaseNumberField.Increment\r\n        data-slot=\"number-field-increment\"\r\n        className={cn(stepClassName, \"border-b\")}\r\n        aria-label=\"Increase\"\r\n      >\r\n        <HugeiconsIcon\r\n          icon={ArrowUp01Icon}\r\n          className=\"size-3.5\"\r\n          strokeWidth={2}\r\n        />\r\n      </BaseNumberField.Increment>\r\n      <BaseNumberField.Decrement\r\n        data-slot=\"number-field-decrement\"\r\n        className={stepClassName}\r\n        aria-label=\"Decrease\"\r\n      >\r\n        <HugeiconsIcon\r\n          icon={ArrowDown01Icon}\r\n          className=\"size-3.5\"\r\n          strokeWidth={2}\r\n        />\r\n      </BaseNumberField.Decrement>\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction NumberFieldScrubArea({\r\n  className,\r\n  ...props\r\n}: BaseNumberField.ScrubArea.Props) {\r\n  return (\r\n    <BaseNumberField.ScrubArea\r\n      data-slot=\"number-field-scrub-area\"\r\n      className={cn(\"cursor-ew-resize select-none\", className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction NumberFieldScrubAreaCursor({\r\n  className,\r\n  ...props\r\n}: BaseNumberField.ScrubAreaCursor.Props) {\r\n  return (\r\n    <BaseNumberField.ScrubAreaCursor\r\n      data-slot=\"number-field-scrub-area-cursor\"\r\n      className={cn(\r\n        \"drop-shadow-[0_1px_1px_oklch(0_0_0/0.53)] filter\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  NumberField,\r\n  NumberFieldGroup,\r\n  NumberFieldInput,\r\n  NumberFieldIncrement,\r\n  NumberFieldDecrement,\r\n  NumberFieldStepper,\r\n  NumberFieldScrubArea,\r\n  NumberFieldScrubAreaCursor,\r\n};\r\n",
      "type": "registry:ui",
      "target": "components/ui/cubby-ui/number-field.tsx"
    }
  ],
  "type": "registry:ui"
}