跳到主要内容

Input

  • 组件说明:标准文本输入框,用于表单与单行文本录入。支持前缀/后缀插槽。
  • 尺寸基线:高度 40px、水平内边距 16px、圆角 5px。
  • 实现约定ui/input 保留输入骨架,design 层统一接管边框、圆角、状态和插槽布局。
  • Figma 规范

基础用法

结果
Loading...
实时编辑器
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 360 }}>
  <Input placeholder="默认输入框" />
  <Input placeholder="带初始值" defaultValue="Hello world" />
</div>

状态

4 种视觉状态:Default / Focused / Error / Disabled。

结果
Loading...
实时编辑器
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 360 }}>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Default</span>
    <Input placeholder="默认状态" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Error</span>
    <Input error placeholder="错误状态" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Disabled(空)</span>
    <Input disabled placeholder="禁用" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Disabled(有值)</span>
    <Input disabled defaultValue="不可编辑" />
  </div>
</div>
状态边框背景说明
DefaultSeparators/Emphasized#CCCCCC透明
FocusedLabels/Primary#000000透明点击预览
ErrorStatus/Destructive#FF503F透明error 属性
DisabledSeparators/Emphasized#CCCCCCGrays/Gray-1#EBEBEBdisabled 属性

主矩阵

当前 spec 验收以 State × Filled × Status 为主。文档站优先展示当前实现对应的核心组合。

结果
Loading...
实时编辑器
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 16, maxWidth: 760 }}>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Normal / Empty / Default</span>
    <Input placeholder="请选择内容" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Normal / Filled / Default</span>
    <Input defaultValue="Filled value" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Focused / Empty / Default</span>
    <Input className="border-[var(--Labels-Primary)]" placeholder="Focused state" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Focused / Filled / Default</span>
    <Input className="border-[var(--Labels-Primary)]" defaultValue="Focused value" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Normal / Empty / Error</span>
    <Input error placeholder="Error state" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Normal / Filled / Error</span>
    <Input error defaultValue="Error value" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Disabled / Empty / Default</span>
    <Input disabled placeholder="Disabled empty" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Disabled / Filled / Default</span>
    <Input disabled defaultValue="Disabled value" />
  </div>
</div>

前缀与后缀

通过 prefixsuffix 属性渲染插槽内容(图标、按钮等)。

结果
Loading...
实时编辑器
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 360 }}>
  <Input prefix={<Search size={16} />} placeholder="搜索..." />
  <Input suffix={<Mail size={16} />} placeholder="邮箱" />
  <Input
    prefix={<Search size={16} />}
    suffix={<Mail size={16} />}
    placeholder="双插槽"
  />
  <Input prefix={<Search size={16} />} error placeholder="错误 + 前缀" />
  <Input prefix={<Search size={16} />} disabled placeholder="禁用 + 前缀" />
</div>

可清空

设置 allowClear 渲染清空(×)按钮。遵循 Figma 规范,按钮仅在输入框聚焦且有内容时出现(Filled=True + Focused),失焦或无内容时隐藏。支持受控与非受控模式。

结果
Loading...
实时编辑器
function ClearableDemo() {
  const [value, setValue] = useState('Hello world')
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 360 }}>
      <Input allowClear defaultValue="点击聚焦后即可清空" />
      <Input
        allowClear
        value={value}
        onChange={(e) => setValue(e.target.value)}
        onClear={() => setValue('')}
        placeholder="受控清空"
      />
    </div>
  )
}

尺寸规范

维度
高度40px
水平内边距16px
前缀/内容/后缀间距8px
圆角5px
字体Body/Regular(14px,行高 22)

Props

属性类型默认值说明
placeholderstring-占位文本
valuestring-受控值
defaultValuestring-初始值(非受控)
typestring'text'输入类型
errorbooleanfalse错误状态,边框使用 Status/Destructive
disabledbooleanfalse禁用状态
allowClearbooleanfalse聚焦且有内容时展示清空按钮
prefixReactNode-前缀插槽(如图标)
suffixReactNode-后缀插槽(如按钮)
onChangeChangeEventHandler-变化回调
onClear() => void-清空按钮回调
clearButtonAriaLabelstring'清空输入'清空按钮的可访问名称,多语言场景可覆盖
aria-labelstring-无障碍标签

Input.Search

  • 组件说明:搜索输入框,支持搜索图标、清空按钮以及 outline / filled 两种样式。
  • Figma 规范
  • 实现约定:搜索图标、输入区域与清空按钮由 design 层统一排布,底层输入结构仍复用 ui/input

