@rt-tools/ui-kit-v2 0.34.2 → 0.34.4

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 (86) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +2 -0
  2. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +2 -0
  4. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +2 -0
  6. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
  7. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +2 -0
  8. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +2 -0
  10. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-counter.mjs +2 -0
  12. package/fesm2022/rt-tools-ui-kit-v2-counter.mjs.map +1 -1
  13. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +4 -0
  14. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
  15. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +4 -0
  16. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
  17. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +4 -0
  18. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
  19. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +2 -0
  20. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
  21. package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs +2 -0
  22. package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs.map +1 -1
  23. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +2 -0
  24. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
  25. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +2 -0
  26. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
  27. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +2 -0
  28. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
  29. package/fesm2022/rt-tools-ui-kit-v2-header.mjs +2 -0
  30. package/fesm2022/rt-tools-ui-kit-v2-header.mjs.map +1 -1
  31. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +103 -6
  32. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
  33. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +2 -0
  34. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -1
  35. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs +2 -0
  36. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs.map +1 -1
  37. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +2 -0
  38. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -1
  39. package/fesm2022/rt-tools-ui-kit-v2-input.mjs +6 -1
  40. package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -1
  41. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +2 -0
  42. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
  43. package/fesm2022/rt-tools-ui-kit-v2-message.mjs +2 -0
  44. package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -1
  45. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +2 -0
  46. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
  47. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +2 -0
  48. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -1
  49. package/fesm2022/rt-tools-ui-kit-v2-pdf-viewer.mjs +2 -0
  50. package/fesm2022/rt-tools-ui-kit-v2-pdf-viewer.mjs.map +1 -1
  51. package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs +2 -0
  52. package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs.map +1 -1
  53. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +10 -0
  54. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  55. package/fesm2022/rt-tools-ui-kit-v2-select.mjs +2 -0
  56. package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
  57. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +6 -0
  58. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
  59. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +2 -0
  60. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -1
  61. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +8 -0
  62. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
  63. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +2 -0
  64. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
  65. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +2 -0
  66. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -1
  67. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +2 -0
  68. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
  69. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +2 -0
  70. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
  71. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +14 -2
  72. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
  73. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +2 -0
  74. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
  75. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +2 -0
  76. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
  77. package/package.json +1 -1
  78. package/src/lib/components/icon-button/CONTEXT.md +32 -16
  79. package/src/lib/components/icon-button/rt-icon-button.component.scss +17 -9
  80. package/src/lib/components/input/CONTEXT.md +6 -0
  81. package/src/lib/components/tooltip/CONTEXT.md +3 -0
  82. package/src/styles/_form.scss +14 -1
  83. package/styles/tokens.css +13 -1
  84. package/types/rt-tools-ui-kit-v2-icon-button.d.ts +38 -2
  85. package/types/rt-tools-ui-kit-v2-input.d.ts +2 -0
  86. package/types/rt-tools-ui-kit-v2-tooltip.d.ts +6 -1
@@ -187,6 +187,8 @@ var RtTagComponent = class RtTagComponent {
187
187
  "disabled",
188
188
  "active",
189
189
  "expanded",
190
+ "ariaHaspopup",
191
+ "link",
190
192
  "indicator"
191
193
  ],
192
194
  outputs: ["clicked"]
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-tag.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/tag/rt-tag.component.ts","../../../projects/ui-kit-v2/src/lib/components/tag/rt-tag.component.html"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n afterRenderEffect,\n booleanAttribute,\n inject,\n input,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n OnDestroy,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { IRtMatchPart, rtMatchParts } from '@rt-tools/ui-kit-v2/core';\nimport { IRtTag } from './rt-tag.model';\n\nconst BEM_BLOCK: string = 'rt-tag';\n\n/** Ступень значка по ступени пилюли. `md` оставляет значок таким, каким он был до ступеней. */\nconst ICON_BY_SIZE: Readonly<Record<IRtTag.Size, IRtIcon.Size>> = { sm: 'xs', md: 'sm', lg: 'md' };\n\n/**\n * Status/label pill для отображения статусов и счётчиков.\n * Поддерживает 6 severity-вариантов (`info` / `success` / `warning` / `danger` /\n * `secondary` / `neutral`), любой шаг скругления входом `radius` и опциональный close-control\n * (рендерит `rt-icon-button` с иконкой `ico-close` и emits `closed` MouseEvent).\n *\n * Все цвета — через семантические `--rt-color-state-*` токены; layout через\n * primitive `--rt-space-*` / `--rt-radius-*` / `--rt-text-*`. BEM-разметка через\n * директивы `rtBlock` / `rtElem` / `rtMod` из `@rt-tools/core`.\n */\n@Component({\n selector: 'rt-tag',\n templateUrl: './rt-tag.component.html',\n styleUrl: './rt-tag.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n RtIconButtonComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtTagComponent implements OnDestroy {\n /** Текст pill — обязательный input. */\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n #resizeObserver: ResizeObserver | null = null;\n\n protected readonly textRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('text');\n\n /** Подписи не хватило места: она урезана многоточием, и целое значение показывает подсказка. */\n protected readonly overflowing: WritableSignal<boolean> = signal<boolean>(false);\n\n /** Размер значка ведёт ступень пилюли: свой вход у него был бы вторым числом об одном. */\n protected readonly iconSize: Signal<IRtIcon.Size> = computed((): IRtIcon.Size => ICON_BY_SIZE[this.size()]);\n\n /** Подпись, разрезанная по словам `highlight`: без них — один кусок целиком. */\n protected readonly parts: Signal<ReadonlyArray<IRtMatchPart>> = computed((): ReadonlyArray<IRtMatchPart> =>\n rtMatchParts(this.value(), this.highlight())\n );\n\n public readonly value: InputSignal<string> = input.required<string>();\n\n /**\n * Слова поиска, найденные куски которых метка отмечает: приложение, что ищет и по меткам,\n * показывает, где слово нашлось. Пустая строка ничего не отмечает.\n */\n public readonly highlight: InputSignal<string> = input<string>('');\n\n /** Семантическая палитра. По умолчанию `neutral` (нейтральный серый). */\n public readonly severity: InputSignal<IRtTag.Severity> = input<IRtTag.Severity>('neutral');\n\n /**\n * Ступень размера. Умолчание `md` — тот размер, каким метка рисовалась до появления ступеней.\n * Отступы, кегль и значок двигаются вместе: кегль, названный отдельно, оставил бы отступы от\n * другой ступени, и ряд пилюль перестал бы выстраиваться.\n */\n public readonly size: InputSignal<IRtTag.Size> = input<IRtTag.Size>('md');\n\n /** Вид заливки. По умолчанию `solid`; `outlined` — прозрачный фон + рамка. */\n public readonly appearance: InputSignal<IRtTag.Appearance> = input<IRtTag.Appearance>('solid');\n\n /** Префикс-иконка слева от текста. `null` (дефолт) — без иконки. */\n public readonly icon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /** Суффикс-иконка справа от текста (напр. `external-link` у тега-ссылки). */\n public readonly iconEnd: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /** Рендерит крестик `rt-icon-button` справа от текста. */\n public readonly closable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Эмиттит MouseEvent при клике на close-button (только если `closable=true`). */\n public readonly closed: OutputEmitterRef<MouseEvent> = output<MouseEvent>();\n\n constructor() {\n afterRenderEffect((): void => {\n this.value();\n this.size();\n this.#observeText();\n this.#measure();\n });\n }\n\n public ngOnDestroy(): void {\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n }\n\n protected onClose(event: MouseEvent): void {\n event.stopPropagation();\n this.closed.emit(event);\n }\n\n /**\n * Переполнение считается наблюдателем за размером, а не отсчётом после отрисовки: отсчёт\n * отвечает о машине, а не о раскладке — на свободной его всегда хватает, на занятой нет, а\n * подпись, переполнившаяся позже, подсказки не получила бы вовсе.\n */\n #observeText(): void {\n const node: HTMLElement | undefined = this.textRef()?.nativeElement;\n\n if (node === undefined || this.#resizeObserver !== null || typeof ResizeObserver === 'undefined') {\n return;\n }\n\n this.#resizeObserver = new ResizeObserver((): void => this.#measure());\n this.#resizeObserver.observe(node);\n }\n\n #measure(): void {\n const node: HTMLElement | undefined = this.textRef()?.nativeElement;\n\n if (node !== undefined) {\n this.overflowing.set(node.scrollWidth > node.clientWidth);\n }\n }\n}\n","<span\n rtBlock=\"rt-tag\"\n qa-dataid=\"tag\"\n [attr.data-severity]=\"severity()\"\n [rtMod]=\"{\n severity: severity(),\n size: size(),\n appearance: appearance(),\n closable: closable(),\n }\">\n @if (icon(); as iconName) {\n <rt-icon rtElem=\"icon\" [size]=\"iconSize()\" [name]=\"iconName\" />\n }\n <!--\n Целое значение показывает подсказка, и только когда подписи не хватило места:\n урезанный текст без подсказки читается как целый — узнать, где он на деле кончается,\n человеку неоткуда. Пустой текст директиву выключает.\n -->\n <span rtElem=\"text\" qa-dataid=\"tag-text\" #text [rtTooltip]=\"overflowing() ? value() : ''\">\n @for (part of parts(); track $index) {\n <span rtElem=\"part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n @if (iconEnd(); as iconEndName) {\n <rt-icon rtElem=\"icon-end\" [size]=\"iconSize()\" [name]=\"iconEndName\" />\n }\n @if (closable()) {\n <rt-icon-button\n rtElem=\"close\"\n qa-dataid=\"tag-close\"\n icon=\"ico-close\"\n variant=\"ghost\"\n size=\"sm\"\n radius=\"full\"\n [ariaLabel]=\"t().uiRemove\"\n (clicked)=\"onClose($event)\" />\n }\n</span>\n"],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-tag.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/tag/rt-tag.component.ts","../../../projects/ui-kit-v2/src/lib/components/tag/rt-tag.component.html"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n afterRenderEffect,\n booleanAttribute,\n inject,\n input,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n OnDestroy,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { IRtMatchPart, rtMatchParts } from '@rt-tools/ui-kit-v2/core';\nimport { IRtTag } from './rt-tag.model';\n\nconst BEM_BLOCK: string = 'rt-tag';\n\n/** Ступень значка по ступени пилюли. `md` оставляет значок таким, каким он был до ступеней. */\nconst ICON_BY_SIZE: Readonly<Record<IRtTag.Size, IRtIcon.Size>> = { sm: 'xs', md: 'sm', lg: 'md' };\n\n/**\n * Status/label pill для отображения статусов и счётчиков.\n * Поддерживает 6 severity-вариантов (`info` / `success` / `warning` / `danger` /\n * `secondary` / `neutral`), любой шаг скругления входом `radius` и опциональный close-control\n * (рендерит `rt-icon-button` с иконкой `ico-close` и emits `closed` MouseEvent).\n *\n * Все цвета — через семантические `--rt-color-state-*` токены; layout через\n * primitive `--rt-space-*` / `--rt-radius-*` / `--rt-text-*`. BEM-разметка через\n * директивы `rtBlock` / `rtElem` / `rtMod` из `@rt-tools/core`.\n */\n@Component({\n selector: 'rt-tag',\n templateUrl: './rt-tag.component.html',\n styleUrl: './rt-tag.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n RtIconButtonComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtTagComponent implements OnDestroy {\n /** Текст pill — обязательный input. */\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n #resizeObserver: ResizeObserver | null = null;\n\n protected readonly textRef: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('text');\n\n /** Подписи не хватило места: она урезана многоточием, и целое значение показывает подсказка. */\n protected readonly overflowing: WritableSignal<boolean> = signal<boolean>(false);\n\n /** Размер значка ведёт ступень пилюли: свой вход у него был бы вторым числом об одном. */\n protected readonly iconSize: Signal<IRtIcon.Size> = computed((): IRtIcon.Size => ICON_BY_SIZE[this.size()]);\n\n /** Подпись, разрезанная по словам `highlight`: без них — один кусок целиком. */\n protected readonly parts: Signal<ReadonlyArray<IRtMatchPart>> = computed((): ReadonlyArray<IRtMatchPart> =>\n rtMatchParts(this.value(), this.highlight())\n );\n\n public readonly value: InputSignal<string> = input.required<string>();\n\n /**\n * Слова поиска, найденные куски которых метка отмечает: приложение, что ищет и по меткам,\n * показывает, где слово нашлось. Пустая строка ничего не отмечает.\n */\n public readonly highlight: InputSignal<string> = input<string>('');\n\n /** Семантическая палитра. По умолчанию `neutral` (нейтральный серый). */\n public readonly severity: InputSignal<IRtTag.Severity> = input<IRtTag.Severity>('neutral');\n\n /**\n * Ступень размера. Умолчание `md` — тот размер, каким метка рисовалась до появления ступеней.\n * Отступы, кегль и значок двигаются вместе: кегль, названный отдельно, оставил бы отступы от\n * другой ступени, и ряд пилюль перестал бы выстраиваться.\n */\n public readonly size: InputSignal<IRtTag.Size> = input<IRtTag.Size>('md');\n\n /** Вид заливки. По умолчанию `solid`; `outlined` — прозрачный фон + рамка. */\n public readonly appearance: InputSignal<IRtTag.Appearance> = input<IRtTag.Appearance>('solid');\n\n /** Префикс-иконка слева от текста. `null` (дефолт) — без иконки. */\n public readonly icon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /** Суффикс-иконка справа от текста (напр. `external-link` у тега-ссылки). */\n public readonly iconEnd: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /** Рендерит крестик `rt-icon-button` справа от текста. */\n public readonly closable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Эмиттит MouseEvent при клике на close-button (только если `closable=true`). */\n public readonly closed: OutputEmitterRef<MouseEvent> = output<MouseEvent>();\n\n constructor() {\n afterRenderEffect((): void => {\n this.value();\n this.size();\n this.#observeText();\n this.#measure();\n });\n }\n\n public ngOnDestroy(): void {\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = null;\n }\n\n protected onClose(event: MouseEvent): void {\n event.stopPropagation();\n this.closed.emit(event);\n }\n\n /**\n * Переполнение считается наблюдателем за размером, а не отсчётом после отрисовки: отсчёт\n * отвечает о машине, а не о раскладке — на свободной его всегда хватает, на занятой нет, а\n * подпись, переполнившаяся позже, подсказки не получила бы вовсе.\n */\n #observeText(): void {\n const node: HTMLElement | undefined = this.textRef()?.nativeElement;\n\n if (node === undefined || this.#resizeObserver !== null || typeof ResizeObserver === 'undefined') {\n return;\n }\n\n this.#resizeObserver = new ResizeObserver((): void => this.#measure());\n this.#resizeObserver.observe(node);\n }\n\n #measure(): void {\n const node: HTMLElement | undefined = this.textRef()?.nativeElement;\n\n if (node !== undefined) {\n this.overflowing.set(node.scrollWidth > node.clientWidth);\n }\n }\n}\n","<span\n rtBlock=\"rt-tag\"\n qa-dataid=\"tag\"\n [attr.data-severity]=\"severity()\"\n [rtMod]=\"{\n severity: severity(),\n size: size(),\n appearance: appearance(),\n closable: closable(),\n }\">\n @if (icon(); as iconName) {\n <rt-icon rtElem=\"icon\" [size]=\"iconSize()\" [name]=\"iconName\" />\n }\n <!--\n Целое значение показывает подсказка, и только когда подписи не хватило места:\n урезанный текст без подсказки читается как целый — узнать, где он на деле кончается,\n человеку неоткуда. Пустой текст директиву выключает.\n -->\n <span rtElem=\"text\" qa-dataid=\"tag-text\" #text [rtTooltip]=\"overflowing() ? value() : ''\">\n @for (part of parts(); track $index) {\n <span rtElem=\"part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n @if (iconEnd(); as iconEndName) {\n <rt-icon rtElem=\"icon-end\" [size]=\"iconSize()\" [name]=\"iconEndName\" />\n }\n @if (closable()) {\n <rt-icon-button\n rtElem=\"close\"\n qa-dataid=\"tag-close\"\n icon=\"ico-close\"\n variant=\"ghost\"\n size=\"sm\"\n radius=\"full\"\n [ariaLabel]=\"t().uiRemove\"\n (clicked)=\"onClose($event)\" />\n }\n</span>\n"],"mappings":";;;;;;;;;AAiCA,MAAM,YAAoB;AAG1B,MAAM,eAA4D;CAAE,IAAI;CAAM,IAAI;CAAM,IAAI;AAAI;AAgChG,IAAa,iBAAb,MAAa,eAAc;CAIvB;CAkDA,cAAA;EApDmB,KAAA,IAA4B,OAAO,aAAa;EAEnE,KAAA,kBAAyC;EAEtB,KAAA,UAAuD,UAAmC,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAGjG,KAAA,cAAuC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAG7D,KAAA,WAAiC,eAA6B,aAAa,KAAK,KAAI,IAAI,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAGxF,KAAA,QAA6C,eAC5D,aAAa,KAAK,MAAK,GAAI,KAAK,UAAS,CAAE,GAC9C,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAEe,KAAA,QAA6B,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAMrD,KAAA,YAAiC,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAGlD,KAAA,WAAyC,MAAuB,WAAU,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAO1E,KAAA,OAAiC,MAAmB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAGzD,KAAA,aAA6C,MAAyB,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;EAG9E,KAAA,OAAyC,MAA2B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAGzE,KAAA,UAA4C,MAA2B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAG5E,KAAA,WAA4D,MAA6B,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;GAC1G,WAAW;EAAgB,CAAA;EAIf,KAAA,SAAuC,OAAM;EAGzD,wBAA6B;GACzB,KAAK,MAAK;GACV,KAAK,KAAI;GACT,KAAK,aAAY;GACjB,KAAK,SAAQ;EACjB,CAAC;CACL;CAEO,cAAW;EACd,KAAK,iBAAiB,WAAU;EAChC,KAAK,kBAAkB;CAC3B;CAEU,QAAQ,OAAiB;EAC/B,MAAM,gBAAe;EACrB,KAAK,OAAO,KAAK,KAAK;CAC1B;CAOA,eAAY;EACR,MAAM,OAAgC,KAAK,QAAO,CAAE,EAAE;EAEtD,IAAI,SAAS,UAAa,KAAK,oBAAoB,QAAQ,OAAO,mBAAmB,aACjF;EAGJ,KAAK,kBAAkB,IAAI,qBAA2B,KAAK,SAAQ,CAAE;EACrE,KAAK,gBAAgB,QAAQ,IAAI;CACrC;CAEA,WAAQ;EACJ,MAAM,OAAgC,KAAK,QAAO,CAAE,EAAE;EAEtD,IAAI,SAAS,QACT,KAAK,YAAY,IAAI,KAAK,cAAc,KAAK,WAAW;CAEhE;CA/FS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAc,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAd;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAc,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,WAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,YAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,SAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,SAAA,EAAA,QAAA,SAAA;GAAA,MAAA,EAAA,gBAAA,SAAA;GAAA,aAAA,CAAA;IAAA,cAAA;IAAA,OAAA;IAAA,WAAA,CAAA,MAAA;IAAA,aAAA;IAAA,UAAA;GAAA,CAAA;GAAA,gBAAA,CAAA;IAAA,WAAA,GAAA;IAAA,QAAA,CAAA,UAAA,QAAA;GAAA,CAAA;GAAA,UAAA;GAAA,UCpE3B;GAsCA,QAAA,CAAA,6xGAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MDkBQ;KAAe,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACf;KAAqB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,SAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACrB;KAAkB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,UAAA,CAAA,WAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAClB;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACb;KAAY,UAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAOP,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAc,YAAA,CAAA;EApB1B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAQ,iBAGD,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IAEL;IACA;IACA;IACA;IACA;IACA;GACH;GAAA,gBACe,CAAC;IAAE,WAAW;IAAmB,QAAQ,CAAC,QAAQ;GAAC,CAAE;GAAC,MAChE,EACF,OAAO,UACV;GAAA,UAAA;GAAA,QAAA,CAAA,6xGAAA;EAAA,CAAA;CAQ4G,CAAA;CAAA,sBAAA,CAAA;CAAA,gBAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,QAAM,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,UAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,MAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,YAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,MAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,UAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,QAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,QAAA;EAAA,CAAA;CAAA;AAAA,CAAA"}
@@ -93,6 +93,8 @@ var RtThemeToggleComponent = class RtThemeToggleComponent {
93
93
  "disabled",
94
94
  "active",
95
95
  "expanded",
96
+ "ariaHaspopup",
97
+ "link",
96
98
  "indicator"
97
99
  ],
