Skip to content

Commit f7bb678

Browse files
authored
Merge pull request #238 from biig-io/feature/accessibility-modal
Add a11y for modal composant. Add documentation about it
2 parents 5c88ba1 + c42cb0d commit f7bb678

File tree

12 files changed

+160
-27
lines changed

12 files changed

+160
-27
lines changed

src/app/demo/autostart/autostart.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ <h1 class="title">Autostarted modal</h1>
2323
<!-- Classic modal -->
2424
<ngx-smart-modal #classicModal
2525
[identifier]="'classicModal'"
26-
[autostart]="true">
26+
[autostart]="true"
27+
ariaLabel="Autostarted modal">
2728
<h1>Hey, I'm an autostarted modal!</h1>
2829
<img class="modal-image"
2930
src="https://placeimg.com/627/200/tech"

src/app/demo/bootstrap/bootstrap.component.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ <h1 class="display-1">Boostrap Modal</h1>
1515
</div>
1616
</div>
1717

18-
<ngx-smart-modal #myBootstrapModal identifier="myBootstrapModal" [closable]="false"
19-
customClass="modal-content no-padding">
18+
<ngx-smart-modal #myBootstrapModal
19+
identifier="myBootstrapModal"
20+
customClass="modal-content no-padding"
21+
ariaLabel="Boostrap modal"
22+
[closable]="false">
2023
<div class="modal-header">
2124
<h5 class="modal-title">Modal title</h5>
2225
<button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="myBootstrapModal.close()">

src/app/demo/feature/feature.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ <h1 class="title">ngx-smart-modal with feature module</h1>
2222

2323
<!-- Classic modal -->
2424
<ngx-smart-modal #classicModal
25-
[identifier]="'classicModal'">
25+
[identifier]="'classicModal'"
26+
ariaLabel="Simple modal">
2627
<h1>Hey, I'm a simple modal!</h1>
2728
<img class="modal-image"
2829
src="https://placeimg.com/627/200/tech"

src/app/demo/foundation/foundation.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ <h1>Foundation Modal</h1>
1515
</div>
1616
</div>
1717

18-
<ngx-smart-modal #myFoundationModal identifier="myFoundationModal" [closable]="false" customClass="reveal">
18+
<ngx-smart-modal #myFoundationModal
19+
identifier="myFoundationModal"
20+
customClass="reveal"
21+
ariaLabel="Foundation modal"
22+
[closable]="false">
1923
<h5>Modal title</h5>
2024
<img src="https://placeimg.com/1000/400/tech" alt="Responsive image">
2125
<p><code>NgxSmartModal</code> fits with any CSS framework. <strong>A N Y!</strong></p>

src/app/demo/main/main.component.html

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ <h3 class="title">Examples with CSS frameworks</h3>
9797

9898
<!-- Classic modal -->
9999
<ngx-smart-modal #classicModal
100-
identifier="classicModal">
100+
identifier="classicModal"
101+
ariaLabel="Classic modal">
101102
<h1>Hey, I'm a simple modal!</h1>
102103
<img class="modal-image"
103104
src="https://placeimg.com/627/200/tech"
@@ -109,7 +110,8 @@ <h1>Hey, I'm a simple modal!</h1>
109110

110111
<!-- Modal inception -->
111112
<ngx-smart-modal #modalInception
112-
identifier="modalInception">
113+
identifier="modalInception"
114+
arialLabel="Inception modal">
113115
<h1>Howdy how, I'm a modal that opens another one!</h1>
114116
<p>{{ sampleText[1] }}</p>
115117

