# Navbar

- Entry point: `@koobiq/components/navbar`
- NgModule: `KbqNavbarModule`
- Page: https://koobiq.io/en/components/navbar/overview

## Overview

The main menu allows for product navigation. It consists of a logo and section links. You can also add an application switch, main action button, notification center, and search.

You can place the menu at the top or to the left. Both options have their advantages. Select the one that suits your product better.

### Horizontal menu

The menu uses the top row and allows content to occupy the full screen width. The horizontal menu works better with three or more columns. The main menu is pinned to the top and remains visible when you scroll content: place it outside the scrolling area.

**Example: Navbar** (`navbar-overview`)

```ts navbar-overview-example.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqBadgeModule } from '@koobiq/components/badge';
import { KbqButtonModule } from '@koobiq/components/button';
import { PopUpPlacements } from '@koobiq/components/core';
import { KbqDividerModule } from '@koobiq/components/divider';
import { KbqDropdownModule } from '@koobiq/components/dropdown';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqNavbarModule } from '@koobiq/components/navbar';
import { injectExampleText } from '../localized-data';

@Component({
    selector: 'navbar-overview-example',
    imports: [
        KbqDropdownModule,
        KbqDividerModule,
        KbqNavbarModule,
        KbqButtonModule,
        KbqBadgeModule,
        KbqIconModule
    ],
    templateUrl: 'navbar-overview-example.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavbarOverviewExample {
    protected readonly text = injectExampleText();

    popUpPlacements = PopUpPlacements;
}
```

```html navbar-overview-example.html
<kbq-dropdown #horizontalNavbarDropdownApps="kbqDropdown">
    @for (app of text().apps; track $index) {
        <button kbq-dropdown-item>{{ app }}</button>
    }
</kbq-dropdown>

<kbq-dropdown #horizontalNavbarTasks="kbqDropdown">
    <button kbq-dropdown-item>{{ text().taskStatuses.open }}</button>
    <button kbq-dropdown-item>{{ text().taskStatuses.inProgress }}</button>
    <button kbq-dropdown-item>{{ text().taskStatuses.done }}</button>
    <button kbq-dropdown-item>{{ text().taskStatuses.canceled }}</button>
</kbq-dropdown>

<kbq-dropdown #horizontalNavbarProfile="kbqDropdown">
    <button kbq-dropdown-item>{{ text().profileMenu.settings }}</button>
    <kbq-divider />
    <button kbq-dropdown-item>{{ text().administration }}</button>
    <button kbq-dropdown-item>{{ text().profileMenu.users }}</button>
    <kbq-divider />
    <button kbq-dropdown-item>{{ text().profileMenu.downloadApp }}</button>
    <kbq-divider />
    <button kbq-dropdown-item>{{ text().profileMenu.switchTenant }}</button>
    <button kbq-dropdown-item>{{ text().profileMenu.logOut }}</button>
</kbq-dropdown>

<kbq-navbar>
    <kbq-navbar-container>
        <kbq-navbar-item
            #horizontalNavbarDropdownAppsDropdownTrigger="kbqDropdownTrigger"
            bento
            [class.kbq-active]="horizontalNavbarDropdownAppsDropdownTrigger.opened"
            [kbqDropdownTriggerFor]="horizontalNavbarDropdownApps"
            [kbqPlacement]="popUpPlacements.BottomLeft"
            [tooltipText]="text().allApps"
            [kbqTrigger]="'hover'"
        >
            <i kbq-icon="kbq-bento-menu_16" color="contrast"></i>
        </kbq-navbar-item>

        <a href="#" kbq-navbar-brand>
            <kbq-navbar-logo>
                <!-- prettier-ignore -->
                <svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M0 25.6C0 28.4045 0 29.9635 1.01826 30.9817C2.03651 32 3.59554 32 6.4 32H25.6C28.4045 32 29.9635 32 30.9817 30.9817C32 29.9635 32 28.4045 32 25.6V6.4C32 3.59554 32 2.03651 30.9817 1.01826C29.9635 0 28.4045 0 25.6 0H6.4C3.59554 0 2.03651 0 1.01826 1.01826C0 2.03651 0 3.59554 0 6.4V25.6Z" fill="#FF0000" fill-rule="evenodd"/><path d="M14.9774 16L11.1933 19.7841L7.40918 16L11.1933 12.267L14.9774 16ZM19.7842 20.858L16.0512 24.5909L12.2671 20.858L16.0512 17.0739L19.7842 20.858ZM19.7842 11.1932L16.0512 14.9261L12.2671 11.1932L16.0512 7.40909L19.7842 11.1932ZM24.591 16L20.858 19.7841L17.1251 16L20.858 12.267L24.591 16Z" fill="white"/></svg>
            </kbq-navbar-logo>
            <kbq-navbar-title>{{ text().appName }}</kbq-navbar-title>
        </a>

        <button
            kbq-navbar-item
            class="kbq-active"
            [kbqPlacement]="popUpPlacements.Bottom"
            [tooltipText]="text().dashboards"
        >
            <i kbq-icon="kbq-dashboard_16" color="contrast"></i>
        </button>

        <kbq-navbar-item
            #horizontalNavbarTasksDropdownTrigger="kbqDropdownTrigger"
            [class.kbq-active]="horizontalNavbarTasksDropdownTrigger.opened"
            [collapsable]="false"
            [kbqDropdownTriggerFor]="horizontalNavbarTasks"
        >
            <kbq-navbar-title>{{ text().tasks }}</kbq-navbar-title>
        </kbq-navbar-item>

        <kbq-navbar-item>
            <kbq-navbar-title>{{ text().projects }}</kbq-navbar-title>
        </kbq-navbar-item>

        <kbq-navbar-item>
            <button kbq-button [color]="'contrast'">
                <span>{{ text().newTask }}</span>
            </button>
        </kbq-navbar-item>
    </kbq-navbar-container>

    <kbq-navbar-container>
        <kbq-navbar-item [kbqPlacement]="popUpPlacements.Bottom" [tooltipText]="text().notifications">
            <i kbq-icon="kbq-bell_16" color="contrast"></i>
            <kbq-badge [badgeColor]="'error'" [compact]="true">5</kbq-badge>
        </kbq-navbar-item>

        <kbq-navbar-item [kbqPlacement]="popUpPlacements.Bottom" [tooltipText]="text().administration">
            <i kbq-icon="kbq-gear_16" color="contrast"></i>
        </kbq-navbar-item>

        <kbq-navbar-divider />

        <kbq-navbar-item [kbqPlacement]="popUpPlacements.Bottom" [tooltipText]="text().help">
            <i kbq-icon="kbq-magnifying-glass_16" color="contrast"></i>
        </kbq-navbar-item>

        <kbq-navbar-item
            #horizontalNavbarProfileDropdownTrigger="kbqDropdownTrigger"
            [class.kbq-active]="horizontalNavbarProfileDropdownTrigger.opened"
            [kbqDropdownTriggerFor]="horizontalNavbarProfile"
            [kbqPlacement]="popUpPlacements.BottomLeft"
            [tooltipText]="text().profile"
            [kbqTrigger]="'hover'"
        >
            <i kbq-icon="kbq-user_16" color="contrast"></i>
        </kbq-navbar-item>
    </kbq-navbar-container>
</kbq-navbar>
```

