agentic-ui

Number Field

A numeric input with stepper buttons and a scrub area. Supports min/max clamping, step size, locale-aware formatting, and keyboard/scroll input.

Variants

import { NumberField } from "@brijbyte/agentic-ui/number-field";

import "@brijbyte/agentic-ui/number-field.css";

export default function BasicDemo() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "var(--space-4)" }}>
      <NumberField label="Quantity" defaultValue={1} min={0} max={100} />
      <NumberField label="Timeout (ms)" defaultValue={3000} step={500} min={0} />
      <NumberField label="Price" defaultValue={9.99} step={0.01} format={{ style: "currency", currency: "USD" }} />
    </div>
  );
}

Composed: base-ui Root + styled parts

import { useId } from "react";
import { NumberField } from "@base-ui/react/number-field";
import {
  NumberFieldGroup,
  NumberFieldInput,
  NumberFieldDecrement,
  NumberFieldIncrement,
  NumberFieldScrubArea,
  NumberFieldScrubAreaCursor,
} from "@brijbyte/agentic-ui/number-field";

import "@brijbyte/agentic-ui/number-field.css";

function ScrubCursorIcon() {
  return (
    <svg width="24" height="12" viewBox="0 0 24 14" fill="currentColor" stroke="white" strokeWidth="0.5" aria-hidden>
      <path d="M19.5 5.5L6.49737 5.51844V2L1 6.9999L6.5 12L6.49737 8.5L19.5 8.5V12L25 6.9999L19.5 2V5.5Z" />
    </svg>
  );
}

export default function ComposedDemo() {
  const id = useId();

  return (
    <NumberField.Root
      id={id}
      defaultValue={42}
      min={0}
      max={999}
      style={{ display: "flex", flexDirection: "column", gap: "var(--space-1)" }}
    >
      <NumberFieldScrubArea>
        <label
          htmlFor={id}
          style={{
            cursor: "ew-resize",
            fontFamily: "var(--font-mono)",
            fontSize: "var(--font-size-xs)",
            fontWeight: "var(--font-weight-medium)",
            color: "var(--color-secondary)",
            textTransform: "uppercase",
            letterSpacing: "var(--letter-spacing-wide)",
          }}
        >
          Custom label
        </label>
        <NumberFieldScrubAreaCursor>
          <ScrubCursorIcon />
        </NumberFieldScrubAreaCursor>
      </NumberFieldScrubArea>

      <NumberFieldGroup>
        <NumberFieldDecrement>−</NumberFieldDecrement>
        <NumberFieldInput />
        <NumberFieldIncrement>+</NumberFieldIncrement>
      </NumberFieldGroup>
    </NumberField.Root>
  );
}