ProComponents, templates & AI tooling
HeroUI
27.7k

InputGroup 输入框组

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

引入

import { InputGroup } 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

前缀图标

在输入框前添加图标。

后缀图标

在输入框后添加图标。

前缀与后缀

同时组合前缀与后缀。

文字前缀

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

文字后缀

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

图标前缀与文字后缀

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

复制按钮后缀

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

图标前缀与复制按钮

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

密码显隐切换

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

加载状态

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

键盘快捷键

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

Badge 后缀

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

必填字段

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

校验

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

禁用状态

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

全宽

变体

InputGroup 支持两种视觉变体:

  • primary(默认)— 带阴影的标准样式,适用于大多数场景
  • secondary — 低强调、无阴影的变体,适合用在 Surface 组件内

在 Surface 内

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

搭配 TextArea

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

样式

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

本页目录