Skip to content

Generate passphrase feature for password form field - #116

Open
david-roper wants to merge 6 commits into
DouglasNeuroInformatics:mainfrom
david-roper:generate-password-feature
Open

Generate passphrase feature for password form field#116
david-roper wants to merge 6 commits into
DouglasNeuroInformatics:mainfrom
david-roper:generate-password-feature

Conversation

@david-roper

@david-roper david-roper commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an optional generatePassphrase hook to the password string field. When a form supplies it, a button appears inside the input that fills the field with the generated value and reveals it.

Changes

StringFieldPassword

  • New optional prop generatePassphrase?: (this: void) => string. The button renders only when it's provided, so existing password fields are unaffected.
  • Clicking fills the field via setValue and flips show to true — a generated passphrase the user can't read isn't much use.
  • The button is left in the natural tab order (unlike the eye toggle, which is tabIndex={-1}), since generating is a real action rather than a view toggle. It sits immediately after the input and activates on Enter/Space.
  • Hovering shows a "Generate a passphrase" tooltip, built with the library's Tooltip rather than a native title so it matches the rest of the components and appears without the browser's delay. The aria-label remains the accessible name, so the tooltip acts as a description. Both strings are translated en/fr.
  • Disabled under disabled || readOnly, matching the eye toggle.
  • Added right padding to the input. It previously had none beyond px-3, so long values slid under the eye button.
  • The strength meter needed no changes — generated values flow through setValue and the existing effect recalculates.

StoryPasswordWithPassphraseGenerator, with a strength bar so the meter's response to generation is visible. Its demo generator draws four words from a 32-word list using crypto.getRandomValues, producing values like willow-hollow-marble-ivory. A library story tends to get copied as a template, so it's worth the few extra lines not to model Math.random for credential generation. The list is exactly 32 words so that reducing a random byte modulo its length stays uniform.

The story needed its own PasswordStory type alias, since generatePassphrase isn't present on every member of the StringFieldProps union.

Tests — new StringFieldPassword.spec.tsx, the first spec for this field: button absent without the prop, fills the field on click, reveals the value, is tab-reachable and Enter-activated, and is disabled when read-only.

Notes for reviewers

  • Consumers can't set this from a form config yet. generatePassphrase is declared locally on StringFieldPasswordProps with a comment marking it for removal, because form configs are typed against StringFormField and the property isn't published there yet (checked against 1.3.0, the current release). Needs a libui-form-types release before this is usable end to end — note the upstream property is currently named generatePassword and will need the same rename. That release would also let us bump to ^1.3.0 and drop the matching local stopgap for allowCustomValue.
  • Only the generator is passphrase-flavoured. The component remains StringFieldPassword on variant: 'password'; this PR doesn't rename the field itself.
  • French wording uses "phrase de passe" (the OQLF-recommended Quebec term) rather than "phrase secrète". Happy to switch if the project prefers the latter.
  • Padding is tuned by eye, not to fully clear both buttons. With the generate button present the two controls occupy 64px of the input's right edge, while pr-10 reserves 40px, so a sufficiently long value can run under the sparkle icon.
  • The two buttons are no longer structurally identical — the generate button is a Button (via Tooltip.Trigger, so it carries a ghost hover state), while the eye toggle remains a bare <button>. Giving the eye the same treatment plus its own tooltip would make them consistent, but that changes the look of every existing password field, so it's left out of this PR.

Testing

  • tsc --noEmit and eslint src clean.
  • Full suite passes: 189 tests across 38 files.
  • Verified the layout and tooltip manually in Storybook.

related to issue DouglasNeuroInformatics/OpenDataCapture#1311

@david-roper
david-roper requested a review from joshunrau as a code owner August 14, 2026 19:33
@gdevenyi

Copy link
Copy Markdown

I would like this done with a passphrase generator instead.

@david-roper

Copy link
Copy Markdown
Contributor Author

@gdevenyi sure i can change the wording the method to reflect a passphrase generator instead

@david-roper david-roper changed the title Generate password feature for password form field Generate passphrase feature for password form field Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants