# Highlight

- Page: https://koobiq.io/en/components/highlight/overview

Highlighting matches helps users quickly understand why a result is relevant and speeds up navigation through lists. Depending on the context, one of two styles is used.

Koobiq provides two pipes for highlighting text matches — `kbqHighlightBackground` and `kbqHighlightBold`. Both take a string and a search argument, wrapping the found matches in a `<mark>` tag — `kbq-highlight-background` for the background-color style and `kbq-highlight` for the bold style.

## Background color

Used in selects and other dropdown pickers with filtering, and to highlight matches in complex content: descriptions, messages, and articles. The solid background remains legible in hover and active states within overlays and makes matches noticeable even in long texts.

**Example: Highlight in select** (`highlight-select`)

```ts highlight-select-example.ts
import { AsyncPipe } from '@angular/common';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { KbqHighlightBackgroundPipe } from '@koobiq/components/core';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqInputModule } from '@koobiq/components/input';
import { KbqSelectModule } from '@koobiq/components/select';
import { map, startWith } from 'rxjs/operators';

@Component({
    selector: 'highlight-select-example',
    imports: [
        KbqSelectModule,
        KbqIconModule,
        KbqInputModule,
        AsyncPipe,
        ReactiveFormsModule,
        KbqHighlightBackgroundPipe
    ],
    template: `
        <kbq-form-field>
            <kbq-select placeholder="Choose a club">
                <kbq-form-field noBorders kbqSelectSearch>
                    <i kbq-icon="kbq-magnifying-glass_16" kbqPrefix></i>
                    <input kbqInput type="text" [formControl]="searchControl" />
                    <kbq-cleaner />
                </kbq-form-field>

                <div kbq-select-search-empty-result>Nothing found</div>

                @for (option of filteredOptions | async; track option) {
                    <kbq-option [value]="option">
                        <span [innerHTML]="option | kbqHighlightBackground: searchControl.value"></span>
                    </kbq-option>
                }
            </kbq-select>
        </kbq-form-field>
    `,
    styles: `
        :host {
            display: flex;
            justify-content: center;
        }

        .kbq-form-field-type-select {
            width: 320px;
        }
    `,
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class HighlightSelectExample {
    readonly options = [
        'Manchester United',
        'Manchester 62 FC',
        'FC United of Manchester',
        'Manchester United Reserves',
        'Manchester United U23',
        'Manchester United U19',
        'Manchester United Academy',
        'Manchester United Women (W)'
    ];
    readonly searchControl = new FormControl('');
    readonly filteredOptions = this.searchControl.valueChanges.pipe(
        startWith(''),
        map((query) => this.search(query))
    );

    private search(query: string | null): string[] {
        return query
            ? this.options.filter((option) => option.toLowerCase().includes(query.toLowerCase()))
            : this.options;
    }
}
```

Matches in text:

**Example: Highlight with background color** (`highlight-background`)

```ts highlight-background-example.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqHighlightBackgroundPipe } from '@koobiq/components/core';

@Component({
    selector: 'highlight-background-example',
    imports: [KbqHighlightBackgroundPipe],
    template: `
        <div class="kbq-headline layout-margin-bottom-s" [innerHTML]="title | kbqHighlightBackground: keyword"></div>
        <div class="kbq-text-normal" [innerHTML]="text | kbqHighlightBackground: keyword"></div>
    `,
    styles: `
        :host {
            display: block;
        }

        .highlight-background-example p {
            margin: var(--kbq-size-m) 0 0;
        }
    `,
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class HighlightBackgroundExample {
    readonly keyword = 'cub';
    readonly title = 'Cube';
    readonly text =
        'The cube can be represented in many ways. One example is by drawing a graph, a structure in graph' +
        ' theory consisting of a set of vertices that are connected with an edge. This graph also represents the' +
        ' family of a cuboid, a polyhedron with six quadrilateral faces, which includes the cube as its special' +
        ' case. The cube and its graph are a three dimensional hypercube, a family of polytopes that also includes' +
        ' the two-dimensional square and four-dimensional tesseract.';
}
```

Matches in search results with a complex layout:

**Example: Highlight in complex content** (`highlight-background-complex`)

