Input Group
A composed input field with prefix/suffix icons, left/right text addons, and inline action buttons. Fully styled and size-consistent with the Input component.
Basic
A composed input with prefix/suffix icon slots and left/right text addons. Maintains consistent height with Input, Select, and Button.
Installation
Install the component via the CLI in one command.
npx @work-rjkashyap/unified-ui add input-grouppnpm dlx @work-rjkashyap/unified-ui add input-groupnpx @work-rjkashyap/unified-ui add input-groupbunx @work-rjkashyap/unified-ui add input-groupIf you haven't initialized your project yet, run npx @work-rjkashyap/unified-ui init first. See the CLI docs for
details.
Or install the full package
Use this approach if you prefer to install the entire design system as a dependency instead of copying individual components.
npm install @work-rjkashyap/unified-uipnpm add @work-rjkashyap/unified-uiyarn add @work-rjkashyap/unified-uibun add @work-rjkashyap/unified-uiAnatomy
import { InputGroup, Button } from "@work-rjkashyap/unified-ui";Basic Usage
InputGroup wraps a standard <input> with optional leading/trailing content. Pass native input attributes via inputProps.
<InputGroup
prefix={<Search className="size-4" />}
inputProps={{ placeholder: "Search...", type: "search" }}
/>Prefix & Suffix Icons
Use prefix and suffix for inline icon slots. These sit inside the input border without a divider.
Left & Right Addons
Addons render outside the text field with a distinct background and a dividing border. Use them for units, labels, or fixed text like http://.
Combined: Icon + Addon
Mix icon prefixes/suffixes with addons for rich composed inputs.
Sizes
| Size | Height | Use Case |
|---|---|---|
sm | 32px | Compact toolbars, dense tables |
md | 36px | Default — most form contexts |
lg | 40px | Prominent inputs, hero forms |
Variants
Error State
Disabled
<InputGroup
disabled
prefix={<Lock className="size-4" />}
inputProps={{
placeholder: "Disabled field",
defaultValue: "read-only value",
}}
/>Inline Action Button
Pass a Button (or any element) as children to replace the default <input> slot with a fully custom layout. This is useful for search bars with an attached submit button.
<InputGroup addonLeft="Search">
<input
className="flex-1 h-full bg-transparent outline-none text-sm px-3 text-foreground placeholder:text-muted-foreground"
placeholder="Type to search..."
/>
<Button variant="primary" size="sm" className="m-1 shrink-0">
Go
</Button>
</InputGroup>Custom Children Slot
When children is provided, it replaces the built-in <input>. Use this to compose any input-like element (e.g., a Select, Combobox, or custom control) inside the group's styled container.
<InputGroup addonLeft="Country" addonRight={<Globe className="size-4" />}>
<select className="flex-1 h-full bg-transparent outline-none text-sm px-3 text-foreground">
<option>United States</option>
<option>United Kingdom</option>
<option>Germany</option>
</select>
</InputGroup>Props
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "md" | "lg" | "md" | Height variant — aligns with Button and Input sizes. |
variant | "default" | "filled" | "default" | Visual style — bordered or muted-filled background. |
prefix | ReactNode | — | Icon or content rendered inside the input on the left (no border). |
suffix | ReactNode | — | Icon or content rendered inside the input on the right (no border). |
addonLeft | ReactNode | — | Text or element attached to the left with a distinct background. |
addonRight | ReactNode | — | Text or element attached to the right with a distinct background. |
disabled | boolean | false | Disables pointer events and reduces opacity for the whole group. |
error | boolean | false | Applies danger-colored border and focus ring. |
inputProps | InputHTMLAttributes<HTMLInputElement> | — | Props spread onto the internal <input> element. |
inputClassName | string | — | Additional CSS classes applied only to the inner <input>. |
children | ReactNode | — | Replaces the default <input> with a custom element. |
className | string | — | Additional CSS classes on the container element. |
Accessibility
- The internal
<input>is a native HTML element — all standard accessibility features apply. - Use
inputProps={{ "aria-label": "..." }}when no visible<label>accompanies the group. - Addon text (
addonLeft,addonRight) is decorative — it is not programmatically associated with the input. Usearia-labelor a visible label to describe the full field. - The
disabledprop appliespointer-events-noneandopacity-50on the whole group via the CSShas-[:disabled]selector — no JS required. - Focus ring appears on
focus-withinusing the standard--ringtoken.
Design Tokens
| Token | Usage |
|---|---|
--input | Container border (default variant) |
--muted | Addon background + filled variant |
--border | Addon divider border |
--ring | Focus ring |
--danger | Error state border and ring |
--radius-md | Container border radius |
--duration-fast | Transition speed |