@@ -124,7 +126,8 @@ <h1>Howdy how, I'm a modal that opens another one!</h1>
124126
<!-- Data in modal -->
125127
<ngx-smart-modal #modalData
126128
identifier="modalData"
127-
customClass="nsm-dialog-animation-ltr">
129+
customClass="nsm-dialog-animation-ltr"
130+
ariaLabel="Data modal">
128131
<h1>Hey, I'm a modal with some data!</h1>
129132
<p>
130133
<strong>Code below comes from
@@ -145,6 +148,7 @@ <h1>Hey, I'm a modal with some data!</h1>
145148
<ngx-smart-modal #modalEvents
146149
identifier="modalEvents"
147150
customClass="nsm-dialog-animation-ttb nsm-centered"
151+
ariaLabel="Events modal"
148152
(onOpen)="log('Modal opened!')"
149153
(onClose)="log('Modal closed!')"
150154
(onOpenFinished)="log('Modal open finished!')"
@@ -163,6 +167,7 @@ <h2>And with customClass 'nsm-dialog-animation-ttb nsm-centered'</h2>
163167
<ngx-smart-modal #videoModal
164168
identifier="videoModal"
165169
customClass="nsm-dialog-animation-btt medium-modal"
170+
ariaLabel="Video modal"
166171
[closable]="false"
167172
[dismissable]="false"
168173
[escapable]="false">
@@ -187,7 +192,8 @@ <h1>Hey, I Rickrolled You!</h1>
187192

188193
<!-- Remote modal -->
189194
<ngx-smart-modal #remoteModal
190-
identifier="remoteModal">
195+
identifier="remoteModal"
196+
ariaLabel="Remote modal">
191197
<h1>Yo, I'm a remotely opened modal!</h1>
192198
<img class="modal-image"
193199
src="https://placeimg.com/627/200/tech"
@@ -208,6 +214,7 @@ <h1>Yo, I'm a remotely opened modal!</h1>
208214
<ngx-smart-modal #sampleModal
209215
identifier="sampleModal"
210216
customClass="large-modal"
217+
ariaLabel="Sample modal"
211218
[backdrop]="false"
212219
[hideDelay]="0">
213220
<h1>Hello! I'm a modal with a custom class, without backdrop, without animation effect and without delay!</h1>
@@ -220,7 +227,8 @@ <h1>Hello! I'm a modal with a custom class, without backdrop, without animation
220227

221228
<!-- Big content modal -->
222229
<ngx-smart-modal #longTextModal
223-
identifier="longTextModal">
230+
identifier="longTextModal"
231+
ariaLabel="Big content modal">
224232
<h1>You wanna see my big content?</h1>
225233
<img class="modal-image"
226234
src="https://placeimg.com/627/200/tech"
@@ -293,7 +301,8 @@ <h1>You wanna see my big content?</h1>
293301
<!-- Undismissable modal -->
294302
<ngx-smart-modal #undismissable
295303
identifier="undismissable"
296-
[dismissable]="false">
304+
aria-label="Undismissable modal">
305+
[dismissable]="false"
297306
<h1>Hey, I'm a not dismissable modal!</h1>
298307
<p>Clicking on my backdrop
299308
<strong>won't</strong> close me.</p>
@@ -308,6 +317,7 @@ <h1>Hey, I'm a not dismissable modal!</h1>
308317
<!-- Inescapable modal -->
309318
<ngx-smart-modal #inescapable
310319
identifier="inescapable"
320+
ariaLabel="Inescapable modal"
311321
[escapable]="false">
312322
<h1>Hey, I'm an unescapable modal!</h1>
313323
<p>Pressing the escape key
@@ -323,7 +333,8 @@ <h1>Hey, I'm an unescapable modal!</h1>
323333
<!-- Custom target -->
324334
<ngx-smart-modal #customTarget
325335
identifier="customTarget"
326-
target="button#targetElement">
336+
target="button#targetElement"
337+
ariaLabel="Custom target modal">
327338
<h1>Hey, I am a modal placed relatively to an element!</h1>
328339
<p>How to use : </p>
329340
<code>target="myElementSelector"</code>

src/app/demo/materialize/materialize.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ <h1 class="display-1">Materialize Modal</h1>
1515
</div>
1616
</div>
1717

18-
<ngx-smart-modal #myMtrlzModal identifier="myMtrlzModal" [closable]="false" customClass="modal no-padding">
18+
<ngx-smart-modal #myMtrlzModal
19+
identifier="myMtrlzModal"
20+
customClass="modal no-padding"
21+
ariaLabel="Materialize modal"
22+
[closable]="false">
1923
<div class="modal-content">
2024
<div class="row">
2125
<div class="card z-depth-0" style="margin: 0;">

