ToroUI

Input Group

A container that combines an input with addons, buttons, and text elements for rich input compositions.


A composable input group that wraps an input (or textarea) with leading/trailing addons, inline buttons, and text. The container manages focus ring, border, and shadow styling so the entire group feels like a single control. Addons can be placed on any edge using the align prop.

import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from "@/components/ui/input-group"
import { MailIcon } from "lucide-react"

export default function InputGroupDemo() {
  return (
    <InputGroup>
      <InputGroupAddon align="inline-start">
        <InputGroupText>
          <MailIcon />
        </InputGroupText>
      </InputGroupAddon>
      <InputGroupInput placeholder="Email address" />
    </InputGroup>
  )
}

Anatomy

import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupText,
  InputGroupInput,
  InputGroupTextarea,
} from "@/components/ui/input-group"
<InputGroup>
  <InputGroupAddon align="inline-start">
    <SearchIcon />
  </InputGroupAddon>
  <InputGroupInput placeholder="Search..." />
  <InputGroupAddon align="inline-end">
    <InputGroupButton>Go</InputGroupButton>
  </InputGroupAddon>
</InputGroup>

Examples

With leading icon

<InputGroup>
  <InputGroupAddon align="inline-start">
    <MailIcon />
  </InputGroupAddon>
  <InputGroupInput placeholder="Email address" type="email" />
</InputGroup>

With trailing button

<InputGroup>
  <InputGroupInput placeholder="Search..." />
  <InputGroupAddon align="inline-end">
    <InputGroupButton size="xs">
      <SearchIcon />
    </InputGroupButton>
  </InputGroupAddon>
</InputGroup>

With text addon

Use InputGroupText to render plain text like currency symbols or domain suffixes.

<InputGroup>
  <InputGroupAddon align="inline-start">
    <InputGroupText>https://</InputGroupText>
  </InputGroupAddon>
  <InputGroupInput placeholder="example.com" />
</InputGroup>

Block-aligned addon

Use align="block-start" or "block-end" for addons that span the full width above or below the input.

<InputGroup>
  <InputGroupAddon align="block-start">
    <InputGroupText>To:</InputGroupText>
  </InputGroupAddon>
  <InputGroupInput placeholder="recipient@example.com" />
</InputGroup>

API Reference

InputGroup

The root container <div>. Manages shared border, focus ring, and layout. Renders with role="group".

PropTypeDefault
classNamestring
childrenReactNode

InputGroupAddon

A positioned container for icons, buttons, or text placed alongside the input. Clicking the addon focuses the input.

PropTypeDefaultDescription
align"inline-start" | "inline-end" | "block-start" | "block-end""inline-start"Which edge of the input group the addon is placed on. inline-* for left/right, block-* for top/bottom.
classNamestring
childrenReactNode

InputGroupButton

A Button component pre-configured for use inside an input group with smaller sizing and no shadow.

PropTypeDefaultDescription
size"xs" | "sm" | "icon-xs" | "icon-sm""xs"The button size.
variantstring"ghost"The button variant. Accepts all Button variants.
type"button" | "submit" | "reset""button"The HTML button type.
classNamestring
childrenReactNode

InputGroupText

A <span> for rendering plain text content like labels or symbols within an addon.

PropTypeDefault
classNamestring
childrenReactNode

InputGroupInput

An Input component styled to remove its own border and shadow so it integrates with the group container.

PropTypeDefault
classNamestring
All standard <input> props

InputGroupTextarea

A Textarea component styled to remove its own border and shadow for integration with the group container.

PropTypeDefault
classNamestring
All standard <textarea> props