Input

Text inputs capture short, single-line text values for forms and user data entry.

Examples

Standard

Sizes

Ghost

No borders

Disabled

Invalid

File input

With label

Input group

Compose inputs with icons, text, or buttons by wrapping them in an InputGroup. The group owns the border and focus ring; InputGroupInput strips its own chrome so the addons sit flush.

With leading icon

With button

Side-by-side with button

With prefix text

https://

Prompt bar

Group sizes

Overview

The Input component wraps Base UI's Input with consistent styling, focus states, and variant support. It's a drop-in replacement for the native <input> element with all the same props.

tsx
import { Input } from "@rogo-technologies/ui/input";

<Input placeholder="Enter a value" />;

For inputs with adornments — icons, prefixes, suffixes, inline buttons — use the InputGroup composition primitives instead of layering absolute-positioned children on top of a plain Input. The group keeps focus, hit-target, and disabled state consistent across its parts.

tsx
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
} from "@rogo-technologies/ui/input-group";
import { IconMagnifyingGlass } from "@rogo-technologies/ui/icons";

<InputGroup>
  <InputGroupAddon>
    <IconMagnifyingGlass />
  </InputGroupAddon>
  <InputGroupInput placeholder="Search..." />
</InputGroup>;

Usage

Sizes

Inputs come in three sizes: sm (32px), md (40px, default), and lg (48px). The same size prop is also available on InputGroup and is propagated down to InputGroupInput and InputGroupAddon via context.

tsx
<Input size="sm" placeholder="Small" />
<Input size="md" placeholder="Medium" />
<Input size="lg" placeholder="Large" />

Ghost

Minimal style with no border or background. Ideal for inline editing scenarios like renaming items.

tsx
<Input placeholder="Untitled" ghost />

No borders

Background and focus ring without a visible border. Useful when the input sits inside a custom container that already provides structure.

tsx
<Input placeholder="Search..." noBorders />

Invalid

Set aria-invalid (or data-invalid) to surface validation errors. The border and focus ring switch to the destructive color automatically.

tsx
<Input placeholder="name@company.com" aria-invalid />

With label

Pair the Input with a plain <label> for accessible form fields. Use type-small text-tertiary for consistent label styling.

tsx
<div className="flex flex-col gap-1">
  <label className="type-small text-tertiary">Email</label>
  <Input placeholder="name@company.com" />
</div>

With form libraries

Compatible with react-hook-form for validation and controlled forms.

tsx
import { useForm, FormProvider } from "react-hook-form";
import { Input } from "@rogo-technologies/ui/input";

function MyForm() {
  const form = useForm({ defaultValues: { name: "" } });

  return (
    <FormProvider {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        <div className="flex flex-col gap-1">
          <label className="type-small text-tertiary">Name</label>
          <Input placeholder="John Doe" {...form.register("name", { required: true })} />
        </div>
        <Button type="submit">Submit</Button>
      </form>
    </FormProvider>
  );
}

API

Input

PropTypeDefaultDescription
size"sm" | "md" | "lg""md"Visual size of the input.
ghostbooleanfalseMinimal style with no border or background. For inline editing.
noBordersbooleanfalseRemoves border but keeps background and focus ring.
renderReactElement | FunctionRenders as a different element (e.g., custom component).
disabledbooleanfalseDisables the input.
classNamestringAdditional CSS classes.

Additionally, the Input accepts all standard HTML <input> attributes (placeholder, type, value, onChange, readOnly, aria-invalid, etc.).

InputGroup

InputGroup is the wrapper that owns border, background, focus ring, and invalid state. It accepts a size prop ("sm" \| "md" \| "lg", default "md") which is propagated to its children via context.

InputGroupInput renders an Input configured to blend into the group (no border, transparent background, no focus ring of its own). It marks itself with data-slot="input-group-control" so the group can react to focus/disabled/invalid state.

InputGroupAddon holds icons, text, or buttons. Use the align prop to position content: "inline-start" (default), "inline-end", "block-start", or "block-end". Clicking the addon focuses the input unless the click lands on an interactive element inside.

InputGroupText renders inline text inside an addon (e.g. https://). InputGroupButton renders a Button sized to fit inside the group; it accepts the same variants as the standard Button.

Guidelines

Do

  • Use the standard variant for most form fields
  • Reach for InputGroup when an input needs an icon, prefix, suffix, or inline button
  • Use ghost for inline editing (e.g., renaming items in a sidebar)
  • Pair inputs with labels for accessibility — use type-small text-tertiary for label styling
  • Use disabled when the field should be visible but not editable
  • Use readOnly with a copy-to-clipboard pattern for credential fields

Don't

  • Don't absolutely position icons inside a plain Input — use InputGroup so focus, hit-target, and disabled state stay consistent
  • Don't use ghost in standard forms — it lacks the visual boundary users expect
  • Don't use noBorders and ghost together — ghost already removes borders
  • Don't forget labels for screen reader accessibility
  • Don't use Input for multiline content — use a <textarea> instead
Made in NYC© 2026 Rogo Technologies Inc.