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
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.
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.
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.
<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.
<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.
<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.
<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.
<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.
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
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "md" | "lg" | "md" | Visual size of the input. |
ghost | boolean | false | Minimal style with no border or background. For inline editing. |
noBorders | boolean | false | Removes border but keeps background and focus ring. |
render | ReactElement | Function | — | Renders as a different element (e.g., custom component). |
disabled | boolean | false | Disables the input. |
className | string | — | Additional 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
InputGroupwhen an input needs an icon, prefix, suffix, or inline button - Use
ghostfor inline editing (e.g., renaming items in a sidebar) - Pair inputs with labels for accessibility — use
type-small text-tertiaryfor label styling - Use
disabledwhen the field should be visible but not editable - Use
readOnlywith a copy-to-clipboard pattern for credential fields
Don't
- Don't absolutely position icons inside a plain
Input— useInputGroupso focus, hit-target, and disabled state stay consistent - Don't use
ghostin standard forms — it lacks the visual boundary users expect - Don't use
noBordersandghosttogether —ghostalready removes borders - Don't forget labels for screen reader accessibility
- Don't use Input for multiline content — use a
<textarea>instead