Summary
A password input with an inline show/hide (eye) toggle has now been hand-rolled twice:
- core-auth login UI
- core-frontend Settings → Profile (
apps/host/src/features/profile/components/PasswordInput.tsx, flagged in core-frontend MR !156 review: "Let's add it into DS as a separate component. It's a bad practice to create a new instance every time.")
Proposal
Add PasswordInput to the DS. The core-frontend implementation is a good starting point — it already composes DS primitives and has the a11y wiring:
InputGroup + Input + InputGroupAddon align="inline-end" so the toggle sits inside the field border
- toggle button:
Eye/EyeOff icons, aria-label ("Show password"/"Hide password"), aria-pressed, focus-visible ring, tooltip with the same label
type flips password ⇄ text; all other Input props pass through untouched (name/onChange/onBlur/ref — react-hook-form register spreads cleanly)
Acceptance
<PasswordInput placeholder="Enter" autoComplete="new-password" {...register('password')} /> works as a drop-in for <Input type="password">
- Toggle is keyboard-accessible and announced (
aria-pressed + label)
- Existing consumers (core-auth, core-frontend profile) can delete their local copies
Summary
A password input with an inline show/hide (eye) toggle has now been hand-rolled twice:
apps/host/src/features/profile/components/PasswordInput.tsx, flagged in core-frontend MR !156 review: "Let's add it into DS as a separate component. It's a bad practice to create a new instance every time.")Proposal
Add
PasswordInputto the DS. The core-frontend implementation is a good starting point — it already composes DS primitives and has the a11y wiring:InputGroup+Input+InputGroupAddon align="inline-end"so the toggle sits inside the field borderEye/EyeOfficons,aria-label("Show password"/"Hide password"),aria-pressed, focus-visible ring, tooltip with the same labeltypeflipspassword⇄text; all otherInputprops pass through untouched (name/onChange/onBlur/ref — react-hook-formregisterspreads cleanly)Acceptance
<PasswordInput placeholder="Enter" autoComplete="new-password" {...register('password')} />works as a drop-in for<Input type="password">aria-pressed+ label)