Skip to content

Commit d1abd51

Browse files
authored
Merge pull request #2699 from Azure/mhdahman/a11y-keyboard
Keyboard accessibility bugs (463, 853, 593)
2 parents 8ec7a70 + 338a5a1 commit d1abd51

7 files changed

Lines changed: 21 additions & 8 deletions

File tree

src/@batch-flask/ui/form/complex-form/complex-form.component.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
AfterViewInit, ChangeDetectorRef, Component, ContentChildren, HostBinding, Input, OnChanges, QueryList, Type,
2+
AfterViewInit, ChangeDetectorRef, Component, ContentChildren, ElementRef, HostBinding, Input, OnChanges, QueryList, Type, ViewChild,
33
} from "@angular/core";
44
import { FormControl } from "@angular/forms";
55
import { AsyncTask, Dto, ServerError, autobind } from "@batch-flask/core";
@@ -71,6 +71,8 @@ export class ComplexFormComponent extends FormBase implements AfterViewInit, OnC
7171

7272
@ContentChildren(FormPageComponent) public pages: QueryList<FormPageComponent>;
7373

74+
@ViewChild('formElement') formElement: ElementRef;
75+
7476
public mainPage: FormPageComponent;
7577
public currentPage: FormPageComponent;
7678
public showJsonEditor = false;
@@ -95,6 +97,9 @@ export class ComplexFormComponent extends FormBase implements AfterViewInit, OnC
9597
this.currentPage = page;
9698
this.mainPage = page;
9799
this.changeDetector.detectChanges();
100+
setTimeout(() => {
101+
this.focusFirstFocusableElement();
102+
})
98103
}
99104

100105
public ngOnChanges(changes) {
@@ -168,6 +173,10 @@ export class ComplexFormComponent extends FormBase implements AfterViewInit, OnC
168173
}
169174
this._pageStack.push(this.currentPage);
170175
this.currentPage = page;
176+
177+
setTimeout(() => {
178+
this.focusFirstFocusableElement()
179+
});
171180
}
172181

173182
@autobind()
@@ -268,4 +277,8 @@ export class ComplexFormComponent extends FormBase implements AfterViewInit, OnC
268277
multiUse: this.multiUse,
269278
};
270279
}
280+
281+
private focusFirstFocusableElement() {
282+
this.formElement.nativeElement?.querySelector('[autofocus], button, input, textarea, select')?.focus()
283+
}
271284
}

src/@batch-flask/ui/form/complex-form/complex-form.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ <h1 *ngIf="currentPage.title">{{currentPage.title}}</h1>
1010
</div>
1111
</div>
1212
<div *ngIf="!showJsonEditor" class="classic-form-container">
13-
<form novalidate>
13+
<form #formElement novalidate>
1414
<ng-template [ngTemplateOutlet]="currentPage.content"></ng-template>
1515
</form>
1616
</div>

src/app/components/account/base/auto-storage-account-picker/auto-storage-account-picker.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,13 @@ export class AutoStorageAccountPickerComponent implements OnInit, ControlValueAc
112112
* to define a custom handler.
113113
*/
114114
onKeydown(event: KeyboardEvent) {
115-
this.classicTooltip.hide();
115+
this.classicTooltip?.hide();
116116
if (event.key === "ArrowDown" || event.key === "ArrowUp" ||
117117
event.key === "Tab") {
118118
if (this.selectedStorageAccounts.size === 1) {
119119
const id = this.selectedStorageAccounts.values().next().value;
120120
if (this.classicAccounts.has(id)) {
121-
this.classicTooltip.show();
121+
this.classicTooltip?.show();
122122
}
123123
}
124124
}

src/app/components/account/base/auto-storage-account-picker/auto-storage-account-picker.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<bl-loading [status]="loadingStatus">
22
<div *ngIf="loadingStatus">
3-
<bl-button type="wide" (do)="pickStorageAccount(noSelectionKey)">
3+
<bl-button type="wide" (do)="pickStorageAccount(noSelectionKey)" autofocus>
44
{{'auto-storage-account-picker.clear-button-label' | i18n}}
55
</bl-button>
66
<h3>{{'auto-storage-account-picker.same-region-title' | i18n: {

src/app/components/gallery/submit/submit-ncj-template.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<bl-form-page [title]="title" main-form-page [formGroup]="form">
1111
<bl-form-section title="Mode" *ngIf="multipleModes">
1212
<div class="modes">
13-
<bl-button type="wide" [class.selected]="modeState === NcjTemplateMode.NewPoolAndJob" (do)="pickMode(NcjTemplateMode.NewPoolAndJob)">Run job with auto pool</bl-button>
13+
<bl-button type="wide" [class.selected]="modeState === NcjTemplateMode.NewPoolAndJob" (do)="pickMode(NcjTemplateMode.NewPoolAndJob)" autofocus>Run job with auto pool</bl-button>
1414
<bl-button type="wide" [class.selected]="modeState === NcjTemplateMode.ExistingPoolAndJob" (do)="pickMode(NcjTemplateMode.ExistingPoolAndJob)">Run job with existing pool</bl-button>
1515
<bl-button type="wide" [class.selected]="modeState === NcjTemplateMode.NewPool" (do)="pickMode(NcjTemplateMode.NewPool)">Create pool for later use</bl-button>
1616
</div>

src/app/components/job/action/add/job-preparation-task-picker.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div [formGroup]="form">
22
<div class="form-element">
33
<bl-form-field>
4-
<input blInput formControlName="id" placeholder="ID">
4+
<input blInput autofocus formControlName="id" placeholder="ID">
55
</bl-form-field>
66
<bl-error controlName="id" code="required">ID is a required field</bl-error>
77
</div>

src/app/components/job/action/add/job-release-task-picker.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div [formGroup]="form">
22
<div class="form-element">
33
<bl-form-field>
4-
<input blInput formControlName="id" placeholder="ID">
4+
<input blInput autofocus formControlName="id" placeholder="ID">
55
</bl-form-field>
66
<bl-error controlName="id" code="required">ID is a required field</bl-error>
77
</div>

0 commit comments

Comments
 (0)