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.
"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.
"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.
"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.
"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.
"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.
"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
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | (values: GroupRenderProps) => React.ReactNode | - | Child components (Input, Prefix, Suffix) or render function. |
className | string | (values: GroupRenderProps) => string | - | CSS classes for styling, supports render props. |
style | React.CSSProperties | (values: GroupRenderProps) => React.CSSProperties | - | Inline styles, supports render props. |
fullWidth | boolean | false | Whether the input group should take full width of its container |
id | string | - | The element's unique identifier. |
Variant Props
| Prop | Type | Default | Description |
|---|---|---|---|
isOnSurface | boolean | - | Whether the group is displayed on a surface background. Automatically detected when inside a Surface component. |
Accessibility Props
| Prop | Type | Default | Description |
|---|---|---|---|
aria-label | string | - | Accessibility label when no visible label is present. |
aria-labelledby | string | - | ID of elements that label this group. |
aria-describedby | string | - | ID of elements that describe this group. |
aria-details | string | - | 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.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | CSS classes for styling. |
isOnSurface | boolean | - | Whether the input is displayed on a surface background. |
type | string | 'text' | Input type (text, password, email, etc.). |
value | string | - | Current value (controlled). |
defaultValue | string | - | Default value (uncontrolled). |
placeholder | string | - | Placeholder text. |
disabled | boolean | - | Whether the input is disabled. |
readOnly | boolean | - | Whether the input is read-only. |
InputGroup.Prefix Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | - | Content to display in the prefix (icons, text, etc.). |
className | string | - | CSS classes for styling. |
InputGroup.Suffix Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | - | Content to display in the suffix (icons, buttons, badges, etc.). |
className | string | - | 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>
);
}




