PasswordInput 密码输入框

输入密码的输入框,可以切换明文显示。

import { PasswordInput } from '@hina-ui/react'

export default function Demo() {
  return (
    <PasswordInput
      defaultValue="hoshimi-shion"
      aria-label="密码"
      autoComplete="current-password"
      className="w-64"
    />
  )
}
tsx

用法

import { PasswordInput } from '@hina-ui/react'
ts

密码输入框在输入区末尾带一个切换明文与密文的按钮,value / onValueChange 绑定文本。未声明的属性都会传给 input,应当传入 autoComplete:登录用 current-password,注册与修改密码用 new-password。

import { PasswordInput } from '@hina-ui/react'

export default function Demo() {
  return (
    <PasswordInput
      defaultValue=""
      aria-label="密码"
      placeholder="密码"
      autoComplete="current-password"
      className="w-64"
    />
  )
}
tsx

示例

可见性

visible 决定是否显示明文,可受控。两个输入框共用同一个值时会一起切换。

'use client'

import { useState } from 'react'
import { PasswordInput, Stack } from '@hina-ui/react'

export default function Demo() {
  const [visible, setVisible] = useState(false)

  return (
    <Stack className="w-64">
      <PasswordInput
        defaultValue=""
        visible={visible}
        onVisibleChange={setVisible}
        aria-label="新密码"
        placeholder="新密码"
        autoComplete="new-password"
      />
      <PasswordInput
        defaultValue=""
        visible={visible}
        onVisibleChange={setVisible}
        aria-label="确认密码"
        placeholder="确认密码"
        autoComplete="new-password"
      />
    </Stack>
  )
}
tsx

尺寸

三档尺寸与输入框相同。

import { PasswordInput, Stack } from '@hina-ui/react'

export default function Demo() {
  return (
    <Stack className="w-64">
      <PasswordInput size="sm" defaultValue="hoshimi" aria-label="小号" />
      <PasswordInput size="md" defaultValue="hoshimi" aria-label="中号" />
      <PasswordInput size="lg" defaultValue="hoshimi" aria-label="大号" />
    </Stack>
  )
}
tsx

形态

primary 带边框、背景与阴影;secondary 使用浅色背景;bare 背景透明,不绘制边框、阴影、悬停底色或容器聚焦环,尺寸与内边距仍由原有设置控制。

bare 保留禁用状态与 aria-invalid;错误信息可由 FormField 显示。附属按钮保留自身的悬停与键盘聚焦反馈。

import { PasswordInput, Stack } from '@hina-ui/react'

export default function Demo() {
  return (
    <Stack className="w-full max-w-xs">
      <PasswordInput variant="primary" aria-label="primary" defaultValue="hoshimi" />
      <PasswordInput variant="secondary" aria-label="secondary" defaultValue="hoshimi" />
      <PasswordInput variant="bare" aria-label="bare" defaultValue="hoshimi" />
    </Stack>
  )
}
tsx

状态

invalid 标出校验未通过,disabled 不可编辑。

import { PasswordInput, Stack } from '@hina-ui/react'

export default function Demo() {
  return (
    <Stack className="w-64">
      <PasswordInput invalid defaultValue="123456" aria-label="校验未通过" />
      <PasswordInput disabled defaultValue="hoshimi" aria-label="已禁用" />
    </Stack>
  )
}
tsx

在表单中

放进 FormField 后,标签指向输入框,说明与错误信息由字段渲染;校验规则与提交交给 Form。两次输入是否一致这类跨字段的规则写在对象层,再指定错误落在哪个字段。

至少 8 位,包含数字

'use client'

import { useState } from 'react'
import * as v from 'valibot'
import { Button, Form, FormField, PasswordInput, Text } from '@hina-ui/react'

const schema = v.pipe(
  v.object({
    password: v.pipe(
      v.string('请输入密码'),
      v.minLength(8, '密码至少 8 位'),
      v.regex(/[0-9]/, '密码需要包含数字'),
    ),
    confirm: v.string('请再次输入密码'),
  }),
  v.forward(
    v.check(input => input.password === input.confirm, '两次输入的密码不一致'),
    ['confirm'],
  ),
)

export default function Demo() {
  const [values, setValues] = useState({ password: '', confirm: '' })
  const [saved, setSaved] = useState(false)

  async function save() {
    await new Promise(resolve => setTimeout(resolve, 600))
    setSaved(true)
  }

  return (
    <Form values={values} rules={schema} className="w-80" onSubmit={save}>
      {({ submitting }) => (
        <>
          <FormField name="password" label="新密码" description="至少 8 位,包含数字" required>
            <PasswordInput
              value={values.password}
              onValueChange={password => setValues({ ...values, password })}
            />
          </FormField>
          <FormField name="confirm" label="确认密码" required>
            <PasswordInput
              value={values.confirm}
              onValueChange={confirm => setValues({ ...values, confirm })}
            />
          </FormField>
          <Button type="submit" loading={submitting} className="self-start">
            修改密码
          </Button>
          {saved && (
            <Text tone="muted" size="sm">
              密码已修改。
            </Text>
          )}
        </>
      )}
    </Form>
  )
}
tsx

行为

  • 点击切换按钮不会让输入区失焦,切换后可以继续输入。
  • 切换只改变显示方式,不改变值。
  • 悬停、聚焦、错误与禁用的表现与 Input 相同。

无障碍

  • 切换按钮可以用 Tab 到达,名称随状态在「显示密码」与「隐藏密码」之间切换。
  • 应当配合 label 元素或者 aria-label 提供名称。invalid 同时设置 aria-invalid。

API

Props

属性
类型
默认值
说明
value
string
—
文本
visible
boolean
false
是否显示明文,可受控
variant
'primary' | 'secondary' | 'bare'
'primary'
形态
size
'sm' | 'md' | 'lg'
'md'
尺寸
invalid
boolean
false
是否校验未通过
disabled
boolean
false
是否禁用
className
string
—
追加至根元素的类名
回调
参数
说明
onValueChange
value: string
文本变化
onVisibleChange
visible: boolean
可见性变化