Skip to content

Commit 8b88e7f

Browse files
authored
Merge pull request #1252 from 4Science/#1171
Fix accessibility issues #1172 #1167 #1171
2 parents 88c5910 + 6cadae4 commit 8b88e7f

File tree

36 files changed

+247
-142
lines changed

36 files changed

+247
-142
lines changed

src/app/+item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@
1919
.drag-handle {
2020
visibility: hidden;
2121
&:hover {
22-
cursor: grab;
22+
cursor: move;
2323
}
2424
}
2525

26-
:host ::ng-deep .bitstream-row:hover .drag-handle {
26+
.bitstream-row-drag-handle:hover {
27+
cursor: move;
28+
}
29+
30+
:host ::ng-deep .bitstream-row:hover .drag-handle, :host ::ng-deep .bitstream-row-drag-handle:focus .drag-handle {
2731
visibility: visible !important;
2832
}
2933

@@ -40,3 +44,9 @@
4044
.cdk-drag-animating {
4145
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
4246
}
47+
48+
.cdk-drop-list-dragging {
49+
.bitstream-row-drag-handle, .drag-handle {
50+
cursor: grabbing;
51+
}
52+
}

src/app/+item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<ds-item-edit-bitstream [fieldUpdate]="updates[uuid]"
2222
[bundleUrl]="bundle.self"
2323
[columnSizes]="columnSizes">
24-
<div class="d-flex align-items-center" slot="drag-handle" cdkDragHandle>
24+
<div class="d-flex align-items-center bitstream-row-drag-handle" slot="drag-handle" cdkDragHandle tabindex="0">
2525
<ds-item-edit-bitstream-drag-handle></ds-item-edit-bitstream-drag-handle>
2626
</div>
2727
</ds-item-edit-bitstream>
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<ng-template #handleView>
2-
<div class="drag-handle text-muted float-left p-1 mr-2">
2+
<div class="drag-handle text-muted float-left p-1 mr-2" tabindex="0">
33
<i class="fas fa-grip-vertical fa-fw" [title]="'item.edit.bitstreams.edit.buttons.drag' | translate"></i>
44
</div>
55
</ng-template>

src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<span>{{metadata?.value}}</span>
3030
</div>
3131
<div *ngIf="(editable | async)" class="field-container">
32-
<textarea class="form-control" type="textarea" [(ngModel)]="metadata.value" [dsDebounce]
32+
<textarea class="form-control" type="textarea" attr.aria-labelledby="fieldValue" [(ngModel)]="metadata.value" [dsDebounce]
3333
(onDebounce)="update()"></textarea>
3434
</div>
3535
</div>
@@ -40,7 +40,7 @@
4040
<span>{{metadata?.language}}</span>
4141
</div>
4242
<div *ngIf="(editable | async)" class="field-container">
43-
<input class="form-control" type="text" [(ngModel)]="metadata.language" [dsDebounce]
43+
<input class="form-control" type="text" attr.aria-labelledby="fieldLang" [(ngModel)]="metadata.language" [dsDebounce]
4444
(onDebounce)="update()"/>
4545
</div>
4646
</div>

src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
<table class="table table-responsive table-striped table-bordered" *ngIf="((updates$ | async)| dsObjectValues).length > 0">
2626
<tbody>
2727
<tr>
28-
<th>{{'item.edit.metadata.headers.field' | translate}}</th>
29-
<th>{{'item.edit.metadata.headers.value' | translate}}</th>
30-
<th class="text-center">{{'item.edit.metadata.headers.language' | translate}}</th>
28+
<th><span id="fieldName">{{'item.edit.metadata.headers.field' | translate}}</span></th>
29+
<th><span id="fieldValue">{{'item.edit.metadata.headers.value' | translate}}</span></th>
30+
<th class="text-center"><span id="fieldLang">{{'item.edit.metadata.headers.language' | translate}}</span></th>
3131
<th class="text-center">{{'item.edit.metadata.headers.edit' | translate}}</th>
3232
</tr>
3333
<tr *ngFor="let updateValue of ((updates$ | async)| dsObjectValues); trackBy: trackUpdate"

src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<li class="nav-item dropdown"
2+
(keyup.enter)="activateSection($event)"
23
(mouseenter)="activateSection($event)"
34
(mouseleave)="deactivateSection($event)">
45
<a href="#" class="nav-link dropdown-toggle" routerLinkActive="active"

src/app/search-navbar/search-navbar.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<div id="search-navbar-container" [title]="'nav.search' | translate" (dsClickOutside)="collapse()">
22
<div class="d-inline-block position-relative">
33
<form [formGroup]="searchForm" (ngSubmit)="onSubmit(searchForm.value)" autocomplete="on">
4-
<input #searchInput [@toggleAnimation]="isExpanded" id="query" name="query"
4+
<input #searchInput [@toggleAnimation]="isExpanded" [attr.aria-label]="('nav.search' | translate)" name="query"
55
formControlName="query" type="text" placeholder="{{searchExpanded ? ('nav.search' | translate) : ''}}"
66
class="d-inline-block bg-transparent position-absolute form-control dropdown-menu-right p-1">
7-
<a class="submit-icon" (click)="searchExpanded ? onSubmit(searchForm.value) : expand()">
7+
<a class="submit-icon" [routerLink]="" (click)="searchExpanded ? onSubmit(searchForm.value) : expand()">
88
<em class="fas fa-search fa-lg fa-fw"></em>
99
</a>
1010
</form>

src/app/search-navbar/search-navbar.component.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ a.submit-icon {
1717
}
1818

1919
@media screen and (max-width: map-get($grid-breakpoints, md)) {
20-
#query:focus {
20+
.query:focus {
2121
max-width: 250px !important;
2222
width: 40vw !important;
2323
}

src/app/shared/auth-nav-menu/auth-nav-menu.component.html

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,26 @@
22
<li *ngIf="!(isAuthenticated | async) && !(isXsOrSm$ | async) && (showAuth | async)" class="nav-item"
33
(click)="$event.stopPropagation();">
44
<div ngbDropdown #loginDrop display="dynamic" placement="bottom-right" class="d-inline-block" @fadeInOut>
5-
<a href="#" id="dropdownLogin" (click)="$event.preventDefault()" ngbDropdownToggle
6-
class="px-1">{{ 'nav.login' | translate }}</a>
7-
<div id="loginDropdownMenu" [ngClass]="{'pl-3 pr-3': (loading | async)}" ngbDropdownMenu
8-
aria-labelledby="dropdownLogin">
5+
<a href="#" class="dropdownLogin px-1 " [attr.aria-label]="'nav.login' |translate" (click)="$event.preventDefault()" ngbDropdownToggle>
6+
{{ 'nav.login' | translate }}
7+
</a>
8+
<div class="loginDropdownMenu" [ngClass]="{'pl-3 pr-3': (loading | async)}" ngbDropdownMenu
9+
[attr.aria-label]="'nav.login' |translate">
910
<ds-log-in
1011
[isStandalonePage]="false"></ds-log-in>
1112
</div>
1213
</div>
1314
</li>
1415
<li *ngIf="!(isAuthenticated | async) && (isXsOrSm$ | async)" class="nav-item">
15-
<a id="loginLink" routerLink="/login" routerLinkActive="active" class="px-1">
16+
<a routerLink="/login" routerLinkActive="active" class="loginLink px-1">
1617
{{ 'nav.login' | translate }}<span class="sr-only">(current)</span>
1718
</a>
1819
</li>
1920
<li *ngIf="(isAuthenticated | async) && !(isXsOrSm$ | async) && (showAuth | async)" class="nav-item">
2021
<div ngbDropdown display="dynamic" placement="bottom-right" class="d-inline-block" @fadeInOut>
21-
<a href="#" id="dropdownUser" role="button" [attr.aria-label]="'nav.logout' |translate" (click)="$event.preventDefault()" [title]="'nav.logout' | translate" class="px-1" ngbDropdownToggle>
22+
<a href="#" role="button" [attr.aria-label]="'nav.logout' |translate" (click)="$event.preventDefault()" [title]="'nav.logout' | translate" class="px-1" ngbDropdownToggle>
2223
<i class="fas fa-user-circle fa-lg fa-fw"></i></a>
23-
<div id="logoutDropdownMenu" ngbDropdownMenu aria-labelledby="dropdownUser">
24+
<div class="logoutDropdownMenu" ngbDropdownMenu [attr.aria-label]="'nav.logout' |translate">
2425
<ds-user-menu></ds-user-menu>
2526
</div>
2627
</div>

src/app/shared/auth-nav-menu/auth-nav-menu.component.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
#loginDropdownMenu, #logoutDropdownMenu {
1+
.loginDropdownMenu, .logoutDropdownMenu {
22
min-width: 330px;
33
z-index: 1002;
44
}
55

6-
#loginDropdownMenu {
6+
.loginDropdownMenu {
77
min-height: 260px;
88
}
99

src/app/shared/auth-nav-menu/auth-nav-menu.component.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ describe('AuthNavMenuComponent', () => {
208208
});
209209

210210
it('should render login dropdown menu', () => {
211-
const loginDropdownMenu = deNavMenuItem.query(By.css('div[id=loginDropdownMenu]'));
211+
const loginDropdownMenu = deNavMenuItem.query(By.css('div.loginDropdownMenu'));
212212
expect(loginDropdownMenu.nativeElement).toBeDefined();
213213
});
214214
});
@@ -320,7 +320,7 @@ describe('AuthNavMenuComponent', () => {
320320
});
321321