```ts ../localized-data.ts
import { computed, Signal } from '@angular/core';
import { kbqInjectLocaleService } from '@koobiq/components/core';

/** Resolves `data` for the active locale of the examples, falling back to `default` (English). */
export const injectLocalizedText = <T>(data: Record<string, T> & { default: T }): Signal<T> => {
    const localeService = kbqInjectLocaleService({ optional: true });

    return computed(() => data[localeService?.localeId() ?? 'default'] ?? data.default);
};

/** Text shown by the navbar examples. */
export interface ExampleText {
    allApps: string;
    /** Applications listed in the "all apps" menu. */
    apps: string[];
    appName: string;
    longAppName: string;
    dashboards: string;
    tasks: string;
    projects: string;
    newTask: string;
    documentation: string;
    more: string;
    point: (index: number) => string;
    notifications: string;
    administration: string;
    help: string;
    profile: string;
    taskStatuses: { open: string; inProgress: string; done: string; canceled: string };
    profileMenu: { settings: string; users: string; downloadApp: string; switchTenant: string; logOut: string };
    /** Placeholder text of the page next to the vertical navbar. */
    pageText: string[];
}

/** Text of the examples in the active locale. */
export const injectExampleText = (): Signal<ExampleText> =>
    injectLocalizedText<ExampleText>({
        'ru-RU': {
            allApps: 'Все приложения',
            apps: ['Управление пользователями', 'База знаний', 'Секретные заметки'],
            appName: 'Название приложения',
            longAppName: 'Очень длинное название меню с переносом строки и усечением многоточием',
            dashboards: 'Дашборды',
            tasks: 'Задачи',
            projects: 'Проекты',
            newTask: 'Новая задача',
            documentation: 'Документация',
            more: 'Еще',
            point: (index) => `Пункт ${index}`,
            notifications: 'Уведомления',
            administration: 'Администрирование',
            help: 'Справка',
            profile: 'Профиль',
            taskStatuses: { open: 'Открытые', inProgress: 'В работе', done: 'Выполненные', canceled: 'Отмененные' },
            profileMenu: {
                settings: 'Настройки',
                users: 'Пользователи',
                downloadApp: 'Скачать приложение',
                switchTenant: 'Сменить тенант',
                logOut: 'Выход'
            },
            pageText: [
                'Целое число в принципе поддерживает скачок функции. Полином отражает экспериментальный разрыв функции, что неудивительно. Интеграл от функции, имеющий конечный разрыв расточительно специфицирует предел функции, таким образом сбылась мечта идиота — утверждение полностью доказано. Интеграл Пуассона развивает интеграл Фурье. Неопределенный интеграл категорически соответствует расходящийся ряд. Не факт, что функция многих переменных по‑прежнему востребована.',
                'К тому же график функции усиливает тригонометрический интеграл по поверхности. Правда, некоторые специалисты отмечают, что неравенство Бернулли обуславливает действительный расходящийся ряд. Тем не менее, неопределенный интеграл раскручивает разрыв функции.',
                'Эпсилон окрестность привлекает интеграл по бесконечной области. Пустое подмножество, общеизвестно, допускает ряд Тейлора. Наибольшее и наименьшее значения функции недоказуемо. Вектор, не вдаваясь в подробности, осмысленно транслирует постулат. Ортогональный определитель упорядочивает линейно зависимый минимум. Интеграл от функции, обращающейся в бесконечность вдоль линии позитивно уравновешивает график функции.'
            ]
        },
        default: {
            allApps: 'All apps',
            apps: ['User Management', 'Knowledge Hub', 'Secret Notes'],
            appName: 'App name',
            longAppName: 'Super Long Menu Title with Line Wrap and Ellipsis Truncation',
            dashboards: 'Dashboards',
            tasks: 'Tasks',
            projects: 'Projects',
            newTask: 'New task',
            documentation: 'Documentation',
            more: 'More',
            point: (index) => `Point ${index}`,
            notifications: 'Notifications',
            administration: 'Administration',
            help: 'Help',
            profile: 'Profile',
            taskStatuses: { open: 'Open', inProgress: 'In progress', done: 'Done', canceled: 'Canceled' },
            profileMenu: {
                settings: 'Settings',
                users: 'Users',
                downloadApp: 'Download app',
                switchTenant: 'Switch tenant',
                logOut: 'Log out'
            },
            pageText: [
                'An integer, in principle, supports a jump of the function. The polynomial reflects an experimental discontinuity of the function, which is not surprising. The integral of a function with a finite discontinuity wastefully specifies the limit of the function, and so the fool’s dream came true — the statement is fully proved. The Poisson integral develops the Fourier integral. The indefinite integral categorically corresponds to a divergent series. It is not a given that a function of several variables is still in demand.',
                'Besides, the graph of the function amplifies the trigonometric surface integral. True, some experts note that Bernoulli’s inequality determines a real divergent series. Nevertheless, the indefinite integral unwinds the discontinuity of the function.',
                'The epsilon neighborhood attracts the integral over an infinite domain. The empty subset, as is well known, admits a Taylor series. The greatest and least values of the function are unprovable. The vector, without going into detail, meaningfully translates the postulate. The orthogonal determinant orders a linearly dependent minimum. The integral of a function that goes to infinity along a line positively balances the graph of the function.'
            ]
        }
    });
```

### Vertical menu

The vertical menu is convenient for long pages. When unfolded, it takes more place on a screen. When collapsed, it shows sections as icons. In some cases, it may be a challenge to pick a clear visual representation for a section.

**Example: Navbar vertical** (`navbar-vertical`)

```ts navbar-vertical-example.ts
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { KbqButtonModule } from '@koobiq/components/button';
import { KbqComponentColors, PopUpPlacements } from '@koobiq/components/core';
import { KbqDropdownModule } from '@koobiq/components/dropdown';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqNavbarModule } from '@koobiq/components/navbar';
import { KbqToolTipModule } from '@koobiq/components/tooltip';
import { injectExampleText } from '../localized-data';

@Component({
    selector: 'navbar-vertical-example',
    imports: [
        KbqDropdownModule,
        KbqNavbarModule,
        KbqButtonModule,
        KbqToolTipModule,
        KbqIconModule
    ],
    templateUrl: 'navbar-vertical-example.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavbarVerticalExample {
    protected readonly text = injectExampleText();

    readonly popUpPlacements = PopUpPlacements;
    readonly colors = KbqComponentColors;
    /** Position of the selected app in `text().apps`, so the selection survives a locale switch. */
    readonly selectedApp = signal(0);
}
```

