className?: string
style?: CSSProperties
@@ -34,6 +36,7 @@ export function Input({
clearable = false,
onClear,
shortcut,
+ suffix,
inputRef,
className,
style,
@@ -52,6 +55,8 @@ export function Input({
+ {suffix !== undefined && {suffix}}
+
{shortcut !== undefined && {shortcut}}
{showClear && (
diff --git a/src/components/PasswordInput.module.css b/src/components/PasswordInput.module.css
deleted file mode 100644
index e8f7390..0000000
--- a/src/components/PasswordInput.module.css
+++ /dev/null
@@ -1,12 +0,0 @@
-.root {
- display: flex;
- align-items: center;
- gap: var(--su-space-2);
- width: 100%;
-}
-
-/* 输入框吃掉剩余宽度,眼睛按钮保持自身尺寸 */
-.input {
- flex: 1;
- min-width: 0;
-}
diff --git a/src/components/PasswordInput.tsx b/src/components/PasswordInput.tsx
index b97dcd2..348f905 100644
--- a/src/components/PasswordInput.tsx
+++ b/src/components/PasswordInput.tsx
@@ -2,15 +2,17 @@ import { useState, type CSSProperties, type InputHTMLAttributes } from 'react'
import { Icon, type IconName } from './Icon'
import { IconButton } from './IconButton'
import { Input, type InputSize } from './Input'
-import styles from './PasswordInput.module.css'
/**
- * 密码输入框:`Input` + 右侧显隐切换。
+ * 密码输入框:`Input` + 输入框内部的显隐切换。
*
* 为什么单独成组件而不是每个页面拼一遍:密码框的「锁图标 + 眼睛按钮 +
* aria 名称 + type 切换」是固定搭配,手拼时很容易漏掉显隐按钮(Stash 的
* 系统改密页就漏过一次),而漏掉之后用户无法确认自己输的是什么。
*
+ * 眼睛放在输入框内部(`Input` 的 suffix 槽)而不是外面并排:
+ * 并排时会和 Edge 原生的密码显隐按钮叠成两个眼睛,视觉上也更像一个控件。
+ *
* 事件语义与 `Input` 一致:`onChange` 收到的是原生事件,Enter 等键盘逻辑
* 用 `onKeyDown`。输入框本身不知道「密码是否正确」这类业务状态。
*/
@@ -39,28 +41,25 @@ export function PasswordInput({
}: PasswordInputProps) {
const [visible, setVisible] = useState(false)
- // 眼睛按钮的高度跟随输入框,避免并排时上下错位
- const buttonSize = size === 'lg' ? 'md' : size === 'sm' ? 'xs' : 'sm'
-
return (
-
-
-
- {toggle && (
- }
- onClick={() => setVisible((current) => !current)}
- />
- )}
-
+ }
+ onClick={() => setVisible((current) => !current)}
+ />
+ ) : undefined
+ }
+ />
)
}