Fixed dropdown accessibility issue

- Removed non-existing dropdownMenuButton references
- Added appropriate roles to dropdown menus
This commit is contained in:
Alexandre Vryghem
2023-12-26 11:26:08 +01:00
committed by Tim Donohue
parent 63fa8f39f5
commit 3e48e5903e
11 changed files with 44 additions and 34 deletions

View File

@@ -15,10 +15,10 @@
[attr.data-test]="'import-dropdown' | dsBrowserOnly" [attr.data-test]="'import-dropdown' | dsBrowserOnly"
title="{{'mydspace.new-submission-external' | translate}}"> title="{{'mydspace.new-submission-external' | translate}}">
<i class="fa fa-file-import" aria-hidden="true"></i> <i class="fa fa-file-import" aria-hidden="true"></i>
<span class="caret"></span> <span class="caret" aria-hidden="true"></span>
</button> </button>
<div ngbDropdownMenu <div ngbDropdownMenu
class="dropdown-menu" class="dropdown-menu p-0"
id="importControlsDropdownMenu" id="importControlsDropdownMenu"
aria-labelledby="dropdownImport"> aria-labelledby="dropdownImport">
<ds-entity-dropdown [isSubmission]="false" (selectionChange)="openPage($event)"></ds-entity-dropdown> <ds-entity-dropdown [isSubmission]="false" (selectionChange)="openPage($event)"></ds-entity-dropdown>

View File

@@ -13,10 +13,10 @@
[attr.data-test]="'submission-dropdown' | dsBrowserOnly" [attr.data-test]="'submission-dropdown' | dsBrowserOnly"
title="{{'mydspace.new-submission' | translate}}"> title="{{'mydspace.new-submission' | translate}}">
<i class="fa fa-plus-circle" aria-hidden="true"></i> <i class="fa fa-plus-circle" aria-hidden="true"></i>
<span class="caret"></span> <span class="caret" aria-hidden="true"></span>
</button> </button>
<div ngbDropdownMenu <div ngbDropdownMenu
class="dropdown-menu" class="dropdown-menu p-0"
id="entityControlsDropdownMenu" id="entityControlsDropdownMenu"
aria-labelledby="dropdownSubmission"> aria-labelledby="dropdownSubmission">
<ds-entity-dropdown [isSubmission]="true" (selectionChange)="openDialog($event)"></ds-entity-dropdown> <ds-entity-dropdown [isSubmission]="true" (selectionChange)="openDialog($event)"></ds-entity-dropdown>

View File

@@ -1,4 +1,4 @@
<div *ngIf="searchField" class="form-group w-100 pr-2 pl-2"> <div *ngIf="searchField" class="form-group w-100 pr-2 pl-2 my-2">
<input type="search" <input type="search"
class="form-control w-100" class="form-control w-100"
(click)="$event.stopPropagation();" (click)="$event.stopPropagation();"
@@ -6,9 +6,9 @@
[formControl]="searchField" [formControl]="searchField"
#searchFieldEl> #searchFieldEl>
</div> </div>
<div class="dropdown-divider"></div> <div class="dropdown-divider m-0"></div>
<ul class="scrollable-menu p-0" <ul class="scrollable-menu p-0 m-0"
aria-labelledby="dropdownMenuButton" role="menu"
(scroll)="onScroll($event)" (scroll)="onScroll($event)"
infiniteScroll infiniteScroll
[infiniteScrollDistance]="1.5" [infiniteScrollDistance]="1.5"
@@ -18,12 +18,13 @@
[scrollWindow]="false" [scrollWindow]="false"
(scrolled)="onScrollDown()"> (scrolled)="onScrollDown()">
<li class="dropdown-item disabled" *ngIf="searchListCollection?.length == 0 && !(isLoading | async)"> <li class="dropdown-item disabled" role="menuitem" *ngIf="searchListCollection?.length == 0 && !(isLoading | async)">
{{'submission.sections.general.no-collection' | translate}} {{'submission.sections.general.no-collection' | translate}}
</li> </li>
<ng-container *ngIf="searchListCollection?.length > 0"> <ng-container *ngIf="searchListCollection?.length > 0">
<li *ngFor="let listItem of searchListCollection" <li *ngFor="let listItem of searchListCollection"
class="dropdown-item collection-item" class="dropdown-item collection-item"
role="menuitem"
title="{{ listItem.collection.name }}" title="{{ listItem.collection.name }}"
(click)="onSelect(listItem)"> (click)="onSelect(listItem)">
<div class="list-unstyled mb-0"> <div class="list-unstyled mb-0">
@@ -34,9 +35,10 @@
</div> </div>
</li> </li>
</ng-container> </ng-container>
<button class="dropdown-item disabled" *ngIf="(isLoading | async)"> <li *ngIf="(isLoading | async)">
<ds-themed-loading message="{{'loading.default' | translate}}"> <button class="dropdown-item disabled">
</ds-themed-loading> <ds-themed-loading message="{{'loading.default' | translate}}">
</button> </ds-themed-loading>
</button>
</li>
</ul> </ul>

View File

@@ -4,7 +4,8 @@
overflow-x: hidden; overflow-x: hidden;
} }
.collection-item { li:not(:last-of-type), .dropdown-divider {
border-top: none;
border-bottom: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color); border-bottom: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);
} }