```html navbar-vertical-example.html
<kbq-dropdown #verticalNavbarDropdown_1="kbqDropdown" [overlapTriggerX]="false" [overlapTriggerY]="true">
    @for (app of text().apps; track $index) {
        <button kbq-dropdown-item (click)="selectedApp.set($index)">{{ app }}</button>
    }
</kbq-dropdown>

<kbq-dropdown #verticalNavbarDropdown_3="kbqDropdown" [overlapTriggerX]="false" [overlapTriggerY]="true">
    <button kbq-dropdown-item>{{ text().point(1) }}</button>
    <button kbq-dropdown-item>{{ text().point(2) }}</button>
</kbq-dropdown>

<div style="height: 480px" class="layout-row">
    <kbq-vertical-navbar #verticalNavbar>
        <kbq-navbar-container>
            <div
                #verticalNavbarDropdownTrigger_1="kbqDropdownTrigger"
                bento
                kbq-navbar-item
                [class.kbq-active]="verticalNavbarDropdownTrigger_1.opened"
                [kbqDropdownTriggerFor]="verticalNavbarDropdown_1"
            >
                <i kbq-icon="kbq-bento-menu_16" color="contrast"></i>
                <div kbq-navbar-title>{{ text().allApps }}</div>
            </div>

            <a href="#" kbq-navbar-brand [collapsedText]="text().apps[selectedApp()]">
                <div kbq-navbar-logo>
                    <!-- prettier-ignore -->
                    <svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M0 25.6C0 28.4045 0 29.9635 1.01826 30.9817C2.03651 32 3.59554 32 6.4 32H25.6C28.4045 32 29.9635 32 30.9817 30.9817C32 29.9635 32 28.4045 32 25.6V6.4C32 3.59554 32 2.03651 30.9817 1.01826C29.9635 0 28.4045 0 25.6 0H6.4C3.59554 0 2.03651 0 1.01826 1.01826C0 2.03651 0 3.59554 0 6.4V25.6Z" fill="#FF0000" fill-rule="evenodd"/><path d="M14.9774 16L11.1933 19.7841L7.40918 16L11.1933 12.267L14.9774 16ZM19.7842 20.858L16.0512 24.5909L12.2671 20.858L16.0512 17.0739L19.7842 20.858ZM19.7842 11.1932L16.0512 14.9261L12.2671 11.1932L16.0512 7.40909L19.7842 11.1932ZM24.591 16L20.858 19.7841L17.1251 16L20.858 12.267L24.591 16Z" fill="white"/></svg>
                </div>

                <div kbq-navbar-title>{{ text().apps[selectedApp()] }}</div>
            </a>

            <a href="#" kbq-navbar-item class="kbq-active">
                <i kbq-icon="kbq-stop_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().dashboards }}</kbq-navbar-title>
            </a>

            <button kbq-navbar-item>
                <i kbq-icon="kbq-stop_16" color="contrast"></i>
                <span kbq-navbar-title>{{ text().tasks }}</span>
            </button>

            <kbq-navbar-item>
                <button
                    kbq-button
                    [class.kbq-button-icon]="!verticalNavbar.expanded()"
                    [color]="colors.Contrast"
                    [kbqPlacement]="popUpPlacements.Right"
                    [kbqStyle]="'filled'"
                    [attr.aria-label]="text().newTask"
                    [kbqTooltip]="text().newTask"
                    [kbqTooltipDisabled]="verticalNavbar.expanded()"
                >
                    <i kbq-icon="kbq-plus_16" [color]="'empty'"></i>
                    @if (verticalNavbar.expanded()) {
                        <span>{{ text().newTask }}</span>
                    }
                </button>
            </kbq-navbar-item>

            <kbq-navbar-item
                #verticalNavbarDropdownTrigger_3="kbqDropdownTrigger"
                [class.kbq-active]="verticalNavbarDropdownTrigger_3.opened"
                [kbqDropdownTriggerFor]="verticalNavbarDropdown_3"
            >
                <i kbq-icon="kbq-ellipsis-vertical_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().more }}</kbq-navbar-title>
            </kbq-navbar-item>
        </kbq-navbar-container>

        <kbq-navbar-container>
            <kbq-navbar-item>
                <i kbq-icon="kbq-user_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().profile }}</kbq-navbar-title>
            </kbq-navbar-item>
        </kbq-navbar-container>

        <button kbq-navbar-toggle></button>
    </kbq-vertical-navbar>

    <div style="overflow: auto; padding-left: 20px; padding-right: 20px" class="flex kbq-text-normal">
        <div>
            @for (paragraph of text().pageText; track $index) {
                <p>{{ paragraph }}</p>
            }
        </div>
    </div>
</div>
```

### Unfolded menu that overlays content

You can also make the vertical menu overlay page content.

**Example: Navbar vertical open over** (`navbar-vertical-open-over`)

```ts navbar-vertical-open-over-example.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqButtonModule } from '@koobiq/components/button';
import { PopUpPlacements } from '@koobiq/components/core';
import { KbqDropdownModule } from '@koobiq/components/dropdown';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqNavbarModule } from '@koobiq/components/navbar';
import { KbqToolTipModule } from '@koobiq/components/tooltip';
import { injectExampleText } from '../localized-data';

@Component({
    selector: 'navbar-vertical-open-over-example',
    imports: [
        KbqDropdownModule,
        KbqNavbarModule,
        KbqButtonModule,
        KbqToolTipModule,
        KbqIconModule
    ],
    templateUrl: 'navbar-vertical-open-over-example.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavbarVerticalOpenOverExample {
    protected readonly text = injectExampleText();

    popUpPlacements = PopUpPlacements;
}
```

