Skip to content
Redpanda UI
Esc
↑↓navigate↵open⌘Jpreview
Made by shadcn
Edit on GitHub

Input Group

Adds icons, text, buttons or keyboard hints before or after an input or textarea, so extra information and actions sit inside the same control.

Powered by

Installation

bash
npx shadcn@latest add @redpanda/input-group
bash
pnpm dlx shadcn@latest add @redpanda/input-group
bash
yarn dlx shadcn@latest add @redpanda/input-group
bash
bunx shadcn@latest add @redpanda/input-group
bash
nubx shadcn@latest add @redpanda/input-group
bash
aube dlx shadcn@latest add @redpanda/input-group

When to use

Use this decision tree to determine when to use the Input Group component:

Usage

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

Anatomy

The InputGroup component enhances inputs with inline addons. Here’s how the components work together:

tsx
<InputGroup>            {/* Container with unified focus state */}  <InputGroupAddon      {/* Addon positioned at inline-start */}    align="inline-start">    <SearchIcon />      {/* Icon, text, or button */}  </InputGroupAddon>  <InputGroupInput />   {/* Styled input (replaces Input) */}  <InputGroupAddon      {/* Addon positioned at inline-end */}    align="inline-end">    <InputGroupButton>  {/* Button in addon */}      Search    </InputGroupButton>  </InputGroupAddon></InputGroup>

Layout Structure

  • InputGroup: Root container with role="group" and unified focus ring
  • InputGroupInput: Replacement for <Input /> with group-specific styles
  • InputGroupTextarea: Replacement for <Textarea /> with group-specific styles
  • InputGroupAddon: Container for icons, text, or buttons alongside the input
  • InputGroupButton: Styled button optimized for input groups (smaller sizes)
  • InputGroupText: Text content that can be displayed in addons

Use shape="pill" on InputGroup for a fully rounded URL field. Its actions separately support the inherited InputGroupButton shape="pill" contract; no local radius variables or rounded-class overrides are needed.

For textarea chrome, use separator on a block-start or block-end addon. The addon owns the adjacent border and its padding. Inline addons do not accept a separator. Use a semantic <code> inside InputGroupText for a filename rather than overriding the text primitive’s typography.

Place a popover trigger directly on the native InputGroupButton, not on an addon wrapping that button. Information-only icons use a named Popover, with optional openOnHover, so keyboard and touch users can open the content. Tooltips are only supplementary visual labels for independently named actions. Stateful favorites expose aria-pressed on that native action.

Alignment Options

InputGroupAddon supports four alignment positions via the align prop:

  • inline-start (default): Left side of input (or right in RTL)
  • inline-end: Right side of input (or left in RTL)
  • block-start: Top of textarea
  • block-end: Bottom of textarea

Typical Usage Patterns

tsx
// Input with leading icon<InputGroup>  <InputGroupAddon>    <SearchIcon />  </InputGroupAddon>  <InputGroupInput placeholder="Search..." /></InputGroup>
// Input with trailing button<InputGroup>  <InputGroupInput placeholder="Enter email..." />  <InputGroupAddon align="inline-end">    <InputGroupButton>Subscribe</InputGroupButton>  </InputGroupAddon></InputGroup>
// Input with both sides<InputGroup>  <InputGroupAddon>    <DollarIcon />  </InputGroupAddon>  <InputGroupInput placeholder="0.00" />  <InputGroupAddon align="inline-end">    <InputGroupText>USD</InputGroupText>  </InputGroupAddon></InputGroup>
// Textarea with button at bottom<InputGroup>  <InputGroupTextarea placeholder="Write a message..." />  <InputGroupAddon align="block-end">    <InputGroupButton size="sm">Send</InputGroupButton>  </InputGroupAddon></InputGroup>
// Input with loading state<InputGroup>  <InputGroupInput placeholder="Searching..." />  <InputGroupAddon align="inline-end">    <Spinner />  </InputGroupAddon></InputGroup>
// Input with keyboard shortcut<InputGroup>  <InputGroupInput placeholder="Search..." />  <InputGroupAddon align="inline-end">    <Kbd>⌘K</Kbd>  </InputGroupAddon></InputGroup>

Examples

Icon

Text

Display additional text information alongside inputs.

InputGroupText owns its standard typography and subtle text color. The text example uses associated static message guidance, not a remaining-character count, and does not impose a character limit. Use the component’s addon/input spacing rather than local input padding overrides.

Button

Add buttons to perform actions within the input group.

Information popovers

Information controls open accessible popovers by keyboard or touch, with optional hover access. Give each popup a title and description. Keep essential password requirements visible and associated with the input even while the popup is closed; this example also sets the native eight-character minimum. The email and API-key examples do not submit or verify credentials.

Textarea

Input groups also work with textarea components. Use block-start or block-end for alignment.

The textarea example edits a local draft. Reset restores its sample, and Copy copies the current value without submitting an enclosing form. Copy failures remain visible without discarding the draft; it does not execute code.

