Skip to content

Commit

Permalink
feat(design): add ARIA features to modal (#2832)
Browse files Browse the repository at this point in the history
  • Loading branch information
xelaint authored and damienwebdev committed Jul 23, 2024
1 parent bf21aab commit fd838fd
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<ng-content select="[daffModalTitle]"></ng-content>
24 changes: 0 additions & 24 deletions libs/design/modal/src/modal-header/modal-header.component.scss

This file was deleted.

3 changes: 1 addition & 2 deletions libs/design/modal/src/modal-header/modal-header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import {

@Component({
selector: 'daff-modal-header',
template: '<ng-content></ng-content>',
styleUrls: ['./modal-header.component.scss'],
templateUrl: './modal-header.component.html',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,8 @@ describe('@daffodil/design/modal | DaffModalTitleDirective', () => {
}));
});
});

it('should define its own id', () => {
expect(de.componentInstance.id).toEqual(de.componentInstance._uniqueRadioId);
});
});
31 changes: 31 additions & 0 deletions libs/design/modal/src/modal-title/modal-title.directive.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,45 @@
import {
Directive,
HostBinding,
Optional,
} from '@angular/core';

import { DaffModalComponent } from '../modal/modal.component';

let modalTitleId = 0;

/**
* Title of a modal.
*/
@Directive({
selector: '[daffModalTitle]',
})

export class DaffModalTitleDirective {
/**
* @docs-private
*/
@HostBinding('class.daff-modal-title') class = true;

private _id = '';

/**
* The html `id` of the modal title.
*/
@HostBinding('attr.id') get uniqueId() {
return this._id;
}

constructor(@Optional() private modal: DaffModalComponent) {
modalTitleId++;

this._id = 'daff-modal-title-' + modalTitleId;

/**
* Sets the ariaLabelledBy of the modal to the id of the modal title.
*/
if(this.modal) {
this.modal.ariaLabelledBy = this.uniqueId;
}
}
}
10 changes: 9 additions & 1 deletion libs/design/modal/src/modal/modal.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { DaffModalComponent } from './modal.component';
import { DaffModalService } from '../service/modal.service';

@Component({ template: `
<div class="daff-modal-wrapper">
<div class="custom-modal-component">
<daff-modal></daff-modal>
</div>
` })
Expand Down Expand Up @@ -54,4 +54,12 @@ describe('@daffodil/design/modal | DaffModalComponent', () => {
it('should create', () => {
expect(wrapper).toBeTruthy();
});

it('should have a role of dialog on the host element', () => {
expect(modal.role).toBe('dialog');
});

it('should set aria-modal to true on the host element', () => {
expect(modalDe.attributes['aria-modal']).toEqual('true');
});
});
23 changes: 23 additions & 0 deletions libs/design/modal/src/modal/modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,29 @@ export class DaffModalComponent implements AfterContentInit, AfterViewInit {
*/
@HostBinding('class.daff-modal') modalClass = true;

/**
* Sets the role to dialog.
*/
@HostBinding('attr.role') role = 'dialog';

/**
* Sets aria-modal to true.
*/
@HostBinding('attr.aria-modal') ariaModal = true;

private _ariaLabelledBy = null;

/**
* The aria-labelledby for the modal. This is set by the id of
* {@link DaffModalTitleDirective} when it is used.
*
*/
@HostBinding('attr.aria-labelledby') get ariaLabelledBy() {
return this._ariaLabelledBy;
} set ariaLabelledBy(value: string) {
this._ariaLabelledBy = value;
}

/**
* Dictates whether or not a modal is open or closed.
*/
Expand Down

0 comments on commit fd838fd

Please sign in to comment.