```html navbar-vertical-open-over-example.html
<kbq-dropdown #verticalNavbarDropdown_1="kbqDropdown" [overlapTriggerX]="false" [overlapTriggerY]="true">
    @for (app of text().apps; track $index) {
        <button kbq-dropdown-item>{{ app }}</button>
    }
</kbq-dropdown>

<kbq-dropdown #verticalNavbarDropdown_3="kbqDropdown" [overlapTriggerX]="false" [overlapTriggerY]="true">
    <button kbq-dropdown-item>{{ text().point(1) }}</button>
    <button kbq-dropdown-item>{{ text().point(2) }}</button>
</kbq-dropdown>

<div style="height: 480px" class="layout-row">
    <kbq-vertical-navbar #verticalNavbar [openOver]="true">
        <kbq-navbar-container>
            <div
                #verticalNavbarDropdownTrigger_1="kbqDropdownTrigger"
                bento
                kbq-navbar-item
                [class.kbq-active]="verticalNavbarDropdownTrigger_1.opened"
                [kbqDropdownTriggerFor]="verticalNavbarDropdown_1"
            >
                <i kbq-icon="kbq-bento-menu_16" color="contrast"></i>
                <div kbq-navbar-title>{{ text().allApps }}</div>
            </div>

            <a href="#" kbq-navbar-brand>
                <div kbq-navbar-logo>
                    <!-- prettier-ignore -->
                    <svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M0 25.6C0 28.4045 0 29.9635 1.01826 30.9817C2.03651 32 3.59554 32 6.4 32H25.6C28.4045 32 29.9635 32 30.9817 30.9817C32 29.9635 32 28.4045 32 25.6V6.4C32 3.59554 32 2.03651 30.9817 1.01826C29.9635 0 28.4045 0 25.6 0H6.4C3.59554 0 2.03651 0 1.01826 1.01826C0 2.03651 0 3.59554 0 6.4V25.6Z" fill="#FF0000" fill-rule="evenodd"/><path d="M14.9774 16L11.1933 19.7841L7.40918 16L11.1933 12.267L14.9774 16ZM19.7842 20.858L16.0512 24.5909L12.2671 20.858L16.0512 17.0739L19.7842 20.858ZM19.7842 11.1932L16.0512 14.9261L12.2671 11.1932L16.0512 7.40909L19.7842 11.1932ZM24.591 16L20.858 19.7841L17.1251 16L20.858 12.267L24.591 16Z" fill="white"/></svg>
                </div>

                <div kbq-navbar-title>{{ text().appName }}</div>
            </a>

            <a href="#" kbq-navbar-item class="kbq-active">
                <i kbq-icon="kbq-stop_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().dashboards }}</kbq-navbar-title>
            </a>

            <button kbq-navbar-item>
                <i kbq-icon="kbq-stop_16" color="contrast"></i>
                <span kbq-navbar-title>{{ text().tasks }}</span>
            </button>

            <kbq-navbar-item>
                <button
                    kbq-button
                    [class.kbq-button-icon]="!verticalNavbar.expanded()"
                    [color]="'contrast'"
                    [kbqPlacement]="popUpPlacements.Right"
                    [kbqStyle]="'filled'"
                    [attr.aria-label]="text().newTask"
                    [kbqTooltip]="text().newTask"
                    [kbqTooltipDisabled]="verticalNavbar.expanded()"
                >
                    <i kbq-icon="kbq-plus_16" [color]="'empty'"></i>
                    @if (verticalNavbar.expanded()) {
                        <span>{{ text().newTask }}</span>
                    }
                </button>
            </kbq-navbar-item>

            <kbq-navbar-item
                #verticalNavbarDropdownTrigger_3="kbqDropdownTrigger"
                [class.kbq-active]="verticalNavbarDropdownTrigger_3.opened"
                [kbqDropdownTriggerFor]="verticalNavbarDropdown_3"
            >
                <i kbq-icon="kbq-ellipsis-vertical_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().more }}</kbq-navbar-title>
            </kbq-navbar-item>
        </kbq-navbar-container>

        <kbq-navbar-container>
            <kbq-navbar-item>
                <i kbq-icon="kbq-user_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().profile }}</kbq-navbar-title>
            </kbq-navbar-item>
        </kbq-navbar-container>

        <button kbq-navbar-toggle></button>
    </kbq-vertical-navbar>

    <div style="overflow: auto; padding-left: 20px; padding-right: 20px" class="kbq-text-normal">
        <div>
            @for (paragraph of text().pageText; track $index) {
                <p>{{ paragraph }}</p>
            }
        </div>
    </div>
</div>
```

### Long application name

When the name does not fit on one line, the header switches to a small two-line title on its own — there is nothing to configure. A name that fits keeps the default style, and one too long even for two lines is truncated and shown in full in a tooltip.

**Example: Navbar vertical app long name** (`navbar-vertical-app-long-name`)

```ts navbar-vertical-app-long-name-example.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqButtonModule } from '@koobiq/components/button';
import { KbqComponentColors, PopUpPlacements } from '@koobiq/components/core';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqNavbarModule } from '@koobiq/components/navbar';
import { KbqToolTipModule } from '@koobiq/components/tooltip';
import { injectExampleText } from '../localized-data';

@Component({
    selector: 'navbar-vertical-app-long-name-example',
    imports: [
        KbqNavbarModule,
        KbqButtonModule,
        KbqToolTipModule,
        KbqIconModule
    ],
    templateUrl: 'navbar-vertical-app-long-name-example.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavbarVerticalAppLongNameExample {
    protected readonly text = injectExampleText();

    readonly popUpPlacements = PopUpPlacements;
    readonly colors = KbqComponentColors;
}
```

```html navbar-vertical-app-long-name-example.html
<div style="height: 480px" class="layout-row">
    <kbq-vertical-navbar #verticalNavbar>
        <kbq-navbar-container>
            <a href="#" kbq-navbar-brand [collapsedText]="text().longAppName">
                <div kbq-navbar-logo>
                    <!-- prettier-ignore -->
                    <svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M0 25.6C0 28.4045 0 29.9635 1.01826 30.9817C2.03651 32 3.59554 32 6.4 32H25.6C28.4045 32 29.9635 32 30.9817 30.9817C32 29.9635 32 28.4045 32 25.6V6.4C32 3.59554 32 2.03651 30.9817 1.01826C29.9635 0 28.4045 0 25.6 0H6.4C3.59554 0 2.03651 0 1.01826 1.01826C0 2.03651 0 3.59554 0 6.4V25.6Z" fill="#FF0000" fill-rule="evenodd"/><path d="M14.9774 16L11.1933 19.7841L7.40918 16L11.1933 12.267L14.9774 16ZM19.7842 20.858L16.0512 24.5909L12.2671 20.858L16.0512 17.0739L19.7842 20.858ZM19.7842 11.1932L16.0512 14.9261L12.2671 11.1932L16.0512 7.40909L19.7842 11.1932ZM24.591 16L20.858 19.7841L17.1251 16L20.858 12.267L24.591 16Z" fill="white"/></svg>
                </div>

                <div kbq-navbar-title>{{ text().longAppName }}</div>
            </a>

            <a href="#" kbq-navbar-item class="kbq-active">
                <i kbq-icon="kbq-stop_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().dashboards }}</kbq-navbar-title>
            </a>

            <button kbq-navbar-item>
                <i kbq-icon="kbq-stop_16" color="contrast"></i>
                <span kbq-navbar-title>{{ text().tasks }}</span>
            </button>

            <kbq-navbar-item>
                <button
                    kbq-button
                    [class.kbq-button-icon]="!verticalNavbar.expanded()"
                    [color]="colors.Contrast"
                    [kbqPlacement]="popUpPlacements.Right"
                    [kbqStyle]="'filled'"
                    [attr.aria-label]="text().newTask"
                    [kbqTooltip]="text().newTask"
                    [kbqTooltipDisabled]="verticalNavbar.expanded()"
                >
                    <i kbq-icon="kbq-plus_16" [color]="'empty'"></i>
                    @if (verticalNavbar.expanded()) {
                        <span>{{ text().newTask }}</span>
                    }
                </button>
            </kbq-navbar-item>
        </kbq-navbar-container>

        <kbq-navbar-container>
            <kbq-navbar-item>
                <i kbq-icon="kbq-user_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().profile }}</kbq-navbar-title>
            </kbq-navbar-item>
        </kbq-navbar-container>

        <button kbq-navbar-toggle></button>
    </kbq-vertical-navbar>

    <div style="overflow: auto; padding-left: 20px; padding-right: 20px" class="flex kbq-text-normal"></div>
</div>
```

