@@ -800,6 +800,20 @@ function handleSingleLineEnter(
800800 * is what stops a password manager autofilling the operator's own credentials
801801 * into a field that sets some other account's password.
802802 */
803+ interface ChipModalPasswordControlProps {
804+ id : string
805+ value : string
806+ onChange : ( value : string ) => void
807+ onKeyDown : ( event : React . KeyboardEvent < HTMLInputElement > ) => void
808+ placeholder ?: string
809+ maxLength ?: number
810+ autoComplete ?: string
811+ disabled ?: boolean
812+ mono ?: boolean
813+ /** ARIA the owning {@link ChipModalField} derives from its own state. */
814+ aria : ChipModalFieldAria
815+ }
816+
803817function ChipModalPasswordControl ( {
804818 id,
805819 value,
@@ -811,18 +825,7 @@ function ChipModalPasswordControl({
811825 disabled,
812826 mono,
813827 aria,
814- } : {
815- id : string
816- value : string
817- onChange : ( value : string ) => void
818- onKeyDown : ( event : React . KeyboardEvent < HTMLInputElement > ) => void
819- placeholder ?: string
820- maxLength ?: number
821- autoComplete ?: string
822- disabled ?: boolean
823- mono ?: boolean
824- aria : ChipModalFieldAria
825- } ) {
828+ } : ChipModalPasswordControlProps ) {
826829 const [ revealed , setRevealed ] = React . useState ( false )
827830
828831 return (
@@ -853,6 +856,10 @@ function ChipModalPasswordControl({
853856 type = 'button'
854857 variant = 'ghost'
855858 disabled = { disabled }
859+ // Keep focus on the input: letting the button take it would fire the
860+ // blur re-mask first, so the click would toggle back from `false`
861+ // and "Hide" would leave a focused password on screen.
862+ onMouseDown = { ( event ) => event . preventDefault ( ) }
856863 onClick = { ( ) => setRevealed ( ( current ) => ! current ) }
857864 className = 'size-6 flex-shrink-0 p-0 text-[var(--text-muted)] hover:text-[var(--text-primary)]'
858865 aria-label = { revealed ? 'Hide password' : 'Show password' }
0 commit comments