From 5c7f4a788f77b222d1de90b0d48bba403ffc1f97 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Mon, 13 Feb 2023 11:48:21 +0100 Subject: [PATCH] Focus on first suitable child in sign in flow When switching steps in the sign in flow we're essentially showing a new dialog (or at least it should behave as such) which means we'll need to reset the focus, if we don't then keyboard focus will just flow to the body whenever we change the dialog contents. --- app/src/ui/dialog/dialog.tsx | 2 +- app/src/ui/sign-in/sign-in.tsx | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/src/ui/dialog/dialog.tsx b/app/src/ui/dialog/dialog.tsx index ff7b39598d..94840c9802 100644 --- a/app/src/ui/dialog/dialog.tsx +++ b/app/src/ui/dialog/dialog.tsx @@ -383,7 +383,7 @@ export class Dialog extends React.Component { * 4. Any remaining button * */ - private focusFirstSuitableChild() { + public focusFirstSuitableChild() { const dialog = this.dialogElement if (dialog === null) { diff --git a/app/src/ui/sign-in/sign-in.tsx b/app/src/ui/sign-in/sign-in.tsx index 9ffe0e6321..0f9689dfc5 100644 --- a/app/src/ui/sign-in/sign-in.tsx +++ b/app/src/ui/sign-in/sign-in.tsx @@ -41,6 +41,8 @@ const SignInWithBrowserTitle = __DARWIN__ const DefaultTitle = 'Sign in' export class SignIn extends React.Component { + private readonly dialogRef = React.createRef() + public constructor(props: ISignInProps) { super(props) @@ -52,6 +54,18 @@ export class SignIn extends React.Component { } } + public componentDidUpdate(prevProps: ISignInProps) { + // Whenever the sign in step changes we replace the dialog contents which + // means we need to re-focus the first suitable child element as it's + // essentially a "new" dialog we're showing only the dialog component itself + // doesn't know that. + if (prevProps.signInState !== null && this.props.signInState !== null) { + if (prevProps.signInState.kind !== this.props.signInState.kind) { + this.dialogRef.current?.focusFirstSuitableChild() + } + } + } + public componentWillReceiveProps(nextProps: ISignInProps) { if (nextProps.signInState !== this.props.signInState) { if ( @@ -161,6 +175,7 @@ export class SignIn extends React.Component { ) @@ -324,6 +339,7 @@ export class SignIn extends React.Component { onDismissed={this.onDismissed} onSubmit={this.onSubmit} loading={state.loading} + ref={this.dialogRef} > {errors} {this.renderStep()}