Skip to content
Snippets Groups Projects
Commit 3be5f503 authored by Pierre Ecarlat's avatar Pierre Ecarlat
Browse files

fix(a11y): Adapt shortcuts

parent e1740b1b
No related branches found
No related tags found
2 merge requests!907V3.2.0,!898fix(a11y): Adapt shortcuts
<a class="skip-link" [routerLink]="[]" [fragment]="'app-body'">Aller au contenu</a>
<div class="visually-hidden">
<p>Utilisez <strong>h</strong> (header) pour revenir au logo Res'in à tout moment.</p>
<p>Utilisez <strong>ESC</strong> pour revenir à la barre de navigation à tout moment.</p>
</div>
<app-header />
<main class="app-container">
......
......@@ -30,28 +30,10 @@ export class AppComponent implements OnInit {
// Listener, keyboard shortcuts
@HostListener('window:keydown', ['$event'])
handleKeyboardEvent(event: KeyboardEvent): void {
const target = event.target as HTMLElement;
const tagName = target.tagName.toLowerCase();
// Check if the focus is within an input, textarea
if (tagName === 'input') {
const inputElement = target as HTMLInputElement;
const inputType = inputElement.type.toLowerCase();
// Ignore only text-based inputs, not others like radio, checkbox, etc.
if (!['radio', 'checkbox', 'button', 'submit', 'reset'].includes(inputType)) {
return;
}
} else if (tagName === 'textarea' || target.isContentEditable) {
return;
}
switch (event.key) {
case 'h': // 'h' to go to the header (resin logo)
this.headerComponent.focusLogo();
event.preventDefault();
break;
default:
break;
// 'esc' to go to the header and escape any focus trap
if (event.key === 'Escape') {
this.headerComponent.focusLogo();
event.preventDefault();
}
}
......
<div class="formView">
<div cdkTrapFocus class="formView">
<app-modal
[title]="'ATTENTION'"
[opened]="showConfirmationModal"
......
import { A11yModule } from '@angular/cdk/a11y';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { SharedModule } from '../../shared/shared.module';
......@@ -71,7 +72,7 @@ import { StructureWifiComponent } from './structure-form/structure-wifi/structur
StructureTrainingTypeComponent,
StructureSolidarityMaterialComponent,
],
imports: [CommonModule, FormViewRoutingModule, SharedModule],
imports: [CommonModule, FormViewRoutingModule, SharedModule, A11yModule],
providers: [PersonalOfferGuard],
})
export class FormViewModule {}
......@@ -2,7 +2,6 @@
<ng-container *ngIf="!failedOrientation">
<app-button
*ngIf="showPrevButton()"
#prevButton
[variant]="'secondary'"
[label]="'Précédent'"
[iconName]="'arrowBack'"
......@@ -10,7 +9,6 @@
/>
<app-button
*ngIf="showNextButton()"
#nextButton
[variant]="'primary'"
[label]="isLastStep ? 'Imprimer' : 'Suivant'"
[iconName]="isLastStep ? 'printer' : 'arrowForward'"
......
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Router } from '@angular/router';
import { ButtonComponent } from '../../../../shared/components';
import { NeedsTypes } from '../../enums/orientation.enums';
import { AllOrientationSteps } from '../../types/orientation.types';
......@@ -22,9 +21,6 @@ export class NavigationComponent {
@Output() goPrev = new EventEmitter<void>();
@Output() goReset = new EventEmitter<void>();
@ViewChild('prevButton', { read: ButtonComponent }) prevButton: ButtonComponent;
@ViewChild('nextButton', { read: ButtonComponent }) nextButton: ButtonComponent;
public NeedsTypeEnum = NeedsTypes;
constructor(private router: Router) {}
......@@ -51,12 +47,4 @@ export class NavigationComponent {
public resetOrientation(): void {
this.goReset.emit();
}
public focusFirstButton(): void {
if (this.showPrevButton()) {
this.prevButton.focus();
} else if (this.showNextButton()) {
this.nextButton.focus();
}
}
}
<div class="orientation" cdkTrapFocus [cdkTrapFocusAutoCapture]="true">
<h1 class="visually-hidden">Orientation</h1>
<div class="visually-hidden">
<p>Utilisez <strong>f</strong> (footer) pour aller directement aux boutons de validation.</p>
</div>
<app-progress-bar [currentPage]="currentStep" [nbSteps]="nbSteps" [formType]="formType.orientation" />
<div class="container" [ngClass]="{ 'no-max-width': fullScreen }">
<app-needs-selection *ngIf="currentStep === null" [(needType)]="needType" (validate)="validatePage(true)" />
......
import { AfterContentChecked, ChangeDetectorRef, Component, HostListener, OnInit, ViewChild } from '@angular/core';
import { AfterContentChecked, ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
import { AbstractControl, FormGroup, UntypedFormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { lastValueFrom } from 'rxjs';
......@@ -114,34 +114,6 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked
@ViewChild(NavigationComponent) navComponent!: NavigationComponent;
// Listener, keyboard shortcuts
@HostListener('window:keydown', ['$event'])
handleKeyboardEvent(event: KeyboardEvent): void {
const target = event.target as HTMLElement;
const tagName = target.tagName.toLowerCase();
// Check if the focus is within an input, textarea
if (tagName === 'input') {
const inputElement = target as HTMLInputElement;
const inputType = inputElement.type.toLowerCase();
// Ignore only text-based inputs, not others like radio, checkbox, etc.
if (!['radio', 'checkbox', 'button', 'submit', 'reset'].includes(inputType)) {
return;
}
} else if (tagName === 'textarea' || target.isContentEditable) {
return;
}
switch (event.key) {
case 'f': // 'f' to go to the navigation footer
this.navComponent.focusFirstButton();
event.preventDefault();
break;
default:
break;
}
}
constructor(
public orientationService: OrientationService,
private notificationService: NotificationService,
......
......@@ -235,13 +235,7 @@
<span class="name">{{ displayFullName }}</span>
</div>
<div class="profileMenuButtons">
<app-button
cdkFocusInitial
[variant]="'primaryBlack'"
[label]="'Voir mon compte'"
[size]="'small'"
(action)="goToProfile()"
/>
<app-button [variant]="'primaryBlack'" [label]="'Voir mon compte'" [size]="'small'" (action)="goToProfile()" />
<app-button [variant]="'secondary'" [label]="'Se déconnecter'" [size]="'small'" (action)="logout()" />
</div>
</div>
......
......@@ -29,7 +29,6 @@
</div>
<app-svg-icon
#closeButton
cdkFocusInitial
[asButton]="true"
[ariaLabel]="'Fermer'"
[folder]="'ico'"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment