src/app/components/simple-image/simple-image.component.ts
Displays an image and image modal
selector | ccf-simple-image |
styleUrls | ./simple-image.component.scss |
templateUrl | ./simple-image.component.html |
Methods |
Inputs |
constructor(dialog: MatDialog)
|
||||||
Creates instance of MatDialog
Parameters :
|
customModalClass | |
Type : string
|
|
Default value : ''
|
|
Custom class for the modal |
headerData | |
Type : CardHeader
|
|
Details of button and subtitle inside the header section of the card |
imageInfo | |
Type : ImageData[]
|
|
Default value : []
|
|
Details to be displayed inside the card |
openImageViewer | ||||||
openImageViewer(content: TemplateRef<>)
|
||||||
Opens a modal when clicked on image
Parameters :
Returns :
void
|
import { Component, Input, TemplateRef } from '@angular/core';
import { CardHeader, ImageData } from './simple-image';
import { MatDialog } from '@angular/material/dialog';
/** Displays an image and image modal */
@Component({
selector: 'ccf-simple-image',
templateUrl: './simple-image.component.html',
styleUrls: ['./simple-image.component.scss'],
})
export class SimpleImageComponent {
/** Details to be displayed inside the card */
@Input() imageInfo: ImageData[] = [];
/** Details of button and subtitle inside the header section of the card */
@Input() headerData?: CardHeader;
/** Custom class for the modal */
@Input() customModalClass = '';
/** Creates instance of MatDialog */
constructor(private readonly dialog: MatDialog) {}
/** Opens a modal when clicked on image */
openImageViewer(content: TemplateRef<unknown>): void {
const fontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
const isSmallScreen = window.innerWidth / fontSize < 63;
if (!isSmallScreen) {
this.dialog.open(content, {
panelClass: ['custom-modal', this.customModalClass],
});
}
}
}
<mat-card *ngFor="let image of imageInfo" class="simple-image-card">
<mat-card-header>
<div *ngIf="image.title">
{{ image.title }}
</div>
<div *ngIf="headerData" class="header-container">
<div class="title-btn">
<div>{{ headerData.title }}</div>
<a mat-raised-button disableRipple href="{{ headerData.buttonData.url }}" target="_blank">
{{ headerData.buttonData.text }}
</a>
</div>
<div class="header-subtitle">{{ headerData.subtitle }}</div>
</div>
</mat-card-header>
<mat-divider></mat-divider>
<div *ngIf="image.description" class="description">
<markdown>{{ image.description }}</markdown>
</div>
<mat-card-actions>
<img [src]="image.image" [alt]="image.alt" (click)="openImageViewer(imageViewerContent)" />
<ng-template #imageViewerContent>
<div class="dialog-header">
<span *ngIf="headerData?.title" mat-dialog-title>{{ headerData?.title }}</span>
<span mat-dialog-title>{{ image.title }}</span>
<div style="flex-grow: 1"></div>
<button mat-dialog-close mat-button [disableRipple]="true" class="open-button">
<mat-icon>close</mat-icon>
</button>
</div>
<mat-divider *ngIf="headerData"></mat-divider>
<img [src]="image.imageDialog" [alt]="image.alt" />
</ng-template>
</mat-card-actions>
</mat-card>
./simple-image.component.scss
:host {
display: block;
padding-bottom: 2rem;
img {
max-width: 100%;
max-height: 100%;
}
.description {
padding: 1.5rem 2rem;
font-weight: 300;
font-size: 1rem;
line-height: 1.5rem;
letter-spacing: 0.005em;
}
mat-card-header {
font-weight: 300;
font-size: 1.5rem;
line-height: 1.5rem;
letter-spacing: 0.005rem;
padding: 1rem 2rem;
}
.image-container {
display: flex;
flex-direction: column;
align-self: center;
}
mat-card-actions {
display: flex;
flex-direction: column;
align-items: center;
padding: unset;
padding-bottom: 1rem !important;
}
.header-container {
width: 100%;
margin: 1rem 0;
}
.title-btn {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 1rem;
flex-wrap: wrap;
gap: 2rem;
}
.mat-mdc-raised-button {
font-weight: 500;
font-size: 1rem;
padding: 0rem 1.5rem;
margin-left: 1px;
min-width: 124px;
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);
white-space: normal;
letter-spacing: 0;
line-height: 20px;
}
.header-subtitle {
font-size: 1rem;
}
.simple-image-card {
padding: unset;
}
::ng-deep .mat-card-header-text {
margin: unset !important;
}
@media (max-width: 26.75rem) {
.mat-mdc-card-header {
font-size: 1.125rem;
padding: 1rem;
}
.description {
padding: 1rem;
}
.mat-card-actions {
pointer-events: none;
}
.title-btn {
flex-wrap: unset;
flex-direction: column;
}
}
}
::ng-deep .custom-modal {
.mat-mdc-dialog-container .mdc-dialog__surface {
display: flex;
flex-direction: column;
padding: 1.5rem;
}
.mat-icon {
padding-bottom: 0.625rem;
height: 1.75rem;
}
.dialog-header {
display: flex;
flex-direction: row;
width: 100%;
}
.mat-button-toggle-focus-overlay {
display: none;
}
.mdc-dialog__title {
display: flex;
--mdc-dialog-subhead-weight: 300;
--mdc-dialog-subhead-size: 1.5rem;
--mdc-dialog-subhead-line-height: 1.5rem;
--mdc-dialog-subhead-tracking: 0.005rem;
margin: unset;
padding: 0;
}
}
::ng-deep .modal {
padding: 1rem;
max-width: calc(100vw - 1rem) !important;
img {
max-height: calc(100vh - 7.5rem - 1px);
}
.mat-divider {
margin: 0 -1.5rem 0 -2rem;
}
}