322322
it('should render login link', () => {
323-
const loginDropdownMenu = deNavMenuItem.query(By.css('a[id=loginLink]'));
323+
const loginDropdownMenu = deNavMenuItem.query(By.css('.loginLink'));
324324
expect(loginDropdownMenu.nativeElement).toBeDefined();
325325
});
326326
});

src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
[formGroup]="group"
33
[ngClass]="[getClass('element', 'container'), getClass('grid', 'container')]">
44
<label *ngIf="!isCheckbox && hasLabel"
5-
[for]="model.id"
5+
[id]="'label_' + model.id"
6+
[for]="id"
67
[innerHTML]="(model.required && model.label) ? (model.label | translate) + ' *' : (model.label | translate)"
78
[ngClass]="[getClass('element', 'label'), getClass('grid', 'label')]"></label>
89
<ng-container *ngTemplateOutlet="startTemplate?.templateRef; context: model"></ng-container>

src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
[cdkDragDisabled]="dragDisabled"
1616
[cdkDragPreviewClass]="'ds-submission-reorder-dragging'">
1717
<!-- Item content -->
18-
<i class="drag-icon fas fa-grip-vertical fa-fw" [class.invisible]="dragDisabled"></i>
18+
<div class="drag-handle" [class.invisible]="dragDisabled" tabindex="0">
19+
<i class="drag-icon fas fa-grip-vertical fa-fw" ></i>
20+
</div>
1921
<ng-container *ngTemplateOutlet="startTemplate?.templateRef; context: groupModel"></ng-container>
2022
<ds-dynamic-form-control-container *ngFor="let _model of groupModel.group"
2123
[bindId]="false"

