Skip to content

Commit

Permalink
Make it work even more!
Browse files Browse the repository at this point in the history
  • Loading branch information
RasmusKjeldgaard committed Nov 12, 2024
1 parent 07da8fa commit dd12ade
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 24 deletions.
32 changes: 20 additions & 12 deletions libs/designsystem/empty-state/src/empty-state.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ContentChildren,
ElementRef,
Input,
OnInit,
QueryList,
} from '@angular/core';
import { ButtonComponent } from '@kirbydesign/designsystem/button';
Expand All @@ -15,14 +16,14 @@ import { ButtonComponent } from '@kirbydesign/designsystem/button';
styleUrls: ['./empty-state.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class EmptyStateComponent implements AfterContentInit {
_title: string;
export class EmptyStateComponent implements AfterContentInit, OnInit {
private _title: string;

@Input() iconName: string;

@Input() set title(value: string) {
this._title = value;
this.setAccessibleModalLabel();
this.setAriaLabelOnModal();
}

get title(): string {
Expand All @@ -33,9 +34,21 @@ export class EmptyStateComponent implements AfterContentInit {

@ContentChildren(ButtonComponent)
private slottedButtons: QueryList<ButtonComponent>;
private ionModalElement: HTMLIonModalElement;
private modalElementDialog: HTMLElement;

constructor(private elementRef: ElementRef<HTMLElement>) {}

ngOnInit(): void {
/* If initialized inside a modal that is not labelled, we want to set
* the aria-label attribute on ion-modal to the title of empty state.
* Further updates are handled by title setter.
*/
this.ionModalElement = this.elementRef.nativeElement.closest('ion-modal');
this.modalElementDialog = this.ionModalElement?.shadowRoot.querySelector('[role="dialog"]');
this.setAriaLabelOnModal();
}

ngAfterContentInit() {
this.enforceAttentionLevelRules();

Expand All @@ -46,16 +59,11 @@ export class EmptyStateComponent implements AfterContentInit {
});
}

setAccessibleModalLabel() {
/* If we are inside a modal that is not labelled, we want to set
the aria-label attribute on ion-modal to point to the title of empty state */
const ionModalDialog = this.elementRef.nativeElement
.closest('ion-modal')
.shadowRoot.querySelector('[role="dialog"]');

ionModalDialog.ariaLabel ?? (ionModalDialog.ariaLabel = this.title);
private setAriaLabelOnModal() {
if (this.modalElementDialog && this._title) {
this.modalElementDialog.ariaLabel = this._title;
}
}

/** Enforces that all slotted buttons will have their attention
* level set to 3, except the first button if it has
* level 1.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,29 @@ import { CanDismissHelper } from '../../modal/services/can-dismiss.helper';
host: { '[class.ion-page]': 'false' }, //Ensure ion-page class doesn't get applied by Ionic Modal Controller
})
export class ModalCompactWrapperComponent implements Modal, OnInit {
private _ariaLabel: string;

@Input() config: ModalConfig;
@Input() content: TemplateRef<any>;
@Input() set titleId(value: string) {
// local titleId variable to be used in ngAfterViewInit if setter is called before OnInit
this._titleId = value;
this.ionModalElement?.setAttribute('aria-labelledby', value);
@Input() set ariaLabel(value: string) {
this._ariaLabel = value;
this.setAriaLabelOnModal();
}

get ariaLabel(): string {
return this._ariaLabel;
}

scrollY: number = Math.abs(this.windowRef.nativeWindow.scrollY);
scrollDisabled = false;
componentPropsInjector: Injector;

private ionModalElement: HTMLIonModalElement;
private modalElementDialog: HTMLElement;
private readonly ionModalDidPresent = new Subject<void>();
private readonly ionModalWillDismiss = new Subject<void>();
readonly didPresent = firstValueFrom(this.ionModalDidPresent);
readonly willClose = firstValueFrom(this.ionModalWillDismiss);
private _titleId;

constructor(
private injector: Injector,
Expand All @@ -55,20 +60,21 @@ export class ModalCompactWrapperComponent implements Modal, OnInit {

ngOnInit(): void {
this.ionModalElement = this.elementRef.nativeElement.closest('ion-modal');
this.modalElementDialog = this.ionModalElement.shadowRoot.querySelector('[role="dialog"]');

/* If initialized with ariaLabel, we want to set the aria-label attribute immediately.
* Further updates are handled by title setter.
*/
this.setAriaLabelOnModal();
console.log('ModalCompactWrapperComponent ngOnInit ariaLabel:', this._ariaLabel);

this.addAriaLabelledByToIonModal();
this.listenForIonModalDidPresent();
this.listenForIonModalWillDismiss();
this.componentPropsInjector = Injector.create({
providers: [{ provide: COMPONENT_PROPS, useValue: this.config.componentProps }],
parent: this.injector,
});
}
addAriaLabelledByToIonModal() {
if (this.ionModalElement && this._titleId) {
this.ionModalElement?.setAttribute('aria-labelledby', this._titleId);
}
}

private listenForIonModalDidPresent() {
if (this.ionModalElement) {
Expand All @@ -88,6 +94,12 @@ export class ModalCompactWrapperComponent implements Modal, OnInit {
}
}

private setAriaLabelOnModal() {
if (this.modalElementDialog && this.ariaLabel) {
this.modalElementDialog.ariaLabel = this.ariaLabel;
}
}

async close(data?: any): Promise<void> {
const ionModalElement = this.elementRef.nativeElement.closest('ion-modal');
if (ionModalElement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
*ngIf="flavor === 'compact'; else modalWrapper"
[config]="_config"
[content]="template"
[titleId]="titleId"
></kirby-modal-compact-wrapper>
</ng-template>
</ion-modal>
Expand Down

0 comments on commit dd12ade

Please sign in to comment.