File

src/app/components/simple-image/simple-image.component.ts

Description

Displays an image and image modal

Metadata

Index

Methods
Inputs

Constructor

constructor(dialog: MatDialog)

Creates instance of MatDialog

Parameters :
Name Type Optional
dialog MatDialog No

Inputs

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

Methods

openImageViewer
openImageViewer(content: TemplateRef<>)

Opens a modal when clicked on image

Parameters :
Name Type Optional
content TemplateRef<> No
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;
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""