ProComponents, templates & AI tooling
HeroUI
27.7k

InputGroup 输入框组

将相关输入控件与前后缀元素组合,以增强表单字段。

引入

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

用法

"use client";

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

组件结构

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

export default () => (
  <TextField>
    <Label />
    <InputGroup>
      <InputGroup.Prefix />
      <InputGroup.Input /> {/* Or use InputGroup.TextArea for multiline input */}
      <InputGroup.Suffix />
    </InputGroup>
  </TextField>
)

InputGroup 使用可选的前缀与后缀包裹输入框,形成视觉上统一的组合。通常放在 TextField 内,用于在输入前后添加图标、文字、按钮等元素。单行输入请使用 InputGroup.Input,多行输入请使用 InputGroup.TextArea

前缀图标

在输入框前添加图标。

我们不会将此邮箱分享给任何人
"use client";

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

后缀图标

在输入框后添加图标。

我们不会发送垃圾邮件
"use client";

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

前缀与后缀

同时组合前缀与后缀。

客户将支付的价格
"use client";

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

export function WithPrefixAndSuffix() {

文字前缀

使用文字作为前缀,例如货币符号或协议前缀。

"use client";

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

export function WithTextPrefix() {

文字后缀

使用文字作为后缀,例如域名后缀或单位。

"use client";

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

export function WithTextSuffix() {

图标前缀与文字后缀

组合图标前缀与文字后缀。

"use client";

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

复制按钮后缀

在后缀中加入交互按钮,例如复制按钮。

"use client";

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

图标前缀与复制按钮

组合图标前缀与交互式后缀按钮。

"use client";

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

密码显隐切换

在后缀中使用按钮切换密码可见性。

"use client";

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

加载状态

在后缀显示加载指示器,表示正在处理。

"use client";

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

export function WithLoadingSuffix() {

键盘快捷键

使用 Kbd 组件展示键盘快捷键。

"use client";

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

export function WithKeyboardShortcut() {

Badge 后缀

在后缀中加入徽章或 chip,用于展示状态或标签。

"use client";

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

export function WithBadgeSuffix() {

必填字段

InputGroup 会遵循父级 TextField 的必填状态。

客户将支付的价格
"use client";

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

校验

InputGroup 会自动反映父级 TextField 的无效状态。

请输入有效的邮箱地址
价格必须大于 0
"use client";

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

禁用状态

InputGroup 会遵循父级 TextField 的禁用状态。

"use client";

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

全宽

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

export function FullWidth() {
  return (

变体

InputGroup 支持两种视觉变体:

  • primary(默认)— 带阴影的标准样式,适用于大多数场景
  • secondary — 低强调、无阴影的变体,适合用在 Surface 组件内
import {Envelope} from "@gravity-ui/icons";
import {InputGroup, Label, TextField} from "@heroui/react";

export function Variants() {
  return (

在 Surface 内

Surface 内使用时,请使用 variant="secondary",以应用适合表面背景的低强调变体。

我们不会将此邮箱分享给任何人
"use client";

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

搭配 TextArea

多行输入请使用 InputGroup.TextArea,并搭配前缀与后缀。当存在 textarea 时,容器高度会自动适应内容,并将前缀/后缀与顶部对齐。

"use client";

import {ArrowUp, At, Microphone, PlugConnection, Plus} from "@gravity-ui/icons";
import {Button, InputGroup, Kbd, Spinner, TextField, Tooltip} from "@heroui/react";
import {useState} from "react";

样式

传入 Tailwind CSS 类

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>
  );
}

自定义组件类

InputGroup 使用可自定义的 CSS 类。你可以覆盖这些类名以匹配自己的设计系统。

@layer components {
  .input-group {
    @apply bg-field text-field-foreground shadow-field rounded-field inline-flex min-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;
  }

  /* Secondary variant */
  .input-group--secondary {
    @apply shadow-none;
    background-color: var(--color-default);
  }
}

CSS 类

  • .input-group – 根容器:带边框、背景与 flex 布局。默认使用 min-h-9items-center;当存在 textarea 时会切换为 items-start
  • .input-group__input – 透明背景、无边框的输入元素。textarea 也使用该基础类。
  • .input-group__prefix – 左侧圆角的前缀容器。与 textarea 搭配时与顶部对齐。
  • .input-group__suffix – 右侧圆角的后缀容器。与 textarea 搭配时与顶部对齐。
  • .input-group--primary – 带阴影的主变体(默认)
  • .input-group--secondary – 无阴影的次变体,适合用在 surface 上

说明: 使用 InputGroup.TextArea 时,容器会从 items-center 切换为 items-start,并使用 height: auto 替代固定高度。前缀与后缀与顶部对齐,并增加内边距以匹配 textarea 的垂直内边距。textarea 使用相同的 .input-group__input 基础类,并通过 [data-slot="input-group-textarea"] 选择器应用 textarea 专用样式(最小高度与纵向 resize)。

交互状态

InputGroup 会根据状态自动管理以下 data 属性:

  • Hover[data-hovered] – 悬停在整个组合上时应用
  • Focus Within[data-focus-within] – 输入框聚焦时应用
  • Invalid[data-invalid] – 父级 TextField 为无效时应用
  • Disabled[data-disabled][aria-disabled] – 父级 TextField 为禁用时应用

API 参考

InputGroup Props

InputGroup 继承 React Aria Group 组件的全部 props。

Base Props

Prop类型默认值描述
childrenReact.ReactNode | (values: GroupRenderProps) => React.ReactNode-子组件(Input、TextArea、Prefix、Suffix)或渲染函数。
classNamestring | (values: GroupRenderProps) => string-用于样式的 CSS 类,支持渲染 prop。
styleReact.CSSProperties | (values: GroupRenderProps) => React.CSSProperties-行内样式,支持渲染 prop。
fullWidthbooleanfalse输入组是否占满容器宽度
idstring-元素的唯一标识符。

Variant Props

Prop类型默认值描述
variant"primary" | "secondary""primary"组件的视觉变体。primary 为默认带阴影样式。secondary 为低强调、无阴影变体,适合用在 surface 上。

Accessibility Props

Prop类型默认值描述
aria-labelstring-没有可见标签时的无障碍标签。
aria-labelledbystring-用于标注该组的元素 ID。
aria-describedbystring-用于描述该组的元素 ID。
aria-detailsstring-包含更多详情的元素 ID。
role'group' | 'region' | 'presentation''group'分组的无障碍角色。重要内容可使用 region,纯视觉分组可使用 presentation

Composition Components

InputGroup 与以下子组件配合使用:

  • InputGroup.Root – 根容器(也可直接写作 InputGroup
  • InputGroup.Input – 单行输入元素组件
  • InputGroup.TextArea – 多行 textarea 元素组件
  • InputGroup.Prefix – 前缀容器组件
  • InputGroup.Suffix – 后缀容器组件

InputGroup.Input Props

InputGroup.Input 继承 React Aria Input 组件的全部 props。

Prop类型默认值描述
classNamestring-用于样式的 CSS 类。
variant"primary" | "secondary""primary"输入的视觉变体。primary 为默认带阴影样式。secondary 为低强调、无阴影变体,适合用在 surface 上。
typestring'text'输入类型(text、password、email 等)。
valuestring-当前值(受控)。
defaultValuestring-默认值(非受控)。
placeholderstring-占位符文本。
disabledboolean-是否禁用输入。
readOnlyboolean-是否只读。

InputGroup.TextArea Props

InputGroup.TextArea 继承 React Aria TextArea 组件的全部 props。

Prop类型默认值描述
classNamestring-用于样式的 CSS 类。
variant"primary" | "secondary""primary"textarea 的视觉变体。primary 为默认带阴影样式。secondary 为低强调、无阴影变体,适合用在 surface 上。
valuestring-当前值(受控)。
defaultValuestring-默认值(非受控)。
placeholderstring-占位符文本。
rowsnumber-可见文本行数。
disabledboolean-是否禁用 textarea。
readOnlyboolean-是否只读。

InputGroup.Prefix Props

Prop类型默认值描述
childrenReact.ReactNode-前缀中要展示的内容(图标、文字等)。
classNamestring-用于样式的 CSS 类。

InputGroup.Suffix Props

Prop类型默认值描述
childrenReact.ReactNode-后缀中要展示的内容(图标、按钮、徽章等)。
classNamestring-用于样式的 CSS 类。

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>
  );
}

TextArea Usage Example

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

function TextAreaExample() {
  const [feedback, setFeedback] = useState("");

  return (
    <TextField fullWidth isInvalid={feedback.length > 500} name="feedback" onChange={setFeedback}>
      <Label>Your Feedback</Label>
      <InputGroup fullWidth>
        <InputGroup.Prefix>
          <Envelope className="size-4 text-muted" />
        </InputGroup.Prefix>
        <InputGroup.TextArea
          className="resize-none"
          placeholder="Share your thoughts, suggestions, or issues..."
          rows={5}
          value={feedback}
        />
      </InputGroup>
      <Description className="flex w-full items-center justify-between px-1">
        <span>Maximum 500 characters.</span>
        <span className="ml-auto">{feedback.length}/500</span>
      </Description>
      <FieldError>Feedback must be less than 500 characters</FieldError>
    </TextField>
  );
}

本页目录