src/app/doc/parts/options/options.component.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class OptionsComponent implements OnInit {
2525
name: 'escapable',
2626
type: 'boolean',
2727
defaultValue: 'true',
28-
description: 'Enable / disable the modal for listening to the escape keypress event (if pressed and this option is set to true, it will close the current opened modal or the latest opened if you have several modals opened at the same time)'
28+
description: 'Enable / disable the modal for listening to the escape keypress event (if pressed and this option is set to true, it will close the current opened modal or the latest opened if you have several modals opened at the same time). ⚠️ NOT RECOMMANDED for accessibility reasons.'
2929
},
3030
{
3131
name: 'dismissable',
@@ -75,6 +75,24 @@ export class OptionsComponent implements OnInit {
7575
defaultValue: 'undefined',
7676
description: 'Displays the modal relatively to the targeted element. ⚠️ Only for NgxSmartModal >= 7.0.0!'
7777
},
78+
{
79+
name: 'ariaLabel',
80+
type: 'string',
81+
defaultValue: 'undefined',
82+
description: 'Define a accessible title for your modal.'
83+
},
84+
{
85+
name: 'ariaLabelledBy',
86+
type: 'string',
87+
defaultValue: 'undefined',
88+
description: 'Define a accessible title for your modal. Enter the id of your title content.'
89+
},
90+
{
91+
name: 'ariaDescribedBy',
92+
type: 'string',
93+
defaultValue: 'undefined',
94+
description: 'Define a accessible description for your modal. Enter the id of your description content.'
95+
}
7896
];
7997
// tslint:enable:max-line-length
8098

src/ngx-smart-modal/src/components/ngx-smart-modal.component.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ import { NgxSmartModalConfig } from '../config/ngx-smart-modal.config';
2626
[ngClass]="{'transparent':!backdrop, 'overlay':true, 'nsm-overlay-open':openedClass}"
2727
(mousedown)="dismiss($event)" #nsmOverlay>
2828
<div [style.z-index]="visible ? layerPosition : -1"
29-
[ngClass]="['nsm-dialog', customClass, openedClass ? 'nsm-dialog-open': 'nsm-dialog-close']" #nsmDialog>
29+
[ngClass]="['nsm-dialog', customClass, openedClass ? 'nsm-dialog-open': 'nsm-dialog-close']" #nsmDialog
30+
[attr.aria-hidden]="openedClass ? false : true"
31+
[attr.aria-label]="ariaLabel"
32+
[attr.aria-labelledby]="ariaLabelledBy"
33+
[attr.aria-describedby]="ariaDescribedBy">
3034
<div class="nsm-content" #nsmContent>
3135
<div class="nsm-body">
3236
<ng-content></ng-content>
@@ -61,6 +65,9 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy {
6165
@Input() public hideDelay: number = 500;
6266
@Input() public autostart: boolean = false;
6367
@Input() public target: string = '';
68+
@Input() public ariaLabel: string | null = null;
69+
@Input() public ariaLabelledBy: string | null = null;
70+
@Input() public ariaDescribedBy: string | null = null;
6471

6572
@Output() public visibleChange: EventEmitter<boolean> = new EventEmitter<boolean>();
6673
@Output() public onClose: EventEmitter<any> = new EventEmitter();
@@ -84,7 +91,7 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy {
8491
private _data: any;
8592

8693
@ViewChildren('nsmContent') private nsmContent: QueryList<ElementRef>;
87-
@ViewChildren('nsmDialog') private nsmDialog: QueryList<ElementRef>;
94+
@ViewChildren('nsmDialog') public nsmDialog: QueryList<ElementRef>;
8895
@ViewChildren('nsmOverlay') private nsmOverlay: QueryList<ElementRef>;
8996

9097
constructor(

src/ngx-smart-modal/src/config/ngx-smart-modal.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ export interface INgxSmartModalOptions {
1313
hideDelay?: number;
1414
autostart?: boolean;
1515
target?: string;
16+
ariaLabel?: string;
17+
ariaLabelledBy?: string;
18+
ariaDescribedBy?: string;
1619
}

src/ngx-smart-modal/src/ngx-smart-modal.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ body.dialog-open {
6767
max-width: 520px;
6868
margin: 0 auto;
6969
pointer-events: none;
70+
outline: none;
7071

7172
// When dialog is closing
7273
&.nsm-dialog-close {

0 commit comments

Comments
 (0)