变体

2 种样式变体 × 2 种尺寸 = 4 种组合。

结果
Loading...
实时编辑器
<div style={{ display: 'flex', flexDirection: 'column', gap: 24, maxWidth: 360 }}>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Outline / Default(40px)</span>
    <Input.Search placeholder="搜索..." />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Outline / Compact(32px)</span>
    <Input.Search size="compact" placeholder="搜索..." />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Filled / Default(40px)</span>
    <Input.Search variant="filled" placeholder="搜索..." />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>Filled / Compact(32px)</span>
    <Input.Search size="compact" variant="filled" placeholder="搜索..." />
  </div>
</div>
样式尺寸高度说明
OutlineDefault40px有边框,聚焦高亮
OutlineCompact32px小号有边框
FilledDefault40px灰色背景,无边框
FilledCompact32px小号灰色背景

受控 + 清空

聚焦且有内容时显示清空按钮(对齐 Figma Focused + Filled 状态)。

结果
Loading...
实时编辑器
function SearchDemo() {
  const [value, setValue] = useState('')
  return (
    <div style={{ maxWidth: 360 }}>
      <Input.Search
        placeholder="输入搜索内容..."
        value={value}
        onChange={(e) => setValue(e.target.value)}
        onClear={() => setValue('')}
      />
      {value && <p style={{ fontSize: 13, color: '#666', marginTop: 8 }}>搜索:{value}</p>}
    </div>
  )
}

Props

属性类型默认值说明
placeholderstring-占位文本
valuestring-受控值
defaultValuestring-初始值(非受控)
size'default' | 'compact''default'尺寸:default=40px、compact=32px
variant'outline' | 'filled''outline'样式:outline(有边框)/ filled(灰色背景)
onChangeChangeEventHandler-变化回调
onClear() => void-清空按钮回调
clearButtonAriaLabelstring'清空搜索'清空按钮的可访问名称,多语言场景可覆盖

Input.Password

  • 组件说明:密码输入框,内建明暗文切换按钮。点击眼睛图标可在密文与明文之间切换。
  • 尺寸基线:与 Input 一致 — 高度 40px、水平内边距 16px、圆角 5px。
  • 实现约定:基于 Input 组合实现,suffix 插槽被眼睛图标按钮占用。
  • Figma 规范

基础用法

结果
Loading...
实时编辑器
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 360 }}>
  <Input.Password placeholder="密码" />
  <Input.Password placeholder="密码" defaultValue="Plaud-2026" />
</div>

状态

结果
Loading...
实时编辑器
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 360 }}>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>默认</span>
    <Input.Password placeholder="密码" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>错误</span>
    <Input.Password error placeholder="密码不正确" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>禁用</span>
    <Input.Password disabled placeholder="密码" />
  </div>
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontSize: 12, color: '#999' }}>禁用(有值)</span>
    <Input.Password disabled defaultValue="secret123" />
  </div>
</div>

受控 + 可见性回调

结果
Loading...
实时编辑器
function PasswordDemo() {
  const [value, setValue] = useState('')
  const [visible, setVisible] = useState(false)
  return (
    <div style={{ maxWidth: 360 }}>
      <Input.Password
        placeholder="输入密码"
        value={value}
        onChange={(e) => setValue(e.target.value)}
        onVisibilityChange={setVisible}
      />
      <p style={{ fontSize: 13, color: '#666', marginTop: 8 }}>
        可见:{visible ? '是' : '否'} | 长度:{value.length}
      </p>
    </div>
  )
}

命名空间用法

Input.PasswordInput.Search 作为命名空间子组件使用。

结果
Loading...
实时编辑器
<div style={{ display: 'flex', flexDirection: 'column', gap: 16, maxWidth: 360 }}>
  <Input.Password placeholder="Input.Password" />
  <Input.Search placeholder="Input.Search" />
</div>

Props

属性类型默认值说明
placeholderstring-占位文本
valuestring-受控值
defaultValuestring-初始值(非受控)
errorbooleanfalse错误状态 — 边框使用 Status/Destructive
disabledbooleanfalse禁用状态
prefixReactNode-前缀插槽(如锁图标)
onVisibilityChange(visible: boolean) => void-明暗文切换回调
onChangeChangeEventHandler-变化回调
aria-labelstring-无障碍标签