Code snippet

  
    
      
        <bs-datatable #tabel [columns]="columns" [fetch]="fetchArtists"
        
    
      
          [(sortColumns)]="sortColumns" pagination>
        
    
      
          <ng-container *bsDatatableRow="let artist">
        
    
      
            <td class="text-nowrap">{{ artist.name }}</td>
        
    
      
            <td class="text-nowrap">{{ artist.yearStarted }}</td>
        
    
      
            <td class="text-nowrap">{{ artist.yearQuit }}</td>
        
    
      
          </ng-container>
        
    
      
        </bs-datatable>
        
    

Highlighting comes from highlight.js. Only its core is loaded up front; the grammar for the language you ask for is fetched on demand, so a page with one ts snippet pays for one grammar rather than all 36.

Line numbers

Off by default — a one-line install command gains nothing from a 1 beside it.

  
    
      
        
          
        export function total(items: Item[]): number {
        
    
      
        
          
          let sum = 0;
        
    
      
        
          
          for (const item of items) {
        
    
      
        
          
            if (item.taxable) {
        
    
      
        
          
              sum += item.price * 1.21;
        
    
      
        
          
            } else {
        
    
      
        
          
              sum += item.price;
        
    
      
        
          
            }
        
    
      
        
          
          }
        
    
      
        
          
          return sum;
        
    
      
        
          
        }
        
    
  
    
      
        <bs-code-snippet [code]="source" [language]="'ts'" [lineNumbers]="true" />
        
    

Theming

The block follows the page's data-bs-theme with no wiring — flip the theme switch in the topbar and this snippet follows it. Pass [theme]="'light'" or 'dark' to pin it instead.

  
    
      
        export function total(items: Item[]): number {
        
    
      
          let sum = 0;
        
    
      
          for (const item of items) {
        
    
      
            if (item.taxable) {
        
    
      
              sum += item.price * 1.21;
        
    
      
            } else {
        
    
      
              sum += item.price;
        
    
      
            }
        
    
      
          }
        
    
      
          return sum;
        
    
      
        }
        
    
  
    
      
        export function total(items: Item[]): number {
        
    
      
          let sum = 0;
        
    
      
          for (const item of items) {
        
    
      
            if (item.taxable) {
        
    
      
              sum += item.price * 1.21;
        
    
      
            } else {
        
    
      
              sum += item.price;
        
    
      
            }
        
    
      
          }
        
    
      
          return sum;
        
    
      
        }
        
    
  
    
      
        <!-- follows data-bs-theme by default -->
        
    
      
        <bs-code-snippet [code]="source" [language]="'ts'" />
        
    
      
        
        
    
      
        <!-- or pin it -->
        
    
      
        <bs-code-snippet [code]="source" [language]="'ts'" [theme]="'dark'" />
        
    

Per-line annotations

Each line can carry a kind, up to two gutter labels and a description. kind is an opaque string — the component ships no colours for it, so you style the row class annotation-<kind> from your own stylesheet and the component stays coverage-agnostic.

Keyboard: Tab reaches the active line, then the arrow keys move between line links and Home / End jump to the first and last. Clicking a line number sets the active line here; the underlying link is a real href, so middle-click still opens it.

  
    
      
        
          
            1
          
        
          
        export function total(items: Item[]): number {
        
    
      
        
          
            2
          
        
          
          let sum = 0;
        
    
      
        
          
            3
          
        
          
          for (const item of items) {
        
    
      
        
          
            4
          
        
          
        
          
            if (item.taxable) {
        
          
            Branches: 1 of 2 taken
          
        
    
      
        
          
            5
          
        
          
              sum += item.price * 1.21;
        
    
      
        
          
            6
          
        
          
            } else {
        
    
      
        
          
            7
          
        
          
              sum += item.price;
        
    
      
        
          
            8
          
            }
        
    
      
        
          
            9
          
        
          
          }
        
    
      
        
          
            10
          
          return sum;
        
    
      
        
          
            11
          
        }
        
    
Use the up and down arrow keys to move between line links, Home and End for the first and last line.
  
    
      
        <bs-code-snippet
        
    
      
          [code]="source"
        
    
      
          [language]="'ts'"
        
    
      
          [lineNumbers]="true"
        
    
      
          [annotations]="coverage"
        
    
      
          [activeLine]="activeLine()"
        
    
      
          [lineHref]="lineHref"
        
    
      
          (lineActivate)="onLineActivate($event)" />
        
    
  
    
      
        readonly coverage: CodeLineAnnotation[] = [
        
    
      
          { line: 4, kind: 'partial', label: '4×', secondaryLabel: '1/2',
        
    
      
            description: 'Branches: 1 of 2 taken' },
        
    
      
          { line: 6, kind: 'uncovered', label: '0' },
        
    
      
        ];
        
    
      
        
        
    
      
        // `kind` is opaque: it becomes the row class annotation-<kind>,
        
    
      
        // styled from your own stylesheet:
        
    
      
        //   .coverage ::ng-deep .annotation-uncovered { … }
        
    
      
        lineHref = (line: number) => `#L${line}`;
        
    
      
        
        
    
      
        // Prevent the link's navigation when you handle the activation yourself.
        
    
      
        // Modified and middle clicks never reach here, so open-in-new-tab keeps working.
        
    
      
        onLineActivate(event: CodeLineActivation) {
        
    
      
          event.preventDefault();
        
    
      
          this.activeLine.set(event.line);
        
    
      
        }
        
    
      
        
        
    
      
        // A fragment does NOT scroll to the line. Read it on navigation and drive
        
    
      
        // the snippet explicitly instead:
        
    
      
        //   viewChild(BsCodeSnippetComponent).scrollToLine(n)
        
    

Constrained size

Give the component a height or max-height and the listing scrolls vertically inside it; constrain the width and long lines scroll horizontally. Both scrollbars belong to the code area, so the copy button and the line-number gutter stay put while you scroll.

  
    
      
        
          
        <bs-datatable #tabel [columns]="columns" [fetch]="fetchArtists"
        
    
      
        
          
          [(sortColumns)]="sortColumns" pagination>
        
    
      
        
          
          <ng-container *bsDatatableRow="let artist">
        
    
      
        
          
            <td class="text-nowrap">{{ artist.name }}</td>
        
    
      
        
          
            <td class="text-nowrap">{{ artist.yearStarted }}</td>
        
    
      
        
          
            <td class="text-nowrap">{{ artist.yearQuit }}</td>
        
    
      
        
          
          </ng-container>
        
    
      
        
          
        </bs-datatable>
        
    
  
    
      
        <bs-code-snippet
        
    
      
          class="sized-snippet"
        
    
      
          [code]="source"
        
    
      
          [language]="'html'"
        
    
      
          [lineNumbers]="true" />
        
    
  
    
      
        /* Any height constraint works — the code area scrolls inside it. */
        
    
      
        .sized-snippet {
        
    
      
          max-height: 220px;
        
    
      
        }