Docs
NumberField

NumberField

Allows a user to enter a number, and increment or decrement the value using stepper buttons.

Loading...

Copy and paste the following code into your project.

"use client";
 
import {
  Button,
  Group,
  NumberField as RaNumberField,
} from "react-aria-components";
 
import type { FormComponentBaseProps } from "@/components/ui/form";
import {
  Description,
  formVariants,
  handleOnKeyDown,
  Input,
  Label,
} from "@/components/ui/form";
import { FormError } from "@/lib/form";
import { useFormFieldContext } from "@/lib/form/context";
import { autoRef, cn, withRenderProps } from "@/lib/utils";
 
export type NumberFieldProps = FormComponentBaseProps &
  React.ComponentPropsWithRef<typeof RaNumberField> & {
    placeholder?: string;
  };
 
export const NumberField = autoRef(
  ({
    onKeyDown,
    onPressEnter,
    className,
    isInvalid,
    label,
    description,
    errorMessage,
    placeholder,
    ...props
  }: NumberFieldProps) => {
    const formField = useFormFieldContext();
 
    return (
      <RaNumberField
        onKeyDown={handleOnKeyDown(onKeyDown, onPressEnter)}
        className={(values) =>
          cn(formVariants.wrapper(), withRenderProps(className)(values))
        }
        isInvalid={formField?.invalid ?? isInvalid}
        {...props}
      >
        <Label>{label}</Label>
        <Group className={cn("group flex", formVariants.input.ring())}>
          <Button
            slot="decrement"
            className="rounded-l-md border px-4 group-s-focus-within:border-y-primary group-s-focus-within:border-l-primary"
          >
            -
          </Button>
          <Input
            placeholder={placeholder}
            className="rounded-none border-x-0 group-s-focus-within:border-y-primary group-s-focus-within:border-l-primary"
            ring={false}
          />
          <Button
            slot="increment"
            className="rounded-r-md border px-4 group-s-focus-within:border-y-primary group-s-focus-within:border-r-primary"
          >
            +
          </Button>
        </Group>
        <Description>{description}</Description>
        <FormError>{errorMessage}</FormError>
      </RaNumberField>
    );
  },
);

Update the import paths to match your project setup.