File

src/app/text-display/text-display.component.ts

Description

The text display component shows text in a labeled box, and if desired, allows the user to edit and save the text

Metadata

selector app-text-display
styleUrls ./text-display.component.scss
templateUrl ./text-display.component.html

Index

Properties
Methods
Inputs
Accessors

Inputs

labelText
Type : string

The title text.

onEditFinished
Type : TextDisplayEditCallbackFn

A callback function.

placeholder
Type : string
Default value : ''

The placeholder will be shown if the content is empty

readonly
Type : boolean

If true, the edit button is not shown

text
Type : string

Sets the content of the text display, and shows the placeholder if the text is empty

Methods

finishEditing
finishEditing(saved: boolean)
Parameters :
Name Type Optional
saved boolean No
Returns : void
startEditing
startEditing()
Returns : void

Properties

editMode
Default value : false
editText
Type : string
Default value : ''
showPlaceholder
Default value : false
Private value
Type : string

Accessors

text
gettext()
settext(value: string)

Sets the content of the text display, and shows the placeholder if the text is empty

Parameters :
Name Type Optional
value string No
Returns : void
import {Component, Input} from '@angular/core';

/**
 * A callback function that is called once the user finishes editing the text.
 * @param saved true if the user clicked save, false if the user cancelled the editing
 */
export type TextDisplayEditCallbackFn = (saved: boolean) => void;

/**
 * The text display component shows text in a labeled box, and if desired, allows the user to edit and save the
 * text
 */
@Component({
  selector: 'app-text-display',
  templateUrl: './text-display.component.html',
  styleUrls: ['./text-display.component.scss']
})
export class TextDisplayComponent {
  private value: string;
  editMode = false;
  editText = '';
  showPlaceholder = false;

  /** A callback function. */
  @Input() onEditFinished: TextDisplayEditCallbackFn;
  /** The title text. */
  @Input() labelText: string;
  /** Sets the content of the text display, and shows the placeholder if the text is empty */
  @Input() set text(value: string) {
    this.value = value;
    this.showPlaceholder = !value || value.length === 0;
  }

  get text(): string {
    return this.value;
  }

  /** If true, the edit button is not shown */
  @Input() readonly: boolean;
  /** The placeholder will be shown if the content is empty */
  @Input() placeholder = '';

  finishEditing(saved: boolean): void {
    this.editMode = false;
    if (saved) {
      this.text = this.editText;
    }

    if (this.onEditFinished) {
      this.onEditFinished(saved);
    }
  }

  startEditing(): void {
    this.editText = this.text;
    this.editMode = true;
  }
}
<ng-container *ngIf="editMode; else readOnlyDisplay">
  <mat-form-field appearance="outline" class="text-edit-container">
    <mat-label>{{ labelText }}</mat-label>
    <textarea [(ngModel)]="editText" matInput autofocus cdkTextareaAutosize style="margin-bottom: 8px"></textarea>
    <div matSuffix style="display: flex">
      <button mat-icon-button color="primary" (click)="finishEditing(true)">
        <mat-icon>save</mat-icon>
      </button>
      <button mat-icon-button color="warn" (click)="finishEditing(false)">
        <mat-icon>cancel</mat-icon>
      </button>
    </div>
  </mat-form-field>
</ng-container>

<ng-template #readOnlyDisplay>
  <div class="text-display-container">
    <div class="text-display-label-container">
      <span class="text-display-label">{{ labelText }}</span>
    </div>
    <button *ngIf="readonly === undefined" mat-icon-button style="float: right; margin: 0" color="primary" (click)="startEditing()">
      <mat-icon>edit</mat-icon>
    </button>
    <div
      [ngClass]="{
        'text-content-container': !showPlaceholder,
        'text-content-container-placeholder': showPlaceholder
      }"
    >
      <ng-container *ngFor="let line of (showPlaceholder ? placeholder : text).split('\n')">
        {{ line.replace("\n", "") }}<br />
      </ng-container>
    </div>
  </div>
</ng-template>

./text-display.component.scss

@import "src/styles/variables";

.text-display-label-container {
  position: relative;
  width: fit-content;
  height: 0.8em;
  line-height: 0.8em;
  padding: 0 2px 0 2px;
  top: -0.5em;
  left: -1px;
  background-color: #fafafa; // FIXME: Hardcoded background color
  color: rgba(0, 0, 0, 0.6);
  text-align: center;
}

.text-display-label {
  display: inline-block;
  vertical-align: middle;
  font-size: 0.8em;
}

.text-display-container {
  margin-top: 10px;
  padding: 0 8px 16px 8px;
  width: 100%;
  height: 100%;
  border: 1px rgba(0, 0, 0, 0.2) solid;
  border-radius: 4px;
  word-break: break-all;
  min-height: 60px;
}

.text-content-container {
  padding-top: 8px;
}

.text-content-container-placeholder {
  padding-top: 8px;
  color: gray;
  font-style: italic;
}

.text-edit-container {
  width: 100%;
  height: 100%;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""