Skip to content

Commit

Permalink
fix: Action sheet adapt to newest CDK (#3733)
Browse files Browse the repository at this point in the history
* fix: Action sheet functionality

* fix typo
  • Loading branch information
JKMarkowski committed Nov 5, 2020
1 parent 7146b6c commit 7b353e8
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
Input,
ViewEncapsulation
} from '@angular/core';
import { ActionSheetItemComponent } from '../action-sheet-item/action-sheet-item.component';
import { KeyboardSupportService } from '../../utils/services/keyboard-support/keyboard-support.service';

/**
* A component used to enforce a certain layout for the action sheet.
Expand Down Expand Up @@ -35,9 +37,21 @@ export class ActionSheetBodyComponent {
@Input()
mobile = false;

constructor(
private _keyboardSupportService: KeyboardSupportService<ActionSheetItemComponent>
) {}

/** Handler for mouse events */
@HostListener('click', ['$event'])
onClick(event: MouseEvent): void {
event.stopPropagation();
}

/** @hidden */
@HostListener('keydown', ['$event'])
keyDownHandler(event: KeyboardEvent): void {
if (this._keyboardSupportService.keyManager) {
this._keyboardSupportService.onKeyDown(event)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ export class ActionSheetControlComponent {

/** Emitted event when control button is clicked **/
@Output()
clicked: EventEmitter<boolean> = new EventEmitter<boolean>();
clicked: EventEmitter<void> = new EventEmitter<void>();

/** Handler for mouse events */
@HostListener('click', ['$event'])
onClick(event: MouseEvent): void {
this.clicked.emit(true);
this.clicked.emit();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
import { KeyboardSupportItemInterface } from '../../utils/interfaces/keyboard-support-item.interface';
import { ButtonComponent } from '../../button/button.component';


export interface ActionSheetClickEvent {
shouldClose: boolean;
}

/**
* A component used to enforce a certain layout for the action sheet.
Expand Down Expand Up @@ -69,11 +71,11 @@ export class ActionSheetItemComponent implements KeyboardSupportItemInterface {
keyDown = new EventEmitter<KeyboardEvent>();

/** @hidden **/
clicked = new EventEmitter<boolean>();
clicked = new EventEmitter<ActionSheetClickEvent>();

constructor(
private _elementRef: ElementRef
) { }
) {}

/** @hidden */
@HostListener('keydown', ['$event'])
Expand All @@ -84,11 +86,9 @@ export class ActionSheetItemComponent implements KeyboardSupportItemInterface {
/** Handler for mouse events */
@HostListener('click', ['$event'])
onClick(event: MouseEvent): void {
this.clicked.emit(!this.isCloseButton);

if (!this.isCloseButton) {
event.stopPropagation();
}
this.clicked.emit({
shouldClose: this.isCloseButton
});
}

/** @hidden Support for KeyboardSupportItemInterface */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<div *ngIf="open" class="fd-action-sheet__wrapper fd-action-sheet__wrapper--active" (click)="close()">
<div *ngIf="open" class="fd-action-sheet__wrapper fd-action-sheet__wrapper--active" (click)="toggleOpenState(false)">
<ng-container *ngTemplateOutlet="childContent?.actionSheetBodyTemplate"></ng-container>
</div>
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import {
Component,
Input,
TemplateRef
} from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, TemplateRef } from '@angular/core';

@Component({
selector: 'fd-action-sheet-mobile',
templateUrl: './action-sheet-mobile.component.html'
templateUrl: './action-sheet-mobile.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ActionSheetMobileComponent {

/** Whenever links should be visible **/
@Input()
open = false;

/** @hidden */
childContent: {
actionSheetBodyTemplate: TemplateRef<any>,
} = null;

/** @hidden */
close(): void {
this.open = false;
constructor(
private _changeDetectionRef: ChangeDetectorRef
) {}

toggleOpenState(isOpen: boolean): void {
this.open = isOpen;
this._changeDetectionRef.detectChanges();
}
}
10 changes: 9 additions & 1 deletion libs/core/src/lib/action-sheet/action-sheet.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
<fd-popover *ngIf="!mobile" placement="bottom" [noArrow]="false" [focusTrapped]="true">
<fd-popover
*ngIf="!mobile"
placement="bottom"
[(isOpen)]="isOpen"
(isOpenChange)="isOpenChangeHandle($event)"
[noArrow]="false"
[focusTrapped]="true"
[triggers]="[]"
[focusAutoCapture]="true">
<fd-popover-control>
<ng-container *ngTemplateOutlet="actionSheetControl"></ng-container>
</fd-popover-control>
Expand Down
130 changes: 77 additions & 53 deletions libs/core/src/lib/action-sheet/action-sheet.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
ElementRef,
EventEmitter,
HostListener,
Injector,
Input,
OnDestroy,
Optional,
Expand All @@ -17,7 +16,8 @@ import {
TemplateRef,
ComponentRef,
QueryList,
ContentChildren
ContentChildren,
ChangeDetectorRef
} from '@angular/core';
import { PopoverComponent } from '../popover/popover.component';
import { DynamicComponentService } from '../utils/dynamic-component/dynamic-component.service';
Expand All @@ -27,11 +27,10 @@ import {
FocusEscapeDirection,
KeyboardSupportService
} from '../utils/services/keyboard-support/keyboard-support.service';
import { ActionSheetItemComponent } from './action-sheet-item/action-sheet-item.component';
import { ActionSheetItemComponent, ActionSheetClickEvent } from './action-sheet-item/action-sheet-item.component';
import { startWith, takeUntil } from 'rxjs/operators';
import { Subject} from 'rxjs';
import { Subject, merge } from 'rxjs';
import { ActionSheetMobileComponent } from './action-sheet-mobile/action-sheet-mobile.component';
import {ACTION_SHEET_COMPONENT, ActionSheetInterface} from './action-sheet.interface';

@Component({
selector: 'fd-action-sheet',
Expand All @@ -43,19 +42,24 @@ import {ACTION_SHEET_COMPONENT, ActionSheetInterface} from './action-sheet.inter
KeyboardSupportService
]
})
export class ActionSheetComponent implements AfterContentInit, AfterViewInit, OnDestroy, ActionSheetInterface {
export class ActionSheetComponent implements AfterContentInit, AfterViewInit, OnDestroy {

/** Whether should be displayed in compact mode **/
@Input()
compact = false;
set compact(compact: boolean) {
this._compact = compact;
this._initializeChildrenState();
this._setItemsProperties();
}
private _compact = false;

/** Whether should be displayed in mobile mode **/
@Input()
mobile = false;

/** Whenever links should be visible **/
@Input()
open = false;
isOpen = false;

/** Whether internal keyboard support should be enabled. It's enabled by default */
@Input()
Expand All @@ -73,7 +77,7 @@ export class ActionSheetComponent implements AfterContentInit, AfterViewInit, On

/** Event thrown, when the action sheet is opened or closed */
@Output()
readonly openChange: EventEmitter<boolean> = new EventEmitter<boolean>();
readonly isOpenChange: EventEmitter<boolean> = new EventEmitter<boolean>();

/** @hidden */
@ContentChild(ActionSheetBodyComponent)
Expand Down Expand Up @@ -107,6 +111,7 @@ export class ActionSheetComponent implements AfterContentInit, AfterViewInit, On
constructor(
private _elementRef: ElementRef,
private _keyboardSupportService: KeyboardSupportService<ActionSheetItemComponent>,
private _changeDetectionRef: ChangeDetectorRef,
@Optional() private _dynamicComponentService: DynamicComponentService
) {}

Expand All @@ -117,21 +122,13 @@ export class ActionSheetComponent implements AfterContentInit, AfterViewInit, On
this._keyboardSupportService.setKeyboardService(this.actionSheetItems, false);
this._listenOnItemsChange();
this._actionControlHandle();
this._actionItemsHandle();
}

/** @hidden */
ngAfterViewInit(): void {
if (this.mobile) {
this._setUpMobileMode();
}
if (this.popoverComponent && this.popoverComponent) {
this.popoverComponent.directiveRef.loaded.pipe(takeUntil(this._onDestroy$)).subscribe(() => {
setTimeout(() => {
this.setItemActive(0);
});
});
}
}

/** @hidden */
Expand All @@ -141,76 +138,103 @@ export class ActionSheetComponent implements AfterContentInit, AfterViewInit, On
}

/** @hidden */
private _initializeChildrenState(): void {
this.actionSheetBody.mobile = this.mobile;
this.actionSheetBody.compact = this.compact;
this.actionSheetItems.forEach(actionSheetItem => actionSheetItem.compact = this.compact);
@HostListener('keydown', ['$event'])
keyDownHandler(event: KeyboardEvent): void {
if (this.keyboardSupport) {
this._keyboardSupportService.onKeyDown(event)
}
}

/** @hidden */
private _actionControlHandle(): void {
this.actionSheetControl.clicked
.pipe(takeUntil(this._onDestroy$))
.subscribe((isOpen) => this.isOpenChangeHandle(isOpen));
/** Method that opens action sheet */
open(): void {
this.isOpenChangeHandle(true);
}

/** @hidden */
private _actionItemsHandle(): void {
this.actionSheetItems.forEach(item => item.clicked
.pipe(takeUntil(this._onDestroy$))
.subscribe((isOpen) => this.isOpenChangeHandle(isOpen))
);
/** Method that closes action sheet */
close(): void {
this.isOpenChangeHandle(false);
}

/** @hidden */
isOpenChangeHandle(isOpen: boolean): void {
this.open = isOpen;
if (this.mobile) {
this.actionSheetMobileDynamic.instance.open = this.open;
} else {
if (this.open) {
this.popoverComponent.open()
} else {
this.popoverComponent.directiveRef.close()
}
this.isOpen = isOpen;
if (this.mobile && this.actionSheetMobileDynamic) {
this.actionSheetMobileDynamic.instance.toggleOpenState(this.isOpen);
}
this.isOpenChange.emit(isOpen);

if (isOpen && !this.mobile) {
this._setItemActive(0);
}
this._changeDetectionRef.detectChanges();
}

/** @hidden */
@HostListener('keydown', ['$event'])
keyDownHandler(event: KeyboardEvent): void {
if (this.keyboardSupport) {
this._keyboardSupportService.onKeyDown(event)
private _initializeChildrenState(): void {
if (this.actionSheetBody) {
this.actionSheetBody.mobile = this.mobile;
this.actionSheetBody.compact = this._compact;
}
}

/** Set fake focus on element with passed index */
setItemActive(index: number): void {
this._keyboardSupportService.keyManager.setActiveItem(index);
/** @hidden */
private _actionControlHandle(): void {
this.actionSheetControl.clicked
.pipe(takeUntil(this._onDestroy$))
.subscribe(() => this.open());
}

/** @hidden */
private _listenOnItemsChange(): void {
this.actionSheetItems.changes
.pipe(
startWith(0),
startWith(1),
takeUntil(this._onDestroy$)
)
.subscribe(() => this._listenOnItemsClick());

.subscribe(() => {
this._listenOnItemsClick();
this._setItemsProperties();
});
}

/** @hidden */
private _listenOnItemsClick(): void {
/** Finish all of the streams, from before */
this._onRefresh$.next();
/** Merge refresh/destroy observables */
const refresh$ = merge(this._onRefresh$, this._onDestroy$)

this.actionSheetItems.forEach((item, index) => item.clicked
.pipe(takeUntil(refresh$))
.subscribe((event: ActionSheetClickEvent) => {
this._setItemActive(index);
if (event.shouldClose) {
this.close();
}
})
);
}

/** Set fake focus on element with passed index */
private _setItemActive(index: number): void {
if (this._keyboardSupportService.keyManager) {
this._keyboardSupportService.keyManager.setActiveItem(index);
}
}

/** @hidden */
private _setItemsProperties(): void {
if (this.actionSheetItems) {
this.actionSheetItems.forEach(actionSheetItem => actionSheetItem.compact = this._compact);
}
}

/** @hidden */
private _setUpMobileMode(): void {
this.actionSheetMobileDynamic = this._dynamicComponentService.createDynamicComponent(
{ actionSheetBodyTemplate: this.actionSheetBodyTemplate },
ActionSheetMobileComponent,
{ container: this._elementRef.nativeElement },
{ injector: Injector.create({ providers: [{ provide: ACTION_SHEET_COMPONENT, useValue: this }] }) }
{ container: this._elementRef.nativeElement }
);
}
}
12 changes: 0 additions & 12 deletions libs/core/src/lib/action-sheet/action-sheet.interface.ts

This file was deleted.

0 comments on commit 7b353e8

Please sign in to comment.