HeroUI

InputGroupUpdated

Group related input controls with prefix and suffix elements for enhanced form fields

Import

import { InputGroup } from '@heroui/react';

Usage

"use client";

import {Envelope} from "@gravity-ui/icons";
import {InputGroup, Label, TextField} from "@heroui/react";

Anatomy

import {InputGroup, TextField, Label} from '@heroui/react';

export default () => (
  <TextField>
    <Label />
    <InputGroup>
      <InputGroup.Prefix />
      <InputGroup.Input />
      <InputGroup.Suffix />
    </InputGroup>
  </TextField>
)

InputGroup wraps an input field with optional prefix and suffix elements, creating a visually cohesive group. It's typically used within TextField to add icons, text, buttons, or other elements before or after the input.

With Prefix Icon

Add an icon before the input field.

We'll never share this with anyone else
"use client";

import {Envelope} from "@gravity-ui/icons";
import {Description, InputGroup, Label, TextField} from "@heroui/react";

With Suffix Icon

Add an icon after the input field.

We don't send spam
"use client";

import {Envelope} from "@gravity-ui/icons";
import {Description, InputGroup, Label, TextField} from "@heroui/react";

With Prefix and Suffix

Combine both prefix and suffix elements.

What customers would pay
"use client";

import {Description, InputGroup, Label, TextField} from "@heroui/react";

