src/app/shared/components/drawer/content/content.component.ts
Component wrapping and providing animations for center content.
OnDestroy
changeDetection | ChangeDetectionStrategy.OnPush |
selector | ccf-drawer-content |
styleUrls | ./content.component.scss |
template |
|
Properties |
|
HostBindings |
constructor(messageService: MessageService, cdr: ChangeDetectorRef)
|
||||||||||||
Creates an instance of content component.
Parameters :
|
@fadeInOut |
Type : boolean
|
Default value : false
|
Whether the content is invisible. |
class |
Type : "ccf-drawer-content"
|
Default value : 'ccf-drawer-content'
|
HTML class |
class.cff-drawer-content-animations |
Type : boolean
|
Default value : false
|
Whether animations are enabled. |
style.margin-left.px |
Type : number
|
Default value : 0
|
Left margin size. |
style.margin-right.px |
Type : number
|
Default value : 0
|
Right margin size. |
animationsEnabled |
Default value : false
|
Decorators :
@HostBinding('class.cff-drawer-content-animations')
|
Whether animations are enabled. |
Readonly className |
Type : string
|
Default value : 'ccf-drawer-content'
|
Decorators :
@HostBinding('class')
|
HTML class |
faded |
Default value : false
|
Decorators :
@HostBinding('@fadeInOut')
|
Whether the content is invisible. |
leftMargin |
Type : number
|
Default value : 0
|
Decorators :
@HostBinding('style.margin-left.px')
|
Left margin size. |
rightMargin |
Type : number
|
Default value : 0
|
Decorators :
@HostBinding('style.margin-right.px')
|
Right margin size. |
import { animate, state, style, transition, trigger } from '@angular/animations';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { DrawerComponent } from '../drawer/drawer.component';
import { Message, MessageService } from '../messages';
/**
* Component wrapping and providing animations for center content.
*/
@Component({
selector: 'ccf-drawer-content',
template: '<ng-content></ng-content>',
styleUrls: ['./content.component.scss'],
animations: [
trigger('fadeInOut', [
state('false', style({ opacity: 1 })),
state('true', style({ opacity: 0 })),
transition('false <=> true', animate('1s')),
]),
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ContentComponent implements OnDestroy {
/** HTML class */
@HostBinding('class') readonly className = 'ccf-drawer-content';
/** Whether animations are enabled. */
@HostBinding('class.cff-drawer-content-animations') animationsEnabled = false;
/** Left margin size. */
@HostBinding('style.margin-left.px') leftMargin = 0;
/** Right margin size. */
@HostBinding('style.margin-right.px') rightMargin = 0;
/** Whether the content is invisible. */
@HostBinding('@fadeInOut') faded = false;
/** References to the side drawers. */
private drawers: DrawerComponent[] = [];
/** Subscriptions managed by this component. */
private readonly subscriptions = new Subscription();
/**
* Creates an instance of content component.
*
* @param messageService Service used to send and receive event messages.
* @param cdr The change detector reference.
*/
constructor(messageService: MessageService, cdr: ChangeDetectorRef) {
const messages = messageService.connect(this).getMessages();
this.subscriptions.add(
messages.subscribe((msg) => {
if (this.handleMessage(msg)) {
cdr.markForCheck();
}
}),
);
}
/** Cleans up all subscriptions. */
ngOnDestroy(): void {
this.subscriptions.unsubscribe();
}
/**
* Process an event message.
*
* @param msg The event.
* @returns true if change detection needs to run.
*/
private handleMessage(msg: Message): boolean {
switch (msg.payload.type) {
case 'drawer-containers-changed':
this.drawers = msg.payload.drawers as DrawerComponent[];
this.updateFaded();
return true;
case 'drawer-initialized':
this.animationsEnabled = true;
return true;
case 'drawer-toggled': {
const position = (msg.source as DrawerComponent).position;
const { opened, width, margin } = msg.payload;
this.updateMargin(position, opened, width, margin);
this.updateFaded();
return true;
}
default:
return false;
}
}
/**
* Updates a margin.
*
* @param position Start (left) or end (right) margin.
* @param opened Whether the drawer is opened.
* @param width The width of the drawer if opened.
* @param margin The margin size.
*/
private updateMargin(position: 'start' | 'end', opened: boolean, width: number, margin: number): void {
const offset = opened ? width + margin : margin;
if (position === 'start') {
this.leftMargin = offset;
} else {
this.rightMargin = offset;
}
}
/**
* Checks and updates the faded state based on the drawer states.
*/
private updateFaded(): void {
const [start, end] = this.drawers;
const startExpanded = start?.opened && start?.expanded;
const endExpanded = end?.opened && end?.expanded;
this.faded = startExpanded || endExpanded;
}
}
./content.component.scss
:host {
display: block;
height: calc(100% - 5.5rem);
z-index: 2;
overflow: auto;
&.cff-drawer-content-animations {
transition: {
duration: 0.5s;
timing-function: ease-in-out;
property: margin-left, margin-right;
}
}
}