libs/core/ui/src/markdown-to-html/markdown-to-html.component.ts

Metadata

Relationships

Index

Properties
Methods
Inputs

Constructor

constructor()

Inputs

markdown
Type : string
Required :  true

Methods

isInternalLink
isInternalLink(url: string)
Parameters :
Name Type Optional
url string No
Returns : boolean
navigate
navigate(url: string)
Parameters :
Name Type Optional
url string No
Returns : void

Properties

processor
Type : unknown
Default value : unified().use(remarkParse).use(RemarkGfm).use(remarkBreaks).use(remarkDirective)
import { NxButtonModule } from '@allianz/ng-aquila/button';
import { NxLinkModule } from '@allianz/ng-aquila/link';
import { NxListModule } from '@allianz/ng-aquila/list';
import remarkDirective from 'remark-directive';
import { ChangeDetectionStrategy, Component, effect, inject, input } from '@angular/core';
import remarkBreaks from 'remark-breaks';
import RemarkGfm from 'remark-gfm';
import remarkParse from 'remark-parse';
import { unified } from 'unified';
import { TalyMarkdownToHtmlService } from './markdown-to-html.service';
import { RemarkModule } from './ngx-remark';

@Component({
  imports: [NxButtonModule, NxListModule, NxLinkModule, RemarkModule],
  selector: 'taly-markdown-to-html',
  templateUrl: './markdown-to-html.component.html',
  standalone: true,
  styleUrl: './markdown-to-html.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MarkdownToHtmlComponent {
  private markdownToHtmlService = inject(TalyMarkdownToHtmlService, { optional: true });
  private readonly internalLinkPrefix = 'page://';

  markdown = input.required<string>();
  processor = unified().use(remarkParse).use(RemarkGfm).use(remarkBreaks).use(remarkDirective);

  constructor() {
    effect(() => {
      const hasInternalLink = this.markdown().includes(this.internalLinkPrefix);
      if (hasInternalLink && !this.markdownToHtmlService) {
        console.warn(
          'Please provide TalyMarkdownToHtmlService if you want to navigate to internal pages'
        );
      }
    });
  }

  navigate(url: string): void {
    const internalPageId = url.slice(this.internalLinkPrefix.length);
    this.markdownToHtmlService?.gotoPage(internalPageId);
  }

  isInternalLink(url: string): boolean {
    return url.startsWith(this.internalLinkPrefix);
  }
}
<span class="nx-popover__text">
  <remark [markdown]="markdown()" [processor]="processor">
    <ng-template remarkTemplate="paragraph" let-node>
      <p class="nx-margin-y-0" [remarkNode]="node"></p>
    </ng-template>
    <ng-template remarkTemplate="link" let-node>
      @if (isInternalLink(node.url)) {
      <button
        nxPlainButton
        class="markdown-button-inline"
        type="button"
        (click)="navigate(node.url)"
      >
        <span [remarkNode]="node"></span>
      </button>
      } @else {
      <nx-link class="markdown-link-inline">
        <!-- eslint-disable-next-line @angular-eslint/template/elements-content-->
        <a target="_blank" rel="noopener" [href]="node.url" [remarkNode]="node"></a>
      </nx-link>
      }
    </ng-template>

    <ng-template remarkTemplate="list" let-node>
      <ul nxList="xsmall" class="nx-margin-bottom-0">
        <!--
          Need to navigate the "listItems" instead of adding [remarkNode]="node" to the "ul" element and providing a custom template for the "listItems".
          Reason: Angular error because "nxList" and "remarkNode" match as selectors for "ul", which is a conflict: https://angular.dev/errors/NG0300
          -->
        @for (item of node.children; track $index) {
        <li class="nx-margin-bottom-0 nx-font-weight-regular" [remarkNode]="item"></li>
        }
      </ul>
    </ng-template>
  </remark>
</span>

./markdown-to-html.component.scss

/* Fix for italic formatting in markdown
* The Allianz base theme globally resets em { font-style: normal; }
* This override restores proper italic rendering for markdown content
*/
:host ::ng-deep p em {
  font-style: italic;
}

.markdown-button-inline {
  font-size: 1em;
  vertical-align: baseline;
  line-height: 1.4em;
}
.markdown-link-inline {
  font-size: 1em;
  line-height: 1.4em;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""