@rt-tools/ui-kit-v2 0.27.0 → 0.29.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 (53) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +2 -2
  2. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-card.mjs +4 -4
  4. package/fesm2022/rt-tools-ui-kit-v2-card.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-container.mjs +9 -4
  6. package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -1
  7. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +37 -4
  8. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +2 -2
  10. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +1 -1
  12. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
  13. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +1 -1
  14. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
  15. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +2 -2
  16. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
  17. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +1 -1
  18. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
  19. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +2 -2
  20. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -1
  21. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +367 -23
  22. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
  23. package/fesm2022/rt-tools-ui-kit-v2-pdf-viewer.mjs +2 -2
  24. package/fesm2022/rt-tools-ui-kit-v2-pdf-viewer.mjs.map +1 -1
  25. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +2 -2
  26. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  27. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +2 -2
  28. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -1
  29. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +2 -2
  30. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
  31. package/package.json +1 -1
  32. package/src/lib/components/calendar/rt-calendar.component.scss +3 -2
  33. package/src/lib/components/card/rt-card.component.scss +10 -0
  34. package/src/lib/components/container/CONTEXT.md +6 -0
  35. package/src/lib/components/container/rt-container.component.scss +4 -0
  36. package/src/lib/components/data-list/toolbar/rt-data-list-toolbar.component.scss +1 -1
  37. package/src/lib/components/dynamic-list/rt-dynamic-list.component.scss +1 -1
  38. package/src/lib/components/filter-control/rt-filter-control.component.scss +4 -2
  39. package/src/lib/components/page-header/CONTEXT.md +12 -0
  40. package/src/lib/components/page-header/more/rt-page-header-more.component.scss +7 -0
  41. package/src/lib/components/page-header/rt-page-header-mobile.scss +24 -0
  42. package/src/lib/components/page-header/rt-page-header.component.scss +25 -3
  43. package/src/lib/components/pdf-viewer/rt-pdf-viewer.component.scss +1 -1
  44. package/src/lib/components/toolbar/rt-toolbar.component.scss +3 -1
  45. package/src/lib/components/workspace/rt-workspace.component.scss +8 -6
  46. package/src/rich-editor/lib/components/chat/rt-chat.component.scss +5 -3
  47. package/src/styles/_breakpoints.scss +19 -0
  48. package/src/styles/_index.scss +4 -0
  49. package/src/styles/_place.scss +7 -0
  50. package/styles/tokens.css +8 -0
  51. package/types/rt-tools-ui-kit-v2-card.d.ts +1 -1
  52. package/types/rt-tools-ui-kit-v2-core.d.ts +24 -5
  53. package/types/rt-tools-ui-kit-v2-page-header.d.ts +60 -6
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-page-header.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/page-header/rt-page-header.logic.ts","../../../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}\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 };\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 * Разделы, у которых активен хоть один пункт панели. Обход идёт по раскрытому\n * списку пунктов: своего адреса у раздела с панелью нет, и подсветить его больше\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\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","import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport {\n afterNextRender,\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 { activeSectionIds, compactSectionsOf, ERtPageHeaderEntry, IRtPageHeaderView, isStuck, toSections } from './rt-page-header.logic';\nimport { IRtPageHeader } from './rt-page-header.model';\n\nconst BEM_BLOCK: string = 'rt-page-header';\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 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 /* Реактивный 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 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 * 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 * области: наблюдатель пересечения с порогом в единицу ловит ровно этот момент — и в окне,\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\" [attr.aria-label]=\"navAriaLabel()\">\n <ul rtElem=\"list\" role=\"list\">\n @for (section of sections(); track section.id) {\n <li rtElem=\"item\" qa-dataid=\"header-nav-item\" [attr.data-id]=\"section.id\">\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 </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 [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 <button\n rtElem=\"user\"\n type=\"button\"\n qa-dataid=\"header-user-menu\"\n #userPopover=\"rtPopover\"\n rtPopoverTrigger=\"hover\"\n rtPopoverAlign=\"end\"\n rtPopoverOffsetY=\"14\"\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":"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"}
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/**\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 * 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 [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 <button\n rtElem=\"user\"\n type=\"button\"\n qa-dataid=\"header-user-menu\"\n #userPopover=\"rtPopover\"\n rtPopoverTrigger=\"hover\"\n rtPopoverAlign=\"end\"\n rtPopoverOffsetY=\"14\"\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":"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"}
@@ -509,7 +509,7 @@ var RtPdfViewerComponent = class RtPdfViewerComponent {
509
509
  ],
510
510
  ngImport: i0,
511
511
  template: "<ng-container rtBlock=\"rt-pdf-viewer\">\n <!-- Ловушка держит Tab внутри; фокус ставит сам компонент, поэтому авто-захвата здесь нет -->\n <div rtElem=\"surface\" cdkTrapFocus>\n <!-- Полоса видна сразу, ещё до загрузки документа: человек видит, что открыл, и может закрыть -->\n <header rtElem=\"bar\">\n <div rtElem=\"title\">\n <rt-icon rtElem=\"file-icon\" name=\"attach-pdf\" size=\"md\" />\n <span rtElem=\"file-name\" qa-dataid=\"pdf-viewer-file-name\" [attr.title]=\"fileName\">{{ fileName }}</span>\n </div>\n\n <div rtElem=\"actions\">\n <rt-icon-button\n qa-dataid=\"pdf-viewer-print\"\n icon=\"print\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerPrint\"\n [tooltip]=\"t().pdfViewerPrint\"\n [disabled]=\"status() !== 'ready'\"\n [loading]=\"printing()\"\n (clicked)=\"print()\" />\n <rt-icon-button\n qa-dataid=\"pdf-viewer-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerDownload\"\n [tooltip]=\"t().pdfViewerDownload\"\n (clicked)=\"download()\" />\n <rt-icon-button\n qa-dataid=\"pdf-viewer-close\"\n icon=\"close\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerClose\"\n [tooltip]=\"t().pdfViewerClose\"\n (clicked)=\"close()\" />\n </div>\n </header>\n\n <div rtElem=\"scroller\" qa-dataid=\"pdf-viewer-pages\" #scroller (scroll)=\"onScroll()\">\n <!-- Столбец стоит и до загрузки: по его ширине выбирается начальный масштаб -->\n <div rtElem=\"column\" #column>\n @if (status() === 'ready') {\n @for (box of boxes(); track box.index) {\n <div\n rtElem=\"page\"\n qa-dataid=\"pdf-viewer-page\"\n #page\n [attr.data-page-index]=\"box.index\"\n [style.width.px]=\"box.width\"\n [style.height.px]=\"box.height\">\n <canvas rtElem=\"canvas\" #canvas></canvas>\n </div>\n }\n }\n </div>\n </div>\n\n @switch (status()) {\n @case ('loading') {\n <div rtElem=\"center\">\n <rt-spinner qa-dataid=\"pdf-viewer-spinner\" color=\"on-primary\" [diameter]=\"40\" />\n </div>\n }\n\n @case ('error') {\n <div rtElem=\"center\">\n <rt-empty-state\n rtElem=\"error\"\n qa-dataid=\"pdf-viewer-error\"\n [title]=\"t().pdfViewerErrorTitle\"\n [description]=\"t().pdfViewerErrorText\">\n <button\n rtButton\n rtElem=\"error-download\"\n qa-dataid=\"pdf-viewer-error-download\"\n type=\"button\"\n icon=\"ico-download\"\n [label]=\"t().pdfViewerDownload\"\n [attr.aria-label]=\"t().pdfViewerDownload\"\n (click)=\"download()\"></button>\n </rt-empty-state>\n </div>\n }\n\n @case ('ready') {\n <div rtElem=\"toolbar\" qa-dataid=\"pdf-viewer-toolbar\">\n <span rtElem=\"counter\" qa-dataid=\"pdf-viewer-counter\" role=\"status\" aria-live=\"off\" [attr.aria-label]=\"pageOfLabel()\">\n {{ counter() }}\n </span>\n <span rtElem=\"divider\" aria-hidden=\"true\"></span>\n <rt-icon-button\n qa-dataid=\"pdf-viewer-zoom-out\"\n icon=\"minus\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().pdfViewerZoomOut\"\n [disabled]=\"!canZoomOut()\"\n (clicked)=\"zoomOut()\" />\n <span rtElem=\"zoom\" qa-dataid=\"pdf-viewer-zoom\">{{ zoomLabel() }}</span>\n <rt-icon-button\n qa-dataid=\"pdf-viewer-zoom-in\"\n icon=\"ico-plus\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().pdfViewerZoomIn\"\n [disabled]=\"!canZoomIn()\"\n (clicked)=\"zoomIn()\" />\n <span rtElem=\"fit-divider\" aria-hidden=\"true\"></span>\n <button\n rtButton\n rtElem=\"fit\"\n qa-dataid=\"pdf-viewer-fit\"\n type=\"button\"\n appearance=\"text\"\n size=\"sm\"\n [label]=\"t().pdfViewerFitWidth\"\n [attr.aria-label]=\"t().pdfViewerFitWidth\"\n [pressed]=\"isFit()\"\n (click)=\"fitWidth()\"></button>\n </div>\n }\n }\n </div>\n</ng-container>\n",
512
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-pdf-viewer{--rt-pdf-viewer-bg: var(--rt-neutral-900);--rt-pdf-viewer-bar-bg: color-mix(in srgb, var(--rt-neutral-900) 35%, var(--rt-neutral-950));--rt-pdf-viewer-bar-height: var(--rt-control-height-2xl);--rt-pdf-viewer-text-color: var(--rt-neutral-0);--rt-pdf-viewer-muted-color: var(--rt-neutral-200);--rt-pdf-viewer-page-bg: var(--rt-neutral-0);--rt-pdf-viewer-page-shadow: var(--rt-shadow-md);--rt-pdf-viewer-page-gap: var(--rt-space-4);--rt-pdf-viewer-toolbar-bg: var(--rt-neutral-800);--rt-pdf-viewer-toolbar-radius: var(--rt-radius-full);--rt-pdf-viewer-divider-width: var(--rt-border-width-thin);--rt-pdf-viewer-divider-color: color-mix(in srgb, var(--rt-neutral-0) 20%, transparent);--rt-pdf-viewer-control-radius: var(--rt-radius-md);--rt-pdf-viewer-control-bg: color-mix(in srgb, var(--rt-neutral-0) 10%, transparent);--rt-pdf-viewer-control-bg-hover: color-mix(in srgb, var(--rt-neutral-0) 24%, transparent);display:block;width:100vw;height:100vh;height:100dvh;background:var(--rt-pdf-viewer-bg);color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__surface{position:absolute;display:flex;flex-direction:column;inset:0}.rt-pdf-viewer__bar{display:flex;height:var(--rt-pdf-viewer-bar-height);flex:none;align-items:center;justify-content:space-between;padding:0 var(--rt-space-4);background:var(--rt-pdf-viewer-bar-bg);gap:var(--rt-space-4)}.rt-pdf-viewer__title{display:flex;min-width:0;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__file-icon{flex:none;color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__file-name{overflow:hidden;min-width:0;font-size:var(--rt-text-sm);text-overflow:ellipsis;white-space:nowrap}.rt-pdf-viewer__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__actions rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover);border-radius:var(--rt-pdf-viewer-control-radius);background:var(--rt-pdf-viewer-control-bg)}.rt-pdf-viewer__scroller{position:relative;overflow:auto;flex:1 1 auto;overscroll-behavior:contain;scrollbar-gutter:stable}.rt-pdf-viewer__column{display:flex;width:max-content;min-width:100%;box-sizing:border-box;flex-direction:column;align-items:center;padding:var(--rt-space-4) var(--rt-space-4) var(--rt-space-24);gap:var(--rt-pdf-viewer-page-gap)}.rt-pdf-viewer__page{flex:none;background:var(--rt-pdf-viewer-page-bg);box-shadow:var(--rt-pdf-viewer-page-shadow)}.rt-pdf-viewer__canvas{display:block;width:100%;height:100%}.rt-pdf-viewer__center{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-4);inset:var(--rt-pdf-viewer-bar-height) 0 0}.rt-pdf-viewer .rt-pdf-viewer__error{--rt-empty-state-title-color: var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer .rt-pdf-viewer__error .rt-empty-state__description{color:var(--rt-pdf-viewer-muted-color)}.rt-pdf-viewer .rt-pdf-viewer__error-download{--rt-btn-bg: var(--rt-pdf-viewer-page-bg);--rt-btn-bg-hover: var(--rt-neutral-100);--rt-btn-bg-active: var(--rt-neutral-200);--rt-btn-color: var(--rt-neutral-900)}.rt-pdf-viewer__toolbar{position:absolute;bottom:var(--rt-space-6);left:50%;display:flex;align-items:center;padding:var(--rt-space-1) var(--rt-space-2);border-radius:var(--rt-pdf-viewer-toolbar-radius);background:var(--rt-pdf-viewer-toolbar-bg);gap:var(--rt-space-1);transform:translate(-50%);white-space:nowrap}.rt-pdf-viewer__toolbar rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}.rt-pdf-viewer__counter,.rt-pdf-viewer__zoom{padding:0 var(--rt-space-2);font-size:var(--rt-text-sm);font-variant-numeric:tabular-nums}.rt-pdf-viewer__zoom{min-width:var(--rt-size-12);text-align:center}.rt-pdf-viewer__divider,.rt-pdf-viewer__fit-divider{width:var(--rt-pdf-viewer-divider-width);height:var(--rt-size-5);margin:0 var(--rt-space-1);background:var(--rt-pdf-viewer-divider-color)}.rt-pdf-viewer .rt-pdf-viewer__fit{--rt-btn-color: var(--rt-pdf-viewer-text-color);--rt-btn-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}@media(width<=480px){.rt-pdf-viewer{--rt-pdf-viewer-bar-height: var(--rt-control-height-xl)}.rt-pdf-viewer__fit,.rt-pdf-viewer__fit-divider{display:none}}.rt-pdf-viewer-print{display:none}.rt-pdf-viewer-print__page{display:block;width:100%;break-after:page;break-inside:avoid}@media print{.rt-pdf-viewer-printing body>:not(.rt-pdf-viewer-print){display:none}.rt-pdf-viewer-printing .rt-pdf-viewer-print{display:block}}}\n"],
512
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-pdf-viewer{--rt-pdf-viewer-bg: var(--rt-neutral-900);--rt-pdf-viewer-bar-bg: color-mix(in srgb, var(--rt-neutral-900) 35%, var(--rt-neutral-950));--rt-pdf-viewer-bar-height: var(--rt-control-height-2xl);--rt-pdf-viewer-text-color: var(--rt-neutral-0);--rt-pdf-viewer-muted-color: var(--rt-neutral-200);--rt-pdf-viewer-page-bg: var(--rt-neutral-0);--rt-pdf-viewer-page-shadow: var(--rt-shadow-md);--rt-pdf-viewer-page-gap: var(--rt-space-4);--rt-pdf-viewer-toolbar-bg: var(--rt-neutral-800);--rt-pdf-viewer-toolbar-radius: var(--rt-radius-full);--rt-pdf-viewer-divider-width: var(--rt-border-width-thin);--rt-pdf-viewer-divider-color: color-mix(in srgb, var(--rt-neutral-0) 20%, transparent);--rt-pdf-viewer-control-radius: var(--rt-radius-md);--rt-pdf-viewer-control-bg: color-mix(in srgb, var(--rt-neutral-0) 10%, transparent);--rt-pdf-viewer-control-bg-hover: color-mix(in srgb, var(--rt-neutral-0) 24%, transparent);display:block;width:100vw;height:100vh;height:100dvh;background:var(--rt-pdf-viewer-bg);color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__surface{position:absolute;display:flex;flex-direction:column;inset:0}.rt-pdf-viewer__bar{display:flex;height:var(--rt-pdf-viewer-bar-height);flex:none;align-items:center;justify-content:space-between;padding:0 var(--rt-space-4);background:var(--rt-pdf-viewer-bar-bg);gap:var(--rt-space-4)}.rt-pdf-viewer__title{display:flex;min-width:0;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__file-icon{flex:none;color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__file-name{overflow:hidden;min-width:0;font-size:var(--rt-text-sm);text-overflow:ellipsis;white-space:nowrap}.rt-pdf-viewer__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__actions rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover);border-radius:var(--rt-pdf-viewer-control-radius);background:var(--rt-pdf-viewer-control-bg)}.rt-pdf-viewer__scroller{position:relative;overflow:auto;flex:1 1 auto;overscroll-behavior:contain;scrollbar-gutter:stable}.rt-pdf-viewer__column{display:flex;width:max-content;min-width:100%;box-sizing:border-box;flex-direction:column;align-items:center;padding:var(--rt-space-4) var(--rt-space-4) var(--rt-space-24);gap:var(--rt-pdf-viewer-page-gap)}.rt-pdf-viewer__page{flex:none;background:var(--rt-pdf-viewer-page-bg);box-shadow:var(--rt-pdf-viewer-page-shadow)}.rt-pdf-viewer__canvas{display:block;width:100%;height:100%}.rt-pdf-viewer__center{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-4);inset:var(--rt-pdf-viewer-bar-height) 0 0}.rt-pdf-viewer .rt-pdf-viewer__error{--rt-empty-state-title-color: var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer .rt-pdf-viewer__error .rt-empty-state__description{color:var(--rt-pdf-viewer-muted-color)}.rt-pdf-viewer .rt-pdf-viewer__error-download{--rt-btn-bg: var(--rt-pdf-viewer-page-bg);--rt-btn-bg-hover: var(--rt-neutral-100);--rt-btn-bg-active: var(--rt-neutral-200);--rt-btn-color: var(--rt-neutral-900)}.rt-pdf-viewer__toolbar{position:absolute;bottom:var(--rt-space-6);left:50%;display:flex;align-items:center;padding:var(--rt-space-1) var(--rt-space-2);border-radius:var(--rt-pdf-viewer-toolbar-radius);background:var(--rt-pdf-viewer-toolbar-bg);gap:var(--rt-space-1);transform:translate(-50%);white-space:nowrap}.rt-pdf-viewer__toolbar rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}.rt-pdf-viewer__counter,.rt-pdf-viewer__zoom{padding:0 var(--rt-space-2);font-size:var(--rt-text-sm);font-variant-numeric:tabular-nums}.rt-pdf-viewer__zoom{min-width:var(--rt-size-12);text-align:center}.rt-pdf-viewer__divider,.rt-pdf-viewer__fit-divider{width:var(--rt-pdf-viewer-divider-width);height:var(--rt-size-5);margin:0 var(--rt-space-1);background:var(--rt-pdf-viewer-divider-color)}.rt-pdf-viewer .rt-pdf-viewer__fit{--rt-btn-color: var(--rt-pdf-viewer-text-color);--rt-btn-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}@container rt-place (width <= 480px){.rt-pdf-viewer{--rt-pdf-viewer-bar-height: var(--rt-control-height-xl)}.rt-pdf-viewer__fit,.rt-pdf-viewer__fit-divider{display:none}}.rt-pdf-viewer-print{display:none}.rt-pdf-viewer-print__page{display:block;width:100%;break-after:page;break-inside:avoid}@media print{.rt-pdf-viewer-printing body>:not(.rt-pdf-viewer-print){display:none}.rt-pdf-viewer-printing .rt-pdf-viewer-print{display:block}}}\n"],
513
513
  dependencies: [
514
514
  {
515
515
  kind: "directive",
@@ -649,7 +649,7 @@ i0.ɵɵngDeclareClassMetadata({
649
649
  "(window:resize)": "onResize()"
650
650
  },
651
651
  template: "<ng-container rtBlock=\"rt-pdf-viewer\">\n <!-- Ловушка держит Tab внутри; фокус ставит сам компонент, поэтому авто-захвата здесь нет -->\n <div rtElem=\"surface\" cdkTrapFocus>\n <!-- Полоса видна сразу, ещё до загрузки документа: человек видит, что открыл, и может закрыть -->\n <header rtElem=\"bar\">\n <div rtElem=\"title\">\n <rt-icon rtElem=\"file-icon\" name=\"attach-pdf\" size=\"md\" />\n <span rtElem=\"file-name\" qa-dataid=\"pdf-viewer-file-name\" [attr.title]=\"fileName\">{{ fileName }}</span>\n </div>\n\n <div rtElem=\"actions\">\n <rt-icon-button\n qa-dataid=\"pdf-viewer-print\"\n icon=\"print\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerPrint\"\n [tooltip]=\"t().pdfViewerPrint\"\n [disabled]=\"status() !== 'ready'\"\n [loading]=\"printing()\"\n (clicked)=\"print()\" />\n <rt-icon-button\n qa-dataid=\"pdf-viewer-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerDownload\"\n [tooltip]=\"t().pdfViewerDownload\"\n (clicked)=\"download()\" />\n <rt-icon-button\n qa-dataid=\"pdf-viewer-close\"\n icon=\"close\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerClose\"\n [tooltip]=\"t().pdfViewerClose\"\n (clicked)=\"close()\" />\n </div>\n </header>\n\n <div rtElem=\"scroller\" qa-dataid=\"pdf-viewer-pages\" #scroller (scroll)=\"onScroll()\">\n <!-- Столбец стоит и до загрузки: по его ширине выбирается начальный масштаб -->\n <div rtElem=\"column\" #column>\n @if (status() === 'ready') {\n @for (box of boxes(); track box.index) {\n <div\n rtElem=\"page\"\n qa-dataid=\"pdf-viewer-page\"\n #page\n [attr.data-page-index]=\"box.index\"\n [style.width.px]=\"box.width\"\n [style.height.px]=\"box.height\">\n <canvas rtElem=\"canvas\" #canvas></canvas>\n </div>\n }\n }\n </div>\n </div>\n\n @switch (status()) {\n @case ('loading') {\n <div rtElem=\"center\">\n <rt-spinner qa-dataid=\"pdf-viewer-spinner\" color=\"on-primary\" [diameter]=\"40\" />\n </div>\n }\n\n @case ('error') {\n <div rtElem=\"center\">\n <rt-empty-state\n rtElem=\"error\"\n qa-dataid=\"pdf-viewer-error\"\n [title]=\"t().pdfViewerErrorTitle\"\n [description]=\"t().pdfViewerErrorText\">\n <button\n rtButton\n rtElem=\"error-download\"\n qa-dataid=\"pdf-viewer-error-download\"\n type=\"button\"\n icon=\"ico-download\"\n [label]=\"t().pdfViewerDownload\"\n [attr.aria-label]=\"t().pdfViewerDownload\"\n (click)=\"download()\"></button>\n </rt-empty-state>\n </div>\n }\n\n @case ('ready') {\n <div rtElem=\"toolbar\" qa-dataid=\"pdf-viewer-toolbar\">\n <span rtElem=\"counter\" qa-dataid=\"pdf-viewer-counter\" role=\"status\" aria-live=\"off\" [attr.aria-label]=\"pageOfLabel()\">\n {{ counter() }}\n </span>\n <span rtElem=\"divider\" aria-hidden=\"true\"></span>\n <rt-icon-button\n qa-dataid=\"pdf-viewer-zoom-out\"\n icon=\"minus\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().pdfViewerZoomOut\"\n [disabled]=\"!canZoomOut()\"\n (clicked)=\"zoomOut()\" />\n <span rtElem=\"zoom\" qa-dataid=\"pdf-viewer-zoom\">{{ zoomLabel() }}</span>\n <rt-icon-button\n qa-dataid=\"pdf-viewer-zoom-in\"\n icon=\"ico-plus\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().pdfViewerZoomIn\"\n [disabled]=\"!canZoomIn()\"\n (clicked)=\"zoomIn()\" />\n <span rtElem=\"fit-divider\" aria-hidden=\"true\"></span>\n <button\n rtButton\n rtElem=\"fit\"\n qa-dataid=\"pdf-viewer-fit\"\n type=\"button\"\n appearance=\"text\"\n size=\"sm\"\n [label]=\"t().pdfViewerFitWidth\"\n [attr.aria-label]=\"t().pdfViewerFitWidth\"\n [pressed]=\"isFit()\"\n (click)=\"fitWidth()\"></button>\n </div>\n }\n }\n </div>\n</ng-container>\n",
652
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-pdf-viewer{--rt-pdf-viewer-bg: var(--rt-neutral-900);--rt-pdf-viewer-bar-bg: color-mix(in srgb, var(--rt-neutral-900) 35%, var(--rt-neutral-950));--rt-pdf-viewer-bar-height: var(--rt-control-height-2xl);--rt-pdf-viewer-text-color: var(--rt-neutral-0);--rt-pdf-viewer-muted-color: var(--rt-neutral-200);--rt-pdf-viewer-page-bg: var(--rt-neutral-0);--rt-pdf-viewer-page-shadow: var(--rt-shadow-md);--rt-pdf-viewer-page-gap: var(--rt-space-4);--rt-pdf-viewer-toolbar-bg: var(--rt-neutral-800);--rt-pdf-viewer-toolbar-radius: var(--rt-radius-full);--rt-pdf-viewer-divider-width: var(--rt-border-width-thin);--rt-pdf-viewer-divider-color: color-mix(in srgb, var(--rt-neutral-0) 20%, transparent);--rt-pdf-viewer-control-radius: var(--rt-radius-md);--rt-pdf-viewer-control-bg: color-mix(in srgb, var(--rt-neutral-0) 10%, transparent);--rt-pdf-viewer-control-bg-hover: color-mix(in srgb, var(--rt-neutral-0) 24%, transparent);display:block;width:100vw;height:100vh;height:100dvh;background:var(--rt-pdf-viewer-bg);color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__surface{position:absolute;display:flex;flex-direction:column;inset:0}.rt-pdf-viewer__bar{display:flex;height:var(--rt-pdf-viewer-bar-height);flex:none;align-items:center;justify-content:space-between;padding:0 var(--rt-space-4);background:var(--rt-pdf-viewer-bar-bg);gap:var(--rt-space-4)}.rt-pdf-viewer__title{display:flex;min-width:0;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__file-icon{flex:none;color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__file-name{overflow:hidden;min-width:0;font-size:var(--rt-text-sm);text-overflow:ellipsis;white-space:nowrap}.rt-pdf-viewer__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__actions rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover);border-radius:var(--rt-pdf-viewer-control-radius);background:var(--rt-pdf-viewer-control-bg)}.rt-pdf-viewer__scroller{position:relative;overflow:auto;flex:1 1 auto;overscroll-behavior:contain;scrollbar-gutter:stable}.rt-pdf-viewer__column{display:flex;width:max-content;min-width:100%;box-sizing:border-box;flex-direction:column;align-items:center;padding:var(--rt-space-4) var(--rt-space-4) var(--rt-space-24);gap:var(--rt-pdf-viewer-page-gap)}.rt-pdf-viewer__page{flex:none;background:var(--rt-pdf-viewer-page-bg);box-shadow:var(--rt-pdf-viewer-page-shadow)}.rt-pdf-viewer__canvas{display:block;width:100%;height:100%}.rt-pdf-viewer__center{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-4);inset:var(--rt-pdf-viewer-bar-height) 0 0}.rt-pdf-viewer .rt-pdf-viewer__error{--rt-empty-state-title-color: var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer .rt-pdf-viewer__error .rt-empty-state__description{color:var(--rt-pdf-viewer-muted-color)}.rt-pdf-viewer .rt-pdf-viewer__error-download{--rt-btn-bg: var(--rt-pdf-viewer-page-bg);--rt-btn-bg-hover: var(--rt-neutral-100);--rt-btn-bg-active: var(--rt-neutral-200);--rt-btn-color: var(--rt-neutral-900)}.rt-pdf-viewer__toolbar{position:absolute;bottom:var(--rt-space-6);left:50%;display:flex;align-items:center;padding:var(--rt-space-1) var(--rt-space-2);border-radius:var(--rt-pdf-viewer-toolbar-radius);background:var(--rt-pdf-viewer-toolbar-bg);gap:var(--rt-space-1);transform:translate(-50%);white-space:nowrap}.rt-pdf-viewer__toolbar rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}.rt-pdf-viewer__counter,.rt-pdf-viewer__zoom{padding:0 var(--rt-space-2);font-size:var(--rt-text-sm);font-variant-numeric:tabular-nums}.rt-pdf-viewer__zoom{min-width:var(--rt-size-12);text-align:center}.rt-pdf-viewer__divider,.rt-pdf-viewer__fit-divider{width:var(--rt-pdf-viewer-divider-width);height:var(--rt-size-5);margin:0 var(--rt-space-1);background:var(--rt-pdf-viewer-divider-color)}.rt-pdf-viewer .rt-pdf-viewer__fit{--rt-btn-color: var(--rt-pdf-viewer-text-color);--rt-btn-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}@media(width<=480px){.rt-pdf-viewer{--rt-pdf-viewer-bar-height: var(--rt-control-height-xl)}.rt-pdf-viewer__fit,.rt-pdf-viewer__fit-divider{display:none}}.rt-pdf-viewer-print{display:none}.rt-pdf-viewer-print__page{display:block;width:100%;break-after:page;break-inside:avoid}@media print{.rt-pdf-viewer-printing body>:not(.rt-pdf-viewer-print){display:none}.rt-pdf-viewer-printing .rt-pdf-viewer-print{display:block}}}\n"]
652
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-pdf-viewer{--rt-pdf-viewer-bg: var(--rt-neutral-900);--rt-pdf-viewer-bar-bg: color-mix(in srgb, var(--rt-neutral-900) 35%, var(--rt-neutral-950));--rt-pdf-viewer-bar-height: var(--rt-control-height-2xl);--rt-pdf-viewer-text-color: var(--rt-neutral-0);--rt-pdf-viewer-muted-color: var(--rt-neutral-200);--rt-pdf-viewer-page-bg: var(--rt-neutral-0);--rt-pdf-viewer-page-shadow: var(--rt-shadow-md);--rt-pdf-viewer-page-gap: var(--rt-space-4);--rt-pdf-viewer-toolbar-bg: var(--rt-neutral-800);--rt-pdf-viewer-toolbar-radius: var(--rt-radius-full);--rt-pdf-viewer-divider-width: var(--rt-border-width-thin);--rt-pdf-viewer-divider-color: color-mix(in srgb, var(--rt-neutral-0) 20%, transparent);--rt-pdf-viewer-control-radius: var(--rt-radius-md);--rt-pdf-viewer-control-bg: color-mix(in srgb, var(--rt-neutral-0) 10%, transparent);--rt-pdf-viewer-control-bg-hover: color-mix(in srgb, var(--rt-neutral-0) 24%, transparent);display:block;width:100vw;height:100vh;height:100dvh;background:var(--rt-pdf-viewer-bg);color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__surface{position:absolute;display:flex;flex-direction:column;inset:0}.rt-pdf-viewer__bar{display:flex;height:var(--rt-pdf-viewer-bar-height);flex:none;align-items:center;justify-content:space-between;padding:0 var(--rt-space-4);background:var(--rt-pdf-viewer-bar-bg);gap:var(--rt-space-4)}.rt-pdf-viewer__title{display:flex;min-width:0;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__file-icon{flex:none;color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__file-name{overflow:hidden;min-width:0;font-size:var(--rt-text-sm);text-overflow:ellipsis;white-space:nowrap}.rt-pdf-viewer__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__actions rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover);border-radius:var(--rt-pdf-viewer-control-radius);background:var(--rt-pdf-viewer-control-bg)}.rt-pdf-viewer__scroller{position:relative;overflow:auto;flex:1 1 auto;overscroll-behavior:contain;scrollbar-gutter:stable}.rt-pdf-viewer__column{display:flex;width:max-content;min-width:100%;box-sizing:border-box;flex-direction:column;align-items:center;padding:var(--rt-space-4) var(--rt-space-4) var(--rt-space-24);gap:var(--rt-pdf-viewer-page-gap)}.rt-pdf-viewer__page{flex:none;background:var(--rt-pdf-viewer-page-bg);box-shadow:var(--rt-pdf-viewer-page-shadow)}.rt-pdf-viewer__canvas{display:block;width:100%;height:100%}.rt-pdf-viewer__center{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-4);inset:var(--rt-pdf-viewer-bar-height) 0 0}.rt-pdf-viewer .rt-pdf-viewer__error{--rt-empty-state-title-color: var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer .rt-pdf-viewer__error .rt-empty-state__description{color:var(--rt-pdf-viewer-muted-color)}.rt-pdf-viewer .rt-pdf-viewer__error-download{--rt-btn-bg: var(--rt-pdf-viewer-page-bg);--rt-btn-bg-hover: var(--rt-neutral-100);--rt-btn-bg-active: var(--rt-neutral-200);--rt-btn-color: var(--rt-neutral-900)}.rt-pdf-viewer__toolbar{position:absolute;bottom:var(--rt-space-6);left:50%;display:flex;align-items:center;padding:var(--rt-space-1) var(--rt-space-2);border-radius:var(--rt-pdf-viewer-toolbar-radius);background:var(--rt-pdf-viewer-toolbar-bg);gap:var(--rt-space-1);transform:translate(-50%);white-space:nowrap}.rt-pdf-viewer__toolbar rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}.rt-pdf-viewer__counter,.rt-pdf-viewer__zoom{padding:0 var(--rt-space-2);font-size:var(--rt-text-sm);font-variant-numeric:tabular-nums}.rt-pdf-viewer__zoom{min-width:var(--rt-size-12);text-align:center}.rt-pdf-viewer__divider,.rt-pdf-viewer__fit-divider{width:var(--rt-pdf-viewer-divider-width);height:var(--rt-size-5);margin:0 var(--rt-space-1);background:var(--rt-pdf-viewer-divider-color)}.rt-pdf-viewer .rt-pdf-viewer__fit{--rt-btn-color: var(--rt-pdf-viewer-text-color);--rt-btn-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}@container rt-place (width <= 480px){.rt-pdf-viewer{--rt-pdf-viewer-bar-height: var(--rt-control-height-xl)}.rt-pdf-viewer__fit,.rt-pdf-viewer__fit-divider{display:none}}.rt-pdf-viewer-print{display:none}.rt-pdf-viewer-print__page{display:block;width:100%;break-after:page;break-inside:avoid}@media print{.rt-pdf-viewer-printing body>:not(.rt-pdf-viewer-print){display:none}.rt-pdf-viewer-printing .rt-pdf-viewer-print{display:block}}}\n"]
653
653
  }]
654
654
  }],
655
655
  ctorParameters: () => [],