The same is available in the horizontal menu.

**Example: Navbar app long name** (`navbar-app-long-name`)

```ts navbar-app-long-name-example.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqBadgeModule } from '@koobiq/components/badge';
import { KbqButtonModule } from '@koobiq/components/button';
import { PopUpPlacements } from '@koobiq/components/core';
import { KbqDividerModule } from '@koobiq/components/divider';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqNavbarModule } from '@koobiq/components/navbar';
import { injectExampleText } from '../localized-data';

@Component({
    selector: 'navbar-app-long-name-example',
    imports: [
        KbqDividerModule,
        KbqNavbarModule,
        KbqButtonModule,
        KbqBadgeModule,
        KbqIconModule
    ],
    templateUrl: 'navbar-app-long-name-example.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavbarAppLongNameExample {
    protected readonly text = injectExampleText();

    popUpPlacements = PopUpPlacements;
}
```

```html navbar-app-long-name-example.html
<kbq-navbar>
    <kbq-navbar-container>
        <a href="#" kbq-navbar-brand>
            <kbq-navbar-logo>
                <!-- prettier-ignore -->
                <svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M0 25.6C0 28.4045 0 29.9635 1.01826 30.9817C2.03651 32 3.59554 32 6.4 32H25.6C28.4045 32 29.9635 32 30.9817 30.9817C32 29.9635 32 28.4045 32 25.6V6.4C32 3.59554 32 2.03651 30.9817 1.01826C29.9635 0 28.4045 0 25.6 0H6.4C3.59554 0 2.03651 0 1.01826 1.01826C0 2.03651 0 3.59554 0 6.4V25.6Z" fill="#FF0000" fill-rule="evenodd"/><path d="M14.9774 16L11.1933 19.7841L7.40918 16L11.1933 12.267L14.9774 16ZM19.7842 20.858L16.0512 24.5909L12.2671 20.858L16.0512 17.0739L19.7842 20.858ZM19.7842 11.1932L16.0512 14.9261L12.2671 11.1932L16.0512 7.40909L19.7842 11.1932ZM24.591 16L20.858 19.7841L17.1251 16L20.858 12.267L24.591 16Z" fill="white"/></svg>
            </kbq-navbar-logo>
            <kbq-navbar-title>{{ text().longAppName }}</kbq-navbar-title>
        </a>

        <button
            kbq-navbar-item
            class="kbq-active"
            [kbqPlacement]="popUpPlacements.Bottom"
            [tooltipText]="text().dashboards"
        >
            <i kbq-icon="kbq-dashboard_16" color="contrast"></i>
        </button>

        <kbq-navbar-item>
            <kbq-navbar-title>{{ text().projects }}</kbq-navbar-title>
        </kbq-navbar-item>

        <kbq-navbar-item>
            <button kbq-button [color]="'contrast'">
                <span>{{ text().newTask }}</span>
            </button>
        </kbq-navbar-item>
    </kbq-navbar-container>

    <kbq-navbar-container>
        <kbq-navbar-item [kbqPlacement]="popUpPlacements.Bottom" [tooltipText]="text().notifications">
            <i kbq-icon="kbq-bell_16" color="contrast"></i>
            <kbq-badge [badgeColor]="'error'" [compact]="true">5</kbq-badge>
        </kbq-navbar-item>

        <kbq-navbar-item [kbqPlacement]="popUpPlacements.Bottom" [tooltipText]="text().administration">
            <i kbq-icon="kbq-gear_16" color="contrast"></i>
        </kbq-navbar-item>

        <kbq-navbar-divider />

        <kbq-navbar-item [kbqPlacement]="popUpPlacements.Bottom" [tooltipText]="text().help">
            <i kbq-icon="kbq-magnifying-glass_16" color="contrast"></i>
        </kbq-navbar-item>
    </kbq-navbar-container>
</kbq-navbar>
```

### Layering

