diff --git a/apps/docs/src/app/components/icons-viewer/icons-viewer.template.html b/apps/docs/src/app/components/icons-viewer/icons-viewer.template.html
index d94236b34c..89a28a89e7 100644
--- a/apps/docs/src/app/components/icons-viewer/icons-viewer.template.html
+++ b/apps/docs/src/app/components/icons-viewer/icons-viewer.template.html
@@ -30,7 +30,7 @@
diff --git a/packages/components-dev/form-field/template.html b/packages/components-dev/form-field/template.html
index ed1c705ca9..c8603a9618 100644
--- a/packages/components-dev/form-field/template.html
+++ b/packages/components-dev/form-field/template.html
@@ -82,7 +82,9 @@
kbqTreeNodeToggle
[style.transform]="treeControl.isExpanded(node) ? '' : 'rotate(-90deg)'"
>
-
+
@@ -109,7 +111,9 @@
kbqTreeNodeToggle
[style.transform]="treeControl.isExpanded(node) ? '' : 'rotate(-90deg)'"
>
-
+
@@ -136,7 +140,9 @@
kbqTreeNodeToggle
[style.transform]="treeControl.isExpanded(node) ? '' : 'rotate(-90deg)'"
>
-
+
@@ -163,7 +169,9 @@
kbqTreeNodeToggle
[style.transform]="treeControl.isExpanded(node) ? '' : 'rotate(-90deg)'"
>
-
+
diff --git a/packages/components-dev/select/template.html b/packages/components-dev/select/template.html
index 9f0f2415b5..a8d379d21c 100644
--- a/packages/components-dev/select/template.html
+++ b/packages/components-dev/select/template.html
@@ -15,7 +15,7 @@
-
+
@@ -59,7 +59,7 @@
-
+
@@ -72,7 +72,7 @@
-
+
@@ -140,7 +140,7 @@
-
+
@@ -166,7 +166,7 @@
-
+
diff --git a/packages/components-dev/tree-select/template.html b/packages/components-dev/tree-select/template.html
index 0a8a43b7b2..b37aa12a1e 100644
--- a/packages/components-dev/tree-select/template.html
+++ b/packages/components-dev/tree-select/template.html
@@ -28,7 +28,9 @@
Custom footer
@@ -39,7 +41,9 @@ Custom footer
>
@@ -79,7 +83,9 @@ Default footer
@@ -94,7 +100,9 @@ Default footer
[style.transform]="treeControl.isExpanded(node) ? '' : 'rotate(-90deg)'"
>
@@ -128,7 +136,9 @@ Default footer
@@ -143,7 +153,9 @@ Default footer
[style.transform]="treeControl.isExpanded(node) ? '' : 'rotate(-90deg)'"
>
@@ -177,7 +189,9 @@ Default footer
@@ -192,7 +206,9 @@ Default footer
[style.transform]="treeControl.isExpanded(node) ? '' : 'rotate(-90deg)'"
>
@@ -230,7 +246,9 @@ Default footer with icon button
@@ -245,7 +263,9 @@ Default footer with icon button
[style.transform]="treeControl.isExpanded(node) ? '' : 'rotate(-90deg)'"
>
@@ -294,7 +314,8 @@ Default footer with icon button
@@ -311,7 +332,8 @@ Default footer with icon button
>
diff --git a/packages/components-dev/tree/template.html b/packages/components-dev/tree/template.html
index 99ec7a86c6..2e83a48c6f 100644
--- a/packages/components-dev/tree/template.html
+++ b/packages/components-dev/tree/template.html
@@ -58,7 +58,9 @@
>
-
+
-
+
@@ -106,7 +110,9 @@
-
+
+
}
} @empty {
{{ localeData.searchEmptyResult }}
diff --git a/packages/components/app-switcher/app-switcher.spec.ts b/packages/components/app-switcher/app-switcher.spec.ts
index b59b38fb08..d2591d8e8d 100644
--- a/packages/components/app-switcher/app-switcher.spec.ts
+++ b/packages/components/app-switcher/app-switcher.spec.ts
@@ -732,6 +732,34 @@ describe('KbqAppSwitcher', () => {
expect(searchResult).toBeTruthy();
}));
+
+ it('highlights only the matched fragment of the app name in search results', fakeAsync(() => {
+ trigger.show();
+ tick();
+ fixture.detectChanges();
+
+ const popup = trigger['instance'] as KbqAppSwitcherComponent;
+
+ popup.searchControl.setValue('pp 1');
+ tick();
+ fixture.detectChanges();
+
+ const marks = overlayContainerElement.querySelectorAll(
+ '.kbq-app-switcher__search-result mark.kbq-highlight-background'
+ );
+
+ expect(marks).toHaveLength(1);
+ expect(marks[0].textContent).toBe('pp 1');
+ expect(marks[0].closest('.kbq-app-switcher-list-item__name')!.textContent).toBe('App 1');
+ }));
+
+ it('does not highlight anything while the search query is empty', fakeAsync(() => {
+ trigger.show();
+ tick();
+ fixture.detectChanges();
+
+ expect(overlayContainerElement.querySelectorAll('mark.kbq-highlight-background')).toHaveLength(0);
+ }));
});
});
diff --git a/packages/components/app-switcher/kbq-app-switcher-list-item.ts b/packages/components/app-switcher/kbq-app-switcher-list-item.ts
index d0df8b2661..bd2e3ce9ac 100644
--- a/packages/components/app-switcher/kbq-app-switcher-list-item.ts
+++ b/packages/components/app-switcher/kbq-app-switcher-list-item.ts
@@ -9,7 +9,7 @@ import {
ViewEncapsulation
} from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
-import { KBQ_TITLE_TEXT_REF } from '@koobiq/components/core';
+import { KBQ_TITLE_TEXT_REF, KbqHighlightBackgroundPipe } from '@koobiq/components/core';
import { KbqDropdownItem } from '@koobiq/components/dropdown';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqAppSwitcherApp } from './app-switcher';
@@ -19,7 +19,8 @@ import { KbqAppSwitcherApp } from './app-switcher';
selector: '[kbq-app-switcher-list-item]',
imports: [
KbqIconModule,
- NgOptimizedImage
+ NgOptimizedImage,
+ KbqHighlightBackgroundPipe
],
template: `
@if (app.icon) {
@@ -31,7 +32,10 @@ import { KbqAppSwitcherApp } from './app-switcher';
}
-
{{ app.name }}
+
@if (app.caption) {
{{ app.caption }}
}
@@ -65,6 +69,8 @@ export class KbqAppSwitcherListItem extends KbqDropdownItem {
// and migrating would break narrowing currently.
@Input() app: KbqAppSwitcherApp;
readonly toggle = input(false, { transform: booleanAttribute });
+ /** Search query to highlight within the app name. */
+ readonly highlightText = input
('');
// TODO: Skipped for migration because:
// Your application code writes to the input. This prevents migration.
@Input({ transform: booleanAttribute }) collapsed: boolean = false;
diff --git a/packages/components/core/highlight/highlight.en.md b/packages/components/core/highlight/highlight.en.md
index f14ceadf09..067a9b9d4e 100644
--- a/packages/components/core/highlight/highlight.en.md
+++ b/packages/components/core/highlight/highlight.en.md
@@ -1,23 +1,29 @@
-mcHighlight is a pipe for highlighting text matches. Highlighting matches helps users quickly understand why a result is relevant and speeds up navigation through lists. Depending on the context, two styles are used.
+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.
-The pipe takes a string and a search argument, wrapping the found matches in a tag.
+Koobiq provides two pipes for highlighting text matches — `kbqHighlightBackground` and `mcHighlight`. Both take a string and a search argument, wrapping the found matches in a `` tag — `kbq-highlight-background` for the background-color style and `kbq-highlight` for the bold style.
-#### Bold
+#### Background color
-Used in selects with search and homogeneous lists (for example, choosing a department or a name). 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.
+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.
-#### Background color
-
-Used in search results over complex content — descriptions, messages, articles. Highlighting also draws attention even inside long texts.
+Matches in text:
-Matches in search results with a complex layout
+Matches in search results with a complex layout:
Matches in a table:
+
+#### 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
+
+```
diff --git a/packages/components/core/highlight/highlight.ru.md b/packages/components/core/highlight/highlight.ru.md
index f38f667704..0cdcec8b2a 100644
--- a/packages/components/core/highlight/highlight.ru.md
+++ b/packages/components/core/highlight/highlight.ru.md
@@ -1,23 +1,29 @@
-mcHighlight — это pipe для подсветки совпадений текста. Выделение совпадений позволяет пользователю быстро понять, почему результат релевантен, и ускоряет навигацию по спискам. В зависимости от контекста применяются два способа оформления.
+Выделение совпадений позволяет пользователю быстро понять, почему результат релевантен, и ускоряет навигацию по спискам. В зависимости от контекста применяется один из двух способов оформления.
-Pipe принимает строку и аргумент для поиска, оборачивая найденные совпадения в тег ``.
+Koobiq предоставляет два pipe для подсветки совпадений текста — `kbqHighlightBackground` и `mcHighlight`. Оба принимают строку и аргумент для поиска, оборачивая найденные совпадения в тег `` — с классом `kbq-highlight-background` для выделения цветом и `kbq-highlight` для жирного шрифта.
-#### Жирный шрифт
+#### Выделение цветом
-Применяется в селектах с поиском и однородных списках (например, выбор отдела или имени). Этот способ ненавязчив и идеален для быстрого сканирования знакомых данных: пользователь сразу видит, что искомое слово есть в строке, но не отвлекается от основного выбора.
+Применяется в селектах и других выпадающих списках с фильтрацией, а также для выделения совпадений в сложном контенте: описаниях, сообщениях и статьях. Сплошной фон остается читаемым в состояниях hover и active внутри оверлея и делает совпадения заметными даже в длинных текстах.
-#### Выделение цветом
-
-Используется в результатах поиска по сложному контенту — описаниям, сообщениям, статьям. Также выделение привлекает внимание даже внутри длинных текстов.
+Совпадения в тексте:
-Совпадения в результатах поиска со сложной версткой
+Совпадения в результатах поиска со сложной версткой:
Совпадения в таблице:
+
+#### Жирный шрифт
+
+Этот способ ненавязчив и идеален для быстрого сканирования знакомых данных: пользователь сразу видит, что искомое слово есть в строке, но не отвлекается от основного выбора.
+
+```html
+
+```
diff --git a/packages/components/filter-bar/pipes/pipe-multi-tree-select.html b/packages/components/filter-bar/pipes/pipe-multi-tree-select.html
index 023f0b91b8..144590bb79 100644
--- a/packages/components/filter-bar/pipes/pipe-multi-tree-select.html
+++ b/packages/components/filter-bar/pipes/pipe-multi-tree-select.html
@@ -65,16 +65,22 @@
(click)="toggleSelectAllNode()"
>
-
+
-
+
-
+
diff --git a/packages/components/filter-bar/pipes/pipe-tree-select.html b/packages/components/filter-bar/pipes/pipe-tree-select.html
index 72b1afee70..9536fd16d1 100644
--- a/packages/components/filter-bar/pipes/pipe-tree-select.html
+++ b/packages/components/filter-bar/pipes/pipe-tree-select.html
@@ -49,12 +49,16 @@
-
+
-
+
diff --git a/packages/components/timezone/timezone-option.component.html b/packages/components/timezone/timezone-option.component.html
index bec6cdbf28..2bae5f9e84 100644
--- a/packages/components/timezone/timezone-option.component.html
+++ b/packages/components/timezone/timezone-option.component.html
@@ -1,16 +1,25 @@
@for (utcItem of timezone.offset | utcOffset | keyvalue; track utcItem) {
}
diff --git a/packages/components/timezone/timezone-option.component.ts b/packages/components/timezone/timezone-option.component.ts
index deba7a8308..d8ddc4454b 100644
--- a/packages/components/timezone/timezone-option.component.ts
+++ b/packages/components/timezone/timezone-option.component.ts
@@ -9,7 +9,7 @@ import {
viewChild,
ViewEncapsulation
} from '@angular/core';
-import { KbqHighlightPipe, KbqOption } from '@koobiq/components/core';
+import { KbqHighlightBackgroundPipe, KbqOption } from '@koobiq/components/core';
import { CitiesByFilterPipe } from './cities-by-filter.pipe';
import { KbqTimezoneZone } from './timezone.models';
import { offsetFormatter } from './timezone.utils';
@@ -20,7 +20,7 @@ import { UtcOffsetPipe } from './utc-offset.pipe';
imports: [
UtcOffsetPipe,
KeyValuePipe,
- KbqHighlightPipe,
+ KbqHighlightBackgroundPipe,
CitiesByFilterPipe
],
templateUrl: 'timezone-option.component.html',
diff --git a/packages/docs-examples/components/autocomplete/autocomplete-overview/autocomplete-overview-example.ts b/packages/docs-examples/components/autocomplete/autocomplete-overview/autocomplete-overview-example.ts
index 2600ee3648..642ac586d8 100644
--- a/packages/docs-examples/components/autocomplete/autocomplete-overview/autocomplete-overview-example.ts
+++ b/packages/docs-examples/components/autocomplete/autocomplete-overview/autocomplete-overview-example.ts
@@ -2,7 +2,7 @@ import { AsyncPipe } from '@angular/common';
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { KbqAutocompleteModule } from '@koobiq/components/autocomplete';
-import { KbqFormsModule } from '@koobiq/components/core';
+import { KbqFormsModule, KbqHighlightBackgroundPipe } from '@koobiq/components/core';
import { KbqInputModule } from '@koobiq/components/input';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
@@ -17,7 +17,8 @@ import { map, startWith } from 'rxjs/operators';
KbqInputModule,
ReactiveFormsModule,
AsyncPipe,
- KbqFormsModule
+ KbqFormsModule,
+ KbqHighlightBackgroundPipe
],
template: `