export function WithPrefixAndSuffix() {

Text Prefix

Use text as a prefix, such as currency symbols or protocol prefixes.

"use client";

import {InputGroup, Label, TextField} from "@heroui/react";

export function WithTextPrefix() {

Text Suffix

Use text as a suffix, such as domain extensions or units.

"use client";

import {InputGroup, Label, TextField} from "@heroui/react";

export function WithTextSuffix() {

Icon Prefix and Text Suffix

Combine an icon prefix with a text suffix.

"use client";

import {Globe} from "@gravity-ui/icons";
import {InputGroup, Label, TextField} from "@heroui/react";

Copy Button Suffix

Add an interactive button in the suffix, such as a copy button.

"use client";

import {Copy} from "@gravity-ui/icons";
import {Button, InputGroup, Label, TextField} from "@heroui/react";

Icon Prefix and Copy Button

Combine an icon prefix with an interactive button suffix.

"use client";

import {Copy, Globe} from "@gravity-ui/icons";
import {Button, InputGroup, Label, TextField} from "@heroui/react";

Password Toggle

Use a button in the suffix to toggle password visibility.

"use client";

import {Eye, EyeSlash} from "@gravity-ui/icons";
import {Button, InputGroup, Label, TextField} from "@heroui/react";
import {useState} from "react";

Loading State

Show a loading spinner in the suffix to indicate processing.

"use client";

import {InputGroup, Spinner, TextField} from "@heroui/react";

export function WithLoadingSuffix() {

Keyboard Shortcut

Display keyboard shortcuts using the Kbd component.

"use client";

import {InputGroup, Kbd, TextField} from "@heroui/react";

export function WithKeyboardShortcut() {

Badge Suffix

Add a badge or chip in the suffix to show status or labels.

"use client";

import {Chip, InputGroup, TextField} from "@heroui/react";

export function WithBadgeSuffix() {

Required Field

InputGroup respects the required state from its parent TextField.

What customers would pay
"use client";

import {Envelope} from "@gravity-ui/icons";
import {Description, InputGroup, Label, TextField} from "@heroui/react";

Validation

InputGroup automatically reflects invalid state from its parent TextField.

Please enter a valid email address
Price must be greater than 0
"use client";

import {Envelope} from "@gravity-ui/icons";
import {FieldError, InputGroup, Label, TextField} from "@heroui/react";

Disabled State

InputGroup respects the disabled state from its parent TextField.

"use client";

import {Envelope} from "@gravity-ui/icons";
import {InputGroup, Label, TextField} from "@heroui/react";

Full Width

import {Envelope, Eye} from "@gravity-ui/icons";
import {InputGroup, Label, TextField} from "@heroui/react";

export function FullWidth() {
  return (

On Surface

When used inside a Surface component, InputGroup automatically applies on-surface styling. You can also manually control this with the isOnSurface prop.

We'll never share this with anyone else
"use client";

import {Envelope} from "@gravity-ui/icons";
import {Description, InputGroup, Label, Surface, TextField} from "@heroui/react";

Styling

Passing Tailwind CSS classes

import {InputGroup, TextField, Label} from '@heroui/react';

function CustomInputGroup() {
  return (
    <TextField>
      <Label>Website</Label>
      <InputGroup className="rounded-xl border-2 border-primary">
        <InputGroup.Prefix className="bg-primary/10 text-primary">
          https://
        </InputGroup.Prefix>
        <InputGroup.Input className="font-medium" />
        <InputGroup.Suffix className="bg-primary/10 text-primary">
          .com
        </InputGroup.Suffix>
      </InputGroup>
    </TextField>
  );
}

Customizing the component classes

InputGroup uses CSS classes that can be customized. Override the component classes to match your design system.

@layer components {
  .input-group {
    @apply bg-field text-field-foreground shadow-field rounded-field inline-flex h-9 items-center overflow-hidden border text-sm outline-none;
  }

  .input-group__input {
    @apply flex-1 rounded-none border-0 bg-transparent px-3 py-2 shadow-none outline-none;
  }

  .input-group__prefix {
    @apply text-field-placeholder rounded-l-field flex h-full items-center justify-center rounded-r-none bg-transparent px-3;
  }

  .input-group__suffix {
    @apply text-field-placeholder rounded-r-field flex h-full items-center justify-center rounded-l-none bg-transparent px-3;
  }

  /* On surface variant */
  .input-group--on-surface {
    @apply bg-on-surface shadow-none;
  }
}

CSS Classes

  • .input-group – Root container with border, background, and flex layout
  • .input-group__input – Input element with transparent background and no border
  • .input-group__prefix – Prefix container with left border radius
  • .input-group__suffix – Suffix container with right border radius
  • .input-group--on-surface – Variant for use on surface backgrounds

Interactive States

InputGroup automatically manages these data attributes based on its state:

  • Hover: [data-hovered] - Applied when hovering over the group
  • Focus Within: [data-focus-within] - Applied when the input is focused
  • Invalid: [data-invalid] - Applied when parent TextField is invalid
  • Disabled: [data-disabled] or [aria-disabled] - Applied when parent TextField is disabled

API Reference

InputGroup Props

InputGroup inherits all props from React Aria's Group component.

Base Props

PropTypeDefaultDescription
childrenReact.ReactNode | (values: GroupRenderProps) => React.ReactNode-Child components (Input, Prefix, Suffix) or render function.
classNamestring | (values: GroupRenderProps) => string-CSS classes for styling, supports render props.
styleReact.CSSProperties | (values: GroupRenderProps) => React.CSSProperties-Inline styles, supports render props.
fullWidthbooleanfalseWhether the input group should take full width of its container
idstring-The element's unique identifier.

Variant Props

PropTypeDefaultDescription
isOnSurfaceboolean-Whether the group is displayed on a surface background. Automatically detected when inside a Surface component.

Accessibility Props

PropTypeDefaultDescription
aria-labelstring-Accessibility label when no visible label is present.
aria-labelledbystring-ID of elements that label this group.
aria-describedbystring-ID of elements that describe this group.
aria-detailsstring-ID of elements with additional details.
role'group' | 'region' | 'presentation''group'Accessibility role for the group. Use 'region' for important content, 'presentation' for visual-only grouping.

Composition Components

InputGroup works with these subcomponents:

  • InputGroup.Root - Root container (also available as InputGroup)
  • InputGroup.Input - Input element component
  • InputGroup.Prefix - Prefix container component
  • InputGroup.Suffix - Suffix container component

InputGroup.Input Props

InputGroup.Input inherits all props from React Aria's Input component.

PropTypeDefaultDescription
classNamestring-CSS classes for styling.
isOnSurfaceboolean-Whether the input is displayed on a surface background.
typestring'text'Input type (text, password, email, etc.).
valuestring-Current value (controlled).
defaultValuestring-Default value (uncontrolled).
placeholderstring-Placeholder text.
disabledboolean-Whether the input is disabled.
readOnlyboolean-Whether the input is read-only.

InputGroup.Prefix Props

PropTypeDefaultDescription
childrenReact.ReactNode-Content to display in the prefix (icons, text, etc.).
classNamestring-CSS classes for styling.

InputGroup.Suffix Props

PropTypeDefaultDescription
childrenReact.ReactNode-Content to display in the suffix (icons, buttons, badges, etc.).
classNamestring-CSS classes for styling.

Usage Example

import {InputGroup, TextField, Label, Button} from '@heroui/react';
import {Icon} from '@iconify/react';

function Example() {
  return (
    <TextField>
      <Label>Email</Label>
      <InputGroup>
        <InputGroup.Prefix>
          <Icon icon="gravity-ui:envelope" />
        </InputGroup.Prefix>
        <InputGroup.Input placeholder="name@email.com" />
        <InputGroup.Suffix>
          <Button isIconOnly size="sm" variant="ghost">
            <Icon icon="gravity-ui:check" />
          </Button>
        </InputGroup.Suffix>
      </InputGroup>
    </TextField>
  );
}

On this page