@rt-tools/ui-kit-v2 0.41.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +4 -4
  2. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +22 -0
  4. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +155 -100
  6. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
  7. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +2 -2
  8. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +1778 -18
  10. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +22 -5
  12. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  13. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +34 -11
  14. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -1
  15. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +725 -47
  16. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
  17. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +6 -0
  18. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
  19. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +217 -6
  20. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
  21. package/package.json +1 -1
  22. package/src/lib/components/calendar/CONTEXT.md +4 -2
  23. package/src/lib/components/calendar/rt-calendar.component.scss +29 -2
  24. package/src/lib/components/date-picker/CONTEXT.md +5 -0
  25. package/src/lib/components/date-picker/panel/CONTEXT.md +42 -0
  26. package/src/lib/components/date-picker/panel/rt-date-panel.component.scss +55 -2
  27. package/src/lib/components/page-header/CONTEXT.md +35 -1
  28. package/src/lib/components/page-header/bar/rt-page-bar.component.scss +161 -0
  29. package/src/lib/components/page-header/rail/rt-page-actions.component.scss +115 -0
  30. package/src/lib/components/page-header/rail/rt-page-phone-menu.component.scss +129 -0
  31. package/src/lib/components/page-header/rail/rt-page-rail.component.scss +281 -0
  32. package/src/lib/components/page-header/rail/rt-page-user.component.scss +76 -0
  33. package/src/lib/components/page-header/rt-page-header.component.scss +5 -0
  34. package/src/lib/components/page-header/stories/component/test-page-header-vertical.component.scss +72 -0
  35. package/src/lib/components/page-header/stories/component/test-page-table.component.scss +81 -0
  36. package/src/lib/components/page-header/user/rt-page-header-user.component.scss +6 -0
  37. package/src/lib/components/stepper/CONTEXT.md +34 -2
  38. package/src/lib/components/stepper/rt-stepper.component.scss +62 -43
  39. package/src/lib/components/tabs/CONTEXT.md +30 -1
  40. package/src/lib/components/tabs/rt-tabs-arrows.scss +140 -0
  41. package/src/lib/components/tabs/rt-tabs-more-menu.scss +126 -0
  42. package/src/lib/components/tabs/rt-tabs-more.component.scss +29 -0
  43. package/src/lib/components/tabs/rt-tabs.component.scss +18 -61
  44. package/src/lib/components/workspace/CONTEXT.md +11 -1
  45. package/src/lib/components/workspace/rt-workspace.component.scss +51 -3
  46. package/src/rich-editor/lib/components/chat/CONTEXT.md +12 -2
  47. package/src/rich-editor/lib/components/chat/rt-chat-messenger.scss +9 -3
  48. package/src/rich-editor/lib/components/chat/rt-chat-translation.scss +92 -0
  49. package/types/rt-tools-ui-kit-v2-calendar.d.ts +13 -1
  50. package/types/rt-tools-ui-kit-v2-core.d.ts +9 -1
  51. package/types/rt-tools-ui-kit-v2-date-picker.d.ts +157 -5
  52. package/types/rt-tools-ui-kit-v2-page-header.d.ts +202 -2
  53. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +25 -0
  54. package/types/rt-tools-ui-kit-v2-stepper.d.ts +20 -6
  55. package/types/rt-tools-ui-kit-v2-tabs.d.ts +120 -1
  56. package/types/rt-tools-ui-kit-v2-workspace.d.ts +33 -1
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-page-header.mjs","names":["BEM_BLOCK"],"sources":["../../../projects/ui-kit-v2/src/lib/components/page-header/rt-page-header.logic.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/more/rt-page-header-more.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/more/rt-page-header-more.component.html","../../../projects/ui-kit-v2/src/lib/components/page-header/rt-page-header.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/rt-page-header.component.html"],"sourcesContent":["import { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { IRtPageHeader } from './rt-page-header.model';\n\n/** Чем пункт отрисуется: панелью, ссылкой или кнопкой. */\nexport enum ERtPageHeaderEntry {\n Panel = 'panel',\n Link = 'link',\n Button = 'button',\n}\n\nexport namespace IRtPageHeaderView {\n /** Пункт, готовый к отрисовке: форма решена заранее, шаблон её не выводит. */\n export interface Entry {\n readonly id: string;\n readonly label: string;\n readonly icon: IRtIcon.Name | null;\n readonly route: string;\n readonly routerLinkActiveExact: boolean;\n readonly disabled: boolean;\n readonly unread: boolean;\n readonly kind: ERtPageHeaderEntry;\n }\n\n export interface Group {\n readonly id: string;\n readonly label: string;\n readonly icon: IRtIcon.Name | null;\n readonly items: ReadonlyArray<Entry>;\n }\n\n export interface Column {\n readonly id: string;\n readonly groups: ReadonlyArray<Group>;\n }\n\n export interface Section extends Entry {\n readonly columns: ReadonlyArray<Column>;\n readonly columnCount: number;\n /** Все пункты панели одним списком: подсветка раздела и сведение маркера. */\n readonly panelItems: ReadonlyArray<Entry>;\n /** Группы всех колонок подряд: на узком экране колонок нет, а группы есть. */\n readonly panelGroups: ReadonlyArray<Group>;\n /** Очередь ухода в «Ещё»: меньшее число уходит раньше. */\n readonly priority: number;\n }\n}\n\nexport namespace IRtPageHeaderFit {\n /** Раздел верхнего ряда с замеренной шириной и важностью. */\n export interface Slot {\n readonly id: string;\n readonly width: number;\n readonly priority: number;\n }\n\n export interface Input {\n /** Разделы в порядке списка. */\n readonly slots: ReadonlyArray<Slot>;\n /** Ширина пункта «Ещё». */\n readonly moreWidth: number;\n /** Ширина, которую ряд может занять. */\n readonly available: number;\n /** Промежуток между соседними пунктами ряда. */\n readonly gap: number;\n }\n\n /** Раскладка ряда: оба списка идут в порядке исходного списка. */\n export interface Result {\n readonly row: ReadonlyArray<string>;\n readonly more: ReadonlyArray<string>;\n }\n}\n\n/**\n * Запас на дробные пиксели замера: сумма округлённых браузером ширин расходится с шириной ряда на\n * доли пикселя, и без запаса последний раздел уходил бы в «Ещё», хотя на глаз помещается.\n */\nconst FIT_TOLERANCE: number = 0.5;\n\n/** Пункты панели одним списком — колонки и группы для этого раскрываются. */\nexport function panelItemsOf(item: IRtPageHeader.Item): ReadonlyArray<IRtPageHeader.Item> {\n return (item.columns ?? []).flatMap((column: IRtPageHeader.Column): ReadonlyArray<IRtPageHeader.Item> =>\n column.groups.flatMap((group: IRtPageHeader.Group): ReadonlyArray<IRtPageHeader.Item> => group.items)\n );\n}\n\n/**\n * Маркер раздела. Пункты панели свёрнуты, и непросмотренное внутри видно только\n * по точке у самого раздела.\n */\nexport function unreadOf(item: IRtPageHeader.Item): boolean {\n return item.unread === true || panelItemsOf(item).some((entry: IRtPageHeader.Item): boolean => entry.unread === true);\n}\n\nexport function entryKindOf(item: IRtPageHeader.Item): ERtPageHeaderEntry {\n if (panelItemsOf(item).length > 0) {\n return ERtPageHeaderEntry.Panel;\n }\n if ((item.route ?? '') !== '' && !item.disabled) {\n return ERtPageHeaderEntry.Link;\n }\n\n return ERtPageHeaderEntry.Button;\n}\n\nexport function toEntry(item: IRtPageHeader.Item): IRtPageHeaderView.Entry {\n return {\n id: item.id,\n label: item.label,\n icon: item.icon ?? null,\n route: item.route ?? '',\n routerLinkActiveExact: item.routerLinkActiveExact === true,\n disabled: item.disabled === true,\n unread: item.unread === true,\n kind: entryKindOf(item),\n };\n}\n\nfunction toGroup(group: IRtPageHeader.Group): IRtPageHeaderView.Group {\n return {\n id: group.id,\n label: group.label ?? '',\n icon: group.icon ?? null,\n items: group.items.map(toEntry),\n };\n}\n\nfunction toColumn(column: IRtPageHeader.Column): IRtPageHeaderView.Column {\n return {\n id: column.id,\n groups: column.groups.map(toGroup),\n };\n}\n\n/** Группы всех колонок одним списком — узкий экран раскладывает панель без колонок. */\nexport function panelGroupsOf(columns: ReadonlyArray<IRtPageHeaderView.Column>): ReadonlyArray<IRtPageHeaderView.Group> {\n return columns.flatMap((column: IRtPageHeaderView.Column): ReadonlyArray<IRtPageHeaderView.Group> => column.groups);\n}\n\n/** Разделы верхнего ряда вместе с раскладкой их панелей. */\nexport function toSections(items: ReadonlyArray<IRtPageHeader.Item>): ReadonlyArray<IRtPageHeaderView.Section> {\n return items.map((item: IRtPageHeader.Item): IRtPageHeaderView.Section => {\n const columns: ReadonlyArray<IRtPageHeaderView.Column> = (item.columns ?? []).map(toColumn);\n\n return {\n ...toEntry(item),\n unread: unreadOf(item),\n columns,\n columnCount: columns.length,\n panelItems: panelItemsOf(item).map(toEntry),\n panelGroups: panelGroupsOf(columns),\n priority: item.priority ?? 0,\n };\n });\n}\n\n/** Адрес без строки запроса и якоря — подсветка считается по пути. */\nexport function pathOf(url: string): string {\n return url.split(/[?#]/)[0] ?? '';\n}\n\nexport function isEntryActive(entry: IRtPageHeaderView.Entry, path: string): boolean {\n if (entry.kind !== ERtPageHeaderEntry.Link) {\n return false;\n }\n\n return entry.routerLinkActiveExact ? path === entry.route : path.startsWith(entry.route);\n}\n\n/**\n * Разделы для кругов сжатой полосы: первые `count` из тех, у кого есть иконка. Раздел без\n * иконки в круг не попадает — показать в нём нечего, и он остаётся под кнопкой «ещё».\n */\nexport function compactSectionsOf(\n sections: ReadonlyArray<IRtPageHeaderView.Section>,\n count: number\n): ReadonlyArray<IRtPageHeaderView.Section> {\n return sections.filter((section: IRtPageHeaderView.Section): boolean => section.icon !== null).slice(0, Math.max(0, count));\n}\n\n/**\n * Прилипла ли шапка: липкий узел стоит на пиксель выше края прокрутки и, прилипнув, теряет этот\n * пиксель из видимой области — наблюдатель пересечения отдаёт долю меньше единицы. Узел, ушедший\n * из области целиком, прилипшим не считается: его не видно вовсе.\n */\nexport function isStuck(intersectionRatio: number, isIntersecting: boolean): boolean {\n return isIntersecting && intersectionRatio < 1;\n}\n\n/**\n * Разделы, у которых активен хоть один пункт панели. Обход идёт по раскрытому\n * списку пунктов: своего адреса у раздела с панелью нет, и подсветить его больше\n * нечем.\n */\nexport function activeSectionIds(sections: ReadonlyArray<IRtPageHeaderView.Section>, url: string): ReadonlySet<string> {\n const path: string = pathOf(url);\n const ids: Set<string> = new Set<string>();\n for (const section of sections) {\n if (section.panelItems.some((entry: IRtPageHeaderView.Entry): boolean => isEntryActive(entry, path))) {\n ids.add(section.id);\n }\n }\n\n return ids;\n}\n\nfunction idOf(slot: IRtPageHeaderFit.Slot): string {\n return slot.id;\n}\n\n/** Ширина ряда из пунктов заданной ширины с промежутками между соседями. */\nfunction rowWidthOf(widths: ReadonlyArray<number>, gap: number): number {\n const total: number = widths.reduce((sum: number, width: number): number => sum + width, 0);\n\n return total + gap * Math.max(0, widths.length - 1);\n}\n\n/**\n * Какие разделы стоят в ряду, а какие уходят в «Ещё». Всё помещается — «Ещё» нет. Иначе разделы\n * уходят по очереди важности, пока оставшиеся вместе с «Ещё» не встанут в доступную ширину:\n * меньшая важность уходит раньше, а при равной — стоящий дальше от начала списка. Порядок\n * оставшихся не меняется.\n */\nexport function fitRow(input: IRtPageHeaderFit.Input): IRtPageHeaderFit.Result {\n const { slots, moreWidth, available, gap } = input;\n const limit: number = available + FIT_TOLERANCE;\n if (\n rowWidthOf(\n slots.map((slot: IRtPageHeaderFit.Slot): number => slot.width),\n gap\n ) <= limit\n ) {\n return { row: slots.map(idOf), more: [] };\n }\n\n const departure: ReadonlyArray<number> = Array.from(slots.keys()).sort(\n (a: number, b: number): number => slots[a].priority - slots[b].priority || b - a\n );\n const kept: Set<number> = new Set<number>(slots.keys());\n for (const index of departure) {\n const keptWidths: ReadonlyArray<number> = Array.from(kept, (at: number): number => slots[at].width);\n if (rowWidthOf([...keptWidths, moreWidth], gap) <= limit) {\n break;\n }\n kept.delete(index);\n }\n\n return {\n row: Array.from(slots.keys())\n .filter((index: number): boolean => kept.has(index))\n .map((index: number): string => slots[index].id),\n more: Array.from(slots.keys())\n .filter((index: number): boolean => !kept.has(index))\n .map((index: number): string => slots[index].id),\n };\n}\n\n/** Активен ли раздел: своим адресом или адресом пункта своей панели. */\nexport function isSectionActive(section: IRtPageHeaderView.Section, path: string): boolean {\n return isEntryActive(section, path) || section.panelItems.some((entry: IRtPageHeaderView.Entry): boolean => isEntryActive(entry, path));\n}\n\n/** Есть ли среди разделов активный — по нему «Ещё» подсвечивается, как выбранный пункт ряда. */\nexport function hasActiveSection(sections: ReadonlyArray<IRtPageHeaderView.Section>, url: string): boolean {\n const path: string = pathOf(url);\n\n return sections.some((section: IRtPageHeaderView.Section): boolean => isSectionActive(section, path));\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, RT_KIT_TRANSLATOR, RtKitLabelPipe, TRtKitLabelMap, TRtKitTranslator } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { ERtPageHeaderEntry, IRtPageHeaderView } from '../rt-page-header.logic';\n\nconst BEM_BLOCK: string = 'rt-page-header-more';\n\n/**\n * Пункт «Ещё» в конце верхнего ряда `rt-page-header` и его панель: разделы, которым не хватило\n * ширины ряда.\n *\n * Кнопка носит вид пункта ряда — элементы блока `rt-page-header`, — и подсвечивается так же, как\n * выбранный раздел, когда выбранный раздел ушёл сюда. Панель открывается тем же поповером, что и\n * панели разделов, по наведению и по нажатию. Раздел с панелью показан в ней заголовком и пунктами\n * своих групп, как в меню узкого экрана, и берёт его блок с модификатором `more`.\n *\n * Какие разделы ушли, решает шапка: здесь ничего не меряется.\n */\n@Component({\n selector: 'rt-page-header-more',\n templateUrl: './rt-page-header-more.component.html',\n styleUrl: './rt-page-header-more.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n RtKitLabelPipe,\n // Angular\n RouterLink,\n RouterLinkActive,\n\n // standalone components / directives\n RtIconComponent,\n RtPopoverDirective,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtPageHeaderMoreComponent {\n readonly #translate: Signal<TRtKitTranslator> = inject(RT_KIT_TRANSLATOR);\n\n /** Переводчик для чистого пайпа подписи: шаблон отдаёт его вторым доводом. */\n protected readonly translate: Signal<TRtKitTranslator> = this.#translate;\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly EntryKind: typeof ERtPageHeaderEntry = ERtPageHeaderEntry;\n\n /** Точка у «Ещё»: непросмотренное ушедшего раздела иначе видно только в открытой панели. */\n protected readonly unread: Signal<boolean> = computed((): boolean =>\n this.sections().some((section: IRtPageHeaderView.Section): boolean => section.unread)\n );\n\n /** Разделы, ушедшие из ряда, в порядке списка. */\n public readonly sections: InputSignal<ReadonlyArray<IRtPageHeaderView.Section>> = input<ReadonlyArray<IRtPageHeaderView.Section>>([]);\n\n /** Выбранный раздел среди ушедших: «Ещё» подсвечивается, как выбранный пункт ряда. */\n public readonly active: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Нажат пункт без адреса — приходит его идентификатор. */\n public readonly itemClick: OutputEmitterRef<string> = output<string>();\n\n protected onItemClick(id: string): void {\n this.itemClick.emit(id);\n }\n}\n","<!--\n Кнопка берёт элементы блока шапки, а не свои: «Ещё» стоит в том же ряду и выглядит как его пункт,\n а второй набор тех же правил разошёлся бы с первым при первой правке.\n-->\n<ng-container rtBlock=\"rt-page-header\">\n <button\n rtElem=\"link\"\n type=\"button\"\n qa-dataid=\"header-nav-more\"\n #morePopover=\"rtPopover\"\n rtPopoverTrigger=\"hover\"\n rtPopoverAlign=\"end\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"14\"\n [rtMod]=\"{ isActive: active(), isOpen: morePopover.isOpen() }\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"morePopover.isOpen()\"\n [rtPopover]=\"moreTpl\"\n (click)=\"morePopover.open()\">\n <span rtElem=\"label\">{{ t().uiNavMore }}</span>\n @if (unread()) {\n <span rtElem=\"marker\" role=\"img\" qa-dataid=\"header-nav-marker\" data-id=\"more\" [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n <span rtElem=\"caret\" aria-hidden=\"true\">\n <rt-icon name=\"chevron-up-down\" size=\"xs\" />\n </span>\n </button>\n</ng-container>\n\n<!--\n Панель «Ещё» — та же разметка, что меню узкого экрана, без аккордеона: раздел с панелью стоит\n заголовком, а пункты его групп идут под ним сразу.\n-->\n<ng-template #moreTpl>\n <div rtBlock=\"rt-page-header-mobile\" role=\"menu\" qa-dataid=\"header-nav-more-list\" [rtMod]=\"{ more: true }\">\n @for (section of sections(); track section.id) {\n @switch (section.kind) {\n @case (EntryKind.Panel) {\n <div rtElem=\"heading\" qa-dataid=\"header-nav-more-section\" [attr.data-id]=\"section.id\">\n <span rtElem=\"label\">{{ section.label }}</span>\n </div>\n <div rtElem=\"children\">\n @for (group of section.panelGroups; track group.id) {\n <div rtElem=\"group\" role=\"group\" [attr.aria-label]=\"group.label || null\">\n @if (group.label) {\n <div rtElem=\"group-title\" qa-dataid=\"header-nav-more-group\" [attr.data-id]=\"group.id\">\n <span rtElem=\"group-label\">{{ group.label }}</span>\n </div>\n }\n @for (entry of group.items; track entry.id) {\n @if (entry.kind === EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n routerLinkActive=\"rt-page-header-mobile__link--is-active\"\n [rtMod]=\"{ child: true }\"\n [attr.data-id]=\"entry.id\"\n [routerLink]=\"entry.route\"\n [routerLinkActiveOptions]=\"{ exact: entry.routerLinkActiveExact }\"\n (click)=\"morePopover.close()\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n } @else if (entry.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"'uiSectionInProgress' | rtKitLabel: translate() : { label: entry.label }\">\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n [rtMod]=\"{ child: true, disabled: true }\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-disabled]=\"true\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n [rtMod]=\"{ child: true }\"\n [attr.data-id]=\"entry.id\"\n (click)=\"onItemClick(entry.id); morePopover.close()\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n </div>\n }\n </div>\n }\n @case (EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n routerLinkActive=\"rt-page-header-mobile__link--is-active\"\n [attr.data-id]=\"section.id\"\n [routerLink]=\"section.route\"\n [routerLinkActiveOptions]=\"{ exact: section.routerLinkActiveExact }\"\n (click)=\"morePopover.close()\">\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n }\n @default {\n @if (section.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"'uiSectionInProgress' | rtKitLabel: translate() : { label: section.label }\">\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n [rtMod]=\"{ disabled: true }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-disabled]=\"true\">\n <span rtElem=\"label\">{{ section.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n [attr.data-id]=\"section.id\"\n (click)=\"onItemClick(section.id); morePopover.close()\">\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n }\n }\n </div>\n</ng-template>\n","import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport {\n afterNextRender,\n afterRenderEffect,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n numberAttribute,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { Event as RouterEvent, NavigationEnd, Router, RouterLink, RouterLinkActive } from '@angular/router';\n\nimport { filter, map } from 'rxjs';\n\nimport { BlockDirective, ElemDirective, ModDirective, WINDOW } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, RT_KIT_TRANSLATOR, RtKitLabelPipe, TRtKitLabelMap, TRtKitTranslator, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { BreakpointsService } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { RtPageHeaderMoreComponent } from './more/rt-page-header-more.component';\nimport {\n activeSectionIds,\n compactSectionsOf,\n fitRow,\n hasActiveSection,\n ERtPageHeaderEntry,\n IRtPageHeaderFit,\n IRtPageHeaderView,\n isStuck,\n toSections,\n} from './rt-page-header.logic';\nimport { IRtPageHeader } from './rt-page-header.model';\n\nconst BEM_BLOCK: string = 'rt-page-header';\n\n/** Подложка узкой шапки: её вид задан в `rt-page-header-mobile.scss`, класс ставит и бургер */\nconst PAGE_HEADER_MOBILE_BACKDROP: string = 'rt-page-header-mobile-backdrop';\n\n/**\n * Верхняя горизонтальная плашка-навигация для первого уровня доменных страниц.\n *\n * Контракт:\n * - `items` — `Item[]`. Анкор для пунктов с `route`; `<button>` для недоступных\n * и для тех, кто обрабатывается снаружи (`itemClick`). Пункт с `columns` —\n * кнопка-триггер: панель второго уровня открывается наведением ([rtPopover]).\n * - `user` — необязательный блок справа. Если задан `userMenu` (TemplateRef) —\n * блок становится hover-триггером попапа с этим контентом (клик — touch-fallback,\n * панель прижата к правому краю); иначе по клику emit'ит `userClick`.\n *\n * Active state — через `RouterLinkActive` с классом `rt-page-header__link--is-active`;\n * для раздела с панелью — вычисляется по текущему URL (своего route у него нет).\n */\n@Component({\n selector: 'rt-page-header',\n templateUrl: './rt-page-header.component.html',\n // Панель второго уровня и панель узкого экрана рисуются в CDK Overlay, вне\n // хоста, поэтому это отдельные корневые блоки — и отдельные файлы: бюджет\n // стилей компонента считается на каждый файл, и одним они его перебирают.\n styleUrls: [\n './rt-page-header.component.scss',\n './rt-page-header-submenu.scss',\n './rt-page-header-mobile.scss',\n './rt-page-header-compact.scss',\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n RtKitLabelPipe,\n // Angular\n RouterLink,\n RouterLinkActive,\n\n // standalone components / directives\n RtIconComponent,\n RtPopoverDirective,\n RtTooltipDirective,\n RtPageHeaderMoreComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-page-header--sticky]': 'stickyCompact()',\n '[class.rt-page-header--is-compact]': 'compact()',\n },\n})\nexport class RtPageHeaderComponent {\n readonly #router: Router = inject(Router);\n\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #host: ElementRef<HTMLElement> = inject<ElementRef<HTMLElement>>(ElementRef);\n\n // Конструктор наблюдателя пересечения объявлен на globalThis, а не на интерфейсе Window —\n // токен отдаёт тот же объект, тип лишь уточняется.\n readonly #window: Window & typeof globalThis = inject(WINDOW) as Window & typeof globalThis;\n\n /**\n * Прилипла ли шапка к краю прокрутки. Считается наблюдателем пересечения, а не смещением\n * окна: страница у потребителя прокручивается и внутри контейнера, и окно об этом не знает.\n */\n readonly #stuck: WritableSignal<boolean> = signal<boolean>(false);\n\n readonly #t_uiMainNav: Signal<string> = rtKitLabel('uiMainNav');\n\n /** Наблюдатель ширины навигации и пунктов ряда: по нему ряд пересчитывает, что уходит в «Ещё». */\n #rowWatch: ResizeObserver | null = null;\n\n /** id разделов, ушедших в «Ещё». До первого замера уходить некому. */\n readonly #overflowIds: WritableSignal<ReadonlySet<string>> = signal<ReadonlySet<string>>(new Set<string>(), {\n equal: (a: ReadonlySet<string>, b: ReadonlySet<string>): boolean =>\n a.size === b.size && [...a].every((id: string): boolean => b.has(id)),\n });\n\n protected readonly navRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('nav');\n\n protected readonly listRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('list');\n\n protected readonly moreItemRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('moreItem');\n\n /* Реактивный URL для подсветки раздела: у раздела с панелью нет своего\n route, поэтому RouterLinkActive не применим — сравниваем по факту навигации. */\n readonly #currentUrl: Signal<string> = toSignal(\n this.#router.events.pipe(\n filter((e: RouterEvent): e is NavigationEnd => e instanceof NavigationEnd),\n map((): string => this.#router.url)\n ),\n { initialValue: this.#router.url }\n );\n\n readonly #breakpoints: BreakpointsService = inject(BreakpointsService);\n\n readonly #translate: Signal<TRtKitTranslator> = inject(RT_KIT_TRANSLATOR);\n\n /** Переводчик для чистого пайпа подписи: шаблон отдаёт его вторым доводом. */\n protected readonly translate: Signal<TRtKitTranslator> = this.#translate;\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly mobileNavPopoverRef: Signal<RtPopoverDirective | undefined> = viewChild('mobileNavPopover', {\n read: RtPopoverDirective,\n });\n\n /** Кнопка «ещё» сжатой полосы открывает ту же панель, что и бургер, своим поповером. */\n protected readonly compactNavPopoverRef: Signal<RtPopoverDirective | undefined> = viewChild('compactNavPopover', {\n read: RtPopoverDirective,\n });\n\n /** Сжатое состояние: шапка липкая и прилипла к верху. */\n protected readonly compact: Signal<boolean> = computed((): boolean => this.stickyCompact() && this.#stuck());\n\n /** Разделы в кругах сжатой полосы: первые с иконкой, число — по входу. */\n protected readonly compactSections: Signal<ReadonlyArray<IRtPageHeaderView.Section>> = computed(\n (): ReadonlyArray<IRtPageHeaderView.Section> => compactSectionsOf(this.sections(), this.compactVisibleCount())\n );\n\n /** Разделы, ушедшие из ряда в «Ещё»: шаблон вынимает их из ряда, сохраняя в разметке для замера. */\n protected readonly overflowIds: Signal<ReadonlySet<string>> = this.#overflowIds.asReadonly();\n\n /** Разделы панели «Ещё» в порядке списка. */\n protected readonly moreSections: Signal<ReadonlyArray<IRtPageHeaderView.Section>> = computed(\n (): ReadonlyArray<IRtPageHeaderView.Section> =>\n this.sections().filter((section: IRtPageHeaderView.Section): boolean => this.overflowIds().has(section.id))\n );\n\n /** «Ещё» стоит в ряду, только когда в ряд не встал хоть один раздел. */\n protected readonly moreShown: Signal<boolean> = computed((): boolean => this.moreSections().length > 0);\n\n /** Выбранный раздел ушёл в «Ещё» — подсвечивается сам «Ещё». */\n protected readonly moreActive: Signal<boolean> = computed((): boolean => hasActiveSection(this.moreSections(), this.#currentUrl()));\n\n /** Форма пункта решается один раз здесь, а не ветвлениями в шаблоне. */\n protected readonly sections: Signal<ReadonlyArray<IRtPageHeaderView.Section>> = computed((): ReadonlyArray<IRtPageHeaderView.Section> =>\n toSections(this.items())\n );\n\n /**\n * id разделов с активным вложенным адресом — для O(1) lookup в шаблоне.\n * Зависит от #currentUrl + items (сигналы) → подсветка реактивна на навигацию.\n */\n protected readonly activeSectionIds: Signal<ReadonlySet<string>> = computed((): ReadonlySet<string> =>\n activeSectionIds(this.sections(), this.#currentUrl())\n );\n\n protected readonly userAvatar: Signal<string> = computed((): string => {\n const u: IRtPageHeader.User | null = this.user();\n if (!u) {\n return '';\n }\n if (u.avatar && u.avatar.length > 0) {\n return u.avatar.charAt(0).toUpperCase();\n }\n return u.name.charAt(0).toUpperCase();\n });\n\n /** Узкий вьюпорт (≤1080px): инлайн-навигация прячется, показывается гамбургер. */\n protected readonly isNarrow: Signal<boolean> = this.#breakpoints.narrow;\n\n /**\n * Подложка меню профиля: на узком экране та же, что у меню разделов из бургера, на широком её\n * нет — меню там открывается наведением. Поповер читает класс при первом открытии.\n */\n protected readonly userMenuBackdropClass: Signal<string> = computed((): string => (this.isNarrow() ? PAGE_HEADER_MOBILE_BACKDROP : ''));\n\n /**\n * id раскрытых разделов-аккордеонов в мобильной панели. Ключ — только раздел:\n * группы внутри раскрытого раздела показаны сразу, и совпасть идентификаторам\n * раздела и группы в этом множестве негде.\n */\n protected readonly expandedSectionIds: WritableSignal<ReadonlySet<string>> = signal<ReadonlySet<string>>(new Set<string>());\n\n protected readonly EntryKind: typeof ERtPageHeaderEntry = ERtPageHeaderEntry;\n\n public readonly items: InputSignal<ReadonlyArray<IRtPageHeader.Item>> = input<ReadonlyArray<IRtPageHeader.Item>>([]);\n\n public readonly user: InputSignal<IRtPageHeader.User | null> = input<IRtPageHeader.User | null>(null);\n\n public readonly userTitle: InputSignal<string> = input<string>('');\n\n public readonly userMenu: InputSignal<TemplateRef<unknown> | null> = input<TemplateRef<unknown> | null>(null);\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly ariaLabel: InputSignal<string> = input<string>('');\n\n /**\n * Шапка липнет к верху окна и, прилипнув, сжимается в полосу: круги первых разделов,\n * кнопка «ещё» и три слота потребителя. Выключено — поведение прежнее.\n */\n public readonly stickyCompact: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Сколько разделов с иконкой показывать кругами в сжатой полосе; остальные — под «ещё». */\n public readonly compactVisibleCount: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(2, {\n transform: numberAttribute,\n });\n\n /** Своё имя навигации важнее умолчания */\n public readonly navAriaLabel: Signal<string> = computed((): string => this.ariaLabel() || this.#t_uiMainNav());\n\n public readonly itemClick: OutputEmitterRef<string> = output<string>();\n\n public readonly userClick: OutputEmitterRef<void> = output<void>();\n\n constructor() {\n // Ресайз обратно в десктоп — гамбургер скрывается CSS'ом; открытую\n // мобильную панель закрываем, иначе overlay зависнет без якоря.\n effect((): void => {\n if (!this.isNarrow()) {\n this.mobileNavPopoverRef()?.close();\n }\n });\n\n afterNextRender((): void => this.#observeStuck());\n\n // Ряд пересчитывается при смене состава и подписей — и разделов, и самого «Ещё»: ширины\n // пунктов меняются вместе с ними. Смену ширины шапки и шрифт, пришедший после первой\n // отрисовки, ловит наблюдатель размера. Эффект после отрисовки идёт только в браузере.\n afterRenderEffect((): void => {\n this.sections();\n this.t();\n this.#watchRow();\n this.#measureRow();\n });\n\n this.#destroyRef.onDestroy((): void => this.#rowWatch?.disconnect());\n }\n\n /** Наблюдение ставится заново на каждый состав: пришедшие пункты должны попасть под него. */\n #watchRow(): void {\n const nav: HTMLElement | undefined = this.navRef()?.nativeElement;\n const list: HTMLElement | undefined = this.listRef()?.nativeElement;\n if (nav === undefined || list === undefined || !('ResizeObserver' in this.#window)) {\n return;\n }\n this.#rowWatch?.disconnect();\n this.#rowWatch = new this.#window.ResizeObserver((): void => this.#measureRow());\n this.#rowWatch.observe(nav);\n Array.from(list.children).forEach((item: Element): void => this.#rowWatch?.observe(item));\n }\n\n /**\n * Замер ряда: ширина навигации, ширина каждого раздела и «Ещё», промежуток между пунктами.\n * Навигация без ширины спрятана — узкий экран или сжатая полоса, — и прежняя раскладка\n * остаётся до её возвращения.\n */\n #measureRow(): void {\n const nav: HTMLElement | undefined = this.navRef()?.nativeElement;\n const list: HTMLElement | undefined = this.listRef()?.nativeElement;\n const moreItem: HTMLElement | undefined = this.moreItemRef()?.nativeElement;\n if (nav === undefined || list === undefined || moreItem === undefined) {\n return;\n }\n const available: number = nav.getBoundingClientRect().width;\n if (available <= 0) {\n return;\n }\n const widths: Map<string, number> = new Map<string, number>();\n list.querySelectorAll<HTMLElement>('[qa-dataid=\"header-nav-item\"]').forEach((item: HTMLElement): void => {\n widths.set(item.dataset['id'] ?? '', item.getBoundingClientRect().width);\n });\n const fit: IRtPageHeaderFit.Result = fitRow({\n slots: this.sections().map((section: IRtPageHeaderView.Section): IRtPageHeaderFit.Slot => ({\n id: section.id,\n width: widths.get(section.id) ?? 0,\n priority: section.priority,\n })),\n moreWidth: moreItem.getBoundingClientRect().width,\n gap: parseFloat(this.#window.getComputedStyle(list).columnGap) || 0,\n available,\n });\n this.#overflowIds.set(new Set<string>(fit.more));\n }\n\n /**\n * Липкая шапка стоит на пиксель выше края прокрутки и, прилипнув, теряет его из видимой\n * области: наблюдатель пересечения с порогом в единицу ловит ровно этот момент — и в окне,\n * и внутри прокручиваемого контейнера, о котором окно не знает.\n */\n #observeStuck(): void {\n const observer: IntersectionObserver = new this.#window.IntersectionObserver(\n (entries: IntersectionObserverEntry[]): void => {\n const entry: IntersectionObserverEntry | undefined = entries.at(-1);\n if (entry !== undefined) {\n this.#stuck.set(isStuck(entry.intersectionRatio, entry.isIntersecting));\n }\n },\n { threshold: [0, 1] }\n );\n observer.observe(this.#host.nativeElement);\n this.#destroyRef.onDestroy((): void => observer.disconnect());\n }\n\n /** Панель разделов открывают и бургер, и кнопка «ещё»: закрываются обе. */\n protected closeNavPanels(): void {\n this.mobileNavPopoverRef()?.close();\n this.compactNavPopoverRef()?.close();\n }\n\n /** Круг раздела без адреса: раздел с панелью открывает общую панель, прочий — сообщает наружу. */\n protected onCompactSectionClick(section: IRtPageHeaderView.Section): void {\n if (section.kind === ERtPageHeaderEntry.Panel) {\n this.compactNavPopoverRef()?.open();\n return;\n }\n this.itemClick.emit(section.id);\n }\n\n protected onItemClick(id: string): void {\n this.itemClick.emit(id);\n }\n\n protected onUserClick(): void {\n this.userClick.emit();\n }\n\n /** Аккордеон мобильной панели: тумблер раскрытия раздела по его id. */\n protected toggleSection(id: string): void {\n this.expandedSectionIds.update((prev: ReadonlySet<string>): ReadonlySet<string> => {\n const next: Set<string> = new Set<string>(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n }\n\n /** Клик по плоскому пункту мобильной панели: emit + закрыть панель. */\n protected onMobileItemClick(id: string): void {\n this.itemClick.emit(id);\n this.closeNavPanels();\n }\n}\n","<ng-container rtBlock=\"rt-page-header\">\n <nav rtElem=\"nav\" #nav [attr.aria-label]=\"navAriaLabel()\">\n <ul rtElem=\"list\" role=\"list\" #list>\n @for (section of sections(); track section.id) {\n <li\n rtElem=\"item\"\n qa-dataid=\"header-nav-item\"\n [rtMod]=\"{ isOverflow: overflowIds().has(section.id) }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-hidden]=\"overflowIds().has(section.id) || null\"\n [attr.inert]=\"overflowIds().has(section.id) || null\">\n @switch (section.kind) {\n @case (EntryKind.Panel) {\n <button\n rtElem=\"link\"\n type=\"button\"\n qa-dataid=\"header-nav-trigger\"\n #groupPopover=\"rtPopover\"\n rtPopoverTrigger=\"hover\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"14\"\n [rtMod]=\"{\n isActive: activeSectionIds().has(section.id),\n isOpen: groupPopover.isOpen(),\n }\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"groupPopover.isOpen()\"\n [rtPopover]=\"submenuTpl\"\n (click)=\"groupPopover.open()\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n <span rtElem=\"caret\" aria-hidden=\"true\">\n <rt-icon name=\"chevron-up-down\" size=\"xs\" />\n </span>\n </button>\n <ng-template #submenuTpl>\n <div rtBlock=\"rt-page-header-submenu\" role=\"menu\" [style.--rt-nav-panel-columns]=\"section.columnCount\">\n @for (column of section.columns; track column.id) {\n <div rtElem=\"column\" qa-dataid=\"header-nav-column\" [attr.data-id]=\"column.id\">\n @for (group of column.groups; track group.id) {\n <div rtElem=\"group\" role=\"group\" [attr.aria-label]=\"group.label || null\">\n @if (group.label) {\n <div rtElem=\"group-title\" qa-dataid=\"header-nav-group\" [attr.data-id]=\"group.id\">\n @if (group.icon) {\n <rt-icon rtElem=\"group-icon\" size=\"xs\" [name]=\"group.icon\" />\n }\n <span rtElem=\"group-label\">{{ group.label }}</span>\n </div>\n }\n @for (entry of group.items; track entry.id) {\n @if (entry.kind === EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-subitem\"\n routerLinkActive=\"rt-page-header-submenu__link--is-active\"\n [attr.data-id]=\"entry.id\"\n [routerLink]=\"entry.route\"\n [routerLinkActiveOptions]=\"{ exact: entry.routerLinkActiveExact }\"\n (click)=\"groupPopover.close()\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n } @else if (entry.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"\n 'uiSectionInProgress' | rtKitLabel: translate() : { label: entry.label }\n \">\n <button\n rtElem=\"link\"\n role=\"menuitem\"\n type=\"button\"\n qa-dataid=\"header-nav-subitem\"\n [rtMod]=\"{ disabled: true }\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-disabled]=\"true\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n role=\"menuitem\"\n type=\"button\"\n qa-dataid=\"header-nav-subitem\"\n [attr.data-id]=\"entry.id\"\n (click)=\"onItemClick(entry.id)\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n }\n @case (EntryKind.Link) {\n <a\n rtElem=\"link\"\n routerLinkActive=\"rt-page-header__link--is-active\"\n [routerLink]=\"section.route\"\n [routerLinkActiveOptions]=\"{ exact: section.routerLinkActiveExact }\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n }\n @default {\n @if (section.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"'uiSectionInProgress' | rtKitLabel: translate() : { label: section.label }\">\n <button rtElem=\"link\" type=\"button\" [rtMod]=\"{ disabled: true }\" [attr.aria-disabled]=\"true\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n </button>\n </span>\n } @else {\n <button rtElem=\"link\" type=\"button\" (click)=\"onItemClick(section.id)\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n }\n </li>\n }\n <li\n rtElem=\"item\"\n #moreItem\n [rtMod]=\"{ isOverflow: !moreShown() }\"\n [attr.aria-hidden]=\"!moreShown() || null\"\n [attr.inert]=\"!moreShown() || null\">\n <rt-page-header-more [sections]=\"moreSections()\" [active]=\"moreActive()\" (itemClick)=\"onItemClick($event)\" />\n </li>\n </ul>\n </nav>\n\n <button\n rtElem=\"burger\"\n type=\"button\"\n qa-dataid=\"header-nav-burger\"\n #mobileNavPopover=\"rtPopover\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"14\"\n rtPopoverBackdropClass=\"rt-page-header-mobile-backdrop\"\n [attr.aria-label]=\"t().uiNavMenu\"\n [rtMod]=\"{ isOpen: mobileNavPopover.isOpen() }\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"mobileNavPopover.isOpen()\"\n [rtPopover]=\"mobileNavTpl\">\n <rt-icon rtElem=\"burger-icon\" name=\"bars\" size=\"md\" />\n </button>\n\n <!--\n Сжатая полоса стоит в разметке всегда, как и узкая: показывает её модификатор хоста.\n Слева стопка кругов — «ещё» поверх остальных, — дальше три слота потребителя.\n -->\n <div rtElem=\"compact\" qa-dataid=\"header-compact\">\n <div rtElem=\"compact-stack\">\n <button\n rtElem=\"compact-circle\"\n type=\"button\"\n qa-dataid=\"header-compact-more\"\n #compactNavPopover=\"rtPopover\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"10\"\n [rtMod]=\"{ more: true, isOpen: compactNavPopover.isOpen() }\"\n [attr.aria-label]=\"t().uiNavMenu\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"compactNavPopover.isOpen()\"\n [rtPopover]=\"mobileNavTpl\">\n <rt-icon name=\"ellipsis-h\" size=\"sm\" />\n </button>\n @for (section of compactSections(); track section.id; let index = $index) {\n @if (section.kind === EntryKind.Link) {\n <a\n rtElem=\"compact-circle\"\n qa-dataid=\"header-compact-section\"\n routerLinkActive=\"rt-page-header__compact-circle--is-active\"\n [style.--rt-nav-compact-index]=\"index + 1\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"section.label\"\n [routerLink]=\"section.route\"\n [routerLinkActiveOptions]=\"{ exact: section.routerLinkActiveExact }\"\n [rtTooltip]=\"section.label\">\n @if (section.icon; as icon) {\n <rt-icon size=\"sm\" [name]=\"icon\" />\n }\n @if (section.unread) {\n <span rtElem=\"compact-marker\" role=\"img\" [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n } @else {\n <button\n rtElem=\"compact-circle\"\n type=\"button\"\n qa-dataid=\"header-compact-section\"\n [rtMod]=\"{ isActive: activeSectionIds().has(section.id), disabled: section.disabled }\"\n [style.--rt-nav-compact-index]=\"index + 1\"\n [disabled]=\"section.disabled\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"section.label\"\n [rtTooltip]=\"section.label\"\n (click)=\"onCompactSectionClick(section)\">\n @if (section.icon; as icon) {\n <rt-icon size=\"sm\" [name]=\"icon\" />\n }\n @if (section.unread) {\n <span rtElem=\"compact-marker\" role=\"img\" [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n </div>\n <div rtElem=\"compact-slot\" [rtMod]=\"{ left: true }\"><ng-content select=\"[rtCompactLeft]\" /></div>\n <div rtElem=\"compact-slot\" [rtMod]=\"{ center: true }\"><ng-content select=\"[rtCompactCenter]\" /></div>\n <div rtElem=\"compact-slot\" [rtMod]=\"{ right: true }\"><ng-content select=\"[rtCompactRight]\" /></div>\n </div>\n\n <ng-template #mobileNavTpl>\n <div rtBlock=\"rt-page-header-mobile\" role=\"menu\">\n @for (section of sections(); track section.id) {\n @switch (section.kind) {\n @case (EntryKind.Panel) {\n <button\n rtElem=\"section\"\n type=\"button\"\n qa-dataid=\"header-nav-mobile-trigger\"\n [rtMod]=\"{\n isExpanded: expandedSectionIds().has(section.id),\n isActive: activeSectionIds().has(section.id),\n }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-expanded]=\"expandedSectionIds().has(section.id)\"\n (click)=\"toggleSection(section.id)\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n <span rtElem=\"caret\" aria-hidden=\"true\">\n <rt-icon name=\"chevron-up-down\" size=\"xs\" />\n </span>\n </button>\n @if (expandedSectionIds().has(section.id)) {\n <div rtElem=\"children\">\n @for (group of section.panelGroups; track group.id) {\n <div rtElem=\"group\" role=\"group\" [attr.aria-label]=\"group.label || null\">\n @if (group.label) {\n <div rtElem=\"group-title\" qa-dataid=\"header-nav-mobile-group\" [attr.data-id]=\"group.id\">\n @if (group.icon) {\n <rt-icon rtElem=\"group-icon\" size=\"xs\" [name]=\"group.icon\" />\n }\n <span rtElem=\"group-label\">{{ group.label }}</span>\n </div>\n }\n @for (entry of group.items; track entry.id) {\n @if (entry.kind === EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n routerLinkActive=\"rt-page-header-mobile__link--is-active\"\n [rtMod]=\"{ child: true }\"\n [attr.data-id]=\"entry.id\"\n [routerLink]=\"entry.route\"\n [routerLinkActiveOptions]=\"{ exact: entry.routerLinkActiveExact }\"\n (click)=\"closeNavPanels()\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n } @else if (entry.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"'uiSectionInProgress' | rtKitLabel: translate() : { label: entry.label }\">\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n [rtMod]=\"{ child: true, disabled: true }\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-disabled]=\"true\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n [rtMod]=\"{ child: true }\"\n [attr.data-id]=\"entry.id\"\n (click)=\"onMobileItemClick(entry.id)\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n </div>\n }\n </div>\n }\n }\n @case (EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n routerLinkActive=\"rt-page-header-mobile__link--is-active\"\n [attr.data-id]=\"section.id\"\n [routerLink]=\"section.route\"\n [routerLinkActiveOptions]=\"{ exact: section.routerLinkActiveExact }\"\n (click)=\"closeNavPanels()\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n }\n @default {\n @if (section.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"'uiSectionInProgress' | rtKitLabel: translate() : { label: section.label }\">\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n [rtMod]=\"{ disabled: true }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-disabled]=\"true\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n [attr.data-id]=\"section.id\"\n (click)=\"onMobileItemClick(section.id)\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n }\n }\n </div>\n </ng-template>\n\n <ng-content select=\"[rtHeaderBell]\" />\n\n @if (user(); as u) {\n @if (userMenu(); as menuTpl) {\n <!--\n Меню профиля открывается наведением, как и разделы: весь верхний\n ряд ведёт себя одинаково. Нажатие остаётся запасным путём для\n касания, а переход курсора на список языков панель переживает —\n вложенный оверлей за уход наружу не считается. На узком экране меню\n стоит на той же подложке, что меню разделов из бургера.\n -->\n <button\n rtElem=\"user\"\n type=\"button\"\n qa-dataid=\"header-user-menu\"\n #userPopover=\"rtPopover\"\n rtPopoverTrigger=\"hover\"\n rtPopoverAlign=\"end\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"14\"\n [rtPopoverBackdropClass]=\"userMenuBackdropClass()\"\n [rtMod]=\"{ isOpen: userPopover.isOpen() }\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"userPopover.isOpen()\"\n [rtPopover]=\"menuTpl\"\n (click)=\"userPopover.open()\">\n <span rtElem=\"user-avatar\" aria-hidden=\"true\">{{ userAvatar() }}</span>\n <span rtElem=\"user-name\" qa-dataid=\"header-user-name\">{{ u.name }}</span>\n <span rtElem=\"user-caret\" aria-hidden=\"true\">\n <rt-icon name=\"chevron-up-down\" size=\"xs\" />\n </span>\n </button>\n } @else {\n <button rtElem=\"user\" type=\"button\" (click)=\"onUserClick()\">\n <span rtElem=\"user-avatar\" aria-hidden=\"true\">{{ userAvatar() }}</span>\n <span rtElem=\"user-name\" qa-dataid=\"header-user-name\">{{ u.name }}</span>\n <span rtElem=\"user-caret\" aria-hidden=\"true\">\n <rt-icon name=\"chevron-up-down\" size=\"xs\" />\n </span>\n </button>\n }\n }\n</ng-container>\n"],"mappings":";;;;;;;;;;AAIA,IAAY;CAAZ,SAAY,oBAAkB;CAC1B,mBAAA,WAAA;CACA,mBAAA,UAAA;CACA,mBAAA,YAAA;AACJ,EAAA,CAJY,uBAAA,qBAAkB,CAAA,EAAA;AAyE9B,MAAM,gBAAwB;AAG9B,SAAgB,aAAa,MAAwB;CACjD,QAAQ,KAAK,WAAW,CAAA,EAAA,CAAI,SAAS,WACjC,OAAO,OAAO,SAAS,UAAkE,MAAM,KAAK,CAAC;AAE7G;AAMA,SAAgB,SAAS,MAAwB;CAC7C,OAAO,KAAK,WAAW,QAAQ,aAAa,IAAI,CAAC,CAAC,MAAM,UAAuC,MAAM,WAAW,IAAI;AACxH;AAEA,SAAgB,YAAY,MAAwB;CAChD,IAAI,aAAa,IAAI,CAAC,CAAC,SAAS,GAC5B,OAAO,mBAAmB;CAE9B,KAAK,KAAK,SAAS,QAAQ,MAAM,CAAC,KAAK,UACnC,OAAO,mBAAmB;CAG9B,OAAO,mBAAmB;AAC9B;AAEA,SAAgB,QAAQ,MAAwB;CAC5C,OAAO;EACH,IAAI,KAAK;EACT,OAAO,KAAK;EACZ,MAAM,KAAK,QAAQ;EACnB,OAAO,KAAK,SAAS;EACrB,uBAAuB,KAAK,0BAA0B;EACtD,UAAU,KAAK,aAAa;EAC5B,QAAQ,KAAK,WAAW;EACxB,MAAM,YAAY,IAAI;CACzB;AACL;AAEA,SAAS,QAAQ,OAA0B;CACvC,OAAO;EACH,IAAI,MAAM;EACV,OAAO,MAAM,SAAS;EACtB,MAAM,MAAM,QAAQ;EACpB,OAAO,MAAM,MAAM,IAAI,OAAO;CACjC;AACL;AAEA,SAAS,SAAS,QAA4B;CAC1C,OAAO;EACH,IAAI,OAAO;EACX,QAAQ,OAAO,OAAO,IAAI,OAAO;CACpC;AACL;AAGA,SAAgB,cAAc,SAAgD;CAC1E,OAAO,QAAQ,SAAS,WAA6E,OAAO,MAAM;AACtH;AAGA,SAAgB,WAAW,OAAwC;CAC/D,OAAO,MAAM,KAAK,SAAuD;EACrE,MAAM,WAAoD,KAAK,WAAW,CAAA,EAAA,CAAI,IAAI,QAAQ;EAE1F,OAAO;GACH,GAAG,QAAQ,IAAI;GACf,QAAQ,SAAS,IAAI;GACrB;GACA,aAAa,QAAQ;GACrB,YAAY,aAAa,IAAI,CAAC,CAAC,IAAI,OAAO;GAC1C,aAAa,cAAc,OAAO;GAClC,UAAU,KAAK,YAAY;EAC9B;CACL,CAAC;AACL;AAGA,SAAgB,OAAO,KAAW;CAC9B,OAAO,IAAI,MAAM,MAAM,CAAC,CAAC,MAAM;AACnC;AAEA,SAAgB,cAAc,OAAgC,MAAY;CACtE,IAAI,MAAM,SAAS,mBAAmB,MAClC,OAAO;CAGX,OAAO,MAAM,wBAAwB,SAAS,MAAM,QAAQ,KAAK,WAAW,MAAM,KAAK;AAC3F;AAMA,SAAgB,kBACZ,UACA,OAAa;CAEb,OAAO,SAAS,QAAQ,YAAgD,QAAQ,SAAS,IAAI,CAAC,CAAC,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AAC9H;AAOA,SAAgB,QAAQ,mBAA2B,gBAAuB;CACtE,OAAO,kBAAkB,oBAAoB;AACjD;AAOA,SAAgB,iBAAiB,UAAoD,KAAW;CAC5F,MAAM,OAAe,OAAO,GAAG;CAC/B,MAAM,sBAAmB,IAAI,IAAG;CAChC,KAAK,MAAM,WAAW,UAClB,IAAI,QAAQ,WAAW,MAAM,UAA4C,cAAc,OAAO,IAAI,CAAC,GAC/F,IAAI,IAAI,QAAQ,EAAE;CAI1B,OAAO;AACX;AAEA,SAAS,KAAK,MAA2B;CACrC,OAAO,KAAK;AAChB;AAGA,SAAS,WAAW,QAA+B,KAAW;CAG1D,OAFsB,OAAO,QAAQ,KAAa,UAA0B,MAAM,OAAO,CAElF,IAAQ,MAAM,KAAK,IAAI,GAAG,OAAO,SAAS,CAAC;AACtD;AAQA,SAAgB,OAAO,OAA6B;CAChD,MAAM,EAAE,OAAO,WAAW,WAAW,QAAQ;CAC7C,MAAM,QAAgB,YAAY;CAClC,IACI,WACI,MAAM,KAAK,SAAwC,KAAK,KAAK,GAC7D,GAAG,KACF,OAEL,OAAO;EAAE,KAAK,MAAM,IAAI,IAAI;EAAG,MAAM,CAAA;CAAE;CAG3C,MAAM,YAAmC,MAAM,KAAK,MAAM,KAAI,CAAE,CAAC,CAAC,MAC7D,GAAW,MAAsB,MAAM,EAAE,CAAC,WAAW,MAAM,EAAE,CAAC,YAAY,IAAI,CAAC;CAEpF,MAAM,OAAoB,IAAI,IAAY,MAAM,KAAI,CAAE;CACtD,KAAK,MAAM,SAAS,WAAW;EAE3B,IAAI,WAAW,CAAC,GAD0B,MAAM,KAAK,OAAO,OAAuB,MAAM,GAAG,CAAC,KAC1E,GAAY,SAAS,GAAG,GAAG,KAAK,OAC/C;EAEJ,KAAK,OAAO,KAAK;CACrB;CAEA,OAAO;EACH,KAAK,MAAM,KAAK,MAAM,KAAI,CAAE,CAAC,CACxB,QAAQ,UAA2B,KAAK,IAAI,KAAK,CAAC,CAAC,CACnD,KAAK,UAA0B,MAAM,MAAM,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,MAAM,KAAI,CAAE,CAAC,CACzB,QAAQ,UAA2B,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CACpD,KAAK,UAA0B,MAAM,MAAM,CAAC,EAAE;CACtD;AACL;AAGA,SAAgB,gBAAgB,SAAoC,MAAY;CAC5E,OAAO,cAAc,SAAS,IAAI,KAAK,QAAQ,WAAW,MAAM,UAA4C,cAAc,OAAO,IAAI,CAAC;AAC1I;AAGA,SAAgB,iBAAiB,UAAoD,KAAW;CAC5F,MAAM,OAAe,OAAO,GAAG;CAE/B,OAAO,SAAS,MAAM,YAAgD,gBAAgB,SAAS,IAAI,CAAC;AACxG;ACjPA,MAAMA,cAAoB;AAqC1B,IAAa,4BAAb,MAAa,0BAAyB;CAxBtC,cAAA;EAyBa,KAAA,aAAuC,OAAO,iBAAiB;EAGrD,KAAA,YAAsC,KAAK;EAE3C,KAAA,IAA4B,OAAO,aAAa;EAEhD,KAAA,YAAuC;EAGvC,KAAA,SAA0B,eACzC,KAAK,SAAQ,CAAE,CAAC,MAAM,YAAgD,QAAQ,MAAM,GACvF,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;EAGe,KAAA,WAAkE,MAAgD,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAGrH,KAAA,SAA0D,MAA6B,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,SAAA,+BAAA,CAAA;GACxG,WAAW;EAAgB,CAAA;EAIf,KAAA,YAAsC,OAAM;CAK/D;CA5BY;CAyBC,YAAY,IAAU;EAC5B,KAAK,UAAU,KAAK,EAAE;CAC1B;CA5BS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAyB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAzB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAyB,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,QAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,SAAA,EAAA,WAAA,YAAA;GAAA,MAAA,EAAA,gBAAA,sBAAA;GAAA,UAAA;GAAA,UC/DtC;GA8KA,QAAA,CAAA,uFAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MD9HQ;KAAU,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACV;KAAgB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,gBAAA;KAAA,UAAA,CAAA,kBAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAGhB;KAAe,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACf;KAAkB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,mBAAA,iBAAA;KAAA,UAAA,CAAA,WAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAClB;KAAkB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,UAAA,CAAA,WAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAClB;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACb;KAAY,UAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAXZ;KAAc,MAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAiBT,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAyB,YAAA,CAAA;EAxBrC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAqB,iBAGd,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IACL;IAEA;IACA;IAGA;IACA;IACA;IACA;IACA;IACA;GACH;GAAA,MACK,EACF,OAAOA,YACV;GAAA,UAAA;GAAA,QAAA,CAAA,uFAAA;EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;AETL,MAAM,YAAoB;AAG1B,MAAM,8BAAsC;AAmD5C,IAAa,wBAAb,MAAa,sBAAqB;CACrB;CAEA;CAEA;CAIA;CAMA;CAEA;CAGT;CAGS;CAaA;CAQA;CAEA;CAgHT,cAAA;EA7JS,KAAA,UAAkB,OAAO,MAAM;EAE/B,KAAA,cAA0B,OAAO,UAAU;EAE3C,KAAA,QAAiC,OAAgC,UAAU;EAI3E,KAAA,UAAsC,OAAO,MAAM;EAMnD,KAAA,SAAkC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;EAExD,KAAA,eAA+B,WAAW,WAAW;EAG9D,KAAA,YAAmC;EAG1B,KAAA,eAAoD,uBAA4B,IAAI,IAAG,GAAU;GAAA,GAAA,YAAA,EAAA,WAAA,eAAA,+BAAA,CAAA;GACtG,QAAQ,GAAwB,MAC5B,EAAE,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,OAAwB,EAAE,IAAI,EAAE,CAAC;EAAC,CAAA;EAG1D,KAAA,SAAsD,UAAmC,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;EAE/F,KAAA,UAAuD,UAAmC,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAEjG,KAAA,cAA2D,UAAmC,YAAW,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAInH,KAAA,cAA8B,SACnC,KAAK,QAAQ,OAAO,KAChB,QAAQ,MAAuC,aAAa,aAAa,GACzE,UAAkB,KAAK,QAAQ,GAAG,CAAC,GAEvC,EAAE,cAAc,KAAK,QAAQ,IAAG,CAAE;EAG7B,KAAA,eAAmC,OAAO,kBAAkB;EAE5D,KAAA,aAAuC,OAAO,iBAAiB;EAGrD,KAAA,YAAsC,KAAK;EAE3C,KAAA,IAA4B,OAAO,aAAa;EAEhD,KAAA,sBAA8D,UAAU,oBAAkB;GAAA,GAAA,YAAA,EAAA,WAAA,sBAAA,+BAAA,CAAA;GACzG,MAAM;EAAkB,CAAA;EAIT,KAAA,uBAA+D,UAAU,qBAAmB;GAAA,GAAA,YAAA,EAAA,WAAA,uBAAA,+BAAA,CAAA;GAC3G,MAAM;EAAkB,CAAA;EAIT,KAAA,UAA2B,eAAwB,KAAK,cAAa,KAAM,KAAK,OAAM,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAGzF,KAAA,kBAAoE,eACnC,kBAAkB,KAAK,SAAQ,GAAI,KAAK,oBAAmB,CAAE,GAChH,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;EAGkB,KAAA,cAA2C,KAAK,aAAa,WAAU;EAGvE,KAAA,eAAiE,eAE5E,KAAK,SAAQ,CAAE,CAAC,QAAQ,YAAgD,KAAK,YAAW,CAAE,CAAC,IAAI,QAAQ,EAAE,CAAC,GACjH,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAGkB,KAAA,YAA6B,eAAwB,KAAK,aAAY,CAAE,CAAC,SAAS,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAGpF,KAAA,aAA8B,eAAwB,iBAAiB,KAAK,aAAY,GAAI,KAAK,YAAW,CAAE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;EAGhH,KAAA,WAA6D,eAC5E,WAAW,KAAK,MAAK,CAAE,GAC1B,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAMkB,KAAA,mBAAgD,eAC/D,iBAAiB,KAAK,SAAQ,GAAI,KAAK,YAAW,CAAE,GACvD,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;EAEkB,KAAA,aAA6B,eAAsB;GAClE,MAAM,IAA+B,KAAK,KAAI;GAC9C,IAAI,CAAC,GACD,OAAO;GAEX,IAAI,EAAE,UAAU,EAAE,OAAO,SAAS,GAC9B,OAAO,EAAE,OAAO,OAAO,CAAC,CAAC,CAAC,YAAW;GAEzC,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,YAAW;EACvC,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;EAGiB,KAAA,WAA4B,KAAK,aAAa;EAM9C,KAAA,wBAAwC,eAAwB,KAAK,SAAQ,IAAK,8BAA8B,IAAI,GAAA,YAAA,CAAA,EAAA,WAAA,wBAAA,CAAA,+BAAA,CAAA,CAAA;EAOpH,KAAA,qBAA0D,uBAA4B,IAAI,IAAG,GAAW,GAAA,YAAA,CAAA,EAAA,WAAA,qBAAA,CAAA,+BAAA,CAAA,CAAA;EAExG,KAAA,YAAuC;EAE1C,KAAA,QAAwD,MAAyC,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAEpG,KAAA,OAA+C,MAAiC,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAErF,KAAA,YAAiC,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAElD,KAAA,WAAqD,MAAmC,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAG7F,KAAA,YAAiC,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAMlD,KAAA,gBAAiE,MAA6B,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,gBAAA,+BAAA,CAAA;GAC/G,WAAW;EAAgB,CAAA;EAIf,KAAA,sBAAqE,MAA2B,GAAC;GAAA,GAAA,YAAA,EAAA,WAAA,sBAAA,+BAAA,CAAA;GAC7G,WAAW;EAAe,CAAA;EAId,KAAA,eAA+B,eAAuB,KAAK,UAAS,KAAM,KAAK,aAAY,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAE9F,KAAA,YAAsC,OAAM;EAE5C,KAAA,YAAoC,OAAM;EAKtD,aAAkB;GACd,IAAI,CAAC,KAAK,SAAQ,GACd,KAAK,oBAAmB,CAAE,EAAE,MAAK;EAEzC,CAAC;EAED,sBAA4B,KAAK,cAAa,CAAE;EAKhD,wBAA6B;GACzB,KAAK,SAAQ;GACb,KAAK,EAAC;GACN,KAAK,UAAS;GACd,KAAK,YAAW;EACpB,CAAC;EAED,KAAK,YAAY,gBAAsB,KAAK,WAAW,WAAU,CAAE;CACvE;CAGA,YAAS;EACL,MAAM,MAA+B,KAAK,OAAM,CAAE,EAAE;EACpD,MAAM,OAAgC,KAAK,QAAO,CAAE,EAAE;EACtD,IAAI,QAAQ,UAAa,SAAS,UAAa,EAAE,oBAAoB,KAAK,UACtE;EAEJ,KAAK,WAAW,WAAU;EAC1B,KAAK,YAAY,IAAI,KAAK,QAAQ,qBAA2B,KAAK,YAAW,CAAE;EAC/E,KAAK,UAAU,QAAQ,GAAG;EAC1B,MAAM,KAAK,KAAK,QAAQ,CAAC,CAAC,SAAS,SAAwB,KAAK,WAAW,QAAQ,IAAI,CAAC;CAC5F;CAOA,cAAW;EACP,MAAM,MAA+B,KAAK,OAAM,CAAE,EAAE;EACpD,MAAM,OAAgC,KAAK,QAAO,CAAE,EAAE;EACtD,MAAM,WAAoC,KAAK,YAAW,CAAE,EAAE;EAC9D,IAAI,QAAQ,UAAa,SAAS,UAAa,aAAa,QACxD;EAEJ,MAAM,YAAoB,IAAI,sBAAqB,CAAE,CAAC;EACtD,IAAI,aAAa,GACb;EAEJ,MAAM,yBAA8B,IAAI,IAAG;EAC3C,KAAK,iBAA8B,iCAA+B,CAAC,CAAC,SAAS,SAA2B;GACpG,OAAO,IAAI,KAAK,QAAQ,SAAS,IAAI,KAAK,sBAAqB,CAAE,CAAC,KAAK;EAC3E,CAAC;EACD,MAAM,MAA+B,OAAO;GACxC,OAAO,KAAK,SAAQ,CAAE,CAAC,KAAK,aAA+D;IACvF,IAAI,QAAQ;IACZ,OAAO,OAAO,IAAI,QAAQ,EAAE,KAAK;IACjC,UAAU,QAAQ;GACrB,EAAC;GACF,WAAW,SAAS,sBAAqB,CAAE,CAAC;GAC5C,KAAK,WAAW,KAAK,QAAQ,iBAAiB,IAAI,CAAC,CAAC,SAAS,KAAK;GAClE;EACH,CAAA;EACD,KAAK,aAAa,IAAI,IAAI,IAAY,IAAI,IAAI,CAAC;CACnD;CAOA,gBAAa;EACT,MAAM,WAAiC,IAAI,KAAK,QAAQ,sBACnD,YAA8C;GAC3C,MAAM,QAA+C,QAAQ,GAAG,EAAE;GAClE,IAAI,UAAU,QACV,KAAK,OAAO,IAAI,QAAQ,MAAM,mBAAmB,MAAM,cAAc,CAAC;EAE9E,GACA,EAAE,WAAW,CAAC,GAAG,CAAC,EAAC,CAAE;EAEzB,SAAS,QAAQ,KAAK,MAAM,aAAa;EACzC,KAAK,YAAY,gBAAsB,SAAS,WAAU,CAAE;CAChE;CAGU,iBAAc;EACpB,KAAK,oBAAmB,CAAE,EAAE,MAAK;EACjC,KAAK,qBAAoB,CAAE,EAAE,MAAK;CACtC;CAGU,sBAAsB,SAAkC;EAC9D,IAAI,QAAQ,SAAS,mBAAmB,OAAO;GAC3C,KAAK,qBAAoB,CAAE,EAAE,KAAI;GACjC;EACJ;EACA,KAAK,UAAU,KAAK,QAAQ,EAAE;CAClC;CAEU,YAAY,IAAU;EAC5B,KAAK,UAAU,KAAK,EAAE;CAC1B;CAEU,cAAW;EACjB,KAAK,UAAU,KAAI;CACvB;CAGU,cAAc,IAAU;EAC9B,KAAK,mBAAmB,QAAQ,SAAkD;GAC9E,MAAM,OAAoB,IAAI,IAAY,IAAI;GAC9C,IAAI,KAAK,IAAI,EAAE,GACX,KAAK,OAAO,EAAE;QAEd,KAAK,IAAI,EAAE;GAEf,OAAO;EACX,CAAC;CACL;CAGU,kBAAkB,IAAU;EAClC,KAAK,UAAU,KAAK,EAAE;EACtB,KAAK,eAAc;CACvB;CA/RS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAqB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAArB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAqB,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,WAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,WAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,eAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,qBAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,SAAA;IAAA,WAAA;IAAA,WAAA;GAAA;GAAA,MAAA;IAAA,YAAA;KAAA,gCAAA;KAAA,oCAAA;IAAA;IAAA,gBAAA;GAAA;GAAA,aAAA;IAAA;KAAA,cAAA;KAAA,OAAA;KAAA,WAAA,CAAA,KAAA;KAAA,aAAA;KAAA,UAAA;IAAA;IAAA;KAAA,cAAA;KAAA,OAAA;KAAA,WAAA,CAAA,MAAA;KAAA,aAAA;KAAA,UAAA;IAAA;IAAA;KAAA,cAAA;KAAA,OAAA;KAAA,WAAA,CAAA,UAAA;KAAA,aAAA;KAAA,UAAA;IAAA;IAAA;KAAA,cAAA;KAAA,OAAA;KAAA,WAAA,CAAA,kBAAA;KAAA,aAAA;KAAA,MAsDpB;KAAkB,UAAA;IAAA;IAAA;KAAA,cAAA;KAAA,OAAA;KAAA,WAAA,CAAA,mBAAA;KAAA,aAAA;KAAA,MAKlB;KAAkB,UAAA;IAAA;GAAA;GAAA,UAAA;GAAA,UCrKhC;GA8eA,QAAA;IAAA;IAAA;IAAA;IAAA;GAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MDtZQ;KAAU,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACV;KAAgB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,gBAAA;KAAA,UAAA,CAAA,kBAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAGhB;KAAe,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACf;KAAkB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,mBAAA,iBAAA;KAAA,UAAA,CAAA,WAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAClB;KAAkB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,UAAA,CAAA,WAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAClB;KAAyB,UAAA;KAAA,QAAA,CAAA,YAAA,QAAA;KAAA,SAAA,CAAA,WAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACzB;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACb;KAAY,UAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAZZ;KAAc,MAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAoBT,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAqB,YAAA,CAAA;EAnCjC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAgB,iBAWT,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IACL;IAEA;IACA;IAGA;IACA;IACA;IACA;IACA;IACA;IACA;GACH;GAAA,MACK;IACF,OAAO;IACP,kCAAkC;IAClC,sCAAsC;GACzC;GAAA,UAAA;GAAA,QAAA;IAAA;IAAA;IAAA;IAAA;GAAA;EAAA,CAAA;CA8B2G,CAAA;CAAA,sBAAA,CAAA;CAAA,gBAAA;EAAA,QAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,OAAK,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAEJ,QAAM,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,aAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAEF,YAAU,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,qBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAqBhC,oBAAkB;IACzG,MAAM;IACT,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,sBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAG2F,qBAAmB;IAC3G,MAAM;IACT,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,MAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,UAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,eAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,qBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,WAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,WAAA;EAAA,CAAA;CAAA;AAAA,CAAA"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-page-header.mjs","names":["BEM_BLOCK","BEM_BLOCK","BEM_BLOCK","BEM_BLOCK","BEM_BLOCK","BEM_BLOCK","BEM_BLOCK"],"sources":["../../../projects/ui-kit-v2/src/lib/components/page-header/rt-page-header.logic.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/more/rt-page-header-more.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/more/rt-page-header-more.component.html","../../../projects/ui-kit-v2/src/lib/components/page-header/rail/rt-page-user.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/rail/rt-page-user.component.html","../../../projects/ui-kit-v2/src/lib/components/page-header/rail/rt-page-actions.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/rail/rt-page-actions.component.html","../../../projects/ui-kit-v2/src/lib/components/page-header/rail/rt-page-phone-menu.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/rail/rt-page-phone-menu.component.html","../../../projects/ui-kit-v2/src/lib/components/page-header/rail/rt-page-rail.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/rail/rt-page-rail.component.html","../../../projects/ui-kit-v2/src/lib/components/page-header/user/rt-page-header-user.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/user/rt-page-header-user.component.html","../../../projects/ui-kit-v2/src/lib/components/page-header/rt-page-header.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/rt-page-header.component.html","../../../projects/ui-kit-v2/src/lib/components/page-header/bar/rt-page-bar-slots.directive.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/bar/rt-page-bar.logic.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/bar/rt-page-bar.component.ts","../../../projects/ui-kit-v2/src/lib/components/page-header/bar/rt-page-bar.component.html"],"sourcesContent":["import { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { IRtPageHeader } from './rt-page-header.model';\n\n/** Чем пункт отрисуется: панелью, ссылкой или кнопкой. */\nexport enum ERtPageHeaderEntry {\n Panel = 'panel',\n Link = 'link',\n Button = 'button',\n}\n\nexport namespace IRtPageHeaderView {\n /** Пункт, готовый к отрисовке: форма решена заранее, шаблон её не выводит. */\n export interface Entry {\n readonly id: string;\n readonly label: string;\n readonly icon: IRtIcon.Name | null;\n readonly route: string;\n readonly routerLinkActiveExact: boolean;\n readonly disabled: boolean;\n readonly unread: boolean;\n readonly kind: ERtPageHeaderEntry;\n }\n\n export interface Group {\n readonly id: string;\n readonly label: string;\n readonly icon: IRtIcon.Name | null;\n readonly items: ReadonlyArray<Entry>;\n }\n\n export interface Column {\n readonly id: string;\n readonly groups: ReadonlyArray<Group>;\n }\n\n export interface Section extends Entry {\n readonly columns: ReadonlyArray<Column>;\n readonly columnCount: number;\n /** Все пункты панели одним списком: подсветка раздела и сведение маркера. */\n readonly panelItems: ReadonlyArray<Entry>;\n /** Группы всех колонок подряд: на узком экране колонок нет, а группы есть. */\n readonly panelGroups: ReadonlyArray<Group>;\n /** Очередь ухода в «Ещё»: меньшее число уходит раньше. */\n readonly priority: number;\n }\n}\n\nexport namespace IRtPageHeaderFit {\n /** Раздел верхнего ряда с замеренной шириной и важностью. */\n export interface Slot {\n readonly id: string;\n readonly width: number;\n readonly priority: number;\n }\n\n export interface Input {\n /** Разделы в порядке списка. */\n readonly slots: ReadonlyArray<Slot>;\n /** Ширина пункта «Ещё». */\n readonly moreWidth: number;\n /** Ширина, которую ряд может занять. */\n readonly available: number;\n /** Промежуток между соседними пунктами ряда. */\n readonly gap: number;\n }\n\n /** Раскладка ряда: оба списка идут в порядке исходного списка. */\n export interface Result {\n readonly row: ReadonlyArray<string>;\n readonly more: ReadonlyArray<string>;\n }\n}\n\n/**\n * Запас на дробные пиксели замера: сумма округлённых браузером ширин расходится с шириной ряда на\n * доли пикселя, и без запаса последний раздел уходил бы в «Ещё», хотя на глаз помещается.\n */\nconst FIT_TOLERANCE: number = 0.5;\n\n/** Пункты панели одним списком — колонки и группы для этого раскрываются. */\nexport function panelItemsOf(item: IRtPageHeader.Item): ReadonlyArray<IRtPageHeader.Item> {\n return (item.columns ?? []).flatMap((column: IRtPageHeader.Column): ReadonlyArray<IRtPageHeader.Item> =>\n column.groups.flatMap((group: IRtPageHeader.Group): ReadonlyArray<IRtPageHeader.Item> => group.items)\n );\n}\n\n/**\n * Маркер раздела. Пункты панели свёрнуты, и непросмотренное внутри видно только\n * по точке у самого раздела.\n */\nexport function unreadOf(item: IRtPageHeader.Item): boolean {\n return item.unread === true || panelItemsOf(item).some((entry: IRtPageHeader.Item): boolean => entry.unread === true);\n}\n\nexport function entryKindOf(item: IRtPageHeader.Item): ERtPageHeaderEntry {\n if (panelItemsOf(item).length > 0) {\n return ERtPageHeaderEntry.Panel;\n }\n if ((item.route ?? '') !== '' && !item.disabled) {\n return ERtPageHeaderEntry.Link;\n }\n\n return ERtPageHeaderEntry.Button;\n}\n\nexport function toEntry(item: IRtPageHeader.Item): IRtPageHeaderView.Entry {\n return {\n id: item.id,\n label: item.label,\n icon: item.icon ?? null,\n route: item.route ?? '',\n routerLinkActiveExact: item.routerLinkActiveExact === true,\n disabled: item.disabled === true,\n unread: item.unread === true,\n kind: entryKindOf(item),\n };\n}\n\nfunction toGroup(group: IRtPageHeader.Group): IRtPageHeaderView.Group {\n return {\n id: group.id,\n label: group.label ?? '',\n icon: group.icon ?? null,\n items: group.items.map(toEntry),\n };\n}\n\nfunction toColumn(column: IRtPageHeader.Column): IRtPageHeaderView.Column {\n return {\n id: column.id,\n groups: column.groups.map(toGroup),\n };\n}\n\n/** Группы всех колонок одним списком — узкий экран раскладывает панель без колонок. */\nexport function panelGroupsOf(columns: ReadonlyArray<IRtPageHeaderView.Column>): ReadonlyArray<IRtPageHeaderView.Group> {\n return columns.flatMap((column: IRtPageHeaderView.Column): ReadonlyArray<IRtPageHeaderView.Group> => column.groups);\n}\n\n/** Разделы верхнего ряда вместе с раскладкой их панелей. */\nexport function toSections(items: ReadonlyArray<IRtPageHeader.Item>): ReadonlyArray<IRtPageHeaderView.Section> {\n return items.map((item: IRtPageHeader.Item): IRtPageHeaderView.Section => {\n const columns: ReadonlyArray<IRtPageHeaderView.Column> = (item.columns ?? []).map(toColumn);\n\n return {\n ...toEntry(item),\n unread: unreadOf(item),\n columns,\n columnCount: columns.length,\n panelItems: panelItemsOf(item).map(toEntry),\n panelGroups: panelGroupsOf(columns),\n priority: item.priority ?? 0,\n };\n });\n}\n\n/** Адрес без строки запроса и якоря — подсветка считается по пути. */\nexport function pathOf(url: string): string {\n return url.split(/[?#]/)[0] ?? '';\n}\n\nexport function isEntryActive(entry: IRtPageHeaderView.Entry, path: string): boolean {\n if (entry.kind !== ERtPageHeaderEntry.Link) {\n return false;\n }\n\n return entry.routerLinkActiveExact ? path === entry.route : path.startsWith(entry.route);\n}\n\n/**\n * Разделы для кругов сжатой полосы: первые `count` из тех, у кого есть иконка. Раздел без\n * иконки в круг не попадает — показать в нём нечего, и он остаётся под кнопкой «ещё».\n */\nexport function compactSectionsOf(\n sections: ReadonlyArray<IRtPageHeaderView.Section>,\n count: number\n): ReadonlyArray<IRtPageHeaderView.Section> {\n return sections.filter((section: IRtPageHeaderView.Section): boolean => section.icon !== null).slice(0, Math.max(0, count));\n}\n\n/**\n * Прилипла ли шапка: липкий узел стоит на пиксель выше края прокрутки и, прилипнув, теряет этот\n * пиксель из видимой области — наблюдатель пересечения отдаёт долю меньше единицы. Узел, ушедший\n * из области целиком, прилипшим не считается: его не видно вовсе.\n */\nexport function isStuck(intersectionRatio: number, isIntersecting: boolean): boolean {\n return isIntersecting && intersectionRatio < 1;\n}\n\n/**\n * Разделы, у которых активен хоть один пункт панели. Обход идёт по раскрытому\n * списку пунктов: своего адреса у раздела с панелью нет, и подсветить его больше\n * нечем.\n */\nexport function activeSectionIds(sections: ReadonlyArray<IRtPageHeaderView.Section>, url: string): ReadonlySet<string> {\n const path: string = pathOf(url);\n const ids: Set<string> = new Set<string>();\n for (const section of sections) {\n if (section.panelItems.some((entry: IRtPageHeaderView.Entry): boolean => isEntryActive(entry, path))) {\n ids.add(section.id);\n }\n }\n\n return ids;\n}\n\nfunction idOf(slot: IRtPageHeaderFit.Slot): string {\n return slot.id;\n}\n\n/** Ширина ряда из пунктов заданной ширины с промежутками между соседями. */\nfunction rowWidthOf(widths: ReadonlyArray<number>, gap: number): number {\n const total: number = widths.reduce((sum: number, width: number): number => sum + width, 0);\n\n return total + gap * Math.max(0, widths.length - 1);\n}\n\n/**\n * Какие разделы стоят в ряду, а какие уходят в «Ещё». Всё помещается — «Ещё» нет. Иначе разделы\n * уходят по очереди важности, пока оставшиеся вместе с «Ещё» не встанут в доступную ширину:\n * меньшая важность уходит раньше, а при равной — стоящий дальше от начала списка. Порядок\n * оставшихся не меняется.\n */\nexport function fitRow(input: IRtPageHeaderFit.Input): IRtPageHeaderFit.Result {\n const { slots, moreWidth, available, gap } = input;\n const limit: number = available + FIT_TOLERANCE;\n if (\n rowWidthOf(\n slots.map((slot: IRtPageHeaderFit.Slot): number => slot.width),\n gap\n ) <= limit\n ) {\n return { row: slots.map(idOf), more: [] };\n }\n\n const departure: ReadonlyArray<number> = Array.from(slots.keys()).sort(\n (a: number, b: number): number => slots[a].priority - slots[b].priority || b - a\n );\n const kept: Set<number> = new Set<number>(slots.keys());\n for (const index of departure) {\n const keptWidths: ReadonlyArray<number> = Array.from(kept, (at: number): number => slots[at].width);\n if (rowWidthOf([...keptWidths, moreWidth], gap) <= limit) {\n break;\n }\n kept.delete(index);\n }\n\n return {\n row: Array.from(slots.keys())\n .filter((index: number): boolean => kept.has(index))\n .map((index: number): string => slots[index].id),\n more: Array.from(slots.keys())\n .filter((index: number): boolean => !kept.has(index))\n .map((index: number): string => slots[index].id),\n };\n}\n\n/** Активен ли раздел: своим адресом или адресом пункта своей панели. */\nexport function isSectionActive(section: IRtPageHeaderView.Section, path: string): boolean {\n return isEntryActive(section, path) || section.panelItems.some((entry: IRtPageHeaderView.Entry): boolean => isEntryActive(entry, path));\n}\n\n/** Есть ли среди разделов активный — по нему «Ещё» подсвечивается, как выбранный пункт ряда. */\nexport function hasActiveSection(sections: ReadonlyArray<IRtPageHeaderView.Section>, url: string): boolean {\n const path: string = pathOf(url);\n\n return sections.some((section: IRtPageHeaderView.Section): boolean => isSectionActive(section, path));\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, RT_KIT_TRANSLATOR, RtKitLabelPipe, TRtKitLabelMap, TRtKitTranslator } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { ERtPageHeaderEntry, IRtPageHeaderView } from '../rt-page-header.logic';\n\nconst BEM_BLOCK: string = 'rt-page-header-more';\n\n/**\n * Пункт «Ещё» в конце верхнего ряда `rt-page-header` и его панель: разделы, которым не хватило\n * ширины ряда.\n *\n * Кнопка носит вид пункта ряда — элементы блока `rt-page-header`, — и подсвечивается так же, как\n * выбранный раздел, когда выбранный раздел ушёл сюда. Панель открывается тем же поповером, что и\n * панели разделов, по наведению и по нажатию. Раздел с панелью показан в ней заголовком и пунктами\n * своих групп, как в меню узкого экрана, и берёт его блок с модификатором `more`.\n *\n * Какие разделы ушли, решает шапка: здесь ничего не меряется.\n */\n@Component({\n selector: 'rt-page-header-more',\n templateUrl: './rt-page-header-more.component.html',\n styleUrl: './rt-page-header-more.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n RtKitLabelPipe,\n // Angular\n RouterLink,\n RouterLinkActive,\n\n // standalone components / directives\n RtIconComponent,\n RtPopoverDirective,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtPageHeaderMoreComponent {\n readonly #translate: Signal<TRtKitTranslator> = inject(RT_KIT_TRANSLATOR);\n\n /** Переводчик для чистого пайпа подписи: шаблон отдаёт его вторым доводом. */\n protected readonly translate: Signal<TRtKitTranslator> = this.#translate;\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly EntryKind: typeof ERtPageHeaderEntry = ERtPageHeaderEntry;\n\n /** Точка у «Ещё»: непросмотренное ушедшего раздела иначе видно только в открытой панели. */\n protected readonly unread: Signal<boolean> = computed((): boolean =>\n this.sections().some((section: IRtPageHeaderView.Section): boolean => section.unread)\n );\n\n /** Разделы, ушедшие из ряда, в порядке списка. */\n public readonly sections: InputSignal<ReadonlyArray<IRtPageHeaderView.Section>> = input<ReadonlyArray<IRtPageHeaderView.Section>>([]);\n\n /** Выбранный раздел среди ушедших: «Ещё» подсвечивается, как выбранный пункт ряда. */\n public readonly active: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Нажат пункт без адреса — приходит его идентификатор. */\n public readonly itemClick: OutputEmitterRef<string> = output<string>();\n\n protected onItemClick(id: string): void {\n this.itemClick.emit(id);\n }\n}\n","<!--\n Кнопка берёт элементы блока шапки, а не свои: «Ещё» стоит в том же ряду и выглядит как его пункт,\n а второй набор тех же правил разошёлся бы с первым при первой правке.\n-->\n<ng-container rtBlock=\"rt-page-header\">\n <button\n rtElem=\"link\"\n type=\"button\"\n qa-dataid=\"header-nav-more\"\n #morePopover=\"rtPopover\"\n rtPopoverTrigger=\"hover\"\n rtPopoverAlign=\"end\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"14\"\n [rtMod]=\"{ isActive: active(), isOpen: morePopover.isOpen() }\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"morePopover.isOpen()\"\n [rtPopover]=\"moreTpl\"\n (click)=\"morePopover.open()\">\n <span rtElem=\"label\">{{ t().uiNavMore }}</span>\n @if (unread()) {\n <span rtElem=\"marker\" role=\"img\" qa-dataid=\"header-nav-marker\" data-id=\"more\" [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n <span rtElem=\"caret\" aria-hidden=\"true\">\n <rt-icon name=\"chevron-up-down\" size=\"xs\" />\n </span>\n </button>\n</ng-container>\n\n<!--\n Панель «Ещё» — та же разметка, что меню узкого экрана, без аккордеона: раздел с панелью стоит\n заголовком, а пункты его групп идут под ним сразу.\n-->\n<ng-template #moreTpl>\n <div rtBlock=\"rt-page-header-mobile\" role=\"menu\" qa-dataid=\"header-nav-more-list\" [rtMod]=\"{ more: true }\">\n @for (section of sections(); track section.id) {\n @switch (section.kind) {\n @case (EntryKind.Panel) {\n <div rtElem=\"heading\" qa-dataid=\"header-nav-more-section\" [attr.data-id]=\"section.id\">\n <span rtElem=\"label\">{{ section.label }}</span>\n </div>\n <div rtElem=\"children\">\n @for (group of section.panelGroups; track group.id) {\n <div rtElem=\"group\" role=\"group\" [attr.aria-label]=\"group.label || null\">\n @if (group.label) {\n <div rtElem=\"group-title\" qa-dataid=\"header-nav-more-group\" [attr.data-id]=\"group.id\">\n <span rtElem=\"group-label\">{{ group.label }}</span>\n </div>\n }\n @for (entry of group.items; track entry.id) {\n @if (entry.kind === EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n routerLinkActive=\"rt-page-header-mobile__link--is-active\"\n [rtMod]=\"{ child: true }\"\n [attr.data-id]=\"entry.id\"\n [routerLink]=\"entry.route\"\n [routerLinkActiveOptions]=\"{ exact: entry.routerLinkActiveExact }\"\n (click)=\"morePopover.close()\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n } @else if (entry.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"'uiSectionInProgress' | rtKitLabel: translate() : { label: entry.label }\">\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n [rtMod]=\"{ child: true, disabled: true }\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-disabled]=\"true\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n [rtMod]=\"{ child: true }\"\n [attr.data-id]=\"entry.id\"\n (click)=\"onItemClick(entry.id); morePopover.close()\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n </div>\n }\n </div>\n }\n @case (EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n routerLinkActive=\"rt-page-header-mobile__link--is-active\"\n [attr.data-id]=\"section.id\"\n [routerLink]=\"section.route\"\n [routerLinkActiveOptions]=\"{ exact: section.routerLinkActiveExact }\"\n (click)=\"morePopover.close()\">\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n }\n @default {\n @if (section.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"'uiSectionInProgress' | rtKitLabel: translate() : { label: section.label }\">\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n [rtMod]=\"{ disabled: true }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-disabled]=\"true\">\n <span rtElem=\"label\">{{ section.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-more-item\"\n [attr.data-id]=\"section.id\"\n (click)=\"onItemClick(section.id); morePopover.close()\">\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n }\n }\n </div>\n</ng-template>\n","import { ConnectedPosition } from '@angular/cdk/overlay';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n computed,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { IRtPageHeader } from '../rt-page-header.model';\n\nconst BEM_BLOCK: string = 'rt-page-user';\n\n/** Меню профиля из рейки: выше аватара, в 8 от рейки и в 8 от низа окна. */\nconst RAIL_POSITIONS: readonly ConnectedPosition[] = [\n { originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'bottom', offsetX: 8, offsetY: -8 },\n];\n\n/** Аватар профиля: стоит в подвале рейки и в ряду с вкладками. Меню задаёт приложение. */\n@Component({\n selector: 'rt-page-user',\n templateUrl: './rt-page-user.component.html',\n styleUrl: './rt-page-user.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [NgTemplateOutlet, RtIconComponent, RtPopoverDirective, BlockDirective, ElemDirective],\n host: { class: BEM_BLOCK },\n})\nexport class RtPageUserComponent {\n protected readonly letter: Signal<string> = computed((): string => {\n const user: IRtPageHeader.User = this.user();\n return (user.avatar || user.name).charAt(0).toUpperCase();\n });\n\n protected readonly positions: Signal<readonly ConnectedPosition[] | null> = computed((): readonly ConnectedPosition[] | null =>\n this.placement() === 'rail' ? RAIL_POSITIONS : null\n );\n\n public readonly user: InputSignal<IRtPageHeader.User> = input.required<IRtPageHeader.User>();\n\n public readonly userMenu: InputSignal<TemplateRef<unknown> | null> = input<TemplateRef<unknown> | null>(null);\n\n /** Откуда открывается меню: из рейки вправо-вверх или вниз под аватаром. */\n public readonly placement: InputSignal<'rail' | 'bar'> = input<'rail' | 'bar'>('bar');\n\n public readonly userClick: OutputEmitterRef<void> = output<void>();\n}\n","<ng-container rtBlock=\"rt-page-user\">\n @if (userMenu(); as menuTpl) {\n <button\n rtElem=\"button\"\n type=\"button\"\n qa-dataid=\"page-user\"\n #userPopover=\"rtPopover\"\n rtPopoverAlign=\"end\"\n rtPopoverFitViewport\n [rtPopoverPositions]=\"positions()\"\n [attr.aria-label]=\"user().name\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"userPopover.isOpen()\"\n [rtPopover]=\"menuTpl\">\n <ng-container [ngTemplateOutlet]=\"body\" />\n </button>\n } @else {\n <button rtElem=\"button\" type=\"button\" qa-dataid=\"page-user\" [attr.aria-label]=\"user().name\" (click)=\"userClick.emit()\">\n <ng-container [ngTemplateOutlet]=\"body\" />\n </button>\n }\n\n <ng-template #body>\n <span rtElem=\"avatar\" aria-hidden=\"true\">{{ letter() }}</span>\n @if (placement() === 'bar') {\n <span rtElem=\"name\">{{ user().name }}</span>\n <span rtElem=\"caret\" aria-hidden=\"true\"><rt-icon name=\"chevron-up-down\" size=\"xs\" /></span>\n }\n </ng-template>\n</ng-container>\n","import {\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n OutputEmitterRef,\n TemplateRef,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { IRtPageHeader } from '../rt-page-header.model';\nimport { RtPageUserComponent } from './rt-page-user.component';\n\nconst BEM_BLOCK: string = 'rt-page-actions';\n\n/**\n * Кнопки вокруг страницы: ассистент, уведомления и профиль. Одна часть на три места: столбец в\n * подвале рейки, строка шапки телефона и ряд вкладок. Состав задаёт приложение.\n */\n@Component({\n selector: 'rt-page-actions',\n templateUrl: './rt-page-actions.component.html',\n styleUrl: './rt-page-actions.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [RtIconComponent, RtPageUserComponent, RtTooltipDirective, BlockDirective, ElemDirective, ModDirective],\n host: { class: BEM_BLOCK, '[class.rt-page-actions--rail]': \"placement() === 'rail'\" },\n})\nexport class RtPageActionsComponent {\n public readonly items: InputSignal<ReadonlyArray<IRtPageHeader.Item>> = input<ReadonlyArray<IRtPageHeader.Item>>([]);\n\n public readonly user: InputSignal<IRtPageHeader.User | null> = input<IRtPageHeader.User | null>(null);\n\n public readonly userMenu: InputSignal<TemplateRef<unknown> | null> = input<TemplateRef<unknown> | null>(null);\n\n /** Где стоят кнопки: в подвале рейки или в ряду вкладок. */\n public readonly placement: InputSignal<'rail' | 'bar'> = input<'rail' | 'bar'>('bar');\n\n public readonly itemClick: OutputEmitterRef<string> = output<string>();\n\n public readonly userClick: OutputEmitterRef<void> = output<void>();\n}\n","<ng-container rtBlock=\"rt-page-actions\">\n @for (item of items(); track item.id) {\n <button\n rtElem=\"item\"\n type=\"button\"\n qa-dataid=\"page-action\"\n rtTooltipPlacement=\"right\"\n [attr.data-id]=\"item.id\"\n [attr.aria-label]=\"item.label\"\n [attr.aria-disabled]=\"item.disabled || null\"\n [attr.aria-pressed]=\"item.active ?? null\"\n [rtMod]=\"{ disabled: item.disabled ?? false, active: item.active ?? false }\"\n [rtTooltip]=\"placement() === 'rail' ? item.label : ''\"\n (click)=\"item.disabled || itemClick.emit(item.id)\">\n <span rtElem=\"plate\">\n @if (item.icon; as icon) {\n <rt-icon size=\"sm\" [name]=\"icon\" />\n }\n @if (item.unread) {\n <span rtElem=\"marker\" qa-dataid=\"page-action-marker\"></span>\n }\n </span>\n </button>\n }\n @if (user(); as u) {\n <rt-page-user [placement]=\"placement()\" [user]=\"u\" [userMenu]=\"userMenu()\" (userClick)=\"userClick.emit()\" />\n }\n</ng-container>\n","import {\n computed,\n inject,\n input,\n output,\n signal,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { ERtPageHeaderEntry, IRtPageHeaderView } from '../rt-page-header.logic';\n\nconst BEM_BLOCK: string = 'rt-page-phone-menu';\n\n/**\n * Столбец разделов вертикальной шапки на телефоне. Раздел с панелью открывает свои пункты на месте\n * списка, «Назад» возвращает к разделам. Логотипа в столбце нет: он остаётся у рейки.\n */\n@Component({\n selector: 'rt-page-phone-menu',\n templateUrl: './rt-page-phone-menu.component.html',\n styleUrl: './rt-page-phone-menu.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [NgTemplateOutlet, RouterLink, RouterLinkActive, RtIconComponent, BlockDirective, ElemDirective, ModDirective],\n host: { class: BEM_BLOCK },\n})\nexport class RtPagePhoneMenuComponent {\n readonly #openId: WritableSignal<string | null> = signal<string | null>(null);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly EntryKind: typeof ERtPageHeaderEntry = ERtPageHeaderEntry;\n\n protected readonly openSection: Signal<IRtPageHeaderView.Section | null> = computed(\n (): IRtPageHeaderView.Section | null =>\n this.sections().find(\n (section: IRtPageHeaderView.Section): boolean => section.id === this.#openId() && section.kind === ERtPageHeaderEntry.Panel\n ) ?? null\n );\n\n public readonly sections: InputSignal<ReadonlyArray<IRtPageHeaderView.Section>> =\n input.required<ReadonlyArray<IRtPageHeaderView.Section>>();\n\n public readonly activeIds: InputSignal<ReadonlySet<string>> = input.required<ReadonlySet<string>>();\n\n public readonly navLabel: InputSignal<string> = input<string>('');\n\n public readonly itemClick: OutputEmitterRef<string> = output<string>();\n\n /** Выбран пункт: столбец больше не нужен. */\n public readonly closed: OutputEmitterRef<void> = output<void>();\n\n protected openPanel(id: string): void {\n this.#openId.set(id);\n }\n\n protected back(): void {\n this.#openId.set(null);\n }\n\n protected onButton(entry: IRtPageHeaderView.Entry): void {\n if (entry.disabled) {\n return;\n }\n this.itemClick.emit(entry.id);\n this.closed.emit();\n }\n}\n","<ng-container rtBlock=\"rt-page-phone-menu\">\n <nav rtElem=\"list\" qa-dataid=\"phone-menu-list\" [attr.aria-label]=\"navLabel() || null\" [rtMod]=\"{ panel: !!openSection() }\">\n @if (openSection(); as section) {\n <button rtElem=\"row\" type=\"button\" qa-dataid=\"phone-menu-back\" (click)=\"back()\">\n <span rtElem=\"icon\"><rt-icon name=\"arrow-left\" [size]=\"20\" /></span>\n <span rtElem=\"label\">{{ t().uiBack }}</span>\n </button>\n @for (group of section.panelGroups; track group.id) {\n @if (group.label) {\n <div rtElem=\"group-title\" qa-dataid=\"phone-menu-group\">{{ group.label }}</div>\n }\n @for (entry of group.items; track entry.id) {\n <ng-container [ngTemplateOutlet]=\"row\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n }\n }\n } @else {\n @for (section of sections(); track section.id) {\n @if (section.kind === EntryKind.Panel) {\n <button\n rtElem=\"row\"\n type=\"button\"\n qa-dataid=\"phone-menu-row\"\n [rtMod]=\"{ active: activeIds().has(section.id) }\"\n [attr.data-id]=\"section.id\"\n (click)=\"openPanel(section.id)\">\n <ng-container [ngTemplateOutlet]=\"icon\" [ngTemplateOutletContext]=\"{ $implicit: section }\" />\n <span rtElem=\"label\" [attr.title]=\"section.label\">{{ section.label }}</span>\n <span rtElem=\"arrow\"><rt-icon name=\"arrow-right\" [size]=\"16\" /></span>\n </button>\n } @else {\n <ng-container [ngTemplateOutlet]=\"row\" [ngTemplateOutletContext]=\"{ $implicit: section }\" />\n }\n }\n }\n </nav>\n\n <ng-template #row let-entry>\n @if (entry.kind === EntryKind.Link) {\n <a\n rtElem=\"row\"\n qa-dataid=\"phone-menu-row\"\n routerLinkActive=\"rt-page-phone-menu__row--active\"\n [attr.data-id]=\"entry.id\"\n [routerLink]=\"entry.route\"\n [routerLinkActiveOptions]=\"{ exact: entry.routerLinkActiveExact }\"\n (click)=\"closed.emit()\">\n <ng-container [ngTemplateOutlet]=\"icon\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n <span rtElem=\"label\" [attr.title]=\"entry.label\">{{ entry.label }}</span>\n </a>\n } @else {\n <button\n rtElem=\"row\"\n type=\"button\"\n qa-dataid=\"phone-menu-row\"\n [rtMod]=\"{ disabled: entry.disabled }\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-disabled]=\"entry.disabled || null\"\n (click)=\"onButton(entry)\">\n <ng-container [ngTemplateOutlet]=\"icon\" [ngTemplateOutletContext]=\"{ $implicit: entry }\" />\n <span rtElem=\"label\" [attr.title]=\"entry.label\">{{ entry.label }}</span>\n </button>\n }\n </ng-template>\n\n <ng-template #icon let-entry>\n @if (entry.icon; as name) {\n <span rtElem=\"icon\">\n <rt-icon [name]=\"name\" [size]=\"20\" />\n @if (entry.unread) {\n <span rtElem=\"marker\" role=\"img\" qa-dataid=\"phone-menu-marker\" [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </span>\n }\n </ng-template>\n</ng-container>\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n afterNextRender,\n booleanAttribute,\n computed,\n inject,\n input,\n linkedSignal,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\n\nimport { BlockDirective, ElemDirective, ModDirective, WINDOW } from '@rt-tools/core';\n\nimport { BreakpointsService, RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { ERtPageHeaderEntry, IRtPageHeaderView } from '../rt-page-header.logic';\nimport { IRtPageHeader } from '../rt-page-header.model';\nimport { RtPageActionsComponent } from './rt-page-actions.component';\nimport { RtPagePhoneMenuComponent } from './rt-page-phone-menu.component';\n\nconst BEM_BLOCK: string = 'rt-page-rail';\n\n/** Сколько панель ждёт возврата указателя: перевести его с пункта на панель — не значит уйти. */\nconst PANEL_CLOSE_DELAY_MS: number = 150;\n\n/**\n * Вертикальная шапка: рейка 50 с разделами и панель раздела 220 поверх страницы. На телефоне та же\n * часть становится строкой 50: бургер открывает разделы столбцом `rt-page-phone-menu`. Адрес и\n * подсветку считает `rt-page-header`: у одного списка разделов одна подсветка в обоих видах.\n */\n@Component({\n selector: 'rt-page-rail',\n templateUrl: './rt-page-rail.component.html',\n styleUrl: './rt-page-rail.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n RouterLink,\n RouterLinkActive,\n RtIconComponent,\n RtPageActionsComponent,\n RtPagePhoneMenuComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n '(mouseleave)': 'schedulePanelClose()',\n '(mouseenter)': 'cancelPanelClose()',\n '(document:keydown.escape)': 'closeAll()',\n '(document:click)': 'onDocumentClick($event)',\n },\n})\nexport class RtPageRailComponent {\n readonly #host: HTMLElement = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n readonly #win: Window = inject(WINDOW);\n\n readonly #injector: Injector = inject(Injector);\n\n #closeTimer: number | null = null;\n\n /** Раздел, чью панель открыло наведение перед нажатием: касание шлёт его перед `click`. */\n #hoverOpenedId: string | null = null;\n\n readonly #openId: WritableSignal<string | null> = signal<string | null>(null);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly EntryKind: typeof ERtPageHeaderEntry = ERtPageHeaderEntry;\n\n /** Открытый раздел: панель рисуется только для раздела с панелью. */\n protected readonly openSection: Signal<IRtPageHeaderView.Section | null> = computed(\n (): IRtPageHeaderView.Section | null =>\n this.sections().find(\n (section: IRtPageHeaderView.Section): boolean => section.id === this.#openId() && section.kind === ERtPageHeaderEntry.Panel\n ) ?? null\n );\n\n /** Столбец телефона открыт бургером. Смена ширины за порог узкого экрана его закрывает. */\n protected readonly phoneMenuOpen: WritableSignal<boolean> = linkedSignal<boolean, boolean>({\n source: inject(BreakpointsService).narrow,\n computation: (): boolean => false,\n });\n\n protected readonly burgerRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('burger');\n\n protected readonly phoneColumnRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('phoneColumn');\n\n public readonly sections: InputSignal<ReadonlyArray<IRtPageHeaderView.Section>> =\n input.required<ReadonlyArray<IRtPageHeaderView.Section>>();\n\n public readonly activeIds: InputSignal<ReadonlySet<string>> = input.required<ReadonlySet<string>>();\n\n public readonly navLabel: InputSignal<string> = input<string>('');\n\n public readonly user: InputSignal<IRtPageHeader.User | null> = input<IRtPageHeader.User | null>(null);\n\n public readonly userMenu: InputSignal<TemplateRef<unknown> | null> = input<TemplateRef<unknown> | null>(null);\n\n /** Подвал рейки: вид с вкладками его убирает и ставит те же кнопки в ряд с вкладками. */\n public readonly foot: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n public readonly footItems: InputSignal<ReadonlyArray<IRtPageHeader.Item>> = input<ReadonlyArray<IRtPageHeader.Item>>([]);\n\n public readonly itemClick: OutputEmitterRef<string> = output<string>();\n\n public readonly userClick: OutputEmitterRef<void> = output<void>();\n\n constructor() {\n inject(DestroyRef).onDestroy((): void => this.cancelPanelClose());\n }\n\n protected openPanel(id: string): void {\n this.cancelPanelClose();\n if (this.#openId() !== id) {\n this.#hoverOpenedId = id;\n }\n this.#openId.set(id);\n }\n\n /**\n * Касание и клавиатура: раздел открывает и закрывает само нажатие. Нажатие, перед которым\n * наведение открыло эту панель, её оставляет: так касание, которое шлёт наведение и нажатие\n * подряд, открывает панель с первого раза. Нажатие мышью не закрывает панель никогда.\n */\n protected togglePanel(id: string, event: Event): void {\n event.stopPropagation();\n const byMouse: boolean = 'pointerType' in event && event.pointerType === 'mouse';\n const keep: boolean = byMouse || this.#hoverOpenedId === id;\n\n this.#hoverOpenedId = null;\n this.#openId.set(!keep && this.#openId() === id ? null : id);\n }\n\n protected closePanel(): void {\n this.cancelPanelClose();\n this.#hoverOpenedId = null;\n this.#openId.set(null);\n }\n\n protected closeAll(): void {\n this.closePanel();\n if (this.phoneMenuOpen()) {\n this.closePhoneMenu();\n }\n }\n\n /** Открытый столбец берёт фокус на первую строку: он окно поверх страницы. */\n protected openPhoneMenu(): void {\n this.phoneMenuOpen.set(true);\n afterNextRender((): void => this.phoneColumnRef()?.nativeElement.querySelector<HTMLElement>('button, a[href]')?.focus(), {\n injector: this.#injector,\n });\n }\n\n /** Закрытый столбец возвращает фокус бургеру, откуда его открыли. */\n protected closePhoneMenu(): void {\n this.phoneMenuOpen.set(false);\n this.burgerRef()?.nativeElement.focus();\n }\n\n protected schedulePanelClose(): void {\n this.cancelPanelClose();\n this.#closeTimer = this.#win.setTimeout((): void => this.closePanel(), PANEL_CLOSE_DELAY_MS);\n }\n\n protected cancelPanelClose(): void {\n if (this.#closeTimer !== null) {\n this.#win.clearTimeout(this.#closeTimer);\n this.#closeTimer = null;\n }\n }\n\n protected onDocumentClick(event: MouseEvent): void {\n if (event.target instanceof Node && !this.#host.contains(event.target)) {\n this.closePanel();\n }\n }\n\n protected onEntryClick(id: string): void {\n this.itemClick.emit(id);\n this.closePanel();\n }\n}\n","<ng-container rtBlock=\"rt-page-rail\">\n <button\n #burger\n rtElem=\"burger\"\n type=\"button\"\n qa-dataid=\"rail-burger\"\n [attr.aria-label]=\"t().uiNavMenu\"\n [attr.aria-expanded]=\"phoneMenuOpen()\"\n (click)=\"openPhoneMenu()\">\n <rt-icon name=\"bars\" size=\"md\" />\n </button>\n\n <div rtElem=\"logo\"><ng-content select=\"[rtRailLogo]\" /></div>\n\n <nav rtElem=\"sections\" qa-dataid=\"rail-sections\" [attr.aria-label]=\"navLabel()\">\n @for (section of sections(); track section.id) {\n @switch (section.kind) {\n @case (EntryKind.Panel) {\n <button\n rtElem=\"item\"\n type=\"button\"\n qa-dataid=\"rail-item\"\n [rtMod]=\"{ active: activeIds().has(section.id), open: openSection()?.id === section.id }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"section.label\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"openSection()?.id === section.id\"\n (mouseenter)=\"openPanel(section.id)\"\n (click)=\"togglePanel(section.id, $event)\">\n <ng-container [ngTemplateOutlet]=\"plate\" [ngTemplateOutletContext]=\"{ $implicit: section }\" />\n </button>\n }\n @case (EntryKind.Link) {\n <a\n rtElem=\"item\"\n qa-dataid=\"rail-item\"\n rtTooltipPlacement=\"right\"\n routerLinkActive=\"rt-page-rail__item--active\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"section.label\"\n [routerLink]=\"section.route\"\n [routerLinkActiveOptions]=\"{ exact: section.routerLinkActiveExact }\"\n [rtTooltip]=\"section.label\"\n (mouseenter)=\"closePanel()\">\n <ng-container [ngTemplateOutlet]=\"plate\" [ngTemplateOutletContext]=\"{ $implicit: section }\" />\n </a>\n }\n @default {\n <button\n rtElem=\"item\"\n type=\"button\"\n qa-dataid=\"rail-item\"\n rtTooltipPlacement=\"right\"\n [rtMod]=\"{ disabled: section.disabled }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"section.label\"\n [attr.aria-disabled]=\"section.disabled || null\"\n [rtTooltip]=\"section.label\"\n (mouseenter)=\"closePanel()\"\n (click)=\"section.disabled || itemClick.emit(section.id)\">\n <ng-container [ngTemplateOutlet]=\"plate\" [ngTemplateOutletContext]=\"{ $implicit: section }\" />\n </button>\n }\n }\n }\n </nav>\n\n <div rtElem=\"page\"><ng-content select=\"[rtRailPage]\" /></div>\n\n @if (foot()) {\n <rt-page-actions\n placement=\"rail\"\n qa-dataid=\"rail-foot\"\n [items]=\"footItems()\"\n [user]=\"user()\"\n [userMenu]=\"userMenu()\"\n (itemClick)=\"itemClick.emit($event)\"\n (userClick)=\"userClick.emit()\" />\n }\n\n @if (openSection(); as section) {\n <div rtElem=\"panel\" role=\"menu\" qa-dataid=\"rail-panel\" [attr.data-id]=\"section.id\">\n @for (group of section.panelGroups; track group.id) {\n <div rtElem=\"group\" role=\"group\" [attr.aria-label]=\"group.label || null\">\n @if (group.label) {\n <div rtElem=\"group-title\">{{ group.label }}</div>\n }\n @for (entry of group.items; track entry.id) {\n @if (entry.kind === EntryKind.Link) {\n <a\n rtElem=\"panel-item\"\n role=\"menuitem\"\n qa-dataid=\"rail-panel-item\"\n routerLinkActive=\"rt-page-rail__panel-item--active\"\n [attr.data-id]=\"entry.id\"\n [routerLink]=\"entry.route\"\n [routerLinkActiveOptions]=\"{ exact: entry.routerLinkActiveExact }\"\n (click)=\"closePanel()\">\n {{ entry.label }}\n </a>\n } @else {\n <button\n rtElem=\"panel-item\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"rail-panel-item\"\n [rtMod]=\"{ disabled: entry.disabled }\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-disabled]=\"entry.disabled || null\"\n (click)=\"entry.disabled || onEntryClick(entry.id)\">\n {{ entry.label }}\n </button>\n }\n }\n </div>\n }\n </div>\n }\n\n @if (phoneMenuOpen()) {\n <div rtElem=\"phone-menu\" qa-dataid=\"rail-phone-menu\">\n <button\n rtElem=\"phone-backdrop\"\n type=\"button\"\n qa-dataid=\"rail-phone-backdrop\"\n [attr.aria-label]=\"t().bottomSheetClose\"\n (click)=\"closePhoneMenu()\"></button>\n <div #phoneColumn rtElem=\"phone-column\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"t().uiNavMenu\">\n <rt-page-phone-menu\n [sections]=\"sections()\"\n [activeIds]=\"activeIds()\"\n [navLabel]=\"navLabel()\"\n (itemClick)=\"itemClick.emit($event)\"\n (closed)=\"closePhoneMenu()\" />\n </div>\n </div>\n }\n</ng-container>\n\n<ng-template #plate let-section>\n <span rtBlock=\"rt-page-rail-plate\">\n @if (section.icon; as icon) {\n <rt-icon size=\"sm\" [name]=\"icon\" />\n } @else {\n <span rtElem=\"letter\" aria-hidden=\"true\" qa-dataid=\"rail-letter\">{{ section.label.charAt(0) }}</span>\n }\n @if (section.unread) {\n <span rtElem=\"marker\" role=\"img\" qa-dataid=\"rail-marker\" [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </span>\n</ng-template>\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n OutputEmitterRef,\n TemplateRef,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\n\nconst BEM_BLOCK: string = 'rt-page-header-user';\n\n/**\n * Кнопка профиля горизонтальной шапки. Меню открывается наведением, как и разделы: весь верхний ряд\n * ведёт себя одинаково. Нажатие остаётся запасным путём для касания, а переход курсора на список\n * языков панель переживает: вложенный оверлей за уход наружу не считается. На узком экране меню\n * стоит на той же подложке, что меню разделов из бургера. Классы и стили кнопки остаются у шапки.\n */\n@Component({\n selector: 'rt-page-header-user',\n templateUrl: './rt-page-header-user.component.html',\n styleUrl: './rt-page-header-user.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [NgTemplateOutlet, RtIconComponent, RtPopoverDirective, BlockDirective, ElemDirective, ModDirective],\n host: { class: BEM_BLOCK },\n})\nexport class RtPageHeaderUserComponent {\n public readonly name: InputSignal<string> = input.required<string>();\n\n public readonly avatar: InputSignal<string> = input.required<string>();\n\n public readonly menu: InputSignal<TemplateRef<unknown> | null> = input<TemplateRef<unknown> | null>(null);\n\n public readonly backdropClass: InputSignal<string> = input<string>('');\n\n public readonly userClick: OutputEmitterRef<void> = output<void>();\n}\n","<ng-container rtBlock=\"rt-page-header\">\n @if (menu(); as menuTpl) {\n <button\n rtElem=\"user\"\n type=\"button\"\n qa-dataid=\"header-user-menu\"\n #userPopover=\"rtPopover\"\n rtPopoverTrigger=\"hover\"\n rtPopoverAlign=\"end\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"14\"\n [rtPopoverBackdropClass]=\"backdropClass()\"\n [rtMod]=\"{ isOpen: userPopover.isOpen() }\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"userPopover.isOpen()\"\n [rtPopover]=\"menuTpl\"\n (click)=\"userPopover.open()\">\n <ng-container [ngTemplateOutlet]=\"body\" />\n </button>\n } @else {\n <button rtElem=\"user\" type=\"button\" qa-dataid=\"header-user\" (click)=\"userClick.emit()\">\n <ng-container [ngTemplateOutlet]=\"body\" />\n </button>\n }\n\n <ng-template #body>\n <span rtElem=\"user-avatar\" aria-hidden=\"true\">{{ avatar() }}</span>\n <span rtElem=\"user-name\" qa-dataid=\"header-user-name\">{{ name() }}</span>\n <span rtElem=\"user-caret\" aria-hidden=\"true\">\n <rt-icon name=\"chevron-up-down\" size=\"xs\" />\n </span>\n </ng-template>\n</ng-container>\n","import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport {\n afterNextRender,\n afterRenderEffect,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n numberAttribute,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { Event as RouterEvent, NavigationEnd, Router, RouterLink, RouterLinkActive } from '@angular/router';\n\nimport { filter, map } from 'rxjs';\n\nimport { BlockDirective, ElemDirective, ModDirective, WINDOW } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, RT_KIT_TRANSLATOR, RtKitLabelPipe, TRtKitLabelMap, TRtKitTranslator, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { BreakpointsService } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { RtPageHeaderMoreComponent } from './more/rt-page-header-more.component';\nimport { RtPageRailComponent } from './rail/rt-page-rail.component';\nimport { RtPageHeaderUserComponent } from './user/rt-page-header-user.component';\nimport {\n activeSectionIds,\n compactSectionsOf,\n fitRow,\n hasActiveSection,\n ERtPageHeaderEntry,\n IRtPageHeaderFit,\n IRtPageHeaderView,\n isStuck,\n toSections,\n} from './rt-page-header.logic';\nimport { IRtPageHeader } from './rt-page-header.model';\n\nconst BEM_BLOCK: string = 'rt-page-header';\n\n/** Подложка узкой шапки: её вид задан в `rt-page-header-mobile.scss`, класс ставит и бургер */\nconst PAGE_HEADER_MOBILE_BACKDROP: string = 'rt-page-header-mobile-backdrop';\n\n/**\n * Верхняя горизонтальная плашка-навигация для первого уровня доменных страниц.\n *\n * Контракт:\n * - `items` — `Item[]`. Анкор для пунктов с `route`; `<button>` для недоступных\n * и для тех, кто обрабатывается снаружи (`itemClick`). Пункт с `columns` —\n * кнопка-триггер: панель второго уровня открывается наведением ([rtPopover]).\n * - `user` — необязательный блок справа. Если задан `userMenu` (TemplateRef) —\n * блок становится hover-триггером попапа с этим контентом (клик — touch-fallback,\n * панель прижата к правому краю); иначе по клику emit'ит `userClick`.\n *\n * Active state — через `RouterLinkActive` с классом `rt-page-header__link--is-active`;\n * для раздела с панелью — вычисляется по текущему URL (своего route у него нет).\n */\n@Component({\n selector: 'rt-page-header',\n templateUrl: './rt-page-header.component.html',\n // Панель второго уровня и панель узкого экрана рисуются в CDK Overlay, вне\n // хоста, поэтому это отдельные корневые блоки — и отдельные файлы: бюджет\n // стилей компонента считается на каждый файл, и одним они его перебирают.\n styleUrls: [\n './rt-page-header.component.scss',\n './rt-page-header-submenu.scss',\n './rt-page-header-mobile.scss',\n './rt-page-header-compact.scss',\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n RtKitLabelPipe,\n // Angular\n RouterLink,\n RouterLinkActive,\n\n // standalone components / directives\n RtIconComponent,\n RtPopoverDirective,\n RtTooltipDirective,\n RtPageHeaderMoreComponent,\n RtPageRailComponent,\n RtPageHeaderUserComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-page-header--sticky]': 'stickyCompact()',\n '[class.rt-page-header--is-compact]': 'compact()',\n '[class.rt-page-header--vertical]': 'isVertical()',\n },\n})\nexport class RtPageHeaderComponent {\n readonly #router: Router = inject(Router);\n\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #host: ElementRef<HTMLElement> = inject<ElementRef<HTMLElement>>(ElementRef);\n\n // Конструктор наблюдателя пересечения объявлен на globalThis, а не на интерфейсе Window —\n // токен отдаёт тот же объект, тип лишь уточняется.\n readonly #window: Window & typeof globalThis = inject(WINDOW) as Window & typeof globalThis;\n\n /**\n * Прилипла ли шапка к краю прокрутки. Считается наблюдателем пересечения, а не смещением\n * окна: страница у потребителя прокручивается и внутри контейнера, и окно об этом не знает.\n */\n readonly #stuck: WritableSignal<boolean> = signal<boolean>(false);\n\n readonly #t_uiMainNav: Signal<string> = rtKitLabel('uiMainNav');\n\n /** Наблюдатель ширины навигации и пунктов ряда: по нему ряд пересчитывает, что уходит в «Ещё». */\n #rowWatch: ResizeObserver | null = null;\n\n /** id разделов, ушедших в «Ещё». До первого замера уходить некому. */\n readonly #overflowIds: WritableSignal<ReadonlySet<string>> = signal<ReadonlySet<string>>(new Set<string>(), {\n equal: (a: ReadonlySet<string>, b: ReadonlySet<string>): boolean =>\n a.size === b.size && [...a].every((id: string): boolean => b.has(id)),\n });\n\n protected readonly navRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('nav');\n\n protected readonly listRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('list');\n\n protected readonly moreItemRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('moreItem');\n\n /* Реактивный URL для подсветки раздела: у раздела с панелью нет своего\n route, поэтому RouterLinkActive не применим — сравниваем по факту навигации. */\n readonly #currentUrl: Signal<string> = toSignal(\n this.#router.events.pipe(\n filter((e: RouterEvent): e is NavigationEnd => e instanceof NavigationEnd),\n map((): string => this.#router.url)\n ),\n { initialValue: this.#router.url }\n );\n\n readonly #breakpoints: BreakpointsService = inject(BreakpointsService);\n\n readonly #translate: Signal<TRtKitTranslator> = inject(RT_KIT_TRANSLATOR);\n\n /** Переводчик для чистого пайпа подписи: шаблон отдаёт его вторым доводом. */\n protected readonly translate: Signal<TRtKitTranslator> = this.#translate;\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly mobileNavPopoverRef: Signal<RtPopoverDirective | undefined> = viewChild('mobileNavPopover', {\n read: RtPopoverDirective,\n });\n\n /** Кнопка «ещё» сжатой полосы открывает ту же панель, что и бургер, своим поповером. */\n protected readonly compactNavPopoverRef: Signal<RtPopoverDirective | undefined> = viewChild('compactNavPopover', {\n read: RtPopoverDirective,\n });\n\n /** Сжатое состояние: шапка липкая, прилипла к верху и стоит в горизонтальном виде — у рейки его нет. */\n protected readonly compact: Signal<boolean> = computed((): boolean => this.stickyCompact() && this.#stuck() && !this.isVertical());\n\n /** Разделы в кругах сжатой полосы: первые с иконкой, число — по входу. */\n protected readonly compactSections: Signal<ReadonlyArray<IRtPageHeaderView.Section>> = computed(\n (): ReadonlyArray<IRtPageHeaderView.Section> => compactSectionsOf(this.sections(), this.compactVisibleCount())\n );\n\n /** Разделы, ушедшие из ряда в «Ещё»: шаблон вынимает их из ряда, сохраняя в разметке для замера. */\n protected readonly overflowIds: Signal<ReadonlySet<string>> = this.#overflowIds.asReadonly();\n\n /** Разделы панели «Ещё» в порядке списка. */\n protected readonly moreSections: Signal<ReadonlyArray<IRtPageHeaderView.Section>> = computed(\n (): ReadonlyArray<IRtPageHeaderView.Section> =>\n this.sections().filter((section: IRtPageHeaderView.Section): boolean => this.overflowIds().has(section.id))\n );\n\n /** «Ещё» стоит в ряду, только когда в ряд не встал хоть один раздел. */\n protected readonly moreShown: Signal<boolean> = computed((): boolean => this.moreSections().length > 0);\n\n /** Выбранный раздел ушёл в «Ещё» — подсвечивается сам «Ещё». */\n protected readonly moreActive: Signal<boolean> = computed((): boolean => hasActiveSection(this.moreSections(), this.#currentUrl()));\n\n /** Форма пункта решается один раз здесь, а не ветвлениями в шаблоне. */\n protected readonly sections: Signal<ReadonlyArray<IRtPageHeaderView.Section>> = computed((): ReadonlyArray<IRtPageHeaderView.Section> =>\n toSections(this.items())\n );\n\n /**\n * id разделов с активным вложенным адресом — для O(1) lookup в шаблоне.\n * Зависит от #currentUrl + items (сигналы) → подсветка реактивна на навигацию.\n */\n protected readonly activeSectionIds: Signal<ReadonlySet<string>> = computed((): ReadonlySet<string> =>\n activeSectionIds(this.sections(), this.#currentUrl())\n );\n\n protected readonly userAvatar: Signal<string> = computed((): string => {\n const u: IRtPageHeader.User | null = this.user();\n if (!u) {\n return '';\n }\n if (u.avatar && u.avatar.length > 0) {\n return u.avatar.charAt(0).toUpperCase();\n }\n return u.name.charAt(0).toUpperCase();\n });\n\n /** Узкий вьюпорт (≤1080px): инлайн-навигация прячется, показывается гамбургер. */\n protected readonly isNarrow: Signal<boolean> = this.#breakpoints.narrow;\n\n /**\n * Подложка меню профиля: на узком экране та же, что у меню разделов из бургера, на широком её\n * нет — меню там открывается наведением. Поповер читает класс при первом открытии.\n */\n protected readonly userMenuBackdropClass: Signal<string> = computed((): string => (this.isNarrow() ? PAGE_HEADER_MOBILE_BACKDROP : ''));\n\n /**\n * id раскрытых разделов-аккордеонов в мобильной панели. Ключ — только раздел:\n * группы внутри раскрытого раздела показаны сразу, и совпасть идентификаторам\n * раздела и группы в этом множестве негде.\n */\n protected readonly expandedSectionIds: WritableSignal<ReadonlySet<string>> = signal<ReadonlySet<string>>(new Set<string>());\n\n protected readonly EntryKind: typeof ERtPageHeaderEntry = ERtPageHeaderEntry;\n\n protected readonly isVertical: Signal<boolean> = computed((): boolean => this.layout() === 'vertical');\n\n public readonly items: InputSignal<ReadonlyArray<IRtPageHeader.Item>> = input<ReadonlyArray<IRtPageHeader.Item>>([]);\n\n public readonly user: InputSignal<IRtPageHeader.User | null> = input<IRtPageHeader.User | null>(null);\n\n public readonly userTitle: InputSignal<string> = input<string>('');\n\n public readonly userMenu: InputSignal<TemplateRef<unknown> | null> = input<TemplateRef<unknown> | null>(null);\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly ariaLabel: InputSignal<string> = input<string>('');\n\n /**\n * Шапка липнет к верху окна и, прилипнув, сжимается в полосу: круги первых разделов,\n * кнопка «ещё» и три слота потребителя. Выключено — поведение прежнее.\n */\n public readonly stickyCompact: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Сколько разделов с иконкой показывать кругами в сжатой полосе; остальные — под «ещё». */\n public readonly compactVisibleCount: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(2, {\n transform: numberAttribute,\n });\n\n /** Вид шапки: разделы в ряд (`horizontal`) или рейкой по левому краю окна (`vertical`). */\n public readonly layout: InputSignal<IRtPageHeader.Layout> = input<IRtPageHeader.Layout>('horizontal');\n\n /** Кнопки подвала рейки: ассистент, уведомления. Нажатие приходит в `itemClick`. */\n public readonly railActions: InputSignal<ReadonlyArray<IRtPageHeader.Item>> = input<ReadonlyArray<IRtPageHeader.Item>>([]);\n\n /** Подвал рейки: вид с вкладками его убирает и ставит те же кнопки в ряд с вкладками. */\n public readonly railFoot: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n /** Своё имя навигации важнее умолчания */\n public readonly navAriaLabel: Signal<string> = computed((): string => this.ariaLabel() || this.#t_uiMainNav());\n\n public readonly itemClick: OutputEmitterRef<string> = output<string>();\n\n public readonly userClick: OutputEmitterRef<void> = output<void>();\n\n constructor() {\n // Ресайз обратно в десктоп — гамбургер скрывается CSS'ом; открытую\n // мобильную панель закрываем, иначе overlay зависнет без якоря.\n effect((): void => {\n if (!this.isNarrow()) {\n this.mobileNavPopoverRef()?.close();\n }\n });\n\n // Наблюдение ставится при любом виде: вид меняется на ходу, а у рейки сжатой полосы нет — её\n // гасит `compact`, а не отсутствие наблюдателя.\n afterNextRender((): void => this.#observeStuck());\n\n // Ряд пересчитывается при смене состава и подписей — и разделов, и самого «Ещё»: ширины\n // пунктов меняются вместе с ними. Смену ширины шапки и шрифт, пришедший после первой\n // отрисовки, ловит наблюдатель размера. Эффект после отрисовки идёт только в браузере.\n afterRenderEffect((): void => {\n this.sections();\n this.t();\n this.#watchRow();\n this.#measureRow();\n });\n\n this.#destroyRef.onDestroy((): void => this.#rowWatch?.disconnect());\n }\n\n /** Наблюдение ставится заново на каждый состав: пришедшие пункты должны попасть под него. */\n #watchRow(): void {\n const nav: HTMLElement | undefined = this.navRef()?.nativeElement;\n const list: HTMLElement | undefined = this.listRef()?.nativeElement;\n if (nav === undefined || list === undefined || !('ResizeObserver' in this.#window)) {\n return;\n }\n this.#rowWatch?.disconnect();\n this.#rowWatch = new this.#window.ResizeObserver((): void => this.#measureRow());\n this.#rowWatch.observe(nav);\n Array.from(list.children).forEach((item: Element): void => this.#rowWatch?.observe(item));\n }\n\n /**\n * Замер ряда: ширина навигации, ширина каждого раздела и «Ещё», промежуток между пунктами.\n * Навигация без ширины спрятана — узкий экран или сжатая полоса, — и прежняя раскладка\n * остаётся до её возвращения.\n */\n #measureRow(): void {\n const nav: HTMLElement | undefined = this.navRef()?.nativeElement;\n const list: HTMLElement | undefined = this.listRef()?.nativeElement;\n const moreItem: HTMLElement | undefined = this.moreItemRef()?.nativeElement;\n if (nav === undefined || list === undefined || moreItem === undefined) {\n return;\n }\n const available: number = nav.getBoundingClientRect().width;\n if (available <= 0) {\n return;\n }\n const widths: Map<string, number> = new Map<string, number>();\n list.querySelectorAll<HTMLElement>('[qa-dataid=\"header-nav-item\"]').forEach((item: HTMLElement): void => {\n widths.set(item.dataset['id'] ?? '', item.getBoundingClientRect().width);\n });\n const fit: IRtPageHeaderFit.Result = fitRow({\n slots: this.sections().map((section: IRtPageHeaderView.Section): IRtPageHeaderFit.Slot => ({\n id: section.id,\n width: widths.get(section.id) ?? 0,\n priority: section.priority,\n })),\n moreWidth: moreItem.getBoundingClientRect().width,\n gap: parseFloat(this.#window.getComputedStyle(list).columnGap) || 0,\n available,\n });\n this.#overflowIds.set(new Set<string>(fit.more));\n }\n\n /**\n * Липкая шапка стоит на пиксель выше края прокрутки и, прилипнув, теряет его из видимой\n * области: наблюдатель пересечения с порогом в единицу ловит ровно этот момент — и в окне,\n * и внутри прокручиваемого контейнера, о котором окно не знает.\n */\n #observeStuck(): void {\n const observer: IntersectionObserver = new this.#window.IntersectionObserver(\n (entries: IntersectionObserverEntry[]): void => {\n const entry: IntersectionObserverEntry | undefined = entries.at(-1);\n if (entry !== undefined) {\n this.#stuck.set(isStuck(entry.intersectionRatio, entry.isIntersecting));\n }\n },\n { threshold: [0, 1] }\n );\n observer.observe(this.#host.nativeElement);\n this.#destroyRef.onDestroy((): void => observer.disconnect());\n }\n\n /** Панель разделов открывают и бургер, и кнопка «ещё»: закрываются обе. */\n protected closeNavPanels(): void {\n this.mobileNavPopoverRef()?.close();\n this.compactNavPopoverRef()?.close();\n }\n\n /** Круг раздела без адреса: раздел с панелью открывает общую панель, прочий — сообщает наружу. */\n protected onCompactSectionClick(section: IRtPageHeaderView.Section): void {\n if (section.kind === ERtPageHeaderEntry.Panel) {\n this.compactNavPopoverRef()?.open();\n return;\n }\n this.itemClick.emit(section.id);\n }\n\n protected onItemClick(id: string): void {\n this.itemClick.emit(id);\n }\n\n protected onUserClick(): void {\n this.userClick.emit();\n }\n\n /** Аккордеон мобильной панели: тумблер раскрытия раздела по его id. */\n protected toggleSection(id: string): void {\n this.expandedSectionIds.update((prev: ReadonlySet<string>): ReadonlySet<string> => {\n const next: Set<string> = new Set<string>(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n return next;\n });\n }\n\n /** Клик по плоскому пункту мобильной панели: emit + закрыть панель. */\n protected onMobileItemClick(id: string): void {\n this.itemClick.emit(id);\n this.closeNavPanels();\n }\n}\n","@if (isVertical()) {\n <rt-page-rail\n [sections]=\"sections()\"\n [activeIds]=\"activeSectionIds()\"\n [navLabel]=\"navAriaLabel()\"\n [user]=\"user()\"\n [userMenu]=\"userMenu()\"\n [foot]=\"railFoot()\"\n [footItems]=\"railActions()\"\n (itemClick)=\"onItemClick($event)\"\n (userClick)=\"onUserClick()\">\n <ng-content select=\"[rtRailLogo]\" ngProjectAs=\"[rtRailLogo]\" />\n <ng-content select=\"[rtRailPage]\" ngProjectAs=\"[rtRailPage]\" />\n </rt-page-rail>\n} @else {\n <ng-container rtBlock=\"rt-page-header\">\n <nav rtElem=\"nav\" #nav [attr.aria-label]=\"navAriaLabel()\">\n <ul rtElem=\"list\" role=\"list\" #list>\n @for (section of sections(); track section.id) {\n <li\n rtElem=\"item\"\n qa-dataid=\"header-nav-item\"\n [rtMod]=\"{ isOverflow: overflowIds().has(section.id) }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-hidden]=\"overflowIds().has(section.id) || null\"\n [attr.inert]=\"overflowIds().has(section.id) || null\">\n @switch (section.kind) {\n @case (EntryKind.Panel) {\n <button\n rtElem=\"link\"\n type=\"button\"\n qa-dataid=\"header-nav-trigger\"\n #groupPopover=\"rtPopover\"\n rtPopoverTrigger=\"hover\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"14\"\n [rtMod]=\"{\n isActive: activeSectionIds().has(section.id),\n isOpen: groupPopover.isOpen(),\n }\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"groupPopover.isOpen()\"\n [rtPopover]=\"submenuTpl\"\n (click)=\"groupPopover.open()\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n <span rtElem=\"caret\" aria-hidden=\"true\">\n <rt-icon name=\"chevron-up-down\" size=\"xs\" />\n </span>\n </button>\n <ng-template #submenuTpl>\n <div rtBlock=\"rt-page-header-submenu\" role=\"menu\" [style.--rt-nav-panel-columns]=\"section.columnCount\">\n @for (column of section.columns; track column.id) {\n <div rtElem=\"column\" qa-dataid=\"header-nav-column\" [attr.data-id]=\"column.id\">\n @for (group of column.groups; track group.id) {\n <div rtElem=\"group\" role=\"group\" [attr.aria-label]=\"group.label || null\">\n @if (group.label) {\n <div\n rtElem=\"group-title\"\n qa-dataid=\"header-nav-group\"\n [attr.data-id]=\"group.id\">\n @if (group.icon) {\n <rt-icon rtElem=\"group-icon\" size=\"xs\" [name]=\"group.icon\" />\n }\n <span rtElem=\"group-label\">{{ group.label }}</span>\n </div>\n }\n @for (entry of group.items; track entry.id) {\n @if (entry.kind === EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-subitem\"\n routerLinkActive=\"rt-page-header-submenu__link--is-active\"\n [attr.data-id]=\"entry.id\"\n [routerLink]=\"entry.route\"\n [routerLinkActiveOptions]=\"{ exact: entry.routerLinkActiveExact }\"\n (click)=\"groupPopover.close()\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n } @else if (entry.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"\n 'uiSectionInProgress'\n | rtKitLabel: translate() : { label: entry.label }\n \">\n <button\n rtElem=\"link\"\n role=\"menuitem\"\n type=\"button\"\n qa-dataid=\"header-nav-subitem\"\n [rtMod]=\"{ disabled: true }\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-disabled]=\"true\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n role=\"menuitem\"\n type=\"button\"\n qa-dataid=\"header-nav-subitem\"\n [attr.data-id]=\"entry.id\"\n (click)=\"onItemClick(entry.id)\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n </ng-template>\n }\n @case (EntryKind.Link) {\n <a\n rtElem=\"link\"\n routerLinkActive=\"rt-page-header__link--is-active\"\n [routerLink]=\"section.route\"\n [routerLinkActiveOptions]=\"{ exact: section.routerLinkActiveExact }\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n }\n @default {\n @if (section.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"'uiSectionInProgress' | rtKitLabel: translate() : { label: section.label }\">\n <button rtElem=\"link\" type=\"button\" [rtMod]=\"{ disabled: true }\" [attr.aria-disabled]=\"true\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n </button>\n </span>\n } @else {\n <button rtElem=\"link\" type=\"button\" (click)=\"onItemClick(section.id)\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n }\n </li>\n }\n <li\n rtElem=\"item\"\n #moreItem\n [rtMod]=\"{ isOverflow: !moreShown() }\"\n [attr.aria-hidden]=\"!moreShown() || null\"\n [attr.inert]=\"!moreShown() || null\">\n <rt-page-header-more [sections]=\"moreSections()\" [active]=\"moreActive()\" (itemClick)=\"onItemClick($event)\" />\n </li>\n </ul>\n </nav>\n\n <button\n rtElem=\"burger\"\n type=\"button\"\n qa-dataid=\"header-nav-burger\"\n #mobileNavPopover=\"rtPopover\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"14\"\n rtPopoverBackdropClass=\"rt-page-header-mobile-backdrop\"\n [attr.aria-label]=\"t().uiNavMenu\"\n [rtMod]=\"{ isOpen: mobileNavPopover.isOpen() }\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"mobileNavPopover.isOpen()\"\n [rtPopover]=\"mobileNavTpl\">\n <rt-icon rtElem=\"burger-icon\" name=\"bars\" size=\"md\" />\n </button>\n\n <!--\n Сжатая полоса стоит в разметке всегда, как и узкая: показывает её модификатор хоста.\n Слева стопка кругов — «ещё» поверх остальных, — дальше три слота потребителя.\n -->\n <div rtElem=\"compact\" qa-dataid=\"header-compact\">\n <div rtElem=\"compact-stack\">\n <button\n rtElem=\"compact-circle\"\n type=\"button\"\n qa-dataid=\"header-compact-more\"\n #compactNavPopover=\"rtPopover\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"10\"\n [rtMod]=\"{ more: true, isOpen: compactNavPopover.isOpen() }\"\n [attr.aria-label]=\"t().uiNavMenu\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"compactNavPopover.isOpen()\"\n [rtPopover]=\"mobileNavTpl\">\n <rt-icon name=\"ellipsis-h\" size=\"sm\" />\n </button>\n @for (section of compactSections(); track section.id; let index = $index) {\n @if (section.kind === EntryKind.Link) {\n <a\n rtElem=\"compact-circle\"\n qa-dataid=\"header-compact-section\"\n routerLinkActive=\"rt-page-header__compact-circle--is-active\"\n [style.--rt-nav-compact-index]=\"index + 1\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"section.label\"\n [routerLink]=\"section.route\"\n [routerLinkActiveOptions]=\"{ exact: section.routerLinkActiveExact }\"\n [rtTooltip]=\"section.label\">\n @if (section.icon; as icon) {\n <rt-icon size=\"sm\" [name]=\"icon\" />\n }\n @if (section.unread) {\n <span rtElem=\"compact-marker\" role=\"img\" [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n } @else {\n <button\n rtElem=\"compact-circle\"\n type=\"button\"\n qa-dataid=\"header-compact-section\"\n [rtMod]=\"{ isActive: activeSectionIds().has(section.id), disabled: section.disabled }\"\n [style.--rt-nav-compact-index]=\"index + 1\"\n [disabled]=\"section.disabled\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"section.label\"\n [rtTooltip]=\"section.label\"\n (click)=\"onCompactSectionClick(section)\">\n @if (section.icon; as icon) {\n <rt-icon size=\"sm\" [name]=\"icon\" />\n }\n @if (section.unread) {\n <span rtElem=\"compact-marker\" role=\"img\" [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n </div>\n <div rtElem=\"compact-slot\" [rtMod]=\"{ left: true }\"><ng-content select=\"[rtCompactLeft]\" /></div>\n <div rtElem=\"compact-slot\" [rtMod]=\"{ center: true }\"><ng-content select=\"[rtCompactCenter]\" /></div>\n <div rtElem=\"compact-slot\" [rtMod]=\"{ right: true }\"><ng-content select=\"[rtCompactRight]\" /></div>\n </div>\n\n <ng-template #mobileNavTpl>\n <div rtBlock=\"rt-page-header-mobile\" role=\"menu\">\n @for (section of sections(); track section.id) {\n @switch (section.kind) {\n @case (EntryKind.Panel) {\n <button\n rtElem=\"section\"\n type=\"button\"\n qa-dataid=\"header-nav-mobile-trigger\"\n [rtMod]=\"{\n isExpanded: expandedSectionIds().has(section.id),\n isActive: activeSectionIds().has(section.id),\n }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-expanded]=\"expandedSectionIds().has(section.id)\"\n (click)=\"toggleSection(section.id)\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n <span rtElem=\"caret\" aria-hidden=\"true\">\n <rt-icon name=\"chevron-up-down\" size=\"xs\" />\n </span>\n </button>\n @if (expandedSectionIds().has(section.id)) {\n <div rtElem=\"children\">\n @for (group of section.panelGroups; track group.id) {\n <div rtElem=\"group\" role=\"group\" [attr.aria-label]=\"group.label || null\">\n @if (group.label) {\n <div rtElem=\"group-title\" qa-dataid=\"header-nav-mobile-group\" [attr.data-id]=\"group.id\">\n @if (group.icon) {\n <rt-icon rtElem=\"group-icon\" size=\"xs\" [name]=\"group.icon\" />\n }\n <span rtElem=\"group-label\">{{ group.label }}</span>\n </div>\n }\n @for (entry of group.items; track entry.id) {\n @if (entry.kind === EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n routerLinkActive=\"rt-page-header-mobile__link--is-active\"\n [rtMod]=\"{ child: true }\"\n [attr.data-id]=\"entry.id\"\n [routerLink]=\"entry.route\"\n [routerLinkActiveOptions]=\"{ exact: entry.routerLinkActiveExact }\"\n (click)=\"closeNavPanels()\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n } @else if (entry.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"\n 'uiSectionInProgress' | rtKitLabel: translate() : { label: entry.label }\n \">\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n [rtMod]=\"{ child: true, disabled: true }\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-disabled]=\"true\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n [rtMod]=\"{ child: true }\"\n [attr.data-id]=\"entry.id\"\n (click)=\"onMobileItemClick(entry.id)\">\n <span rtElem=\"label\">{{ entry.label }}</span>\n @if (entry.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"entry.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n </div>\n }\n </div>\n }\n }\n @case (EntryKind.Link) {\n <a\n rtElem=\"link\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n routerLinkActive=\"rt-page-header-mobile__link--is-active\"\n [attr.data-id]=\"section.id\"\n [routerLink]=\"section.route\"\n [routerLinkActiveOptions]=\"{ exact: section.routerLinkActiveExact }\"\n (click)=\"closeNavPanels()\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </a>\n }\n @default {\n @if (section.disabled) {\n <span\n rtElem=\"disabled-slot\"\n role=\"none\"\n [rtTooltip]=\"'uiSectionInProgress' | rtKitLabel: translate() : { label: section.label }\">\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n [rtMod]=\"{ disabled: true }\"\n [attr.data-id]=\"section.id\"\n [attr.aria-disabled]=\"true\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n </button>\n </span>\n } @else {\n <button\n rtElem=\"link\"\n type=\"button\"\n role=\"menuitem\"\n qa-dataid=\"header-nav-mobile-item\"\n [attr.data-id]=\"section.id\"\n (click)=\"onMobileItemClick(section.id)\">\n @if (section.icon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"section.icon\" />\n }\n <span rtElem=\"label\">{{ section.label }}</span>\n @if (section.unread) {\n <span\n rtElem=\"marker\"\n role=\"img\"\n qa-dataid=\"header-nav-marker\"\n [attr.data-id]=\"section.id\"\n [attr.aria-label]=\"t().uiNavUnread\"></span>\n }\n </button>\n }\n }\n }\n }\n </div>\n </ng-template>\n\n <ng-content select=\"[rtHeaderBell]\" />\n\n @if (user(); as u) {\n <rt-page-header-user\n [name]=\"u.name\"\n [avatar]=\"userAvatar()\"\n [menu]=\"userMenu()\"\n [backdropClass]=\"userMenuBackdropClass()\"\n (userClick)=\"onUserClick()\" />\n }\n </ng-container>\n}\n","import { inject, Directive, TemplateRef } from '@angular/core';\n\n/** Отбор страницы. Шаблон один, а встаёт он в ряд, под кнопку «Ещё отборы» или в шторку телефона. */\n@Directive({ selector: '[rtPageBarFilter]' })\nexport class RtPageBarFilterDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/** Поиск страницы: поле занимает свободное место ряда, а на телефоне встаёт в шторку над отборами. */\n@Directive({ selector: '[rtPageBarSearch]' })\nexport class RtPageBarSearchDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","/** Ширина шапки, с которой отборы и действия уходят в кнопки, как на телефоне. */\nconst NARROW_WIDTH: number = 768;\n/** Отступы шапки от краёв страницы: по 20 с каждой стороны. */\nconst INLINE_PADDING: number = 40;\n/**\n * Ширины, по которым считается раскладка. Ширины отбора и кнопки «Ещё отборы» стоят и в стилях\n * шапки; их равенство держит тест `rt-page-bar.logic.spec.ts`, разойтись молча им не дадут.\n * Промежуток — шаг `--rt-space-3`, минимум поиска есть только здесь: в стилях поиск гибкий.\n */\nexport const RT_PAGE_BAR_SIZES: Readonly<{ gap: number; filterOneRow: number; filterTwoRows: number; searchMin: number; more: number }> = {\n gap: 12,\n filterOneRow: 170,\n filterTwoRows: 150,\n // Шапка 1280 с заголовком «Все брони», тремя отборами и тремя действиями встаёт в одну строку,\n // как на одобренных кадрах: нужно 1185 при 1190 доступных.\n searchMin: 390,\n more: 185,\n};\n\nconst GAP: number = RT_PAGE_BAR_SIZES.gap;\nconst FILTER_ONE_ROW: number = RT_PAGE_BAR_SIZES.filterOneRow;\nconst FILTER_TWO_ROWS: number = RT_PAGE_BAR_SIZES.filterTwoRows;\nconst SEARCH_MIN: number = RT_PAGE_BAR_SIZES.searchMin;\nconst MORE_WIDTH: number = RT_PAGE_BAR_SIZES.more;\n\nexport namespace IRtPageBarFit {\n export type Mode = 'one' | 'two' | 'narrow';\n\n export interface Input {\n /** Ширина самой шапки: на странице, суженной ассистентом, она меньше окна. */\n readonly width: number;\n readonly titleWidth: number;\n readonly actionsWidth: number;\n readonly filterCount: number;\n readonly hasSearch: boolean;\n }\n\n export interface Result {\n readonly mode: Mode;\n /** Сколько отборов стоит в ряду; остальные лежат под кнопкой «Ещё отборы». */\n readonly rowFilters: number;\n }\n}\n\n/** Ширина панели действий: кнопки по 32 с промежутком 8. */\nexport function actionsWidthOf(count: number): number {\n return count > 0 ? count * 40 - 8 : 0;\n}\n\nfunction filtersInSecondRow(content: number, count: number, hasSearch: boolean): number {\n const room: number = content - (hasSearch ? SEARCH_MIN + GAP : 0);\n const fitting: number = Math.floor((room + GAP) / (FILTER_TWO_ROWS + GAP));\n if (fitting >= count) {\n return count;\n }\n return Math.max(0, Math.floor((room - MORE_WIDTH) / (FILTER_TWO_ROWS + GAP)));\n}\n\n/**\n * Сколько строк нужно шапке и сколько отборов в них встаёт. Третьей строки нет: что не встало во\n * вторую, уходит под кнопку. Ширина без замера (скрытая шапка) оставляет одну строку.\n */\nexport function pageBarFit(input: IRtPageBarFit.Input): IRtPageBarFit.Result {\n if (input.width <= 0) {\n return { mode: 'one', rowFilters: input.filterCount };\n }\n if (input.width <= NARROW_WIDTH) {\n return { mode: 'narrow', rowFilters: 0 };\n }\n const content: number = input.width - INLINE_PADDING;\n const oneRow: number =\n input.titleWidth +\n (input.hasSearch ? GAP + SEARCH_MIN : 0) +\n input.filterCount * (GAP + FILTER_ONE_ROW) +\n (input.actionsWidth > 0 ? GAP + input.actionsWidth : 0);\n // Без поиска и отборов во вторую строку уводить нечего: длинный заголовок обрезается в первой.\n if (oneRow <= content || (!input.hasSearch && input.filterCount === 0)) {\n return { mode: 'one', rowFilters: input.filterCount };\n }\n return { mode: 'two', rowFilters: filtersInSecondRow(content, input.filterCount, input.hasSearch) };\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { DOCUMENT, NgTemplateOutlet } from '@angular/common';\nimport {\n afterRenderEffect,\n booleanAttribute,\n computed,\n contentChild,\n contentChildren,\n inject,\n input,\n linkedSignal,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective, WINDOW } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtBottomSheetComponent } from '@rt-tools/ui-kit-v2/bottom-sheet';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtMenuComponent, RtMenuItemComponent } from '@rt-tools/ui-kit-v2/menu';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtPageBarFilterDirective, RtPageBarSearchDirective } from './rt-page-bar-slots.directive';\nimport { actionsWidthOf, pageBarFit, IRtPageBarFit } from './rt-page-bar.logic';\nimport { IRtPageBar } from './rt-page-bar.model';\n\nconst BEM_BLOCK: string = 'rt-page-bar';\n\n/**\n * Компактная шапка страницы: одна строка 56 или две строки 104. Вид считается по ширине самой\n * шапки, а не окна: страница, суженная ассистентом, уводит отборы так же, как телефон. Шапка\n * отдельная часть: страница без неё остаётся со своим заголовком.\n */\n@Component({\n selector: 'rt-page-bar',\n templateUrl: './rt-page-bar.component.html',\n styleUrl: './rt-page-bar.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n RtBottomSheetComponent,\n RtButtonDirective,\n RtIconButtonComponent,\n RtMenuComponent,\n RtMenuItemComponent,\n RtPopoverDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: { class: BEM_BLOCK, '[class.rt-page-bar--narrow]': 'isNarrow()' },\n})\nexport class RtPageBarComponent {\n readonly #host: HTMLElement = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n readonly #window: Window & typeof globalThis = inject(WINDOW) as Window & typeof globalThis;\n\n readonly #width: WritableSignal<number> = signal<number>(0);\n\n readonly #titleWidth: WritableSignal<number> = signal<number>(0);\n\n /** Сколько раз догружались шрифты: заголовок, замеренный запасным шрифтом, меряется снова. */\n readonly #fontLoads: WritableSignal<number> = signal<number>(0);\n\n readonly #fit: Signal<IRtPageBarFit.Result> = computed((): IRtPageBarFit.Result =>\n pageBarFit({\n width: this.#width(),\n titleWidth: this.#titleWidth(),\n actionsWidth: actionsWidthOf(this.actions().length),\n filterCount: this.filters().length,\n hasSearch: this.search() !== undefined,\n })\n );\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly titleRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('title');\n\n protected readonly filters: Signal<ReadonlyArray<RtPageBarFilterDirective>> = contentChildren(RtPageBarFilterDirective);\n\n protected readonly search: Signal<RtPageBarSearchDirective | undefined> = contentChild(RtPageBarSearchDirective);\n\n protected readonly mode: Signal<IRtPageBarFit.Mode> = computed((): IRtPageBarFit.Mode => this.#fit().mode);\n\n protected readonly isNarrow: Signal<boolean> = computed((): boolean => this.mode() === 'narrow');\n\n protected readonly rowFilters: Signal<ReadonlyArray<RtPageBarFilterDirective>> = computed((): ReadonlyArray<RtPageBarFilterDirective> =>\n this.filters().slice(0, this.#fit().rowFilters)\n );\n\n protected readonly moreFilters: Signal<ReadonlyArray<RtPageBarFilterDirective>> = computed(\n (): ReadonlyArray<RtPageBarFilterDirective> => this.filters().slice(this.#fit().rowFilters)\n );\n\n /** Шторка отборов узкого вида: смена вида её закрывает, и при возврате в узкий она не открывается сама. */\n protected readonly sheetOpen: WritableSignal<boolean> = linkedSignal<boolean, boolean>({\n source: this.isNarrow,\n computation: (): boolean => false,\n });\n\n public readonly pageTitle: InputSignal<string> = input.required<string>();\n\n public readonly actions: InputSignal<ReadonlyArray<IRtPageBar.Action>> = input<ReadonlyArray<IRtPageBar.Action>>([]);\n\n /** Отборы применены: на кнопке отборов узкого вида горит точка. */\n public readonly filtersActive: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly actionClick: OutputEmitterRef<string> = output<string>();\n\n /** Нажата «Применить» в шторке отборов узкого вида. */\n public readonly filtersApply: OutputEmitterRef<void> = output<void>();\n\n constructor() {\n const destroyRef: DestroyRef = inject(DestroyRef);\n let watch: ResizeObserver | null = null;\n\n // Заголовок меряется в широком виде и заново после смены текста, шрифтов и возврата из узкого.\n // В узком виде он растянут и мельче, и замер дал бы ширину строки, а не текста.\n afterRenderEffect((): void => {\n if (watch === null && 'ResizeObserver' in this.#window) {\n watch = new this.#window.ResizeObserver((): void => this.#width.set(this.#host.getBoundingClientRect().width));\n watch.observe(this.#host);\n }\n this.pageTitle();\n this.#fontLoads();\n const title: HTMLElement | undefined = this.titleRef()?.nativeElement;\n if (title !== undefined && !this.isNarrow()) {\n this.#titleWidth.set(title.scrollWidth);\n }\n });\n\n const doc: Document = inject(DOCUMENT);\n const fonts: FontFaceSet | null = 'fonts' in doc ? doc.fonts : null;\n const onFontsLoaded: () => void = (): void => this.#fontLoads.update((count: number): number => count + 1);\n fonts?.addEventListener('loadingdone', onFontsLoaded);\n\n destroyRef.onDestroy((): void => {\n watch?.disconnect();\n fonts?.removeEventListener('loadingdone', onFontsLoaded);\n });\n }\n\n protected onApply(): void {\n this.filtersApply.emit();\n this.sheetOpen.set(false);\n }\n}\n","<ng-container rtBlock=\"rt-page-bar\">\n <div rtElem=\"row\">\n <h1 rtElem=\"title\" qa-dataid=\"page-bar-title\" #title [attr.title]=\"pageTitle()\">{{ pageTitle() }}</h1>\n\n @switch (mode()) {\n @case ('narrow') {\n <span rtElem=\"spacer\"></span>\n @if (filters().length > 0 || search()) {\n <span rtElem=\"filters-trigger\">\n <rt-icon-button\n icon=\"filter\"\n size=\"sm\"\n qa-dataid=\"page-bar-filters\"\n [ariaLabel]=\"filtersActive() ? t().uiFiltersActive : t().uiFilters\"\n (click)=\"sheetOpen.set(true)\" />\n @if (filtersActive()) {\n <span rtElem=\"dot\" qa-dataid=\"page-bar-filters-dot\"></span>\n }\n </span>\n }\n @if (actions().length > 0) {\n <rt-menu qa-dataid=\"page-bar-actions-menu\" triggerSize=\"sm\" panelClass=\"rt-page-bar-menu\" [ariaLabel]=\"t().uiActions\">\n @for (action of actions(); track action.id) {\n <rt-menu-item\n [icon]=\"action.icon\"\n [label]=\"action.label\"\n [disabled]=\"action.disabled ?? false\"\n (selected)=\"actionClick.emit(action.id)\" />\n }\n </rt-menu>\n }\n }\n @case ('one') {\n <ng-container [ngTemplateOutlet]=\"filterRow\" [ngTemplateOutletContext]=\"{ wide: true }\" />\n <ng-container [ngTemplateOutlet]=\"actionRow\" />\n }\n @default {\n <span rtElem=\"spacer\"></span>\n <ng-container [ngTemplateOutlet]=\"actionRow\" />\n }\n }\n </div>\n\n @if (mode() === 'two') {\n <div rtElem=\"row\" qa-dataid=\"page-bar-second-row\">\n <ng-container [ngTemplateOutlet]=\"filterRow\" [ngTemplateOutletContext]=\"{ wide: false }\" />\n @if (moreFilters().length > 0) {\n <button\n rtButton\n rtElem=\"more\"\n type=\"button\"\n theme=\"secondary\"\n appearance=\"outlined\"\n size=\"sm\"\n icon=\"ico-plus\"\n qa-dataid=\"page-bar-more-filters\"\n rtPopoverAlign=\"end\"\n [label]=\"t().uiMoreFilters + ' · ' + moreFilters().length\"\n [attr.aria-label]=\"t().uiMoreFilters + ' · ' + moreFilters().length\"\n [rtPopover]=\"morePanel\"></button>\n }\n </div>\n }\n\n @if (isNarrow() && sheetOpen()) {\n <rt-bottom-sheet [open]=\"true\" (openChange)=\"sheetOpen.set($event)\">\n <span sheetHeader>{{ t().uiPageFilters }}</span>\n <div rtElem=\"sheet\" qa-dataid=\"page-bar-sheet\">\n @if (search(); as searchSlot) {\n <ng-container [ngTemplateOutlet]=\"searchSlot.templateRef\" />\n }\n @for (filter of filters(); track filter) {\n <ng-container [ngTemplateOutlet]=\"filter.templateRef\" />\n }\n </div>\n <button sheetFooter rtButton rtElem=\"apply\" type=\"button\" qa-dataid=\"page-bar-apply\" (click)=\"onApply()\">\n {{ t().uiApply }}\n </button>\n </rt-bottom-sheet>\n }\n\n <ng-template #filterRow let-wide=\"wide\">\n @if (search(); as searchSlot) {\n <div rtElem=\"search\"><ng-container [ngTemplateOutlet]=\"searchSlot.templateRef\" /></div>\n }\n @for (filter of rowFilters(); track filter) {\n <div rtElem=\"filter\" [rtMod]=\"{ wide: wide }\"><ng-container [ngTemplateOutlet]=\"filter.templateRef\" /></div>\n }\n </ng-template>\n\n <ng-template #actionRow>\n @if (actions().length > 0) {\n <div rtElem=\"actions\">\n @for (action of actions(); track action.id) {\n <rt-icon-button\n qa-dataid=\"page-bar-action\"\n size=\"sm\"\n variant=\"primary\"\n [attr.data-id]=\"action.id\"\n [icon]=\"action.icon\"\n [ariaLabel]=\"action.label\"\n [tooltip]=\"action.label\"\n [disabled]=\"action.disabled ?? false\"\n (click)=\"actionClick.emit(action.id)\" />\n }\n </div>\n }\n </ng-template>\n\n <ng-template #morePanel>\n <div rtBlock=\"rt-page-bar-more\" qa-dataid=\"page-bar-more-panel\">\n @for (filter of moreFilters(); track filter) {\n <ng-container [ngTemplateOutlet]=\"filter.templateRef\" />\n }\n </div>\n </ng-template>\n</ng-container>\n"],"mappings":"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"}