98
100
  outputs: ["clicked"]
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-theme-toggle.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/theme-toggle/rt-theme-toggle.component.ts","../../../projects/ui-kit-v2/src/lib/components/theme-toggle/rt-theme-toggle.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, input, InputSignal, Signal, ViewEncapsulation } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { ThemeService } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtToggleSwitchComponent } from '@rt-tools/ui-kit-v2/toggle-switch';\nimport { IRtThemeToggle } from './rt-theme-toggle.model';\n\nconst BEM_BLOCK: string = 'rt-theme-toggle';\n\n/**\n * Переключатель темы в двух видах (`appearance`):\n * - `icon` — круглая icon-кнопка, рендер делегирован в `rt-icon-button`\n * (ghost-стиль, focus-visible, hover, aria-pressed через `[active]`);\n * - `switch` — тоггл-рельса `rt-toggle-switch` с иконками внутри трека.\n *\n * В обоих видах видна иконка противоположной темы — кликом пользователь\n * переходит к ней. В `switch` это получается само: бегунок стоит над иконкой\n * текущей темы и закрывает её.\n *\n * Инжектит ThemeService напрямую — допустимо благодаря расширенному boundary\n * ThemeService сам провайден root.\n */\n@Component({\n selector: 'rt-theme-toggle',\n templateUrl: './rt-theme-toggle.component.html',\n styleUrls: ['./rt-theme-toggle.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n FormsModule,\n\n // standalone components / directives\n RtIconButtonComponent,\n RtToggleSwitchComponent,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtThemeToggleComponent {\n /** Тексты компонента: сигналы, потому что язык может смениться без перезагрузки */\n readonly #t_themeToggleLabel: Signal<string> = rtKitLabel('themeToggleLabel');\n\n readonly #theme: ThemeService = inject(ThemeService);\n\n protected readonly iconName: Signal<IRtIcon.Name> = computed((): IRtIcon.Name => (this.#theme.isDark() ? 'ico-sun' : 'moon'));\n\n protected readonly isSwitch: Signal<boolean> = computed((): boolean => this.appearance() === 'switch');\n\n protected readonly isDark: Signal<boolean> = this.#theme.isDark;\n\n protected readonly label: string = this.#t_themeToggleLabel();\n\n /** Внешний вид. Default `icon` — компактная кнопка для шапки. */\n public readonly appearance: InputSignal<IRtThemeToggle.Appearance> = input<IRtThemeToggle.Appearance>('icon');\n\n public onToggle(): void {\n this.#theme.toggle();\n }\n}\n","@if (isSwitch()) {\n <rt-toggle-switch\n qa-dataid=\"theme-toggle-control\"\n size=\"md\"\n iconOff=\"ico-sun\"\n iconOn=\"moon\"\n [ariaLabel]=\"label\"\n [ngModel]=\"isDark()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onToggle()\" />\n} @else {\n <rt-icon-button\n qa-dataid=\"theme-toggle-control\"\n variant=\"ghost\"\n size=\"md\"\n radius=\"full\"\n [ariaLabel]=\"label\"\n [icon]=\"iconName()\"\n [active]=\"isDark()\"\n (clicked)=\"onToggle()\" />\n}\n"],"mappings":";;;;;;;AAWA,MAAM,YAAoB;AAiC1B,IAAa,yBAAb,MAAa,uBAAsB;CAlBnC,cAAA;EAoBa,KAAA,sBAAsC,WAAW,kBAAkB;EAEnE,KAAA,SAAuB,OAAO,YAAY;EAEhC,KAAA,WAAiC,eAA8B,KAAK,OAAO,OAAM,IAAK,YAAY,QAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAE1G,KAAA,WAA4B,eAAwB,KAAK,WAAU,MAAO,UAAS,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAEnF,KAAA,SAA0B,KAAK,OAAO;EAEtC,KAAA,QAAgB,KAAK,oBAAmB;EAG3C,KAAA,aAAqD,MAAiC,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAKhH;CAlBY;CAEA;CAaF,WAAQ;EACX,KAAK,OAAO,OAAM;CACtB;CAnBS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAsB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAtB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAsB,cAAA;GAAA,UAAA;GAAA,QAAA,EAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA,EAAA;GAAA,MAAA,EAAA,gBAAA,kBAAA;GAAA,UAAA;GAAA,UC5CnC;GAqBA,QAAA,CAAA,sFAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MDaQ;IAAW;IAAA;KAAA,MAAA;KAAA,MAAA,GAAA;KAAA,UAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAAA,GAAA;KAAA,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,eAAA;KAAA,UAAA,CAAA,SAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAGX;KAAqB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,SAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACrB;KAAuB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAMlB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAsB,YAAA,CAAA;EAlBlC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAiB,iBAGV,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IAEL;IAGA;IACA;GACH;GAAA,MACK,EACF,OAAO,UACV;GAAA,UAAA;GAAA,QAAA,CAAA,sFAAA;EAAA,CAAA"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-theme-toggle.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/theme-toggle/rt-theme-toggle.component.ts","../../../projects/ui-kit-v2/src/lib/components/theme-toggle/rt-theme-toggle.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, input, InputSignal, Signal, ViewEncapsulation } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { ThemeService } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtToggleSwitchComponent } from '@rt-tools/ui-kit-v2/toggle-switch';\nimport { IRtThemeToggle } from './rt-theme-toggle.model';\n\nconst BEM_BLOCK: string = 'rt-theme-toggle';\n\n/**\n * Переключатель темы в двух видах (`appearance`):\n * - `icon` — круглая icon-кнопка, рендер делегирован в `rt-icon-button`\n * (ghost-стиль, focus-visible, hover, aria-pressed через `[active]`);\n * - `switch` — тоггл-рельса `rt-toggle-switch` с иконками внутри трека.\n *\n * В обоих видах видна иконка противоположной темы — кликом пользователь\n * переходит к ней. В `switch` это получается само: бегунок стоит над иконкой\n * текущей темы и закрывает её.\n *\n * Инжектит ThemeService напрямую — допустимо благодаря расширенному boundary\n * ThemeService сам провайден root.\n */\n@Component({\n selector: 'rt-theme-toggle',\n templateUrl: './rt-theme-toggle.component.html',\n styleUrls: ['./rt-theme-toggle.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n FormsModule,\n\n // standalone components / directives\n RtIconButtonComponent,\n RtToggleSwitchComponent,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtThemeToggleComponent {\n /** Тексты компонента: сигналы, потому что язык может смениться без перезагрузки */\n readonly #t_themeToggleLabel: Signal<string> = rtKitLabel('themeToggleLabel');\n\n readonly #theme: ThemeService = inject(ThemeService);\n\n protected readonly iconName: Signal<IRtIcon.Name> = computed((): IRtIcon.Name => (this.#theme.isDark() ? 'ico-sun' : 'moon'));\n\n protected readonly isSwitch: Signal<boolean> = computed((): boolean => this.appearance() === 'switch');\n\n protected readonly isDark: Signal<boolean> = this.#theme.isDark;\n\n protected readonly label: string = this.#t_themeToggleLabel();\n\n /** Внешний вид. Default `icon` — компактная кнопка для шапки. */\n public readonly appearance: InputSignal<IRtThemeToggle.Appearance> = input<IRtThemeToggle.Appearance>('icon');\n\n public onToggle(): void {\n this.#theme.toggle();\n }\n}\n","@if (isSwitch()) {\n <rt-toggle-switch\n qa-dataid=\"theme-toggle-control\"\n size=\"md\"\n iconOff=\"ico-sun\"\n iconOn=\"moon\"\n [ariaLabel]=\"label\"\n [ngModel]=\"isDark()\"\n [ngModelOptions]=\"{ standalone: true }\"\n (ngModelChange)=\"onToggle()\" />\n} @else {\n <rt-icon-button\n qa-dataid=\"theme-toggle-control\"\n variant=\"ghost\"\n size=\"md\"\n radius=\"full\"\n [ariaLabel]=\"label\"\n [icon]=\"iconName()\"\n [active]=\"isDark()\"\n (clicked)=\"onToggle()\" />\n}\n"],"mappings":";;;;;;;AAWA,MAAM,YAAoB;AAiC1B,IAAa,yBAAb,MAAa,uBAAsB;CAlBnC,cAAA;EAoBa,KAAA,sBAAsC,WAAW,kBAAkB;EAEnE,KAAA,SAAuB,OAAO,YAAY;EAEhC,KAAA,WAAiC,eAA8B,KAAK,OAAO,OAAM,IAAK,YAAY,QAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAE1G,KAAA,WAA4B,eAAwB,KAAK,WAAU,MAAO,UAAS,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAEnF,KAAA,SAA0B,KAAK,OAAO;EAEtC,KAAA,QAAgB,KAAK,oBAAmB;EAG3C,KAAA,aAAqD,MAAiC,QAAO,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;CAKhH;CAlBY;CAEA;CAaF,WAAQ;EACX,KAAK,OAAO,OAAM;CACtB;CAnBS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAsB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAtB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAsB,cAAA;GAAA,UAAA;GAAA,QAAA,EAAA,YAAA;IAAA,mBAAA;IAAA,YAAA;IAAA,UAAA;IAAA,YAAA;IAAA,mBAAA;GAAA,EAAA;GAAA,MAAA,EAAA,gBAAA,kBAAA;GAAA,UAAA;GAAA,UC5CnC;GAqBA,QAAA,CAAA,sFAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MDaQ;IAAW;IAAA;KAAA,MAAA;KAAA,MAAA,GAAA;KAAA,UAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAAA,GAAA;KAAA,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,eAAA;KAAA,UAAA,CAAA,SAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAGX;KAAqB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,SAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACrB;KAAuB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAMlB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAsB,YAAA,CAAA;EAlBlC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAiB,iBAGV,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IAEL;IAGA;IACA;GACH;GAAA,MACK,EACF,OAAO,UACV;GAAA,UAAA;GAAA,QAAA,CAAA,sFAAA;EAAA,CAAA"}
@@ -474,6 +474,8 @@ var RtThreadListComponent = class RtThreadListComponent {
474
474
  "disabled",
475
475
  "active",
476
476
  "expanded",
477
+ "ariaHaspopup",
478
+ "link",
477
479
  "indicator"
478
480
  ],
479
481
  outputs: ["clicked"]
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-thread-list.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.directives.ts","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.component.ts","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.component.html"],"sourcesContent":["import { Directive, inject, input, InputSignal, TemplateRef } from '@angular/core';\n\nimport { IRtThreadList } from './rt-thread-list.model';\n\n/**\n * Помечает `<ng-template>` содержимого строки списка. Входом `[rtThreadListRow]`\n * потребитель передаёт свой массив строк — из него выводится тип `TRow`, поэтому\n * `let-row` в темплейте типизируется строго (context-guard ниже это подтверждает).\n */\n@Directive({\n selector: 'ng-template[rtThreadListRow]',\n})\nexport class RtThreadListRowDirective<TRow extends IRtThreadList.Row> {\n public readonly templateRef: TemplateRef<IRtThreadList.RowContext<TRow>> =\n inject<TemplateRef<IRtThreadList.RowContext<TRow>>>(TemplateRef);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([], {\n alias: 'rtThreadListRow',\n });\n\n public static ngTemplateContextGuard<TRow extends IRtThreadList.Row>(\n _directive: RtThreadListRowDirective<TRow>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtThreadList.RowContext<TRow> {\n return true;\n }\n}\n\n/**\n * Помечает `<ng-template>` действий строки (удалить, закрепить). Действия рисуются рядом с\n * кнопкой строки, а не внутри неё: вложенная кнопка в `<button>` недопустима и крадёт клик\n * выбора строки. Видны при наведении и фокусе внутри строки.\n */\n@Directive({\n selector: 'ng-template[rtThreadListRowActions]',\n})\nexport class RtThreadListRowActionsDirective<TRow extends IRtThreadList.Row> {\n public readonly templateRef: TemplateRef<IRtThreadList.RowContext<TRow>> =\n inject<TemplateRef<IRtThreadList.RowContext<TRow>>>(TemplateRef);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([], {\n alias: 'rtThreadListRowActions',\n });\n\n public static ngTemplateContextGuard<TRow extends IRtThreadList.Row>(\n _directive: RtThreadListRowActionsDirective<TRow>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtThreadList.RowContext<TRow> {\n return true;\n }\n}\n\n/**\n * Помечает `<ng-template>` с фильтрами — его содержимое рендерится в поповере,\n * который открывает иконка-фильтр в шапке списка.\n */\n@Directive({\n selector: 'ng-template[rtThreadListFilters]',\n})\nexport class RtThreadListFiltersDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/**\n * Помечает `<ng-template>` с кастомным контролом поиска. Когда потребитель его\n * проецирует, шапка списка рендерит его содержимое вместо встроенного `rt-input`\n * — так воркспейс подставляет свой автокомплит по каталогу вместо текстового\n * поиска, не ломая generic-природу списка.\n */\n@Directive({\n selector: 'ng-template[rtThreadListSearch]',\n})\nexport class RtThreadListSearchDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n InputSignal,\n InputSignalWithTransform,\n OnInit,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\nimport { distinctUntilChanged, map } from 'rxjs';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { searchDebounce } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtInfiniteScrollDirective } from '@rt-tools/ui-kit-v2/core';\nimport { RtEmptyStateComponent } from '@rt-tools/ui-kit-v2/empty-state';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtServiceLogoComponent } from '@rt-tools/ui-kit-v2/service-logo';\nimport { RtSkeletonComponent } from '@rt-tools/ui-kit-v2/skeleton';\nimport {\n RtThreadListFiltersDirective,\n RtThreadListRowActionsDirective,\n RtThreadListRowDirective,\n RtThreadListSearchDirective,\n} from './rt-thread-list.directives';\nimport { IRtThreadList } from './rt-thread-list.model';\n\nconst BEM_BLOCK: string = 'rt-thread-list';\n\n/** Кол-во скелетон-строк на первичной загрузке (пока `rows` пусты). */\nconst SKELETON_ROWS_COUNT: number = 6;\n\n/** Значки строк-превью пустого списка по умолчанию: люди переписки. */\nconst PREVIEW_ICONS: readonly IRtIcon.Name[] = ['user', 'users', 'user'];\n\n/**\n * Презентационный список тредов для воркспейсов:\n * поиск с дебаунсом, фильтр-поповер и бесконечная прокрутка. Данные и оркестрация\n * — на вызывающем; список стора/api не видит.\n *\n * Строку рисует потребитель через `<ng-template rtThreadListRow let-row>` (body +\n * meta); оболочка владеет кнопкой строки (active/unread/overdue), поиском, кнопкой\n * фильтров (точка-индикатор при `filtersActive`) и скроллом. Фильтры потребитель\n * кладёт в `<ng-template rtThreadListFilters>` — они рендерятся в поповере.\n */\n@Component({\n selector: 'rt-thread-list',\n templateUrl: './rt-thread-list.component.html',\n styleUrls: ['./rt-thread-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n ReactiveFormsModule,\n\n // standalone components / directives\n RtEmptyStateComponent,\n RtIconComponent,\n RtIconButtonComponent,\n RtInputComponent,\n RtPopoverDirective,\n RtServiceLogoComponent,\n RtSkeletonComponent,\n BlockDirective,\n ElemDirective,\n RtInfiniteScrollDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtThreadListComponent<TRow extends IRtThreadList.Row> implements OnInit {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #t_uiSearch: Signal<string> = rtKitLabel('uiSearch');\n readonly #t_uiNothingFound: Signal<string> = rtKitLabel('uiNothingFound');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly searchPlaceholderText: Signal<string> = computed((): string => this.searchPlaceholder() || this.#t_uiSearch());\n protected readonly emptyTitle: Signal<string> = computed((): string => this.emptyText() || this.#t_uiNothingFound());\n\n protected readonly skeletonRows: number[] = Array.from({ length: SKELETON_ROWS_COUNT }, (_: unknown, i: number): number => i);\n\n /** Декоративные строки-превью пустого состояния: значок строки из `emptyPreviewIcons`, каждая вторая сдвинута. */\n protected readonly emptyPreviewRows: Signal<readonly IRtThreadList.PreviewRow[]> = computed((): readonly IRtThreadList.PreviewRow[] =>\n this.emptyPreviewIcons().map((icon: IRtIcon.Name, index: number): IRtThreadList.PreviewRow => ({\n icon,\n id: index,\n offset: index % 2 === 1,\n }))\n );\n\n protected readonly searchControl: FormControl<string> = new FormControl<string>('', {\n nonNullable: true,\n });\n\n protected readonly rowTemplate: Signal<RtThreadListRowDirective<TRow> | undefined> = contentChild(RtThreadListRowDirective<TRow>);\n\n protected readonly rowActionsTemplate: Signal<RtThreadListRowActionsDirective<TRow> | undefined> = contentChild(\n RtThreadListRowActionsDirective<TRow>\n );\n\n protected readonly filtersTemplate: Signal<RtThreadListFiltersDirective | undefined> = contentChild(RtThreadListFiltersDirective);\n\n protected readonly searchTemplate: Signal<RtThreadListSearchDirective | undefined> = contentChild(RtThreadListSearchDirective);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([]);\n\n public readonly activeId: InputSignal<IRtThreadList.TRowId | null> = input<IRtThreadList.TRowId | null>(null);\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly searchPlaceholder: InputSignal<string> = input<string>('');\n\n public readonly emptyText: InputSignal<string> = input<string>('');\n\n /** Значки декоративных строк-превью пустого состояния, по строке на значок */\n public readonly emptyPreviewIcons: InputSignal<readonly IRtIcon.Name[]> = input<readonly IRtIcon.Name[]>(PREVIEW_ICONS);\n\n public readonly loading: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly fetching: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly hasMore: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly filtersActive: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n // Имя `select` зарезервировано под нативное DOM-событие\n // (@angular-eslint/no-output-native), поэтому output переименован.\n public readonly selectRow: OutputEmitterRef<IRtThreadList.TRowId> = output<IRtThreadList.TRowId>();\n\n // Ctrl/⌘+клик по строке: потребитель открывает строку в новой вкладке.\n // Обычный клик остаётся на `selectRow`.\n public readonly openInNewTab: OutputEmitterRef<IRtThreadList.TRowId> = output<IRtThreadList.TRowId>();\n\n public readonly searchChange: OutputEmitterRef<string> = output<string>();\n\n public readonly loadMore: OutputEmitterRef<void> = output<void>();\n\n public ngOnInit(): void {\n // Дебаунс непустого ввода; очистка крестиком применяется сразу (searchDebounce).\n this.searchControl.valueChanges\n .pipe(\n map((value: string): string => value.trim()),\n searchDebounce(),\n distinctUntilChanged(),\n takeUntilDestroyed(this.#destroyRef)\n )\n .subscribe((value: string): void => this.searchChange.emit(value));\n }\n\n protected onSelect(id: IRtThreadList.TRowId, event: MouseEvent): void {\n // Ctrl (Win/Linux) или ⌘ (macOS) — «открыть в новой вкладке», как у\n // нативных ссылок. Иначе — обычный выбор строки в текущей вкладке.\n if (event.ctrlKey || event.metaKey) {\n this.openInNewTab.emit(id);\n return;\n }\n this.selectRow.emit(id);\n }\n\n protected onLoadMore(): void {\n this.loadMore.emit();\n }\n}\n","<ng-container rtBlock=\"rt-thread-list\">\n <header rtElem=\"head\">\n @if (searchTemplate()) {\n <div rtElem=\"search\" qa-dataid=\"thread-list-search\">\n <ng-container [ngTemplateOutlet]=\"searchTemplate()?.templateRef ?? null\" />\n </div>\n } @else {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"thread-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"searchPlaceholderText()\"\n [formControl]=\"searchControl\" />\n }\n @if (filtersTemplate()) {\n <rt-icon-button\n rtElem=\"filter-trigger\"\n qa-dataid=\"thread-list-filter\"\n icon=\"filter\"\n variant=\"secondary\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiFilters\"\n [indicator]=\"filtersActive()\"\n [rtPopover]=\"filtersPanel\" />\n }\n </header>\n\n <ng-template #rowButton let-row>\n <button\n rtElem=\"row\"\n qa-dataid=\"thread-list-row\"\n type=\"button\"\n [attr.data-id]=\"row.id\"\n [attr.data-unread]=\"row.hasUnread\"\n [attr.aria-current]=\"row.id === activeId() ? 'true' : null\"\n [rtMod]=\"{\n active: row.id === activeId(),\n unread: row.hasUnread,\n overdue: !!row.overdue,\n }\"\n (click)=\"onSelect(row.id, $event)\">\n @if (row.sign; as sign) {\n <rt-service-logo rtElem=\"row-sign\" qa-dataid=\"thread-list-row-sign\" size=\"xs\" [logos]=\"[sign]\" />\n <span rtElem=\"row-content\">\n <ng-container [ngTemplateOutlet]=\"rowContent\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowContent\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n </button>\n </ng-template>\n\n <ng-template #rowContent let-row>\n <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </ng-template>\n\n <ng-template #filtersPanel>\n <div rtElem=\"filters-panel\" qa-dataid=\"thread-list-filters-panel\">\n <ng-container [ngTemplateOutlet]=\"filtersTemplate()?.templateRef ?? null\" />\n </div>\n </ng-template>\n\n <div rtElem=\"rows\" qa-dataid=\"thread-list-rows\">\n @if (loading() && !rows().length) {\n @for (i of skeletonRows; track i) {\n <div rtElem=\"row-skeleton\" qa-dataid=\"thread-list-row-skeleton\" aria-hidden=\"true\">\n <rt-skeleton width=\"60%\" height=\"14px\" />\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n } @else if (!rows().length) {\n <rt-empty-state rtElem=\"empty\" qa-dataid=\"thread-list-empty\" [description]=\"t().uiThreadListEmptyHint\" [title]=\"emptyTitle()\">\n <div rtEmptyIllustration rtElem=\"empty-preview\">\n @for (row of emptyPreviewRows(); track row.id) {\n <div rtElem=\"empty-card\" [rtMod]=\"{ offset: row.offset }\">\n <span rtElem=\"empty-avatar\">\n <rt-icon size=\"sm\" [name]=\"row.icon\" />\n </span>\n <span rtElem=\"empty-lines\">\n <span rtElem=\"empty-line\" [rtMod]=\"{ short: true }\"></span>\n <span rtElem=\"empty-line\"></span>\n </span>\n </div>\n }\n </div>\n </rt-empty-state>\n } @else {\n @for (row of rows(); track row.id) {\n @if (rowActionsTemplate(); as actions) {\n <div rtElem=\"row-wrap\" qa-dataid=\"thread-list-row-wrap\">\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n <div rtElem=\"row-actions\" qa-dataid=\"thread-list-row-actions\">\n <ng-container [ngTemplateOutlet]=\"actions.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </div>\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n }\n @if (fetching()) {\n <div rtElem=\"row-loader\" qa-dataid=\"thread-list-row-loader\">\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n @if (hasMore()) {\n <div\n rtElem=\"load-anchor\"\n qa-dataid=\"thread-list-load-more\"\n aria-hidden=\"true\"\n rtInfiniteScroll\n [disabled]=\"fetching()\"\n (loadMore)=\"onLoadMore()\"></div>\n }\n }\n </div>\n</ng-container>\n"],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-thread-list.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.directives.ts","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.component.ts","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.component.html"],"sourcesContent":["import { Directive, inject, input, InputSignal, TemplateRef } from '@angular/core';\n\nimport { IRtThreadList } from './rt-thread-list.model';\n\n/**\n * Помечает `<ng-template>` содержимого строки списка. Входом `[rtThreadListRow]`\n * потребитель передаёт свой массив строк — из него выводится тип `TRow`, поэтому\n * `let-row` в темплейте типизируется строго (context-guard ниже это подтверждает).\n */\n@Directive({\n selector: 'ng-template[rtThreadListRow]',\n})\nexport class RtThreadListRowDirective<TRow extends IRtThreadList.Row> {\n public readonly templateRef: TemplateRef<IRtThreadList.RowContext<TRow>> =\n inject<TemplateRef<IRtThreadList.RowContext<TRow>>>(TemplateRef);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([], {\n alias: 'rtThreadListRow',\n });\n\n public static ngTemplateContextGuard<TRow extends IRtThreadList.Row>(\n _directive: RtThreadListRowDirective<TRow>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtThreadList.RowContext<TRow> {\n return true;\n }\n}\n\n/**\n * Помечает `<ng-template>` действий строки (удалить, закрепить). Действия рисуются рядом с\n * кнопкой строки, а не внутри неё: вложенная кнопка в `<button>` недопустима и крадёт клик\n * выбора строки. Видны при наведении и фокусе внутри строки.\n */\n@Directive({\n selector: 'ng-template[rtThreadListRowActions]',\n})\nexport class RtThreadListRowActionsDirective<TRow extends IRtThreadList.Row> {\n public readonly templateRef: TemplateRef<IRtThreadList.RowContext<TRow>> =\n inject<TemplateRef<IRtThreadList.RowContext<TRow>>>(TemplateRef);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([], {\n alias: 'rtThreadListRowActions',\n });\n\n public static ngTemplateContextGuard<TRow extends IRtThreadList.Row>(\n _directive: RtThreadListRowActionsDirective<TRow>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtThreadList.RowContext<TRow> {\n return true;\n }\n}\n\n/**\n * Помечает `<ng-template>` с фильтрами — его содержимое рендерится в поповере,\n * который открывает иконка-фильтр в шапке списка.\n */\n@Directive({\n selector: 'ng-template[rtThreadListFilters]',\n})\nexport class RtThreadListFiltersDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/**\n * Помечает `<ng-template>` с кастомным контролом поиска. Когда потребитель его\n * проецирует, шапка списка рендерит его содержимое вместо встроенного `rt-input`\n * — так воркспейс подставляет свой автокомплит по каталогу вместо текстового\n * поиска, не ломая generic-природу списка.\n */\n@Directive({\n selector: 'ng-template[rtThreadListSearch]',\n})\nexport class RtThreadListSearchDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n InputSignal,\n InputSignalWithTransform,\n OnInit,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\nimport { distinctUntilChanged, map } from 'rxjs';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { searchDebounce } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtInfiniteScrollDirective } from '@rt-tools/ui-kit-v2/core';\nimport { RtEmptyStateComponent } from '@rt-tools/ui-kit-v2/empty-state';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtServiceLogoComponent } from '@rt-tools/ui-kit-v2/service-logo';\nimport { RtSkeletonComponent } from '@rt-tools/ui-kit-v2/skeleton';\nimport {\n RtThreadListFiltersDirective,\n RtThreadListRowActionsDirective,\n RtThreadListRowDirective,\n RtThreadListSearchDirective,\n} from './rt-thread-list.directives';\nimport { IRtThreadList } from './rt-thread-list.model';\n\nconst BEM_BLOCK: string = 'rt-thread-list';\n\n/** Кол-во скелетон-строк на первичной загрузке (пока `rows` пусты). */\nconst SKELETON_ROWS_COUNT: number = 6;\n\n/** Значки строк-превью пустого списка по умолчанию: люди переписки. */\nconst PREVIEW_ICONS: readonly IRtIcon.Name[] = ['user', 'users', 'user'];\n\n/**\n * Презентационный список тредов для воркспейсов:\n * поиск с дебаунсом, фильтр-поповер и бесконечная прокрутка. Данные и оркестрация\n * — на вызывающем; список стора/api не видит.\n *\n * Строку рисует потребитель через `<ng-template rtThreadListRow let-row>` (body +\n * meta); оболочка владеет кнопкой строки (active/unread/overdue), поиском, кнопкой\n * фильтров (точка-индикатор при `filtersActive`) и скроллом. Фильтры потребитель\n * кладёт в `<ng-template rtThreadListFilters>` — они рендерятся в поповере.\n */\n@Component({\n selector: 'rt-thread-list',\n templateUrl: './rt-thread-list.component.html',\n styleUrls: ['./rt-thread-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n ReactiveFormsModule,\n\n // standalone components / directives\n RtEmptyStateComponent,\n RtIconComponent,\n RtIconButtonComponent,\n RtInputComponent,\n RtPopoverDirective,\n RtServiceLogoComponent,\n RtSkeletonComponent,\n BlockDirective,\n ElemDirective,\n RtInfiniteScrollDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtThreadListComponent<TRow extends IRtThreadList.Row> implements OnInit {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #t_uiSearch: Signal<string> = rtKitLabel('uiSearch');\n readonly #t_uiNothingFound: Signal<string> = rtKitLabel('uiNothingFound');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly searchPlaceholderText: Signal<string> = computed((): string => this.searchPlaceholder() || this.#t_uiSearch());\n protected readonly emptyTitle: Signal<string> = computed((): string => this.emptyText() || this.#t_uiNothingFound());\n\n protected readonly skeletonRows: number[] = Array.from({ length: SKELETON_ROWS_COUNT }, (_: unknown, i: number): number => i);\n\n /** Декоративные строки-превью пустого состояния: значок строки из `emptyPreviewIcons`, каждая вторая сдвинута. */\n protected readonly emptyPreviewRows: Signal<readonly IRtThreadList.PreviewRow[]> = computed((): readonly IRtThreadList.PreviewRow[] =>\n this.emptyPreviewIcons().map((icon: IRtIcon.Name, index: number): IRtThreadList.PreviewRow => ({\n icon,\n id: index,\n offset: index % 2 === 1,\n }))\n );\n\n protected readonly searchControl: FormControl<string> = new FormControl<string>('', {\n nonNullable: true,\n });\n\n protected readonly rowTemplate: Signal<RtThreadListRowDirective<TRow> | undefined> = contentChild(RtThreadListRowDirective<TRow>);\n\n protected readonly rowActionsTemplate: Signal<RtThreadListRowActionsDirective<TRow> | undefined> = contentChild(\n RtThreadListRowActionsDirective<TRow>\n );\n\n protected readonly filtersTemplate: Signal<RtThreadListFiltersDirective | undefined> = contentChild(RtThreadListFiltersDirective);\n\n protected readonly searchTemplate: Signal<RtThreadListSearchDirective | undefined> = contentChild(RtThreadListSearchDirective);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([]);\n\n public readonly activeId: InputSignal<IRtThreadList.TRowId | null> = input<IRtThreadList.TRowId | null>(null);\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly searchPlaceholder: InputSignal<string> = input<string>('');\n\n public readonly emptyText: InputSignal<string> = input<string>('');\n\n /** Значки декоративных строк-превью пустого состояния, по строке на значок */\n public readonly emptyPreviewIcons: InputSignal<readonly IRtIcon.Name[]> = input<readonly IRtIcon.Name[]>(PREVIEW_ICONS);\n\n public readonly loading: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly fetching: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly hasMore: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly filtersActive: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n // Имя `select` зарезервировано под нативное DOM-событие\n // (@angular-eslint/no-output-native), поэтому output переименован.\n public readonly selectRow: OutputEmitterRef<IRtThreadList.TRowId> = output<IRtThreadList.TRowId>();\n\n // Ctrl/⌘+клик по строке: потребитель открывает строку в новой вкладке.\n // Обычный клик остаётся на `selectRow`.\n public readonly openInNewTab: OutputEmitterRef<IRtThreadList.TRowId> = output<IRtThreadList.TRowId>();\n\n public readonly searchChange: OutputEmitterRef<string> = output<string>();\n\n public readonly loadMore: OutputEmitterRef<void> = output<void>();\n\n public ngOnInit(): void {\n // Дебаунс непустого ввода; очистка крестиком применяется сразу (searchDebounce).\n this.searchControl.valueChanges\n .pipe(\n map((value: string): string => value.trim()),\n searchDebounce(),\n distinctUntilChanged(),\n takeUntilDestroyed(this.#destroyRef)\n )\n .subscribe((value: string): void => this.searchChange.emit(value));\n }\n\n protected onSelect(id: IRtThreadList.TRowId, event: MouseEvent): void {\n // Ctrl (Win/Linux) или ⌘ (macOS) — «открыть в новой вкладке», как у\n // нативных ссылок. Иначе — обычный выбор строки в текущей вкладке.\n if (event.ctrlKey || event.metaKey) {\n this.openInNewTab.emit(id);\n return;\n }\n this.selectRow.emit(id);\n }\n\n protected onLoadMore(): void {\n this.loadMore.emit();\n }\n}\n","<ng-container rtBlock=\"rt-thread-list\">\n <header rtElem=\"head\">\n @if (searchTemplate()) {\n <div rtElem=\"search\" qa-dataid=\"thread-list-search\">\n <ng-container [ngTemplateOutlet]=\"searchTemplate()?.templateRef ?? null\" />\n </div>\n } @else {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"thread-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"searchPlaceholderText()\"\n [formControl]=\"searchControl\" />\n }\n @if (filtersTemplate()) {\n <rt-icon-button\n rtElem=\"filter-trigger\"\n qa-dataid=\"thread-list-filter\"\n icon=\"filter\"\n variant=\"secondary\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiFilters\"\n [indicator]=\"filtersActive()\"\n [rtPopover]=\"filtersPanel\" />\n }\n </header>\n\n <ng-template #rowButton let-row>\n <button\n rtElem=\"row\"\n qa-dataid=\"thread-list-row\"\n type=\"button\"\n [attr.data-id]=\"row.id\"\n [attr.data-unread]=\"row.hasUnread\"\n [attr.aria-current]=\"row.id === activeId() ? 'true' : null\"\n [rtMod]=\"{\n active: row.id === activeId(),\n unread: row.hasUnread,\n overdue: !!row.overdue,\n }\"\n (click)=\"onSelect(row.id, $event)\">\n @if (row.sign; as sign) {\n <rt-service-logo rtElem=\"row-sign\" qa-dataid=\"thread-list-row-sign\" size=\"xs\" [logos]=\"[sign]\" />\n <span rtElem=\"row-content\">\n <ng-container [ngTemplateOutlet]=\"rowContent\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowContent\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n </button>\n </ng-template>\n\n <ng-template #rowContent let-row>\n <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </ng-template>\n\n <ng-template #filtersPanel>\n <div rtElem=\"filters-panel\" qa-dataid=\"thread-list-filters-panel\">\n <ng-container [ngTemplateOutlet]=\"filtersTemplate()?.templateRef ?? null\" />\n </div>\n </ng-template>\n\n <div rtElem=\"rows\" qa-dataid=\"thread-list-rows\">\n @if (loading() && !rows().length) {\n @for (i of skeletonRows; track i) {\n <div rtElem=\"row-skeleton\" qa-dataid=\"thread-list-row-skeleton\" aria-hidden=\"true\">\n <rt-skeleton width=\"60%\" height=\"14px\" />\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n } @else if (!rows().length) {\n <rt-empty-state rtElem=\"empty\" qa-dataid=\"thread-list-empty\" [description]=\"t().uiThreadListEmptyHint\" [title]=\"emptyTitle()\">\n <div rtEmptyIllustration rtElem=\"empty-preview\">\n @for (row of emptyPreviewRows(); track row.id) {\n <div rtElem=\"empty-card\" [rtMod]=\"{ offset: row.offset }\">\n <span rtElem=\"empty-avatar\">\n <rt-icon size=\"sm\" [name]=\"row.icon\" />\n </span>\n <span rtElem=\"empty-lines\">\n <span rtElem=\"empty-line\" [rtMod]=\"{ short: true }\"></span>\n <span rtElem=\"empty-line\"></span>\n </span>\n </div>\n }\n </div>\n </rt-empty-state>\n } @else {\n @for (row of rows(); track row.id) {\n @if (rowActionsTemplate(); as actions) {\n <div rtElem=\"row-wrap\" qa-dataid=\"thread-list-row-wrap\">\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n <div rtElem=\"row-actions\" qa-dataid=\"thread-list-row-actions\">\n <ng-container [ngTemplateOutlet]=\"actions.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </div>\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n }\n @if (fetching()) {\n <div rtElem=\"row-loader\" qa-dataid=\"thread-list-row-loader\">\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n @if (hasMore()) {\n <div\n rtElem=\"load-anchor\"\n qa-dataid=\"thread-list-load-more\"\n aria-hidden=\"true\"\n rtInfiniteScroll\n [disabled]=\"fetching()\"\n (loadMore)=\"onLoadMore()\"></div>\n }\n }\n </div>\n</ng-container>\n"],"mappings":"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"}
@@ -406,6 +406,8 @@ var RtToastComponent = class RtToastComponent {
406
406
  "disabled",
407
407
  "active",
408
408
  "expanded",
409
+ "ariaHaspopup",
410
+ "link",
409
411
  "indicator"
410
412
  ],
411
413
  outputs: ["clicked"]
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-toast.mjs","names":["BEM_BLOCK"],"sources":["../../../projects/ui-kit-v2/src/lib/components/toast/rt-toaster.model.ts","../../../projects/ui-kit-v2/src/lib/components/toast/rt-toast.component.ts","../../../projects/ui-kit-v2/src/lib/components/toast/rt-toast.component.html","../../../projects/ui-kit-v2/src/lib/components/toast/rt-toaster.component.ts","../../../projects/ui-kit-v2/src/lib/components/toast/rt-toaster.component.html"],"sourcesContent":["import { InjectionToken, Type } from '@angular/core';\n\nimport { INotification, NotificationRef } from '@rt-tools/ui-kit-v2/core';\n\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\nexport const RT_TOASTER_GAP_PX: number = 14;\n\n/**\n * Значки severity у тоста. Приложение подменяет карту целиком — например, на имена\n * Material, — а тост со своим `icon` берёт свой значок мимо карты.\n */\nexport const RT_TOAST_SEVERITY_ICONS: InjectionToken<Readonly<Record<INotification.Severity, IRtIcon.Name>>> = new InjectionToken<\n Readonly<Record<INotification.Severity, IRtIcon.Name>>\n>('RT_TOAST_SEVERITY_ICONS', {\n providedIn: 'root',\n factory: (): Readonly<Record<INotification.Severity, IRtIcon.Name>> => ({\n info: 'info-circle',\n success: 'check-circle',\n warning: 'exclamation-circle',\n danger: 'times-circle',\n }),\n});\n\n/** Данные своего компонента тоста — то, что приложение передало в `openFromComponent`. */\nexport const RT_TOAST_DATA: InjectionToken<unknown> = new InjectionToken<unknown>('RT_TOAST_DATA');\n\nexport namespace IRtToaster {\n export type Position = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';\n\n export type PositionY = 'top' | 'bottom';\n\n export type PositionX = 'left' | 'center' | 'right';\n\n /** `stack` копит тосты стопкой; `replace` — новый тост уводит прежние. */\n export type Mode = 'stack' | 'replace';\n\n export interface Toast {\n readonly id: number;\n readonly severity: INotification.Severity;\n readonly message: string;\n readonly description?: string;\n readonly meta?: string;\n readonly action?: INotification.Action;\n readonly secondaryAction?: INotification.Action;\n readonly filled?: boolean;\n readonly duration?: number | null;\n readonly progress?: boolean;\n readonly icon?: IRtIcon.Name | null;\n readonly onDismiss?: (reason: INotification.DismissReason) => void;\n /** Тост вытеснен новым в режиме `replace` и уходит своей анимацией. */\n readonly replaced?: boolean;\n readonly progressValue?: number | null;\n readonly details?: string;\n readonly component?: Type<unknown>;\n readonly data?: unknown;\n /** Голый тост: оболочки нет, свой компонент рисует карточку сам. */\n readonly bare?: boolean;\n /** Ручка тоста: тост сообщает ей, почему ушёл. */\n readonly ref?: NotificationRef;\n /** Приложение закрыло тост ручкой: он уходит своей анимацией, как вытесненный. */\n readonly dismissRequested?: boolean;\n }\n\n /** Изменение показанного тоста от его ручки. */\n export interface Change {\n readonly toastId: number;\n readonly patch: INotification.Update & Pick<Toast, 'dismissRequested'>;\n }\n\n export interface Height {\n readonly toastId: number;\n readonly height: number;\n }\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { NgComponentOutlet } from '@angular/common';\nimport {\n afterNextRender,\n AfterViewInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n HostBinding,\n inject,\n Injector,\n input,\n InputSignal,\n InputSignalWithTransform,\n OnDestroy,\n output,\n OutputEmitterRef,\n signal,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { INotification, NotificationRef } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtCopyValueComponent } from '@rt-tools/ui-kit-v2/copy-value';\nimport { RtProgressBarComponent } from '@rt-tools/ui-kit-v2/progress-bar';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RT_TOAST_DATA, RT_TOAST_SEVERITY_ICONS, RT_TOASTER_GAP_PX, IRtToaster } from './rt-toaster.model';\n\n/** Что нужно своему компоненту тоста: данные и ручка. Меняются они реже прочих полей тоста. */\ninterface IToastComponentInputs {\n readonly data: unknown;\n readonly ref: NotificationRef | undefined;\n}\n\nconst BEM_BLOCK: string = 'rt-toast';\n\nconst UNMOUNT_DELAY_MS: number = 200;\n\n@Component({\n selector: 'rt-toast',\n templateUrl: './rt-toast.component.html',\n styleUrl: './rt-toast.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgComponentOutlet,\n RtButtonDirective,\n RtCopyValueComponent,\n RtIconComponent,\n RtIconButtonComponent,\n RtProgressBarComponent,\n BlockDirective,\n ElemDirective,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'status',\n 'aria-atomic': 'true',\n },\n})\nexport class RtToastComponent implements AfterViewInit, OnDestroy {\n readonly #host: ElementRef<HTMLElement> = inject(ElementRef);\n\n readonly #injector: Injector = inject(Injector);\n\n /**\n * Данные и ручка своего компонента — отдельным сигналом с равенством по ним: живая доля\n * меняет тост на каждом тике, и без этого компонент создавался бы заново вместе с инжектором.\n */\n readonly #componentInputs: Signal<IToastComponentInputs> = computed(\n (): IToastComponentInputs => ({ data: this.toast().data, ref: this.toast().ref }),\n {\n equal: (left: IToastComponentInputs, right: IToastComponentInputs): boolean =>\n left.data === right.data && left.ref === right.ref,\n }\n );\n\n readonly #severityIcons: Readonly<Record<INotification.Severity, IRtIcon.Name>> = inject(RT_TOAST_SEVERITY_ICONS);\n\n readonly #mounted: WritableSignal<boolean> = signal<boolean>(false);\n\n readonly #removed: WritableSignal<boolean> = signal<boolean>(false);\n\n readonly #offsetBeforeRemove: WritableSignal<number> = signal<number>(0);\n\n readonly #initialHeight: WritableSignal<number> = signal<number>(0);\n\n readonly #heightIndex: Signal<number> = computed((): number =>\n this.heights().findIndex((item: IRtToaster.Height): boolean => item.toastId === this.toast().id)\n );\n\n readonly #heightBefore: Signal<number> = computed((): number =>\n this.heights().reduce(\n (total: number, item: IRtToaster.Height, itemIndex: number): number =>\n itemIndex >= this.#heightIndex() ? total : total + item.height,\n 0\n )\n );\n\n readonly #offset: Signal<number> = computed((): number => Math.round(this.#heightIndex() * RT_TOASTER_GAP_PX + this.#heightBefore()));\n\n readonly #positionY: Signal<IRtToaster.PositionY> = computed((): IRtToaster.PositionY =>\n this.position().startsWith('top') ? 'top' : 'bottom'\n );\n\n #timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n #unmountTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n #remainingTimeMs: number = 0;\n\n #closeTimerStartedAt: number = 0;\n\n #closeTimerPausedAt: number = 0;\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n /** Свой значок тоста важнее карты severity; `null` у тоста значок снимает. */\n protected readonly icon: Signal<IRtIcon.Name | null> = computed((): IRtIcon.Name | null => {\n const icon: IRtIcon.Name | null | undefined = this.toast().icon;\n return icon === undefined ? this.#severityIcons[this.toast().severity] : icon;\n });\n\n /** Срок жизни тоста: свой, если задан, иначе тостера; `null` — таймера нет. */\n protected readonly lifetime: Signal<number | null> = computed((): number | null => {\n const duration: number | null | undefined = this.toast().duration;\n return duration === undefined ? this.duration() : duration;\n });\n\n /** Инжектор своего компонента: данные токеном `RT_TOAST_DATA` и ручка `NotificationRef`. */\n protected readonly componentInjector: Signal<Injector> = computed((): Injector => {\n const inputs: IToastComponentInputs = this.#componentInputs();\n\n return Injector.create({\n providers: [\n { provide: RT_TOAST_DATA, useValue: inputs.data },\n { provide: NotificationRef, useValue: inputs.ref ?? null },\n ],\n parent: this.#injector,\n });\n });\n\n /** Живая доля задачи: число 0–100 — полоса стоит, `null` и пусто — её нет. */\n protected readonly progressValue: Signal<number | null> = computed((): number | null => this.toast().progressValue ?? null);\n\n /** Подробности раскрыты. */\n protected readonly detailsOpen: WritableSignal<boolean> = signal<boolean>(false);\n\n /** Голый тост: значка, крестика и полосы срока нет, оболочку снимает модификатор. */\n protected readonly bare: Signal<boolean> = computed((): boolean => this.toast().bare === true);\n\n protected readonly showProgress: Signal<boolean> = computed(\n (): boolean => !this.bare() && this.toast().progress === true && this.lifetime() !== null\n );\n\n /** Таймер и полоса срока встают от одного признака, чтобы не разойтись. */\n protected readonly paused: Signal<boolean> = computed((): boolean => this.expanded() || this.interacting());\n\n public readonly toast: InputSignal<IRtToaster.Toast> = input.required<IRtToaster.Toast>();\n\n public readonly index: InputSignal<number> = input.required<number>();\n\n public readonly totalToasts: InputSignal<number> = input.required<number>();\n\n public readonly heights: InputSignal<IRtToaster.Height[]> = input.required<IRtToaster.Height[]>();\n\n public readonly expanded: InputSignalWithTransform<boolean, BooleanInput> = input.required<boolean, BooleanInput>({\n transform: booleanAttribute,\n });\n\n public readonly expandByDefault: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly interacting: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly position: InputSignal<IRtToaster.Position> = input<IRtToaster.Position>('bottom-right');\n\n public readonly visibleToasts: InputSignal<number> = input<number>(3);\n\n public readonly duration: InputSignal<number> = input<number>(4000);\n\n public readonly heightAdded: OutputEmitterRef<IRtToaster.Height> = output<IRtToaster.Height>();\n\n public readonly heightRemoved: OutputEmitterRef<number> = output<number>();\n\n public readonly dismissed: OutputEmitterRef<number> = output<number>();\n\n @HostBinding('class')\n public get hostModifierClasses(): Record<string, boolean> {\n return {\n [`${BEM_BLOCK}--severity--${this.toast().severity}`]: true,\n [`${BEM_BLOCK}--filled`]: this.toast().filled === true,\n [`${BEM_BLOCK}--bare`]: this.bare(),\n [`${BEM_BLOCK}--y--${this.#positionY()}`]: true,\n [`${BEM_BLOCK}--mounted`]: this.#mounted(),\n [`${BEM_BLOCK}--removed`]: this.#removed(),\n [`${BEM_BLOCK}--front`]: this.index() === 0,\n [`${BEM_BLOCK}--hidden`]: this.index() + 1 > this.visibleToasts(),\n [`${BEM_BLOCK}--expanded`]: this.expanded() || (this.expandByDefault() && this.#mounted()),\n [`${BEM_BLOCK}--paused`]: this.paused(),\n };\n }\n\n @HostBinding('style')\n public get hostStackStyles(): Record<string, string> {\n return {\n '--index': `${this.index()}`,\n '--toasts-before': `${this.index()}`,\n '--z-index': `${this.totalToasts() - this.index()}`,\n '--offset': `${this.#removed() ? this.#offsetBeforeRemove() : this.#offset()}px`,\n '--initial-height': this.expandByDefault() ? 'auto' : `${this.#initialHeight()}px`,\n '--lifetime': `${this.lifetime() ?? 0}ms`,\n };\n }\n\n constructor() {\n effect((onCleanup: (cleanup: () => void) => void): void => {\n if (!this.#mounted() || this.#removed() || this.lifetime() === null) {\n return;\n }\n\n if (this.paused()) {\n this.#pauseTimer();\n } else {\n this.#startTimer();\n }\n\n onCleanup((): void => clearTimeout(this.#timeoutId));\n });\n\n // Вытесненный в режиме `replace` уходит тем же путём, что и закрытый крестиком.\n effect((): void => {\n if (this.#mounted() && this.toast().replaced === true) {\n this.#deleteToast('replaced');\n }\n });\n\n // Закрытый ручкой приложения — тоже.\n effect((): void => {\n if (this.#mounted() && this.toast().dismissRequested === true) {\n this.#deleteToast('dismiss');\n }\n });\n\n // Новый текст, доля или раскрытые подробности меняют высоту: стопка пересчитывает сдвиги.\n effect((): void => {\n const toast: IRtToaster.Toast = this.toast();\n this.detailsOpen();\n if (!this.#mounted() || toast.replaced === true) {\n return;\n }\n afterNextRender((): void => this.#remeasure(), { injector: this.#injector });\n });\n }\n\n public ngAfterViewInit(): void {\n this.#remainingTimeMs = this.lifetime() ?? 0;\n\n const height: number = this.#host.nativeElement.getBoundingClientRect().height;\n this.#initialHeight.set(height);\n this.heightAdded.emit({ toastId: this.toast().id, height });\n\n this.#mounted.set(true);\n }\n\n public ngOnDestroy(): void {\n clearTimeout(this.#timeoutId);\n clearTimeout(this.#unmountTimeoutId);\n // Тост ушёл не своим путём — вместе с тостером. Ушедший своим путём ручку уже закрыл, и\n // повторная отметка ничего не делает.\n this.toast().ref?.markClosed('destroyed');\n }\n\n protected onAction(): void {\n this.toast().action?.handler();\n this.#deleteToast(null);\n }\n\n protected onSecondaryAction(): void {\n this.toast().secondaryAction?.handler();\n this.#deleteToast(null);\n }\n\n protected onClose(): void {\n this.#deleteToast('close');\n }\n\n protected toggleDetails(): void {\n this.detailsOpen.update((open: boolean): boolean => !open);\n }\n\n /**\n * Уход тоста. Причину получает ручка; колбэк приложения — только уход без действия и без\n * `dismiss()`: действие уже вызвало свой обработчик, а закрыло тост само приложение.\n */\n #deleteToast(reason: INotification.CloseReason | null): void {\n if (this.#removed()) {\n return;\n }\n\n this.#removed.set(true);\n\n if (reason !== null && reason !== 'action' && reason !== 'dismiss' && reason !== 'destroyed') {\n this.toast().onDismiss?.(reason);\n }\n\n this.toast().ref?.markClosed(reason ?? 'action');\n\n this.#offsetBeforeRemove.set(this.#offset());\n this.heightRemoved.emit(this.toast().id);\n\n this.#unmountTimeoutId = setTimeout((): void => this.dismissed.emit(this.toast().id), UNMOUNT_DELAY_MS);\n }\n\n /** Высота по содержимому: своя высота стопки на время замера снимается. */\n #remeasure(): void {\n if (this.#removed()) {\n return;\n }\n\n const host: HTMLElement = this.#host.nativeElement;\n host.style.height = 'auto';\n const height: number = host.offsetHeight;\n host.style.height = '';\n\n if (height !== this.#initialHeight()) {\n this.#initialHeight.set(height);\n this.heightAdded.emit({ toastId: this.toast().id, height });\n }\n }\n\n #startTimer(): void {\n this.#closeTimerStartedAt = Date.now();\n this.#timeoutId = setTimeout((): void => this.#deleteToast('timeout'), this.#remainingTimeMs);\n }\n\n #pauseTimer(): void {\n if (this.#closeTimerPausedAt < this.#closeTimerStartedAt) {\n const elapsedMs: number = Date.now() - this.#closeTimerStartedAt;\n this.#remainingTimeMs = this.#remainingTimeMs - elapsedMs;\n }\n\n this.#closeTimerPausedAt = Date.now();\n }\n}\n","<ng-container rtBlock=\"rt-toast\">\n @if (!bare() && icon(); as icon) {\n <rt-icon rtElem=\"icon\" qa-dataid=\"toast-icon\" size=\"sm\" [name]=\"icon\" />\n }\n <div rtElem=\"content\" qa-dataid=\"toast-content\">\n @if (toast().meta; as meta) {\n <span rtElem=\"meta\" qa-dataid=\"toast-meta\">{{ meta }}</span>\n }\n @if (toast().component; as component) {\n <!-- Свой компонент встаёт на место сообщения; сообщение остаётся именем для чтения с экрана. -->\n @if (toast().message) {\n <span rtElem=\"sr-message\">{{ toast().message }}</span>\n }\n <div rtElem=\"custom\" qa-dataid=\"toast-custom\">\n <ng-container [ngComponentOutlet]=\"component\" [ngComponentOutletInjector]=\"componentInjector()\" />\n </div>\n } @else {\n <span rtElem=\"message\" qa-dataid=\"toast-message\">{{ toast().message }}</span>\n @if (toast().description; as description) {\n <span rtElem=\"description\" qa-dataid=\"toast-description\">{{ description }}</span>\n }\n }\n @if (progressValue() !== null) {\n <rt-progress-bar rtElem=\"value\" qa-dataid=\"toast-progress-value\" [value]=\"progressValue() ?? 0\" [ariaLabel]=\"toast().message\" />\n }\n @if (toast().details; as details) {\n <button\n rtButton\n rtElem=\"details-toggle\"\n qa-dataid=\"toast-details-toggle\"\n size=\"sm\"\n theme=\"secondary\"\n appearance=\"text\"\n type=\"button\"\n [attr.aria-expanded]=\"detailsOpen()\"\n (click)=\"toggleDetails()\">\n {{ detailsOpen() ? t().uiHide : t().uiDetails }}\n </button>\n @if (detailsOpen()) {\n <rt-copy-value rtElem=\"details\" qa-dataid=\"toast-details\" wrap [value]=\"details\" />\n }\n }\n @if (toast().action || toast().secondaryAction) {\n <div rtElem=\"actions\">\n @if (toast().action; as action) {\n <button rtButton rtElem=\"action\" qa-dataid=\"toast-action\" size=\"sm\" type=\"button\" (click)=\"onAction()\">\n {{ action.label }}\n </button>\n }\n @if (toast().secondaryAction; as secondaryAction) {\n <button\n rtButton\n rtElem=\"action\"\n qa-dataid=\"toast-secondary-action\"\n size=\"sm\"\n theme=\"secondary\"\n appearance=\"text\"\n type=\"button\"\n (click)=\"onSecondaryAction()\">\n {{ secondaryAction.label }}\n </button>\n }\n </div>\n }\n </div>\n @if (!bare()) {\n <rt-icon-button\n rtElem=\"close\"\n qa-dataid=\"toast-close\"\n icon=\"ico-close\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().uiClose\"\n (clicked)=\"onClose()\" />\n }\n @if (showProgress()) {\n <span rtElem=\"progress\" qa-dataid=\"toast-progress\" aria-hidden=\"true\"></span>\n }\n</ng-container>\n","import {\n ChangeDetectionStrategy,\n Component,\n HostBinding,\n InputSignal,\n InputSignalWithTransform,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n booleanAttribute,\n computed,\n inject,\n input,\n linkedSignal,\n numberAttribute,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { EMPTY, filter, map, merge, mergeMap, Observable } from 'rxjs';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { INotification, NotificationBus, NotificationRef } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtToastComponent } from './rt-toast.component';\nimport { RT_TOASTER_GAP_PX, IRtToaster } from './rt-toaster.model';\n\nconst BEM_BLOCK: string = 'rt-toaster';\n\nconst DEFAULT_DURATION_MS: number = 4000;\n\nconst DEFAULT_VISIBLE_TOASTS: number = 3;\n\n/** Канал события без своего `channel` и тостера без входа: один тостер по-прежнему получает всё. */\nconst DEFAULT_CHANNEL: string = 'default';\n\n@Component({\n selector: 'rt-toaster',\n templateUrl: './rt-toaster.component.html',\n styleUrl: './rt-toaster.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [RtToastComponent],\n host: {\n class: BEM_BLOCK,\n role: 'region',\n '[attr.aria-label]': 'ariaLabel()',\n '(mouseenter)': 'onStackEnter()',\n '(mousemove)': 'onStackEnter()',\n '(mouseleave)': 'onStackLeave()',\n '(pointerdown)': 'onStackPointerDown()',\n '(pointerup)': 'onStackPointerUp()',\n },\n})\nexport class RtToasterComponent {\n readonly #notificationBus: NotificationBus = inject(NotificationBus);\n\n protected readonly ariaLabel: Signal<string> = rtKitLabel('uiNotifications');\n\n #toastCounter: number = 0;\n\n protected readonly toasts: WritableSignal<IRtToaster.Toast[]> = signal<IRtToaster.Toast[]>([]);\n\n protected readonly heights: WritableSignal<IRtToaster.Height[]> = signal<IRtToaster.Height[]>([]);\n\n protected readonly expanded: WritableSignal<boolean> = linkedSignal<IRtToaster.Toast[], boolean>({\n source: this.toasts,\n computation: (toasts: IRtToaster.Toast[]): boolean => toasts.length < 1,\n });\n\n protected readonly interacting: WritableSignal<boolean> = signal<boolean>(false);\n\n protected readonly positionY: Signal<IRtToaster.PositionY> = computed((): IRtToaster.PositionY =>\n this.position().startsWith('top') ? 'top' : 'bottom'\n );\n\n protected readonly positionX: Signal<IRtToaster.PositionX> = computed((): IRtToaster.PositionX => {\n if (this.position().endsWith('left')) {\n return 'left';\n }\n return this.position().endsWith('center') ? 'center' : 'right';\n });\n\n public readonly position: InputSignal<IRtToaster.Position> = input<IRtToaster.Position>('bottom-right');\n\n public readonly duration: InputSignalWithTransform<number, number | string> = input<number, number | string>(DEFAULT_DURATION_MS, {\n transform: numberAttribute,\n });\n\n public readonly visibleToasts: InputSignalWithTransform<number, number | string> = input<number, number | string>(\n DEFAULT_VISIBLE_TOASTS,\n { transform: numberAttribute }\n );\n\n /** `replace` — новый тост уводит прежние их же анимацией ухода, а не копится стопкой. */\n public readonly mode: InputSignal<IRtToaster.Mode> = input<IRtToaster.Mode>('stack');\n\n public readonly expand: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Канал тостера: он показывает только события с этим `channel`. Второй тостер со своим каналом\n * держит закреплённые тосты в своём углу и своей стопке.\n */\n public readonly channel: InputSignal<string> = input<string>(DEFAULT_CHANNEL);\n\n @HostBinding('class')\n public get hostModifierClasses(): Record<string, boolean> {\n return {\n [`${BEM_BLOCK}--y--${this.positionY()}`]: true,\n [`${BEM_BLOCK}--x--${this.positionX()}`]: true,\n };\n }\n\n @HostBinding('style')\n public get hostStackStyles(): Record<string, string> {\n return {\n '--front-toast-height': `${this.heights()[0]?.height ?? 0}px`,\n '--gap': `${RT_TOASTER_GAP_PX}px`,\n };\n }\n\n constructor() {\n // Ручка тоста слушается до его ухода: `markClosed` завершает её потоки, и подписка уходит сама.\n this.#notificationBus\n .onEmit()\n .pipe(\n filter((event: INotification.Event): boolean => (event.payload.channel ?? DEFAULT_CHANNEL) === this.channel()),\n map((event: INotification.Event): IRtToaster.Toast => this.#addToast(event)),\n mergeMap((toast: IRtToaster.Toast): Observable<IRtToaster.Change> => this.#changesOf(toast)),\n takeUntilDestroyed()\n )\n .subscribe((change: IRtToaster.Change): void => this.#applyChange(change));\n }\n\n protected onStackEnter(): void {\n if (this.toasts().length > 0) {\n this.expanded.set(true);\n }\n }\n\n protected onStackLeave(): void {\n if (!this.interacting()) {\n this.expanded.set(false);\n }\n }\n\n protected onStackPointerDown(): void {\n this.interacting.set(true);\n }\n\n protected onStackPointerUp(): void {\n this.interacting.set(false);\n }\n\n protected onHeightAdded(height: IRtToaster.Height): void {\n this.heights.update((items: IRtToaster.Height[]): IRtToaster.Height[] =>\n this.#sortHeights([height, ...items.filter((item: IRtToaster.Height): boolean => item.toastId !== height.toastId)])\n );\n }\n\n protected onHeightRemoved(toastId: number): void {\n this.heights.update((items: IRtToaster.Height[]): IRtToaster.Height[] =>\n items.filter((item: IRtToaster.Height): boolean => item.toastId !== toastId)\n );\n }\n\n protected onDismissed(toastId: number): void {\n this.onHeightRemoved(toastId);\n this.toasts.update((items: IRtToaster.Toast[]): IRtToaster.Toast[] =>\n items.filter((item: IRtToaster.Toast): boolean => item.id !== toastId)\n );\n }\n\n #addToast(event: INotification.Event): IRtToaster.Toast {\n this.#toastCounter += 1;\n const toast: IRtToaster.Toast = {\n id: this.#toastCounter,\n severity: event.payload.severity,\n message: event.payload.message,\n description: event.payload.description,\n meta: event.payload.meta,\n action: event.payload.action,\n secondaryAction: event.payload.secondaryAction,\n filled: event.payload.filled,\n duration: event.payload.duration,\n progress: event.payload.progress,\n icon: event.payload.icon,\n onDismiss: event.payload.onDismiss,\n progressValue: event.payload.progressValue,\n details: event.payload.details,\n component: event.payload.component,\n data: event.payload.data,\n bare: event.payload.bare,\n ref: event.ref instanceof NotificationRef ? event.ref : undefined,\n };\n this.toasts.update((items: IRtToaster.Toast[]): IRtToaster.Toast[] => [\n toast,\n ...(this.mode() === 'replace' ? items.map((item: IRtToaster.Toast): IRtToaster.Toast => this.#replaced(item)) : items),\n ]);\n\n return toast;\n }\n\n /** Изменения тоста от его ручки: обновление полей и просьба закрыть. Без ручки — ничего. */\n #changesOf(toast: IRtToaster.Toast): Observable<IRtToaster.Change> {\n const ref: NotificationRef | undefined = toast.ref;\n\n if (ref === undefined) {\n return EMPTY;\n }\n\n return merge(\n ref.onUpdate().pipe(map((patch: INotification.Update): IRtToaster.Change => ({ toastId: toast.id, patch }))),\n ref.onDismissRequest().pipe(map((): IRtToaster.Change => ({ toastId: toast.id, patch: { dismissRequested: true } })))\n );\n }\n\n #applyChange(change: IRtToaster.Change): void {\n this.toasts.update((items: IRtToaster.Toast[]): IRtToaster.Toast[] =>\n items.map((item: IRtToaster.Toast): IRtToaster.Toast => (item.id === change.toastId ? { ...item, ...change.patch } : item))\n );\n }\n\n #replaced(toast: IRtToaster.Toast): IRtToaster.Toast {\n return toast.replaced ? toast : { ...toast, replaced: true };\n }\n\n #sortHeights(items: IRtToaster.Height[]): IRtToaster.Height[] {\n const order: number[] = this.toasts().map((toast: IRtToaster.Toast): number => toast.id);\n return [...items].sort(\n (left: IRtToaster.Height, right: IRtToaster.Height): number => order.indexOf(left.toastId) - order.indexOf(right.toastId)\n );\n }\n}\n","@for (item of toasts(); track item.id) {\n <rt-toast\n qa-dataid=\"toast\"\n [toast]=\"item\"\n [index]=\"$index\"\n [totalToasts]=\"toasts().length\"\n [heights]=\"heights()\"\n [expanded]=\"expanded()\"\n [expandByDefault]=\"expand()\"\n [interacting]=\"interacting()\"\n [position]=\"position()\"\n [visibleToasts]=\"visibleToasts()\"\n [duration]=\"duration()\"\n (heightAdded)=\"onHeightAdded($event)\"\n (heightRemoved)=\"onHeightRemoved($event)\"\n (dismissed)=\"onDismissed($event)\" />\n}\n"],"mappings":";;;;;;;;;;;;AAMA,MAAa,oBAA4B;AAMzC,MAAa,0BAAkG,IAAI,eAEjH,2BAA2B;CACzB,YAAY;CACZ,gBAAwE;EACpE,MAAM;EACN,SAAS;EACT,SAAS;EACT,QAAQ;CACX;AACJ,CAAA;AAGD,MAAa,gBAAyC,IAAI,eAAwB,eAAe;ACoBjG,MAAMA,cAAoB;AAE1B,MAAM,mBAA2B;AAwBjC,IAAa,mBAAb,MAAa,iBAAgB;CAChB;CAEA;CAMA;CAQA;CAEA;CAEA;CAEA;CAEA;CAEA;CAIA;CAQA;CAEA;CAIT;CAEA;CAEA;CAEA;CAEA;CA6EA,IACW,sBAAmB;EAC1B,OAAO;IACF,GAAGA,YAAS,cAAe,KAAK,MAAK,CAAE,CAAC,aAAa;IACrD,GAAGA,YAAS,YAAa,KAAK,MAAK,CAAE,CAAC,WAAW;IACjD,GAAGA,YAAS,UAAW,KAAK,KAAI;IAChC,GAAGA,YAAS,OAAQ,KAAK,WAAU,MAAO;IAC1C,GAAGA,YAAS,aAAc,KAAK,SAAQ;IACvC,GAAGA,YAAS,aAAc,KAAK,SAAQ;IACvC,GAAGA,YAAS,WAAY,KAAK,MAAK,MAAO;IACzC,GAAGA,YAAS,YAAa,KAAK,MAAK,IAAK,IAAI,KAAK,cAAa;IAC9D,GAAGA,YAAS,cAAe,KAAK,SAAQ,KAAO,KAAK,gBAAe,KAAM,KAAK,SAAQ;IACtF,GAAGA,YAAS,YAAa,KAAK,OAAM;EACxC;CACL;CAEA,IACW,kBAAe;EACtB,OAAO;GACH,WAAW,GAAG,KAAK,MAAK;GACxB,mBAAmB,GAAG,KAAK,MAAK;GAChC,aAAa,GAAG,KAAK,YAAW,IAAK,KAAK,MAAK;GAC/C,YAAY,GAAG,KAAK,SAAQ,IAAK,KAAK,oBAAmB,IAAK,KAAK,QAAO,EAAE;GAC5E,oBAAoB,KAAK,gBAAe,IAAK,SAAS,GAAG,KAAK,eAAc,EAAE;GAC9E,cAAc,GAAG,KAAK,SAAQ,KAAM,EAAC;EACxC;CACL;CAEA,cAAA;EA7JS,KAAA,QAAiC,OAAO,UAAU;EAElD,KAAA,YAAsB,OAAO,QAAQ;EAMrC,KAAA,mBAAkD,gBACzB;GAAE,MAAM,KAAK,MAAK,CAAE,CAAC;GAAM,KAAK,KAAK,MAAK,CAAE,CAAC;EAAG,IAAG;GAAA,GAAA,YAAA,EAAA,WAAA,mBAAA,+BAAA,CAAA;GAE7E,QAAQ,MAA6B,UACjC,KAAK,SAAS,MAAM,QAAQ,KAAK,QAAQ,MAAM;EAAG,CAAA;EAIrD,KAAA,iBAAyE,OAAO,uBAAuB;EAEvG,KAAA,WAAoC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAE1D,KAAA,WAAoC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAE1D,KAAA,sBAA8C,OAAe,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,sBAAA,CAAA,+BAAA,CAAA,CAAA;EAE/D,KAAA,iBAAyC,OAAe,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;EAE1D,KAAA,eAA+B,eACpC,KAAK,QAAO,CAAE,CAAC,WAAW,SAAqC,KAAK,YAAY,KAAK,MAAK,CAAE,CAAC,EAAE,GAClG,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAEQ,KAAA,gBAAgC,eACrC,KAAK,QAAO,CAAE,CAAC,QACV,OAAe,MAAyB,cACrC,aAAa,KAAK,aAAY,IAAK,QAAQ,QAAQ,KAAK,QAC5D,CAAC,GAER,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;EAEQ,KAAA,UAA0B,eAAuB,KAAK,MAAM,KAAK,aAAY,IAAA,KAAyB,KAAK,cAAa,CAAE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAE5H,KAAA,aAA2C,eAChD,KAAK,SAAQ,CAAE,CAAC,WAAW,KAAK,IAAI,QAAQ,UAC/C,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;EAMD,KAAA,mBAA2B;EAE3B,KAAA,uBAA+B;EAE/B,KAAA,sBAA8B;EAEX,KAAA,IAA4B,OAAO,aAAa;EAGhD,KAAA,OAAoC,eAAmC;GACtF,MAAM,OAAwC,KAAK,MAAK,CAAE,CAAC;GAC3D,OAAO,SAAS,SAAY,KAAK,eAAe,KAAK,MAAK,CAAE,CAAC,YAAY;EAC7E,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAGiB,KAAA,WAAkC,eAA6B;GAC9E,MAAM,WAAsC,KAAK,MAAK,CAAE,CAAC;GACzD,OAAO,aAAa,SAAY,KAAK,SAAQ,IAAK;EACtD,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAGiB,KAAA,oBAAsC,eAAwB;GAC7E,MAAM,SAAgC,KAAK,iBAAgB;GAE3D,OAAO,SAAS,OAAO;IACnB,WAAW,CACP;KAAE,SAAS;KAAe,UAAU,OAAO;IAAI,GAC/C;KAAE,SAAS;KAAiB,UAAU,OAAO,OAAO;IAAI,CAC3D;IACD,QAAQ,KAAK;GAChB,CAAA;EACL,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;EAGiB,KAAA,gBAAuC,eAA8B,KAAK,MAAK,CAAE,CAAC,iBAAiB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;EAGxG,KAAA,cAAuC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAG7D,KAAA,OAAwB,eAAwB,KAAK,MAAK,CAAE,CAAC,SAAS,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAE3E,KAAA,eAAgC,eAChC,CAAC,KAAK,KAAI,KAAM,KAAK,MAAK,CAAE,CAAC,aAAa,QAAQ,KAAK,SAAQ,MAAO,MACxF,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAGkB,KAAA,SAA0B,eAAwB,KAAK,SAAQ,KAAM,KAAK,YAAW,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;EAE3F,KAAA,QAAuC,MAAM,SAA4B,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAEzE,KAAA,QAA6B,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAErD,KAAA,cAAmC,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAE3D,KAAA,UAA4C,MAAM,SAA+B,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAEjF,KAAA,WAA4D,MAAM,SAAQ;GAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;GACtF,WAAW;EAAgB,CAAA;EAGf,KAAA,kBAAmE,MAA6B,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,kBAAA,+BAAA,CAAA;GACjH,WAAW;EAAgB,CAAA;EAGf,KAAA,cAA+D,MAA6B,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,cAAA,+BAAA,CAAA;GAC7G,WAAW;EAAgB,CAAA;EAGf,KAAA,WAA6C,MAA2B,gBAAe,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAEvF,KAAA,gBAAqC,MAAc,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;EAErD,KAAA,WAAgC,MAAc,KAAK,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAEnD,KAAA,cAAmD,OAAM;EAEzD,KAAA,gBAA0C,OAAM;EAEhD,KAAA,YAAsC,OAAM;EA+BxD,QAAQ,cAAkD;GACtD,IAAI,CAAC,KAAK,SAAQ,KAAM,KAAK,SAAQ,KAAM,KAAK,SAAQ,MAAO,MAC3D;GAGJ,IAAI,KAAK,OAAM,GACX,KAAK,YAAW;QAEhB,KAAK,YAAW;GAGpB,gBAAsB,aAAa,KAAK,UAAU,CAAC;EACvD,CAAC;EAGD,aAAkB;GACd,IAAI,KAAK,SAAQ,KAAM,KAAK,MAAK,CAAE,CAAC,aAAa,MAC7C,KAAK,aAAa,UAAU;EAEpC,CAAC;EAGD,aAAkB;GACd,IAAI,KAAK,SAAQ,KAAM,KAAK,MAAK,CAAE,CAAC,qBAAqB,MACrD,KAAK,aAAa,SAAS;EAEnC,CAAC;EAGD,aAAkB;GACd,MAAM,QAA0B,KAAK,MAAK;GAC1C,KAAK,YAAW;GAChB,IAAI,CAAC,KAAK,SAAQ,KAAM,MAAM,aAAa,MACvC;GAEJ,sBAA4B,KAAK,WAAU,GAAI,EAAE,UAAU,KAAK,UAAS,CAAE;EAC/E,CAAC;CACL;CAEO,kBAAe;EAClB,KAAK,mBAAmB,KAAK,SAAQ,KAAM;EAE3C,MAAM,SAAiB,KAAK,MAAM,cAAc,sBAAqB,CAAE,CAAC;EACxE,KAAK,eAAe,IAAI,MAAM;EAC9B,KAAK,YAAY,KAAK;GAAE,SAAS,KAAK,MAAK,CAAE,CAAC;GAAI;EAAM,CAAE;EAE1D,KAAK,SAAS,IAAI,IAAI;CAC1B;CAEO,cAAW;EACd,aAAa,KAAK,UAAU;EAC5B,aAAa,KAAK,iBAAiB;EAGnC,KAAK,MAAK,CAAE,CAAC,KAAK,WAAW,WAAW;CAC5C;CAEU,WAAQ;EACd,KAAK,MAAK,CAAE,CAAC,QAAQ,QAAO;EAC5B,KAAK,aAAa,IAAI;CAC1B;CAEU,oBAAiB;EACvB,KAAK,MAAK,CAAE,CAAC,iBAAiB,QAAO;EACrC,KAAK,aAAa,IAAI;CAC1B;CAEU,UAAO;EACb,KAAK,aAAa,OAAO;CAC7B;CAEU,gBAAa;EACnB,KAAK,YAAY,QAAQ,SAA2B,CAAC,IAAI;CAC7D;CAMA,aAAa,QAAwC;EACjD,IAAI,KAAK,SAAQ,GACb;EAGJ,KAAK,SAAS,IAAI,IAAI;EAEtB,IAAI,WAAW,QAAQ,WAAW,YAAY,WAAW,aAAa,WAAW,aAC7E,KAAK,MAAK,CAAE,CAAC,YAAY,MAAM;EAGnC,KAAK,MAAK,CAAE,CAAC,KAAK,WAAW,UAAU,QAAQ;EAE/C,KAAK,oBAAoB,IAAI,KAAK,QAAO,CAAE;EAC3C,KAAK,cAAc,KAAK,KAAK,MAAK,CAAE,CAAC,EAAE;EAEvC,KAAK,oBAAoB,iBAAuB,KAAK,UAAU,KAAK,KAAK,MAAK,CAAE,CAAC,EAAE,GAAG,gBAAgB;CAC1G;CAGA,aAAU;EACN,IAAI,KAAK,SAAQ,GACb;EAGJ,MAAM,OAAoB,KAAK,MAAM;EACrC,KAAK,MAAM,SAAS;EACpB,MAAM,SAAiB,KAAK;EAC5B,KAAK,MAAM,SAAS;EAEpB,IAAI,WAAW,KAAK,eAAc,GAAI;GAClC,KAAK,eAAe,IAAI,MAAM;GAC9B,KAAK,YAAY,KAAK;IAAE,SAAS,KAAK,MAAK,CAAE,CAAC;IAAI;GAAM,CAAE;EAC9D;CACJ;CAEA,cAAW;EACP,KAAK,uBAAuB,KAAK,IAAG;EACpC,KAAK,aAAa,iBAAuB,KAAK,aAAa,SAAS,GAAG,KAAK,gBAAgB;CAChG;CAEA,cAAW;EACP,IAAI,KAAK,sBAAsB,KAAK,sBAAsB;GACtD,MAAM,YAAoB,KAAK,IAAG,IAAK,KAAK;GAC5C,KAAK,mBAAmB,KAAK,mBAAmB;EACpD;EAEA,KAAK,sBAAsB,KAAK,IAAG;CACvC;CA9RS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAgB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAhB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAgB,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,aAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,SAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,iBAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,aAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,eAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,SAAA;IAAA,aAAA;IAAA,eAAA;IAAA,WAAA;GAAA;GAAA,MAAA;IAAA,YAAA;KAAA,QAAA;KAAA,eAAA;IAAA;IAAA,YAAA;KAAA,SAAA;KAAA,SAAA;IAAA;IAAA,gBAAA;GAAA;GAAA,UAAA;GAAA,UCvE7B;GA+EA,QAAA,CAAA,yoMAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MDvBQ;KAAiB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,UAAA,CAAA,mBAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACjB;KAAiB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACjB;KAAoB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,aAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACpB;KAAe,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACf;KAAqB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,SAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACrB;KAAsB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACtB;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAQR,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAgB,YAAA,CAAA;EAtB5B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAU,iBAGH,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACH;GAAA,MACK;IACF,OAAOA;IACP,MAAM;IACN,eAAe;GAClB;GAAA,UAAA;GAAA,QAAA,CAAA,yoMAAA;EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoIA,MAAA;GAAY,MAAA,CAAA,OAAO;;;GAgBnB,MAAA;GAAY,MAAA,CAAA,OAAO;;;;AE9LxB,MAAM,YAAoB;AAE1B,MAAM,sBAA8B;AAEpC,MAAM,yBAAiC;AAGvC,MAAM,kBAA0B;AAoBhC,IAAa,qBAAb,MAAa,mBAAkB;CAClB;CAIT;CAgDA,IACW,sBAAmB;EAC1B,OAAO;IACF,GAAG,UAAS,OAAQ,KAAK,UAAS,MAAO;IACzC,GAAG,UAAS,OAAQ,KAAK,UAAS,MAAO;EAC7C;CACL;CAEA,IACW,kBAAe;EACtB,OAAO;GACH,wBAAwB,GAAG,KAAK,QAAO,CAAE,CAAC,EAAE,EAAE,UAAU,EAAC;GACzD,SAAS;EACZ;CACL;CAEA,cAAA;EApES,KAAA,mBAAoC,OAAO,eAAe;EAEhD,KAAA,YAA4B,WAAW,iBAAiB;EAE3E,KAAA,gBAAwB;EAEL,KAAA,SAA6C,OAA2B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;EAE3E,KAAA,UAA+C,OAA4B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAE9E,KAAA,WAAoC,aAAY;GAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;GAC/D,QAAQ,KAAK;GACb,cAAc,WAAwC,OAAO,SAAS;EAAC,CAAA;EAGxD,KAAA,cAAuC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAE7D,KAAA,YAA0C,eACzD,KAAK,SAAQ,CAAE,CAAC,WAAW,KAAK,IAAI,QAAQ,UAC/C,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAEkB,KAAA,YAA0C,eAAoC;GAC7F,IAAI,KAAK,SAAQ,CAAE,CAAC,SAAS,MAAM,GAC/B,OAAO;GAEX,OAAO,KAAK,SAAQ,CAAE,CAAC,SAAS,QAAQ,IAAI,WAAW;EAC3D,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAEc,KAAA,WAA6C,MAA2B,gBAAe,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAEvF,KAAA,WAA8D,MAA+B,qBAAmB;GAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;GAC5H,WAAW;EAAe,CAAA;EAGd,KAAA,gBAAmE,MAC/E,wBAAsB;GAAA,GAAA,YAAA,EAAA,WAAA,gBAAA,+BAAA,CAAA;GACpB,WAAW;EAAe,CAAA;EAIhB,KAAA,OAAqC,MAAuB,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAEpE,KAAA,SAA8D,MAAiC,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,SAAA,+BAAA,CAAA;GAChH,WAAW;EAAgB,CAAA;EAOf,KAAA,UAA+B,MAAc,iBAAgB,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAoBzE,KAAK,iBACA,OAAM,CAAE,CACR,KACG,QAAQ,WAAyC,MAAM,QAAQ,WAAW,qBAAqB,KAAK,QAAO,CAAE,GAC7G,KAAK,UAAiD,KAAK,UAAU,KAAK,CAAC,GAC3E,UAAU,UAA2D,KAAK,WAAW,KAAK,CAAC,GAC3F,mBAAkB,CAAE,CACvB,CACA,WAAW,WAAoC,KAAK,aAAa,MAAM,CAAC;CACjF;CAEU,eAAY;EAClB,IAAI,KAAK,OAAM,CAAE,CAAC,SAAS,GACvB,KAAK,SAAS,IAAI,IAAI;CAE9B;CAEU,eAAY;EAClB,IAAI,CAAC,KAAK,YAAW,GACjB,KAAK,SAAS,IAAI,KAAK;CAE/B;CAEU,qBAAkB;EACxB,KAAK,YAAY,IAAI,IAAI;CAC7B;CAEU,mBAAgB;EACtB,KAAK,YAAY,IAAI,KAAK;CAC9B;CAEU,cAAc,QAAyB;EAC7C,KAAK,QAAQ,QAAQ,UACjB,KAAK,aAAa,CAAC,QAAQ,GAAG,MAAM,QAAQ,SAAqC,KAAK,YAAY,OAAO,OAAO,CAAC,CAAC,CAAC;CAE3H;CAEU,gBAAgB,SAAe;EACrC,KAAK,QAAQ,QAAQ,UACjB,MAAM,QAAQ,SAAqC,KAAK,YAAY,OAAO,CAAC;CAEpF;CAEU,YAAY,SAAe;EACjC,KAAK,gBAAgB,OAAO;EAC5B,KAAK,OAAO,QAAQ,UAChB,MAAM,QAAQ,SAAoC,KAAK,OAAO,OAAO,CAAC;CAE9E;CAEA,UAAU,OAA0B;EAChC,KAAK,iBAAiB;EACtB,MAAM,QAA0B;GAC5B,IAAI,KAAK;GACT,UAAU,MAAM,QAAQ;GACxB,SAAS,MAAM,QAAQ;GACvB,aAAa,MAAM,QAAQ;GAC3B,MAAM,MAAM,QAAQ;GACpB,QAAQ,MAAM,QAAQ;GACtB,iBAAiB,MAAM,QAAQ;GAC/B,QAAQ,MAAM,QAAQ;GACtB,UAAU,MAAM,QAAQ;GACxB,UAAU,MAAM,QAAQ;GACxB,MAAM,MAAM,QAAQ;GACpB,WAAW,MAAM,QAAQ;GACzB,eAAe,MAAM,QAAQ;GAC7B,SAAS,MAAM,QAAQ;GACvB,WAAW,MAAM,QAAQ;GACzB,MAAM,MAAM,QAAQ;GACpB,MAAM,MAAM,QAAQ;GACpB,KAAK,MAAM,eAAe,kBAAkB,MAAM,MAAM;EAC3D;EACD,KAAK,OAAO,QAAQ,UAAkD,CAClE,OACA,GAAI,KAAK,KAAI,MAAO,YAAY,MAAM,KAAK,SAA6C,KAAK,UAAU,IAAI,CAAC,IAAI,KACnH,CAAA;EAED,OAAO;CACX;CAGA,WAAW,OAAuB;EAC9B,MAAM,MAAmC,MAAM;EAE/C,IAAI,QAAQ,QACR,OAAO;EAGX,OAAO,MACH,IAAI,SAAQ,CAAE,CAAC,KAAK,KAAK,WAAoD;GAAE,SAAS,MAAM;GAAI;EAAK,EAAG,CAAC,GAC3G,IAAI,iBAAgB,CAAE,CAAC,KAAK,WAA8B;GAAE,SAAS,MAAM;GAAI,OAAO,EAAE,kBAAkB,KAAI;EAAE,EAAG,CAAC,CAAC;CAE7H;CAEA,aAAa,QAAyB;EAClC,KAAK,OAAO,QAAQ,UAChB,MAAM,KAAK,SAA8C,KAAK,OAAO,OAAO,UAAU;GAAE,GAAG;GAAM,GAAG,OAAO;EAAK,IAAK,IAAK,CAAC;CAEnI;CAEA,UAAU,OAAuB;EAC7B,OAAO,MAAM,WAAW,QAAQ;GAAE,GAAG;GAAO,UAAU;EAAI;CAC9D;CAEA,aAAa,OAA0B;EACnC,MAAM,QAAkB,KAAK,OAAM,CAAE,CAAC,KAAK,UAAoC,MAAM,EAAE;EACvF,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MACb,MAAyB,UAAqC,MAAM,QAAQ,KAAK,OAAO,IAAI,MAAM,QAAQ,MAAM,OAAO,CAAC;CAEjI;CApLS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAkB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAlB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAkB,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,eAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,QAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,SAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,MAAA;IAAA,YAAA,EAAA,QAAA,SAAA;IAAA,WAAA;KAAA,cAAA;KAAA,aAAA;KAAA,cAAA;KAAA,eAAA;KAAA,aAAA;IAAA;IAAA,YAAA;KAAA,mBAAA;KAAA,SAAA;KAAA,SAAA;IAAA;IAAA,gBAAA;GAAA;GAAA,UAAA;GAAA,UCtD/B;GAiBA,QAAA,CAAA,myBAAA;GAAA,cAAA,CAAA;IAAA,MAAA;IAAA,MDyBc;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;IAAA;GAAA,CAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAYjB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAkB,YAAA,CAAA;EAlB9B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAY,iBAGL,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B,CAAC,gBAAgB;GAAC,MACrB;IACF,OAAO;IACP,MAAM;IACN,qBAAqB;IACrB,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;GAClB;GAAA,UAAA;GAAA,QAAA,CAAA,myBAAA;EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDA,MAAA;GAAY,MAAA,CAAA,OAAO;;;GAQnB,MAAA;GAAY,MAAA,CAAA,OAAO"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-toast.mjs","names":["BEM_BLOCK"],"sources":["../../../projects/ui-kit-v2/src/lib/components/toast/rt-toaster.model.ts","../../../projects/ui-kit-v2/src/lib/components/toast/rt-toast.component.ts","../../../projects/ui-kit-v2/src/lib/components/toast/rt-toast.component.html","../../../projects/ui-kit-v2/src/lib/components/toast/rt-toaster.component.ts","../../../projects/ui-kit-v2/src/lib/components/toast/rt-toaster.component.html"],"sourcesContent":["import { InjectionToken, Type } from '@angular/core';\n\nimport { INotification, NotificationRef } from '@rt-tools/ui-kit-v2/core';\n\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\nexport const RT_TOASTER_GAP_PX: number = 14;\n\n/**\n * Значки severity у тоста. Приложение подменяет карту целиком — например, на имена\n * Material, — а тост со своим `icon` берёт свой значок мимо карты.\n */\nexport const RT_TOAST_SEVERITY_ICONS: InjectionToken<Readonly<Record<INotification.Severity, IRtIcon.Name>>> = new InjectionToken<\n Readonly<Record<INotification.Severity, IRtIcon.Name>>\n>('RT_TOAST_SEVERITY_ICONS', {\n providedIn: 'root',\n factory: (): Readonly<Record<INotification.Severity, IRtIcon.Name>> => ({\n info: 'info-circle',\n success: 'check-circle',\n warning: 'exclamation-circle',\n danger: 'times-circle',\n }),\n});\n\n/** Данные своего компонента тоста — то, что приложение передало в `openFromComponent`. */\nexport const RT_TOAST_DATA: InjectionToken<unknown> = new InjectionToken<unknown>('RT_TOAST_DATA');\n\nexport namespace IRtToaster {\n export type Position = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';\n\n export type PositionY = 'top' | 'bottom';\n\n export type PositionX = 'left' | 'center' | 'right';\n\n /** `stack` копит тосты стопкой; `replace` — новый тост уводит прежние. */\n export type Mode = 'stack' | 'replace';\n\n export interface Toast {\n readonly id: number;\n readonly severity: INotification.Severity;\n readonly message: string;\n readonly description?: string;\n readonly meta?: string;\n readonly action?: INotification.Action;\n readonly secondaryAction?: INotification.Action;\n readonly filled?: boolean;\n readonly duration?: number | null;\n readonly progress?: boolean;\n readonly icon?: IRtIcon.Name | null;\n readonly onDismiss?: (reason: INotification.DismissReason) => void;\n /** Тост вытеснен новым в режиме `replace` и уходит своей анимацией. */\n readonly replaced?: boolean;\n readonly progressValue?: number | null;\n readonly details?: string;\n readonly component?: Type<unknown>;\n readonly data?: unknown;\n /** Голый тост: оболочки нет, свой компонент рисует карточку сам. */\n readonly bare?: boolean;\n /** Ручка тоста: тост сообщает ей, почему ушёл. */\n readonly ref?: NotificationRef;\n /** Приложение закрыло тост ручкой: он уходит своей анимацией, как вытесненный. */\n readonly dismissRequested?: boolean;\n }\n\n /** Изменение показанного тоста от его ручки. */\n export interface Change {\n readonly toastId: number;\n readonly patch: INotification.Update & Pick<Toast, 'dismissRequested'>;\n }\n\n export interface Height {\n readonly toastId: number;\n readonly height: number;\n }\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { NgComponentOutlet } from '@angular/common';\nimport {\n afterNextRender,\n AfterViewInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n HostBinding,\n inject,\n Injector,\n input,\n InputSignal,\n InputSignalWithTransform,\n OnDestroy,\n output,\n OutputEmitterRef,\n signal,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { INotification, NotificationRef } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtCopyValueComponent } from '@rt-tools/ui-kit-v2/copy-value';\nimport { RtProgressBarComponent } from '@rt-tools/ui-kit-v2/progress-bar';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RT_TOAST_DATA, RT_TOAST_SEVERITY_ICONS, RT_TOASTER_GAP_PX, IRtToaster } from './rt-toaster.model';\n\n/** Что нужно своему компоненту тоста: данные и ручка. Меняются они реже прочих полей тоста. */\ninterface IToastComponentInputs {\n readonly data: unknown;\n readonly ref: NotificationRef | undefined;\n}\n\nconst BEM_BLOCK: string = 'rt-toast';\n\nconst UNMOUNT_DELAY_MS: number = 200;\n\n@Component({\n selector: 'rt-toast',\n templateUrl: './rt-toast.component.html',\n styleUrl: './rt-toast.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgComponentOutlet,\n RtButtonDirective,\n RtCopyValueComponent,\n RtIconComponent,\n RtIconButtonComponent,\n RtProgressBarComponent,\n BlockDirective,\n ElemDirective,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'status',\n 'aria-atomic': 'true',\n },\n})\nexport class RtToastComponent implements AfterViewInit, OnDestroy {\n readonly #host: ElementRef<HTMLElement> = inject(ElementRef);\n\n readonly #injector: Injector = inject(Injector);\n\n /**\n * Данные и ручка своего компонента — отдельным сигналом с равенством по ним: живая доля\n * меняет тост на каждом тике, и без этого компонент создавался бы заново вместе с инжектором.\n */\n readonly #componentInputs: Signal<IToastComponentInputs> = computed(\n (): IToastComponentInputs => ({ data: this.toast().data, ref: this.toast().ref }),\n {\n equal: (left: IToastComponentInputs, right: IToastComponentInputs): boolean =>\n left.data === right.data && left.ref === right.ref,\n }\n );\n\n readonly #severityIcons: Readonly<Record<INotification.Severity, IRtIcon.Name>> = inject(RT_TOAST_SEVERITY_ICONS);\n\n readonly #mounted: WritableSignal<boolean> = signal<boolean>(false);\n\n readonly #removed: WritableSignal<boolean> = signal<boolean>(false);\n\n readonly #offsetBeforeRemove: WritableSignal<number> = signal<number>(0);\n\n readonly #initialHeight: WritableSignal<number> = signal<number>(0);\n\n readonly #heightIndex: Signal<number> = computed((): number =>\n this.heights().findIndex((item: IRtToaster.Height): boolean => item.toastId === this.toast().id)\n );\n\n readonly #heightBefore: Signal<number> = computed((): number =>\n this.heights().reduce(\n (total: number, item: IRtToaster.Height, itemIndex: number): number =>\n itemIndex >= this.#heightIndex() ? total : total + item.height,\n 0\n )\n );\n\n readonly #offset: Signal<number> = computed((): number => Math.round(this.#heightIndex() * RT_TOASTER_GAP_PX + this.#heightBefore()));\n\n readonly #positionY: Signal<IRtToaster.PositionY> = computed((): IRtToaster.PositionY =>\n this.position().startsWith('top') ? 'top' : 'bottom'\n );\n\n #timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n #unmountTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n #remainingTimeMs: number = 0;\n\n #closeTimerStartedAt: number = 0;\n\n #closeTimerPausedAt: number = 0;\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n /** Свой значок тоста важнее карты severity; `null` у тоста значок снимает. */\n protected readonly icon: Signal<IRtIcon.Name | null> = computed((): IRtIcon.Name | null => {\n const icon: IRtIcon.Name | null | undefined = this.toast().icon;\n return icon === undefined ? this.#severityIcons[this.toast().severity] : icon;\n });\n\n /** Срок жизни тоста: свой, если задан, иначе тостера; `null` — таймера нет. */\n protected readonly lifetime: Signal<number | null> = computed((): number | null => {\n const duration: number | null | undefined = this.toast().duration;\n return duration === undefined ? this.duration() : duration;\n });\n\n /** Инжектор своего компонента: данные токеном `RT_TOAST_DATA` и ручка `NotificationRef`. */\n protected readonly componentInjector: Signal<Injector> = computed((): Injector => {\n const inputs: IToastComponentInputs = this.#componentInputs();\n\n return Injector.create({\n providers: [\n { provide: RT_TOAST_DATA, useValue: inputs.data },\n { provide: NotificationRef, useValue: inputs.ref ?? null },\n ],\n parent: this.#injector,\n });\n });\n\n /** Живая доля задачи: число 0–100 — полоса стоит, `null` и пусто — её нет. */\n protected readonly progressValue: Signal<number | null> = computed((): number | null => this.toast().progressValue ?? null);\n\n /** Подробности раскрыты. */\n protected readonly detailsOpen: WritableSignal<boolean> = signal<boolean>(false);\n\n /** Голый тост: значка, крестика и полосы срока нет, оболочку снимает модификатор. */\n protected readonly bare: Signal<boolean> = computed((): boolean => this.toast().bare === true);\n\n protected readonly showProgress: Signal<boolean> = computed(\n (): boolean => !this.bare() && this.toast().progress === true && this.lifetime() !== null\n );\n\n /** Таймер и полоса срока встают от одного признака, чтобы не разойтись. */\n protected readonly paused: Signal<boolean> = computed((): boolean => this.expanded() || this.interacting());\n\n public readonly toast: InputSignal<IRtToaster.Toast> = input.required<IRtToaster.Toast>();\n\n public readonly index: InputSignal<number> = input.required<number>();\n\n public readonly totalToasts: InputSignal<number> = input.required<number>();\n\n public readonly heights: InputSignal<IRtToaster.Height[]> = input.required<IRtToaster.Height[]>();\n\n public readonly expanded: InputSignalWithTransform<boolean, BooleanInput> = input.required<boolean, BooleanInput>({\n transform: booleanAttribute,\n });\n\n public readonly expandByDefault: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly interacting: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly position: InputSignal<IRtToaster.Position> = input<IRtToaster.Position>('bottom-right');\n\n public readonly visibleToasts: InputSignal<number> = input<number>(3);\n\n public readonly duration: InputSignal<number> = input<number>(4000);\n\n public readonly heightAdded: OutputEmitterRef<IRtToaster.Height> = output<IRtToaster.Height>();\n\n public readonly heightRemoved: OutputEmitterRef<number> = output<number>();\n\n public readonly dismissed: OutputEmitterRef<number> = output<number>();\n\n @HostBinding('class')\n public get hostModifierClasses(): Record<string, boolean> {\n return {\n [`${BEM_BLOCK}--severity--${this.toast().severity}`]: true,\n [`${BEM_BLOCK}--filled`]: this.toast().filled === true,\n [`${BEM_BLOCK}--bare`]: this.bare(),\n [`${BEM_BLOCK}--y--${this.#positionY()}`]: true,\n [`${BEM_BLOCK}--mounted`]: this.#mounted(),\n [`${BEM_BLOCK}--removed`]: this.#removed(),\n [`${BEM_BLOCK}--front`]: this.index() === 0,\n [`${BEM_BLOCK}--hidden`]: this.index() + 1 > this.visibleToasts(),\n [`${BEM_BLOCK}--expanded`]: this.expanded() || (this.expandByDefault() && this.#mounted()),\n [`${BEM_BLOCK}--paused`]: this.paused(),\n };\n }\n\n @HostBinding('style')\n public get hostStackStyles(): Record<string, string> {\n return {\n '--index': `${this.index()}`,\n '--toasts-before': `${this.index()}`,\n '--z-index': `${this.totalToasts() - this.index()}`,\n '--offset': `${this.#removed() ? this.#offsetBeforeRemove() : this.#offset()}px`,\n '--initial-height': this.expandByDefault() ? 'auto' : `${this.#initialHeight()}px`,\n '--lifetime': `${this.lifetime() ?? 0}ms`,\n };\n }\n\n constructor() {\n effect((onCleanup: (cleanup: () => void) => void): void => {\n if (!this.#mounted() || this.#removed() || this.lifetime() === null) {\n return;\n }\n\n if (this.paused()) {\n this.#pauseTimer();\n } else {\n this.#startTimer();\n }\n\n onCleanup((): void => clearTimeout(this.#timeoutId));\n });\n\n // Вытесненный в режиме `replace` уходит тем же путём, что и закрытый крестиком.\n effect((): void => {\n if (this.#mounted() && this.toast().replaced === true) {\n this.#deleteToast('replaced');\n }\n });\n\n // Закрытый ручкой приложения — тоже.\n effect((): void => {\n if (this.#mounted() && this.toast().dismissRequested === true) {\n this.#deleteToast('dismiss');\n }\n });\n\n // Новый текст, доля или раскрытые подробности меняют высоту: стопка пересчитывает сдвиги.\n effect((): void => {\n const toast: IRtToaster.Toast = this.toast();\n this.detailsOpen();\n if (!this.#mounted() || toast.replaced === true) {\n return;\n }\n afterNextRender((): void => this.#remeasure(), { injector: this.#injector });\n });\n }\n\n public ngAfterViewInit(): void {\n this.#remainingTimeMs = this.lifetime() ?? 0;\n\n const height: number = this.#host.nativeElement.getBoundingClientRect().height;\n this.#initialHeight.set(height);\n this.heightAdded.emit({ toastId: this.toast().id, height });\n\n this.#mounted.set(true);\n }\n\n public ngOnDestroy(): void {\n clearTimeout(this.#timeoutId);\n clearTimeout(this.#unmountTimeoutId);\n // Тост ушёл не своим путём — вместе с тостером. Ушедший своим путём ручку уже закрыл, и\n // повторная отметка ничего не делает.\n this.toast().ref?.markClosed('destroyed');\n }\n\n protected onAction(): void {\n this.toast().action?.handler();\n this.#deleteToast(null);\n }\n\n protected onSecondaryAction(): void {\n this.toast().secondaryAction?.handler();\n this.#deleteToast(null);\n }\n\n protected onClose(): void {\n this.#deleteToast('close');\n }\n\n protected toggleDetails(): void {\n this.detailsOpen.update((open: boolean): boolean => !open);\n }\n\n /**\n * Уход тоста. Причину получает ручка; колбэк приложения — только уход без действия и без\n * `dismiss()`: действие уже вызвало свой обработчик, а закрыло тост само приложение.\n */\n #deleteToast(reason: INotification.CloseReason | null): void {\n if (this.#removed()) {\n return;\n }\n\n this.#removed.set(true);\n\n if (reason !== null && reason !== 'action' && reason !== 'dismiss' && reason !== 'destroyed') {\n this.toast().onDismiss?.(reason);\n }\n\n this.toast().ref?.markClosed(reason ?? 'action');\n\n this.#offsetBeforeRemove.set(this.#offset());\n this.heightRemoved.emit(this.toast().id);\n\n this.#unmountTimeoutId = setTimeout((): void => this.dismissed.emit(this.toast().id), UNMOUNT_DELAY_MS);\n }\n\n /** Высота по содержимому: своя высота стопки на время замера снимается. */\n #remeasure(): void {\n if (this.#removed()) {\n return;\n }\n\n const host: HTMLElement = this.#host.nativeElement;\n host.style.height = 'auto';\n const height: number = host.offsetHeight;\n host.style.height = '';\n\n if (height !== this.#initialHeight()) {\n this.#initialHeight.set(height);\n this.heightAdded.emit({ toastId: this.toast().id, height });\n }\n }\n\n #startTimer(): void {\n this.#closeTimerStartedAt = Date.now();\n this.#timeoutId = setTimeout((): void => this.#deleteToast('timeout'), this.#remainingTimeMs);\n }\n\n #pauseTimer(): void {\n if (this.#closeTimerPausedAt < this.#closeTimerStartedAt) {\n const elapsedMs: number = Date.now() - this.#closeTimerStartedAt;\n this.#remainingTimeMs = this.#remainingTimeMs - elapsedMs;\n }\n\n this.#closeTimerPausedAt = Date.now();\n }\n}\n","<ng-container rtBlock=\"rt-toast\">\n @if (!bare() && icon(); as icon) {\n <rt-icon rtElem=\"icon\" qa-dataid=\"toast-icon\" size=\"sm\" [name]=\"icon\" />\n }\n <div rtElem=\"content\" qa-dataid=\"toast-content\">\n @if (toast().meta; as meta) {\n <span rtElem=\"meta\" qa-dataid=\"toast-meta\">{{ meta }}</span>\n }\n @if (toast().component; as component) {\n <!-- Свой компонент встаёт на место сообщения; сообщение остаётся именем для чтения с экрана. -->\n @if (toast().message) {\n <span rtElem=\"sr-message\">{{ toast().message }}</span>\n }\n <div rtElem=\"custom\" qa-dataid=\"toast-custom\">\n <ng-container [ngComponentOutlet]=\"component\" [ngComponentOutletInjector]=\"componentInjector()\" />\n </div>\n } @else {\n <span rtElem=\"message\" qa-dataid=\"toast-message\">{{ toast().message }}</span>\n @if (toast().description; as description) {\n <span rtElem=\"description\" qa-dataid=\"toast-description\">{{ description }}</span>\n }\n }\n @if (progressValue() !== null) {\n <rt-progress-bar rtElem=\"value\" qa-dataid=\"toast-progress-value\" [value]=\"progressValue() ?? 0\" [ariaLabel]=\"toast().message\" />\n }\n @if (toast().details; as details) {\n <button\n rtButton\n rtElem=\"details-toggle\"\n qa-dataid=\"toast-details-toggle\"\n size=\"sm\"\n theme=\"secondary\"\n appearance=\"text\"\n type=\"button\"\n [attr.aria-expanded]=\"detailsOpen()\"\n (click)=\"toggleDetails()\">\n {{ detailsOpen() ? t().uiHide : t().uiDetails }}\n </button>\n @if (detailsOpen()) {\n <rt-copy-value rtElem=\"details\" qa-dataid=\"toast-details\" wrap [value]=\"details\" />\n }\n }\n @if (toast().action || toast().secondaryAction) {\n <div rtElem=\"actions\">\n @if (toast().action; as action) {\n <button rtButton rtElem=\"action\" qa-dataid=\"toast-action\" size=\"sm\" type=\"button\" (click)=\"onAction()\">\n {{ action.label }}\n </button>\n }\n @if (toast().secondaryAction; as secondaryAction) {\n <button\n rtButton\n rtElem=\"action\"\n qa-dataid=\"toast-secondary-action\"\n size=\"sm\"\n theme=\"secondary\"\n appearance=\"text\"\n type=\"button\"\n (click)=\"onSecondaryAction()\">\n {{ secondaryAction.label }}\n </button>\n }\n </div>\n }\n </div>\n @if (!bare()) {\n <rt-icon-button\n rtElem=\"close\"\n qa-dataid=\"toast-close\"\n icon=\"ico-close\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().uiClose\"\n (clicked)=\"onClose()\" />\n }\n @if (showProgress()) {\n <span rtElem=\"progress\" qa-dataid=\"toast-progress\" aria-hidden=\"true\"></span>\n }\n</ng-container>\n","import {\n ChangeDetectionStrategy,\n Component,\n HostBinding,\n InputSignal,\n InputSignalWithTransform,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n booleanAttribute,\n computed,\n inject,\n input,\n linkedSignal,\n numberAttribute,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { EMPTY, filter, map, merge, mergeMap, Observable } from 'rxjs';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { INotification, NotificationBus, NotificationRef } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtToastComponent } from './rt-toast.component';\nimport { RT_TOASTER_GAP_PX, IRtToaster } from './rt-toaster.model';\n\nconst BEM_BLOCK: string = 'rt-toaster';\n\nconst DEFAULT_DURATION_MS: number = 4000;\n\nconst DEFAULT_VISIBLE_TOASTS: number = 3;\n\n/** Канал события без своего `channel` и тостера без входа: один тостер по-прежнему получает всё. */\nconst DEFAULT_CHANNEL: string = 'default';\n\n@Component({\n selector: 'rt-toaster',\n templateUrl: './rt-toaster.component.html',\n styleUrl: './rt-toaster.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [RtToastComponent],\n host: {\n class: BEM_BLOCK,\n role: 'region',\n '[attr.aria-label]': 'ariaLabel()',\n '(mouseenter)': 'onStackEnter()',\n '(mousemove)': 'onStackEnter()',\n '(mouseleave)': 'onStackLeave()',\n '(pointerdown)': 'onStackPointerDown()',\n '(pointerup)': 'onStackPointerUp()',\n },\n})\nexport class RtToasterComponent {\n readonly #notificationBus: NotificationBus = inject(NotificationBus);\n\n protected readonly ariaLabel: Signal<string> = rtKitLabel('uiNotifications');\n\n #toastCounter: number = 0;\n\n protected readonly toasts: WritableSignal<IRtToaster.Toast[]> = signal<IRtToaster.Toast[]>([]);\n\n protected readonly heights: WritableSignal<IRtToaster.Height[]> = signal<IRtToaster.Height[]>([]);\n\n protected readonly expanded: WritableSignal<boolean> = linkedSignal<IRtToaster.Toast[], boolean>({\n source: this.toasts,\n computation: (toasts: IRtToaster.Toast[]): boolean => toasts.length < 1,\n });\n\n protected readonly interacting: WritableSignal<boolean> = signal<boolean>(false);\n\n protected readonly positionY: Signal<IRtToaster.PositionY> = computed((): IRtToaster.PositionY =>\n this.position().startsWith('top') ? 'top' : 'bottom'\n );\n\n protected readonly positionX: Signal<IRtToaster.PositionX> = computed((): IRtToaster.PositionX => {\n if (this.position().endsWith('left')) {\n return 'left';\n }\n return this.position().endsWith('center') ? 'center' : 'right';\n });\n\n public readonly position: InputSignal<IRtToaster.Position> = input<IRtToaster.Position>('bottom-right');\n\n public readonly duration: InputSignalWithTransform<number, number | string> = input<number, number | string>(DEFAULT_DURATION_MS, {\n transform: numberAttribute,\n });\n\n public readonly visibleToasts: InputSignalWithTransform<number, number | string> = input<number, number | string>(\n DEFAULT_VISIBLE_TOASTS,\n { transform: numberAttribute }\n );\n\n /** `replace` — новый тост уводит прежние их же анимацией ухода, а не копится стопкой. */\n public readonly mode: InputSignal<IRtToaster.Mode> = input<IRtToaster.Mode>('stack');\n\n public readonly expand: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Канал тостера: он показывает только события с этим `channel`. Второй тостер со своим каналом\n * держит закреплённые тосты в своём углу и своей стопке.\n */\n public readonly channel: InputSignal<string> = input<string>(DEFAULT_CHANNEL);\n\n @HostBinding('class')\n public get hostModifierClasses(): Record<string, boolean> {\n return {\n [`${BEM_BLOCK}--y--${this.positionY()}`]: true,\n [`${BEM_BLOCK}--x--${this.positionX()}`]: true,\n };\n }\n\n @HostBinding('style')\n public get hostStackStyles(): Record<string, string> {\n return {\n '--front-toast-height': `${this.heights()[0]?.height ?? 0}px`,\n '--gap': `${RT_TOASTER_GAP_PX}px`,\n };\n }\n\n constructor() {\n // Ручка тоста слушается до его ухода: `markClosed` завершает её потоки, и подписка уходит сама.\n this.#notificationBus\n .onEmit()\n .pipe(\n filter((event: INotification.Event): boolean => (event.payload.channel ?? DEFAULT_CHANNEL) === this.channel()),\n map((event: INotification.Event): IRtToaster.Toast => this.#addToast(event)),\n mergeMap((toast: IRtToaster.Toast): Observable<IRtToaster.Change> => this.#changesOf(toast)),\n takeUntilDestroyed()\n )\n .subscribe((change: IRtToaster.Change): void => this.#applyChange(change));\n }\n\n protected onStackEnter(): void {\n if (this.toasts().length > 0) {\n this.expanded.set(true);\n }\n }\n\n protected onStackLeave(): void {\n if (!this.interacting()) {\n this.expanded.set(false);\n }\n }\n\n protected onStackPointerDown(): void {\n this.interacting.set(true);\n }\n\n protected onStackPointerUp(): void {\n this.interacting.set(false);\n }\n\n protected onHeightAdded(height: IRtToaster.Height): void {\n this.heights.update((items: IRtToaster.Height[]): IRtToaster.Height[] =>\n this.#sortHeights([height, ...items.filter((item: IRtToaster.Height): boolean => item.toastId !== height.toastId)])\n );\n }\n\n protected onHeightRemoved(toastId: number): void {\n this.heights.update((items: IRtToaster.Height[]): IRtToaster.Height[] =>\n items.filter((item: IRtToaster.Height): boolean => item.toastId !== toastId)\n );\n }\n\n protected onDismissed(toastId: number): void {\n this.onHeightRemoved(toastId);\n this.toasts.update((items: IRtToaster.Toast[]): IRtToaster.Toast[] =>\n items.filter((item: IRtToaster.Toast): boolean => item.id !== toastId)\n );\n }\n\n #addToast(event: INotification.Event): IRtToaster.Toast {\n this.#toastCounter += 1;\n const toast: IRtToaster.Toast = {\n id: this.#toastCounter,\n severity: event.payload.severity,\n message: event.payload.message,\n description: event.payload.description,\n meta: event.payload.meta,\n action: event.payload.action,\n secondaryAction: event.payload.secondaryAction,\n filled: event.payload.filled,\n duration: event.payload.duration,\n progress: event.payload.progress,\n icon: event.payload.icon,\n onDismiss: event.payload.onDismiss,\n progressValue: event.payload.progressValue,\n details: event.payload.details,\n component: event.payload.component,\n data: event.payload.data,\n bare: event.payload.bare,\n ref: event.ref instanceof NotificationRef ? event.ref : undefined,\n };\n this.toasts.update((items: IRtToaster.Toast[]): IRtToaster.Toast[] => [\n toast,\n ...(this.mode() === 'replace' ? items.map((item: IRtToaster.Toast): IRtToaster.Toast => this.#replaced(item)) : items),\n ]);\n\n return toast;\n }\n\n /** Изменения тоста от его ручки: обновление полей и просьба закрыть. Без ручки — ничего. */\n #changesOf(toast: IRtToaster.Toast): Observable<IRtToaster.Change> {\n const ref: NotificationRef | undefined = toast.ref;\n\n if (ref === undefined) {\n return EMPTY;\n }\n\n return merge(\n ref.onUpdate().pipe(map((patch: INotification.Update): IRtToaster.Change => ({ toastId: toast.id, patch }))),\n ref.onDismissRequest().pipe(map((): IRtToaster.Change => ({ toastId: toast.id, patch: { dismissRequested: true } })))\n );\n }\n\n #applyChange(change: IRtToaster.Change): void {\n this.toasts.update((items: IRtToaster.Toast[]): IRtToaster.Toast[] =>\n items.map((item: IRtToaster.Toast): IRtToaster.Toast => (item.id === change.toastId ? { ...item, ...change.patch } : item))\n );\n }\n\n #replaced(toast: IRtToaster.Toast): IRtToaster.Toast {\n return toast.replaced ? toast : { ...toast, replaced: true };\n }\n\n #sortHeights(items: IRtToaster.Height[]): IRtToaster.Height[] {\n const order: number[] = this.toasts().map((toast: IRtToaster.Toast): number => toast.id);\n return [...items].sort(\n (left: IRtToaster.Height, right: IRtToaster.Height): number => order.indexOf(left.toastId) - order.indexOf(right.toastId)\n );\n }\n}\n","@for (item of toasts(); track item.id) {\n <rt-toast\n qa-dataid=\"toast\"\n [toast]=\"item\"\n [index]=\"$index\"\n [totalToasts]=\"toasts().length\"\n [heights]=\"heights()\"\n [expanded]=\"expanded()\"\n [expandByDefault]=\"expand()\"\n [interacting]=\"interacting()\"\n [position]=\"position()\"\n [visibleToasts]=\"visibleToasts()\"\n [duration]=\"duration()\"\n (heightAdded)=\"onHeightAdded($event)\"\n (heightRemoved)=\"onHeightRemoved($event)\"\n (dismissed)=\"onDismissed($event)\" />\n}\n"],"mappings":";;;;;;;;;;;;AAMA,MAAa,oBAA4B;AAMzC,MAAa,0BAAkG,IAAI,eAEjH,2BAA2B;CACzB,YAAY;CACZ,gBAAwE;EACpE,MAAM;EACN,SAAS;EACT,SAAS;EACT,QAAQ;CACX;AACJ,CAAA;AAGD,MAAa,gBAAyC,IAAI,eAAwB,eAAe;ACoBjG,MAAMA,cAAoB;AAE1B,MAAM,mBAA2B;AAwBjC,IAAa,mBAAb,MAAa,iBAAgB;CAChB;CAEA;CAMA;CAQA;CAEA;CAEA;CAEA;CAEA;CAEA;CAIA;CAQA;CAEA;CAIT;CAEA;CAEA;CAEA;CAEA;CA6EA,IACW,sBAAmB;EAC1B,OAAO;IACF,GAAGA,YAAS,cAAe,KAAK,MAAK,CAAE,CAAC,aAAa;IACrD,GAAGA,YAAS,YAAa,KAAK,MAAK,CAAE,CAAC,WAAW;IACjD,GAAGA,YAAS,UAAW,KAAK,KAAI;IAChC,GAAGA,YAAS,OAAQ,KAAK,WAAU,MAAO;IAC1C,GAAGA,YAAS,aAAc,KAAK,SAAQ;IACvC,GAAGA,YAAS,aAAc,KAAK,SAAQ;IACvC,GAAGA,YAAS,WAAY,KAAK,MAAK,MAAO;IACzC,GAAGA,YAAS,YAAa,KAAK,MAAK,IAAK,IAAI,KAAK,cAAa;IAC9D,GAAGA,YAAS,cAAe,KAAK,SAAQ,KAAO,KAAK,gBAAe,KAAM,KAAK,SAAQ;IACtF,GAAGA,YAAS,YAAa,KAAK,OAAM;EACxC;CACL;CAEA,IACW,kBAAe;EACtB,OAAO;GACH,WAAW,GAAG,KAAK,MAAK;GACxB,mBAAmB,GAAG,KAAK,MAAK;GAChC,aAAa,GAAG,KAAK,YAAW,IAAK,KAAK,MAAK;GAC/C,YAAY,GAAG,KAAK,SAAQ,IAAK,KAAK,oBAAmB,IAAK,KAAK,QAAO,EAAE;GAC5E,oBAAoB,KAAK,gBAAe,IAAK,SAAS,GAAG,KAAK,eAAc,EAAE;GAC9E,cAAc,GAAG,KAAK,SAAQ,KAAM,EAAC;EACxC;CACL;CAEA,cAAA;EA7JS,KAAA,QAAiC,OAAO,UAAU;EAElD,KAAA,YAAsB,OAAO,QAAQ;EAMrC,KAAA,mBAAkD,gBACzB;GAAE,MAAM,KAAK,MAAK,CAAE,CAAC;GAAM,KAAK,KAAK,MAAK,CAAE,CAAC;EAAG,IAAG;GAAA,GAAA,YAAA,EAAA,WAAA,mBAAA,+BAAA,CAAA;GAE7E,QAAQ,MAA6B,UACjC,KAAK,SAAS,MAAM,QAAQ,KAAK,QAAQ,MAAM;EAAG,CAAA;EAIrD,KAAA,iBAAyE,OAAO,uBAAuB;EAEvG,KAAA,WAAoC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAE1D,KAAA,WAAoC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAE1D,KAAA,sBAA8C,OAAe,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,sBAAA,CAAA,+BAAA,CAAA,CAAA;EAE/D,KAAA,iBAAyC,OAAe,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,iBAAA,CAAA,+BAAA,CAAA,CAAA;EAE1D,KAAA,eAA+B,eACpC,KAAK,QAAO,CAAE,CAAC,WAAW,SAAqC,KAAK,YAAY,KAAK,MAAK,CAAE,CAAC,EAAE,GAClG,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAEQ,KAAA,gBAAgC,eACrC,KAAK,QAAO,CAAE,CAAC,QACV,OAAe,MAAyB,cACrC,aAAa,KAAK,aAAY,IAAK,QAAQ,QAAQ,KAAK,QAC5D,CAAC,GAER,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;EAEQ,KAAA,UAA0B,eAAuB,KAAK,MAAM,KAAK,aAAY,IAAA,KAAyB,KAAK,cAAa,CAAE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAE5H,KAAA,aAA2C,eAChD,KAAK,SAAQ,CAAE,CAAC,WAAW,KAAK,IAAI,QAAQ,UAC/C,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;EAMD,KAAA,mBAA2B;EAE3B,KAAA,uBAA+B;EAE/B,KAAA,sBAA8B;EAEX,KAAA,IAA4B,OAAO,aAAa;EAGhD,KAAA,OAAoC,eAAmC;GACtF,MAAM,OAAwC,KAAK,MAAK,CAAE,CAAC;GAC3D,OAAO,SAAS,SAAY,KAAK,eAAe,KAAK,MAAK,CAAE,CAAC,YAAY;EAC7E,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAGiB,KAAA,WAAkC,eAA6B;GAC9E,MAAM,WAAsC,KAAK,MAAK,CAAE,CAAC;GACzD,OAAO,aAAa,SAAY,KAAK,SAAQ,IAAK;EACtD,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAGiB,KAAA,oBAAsC,eAAwB;GAC7E,MAAM,SAAgC,KAAK,iBAAgB;GAE3D,OAAO,SAAS,OAAO;IACnB,WAAW,CACP;KAAE,SAAS;KAAe,UAAU,OAAO;IAAI,GAC/C;KAAE,SAAS;KAAiB,UAAU,OAAO,OAAO;IAAI,CAC3D;IACD,QAAQ,KAAK;GAChB,CAAA;EACL,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,oBAAA,CAAA,+BAAA,CAAA,CAAA;EAGiB,KAAA,gBAAuC,eAA8B,KAAK,MAAK,CAAE,CAAC,iBAAiB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;EAGxG,KAAA,cAAuC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAG7D,KAAA,OAAwB,eAAwB,KAAK,MAAK,CAAE,CAAC,SAAS,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAE3E,KAAA,eAAgC,eAChC,CAAC,KAAK,KAAI,KAAM,KAAK,MAAK,CAAE,CAAC,aAAa,QAAQ,KAAK,SAAQ,MAAO,MACxF,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAGkB,KAAA,SAA0B,eAAwB,KAAK,SAAQ,KAAM,KAAK,YAAW,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;EAE3F,KAAA,QAAuC,MAAM,SAA4B,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAEzE,KAAA,QAA6B,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAErD,KAAA,cAAmC,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAE3D,KAAA,UAA4C,MAAM,SAA+B,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAEjF,KAAA,WAA4D,MAAM,SAAQ;GAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;GACtF,WAAW;EAAgB,CAAA;EAGf,KAAA,kBAAmE,MAA6B,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,kBAAA,+BAAA,CAAA;GACjH,WAAW;EAAgB,CAAA;EAGf,KAAA,cAA+D,MAA6B,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,cAAA,+BAAA,CAAA;GAC7G,WAAW;EAAgB,CAAA;EAGf,KAAA,WAA6C,MAA2B,gBAAe,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAEvF,KAAA,gBAAqC,MAAc,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;EAErD,KAAA,WAAgC,MAAc,KAAK,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAEnD,KAAA,cAAmD,OAAM;EAEzD,KAAA,gBAA0C,OAAM;EAEhD,KAAA,YAAsC,OAAM;EA+BxD,QAAQ,cAAkD;GACtD,IAAI,CAAC,KAAK,SAAQ,KAAM,KAAK,SAAQ,KAAM,KAAK,SAAQ,MAAO,MAC3D;GAGJ,IAAI,KAAK,OAAM,GACX,KAAK,YAAW;QAEhB,KAAK,YAAW;GAGpB,gBAAsB,aAAa,KAAK,UAAU,CAAC;EACvD,CAAC;EAGD,aAAkB;GACd,IAAI,KAAK,SAAQ,KAAM,KAAK,MAAK,CAAE,CAAC,aAAa,MAC7C,KAAK,aAAa,UAAU;EAEpC,CAAC;EAGD,aAAkB;GACd,IAAI,KAAK,SAAQ,KAAM,KAAK,MAAK,CAAE,CAAC,qBAAqB,MACrD,KAAK,aAAa,SAAS;EAEnC,CAAC;EAGD,aAAkB;GACd,MAAM,QAA0B,KAAK,MAAK;GAC1C,KAAK,YAAW;GAChB,IAAI,CAAC,KAAK,SAAQ,KAAM,MAAM,aAAa,MACvC;GAEJ,sBAA4B,KAAK,WAAU,GAAI,EAAE,UAAU,KAAK,UAAS,CAAE;EAC/E,CAAC;CACL;CAEO,kBAAe;EAClB,KAAK,mBAAmB,KAAK,SAAQ,KAAM;EAE3C,MAAM,SAAiB,KAAK,MAAM,cAAc,sBAAqB,CAAE,CAAC;EACxE,KAAK,eAAe,IAAI,MAAM;EAC9B,KAAK,YAAY,KAAK;GAAE,SAAS,KAAK,MAAK,CAAE,CAAC;GAAI;EAAM,CAAE;EAE1D,KAAK,SAAS,IAAI,IAAI;CAC1B;CAEO,cAAW;EACd,aAAa,KAAK,UAAU;EAC5B,aAAa,KAAK,iBAAiB;EAGnC,KAAK,MAAK,CAAE,CAAC,KAAK,WAAW,WAAW;CAC5C;CAEU,WAAQ;EACd,KAAK,MAAK,CAAE,CAAC,QAAQ,QAAO;EAC5B,KAAK,aAAa,IAAI;CAC1B;CAEU,oBAAiB;EACvB,KAAK,MAAK,CAAE,CAAC,iBAAiB,QAAO;EACrC,KAAK,aAAa,IAAI;CAC1B;CAEU,UAAO;EACb,KAAK,aAAa,OAAO;CAC7B;CAEU,gBAAa;EACnB,KAAK,YAAY,QAAQ,SAA2B,CAAC,IAAI;CAC7D;CAMA,aAAa,QAAwC;EACjD,IAAI,KAAK,SAAQ,GACb;EAGJ,KAAK,SAAS,IAAI,IAAI;EAEtB,IAAI,WAAW,QAAQ,WAAW,YAAY,WAAW,aAAa,WAAW,aAC7E,KAAK,MAAK,CAAE,CAAC,YAAY,MAAM;EAGnC,KAAK,MAAK,CAAE,CAAC,KAAK,WAAW,UAAU,QAAQ;EAE/C,KAAK,oBAAoB,IAAI,KAAK,QAAO,CAAE;EAC3C,KAAK,cAAc,KAAK,KAAK,MAAK,CAAE,CAAC,EAAE;EAEvC,KAAK,oBAAoB,iBAAuB,KAAK,UAAU,KAAK,KAAK,MAAK,CAAE,CAAC,EAAE,GAAG,gBAAgB;CAC1G;CAGA,aAAU;EACN,IAAI,KAAK,SAAQ,GACb;EAGJ,MAAM,OAAoB,KAAK,MAAM;EACrC,KAAK,MAAM,SAAS;EACpB,MAAM,SAAiB,KAAK;EAC5B,KAAK,MAAM,SAAS;EAEpB,IAAI,WAAW,KAAK,eAAc,GAAI;GAClC,KAAK,eAAe,IAAI,MAAM;GAC9B,KAAK,YAAY,KAAK;IAAE,SAAS,KAAK,MAAK,CAAE,CAAC;IAAI;GAAM,CAAE;EAC9D;CACJ;CAEA,cAAW;EACP,KAAK,uBAAuB,KAAK,IAAG;EACpC,KAAK,aAAa,iBAAuB,KAAK,aAAa,SAAS,GAAG,KAAK,gBAAgB;CAChG;CAEA,cAAW;EACP,IAAI,KAAK,sBAAsB,KAAK,sBAAsB;GACtD,MAAM,YAAoB,KAAK,IAAG,IAAK,KAAK;GAC5C,KAAK,mBAAmB,KAAK,mBAAmB;EACpD;EAEA,KAAK,sBAAsB,KAAK,IAAG;CACvC;CA9RS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAgB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAhB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAgB,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,aAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,SAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,iBAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,aAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,eAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,SAAA;IAAA,aAAA;IAAA,eAAA;IAAA,WAAA;GAAA;GAAA,MAAA;IAAA,YAAA;KAAA,QAAA;KAAA,eAAA;IAAA;IAAA,YAAA;KAAA,SAAA;KAAA,SAAA;IAAA;IAAA,gBAAA;GAAA;GAAA,UAAA;GAAA,UCvE7B;GA+EA,QAAA,CAAA,yoMAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MDvBQ;KAAiB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,UAAA,CAAA,mBAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACjB;KAAiB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACjB;KAAoB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,aAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACpB;KAAe,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACf;KAAqB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,SAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACrB;KAAsB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACtB;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAQR,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAgB,YAAA,CAAA;EAtB5B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAU,iBAGH,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACH;GAAA,MACK;IACF,OAAOA;IACP,MAAM;IACN,eAAe;GAClB;GAAA,UAAA;GAAA,QAAA,CAAA,yoMAAA;EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoIA,MAAA;GAAY,MAAA,CAAA,OAAO;;;GAgBnB,MAAA;GAAY,MAAA,CAAA,OAAO;;;;AE9LxB,MAAM,YAAoB;AAE1B,MAAM,sBAA8B;AAEpC,MAAM,yBAAiC;AAGvC,MAAM,kBAA0B;AAoBhC,IAAa,qBAAb,MAAa,mBAAkB;CAClB;CAIT;CAgDA,IACW,sBAAmB;EAC1B,OAAO;IACF,GAAG,UAAS,OAAQ,KAAK,UAAS,MAAO;IACzC,GAAG,UAAS,OAAQ,KAAK,UAAS,MAAO;EAC7C;CACL;CAEA,IACW,kBAAe;EACtB,OAAO;GACH,wBAAwB,GAAG,KAAK,QAAO,CAAE,CAAC,EAAE,EAAE,UAAU,EAAC;GACzD,SAAS;EACZ;CACL;CAEA,cAAA;EApES,KAAA,mBAAoC,OAAO,eAAe;EAEhD,KAAA,YAA4B,WAAW,iBAAiB;EAE3E,KAAA,gBAAwB;EAEL,KAAA,SAA6C,OAA2B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,SAAA,CAAA,+BAAA,CAAA,CAAA;EAE3E,KAAA,UAA+C,OAA4B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAE9E,KAAA,WAAoC,aAAY;GAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;GAC/D,QAAQ,KAAK;GACb,cAAc,WAAwC,OAAO,SAAS;EAAC,CAAA;EAGxD,KAAA,cAAuC,OAAgB,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAE7D,KAAA,YAA0C,eACzD,KAAK,SAAQ,CAAE,CAAC,WAAW,KAAK,IAAI,QAAQ,UAC/C,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAEkB,KAAA,YAA0C,eAAoC;GAC7F,IAAI,KAAK,SAAQ,CAAE,CAAC,SAAS,MAAM,GAC/B,OAAO;GAEX,OAAO,KAAK,SAAQ,CAAE,CAAC,SAAS,QAAQ,IAAI,WAAW;EAC3D,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAEc,KAAA,WAA6C,MAA2B,gBAAe,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAEvF,KAAA,WAA8D,MAA+B,qBAAmB;GAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;GAC5H,WAAW;EAAe,CAAA;EAGd,KAAA,gBAAmE,MAC/E,wBAAsB;GAAA,GAAA,YAAA,EAAA,WAAA,gBAAA,+BAAA,CAAA;GACpB,WAAW;EAAe,CAAA;EAIhB,KAAA,OAAqC,MAAuB,SAAQ,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAEpE,KAAA,SAA8D,MAAiC,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,SAAA,+BAAA,CAAA;GAChH,WAAW;EAAgB,CAAA;EAOf,KAAA,UAA+B,MAAc,iBAAgB,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAoBzE,KAAK,iBACA,OAAM,CAAE,CACR,KACG,QAAQ,WAAyC,MAAM,QAAQ,WAAW,qBAAqB,KAAK,QAAO,CAAE,GAC7G,KAAK,UAAiD,KAAK,UAAU,KAAK,CAAC,GAC3E,UAAU,UAA2D,KAAK,WAAW,KAAK,CAAC,GAC3F,mBAAkB,CAAE,CACvB,CACA,WAAW,WAAoC,KAAK,aAAa,MAAM,CAAC;CACjF;CAEU,eAAY;EAClB,IAAI,KAAK,OAAM,CAAE,CAAC,SAAS,GACvB,KAAK,SAAS,IAAI,IAAI;CAE9B;CAEU,eAAY;EAClB,IAAI,CAAC,KAAK,YAAW,GACjB,KAAK,SAAS,IAAI,KAAK;CAE/B;CAEU,qBAAkB;EACxB,KAAK,YAAY,IAAI,IAAI;CAC7B;CAEU,mBAAgB;EACtB,KAAK,YAAY,IAAI,KAAK;CAC9B;CAEU,cAAc,QAAyB;EAC7C,KAAK,QAAQ,QAAQ,UACjB,KAAK,aAAa,CAAC,QAAQ,GAAG,MAAM,QAAQ,SAAqC,KAAK,YAAY,OAAO,OAAO,CAAC,CAAC,CAAC;CAE3H;CAEU,gBAAgB,SAAe;EACrC,KAAK,QAAQ,QAAQ,UACjB,MAAM,QAAQ,SAAqC,KAAK,YAAY,OAAO,CAAC;CAEpF;CAEU,YAAY,SAAe;EACjC,KAAK,gBAAgB,OAAO;EAC5B,KAAK,OAAO,QAAQ,UAChB,MAAM,QAAQ,SAAoC,KAAK,OAAO,OAAO,CAAC;CAE9E;CAEA,UAAU,OAA0B;EAChC,KAAK,iBAAiB;EACtB,MAAM,QAA0B;GAC5B,IAAI,KAAK;GACT,UAAU,MAAM,QAAQ;GACxB,SAAS,MAAM,QAAQ;GACvB,aAAa,MAAM,QAAQ;GAC3B,MAAM,MAAM,QAAQ;GACpB,QAAQ,MAAM,QAAQ;GACtB,iBAAiB,MAAM,QAAQ;GAC/B,QAAQ,MAAM,QAAQ;GACtB,UAAU,MAAM,QAAQ;GACxB,UAAU,MAAM,QAAQ;GACxB,MAAM,MAAM,QAAQ;GACpB,WAAW,MAAM,QAAQ;GACzB,eAAe,MAAM,QAAQ;GAC7B,SAAS,MAAM,QAAQ;GACvB,WAAW,MAAM,QAAQ;GACzB,MAAM,MAAM,QAAQ;GACpB,MAAM,MAAM,QAAQ;GACpB,KAAK,MAAM,eAAe,kBAAkB,MAAM,MAAM;EAC3D;EACD,KAAK,OAAO,QAAQ,UAAkD,CAClE,OACA,GAAI,KAAK,KAAI,MAAO,YAAY,MAAM,KAAK,SAA6C,KAAK,UAAU,IAAI,CAAC,IAAI,KACnH,CAAA;EAED,OAAO;CACX;CAGA,WAAW,OAAuB;EAC9B,MAAM,MAAmC,MAAM;EAE/C,IAAI,QAAQ,QACR,OAAO;EAGX,OAAO,MACH,IAAI,SAAQ,CAAE,CAAC,KAAK,KAAK,WAAoD;GAAE,SAAS,MAAM;GAAI;EAAK,EAAG,CAAC,GAC3G,IAAI,iBAAgB,CAAE,CAAC,KAAK,WAA8B;GAAE,SAAS,MAAM;GAAI,OAAO,EAAE,kBAAkB,KAAI;EAAE,EAAG,CAAC,CAAC;CAE7H;CAEA,aAAa,QAAyB;EAClC,KAAK,OAAO,QAAQ,UAChB,MAAM,KAAK,SAA8C,KAAK,OAAO,OAAO,UAAU;GAAE,GAAG;GAAM,GAAG,OAAO;EAAK,IAAK,IAAK,CAAC;CAEnI;CAEA,UAAU,OAAuB;EAC7B,OAAO,MAAM,WAAW,QAAQ;GAAE,GAAG;GAAO,UAAU;EAAI;CAC9D;CAEA,aAAa,OAA0B;EACnC,MAAM,QAAkB,KAAK,OAAM,CAAE,CAAC,KAAK,UAAoC,MAAM,EAAE;EACvF,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MACb,MAAyB,UAAqC,MAAM,QAAQ,KAAK,OAAO,IAAI,MAAM,QAAQ,MAAM,OAAO,CAAC;CAEjI;CApLS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAkB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAlB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAkB,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,eAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,QAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,SAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,MAAA;IAAA,YAAA,EAAA,QAAA,SAAA;IAAA,WAAA;KAAA,cAAA;KAAA,aAAA;KAAA,cAAA;KAAA,eAAA;KAAA,aAAA;IAAA;IAAA,YAAA;KAAA,mBAAA;KAAA,SAAA;KAAA,SAAA;IAAA;IAAA,gBAAA;GAAA;GAAA,UAAA;GAAA,UCtD/B;GAiBA,QAAA,CAAA,myBAAA;GAAA,cAAA,CAAA;IAAA,MAAA;IAAA,MDyBc;IAAgB,UAAA;IAAA,QAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;KAAA;IAAA;IAAA,SAAA;KAAA;KAAA;KAAA;IAAA;GAAA,CAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAYjB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAkB,YAAA,CAAA;EAlB9B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAY,iBAGL,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B,CAAC,gBAAgB;GAAC,MACrB;IACF,OAAO;IACP,MAAM;IACN,qBAAqB;IACrB,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;GAClB;GAAA,UAAA;GAAA,QAAA,CAAA,myBAAA;EAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDA,MAAA;GAAY,MAAA,CAAA,OAAO;;;GAQnB,MAAA;GAAY,MAAA,CAAA,OAAO"}
@@ -1,6 +1,7 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { ChangeDetectionStrategy, Component, Directive, ElementRef, ViewEncapsulation, booleanAttribute, effect, inject, input, numberAttribute, signal } from "@angular/core";
3
3
  import { FocusMonitor } from "@angular/cdk/a11y";
4
+ import { hasModifierKey } from "@angular/cdk/keycodes";
4
5
  import { Overlay, OverlayConfig, ScrollStrategyOptions } from "@angular/cdk/overlay";
5
6
  import { ComponentPortal } from "@angular/cdk/portal";
6
7
  import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
@@ -188,6 +189,15 @@ var RtTooltipDirective = class RtTooltipDirective {
188
189
  onClick() {
189
190
  if (this.hideOnClick() || this.#tooltipRef === null) this.hide();
190
191
  }
192
+ onKeydown(event) {
193
+ if (event.key !== "Escape" || hasModifierKey(event)) return;
194
+ const wasOpen = this.#tooltipRef !== null;
195
+ this.hide();
196
+ if (wasOpen) {
197
+ event.preventDefault();
198
+ event.stopPropagation();
199
+ }
200
+ }
191
201
  #syncText(text) {
192
202
  if (this.#tooltipRef === null) return;
193
203
  if (text.trim() === "") {
@@ -290,7 +300,8 @@ var RtTooltipDirective = class RtTooltipDirective {
290
300
  "mouseenter": "show()",
291
301
  "mouseleave": "hide()",
292
302
  "focusout": "hide()",
293
- "click": "onClick()"
303
+ "click": "onClick()",
304
+ "keydown": "onKeydown($event)"
294
305
  } },
295
306
  exportAs: ["rtTooltip"],
296
307
  ngImport: i0
@@ -311,7 +322,8 @@ i0.ɵɵngDeclareClassMetadata({
311
322
  "(mouseenter)": "show()",
312
323
  "(mouseleave)": "hide()",
313
324
  "(focusout)": "hide()",
314
- "(click)": "onClick()"
325
+ "(click)": "onClick()",
326
+ "(keydown)": "onKeydown($event)"
315
327
  }
316
328
  }]
317
329
  }],