Fix form field focus on setup pages (#2336)

- Using componentDidUpdate() to check for currentPage change in setup registration form. Initially tried adding `autofocus` prop to the first `<InputFieldWithIcon />` on each page. As seen in AdminDetails page. Didn't work. I believe React only pays attention to `autofocus` when the <input> is re-rendered.

- Calling focus() on page's first input  when currentPage changes and is true. Using refs callback

- Delaying focus by 300ms using setTimeout because the `.user-registration__field-wrapper` has a transition duration of 300ms. Setting the inputs focus immediately creates a snapping movement and ruins the smooth transition.

Fixes #936
This commit is contained in:
noahtalerman 2020-10-21 21:03:39 -04:00 committed by GitHub
parent 8246b4d1f8
commit a6529cc5b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 0 deletions

View File

@ -23,6 +23,17 @@ class AdminDetails extends Component {
handleSubmit: PropTypes.func.isRequired,
};
componentDidUpdate(prevProps) {
if (this.props.currentPage && this.props.currentPage !== prevProps.currentPage) {
// Component has a transition duration of 300ms set in
// RegistrationForm/_styles.scss. We need to wait 300ms before
// calling .focus() to preserve smooth transition.
setTimeout(() => {
this.firstInput.input.focus();
}, 300);
}
}
render () {
const { className, currentPage, fields, handleSubmit } = this.props;
const tabIndex = currentPage ? 1 : -1;
@ -36,6 +47,7 @@ class AdminDetails extends Component {
placeholder="Username"
tabIndex={tabIndex}
autofocus={currentPage}
ref={(input) => { this.firstInput = input; }}
/>
<InputFieldWithIcon
{...fields.password}

View File

@ -20,6 +20,17 @@ class KolideDetails extends Component {
handleSubmit: PropTypes.func.isRequired,
};
componentDidUpdate(prevProps) {
if (this.props.currentPage && this.props.currentPage !== prevProps.currentPage) {
// Component has a transition duration of 300ms set in
// RegistrationForm/_styles.scss. We need to wait 300ms before
// calling .focus() to preserve smooth transition.
setTimeout(() => {
this.firstInput.input.focus();
}, 300);
}
}
render () {
const { className, currentPage, fields, handleSubmit } = this.props;
const tabIndex = currentPage ? 1 : -1;
@ -32,6 +43,7 @@ class KolideDetails extends Component {
placeholder="Fleet Web Address"
tabIndex={tabIndex}
hint={['Dont include ', <code key="hint">/v1</code>, ' or any other path']}
ref={(input) => { this.firstInput = input; }}
/>
</div>
<Button type="submit" variant="gradient" tabIndex={tabIndex} disabled={!currentPage}>

View File

@ -21,6 +21,17 @@ class OrgDetails extends Component {
handleSubmit: PropTypes.func.isRequired,
};
componentDidUpdate(prevProps) {
if (this.props.currentPage && this.props.currentPage !== prevProps.currentPage) {
// Component has a transition duration of 300ms set in
// RegistrationForm/_styles.scss. We need to wait 300ms before
// calling .focus() to preserve smooth transition.
setTimeout(() => {
this.firstInput.input.focus();
}, 300);
}
}
render () {
const { className, currentPage, fields, handleSubmit } = this.props;
const tabIndex = currentPage ? 1 : -1;
@ -32,6 +43,7 @@ class OrgDetails extends Component {
{...fields.org_name}
placeholder="Organization Name"
tabIndex={tabIndex}
ref={(input) => { this.firstInput = input; }}
/>
<InputFieldWithIcon
{...fields.org_logo_url}