View File

@@ -22,7 +22,7 @@
class="dropdown-menu" class="dropdown-menu"
id="dsSelectDropdownMenu" id="dsSelectDropdownMenu"
aria-labelledby="dsSelectMenuButton"> aria-labelledby="dsSelectMenuButton">
<div aria-labelledby="dropdownMenuButton"> <div>
<ng-content select=".menu"></ng-content> <ng-content select=".menu"></ng-content>
</div> </div>
</div> </div>

View File

@@ -1,6 +1,5 @@
<div <ul class="scrollable-menu list-unstyled mb-0"
class="scrollable-menu" role="menu"
aria-labelledby="dropdownMenuButton"
(scroll)="onScroll($event)" (scroll)="onScroll($event)"
infiniteScroll infiniteScroll
[infiniteScrollDistance]="5" [infiniteScrollDistance]="5"
@@ -9,20 +8,23 @@
[fromRoot]="true" [fromRoot]="true"
[scrollWindow]="false" [scrollWindow]="false"
(scrolled)="onScrollDown()"> (scrolled)="onScrollDown()">
<button class="dropdown-item disabled" *ngIf="searchListEntity?.length == 0 && !(isLoadingList | async)"> <li *ngIf="searchListEntity?.length == 0 && !(isLoadingList | async)">
<button class="dropdown-item disabled" role="menuitem">
{{'submission.sections.general.no-entity' | translate}} {{'submission.sections.general.no-entity' | translate}}
</button> </button>
<button *ngFor="let listItem of searchListEntity" </li>
class="dropdown-item entity-item" <li *ngFor="let listItem of searchListEntity" class="entity-item text-primary">
<button class="dropdown-item"
role="menuitem"
title="{{ listItem.label }}" title="{{ listItem.label }}"
(click)="onSelect(listItem)"> (click)="onSelect(listItem)">
<ul class="list-unstyled mb-0"> <span class="text-truncate font-weight-bold">{{ listItem.label.toLowerCase() + '.listelement.badge' | translate }}</span>
<li class="list-item text-truncate text-primary font-weight-bold">{{ listItem.label.toLowerCase() + '.listelement.badge' | translate }}</li>
</ul>
</button> </button>
<button class="dropdown-item disabled" *ngIf="(isLoadingList | async)" > </li>
<li *ngIf="(isLoadingList | async)">
<button class="dropdown-item disabled" role="menuitem">
<ds-themed-loading message="{{'loading.default' | translate}}"> <ds-themed-loading message="{{'loading.default' | translate}}">
</ds-themed-loading> </ds-themed-loading>
</button> </button>
</li>
</div> </ul>

View File

@@ -1,5 +1,9 @@
.list-item:active { .dropdown-item {
color: white !important; padding: 0.35rem 1rem;
&:active {
color: white !important;
}
} }
.scrollable-menu { .scrollable-menu {
@@ -8,7 +12,7 @@
overflow-x: hidden; overflow-x: hidden;
} }
.entity-item { li:not(:last-of-type) .dropdown-item {
border-bottom: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color); border-bottom: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);
} }

View File

@@ -123,7 +123,7 @@ describe('EntityDropdownComponent', () => {
scheduler.flush(); scheduler.flush();
spyOn(component, 'onSelect'); spyOn(component, 'onSelect');
const entityItem = fixture.debugElement.query(By.css('.entity-item:nth-child(2)')); const entityItem = fixture.debugElement.query(By.css('.entity-item:nth-child(2) button'));
entityItem.triggerEventHandler('click', null); entityItem.triggerEventHandler('click', null);
scheduler.schedule(() => fixture.detectChanges()); scheduler.schedule(() => fixture.detectChanges());

View File

@@ -88,7 +88,6 @@
aria-expanded="false" aria-expanded="false"
[attr.aria-labelledby]="'label_' + model.id"> [attr.aria-labelledby]="'label_' + model.id">
<div class="scrollable-menu" <div class="scrollable-menu"
aria-labelledby="scrollableDropdownMenuButton"
infiniteScroll infiniteScroll
[infiniteScrollDistance]="2" [infiniteScrollDistance]="2"
[infiniteScrollThrottle]="50" [infiniteScrollThrottle]="50"

View File

@@ -32,7 +32,7 @@
</button> </button>
<div ngbDropdownMenu <div ngbDropdownMenu
class="dropdown-menu" class="dropdown-menu p-0"
id="collectionControlsDropdownMenu" id="collectionControlsDropdownMenu"
aria-labelledby="collectionControlsMenuButton"> aria-labelledby="collectionControlsMenuButton">
<ds-themed-collection-dropdown <ds-themed-collection-dropdown

View File

@@ -4446,6 +4446,8 @@
"submission.sections.general.no-collection": "No collection found", "submission.sections.general.no-collection": "No collection found",
"submission.sections.general.no-entity": "No entity types found",
"submission.sections.general.no-sections": "No options available", "submission.sections.general.no-sections": "No options available",
"submission.sections.general.save_error_notice": "There was an issue when saving the item, please try again later.", "submission.sections.general.save_error_notice": "There was an issue when saving the item, please try again later.",