src/app/shared/form/builder/ds-dynamic-form-ui/models/array-group/dynamic-form-array.component.scss

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,20 @@
2626

2727
}
2828

29+
.drag-handle {
30+
&:hover {
31+
cursor: move;
32+
}
33+
34+
&:focus {
35+
.drag-icon {
36+
visibility: visible;
37+
}
38+
}
39+
}
40+
2941
.cdk-drop-list-dragging {
30-
.cdk-drag {
42+
.drag-handle {
3143
cursor: grabbing;
3244
.drag-icon {
3345
visibility: hidden;

src/app/shared/form/builder/ds-dynamic-form-ui/models/date-picker-inline/dynamic-date-picker-inline.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<div [formGroup]="group" class="input-group">
22

33
<input ngbDatepicker class="form-control" #datepicker="ngbDatepicker"
4+
[attr.aria-labelledby]="'label_' + model.id"
45
[class.is-invalid]="showErrorMessages"
56
[displayMonths]="model.getAdditional('displayMonths', config['displayMonths'])"
67
[id]="id"
@@ -26,6 +27,7 @@
2627

2728
<button class="btn btn-outline-secondary"
2829
type="button"
30+
[attr.aria-labelledby]="'label_' + model.id"
2931
[class.disabled]="model.disabled"
3032
[disabled]="model.disabled"
3133
(click)="datepicker.toggle()">

src/app/shared/form/builder/ds-dynamic-form-ui/models/list/dynamic-list.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<div *ngFor="let item of columnItems" class="custom-control custom-checkbox">
1212

1313
<input type="checkbox" class="custom-control-input"
14+
[attr.aria-labelledby]="'label_' + model.id"
1415
[attr.tabindex]="item.index"
1516
[checked]="item.value"
1617
[id]="item.id"

src/app/shared/form/builder/ds-dynamic-form-ui/models/lookup/dynamic-lookup.component.html

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
[authorityValue]="model.value"
1212
(whenClickOnConfidenceNotAccepted)="whenClickOnConfidenceNotAccepted(sdRef, $event)"></i>
1313
<input class="form-control"
14+
[attr.aria-labelledby]="'label_' + model.id"
1415
[attr.autoComplete]="model.autoComplete"
1516
[class.is-invalid]="showErrorMessages"
1617
[id]="model.id"
@@ -30,6 +31,7 @@
3031
<div *ngIf="isLookupName()" class="col" >
3132
<input class="form-control"
3233
[ngClass]="{}"
34+
[attr.aria-labelledby]="'label_' + model.id"
3335
[attr.autoComplete]="model.autoComplete"
3436
[class.is-invalid]="showErrorMessages"
3537
[id]="id"
@@ -84,7 +86,7 @@
8486
class="dropdown-menu scrollable-dropdown-menu w-100"
8587
aria-haspopup="true"
8688
aria-expanded="false"
87-
aria-labelledby="scrollableDropdownMenuButton">
89+
[attr.aria-labelledby]="'label_' + model.id">
8890
<div class="scrollable-menu"
8991
aria-labelledby="scrollableDropdownMenuButton"
9092
infiniteScroll
@@ -112,7 +114,7 @@
112114
</div>
113115

114116
<ng-template #hasInfo let-entry="entry">
115-
<ul class="list-unstyled mb-0">
117+
<ul class="list-unstyled mb-0" [attr.aria-labelledby]="'label_' + model.id">
116118
<li class="list-item text-truncate text-primary font-weight-bold">{{entry.value}}</li>
117119
<li class="list-item text-truncate text-secondary" *ngFor="let item of entry.otherInformation | dsObjNgFor" >
118120
{{ 'form.other-information.' + item.key | translate }} : {{item.value}}
@@ -121,7 +123,7 @@
121123
</ng-template>
122124

123125
<ng-template #noInfo let-entry="entry">
124-
<ul class="list-unstyled mb-0">
126+
<ul class="list-unstyled mb-0" [attr.aria-labelledby]="'label_' + model.id">
125127
<li class="list-item text-truncate text-primary font-weight-bold">{{entry.value}}</li>
126128
</ul>
127129
</ng-template>

src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.html

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
(whenClickOnConfidenceNotAccepted)="whenClickOnConfidenceNotAccepted($event)"></i>
3131
<input #instance="ngbTypeahead"
3232
class="form-control"
33+
[attr.aria-labelledby]="'label_' + model.id"
3334
[attr.autoComplete]="model.autoComplete"
3435
[class.is-invalid]="showErrorMessages"
3536
[id]="model.id"
@@ -50,19 +51,24 @@
5051
<div class="invalid-feedback" *ngIf="searchFailed">Sorry, suggestions could not be loaded.</div>
5152
</div>
5253

53-
<input *ngIf="(isHierarchicalVocabulary() | async)"
54-
class="form-control custom-select"
55-
[attr.autoComplete]="model.autoComplete"
56-
[class.is-invalid]="showErrorMessages"
57-
[id]="id"
58-
[name]="model.name"
59-
[placeholder]="model.placeholder"
60-
[readonly]="model.readOnly"
61-
[type]="model.inputType"
62-
[value]="currentValue?.display"
63-
(focus)="onFocus($event)"
64-
(change)="onChange($event)"
65-
(click)="openTree($event)"
66-
(keydown)="$event.preventDefault()"
67-
(keypress)="$event.preventDefault()"
68-
(keyup)="$event.preventDefault()">
54+
<div *ngIf="(isHierarchicalVocabulary() | async)" class="position-relative right-addon">
55+
<i class="dropdown-toggle position-absolute tree-toggle" (click)="openTree($event)"
56+
aria-hidden="true"></i>
57+
<input class="form-control"
58+
[attr.aria-labelledby]="'label_' + model.id"
59+
[attr.autoComplete]="model.autoComplete"
60+
[class.is-invalid]="showErrorMessages"
61+
[class.tree-input]="!model.readOnly"
62+
[id]="id"
63+
[name]="model.name"
64+
[placeholder]="model.placeholder"
65+
[readonly]="true"
66+
[type]="model.inputType"
67+
[value]="currentValue?.display"
68+
(focus)="onFocus($event)"
69+
(change)="onChange($event)"
70+
(click)="openTree($event)"
71+
(keydown)="$event.preventDefault()"
72+
(keypress)="$event.preventDefault()"
73+
(keyup)="$event.preventDefault()">
74+
</div>

src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@import '../../../../form.component';
2+
13
:host ::ng-deep .dropdown-menu {
24
width: 100% !important;
35
max-height: var(--ds-dropdown-menu-max-height);
@@ -21,3 +23,11 @@
2123
max-height: 85vh !important;
2224
overflow-y: auto;
2325
}
26+
27+
.tree-toggle {
28+
padding: 0.70rem 0.70rem 0 0.70rem ;
29+
}
30+
31+
.tree-input[readonly]{
32+
background-color: #fff;
33+
}

src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.html

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
1-
<div #sdRef="ngbDropdown" ngbDropdown class="w-100">
2-
<input ngbDropdownToggle class="form-control custom-select"
3-
[attr.autoComplete]="model.autoComplete"
4-
[class.is-invalid]="showErrorMessages"
5-
[id]="id"
6-
[name]="model.name"
7-
[readonly]="model.readOnly"
8-
[type]="model.inputType"
9-
[value]="(currentValue | async)"
10-
(blur)="onBlur($event)"
11-
(click)="$event.stopPropagation(); openDropdown(sdRef);"
12-
(focus)="onFocus($event)"
13-
(keypress)="$event.preventDefault()">
1+
<div #sdRef="ngbDropdown" ngbDropdown display="dynamic" placement="bottom-right" class="w-100">
2+
<div class="position-relative right-addon">
3+
<i ngbDropdownToggle class="position-absolute scrollable-dropdown-toggle"
4+
aria-hidden="true"></i>
5+
<input class="form-control"
6+
[attr.aria-label]="model.placeholder"
7+
[attr.autoComplete]="model.autoComplete"
8+
[class.is-invalid]="showErrorMessages"
9+
[class.scrollable-dropdown-input]="!model.readOnly"
10+
[id]="id"
11+
[name]="model.name"
12+
[readonly]="true"
13+
[type]="model.inputType"
14+
[value]="(currentValue | async)"
15+
(blur)="onBlur($event)"
16+
(click)="$event.stopPropagation(); openDropdown(sdRef);"
17+
(focus)="onFocus($event)"
18+
(keypress)="$event.preventDefault()">
19+
</div>
1420

1521
<div ngbDropdownMenu
1622
class="dropdown-menu scrollable-dropdown-menu w-100"
1723
aria-haspopup="true"
1824
aria-expanded="false"
19-
aria-labelledby="scrollableDropdownMenuButton">
25+
[attr.aria-label]="model.placeholder">
2026
<div class="scrollable-menu"
21-
aria-labelledby="scrollableDropdownMenuButton"
27+
[attr.aria-label]="model.placeholder"
2228
infiniteScroll
2329
[infiniteScrollDistance]="2"
2430
[infiniteScrollThrottle]="50"

0 commit comments

Comments
 (0)