The horizontal menu sits at `z-index: 990` (`--kbq-navbar-z-index`), so panels opened from the page content paint above it. To have them slide under it, see [Panels under a sticky header](https://koobiq.io/en/components/core.md#panels-under-a-sticky-header).

## API

### Components

#### KbqNavbar (component)

```ts
@Component({ selector: 'kbq-navbar' })
class KbqNavbar extends KbqFocusableComponent {
    readonly ariaLabel = input<string | null>(null, {
        alias: 'aria-label'
    });
}
```

- `[aria-label]`: `string | null` — Accessible name of the navigation landmark. Set it whenever a page renders more than one navbar, so
  assistive technology can tell them apart.

#### KbqNavbarBrand (component)

```ts
@Component({
    selector: 'kbq-navbar-brand, [kbq-navbar-brand]',
    exportAs: 'kbqNavbarBrand'
})
class KbqNavbarBrand {
    readonly collapsedText = input<string>('');
    readonly tooltipDisabled = input<boolean | undefined>(undefined, {
        alias: 'kbqTooltipDisabled'
    });
    readonly ariaLabel = input<string | null>(null, {
        alias: 'aria-label'
    });
    get isLink(): boolean;
}
```

- `[collapsedText]`: `string` — text that will be displayed in the tooltip. By default, the text is taken from kbq-navbar-title.
- `[kbqTooltipDisabled]`: `boolean | undefined` — Explicitly enables or disables the brand's tooltip.

  Left unset, the tooltip is enabled exactly when the title cannot be read from the brand itself — the
  navbar is collapsed, the title is clipped, or there is no title at all.
- `[aria-label]`: `string | null` — Accessible name of the brand. Needed when the brand renders nothing but a logo.
- `isLink`: `boolean` — Whether the brand is rendered as a native link.

#### KbqNavbarItem (component)

```ts
@Component({
    selector: 'kbq-navbar-item, [kbq-navbar-item]',
    exportAs: 'kbqNavbarItem'
})
class KbqNavbarItem {
    readonly collapsedText = input<string>('');
    readonly collapsable = input<boolean>(true);
    readonly tooltipDisabled = input<boolean | undefined>(undefined, {
        alias: 'kbqTooltipDisabled'
    });
    readonly ariaLabel = input<string | null>(null, {
        alias: 'aria-label'
    });
    set collapsed(value: boolean);
    readonly isCollapsed: Signal<boolean>;
    get titleText(): string | null;
}
```

- `[collapsedText]`: `string` — Text shown in the tooltip of a collapsed item. Defaults to the text of the projected `kbq-navbar-title`.
- `[collapsable]`: `boolean` — Whether the item may be collapsed when the horizontal navbar runs out of room.
- `[kbqTooltipDisabled]`: `boolean | undefined` — Explicitly enables or disables the item's tooltip.

  Left unset, the tooltip is enabled exactly when the title cannot be read from the item itself — the item
  is collapsed, its title is clipped, or it has no title at all.
- `[aria-label]`: `string | null` — Accessible name of the item. Needed for an icon-only item, which has no visible label of its own; an
  item that renders a title is named by it.
- `collapsed`: `boolean` — Collapses the item regardless of what the ambient navbar decided.
- `isCollapsed`: `Signal<boolean>` — Whether the item is rendered in its collapsed (icon-only) form.
- `titleText`: `string | null` — Text used for the tooltip and for the accessible name of a collapsed item.

#### KbqNavbarToggle (component)

```ts
@Component({ selector: 'kbq-navbar-toggle, [kbq-navbar-toggle]' })
class KbqNavbarToggle {
    toggle(): void;
}
```

- `toggle()`: `void` — toggles the state of the navbar

#### KbqVerticalNavbar (component)

```ts
@Component({ selector: 'kbq-vertical-navbar', exportAs: 'KbqVerticalNavbar' })
class KbqVerticalNavbar extends KbqFocusableComponent {
    readonly openOver = input<boolean>(false);
    readonly expanded = model<boolean>(false);
    readonly ariaLabel = input<string | null>(null, {
        alias: 'aria-label'
    });
    readonly localeConfiguration: Signal<KbqNavbarLocaleConfiguration>;
    toggle(): void;
}
```

- `[openOver]`: `boolean` — Whether the expanded navbar overlays the page content instead of taking room from it.
- `[(expanded)]`: `boolean` — Whether the navbar is expanded.
- `[localeOverrides]`: `KbqPartialLocaleData | undefined` — Localized strings for this element and its subtree, keyed by locale section. Every key is optional at
  every depth.
- `[aria-label]`: `string | null` — Accessible name of the navigation landmark. Set it whenever a page renders more than one navbar, so
  assistive technology can tell them apart.
- `localeConfiguration`: `Signal<KbqNavbarLocaleConfiguration>` — Localized strings of the navbar.

  A signal, so that a locale change reaches the `OnPush` descendants that render these strings — a plain
  field would leave them showing the previous locale until something else marked them dirty. It also keeps
  the value observable from outside: `KbqNavbarToggle` reads it in an `effect` to refresh its tooltip,
  which a `markForCheck()` here could never have reached in that separate `OnPush` view.
- `toggle()`: `void` — Expands a collapsed navbar and collapses an expanded one.

### Directives

#### KbqFocusableComponent (directive)

```ts
@Directive()
class KbqFocusableComponent {
    readonly ariaLabel = input<string | null>(null, {
        alias: 'aria-label'
    });
}
```

- `[aria-label]`: `string | null` — Accessible name of the navigation landmark. Set it whenever a page renders more than one navbar, so
  assistive technology can tell them apart.

#### KbqNavbarBento (directive)

```ts
@Directive({ selector: 'kbq-navbar-item[bento], [kbq-navbar-item][bento]' })
class KbqNavbarBento {}
```

#### KbqNavbarContainer (directive)

```ts
@Directive({ selector: 'kbq-navbar-container' })
class KbqNavbarContainer {}
```

#### KbqNavbarDivider (directive)

```ts
@Directive({ selector: 'kbq-navbar-divider' })
class KbqNavbarDivider {}
```

#### KbqNavbarFocusableItem (directive)

```ts
@Directive({
    selector: 'kbq-navbar-item, [kbq-navbar-item], kbq-navbar-brand, [kbq-navbar-brand], kbq-navbar-toggle'
})
class KbqNavbarFocusableItem implements IFocusableOption {
    disabled = input<boolean | undefined>();
    get nestedElement(): KbqButton | KbqFormField | undefined;
    set hasFocus(value: boolean);
}
```

- `[disabled]`: `boolean | undefined` — Whether the item is disabled. Also `true` for a decorative element, which the key manager skips as well.
- `nestedElement`: `KbqButton | KbqFormField | undefined` — Interactive element projected into the item, if any.

#### KbqNavbarItemSuffix (directive)

Marks content to be projected after the title of a navbar item.

```ts
@Directive({ selector: '[kbqNavbarItemSuffix]' })
class KbqNavbarItemSuffix {}
```

#### KbqNavbarLogo (directive)

```ts
@Directive({ selector: 'kbq-navbar-logo, [kbq-navbar-logo]' })
class KbqNavbarLogo {}
```

#### KbqNavbarRectangleElement (directive)

```ts
@Directive({
    selector: 'kbq-navbar-item, [kbq-navbar-item], kbq-navbar-divider, kbq-navbar-brand, [kbq-navbar-brand]'
})
class KbqNavbarRectangleElement {
    orientation: KbqNavbarOrientation;
    set collapsed(value: boolean);
    getOuterElementWidth(): number;
}
```

- `orientation`: `KbqNavbarOrientation` — Orientation of the navbar this element belongs to. Written by the ambient `KbqNavbar` /
  `KbqVerticalNavbar`; the element itself only reads it.
- `getOuterElementWidth()`: `number` — Outer width of the element: its border box plus horizontal margins.

#### KbqNavbarTitle (directive)

```ts
@Directive({ selector: 'kbq-navbar-title, [kbq-navbar-title]' })
class KbqNavbarTitle {
    get text(): string;
    get isOverflown(): boolean;
    get isClamped(): boolean;
    getOuterElementWidth(): number;
}
```

- `text`: `string` — Text content of the title element.
- `isOverflown`: `boolean` — Whether the text is clipped horizontally (e.g. by `text-overflow: ellipsis`).
- `isClamped`: `boolean` — Whether the text is clipped vertically (e.g. by `-webkit-line-clamp`).

  Kept separate from `isOverflown` on purpose: wrapped text never exceeds its width, so only this
  check catches a clamped title. `isOverflown` is also read by `KbqNavbarItem`, whose titles are
  always `nowrap` — folding the two together would let sub-pixel line-height rounding enable
  tooltips on every navbar item.
- `getOuterElementWidth()`: `number` — Outer width of the title: its border box plus horizontal margins.

### Types

#### KbqNavbarOrientation (type)

Orientation of the navbar an element belongs to.

```ts
type KbqNavbarOrientation = 'horizontal' | 'vertical';
```

### Constants

#### KBQ_VERTICAL_NAVBAR_CONFIGURATION (const)

Deprecated: Use `KBQ_NAVBAR_LOCALE_CONFIGURATION`. Will be removed in 22.0.0.

```ts
const KBQ_VERTICAL_NAVBAR_CONFIGURATION: InjectionToken<KbqNavbarLocaleConfiguration>;
```

#### KBQ_VERTICAL_NAVBAR_DEFAULT_CONFIGURATION (const)

Deprecated: Use `KBQ_NAVBAR_DEFAULT_LOCALE_CONFIGURATION`. Will be removed in 22.0.0.

```ts
const KBQ_VERTICAL_NAVBAR_DEFAULT_CONFIGURATION: KbqNavbarLocaleConfiguration;
```

#### kbqNavbarLocaleConfigurationProvider (const)

Utility provider for `KBQ_NAVBAR_LOCALE_CONFIGURATION`. Only the strings you pass are overridden; the
rest keep following the active locale.

```ts
const kbqNavbarLocaleConfigurationProvider: (
    configuration: KbqDeepPartial<KbqNavbarLocaleConfiguration>
) => Provider;
```

## Examples

### Adding items from a template

You can declare `kbq-navbar-item` elements inside an `<ng-template>` and insert them with `*ngTemplateOutlet` — for example, to render the items from a data array. Declare the template inside `<kbq-navbar>` so the navbar keeps managing keyboard navigation, layout, and responsive collapsing of the items.

**Example: Navbar items from a template** (`navbar-template-outlet`)

```ts navbar-template-outlet-example.ts
import { NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, signal } from '@angular/core';
import { KbqButtonModule } from '@koobiq/components/button';
import { KbqComponentColors, PopUpPlacements } from '@koobiq/components/core';
import { KbqDropdownModule } from '@koobiq/components/dropdown';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqNavbarModule } from '@koobiq/components/navbar';
import { KbqToolTipModule } from '@koobiq/components/tooltip';
import { injectExampleText } from '../localized-data';

type NavbarLink = {
    icon: string;
    label: string;
    active?: boolean;
};

@Component({
    selector: 'navbar-template-outlet-example',
    imports: [
        KbqDropdownModule,
        KbqNavbarModule,
        KbqButtonModule,
        KbqToolTipModule,
        KbqIconModule,
        NgTemplateOutlet
    ],
    templateUrl: 'navbar-template-outlet-example.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavbarTemplateOutletExample {
    protected readonly text = injectExampleText();

    readonly popUpPlacements = PopUpPlacements;
    readonly colors = KbqComponentColors;
    /** Position of the selected app in `text().apps`, so the selection survives a locale switch. */
    readonly selectedApp = signal(0);

    /** Uniform navbar links rendered from a single reusable template. */
    readonly items = computed<readonly NavbarLink[]>(() => [
        { icon: 'kbq-stop_16', label: this.text().dashboards, active: true },
        { icon: 'kbq-stop_16', label: this.text().tasks }
    ]);

    /** Bottom navbar link rendered from the same reusable template. */
    readonly profile = computed<NavbarLink>(() => ({ icon: 'kbq-user_16', label: this.text().profile }));
}
```

```html navbar-template-outlet-example.html
<kbq-dropdown #verticalNavbarDropdown_1="kbqDropdown" [overlapTriggerX]="false" [overlapTriggerY]="true">
    @for (app of text().apps; track $index) {
        <button kbq-dropdown-item (click)="selectedApp.set($index)">{{ app }}</button>
    }
</kbq-dropdown>

<kbq-dropdown #verticalNavbarDropdown_3="kbqDropdown" [overlapTriggerX]="false" [overlapTriggerY]="true">
    <button kbq-dropdown-item>{{ text().point(1) }}</button>
    <button kbq-dropdown-item>{{ text().point(2) }}</button>
</kbq-dropdown>

<div style="height: 480px" class="layout-row">
    <kbq-vertical-navbar #verticalNavbar>
        <!--
            Declare every <ng-template> right where its item appears. The navbar derives its
            keyboard-focus order from its contentChildren(KbqNavbarFocusableItem) query, which lists
            matches in TEMPLATE DECLARATION order — NOT in *ngTemplateOutlet insertion order. Keeping
            each template next to its outlet, and NOT sharing one template across the two containers,
            keeps focus order aligned with visual order. Templates must also stay INSIDE the navbar so
            its content queries keep managing the items (keyboard navigation, layout, collapsing).
        -->
        <kbq-navbar-container>
            <ng-template #bentoTrigger>
                <div
                    #bentoDropdownTrigger="kbqDropdownTrigger"
                    bento
                    kbq-navbar-item
                    [class.kbq-active]="bentoDropdownTrigger.opened"
                    [kbqDropdownTriggerFor]="verticalNavbarDropdown_1"
                >
                    <i kbq-icon="kbq-bento-menu_16" color="contrast"></i>
                    <div kbq-navbar-title>{{ text().allApps }}</div>
                </div>
            </ng-template>
            <ng-container *ngTemplateOutlet="bentoTrigger" />

            <a href="#" kbq-navbar-brand [collapsedText]="text().apps[selectedApp()]">
                <div kbq-navbar-logo>
                    <!-- prettier-ignore -->
                    <svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M0 25.6C0 28.4045 0 29.9635 1.01826 30.9817C2.03651 32 3.59554 32 6.4 32H25.6C28.4045 32 29.9635 32 30.9817 30.9817C32 29.9635 32 28.4045 32 25.6V6.4C32 3.59554 32 2.03651 30.9817 1.01826C29.9635 0 28.4045 0 25.6 0H6.4C3.59554 0 2.03651 0 1.01826 1.01826C0 2.03651 0 3.59554 0 6.4V25.6Z" fill="#FF0000" fill-rule="evenodd"/><path d="M14.9774 16L11.1933 19.7841L7.40918 16L11.1933 12.267L14.9774 16ZM19.7842 20.858L16.0512 24.5909L12.2671 20.858L16.0512 17.0739L19.7842 20.858ZM19.7842 11.1932L16.0512 14.9261L12.2671 11.1932L16.0512 7.40909L19.7842 11.1932ZM24.591 16L20.858 19.7841L17.1251 16L20.858 12.267L24.591 16Z" fill="white"/></svg>
                </div>

                <div kbq-navbar-title>{{ text().apps[selectedApp()] }}</div>
            </a>

            <ng-template #navbarItem let-item>
                <kbq-navbar-item [class.kbq-active]="item.active">
                    <i color="contrast" [kbq-icon]="item.icon"></i>
                    <kbq-navbar-title>{{ item.label }}</kbq-navbar-title>
                </kbq-navbar-item>
            </ng-template>
            @for (item of items(); track $index) {
                <ng-container *ngTemplateOutlet="navbarItem; context: { $implicit: item }" />
            }

            <ng-template #actionButton>
                <kbq-navbar-item>
                    <button
                        kbq-button
                        [class.kbq-button-icon]="!verticalNavbar.expanded()"
                        [color]="colors.Contrast"
                        [kbqPlacement]="popUpPlacements.Right"
                        [kbqStyle]="'filled'"
                        [attr.aria-label]="text().newTask"
                        [kbqTooltip]="text().newTask"
                        [kbqTooltipDisabled]="verticalNavbar.expanded()"
                    >
                        <i kbq-icon="kbq-plus_16" [color]="'empty'"></i>
                        @if (verticalNavbar.expanded()) {
                            <span>{{ text().newTask }}</span>
                        }
                    </button>
                </kbq-navbar-item>
            </ng-template>
            <ng-container *ngTemplateOutlet="actionButton" />

            <ng-template #moreTrigger>
                <kbq-navbar-item
                    #moreDropdownTrigger="kbqDropdownTrigger"
                    [class.kbq-active]="moreDropdownTrigger.opened"
                    [kbqDropdownTriggerFor]="verticalNavbarDropdown_3"
                >
                    <i kbq-icon="kbq-ellipsis-vertical_16" color="contrast"></i>
                    <kbq-navbar-title>{{ text().more }}</kbq-navbar-title>
                </kbq-navbar-item>
            </ng-template>
            <ng-container *ngTemplateOutlet="moreTrigger" />
        </kbq-navbar-container>

        <kbq-navbar-container>
            <!--
                Single bottom item, rendered inline: it lives in a different container from the list
                above, so it must not reuse that container's template (a shared <ng-template> would
                fold this item into the group above in the focus order).
            -->
            <kbq-navbar-item>
                <i color="contrast" [kbq-icon]="profile().icon"></i>
                <kbq-navbar-title>{{ profile().label }}</kbq-navbar-title>
            </kbq-navbar-item>
        </kbq-navbar-container>

        <button kbq-navbar-toggle></button>
    </kbq-vertical-navbar>

    <div style="overflow: auto; padding-left: 20px; padding-right: 20px" class="flex kbq-text-normal">
        <div>
            @for (paragraph of text().pageText; track $index) {
                <p>{{ paragraph }}</p>
            }
        </div>
    </div>
</div>
```

### Icon after the title

To show an icon after the item title — for example, on a link to an external resource — add `kbqNavbarItemSuffix` to it. An icon without this attribute is shown before the title, wherever it is written.

**Example: Navbar item with an icon after the title** (`navbar-item-suffix`)

```ts navbar-item-suffix-example.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqNavbarModule } from '@koobiq/components/navbar';
import { injectExampleText } from '../localized-data';

@Component({
    selector: 'navbar-item-suffix-example',
    imports: [KbqNavbarModule, KbqIconModule],
    templateUrl: 'navbar-item-suffix-example.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavbarItemSuffixExample {
    protected readonly text = injectExampleText();
}
```

```html navbar-item-suffix-example.html
<kbq-navbar>
    <kbq-navbar-container>
        <a href="#" kbq-navbar-brand>
            <kbq-navbar-logo>
                <!-- prettier-ignore -->
                <svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M0 25.6C0 28.4045 0 29.9635 1.01826 30.9817C2.03651 32 3.59554 32 6.4 32H25.6C28.4045 32 29.9635 32 30.9817 30.9817C32 29.9635 32 28.4045 32 25.6V6.4C32 3.59554 32 2.03651 30.9817 1.01826C29.9635 0 28.4045 0 25.6 0H6.4C3.59554 0 2.03651 0 1.01826 1.01826C0 2.03651 0 3.59554 0 6.4V25.6Z" fill="#FF0000" fill-rule="evenodd"/><path d="M14.9774 16L11.1933 19.7841L7.40918 16L11.1933 12.267L14.9774 16ZM19.7842 20.858L16.0512 24.5909L12.2671 20.858L16.0512 17.0739L19.7842 20.858ZM19.7842 11.1932L16.0512 14.9261L12.2671 11.1932L16.0512 7.40909L19.7842 11.1932ZM24.591 16L20.858 19.7841L17.1251 16L20.858 12.267L24.591 16Z" fill="white"/></svg>
            </kbq-navbar-logo>
            <kbq-navbar-title>{{ text().appName }}</kbq-navbar-title>
        </a>

        <kbq-navbar-item class="kbq-active">
            <kbq-navbar-title>{{ text().projects }}</kbq-navbar-title>
        </kbq-navbar-item>

        <a href="#" kbq-navbar-item>
            <kbq-navbar-title>{{ text().documentation }}</kbq-navbar-title>
            <i kbq-icon="kbq-arrow-up-right-from-square_16" color="contrast" kbqNavbarItemSuffix></i>
        </a>
    </kbq-navbar-container>
</kbq-navbar>
```

In the vertical menu the icon is pinned to the right edge of the item.

**Example: Navbar vertical item with an icon after the title** (`navbar-vertical-item-suffix`)

```ts navbar-vertical-item-suffix-example.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqNavbarModule } from '@koobiq/components/navbar';
import { injectExampleText } from '../localized-data';

@Component({
    selector: 'navbar-vertical-item-suffix-example',
    imports: [KbqNavbarModule, KbqIconModule],
    templateUrl: 'navbar-vertical-item-suffix-example.html',
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavbarVerticalItemSuffixExample {
    protected readonly text = injectExampleText();
}
```

```html navbar-vertical-item-suffix-example.html
<div style="height: 480px" class="layout-row">
    <kbq-vertical-navbar [expanded]="true">
        <kbq-navbar-container>
            <a href="#" kbq-navbar-item class="kbq-active">
                <i kbq-icon="kbq-stop_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().dashboards }}</kbq-navbar-title>
            </a>

            <a href="#" kbq-navbar-item>
                <i kbq-icon="kbq-book-open_16" color="contrast"></i>
                <kbq-navbar-title>{{ text().documentation }}</kbq-navbar-title>
                <i kbq-icon="kbq-arrow-up-right-from-square_16" color="contrast" kbqNavbarItemSuffix></i>
            </a>
        </kbq-navbar-container>

        <button kbq-navbar-toggle></button>
    </kbq-vertical-navbar>
</div>
```
