{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "number-input",
  "title": "Number Input",
  "description": "Digits roll up or down as the value changes, and the buttons press in.",
  "dependencies": [
    "@ui-sdk/core@0.1.0-beta.2",
    "@ui-sdk/react@0.1.0-beta.2"
  ],
  "registryDependencies": [
    "@keyframery/motion"
  ],
  "files": [
    {
      "path": "registry/components/keyframery/primitives/number-input.tsx",
      "content": "\"use client\"\n\n/* Animated drop-in for `@ui-sdk/react/number-input`: same parts, same props. Swap the import and keep\n   your code. This file adds motion only. Colours, radii, shadows and spacing stay yours. */\n\nimport {\n  NumberInputControl as NumberInputControlPart,\n  NumberInputDecrement as NumberInputDecrementPart,\n  NumberInputGroup as NumberInputGroupPart,\n  NumberInputIncrement as NumberInputIncrementPart,\n} from \"@ui-sdk/react/number-input\"\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport * from \"@ui-sdk/react/number-input\"\n\n/* The group is usually the field's box: its focus ring is the outline, which closes in from\n   10px out on a spring, easing from its resting colour to its focus colour. Give it width and colour with `has-[input:focus-visible]:outline-…`. */\nfunction NumberInputGroup({ className, ...props }: React.ComponentProps<typeof NumberInputGroupPart>) {\n  return (\n    <NumberInputGroupPart\n      className={cn(\n        \"outline-offset-[10px] has-[input:focus-visible]:outline-offset-0 data-scrubbing:outline-offset-0\",\n        \"[transition:outline-offset_calc(160ms*var(--kf-speed,1))_var(--ease-house),outline-width_calc(160ms*var(--kf-speed,1))_var(--ease-house),outline-color_0s_linear_calc(160ms*var(--kf-speed,1)),box-shadow_calc(150ms*var(--kf-speed,1))_var(--ease-house),background-color_calc(150ms*var(--kf-speed,1))_var(--ease-house)] has-[input:focus-visible]:[transition:outline-offset_calc(900ms*var(--kf-speed,1))_var(--ease-spring),outline-width_calc(900ms*var(--kf-speed,1))_var(--ease-spring),outline-color_calc(700ms*var(--kf-speed,1))_var(--ease-house),box-shadow_calc(150ms*var(--kf-speed,1))_var(--ease-house),background-color_calc(150ms*var(--kf-speed,1))_var(--ease-house)] data-scrubbing:[transition:outline-offset_calc(900ms*var(--kf-speed,1))_var(--ease-spring),outline-width_calc(900ms*var(--kf-speed,1))_var(--ease-spring),outline-color_calc(700ms*var(--kf-speed,1))_var(--ease-house),box-shadow_calc(150ms*var(--kf-speed,1))_var(--ease-house),background-color_calc(150ms*var(--kf-speed,1))_var(--ease-house)]\",\n        \"motion-reduce:[transition:none]!\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* While a stepper is held, the value leans 3px toward it, and springs back on release. */\nfunction NumberInputControl({\n  className,\n  ...props\n}: React.ComponentProps<typeof NumberInputControlPart>) {\n  return (\n    <NumberInputControlPart\n      className={cn(\n        \"transition-[translate] duration-[calc(300ms*var(--kf-speed,1))] ease-pop motion-reduce:transition-none!\",\n        \"in-[[data-slot=number-input-group]:has([data-slot=number-input-increment]:not([data-disabled]):active)]:translate-x-[3px]\",\n        \"in-[[data-slot=number-input-group]:has([data-slot=number-input-decrement]:not([data-disabled]):active)]:-translate-x-[3px]\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* Steppers press deep and spring back with a pop. */\nconst stepperMotion =\n  \"[transition:scale_calc(280ms*var(--kf-speed,1))_var(--ease-pop),translate_calc(280ms*var(--kf-speed,1))_var(--ease-pop),box-shadow_calc(120ms*var(--kf-speed,1))_var(--ease-house),background-color_calc(120ms*var(--kf-speed,1))_var(--ease-house),color_calc(120ms*var(--kf-speed,1))_var(--ease-house),opacity_calc(120ms*var(--kf-speed,1))_var(--ease-house)] \" +\n  \"active:scale-[0.84] data-disabled:active:scale-100 motion-reduce:[transition:none]!\"\n\nfunction NumberInputDecrement({\n  className,\n  ...props\n}: React.ComponentProps<typeof NumberInputDecrementPart>) {\n  return <NumberInputDecrementPart className={cn(stepperMotion, className)} {...props} />\n}\n\nfunction NumberInputIncrement({\n  className,\n  ...props\n}: React.ComponentProps<typeof NumberInputIncrementPart>) {\n  return <NumberInputIncrementPart className={cn(stepperMotion, className)} {...props} />\n}\n\nexport { NumberInputControl, NumberInputDecrement, NumberInputGroup, NumberInputIncrement }\n",
      "type": "registry:component",
      "target": "components/keyframery/primitives/number-input.tsx"
    },
    {
      "path": "registry/components/keyframery/number-input.tsx",
      "content": "\"use client\"\n\n/* Styled number input: the animated primitive plus the Keyframery look. */\n\nimport * as React from \"react\"\n\nimport {\n  NumberInput as NumberInputRoot,\n  NumberInputControl as NumberInputControlPrimitive,\n  NumberInputDecrement as NumberInputDecrementPrimitive,\n  NumberInputGroup as NumberInputGroupPrimitive,\n  NumberInputIncrement as NumberInputIncrementPrimitive,\n  NumberInputScrubArea as NumberInputScrubAreaPart,\n  NumberInputScrubAreaCursor as NumberInputScrubAreaCursorPart,\n  createNumberInputController,\n} from \"@/components/keyframery/primitives/number-input\"\nimport { cn } from \"@/lib/utils\"\n\nfunction NumberInput({ className, ...props }: React.ComponentProps<typeof NumberInputRoot>) {\n  return <NumberInputRoot className={cn(\"flex min-w-0 flex-col gap-1.5\", className)} {...props} />\n}\n\n/* The group is the field: two keys with the value between them. */\nfunction NumberInputGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof NumberInputGroupPrimitive>) {\n  return (\n    <NumberInputGroupPrimitive\n      className={cn(\n        \"flex h-9 w-full min-w-0 items-center gap-1 rounded-[10px] bg-background p-1 text-[13px]\",\n        \"outline-0 outline-ring\",\n        \"[--field-line:rgb(0_0_0/0.09)] dark:[--field-line:rgb(255_255_255/0.1)]\",\n        \"shadow-[0_0_0_1px_var(--field-line),0_1px_2px_rgb(0_0_0/0.05)] dark:shadow-[0_0_0_1px_var(--field-line)]\",\n        \"hover:[--field-line:rgb(0_0_0/0.16)] dark:hover:[--field-line:rgb(255_255_255/0.18)]\",\n        \"has-[input:focus-visible]:outline-[3px] has-[input:focus-visible]:outline-ring/30 has-[input:focus-visible]:[--field-line:var(--ring)] dark:has-[input:focus-visible]:[--field-line:var(--ring)]\",\n        \"data-scrubbing:outline-[3px] data-scrubbing:outline-ring/30 data-scrubbing:[--field-line:var(--ring)] dark:data-scrubbing:[--field-line:var(--ring)]\",\n        \"has-aria-invalid:outline-destructive has-aria-invalid:has-[input:focus-visible]:outline-destructive/30 has-aria-invalid:[--field-line:var(--destructive)] dark:has-aria-invalid:[--field-line:var(--destructive)]\",\n        \"data-readonly:bg-muted/50\",\n        \"data-disabled:cursor-not-allowed data-disabled:bg-muted data-disabled:[--field-line:rgb(0_0_0/0.06)] dark:data-disabled:[--field-line:rgb(255_255_255/0.06)]\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction NumberInputControl({\n  className,\n  ...props\n}: React.ComponentProps<typeof NumberInputControlPrimitive>) {\n  return (\n    <NumberInputControlPrimitive\n      className={cn(\n        \"h-full w-full min-w-0 flex-1 bg-transparent text-center text-[13px] font-medium text-foreground tabular-nums outline-none placeholder:text-muted-foreground/70\",\n        \"data-disabled:cursor-not-allowed data-disabled:text-muted-foreground\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* A small key. It goes flat at its bound or when the field is off. */\nconst stepKey = cn(\n  \"grid size-7 shrink-0 cursor-pointer place-items-center rounded-[7px] bg-background text-foreground outline-none select-none\",\n  \"shadow-[0_0_0_1px_rgb(0_0_0/0.06),0_1px_1px_rgb(0_0_0/0.05),0_2px_4px_-2px_rgb(0_0_0/0.1)]\",\n  \"dark:bg-accent dark:shadow-[0_0_0_1px_rgb(255_255_255/0.07),inset_0_1px_0_rgb(255_255_255/0.08),0_2px_6px_-1px_rgb(0_0_0/0.6)]\",\n  \"hover:bg-muted/60 dark:hover:bg-accent/80\",\n  \"active:translate-y-px active:shadow-[0_0_0_1px_rgb(0_0_0/0.07),0_0_1px_rgb(0_0_0/0.08)] dark:active:shadow-[0_0_0_1px_rgb(255_255_255/0.06),0_0_1px_rgb(0_0_0/0.6)]\",\n  \"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n  \"data-disabled:cursor-not-allowed data-disabled:translate-y-0 data-disabled:bg-transparent data-disabled:text-muted-foreground/50 data-disabled:shadow-none dark:data-disabled:bg-transparent dark:data-disabled:shadow-none\",\n  \"[&_svg]:size-3.5 [&_svg]:shrink-0\",\n)\n\nfunction StepIcon({ plus }: { plus?: boolean }) {\n  return (\n    <svg\n      viewBox=\"0 0 16 16\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth=\"1.5\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      aria-hidden=\"true\"\n    >\n      <path d=\"M3.5 8h9\" />\n      {plus && <path d=\"M8 3.5v9\" />}\n    </svg>\n  )\n}\n\nfunction NumberInputDecrement({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof NumberInputDecrementPrimitive>) {\n  return (\n    <NumberInputDecrementPrimitive className={cn(stepKey, className)} {...props}>\n      {children ?? <StepIcon />}\n    </NumberInputDecrementPrimitive>\n  )\n}\n\nfunction NumberInputIncrement({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof NumberInputIncrementPrimitive>) {\n  return (\n    <NumberInputIncrementPrimitive className={cn(stepKey, className)} {...props}>\n      {children ?? <StepIcon plus />}\n    </NumberInputIncrementPrimitive>\n  )\n}\n\n/* Drag it sideways to change the value. Usually wraps the label. */\nfunction NumberInputScrubArea({\n  className,\n  ...props\n}: React.ComponentProps<typeof NumberInputScrubAreaPart>) {\n  return (\n    <NumberInputScrubAreaPart\n      className={cn(\n        \"w-fit cursor-ew-resize select-none data-[orientation=vertical]:cursor-ns-resize\",\n        \"data-disabled:cursor-not-allowed data-readonly:cursor-default\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\n/* Drawn while the pointer is locked during a drag; the part places it with a translation. */\nfunction NumberInputScrubAreaCursor({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof NumberInputScrubAreaCursorPart>) {\n  return (\n    <NumberInputScrubAreaCursorPart\n      className={cn(\n        \"pointer-events-none -ms-2 -mt-2 size-4 text-foreground drop-shadow-[0_1px_1px_rgb(0_0_0/0.25)] [&_svg]:size-4\",\n        className,\n      )}\n      {...props}\n    >\n      {children ?? (\n        <svg\n          viewBox=\"0 0 16 16\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"1.5\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          aria-hidden=\"true\"\n        >\n          <path d=\"M2 8h12M4.5 5.5 2 8l2.5 2.5M11.5 5.5 14 8l-2.5 2.5\" />\n        </svg>\n      )}\n    </NumberInputScrubAreaCursorPart>\n  )\n}\n\nexport {\n  NumberInput,\n  NumberInputControl,\n  NumberInputDecrement,\n  NumberInputGroup,\n  NumberInputIncrement,\n  NumberInputScrubArea,\n  NumberInputScrubAreaCursor,\n  createNumberInputController,\n}\n",
      "type": "registry:component",
      "target": "components/keyframery/number-input.tsx"
    }
  ],
  "type": "registry:component"
}