forked from hazza/dspace-angular
Fixed dropdown accessibility issue
- Removed non-existing dropdownMenuButton references - Added appropriate roles to dropdown menus
This commit is contained in:

committed by
Tim Donohue

parent
63fa8f39f5
commit
3e48e5903e
@@ -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>
|
||||||
|
@@ -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>
|
||||||
|
@@ -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>
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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>
|
||||||
|
@@ -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>
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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());
|
||||||
|
@@ -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"
|
||||||
|
@@ -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
|
||||||
|
@@ -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.",
|
||||||
|
Reference in New Issue
Block a user