-
Notifications
You must be signed in to change notification settings - Fork 214
feat(fxa-settings): Add input component with separated characters #16741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
d9fdbae
to
ab094b9
Compare
focusOnSpecifiedInput(index); | ||
} | ||
}; | ||
// TODO in FXA-7888 review for LTR/RTL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bcolsson I've seen some comments that indicate that PIN code inputs should be rendered LTR for both LTR and RTL languages. Do you know if this is accurate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In most RTL languages that I'm aware of, numbers are typically written LTR (though it gets more confusing if they're separated into groups of numbers - like phone numbers), so the comment linked makes sense.
In this case, yeah I think it's accurate to use LTR for RTL languages here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking so good! I'm going to leave these comments for now, they are all nits, and I'm currently checking it out with a screenreader. I'll let you know if I've got any suggestions.
// also ensure that emailed code is displayed in correct direction or might fail | ||
'flex my-2 rtl:flex-row-reverse', | ||
codeLength === 6 && 'gap-4', | ||
codeLength === 8 && 'gap-2' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a blue focus color so it doesn't use the system default (mine's showing up pink)? Not sure if you'll need anything else besides the shadow-input-blue-focus
class.
What do you think about codeLength === 8 && 'gap-1 mobileLandscape:gap-2'
to help a little bit with mobile, especially small mobile devices? 320px width before and after:
This also looks OK to me with the standard mobile width (375px):
<form | ||
noValidate | ||
className="flex flex-col gap-4 my-6" | ||
onSubmit={(e) => handleSubmit(e)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also just do: onSubmit={handleSubmit(e)}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried, but does not work. e
is not defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's actually onSubmit={handleSubmit}
(if you want to use the shorthand)
git grep " onSubmit=" | cat
}); | ||
|
||
describe('keyboard navigation', () => { | ||
it('can navigate between inputs with arrow keys', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Very nice, and nice to have tests for these too!
let currentCodeArray = [...codeArray]; | ||
currentCodeArray[index] = undefined; | ||
await setCodeArray(currentCodeArray); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple nits:
- Can
currentCodeArray
become aconst
(also in delete fn)? - Does
setCodeArray
need anawait
(also in delete fn)? - Drop
focusOnSpecifiedInput(index);
to its own line after theelse
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes to 1 and 3, but await
is needed for setCodeArray
else there are glitches with the focus change in the next step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 We might need a comment above that then. When I was in this branch I saw my linter saying "await" wasn't needed. Not sure how that works since it is sync.
@vpomerleau Just tested with VO on Mac and here's some of my thoughts:
Excellent work! 👏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for all your work here!
@@ -0,0 +1,5 @@ | |||
## FormVerifyTotp | |||
|
|||
# When focused on the button, screen reader will read the action and entire number that will be submitted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
expect(button).toBeDisabled(); | ||
|
||
await waitFor(() => { | ||
user.click(screen.getByRole('textbox', { name: 'Digit 1 of 6' })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reads so much nicer in my opinion, not nearly as easy to get lost when tabbing forwards/backwards through the inputs. 😍
<button | ||
type="submit" | ||
className="cta-primary cta-xl" | ||
disabled={isSubmitting || codeArray.includes(undefined)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe stringifiedCode.length < codeLength
is more clear than codeArray.includes(undefined)
? I don't feel strongly at all though, I just squinted at this for a sec before realizing what it was for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed!! Will update
// and focus shifts to next input | ||
expect( | ||
screen.getByRole('textbox', { name: 'Digit 2 of 6' }) | ||
).toHaveFocus(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice tests 😎
@vpomerleau Just noticed after submitting my review, mobile looks even more squished than before. There's something off with the gap here: ![]() |
…vidual character inputs Because: * New designs for reset password with code include code inputs with individual input boxes This commit: * Create a TotpInputGroup component that contains individual input boxes for each character, with associated methods for handling input, keyboard navigation (including arrow keys, backspace, delete), pasting content into the boxes * Add inline error feedback below new code input component, instead of tooltip * Create a FormVerifyTotp component that includes the new TotpInputGroup (configurable for 6 or 8 digit codes) and submission button, with pre-submission validation that code contains the expected number of digits and no other characters * Add l10n and storybooks Closes #FXA-7888
Thanks for catching this! I added a min width to the input boxes. |
Because
This pull request
TotpInputGroup
component that contains individual input boxes for each character, with associated methods for handling input, keyboard navigation (including arrow keys, backspace, delete), pasting content into the boxesFormVerifyTotp
component that includes the newTotpInputGroup
(configurable for 6 or 8 digit codes) and submission button, with pre-submission validation that code contains the expected number of digits and no other charactersIssue that this pull request solves
Closes: #FXA-7888
Checklist
Put an
x
in the boxes that applyScreenshots (Optional)
**Storybook links:
FormVerifyTotp with 6-digit input
FormVerifyTotp with 8-digit input
FormVerifyTotp with error on submit
Other information (Optional)
Notes: PIN code must be displayed LTR for BOTH left-to-right and right-to-left languages