Skip to content
Snippets Groups Projects
Commit 4e63abc9 authored by Marlène SIMONDANT's avatar Marlène SIMONDANT
Browse files

fix(Accessibility) : registry

parent 88f56db9
No related branches found
No related tags found
2 merge requests!846V3.1.0 (sans impression),!819fix(Accessibility) : registry
<div class="results" id="resultList"> <div class="results" id="resultList">
<div *ngIf="!isLogged && !isLoading" class="notConnected"> <div *ngIf="!isLogged && !isLoading" class="notConnected">
<img src="../../assets/ico/annuaire-unlogged.svg" alt="Illustration annuaire" /> <img src="../../assets/ico/annuaire-unlogged.svg" alt="" />
<div class="count" [ngPlural]="totalUserResult"> <div class="count" aria-live="polite" [ngPlural]="totalUserResult">
<ng-template ngPluralCase="0">Aucun membre n'est présent dans l'annuaire Rés'in</ng-template> <ng-template ngPluralCase="0">Aucun membre n'est présent dans l'annuaire Rés'in</ng-template>
<ng-template ngPluralCase="1">1 membre est présent dans l'annuaire Rés'in</ng-template> <ng-template ngPluralCase="1">1 membre est présent dans l'annuaire Rés'in</ng-template>
<ng-template ngPluralCase="other"> <ng-template ngPluralCase="other">
...@@ -46,10 +46,12 @@ ...@@ -46,10 +46,12 @@
[showAppointment]="true" [showAppointment]="true"
[showContactInfo]="false" [showContactInfo]="false"
[showEmployer]="true" [showEmployer]="true"
(keydown)="onMemberCardKeydown($event)"
/> />
<div *ngIf="showPagination && !isLoading" class="pagination"> <div *ngIf="showPagination && !isLoading" class="pagination">
<p>{{ userList.length }} membres affichés sur {{ totalUserResult }}</p> <p>{{ userList.length }} membres affichés sur {{ totalUserResult }}</p>
<app-button <app-button
aria-live="polite"
[label]="'Voir plus'" [label]="'Voir plus'"
[variant]="'primaryBlack'" [variant]="'primaryBlack'"
[size]="'medium'" [size]="'medium'"
...@@ -61,6 +63,6 @@ ...@@ -61,6 +63,6 @@
</div> </div>
</ng-container> </ng-container>
<div *ngIf="isLoading" class="loader" aria-busy="true"> <div *ngIf="isLoading" class="loader" aria-busy="true">
<img class="loader-gif" src="/assets/gif/loader_circle.gif" alt /> <img class="loader-gif" src="/assets/gif/loader_circle.gif" alt="Chargement en cours" />
</div> </div>
</div> </div>
import { AfterViewInit, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; import {
AfterViewInit,
Component,
ElementRef,
EventEmitter,
Input,
OnChanges,
Output,
SimpleChanges,
} from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { UserAnnuary } from '../../models/user.model'; import { UserAnnuary } from '../../models/user.model';
import { WindowScrollService } from '../../shared/service/windowScroll.service'; import { WindowScrollService } from '../../shared/service/windowScroll.service';
...@@ -12,6 +21,7 @@ export class ResultListComponent implements OnChanges, AfterViewInit { ...@@ -12,6 +21,7 @@ export class ResultListComponent implements OnChanges, AfterViewInit {
constructor( constructor(
private router: Router, private router: Router,
private windowScrollService: WindowScrollService, private windowScrollService: WindowScrollService,
private elementRef: ElementRef,
) {} ) {}
@Input() userList: UserAnnuary[]; @Input() userList: UserAnnuary[];
@Input() totalUserResult: number; @Input() totalUserResult: number;
...@@ -21,13 +31,13 @@ export class ResultListComponent implements OnChanges, AfterViewInit { ...@@ -21,13 +31,13 @@ export class ResultListComponent implements OnChanges, AfterViewInit {
@Output() showMoreEvent = new EventEmitter<void>(); @Output() showMoreEvent = new EventEmitter<void>();
public maxPerPage = 20; public maxPerPage = 20;
public showPagination = false; public showPagination = false;
public keyboardEvent = false;
public nextChildIndex: number;
ngAfterViewInit(): void { ngAfterViewInit(): void {
// Delay required before all member-card components are displayed on the page requestAnimationFrame(() => {
setTimeout( document.getElementById('app-body')?.scrollTo({ top: this.windowScrollService.scrollYToPreserve.value });
() => document.getElementById('app-body')?.scrollTo({ top: this.windowScrollService.scrollYToPreserve.value }), });
10,
);
} }
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
...@@ -35,6 +45,13 @@ export class ResultListComponent implements OnChanges, AfterViewInit { ...@@ -35,6 +45,13 @@ export class ResultListComponent implements OnChanges, AfterViewInit {
this.showPagination = true; this.showPagination = true;
} }
if (this.userList.length >= this.totalUserResult) this.showPagination = false; if (this.userList.length >= this.totalUserResult) this.showPagination = false;
// Accessibility: after click on "view more" button, send focus to the first newly displayed member card
if (this.keyboardEvent && this.nextChildIndex) {
requestAnimationFrame(() => {
this.setFocusOnFirstNewMemberCard();
});
}
} }
public goToUser(userId: string): void { public goToUser(userId: string): void {
this.router.navigateByUrl(`/profile/${userId}`); this.router.navigateByUrl(`/profile/${userId}`);
...@@ -48,7 +65,29 @@ export class ResultListComponent implements OnChanges, AfterViewInit { ...@@ -48,7 +65,29 @@ export class ResultListComponent implements OnChanges, AfterViewInit {
public resetFilters(): void { public resetFilters(): void {
this.resetEvent.emit(); this.resetEvent.emit();
} }
public onMemberCardKeydown(event: KeyboardEvent): void {
switch (event.key) {
case 'ArrowUp':
case 'ArrowDown':
case 'Tab':
this.keyboardEvent = true;
break;
}
}
private setFocusOnFirstNewMemberCard(): void {
const lastFocusedMemberCard = this.elementRef.nativeElement.querySelector(
`.users app-member-card:nth-child(${this.nextChildIndex}) > div`,
);
if (lastFocusedMemberCard) {
const focusedElement = lastFocusedMemberCard as HTMLElement;
focusedElement.focus();
}
}
public showMore(): void { public showMore(): void {
this.nextChildIndex = this.userList.length + 1;
this.showMoreEvent.emit(); this.showMoreEvent.emit();
} }
} }
...@@ -80,15 +80,30 @@ ...@@ -80,15 +80,30 @@
</div> </div>
<div class="sectionContent infoSection"> <div class="sectionContent infoSection">
<div class="row"> <div class="row">
<app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'address'" /> <app-svg-icon
[attr.aria-label]="'Adresse postale'"
[iconClass]="'icon-20'"
[folder]="'tags'"
[icon]="'address'"
/>
{{ getAddress() }} {{ getAddress() }}
</div> </div>
<div *ngIf="structure.contactPhone" class="row"> <div *ngIf="structure.contactPhone" class="row">
<app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'phone'" /> <app-svg-icon
[attr.aria-label]="'Numéro de téléphone'"
[iconClass]="'icon-20'"
[folder]="'tags'"
[icon]="'phone'"
/>
{{ structure.contactPhone | phone }} {{ structure.contactPhone | phone }}
</div> </div>
<div *ngIf="structure.contactMail" class="row"> <div *ngIf="structure.contactMail" class="row">
<app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'mail'" /> <app-svg-icon
[attr.aria-label]="'Adresse e-mail'"
[iconClass]="'icon-20'"
[folder]="'tags'"
[icon]="'mail'"
/>
<a href="mailto:{{ structure.contactMail }}">{{ structure.contactMail }}</a> <a href="mailto:{{ structure.contactMail }}">{{ structure.contactMail }}</a>
</div> </div>
</div> </div>
......
...@@ -44,11 +44,21 @@ ...@@ -44,11 +44,21 @@
</div> </div>
<div class="block contact"> <div class="block contact">
<div class="row"> <div class="row">
<app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'phone'" /> <app-svg-icon
[attr.aria-label]="'Numéro de téléphone'"
[iconClass]="'icon-20'"
[folder]="'tags'"
[icon]="'phone'"
/>
<div>{{ userProfile.phone | phone }}</div> <div>{{ userProfile.phone | phone }}</div>
</div> </div>
<div class="row"> <div class="row">
<app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'mail'" /> <app-svg-icon
[attr.aria-label]="'Adresse e-mail'"
[iconClass]="'icon-20'"
[folder]="'tags'"
[icon]="'mail'"
/>
<a href="mailto:{{ userProfile.email }}">{{ userProfile.email }}</a> <a href="mailto:{{ userProfile.email }}">{{ userProfile.email }}</a>
</div> </div>
<div *ngIf="isPublic && userProfile.withAppointment" class="row"> <div *ngIf="isPublic && userProfile.withAppointment" class="row">
......
<button <button
type="button" type="button"
[attr.aria-label]="'Déplier les filtres : ' + label"
[ngClass]="{ [ngClass]="{
expanded: expanded, expanded: expanded,
active: active active: active
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<p>{{ getJob() }}</p> <p>{{ getJob() }}</p>
<div *ngIf="showAppointment && member.withAppointment" class="appointment"> <div *ngIf="showAppointment && member.withAppointment" class="appointment">
<app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'rdv'" /> <app-svg-icon [iconClass]="'icon-20'" [folder]="'tags'" [icon]="'rdv'" />
<span>Rendez-vous</span> <span aria-label="Prise de rendez-vous possible">Rendez-vous</span>
</div> </div>
</div> </div>
<div *ngIf="showContactInfo" class="infoDetails"> <div *ngIf="showContactInfo" class="infoDetails">
......
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