src/app/components/page-element/page-element.component.ts
Renders a component according to it's type
changeDetection | ChangeDetectionStrategy.OnPush |
selector | page-element |
styleUrls | ./page-element.component.scss |
templateUrl | ./page-element.component.html |
Properties |
Methods |
Inputs |
HostListeners |
constructor(router: Router, route: ActivatedRoute, scroller: ViewportScroller, cdr: ChangeDetectorRef)
|
|||||||||||||||
Creates instance of Router, ActivatedRoute, ViewportScroller and navigates to page element if fragment is changed
Parameters :
|
def | |
Type : PageDef
|
|
Details of element to be displayed |
document:scroll |
document:scroll(undefined: literal type)
|
Updates scrolled value if page is scrolled |
clicked | ||||||
clicked(card: LongCard)
|
||||||
Navigates to specified route
Parameters :
Returns :
void
|
onScroll | |||||||
onScroll(undefined: literal type)
|
|||||||
Decorators :
@HostListener('document:scroll')
|
|||||||
Updates scrolled value if page is scrolled
Parameters :
Returns :
void
|
scrollTo | ||||||
scrollTo(id: string)
|
||||||
Scrolls to the specified page element
Parameters :
Returns :
void
|
scrolled |
Default value : false
|
Flag to check if page is scrolled |
import { ViewportScroller } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, Input } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { LongCard } from '../card-button-long/long-card';
import { PageDef } from './page-def';
/** Renders a component according to it's type */
@Component({
selector: 'page-element',
templateUrl: './page-element.component.html',
styleUrls: ['./page-element.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PageElementComponent {
/** Details of element to be displayed */
@Input() def!: PageDef;
/** Subscriptions managed by this component. */
private readonly subscriptions = new Subscription();
/** Flag to check if page is scrolled */
scrolled = false;
/** Creates instance of Router, ActivatedRoute, ViewportScroller
* and navigates to page element if fragment is changed */
constructor(
private readonly router: Router,
private readonly route: ActivatedRoute,
private readonly scroller: ViewportScroller,
private readonly cdr: ChangeDetectorRef,
) {
this.subscriptions.add(
this.route.fragment.subscribe((anchor) => {
if (anchor) {
this.scroller.scrollToAnchor(anchor);
}
}),
);
}
/** Updates scrolled value if page is scrolled */
@HostListener('document:scroll')
onScroll({ scrollY: scrollPosition }: { scrollY: number } = window): void {
const scrolled = scrollPosition > 235;
if (scrolled !== this.scrolled) {
this.scrolled = scrolled;
this.cdr.markForCheck();
}
}
/** Navigates to specified route */
clicked(card: LongCard): void {
this.router.navigate([card.route]);
}
/** Scrolls to the specified page element */
scrollTo(id: string): void {
this.router.navigate([], { fragment: id });
this.scroller.scrollToAnchor(id);
}
}
<ng-container [ngSwitch]="def.type">
<ccf-page-header
*ngSwitchCase="'header'"
[style]="def['styles']"
[headerCard]="def['headerCard']"
class="page-header"
></ccf-page-header>
<ccf-page-data *ngSwitchCase="'page-data'" [data]="def['pageData']" [style]="def['styles']" class="description">
</ccf-page-data>
<announcement-card *ngSwitchCase="'announcement'" [messages]="def['announcementCard']"></announcement-card>
<ccf-use-button *ngSwitchCase="'button'" [buttonData]="$any(def)" class="button-container" [style]="def['styles']">
</ccf-use-button>
<ccf-sop-links *ngSwitchCase="'sop-links'" [links]="def['sopData']"></ccf-sop-links>
<ccf-board-members *ngSwitchCase="'board-members'" [membersData]="def['boardMembersData']"></ccf-board-members>
<ccf-card-button-long
*ngSwitchCase="'long-card'"
[longButtonItems]="def['longCardItems']"
(cardRoutes)="clicked($event)"
></ccf-card-button-long>
<ccf-simple-tile *ngSwitchCase="'simple-tile'" [definitions]="def['description']"></ccf-simple-tile>
<youtube-model *ngSwitchCase="'player'" [playerData]="def['youtubePlayer']"></youtube-model>
<div *ngSwitchCase="'title'" [class]="def['class']" [style]="def['styles']">
{{ def['title'] }}
</div>
<div *ngSwitchCase="'margin'" [style.margin-top]="def['top']" [style.margin-bottom]="def['bottom']"></div>
<card-with-header *ngSwitchCase="'long-card-with-title'" [cardBlockData]="def['longCardWithTitleData']">
</card-with-header>
<ccf-simple-image
*ngSwitchCase="'simple-image'"
[imageInfo]="def['imageData']"
[headerData]="def['headerData']"
[customModalClass]="def['customModalClass']"
></ccf-simple-image>
<img
*ngSwitchCase="'image'"
[src]="def['imageSource']"
[class]="def['class']"
[style]="def['styles']"
[alt]="def['alt']"
/>
<div *ngSwitchCase="'text'" [style]="def['styles']" [class]="def['class']">
{{ def['text'] }}
</div>
<div *ngSwitchCase="'styled-group'" [style]="def['styles']" [class]="def['class']" [id]="def['id']">
<page-element *ngFor="let comp of def['components']" [def]="comp"></page-element>
</div>
<div *ngSwitchCase="'carousel'" [style]="def['carouselContainerStyles']">
<ccf-carousel [carouselInfo]="def['carouselInfo']"></ccf-carousel>
</div>
<count-info-card *ngSwitchCase="'count-card'" [cardInformation]="def['countCardInfo']"></count-info-card>
<ccf-section-card *ngSwitchCase="'section-card'" [cards]="def['cardsInfo']"></ccf-section-card>
<table-version
*ngSwitchCase="'table-version'"
[isTotal]="def['isTotal']"
[versionChooserDisabled]="def['versionChooserDisabled']"
[headerInfo]="def['headerInfo']"
[versionData]="def['versionData']"
[additionalHeaders]="def['additionalHeaders']"
[cellHeaders]="def['cellHeaders']"
[isTotal]="def['isTotal']"
[isDownload]="def['isDownload']"
></table-version>
<mat-card *ngSwitchCase="'mat-card'" [style]="def['styles']">
<page-element *ngFor="let comp of def['components']" [def]="comp"></page-element>
</mat-card>
<ccf-prize-card *ngSwitchCase="'prize-card'" [prizeCard]="def['prizeCard']"></ccf-prize-card>
<div *ngSwitchCase="'datasets'" [style]="def['styles']">
<a *ngFor="let link of def['links']" [href]="link['href']" [title]="link['title']" [class]="link['class']">{{
link['data']
}}</a>
</div>
<menu-tree
*ngSwitchCase="'menu-tree'"
class="menu"
[style]="def['styles']"
[treeItems]="def['mobileNavigationItems']"
[icon]="def['icon']"
[overlayClass]="def['overlayClass']"
[treeClass]="'tree-class'"
[positions]="def['positions']"
></menu-tree>
<mat-drawer-container *ngSwitchCase="'drawer'" [autosize]="true">
<mat-drawer mode="side" opened [style]="def['drawerStyles']" [ngClass]="{ scrolled: scrolled }">
<ul class="toc-list">
<li *ngFor="let items of def['navigationItems']" [value]="items" (click)="scrollTo(items.id || '')">
{{ items.menuName }}
</li>
</ul>
</mat-drawer>
<mat-drawer-content>
<page-element *ngFor="let comp of def['components']" [def]="comp"></page-element>
</mat-drawer-content>
</mat-drawer-container>
<mat-divider *ngSwitchCase="'divider'" [style]="def['styles']"></mat-divider>
<contact-card *ngSwitchCase="'contact-card'" [contactCard]="def['contactData']"></contact-card>
<ccf-organ-version
*ngSwitchCase="'organ-version'"
[versionData]="def['versionData']"
[isMultiRow]="def['isMultiRow']"
[organInfo]="def['organInfo']"
[tableRequired]="def['tableRequired']"
[headerInfo]="def['headerInfo']"
></ccf-organ-version>
<ccf-download-ftu
*ngSwitchCase="'download-ftu'"
[data]="def['versionedData']"
[versions]="def['versions']"
[displayMetadata]="def['displayMetadata']"
[columnLabels]="def['columnLabels']"
[downloadIcon]="def['downloadIcon']"
></ccf-download-ftu>
<copy-clipboard *ngSwitchCase="'copy-clipboard'" [clipBoardData]="def['clipboardData']" [style]="def['styles']">
</copy-clipboard>
</ng-container>
./page-element.component.scss
:host {
.title {
font-weight: 300;
font-size: 2.25rem;
line-height: 2.75rem;
letter-spacing: 0.005rem;
padding-top: 2rem;
padding-bottom: 1rem;
}
.description {
margin-bottom: 5rem;
}
.button-container {
margin-bottom: 2.5rem;
width: fit-content;
}
.page-header {
display: block;
margin: 3.5rem 0;
}
a:hover {
text-decoration: underline;
text-decoration-thickness: 2px;
color: #444c65;
}
mat-drawer {
min-width: 306px;
}
.toc-list {
border: #e0e0e0 2px solid;
padding-top: unset;
position: static;
list-style: none;
margin: unset;
padding: unset;
border-radius: 4px;
background-color: white;
li {
display: flex;
align-items: center;
padding: 0rem 1rem;
font-weight: 500;
font-size: 1rem;
line-height: 1.5rem;
border-bottom: #e0e0e0 1px solid;
color: #054f89;
height: 3rem;
&:hover {
background-color: #f5f5f5;
text-decoration: underline;
text-decoration-thickness: 2px;
color: #444c65;
cursor: pointer;
}
}
}
.scrolled {
position: fixed;
top: 4rem;
}
.mat-drawer-side {
border-right: unset;
padding-right: 2.5rem;
}
.download-button {
display: flex;
align-items: center;
justify-content: center;
font-weight: 500;
font-size: 0.875rem;
padding: 0rem 1.5rem;
margin-left: 1px;
min-width: 124px;
width: fit-content;
color: #444c65;
border-radius: 6.25rem;
height: 40px;
background-color: #f7f2fa;
box-shadow:
0px 1px 2px rgba(0, 0, 0, 0.3),
0px 1px 3px 1px rgba(0, 0, 0, 0.15);
}
.download-button:hover {
background: rgba(103, 80, 164, 0.08);
}
.download-button:focus,
.download-button:active {
background: rgba(103, 80, 164, 0.12);
}
.download-button:disabled {
background: rgba(29, 27, 32, 0.12);
}
.icon {
margin-right: 11px;
}
menu-tree {
display: none;
}
.menu {
position: fixed;
top: 2.5rem;
z-index: 10;
}
.three-dim-space {
display: flex;
flex-direction: row;
}
@media (max-width: 50rem) {
.image {
width: 100%;
}
}
@media (max-width: 40rem) {
menu-tree {
display: block;
}
mat-drawer {
display: none;
}
ccf-page-header {
margin-top: 4rem !important;
}
.three-dim-space {
flex-wrap: wrap;
}
}
}
@media screen and (max-width: 428px) {
.use-btns-us3 {
flex-direction: column;
}
}
::ng-deep {
.tree-class {
border-radius: 0.25rem;
max-width: 288px;
padding: unset;
}
.overlay-position {
max-height: calc(100vh - 4.5rem);
.mat-tree-node {
font-weight: 500;
color: #054f89;
}
}
.overlay-position-fifth-release,
.overlay-position-fourth-release {
max-height: calc(100vh - 4.5rem);
.mat-tree-node {
display: block;
padding: unset;
font-weight: 500;
color: #054f89;
}
}
.tree-class .table-of-contents {
padding: 0.75rem 0rem;
padding-left: 1rem;
}
}
::ng-deep .panelClass {
position: relative !important;
top: 1px;
min-width: unset !important;
}