```ts highlight-background-complex-example.ts
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { KbqButtonModule } from '@koobiq/components/button';
import { KbqComponentColors, KbqHighlightBackgroundPipe } from '@koobiq/components/core';
import { KbqIcon } from '@koobiq/components/icon';
import { KbqInputModule } from '@koobiq/components/input';
import { KbqLink } from '@koobiq/components/link';

type SearchResult = {
    title: string;
    url: string;
    snippet: string;
};

@Component({
    selector: 'highlight-background-complex-example',
    imports: [
        KbqInputModule,
        KbqIcon,
        KbqButtonModule,
        ReactiveFormsModule,
        KbqHighlightBackgroundPipe,
        KbqLink
    ],
    template: `
        <div style="margin-bottom: var(--kbq-size-xl)">
            <kbq-fieldset>
                <kbq-form-field kbqFieldsetItem>
                    <i kbqPrefix kbq-icon="kbq-magnifying-glass_16"></i>
                    <input kbqInput placeholder="Search" [formControl]="control" />
                </kbq-form-field>
                <button kbqFieldsetItem kbq-button [color]="colors.Contrast" (click)="applySearch()">Search</button>
            </kbq-fieldset>
        </div>

        @for (result of results; track result.url) {
            <article style="margin-bottom: var(--kbq-size-l)">
                <a href="{{ result.url }}" target="_blank" kbqLink>
                    <span
                        class="kbq-text-big-strong"
                        [innerHTML]="result.title | kbqHighlightBackground: query()"
                    ></span>
                </a>
                <div class="highlight-example__header">{{ result.url }}</div>
                <p style="margin: 0" [innerHTML]="result.snippet | kbqHighlightBackground: query()"></p>
            </article>
        }
    `,
    styles: `
        :host {
            display: block;
        }

        .highlight-example__header {
            margin: var(--kbq-size-xxs) 0;
            color: var(--kbq-foreground-contrast-secondary);
        }
    `,
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class HighlightBackgroundComplexExample {
    protected readonly colors = KbqComponentColors;
    protected readonly control = new FormControl('cube');
    protected readonly query = signal(this.control.value);
    protected readonly results: SearchResult[] = [
        {
            title: 'Cube',
            url: 'https://en.wikipedia.org/wiki/Cube',
            snippet:
                'A cube is a three-dimensional solid object in geometry. A cube has eight vertices and twelve straight' +
                ' edges of the same length, so that these edges form six faces.'
        },
        {
            title: 'Cube (1997 film)',
            url: 'https://en.wikipedia.org/wiki/Cube_(1997_film)',
            snippet:
                'Cube is a 1997 Canadian science fiction horror film directed and co-written by Vincenzo Natali.' +
                " A product of the Canadian Film Centre's First Feature Project."
        },
        {
            title: 'Cube (algebra)',
            url: 'https://en.wikipedia.org/wiki/Cube_(algebra)',
            snippet:
                'In arithmetic and algebra, the cube of a number n is its third power, that is, the result of' +
                ' multiplying three instances of n together.'
        },
        {
            title: 'Cube (2021 film)',
            url: 'https://en.wikipedia.org/wiki/Cube_(2021_film)',
            snippet:
                'The story centers on a group of strangers who awaken in a cube-shaped room connected to adjacent' +
                ' rooms, forming an elaborate maze filled with traps.'
        }
    ];

    protected applySearch(): void {
        this.query.set(this.control.value);
    }
}
```

Matches in a table:

**Example: Highlight in table** (`highlight-background-table`)

```ts highlight-background-table-example.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqHighlightBackgroundPipe } from '@koobiq/components/core';
import { KbqLink } from '@koobiq/components/link';
import { KbqTableModule } from '@koobiq/components/table';

type CompanyRow = {
    city: string;
    company: string;
    person: string;
    notes: string;
    note?: string;
};

@Component({
    selector: 'highlight-background-table-example',
    imports: [
        KbqTableModule,
        KbqLink,
        KbqHighlightBackgroundPipe
    ],
    template: `
        <table kbq-table class="highlight-table">
            <thead>
                <tr>
                    <th style="width: 96px">City</th>
                    <th style="width: 124px">Company</th>
                    <th style="width: 116px">Person</th>
                    <th>Notes</th>
                </tr>
            </thead>
            <tbody>
                @for (row of rows; track row.city) {
                    <tr [class.highlight-table__row_with-note]="row.note">
                        <td>
                            <a kbqLink href="#" (click)="$event.preventDefault()">
                                <span [innerHTML]="row.city | kbqHighlightBackground: keyword"></span>
                            </a>
                        </td>
                        <td [innerHTML]="row.company | kbqHighlightBackground: keyword"></td>
                        <td [innerHTML]="row.person | kbqHighlightBackground: keyword"></td>
                        <td [innerHTML]="row.notes | kbqHighlightBackground: keyword"></td>
                    </tr>
                }
            </tbody>
        </table>
    `,
    styles: `
        :host {
            display: block;
        }

        .highlight-table {
            width: 100%;
        }

        .highlight-table__row_with-note > td {
            border-bottom: none;
            padding-bottom: var(--kbq-size-xxs);
        }
    `,
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class HighlightBackgroundTableExample {
    protected readonly keyword = 'manc';
    protected readonly rows: CompanyRow[] = [
        {
            city: 'Manchester',
            company: 'Blue Harbor Ltd',
            person: 'Alice Brown',
            notes: 'Annual review completed'
        },
        {
            city: 'Liverpool',
            company: 'Mancraft Studio',
            person: 'Daniel Reed',
            notes: 'New client onboarded'
        },
        {
            city: 'Bristol',
            company: 'GreenField Tech',
            person: 'Mancini Robert',
            notes: 'Budget approved'
        },
        {
            city: 'Leeds',
            company: 'Northwind Labs',
            person: 'Emma Stone',
            notes: 'Visit planned for Manchester office'
        },
        {
            city: 'York',
            company: 'Delta Systems',
            person: 'Michael Turner',
            notes: 'Contract with Mancorp signed'
        },
        {
            city: 'Oxford',
            company: 'Silver Bridge',
            person: 'Laura Green',
            notes: 'Archived in mancategory B'
        }
    ];
}
```

## Bold

This style is unobtrusive and ideal for quickly scanning familiar data: the user immediately sees that the searched word is in the row but is not distracted from the main choice.

```html
<span [innerHTML]="item | kbqHighlightBold: searchQuery"></span>
```

The pipe used to be called `mcHighlight`: that name is deprecated and will be removed in 22.0.0.