Spinner

Show loading indicators while processing input.

Label

Add labels within input groups to improve accessibility.

Pair input groups with dropdown menus for complex interactions.

Button Group

Wrap input groups with button groups to create prefixes and suffixes.

Custom Input

Custom controls that render a native input or textarea element get group focus state handling automatically. Add a data-slot attribute and aria-invalid to opt in to the group error state styling.

No style is applied to the custom input. Apply your own styles using the className prop.

tsx
'use client';
import TextareaAutosize from 'react-textarea-autosize';
import { InputGroup, InputGroupAddon, InputGroupButton } from '@/components/ui/input-group';
export function InputGroupCustom() {  return (    <div className="grid w-full max-w-sm gap-6">      <InputGroup>        <TextareaAutosize          data-slot="input-group-control"          className="flex field-sizing-content min-h-16 w-full resize-none rounded-md bg-transparent px-3 py-2.5 text-base transition-[color,box-shadow] outline-none md:text-sm"          placeholder="Autoresize textarea..."        />        <InputGroupAddon align="block-end">          <InputGroupButton className="ml-auto" size="sm">            Submit          </InputGroupButton>        </InputGroupAddon>      </InputGroup>    </div>  );}
tsx
import { InputGroup, InputGroupAddon } from '@/component/ui/input-group';import TextareaAutosize from 'react-textarea-autosize';
export function InputGroupCustom() {  return (    <InputGroup>      <TextareaAutosize        data-slot="input-group-control"        className="flex field-sizing-content min-h-16 w-full resize-none rounded-md bg-input-fill px-3 py-2 text-base transition-[color,box-shadow] outline-none motion-reduce:transition-none"        placeholder="Autoresize textarea..."      />      <InputGroupAddon align="block-end">how</InputGroupAddon>    </InputGroup>  );}

API Reference

InputGroup

The main component that wraps inputs and addons.

Prop Type Default
className string
tsx
<InputGroup>  <InputGroupInput />  <InputGroupAddon /></InputGroup>

InputGroupAddon

Displays icons, text, buttons, or other content alongside inputs.

Prop Type Default
separator boolean (block alignments only) false
align "inline-start" | "inline-end" | "block-start" | "block-end" "inline-start"
className string
tsx
<InputGroupAddon align="inline-end">  <SearchIcon /></InputGroupAddon>

For <InputGroupInput />, use the inline-start or inline-end alignment. For <InputGroupTextarea />, use the block-start or block-end alignment.

The InputGroupAddon component can have multiple InputGroupButton components and icons.

tsx
<InputGroupAddon>  <InputGroupButton>Button</InputGroupButton>  <InputGroupButton>Button</InputGroupButton></InputGroupAddon>

InputGroupButton

Displays buttons within input groups.

Prop Type Default
shape "default" | "pill" "default"
size "xs" | "icon-xs" | "sm" | "icon-sm" "xs"
variant "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" "ghost"
className string
tsx
<InputGroupButton>Button</InputGroupButton><InputGroupButton size="icon-xs" aria-label="Copy">  <CopyIcon /></InputGroupButton>

InputGroupInput

Replacement for <Input /> when building input groups. This component has the input group styles pre-applied, and the surrounding <InputGroup /> handles its focus state automatically.

Prop Type Default
className string

All other props are passed through to the underlying <Input /> component.

tsx
<InputGroup>  <InputGroupInput placeholder="Enter text..." />  <InputGroupAddon>    <SearchIcon />  </InputGroupAddon></InputGroup>

InputGroupTextarea

Replacement for <Textarea /> when building input groups. This component has the textarea group styles pre-applied, and the surrounding <InputGroup /> handles its focus state automatically.

Prop Type Default
className string

All other props are passed through to the underlying <Textarea /> component.

tsx
<InputGroup>  <InputGroupTextarea placeholder="Enter message..." />  <InputGroupAddon align="block-end">    <InputGroupButton>Send</InputGroupButton>  </InputGroupAddon></InputGroup>

Props

Credits

  • We take our inspiration from Shadcn UI for the input-group component and style.

Recent changes

  • patchv1.2.0Pin shipped dependency floors to the version we develop against. Registry items now declare ranges like `^5.1.9` (the actual installed version) instead of collapsing to `^5.0.0`, so consumers start on the known-tested baseline while caret semantics still allow any compatible release within the same major.#133
  • minorv1.1.0Theme docs refresh, readability pass on semantic foregrounds, and consumer-facing Base UI regression fixes.#121
  • minorv1.0.0Post-Base-UI polish. Public API unchanged.#116
  • majorv1.0.0Migrate every Radix-based primitive to `@base-ui/react@^1.4.0` (Base UI).#114
  • minorv0.3.0Add theme-provider component to the registry with documentation and tests. Includes playground type improvements (export RegistryItem, remove as-const boilerplate) and docs site dark mode border color fix.#109
See full history →

Last updated on

Was this page helpful?