@rt-tools/ui-kit-v2 0.30.0 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +1 -0
  2. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +35 -12
  4. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-service-block.mjs +131 -0
  6. package/fesm2022/rt-tools-ui-kit-v2-service-block.mjs.map +1 -0
  7. package/fesm2022/rt-tools-ui-kit-v2-service-logo.mjs +5 -2
  8. package/fesm2022/rt-tools-ui-kit-v2-service-logo.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +12 -4
  10. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2.mjs +1 -0
  12. package/package.json +5 -1
  13. package/src/lib/components/service-block/CONTEXT.md +37 -0
  14. package/src/lib/components/service-block/rt-service-block.component.scss +61 -0
  15. package/src/lib/components/service-logo/CONTEXT.md +2 -2
  16. package/src/lib/components/service-logo/rt-service-logo.component.scss +8 -1
  17. package/src/lib/components/thread-list/CONTEXT.md +7 -1
  18. package/src/lib/components/thread-list/rt-thread-list.component.scss +15 -0
  19. package/src/rich-editor/lib/components/chat/CONTEXT.md +6 -2
  20. package/src/rich-editor/lib/components/chat/rt-chat.component.scss +5 -0
  21. package/src/styles/_primitives.scss +1 -0
  22. package/styles/tokens.css +1 -0
  23. package/types/rt-tools-ui-kit-v2-core.d.ts +1 -1
  24. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +11 -1
  25. package/types/rt-tools-ui-kit-v2-service-block.d.ts +34 -0
  26. package/types/rt-tools-ui-kit-v2-service-logo.d.ts +2 -2
  27. package/types/rt-tools-ui-kit-v2-thread-list.d.ts +4 -0
  28. package/types/rt-tools-ui-kit-v2.d.ts +1 -0
@@ -0,0 +1,131 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from "@angular/core";
3
+ import { BlockDirective, ElemDirective } from "@rt-tools/core";
4
+ import { RtServiceLogoComponent } from "@rt-tools/ui-kit-v2/service-logo";
5
+ const BEM_BLOCK = "rt-service-block";
6
+ var RtServiceBlockComponent = class RtServiceBlockComponent {
7
+ constructor() {
8
+ this.logos = input.required(...ngDevMode ? [{ debugName: "logos" }] : /* istanbul ignore next */ []);
9
+ this.name = input.required(...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
10
+ this.description = input("", ...ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []);
11
+ }
12
+ static {
13
+ this.ɵfac = i0.ɵɵngDeclareFactory({
14
+ minVersion: "12.0.0",
15
+ version: "22.2.2",
16
+ ngImport: i0,
17
+ type: RtServiceBlockComponent,
18
+ deps: [],
19
+ target: i0.ɵɵFactoryTarget.Component
20
+ });
21
+ }
22
+ static {
23
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
24
+ minVersion: "17.0.0",
25
+ version: "22.2.2",
26
+ type: RtServiceBlockComponent,
27
+ isStandalone: true,
28
+ selector: "rt-service-block",
29
+ inputs: {
30
+ logos: {
31
+ classPropertyName: "logos",
32
+ publicName: "logos",
33
+ isSignal: true,
34
+ isRequired: true,
35
+ transformFunction: null
36
+ },
37
+ name: {
38
+ classPropertyName: "name",
39
+ publicName: "name",
40
+ isSignal: true,
41
+ isRequired: true,
42
+ transformFunction: null
43
+ },
44
+ description: {
45
+ classPropertyName: "description",
46
+ publicName: "description",
47
+ isSignal: true,
48
+ isRequired: false,
49
+ transformFunction: null
50
+ }
51
+ },
52
+ host: { classAttribute: "rt-service-block" },
53
+ ngImport: i0,
54
+ template: "<ng-container rtBlock=\"rt-service-block\">\n <rt-service-logo rtElem=\"logo\" qa-dataid=\"service-block-logo\" [logos]=\"logos()\" />\n\n <div rtElem=\"text\">\n <p rtElem=\"name\" qa-dataid=\"service-block-name\">{{ name() }}</p>\n\n @if (description(); as text) {\n <p rtElem=\"description\" qa-dataid=\"service-block-description\">{{ text }}</p>\n }\n </div>\n</ng-container>\n",
55
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-service-block{--rt-service-block-gap: var(--rt-space-4);--rt-service-block-text-gap: var(--rt-space-0-5);--rt-service-block-padding-bottom: var(--rt-space-5);--rt-service-block-divider: var(--rt-border-width-thin) solid var(--rt-color-border-subtle);--rt-service-block-name-size: var(--rt-text-xl);--rt-service-block-name-weight: var(--rt-font-weight-semibold);--rt-service-block-name-line-height: var(--rt-leading-snug);--rt-service-block-name-color: var(--rt-color-text-primary);--rt-service-block-description-size: var(--rt-text-sm);--rt-service-block-description-weight: var(--rt-font-weight-regular);--rt-service-block-description-line-height: var(--rt-leading-normal);--rt-service-block-description-color: var(--rt-color-text-muted);display:flex;width:100%;align-items:center;padding-bottom:var(--rt-service-block-padding-bottom);border-bottom:var(--rt-service-block-divider);gap:var(--rt-service-block-gap)}.rt-service-block__logo{flex:none}.rt-service-block__text{display:flex;min-width:0;flex:1 1 0;flex-direction:column;gap:var(--rt-service-block-text-gap);overflow-wrap:anywhere}.rt-service-block__name{margin:0;color:var(--rt-service-block-name-color);font-size:var(--rt-service-block-name-size);font-weight:var(--rt-service-block-name-weight);line-height:var(--rt-service-block-name-line-height)}.rt-service-block__description{margin:0;color:var(--rt-service-block-description-color);font-size:var(--rt-service-block-description-size);font-weight:var(--rt-service-block-description-weight);line-height:var(--rt-service-block-description-line-height)}}\n"],
56
+ dependencies: [
57
+ {
58
+ kind: "directive",
59
+ type: BlockDirective,
60
+ selector: "[rtBlock]",
61
+ inputs: ["rtMod"]
62
+ },
63
+ {
64
+ kind: "directive",
65
+ type: ElemDirective,
66
+ selector: "[rtElem]",
67
+ inputs: ["rtMod"]
68
+ },
69
+ {
70
+ kind: "component",
71
+ type: RtServiceLogoComponent,
72
+ selector: "rt-service-logo",
73
+ inputs: ["logos", "size"]
74
+ }
75
+ ],
76
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
77
+ encapsulation: i0.ViewEncapsulation.None
78
+ });
79
+ }
80
+ };
81
+ i0.ɵɵngDeclareClassMetadata({
82
+ minVersion: "12.0.0",
83
+ version: "22.2.2",
84
+ ngImport: i0,
85
+ type: RtServiceBlockComponent,
86
+ decorators: [{
87
+ type: Component,
88
+ args: [{
89
+ selector: "rt-service-block",
90
+ changeDetection: ChangeDetectionStrategy.OnPush,
91
+ encapsulation: ViewEncapsulation.None,
92
+ imports: [
93
+ BlockDirective,
94
+ ElemDirective,
95
+ RtServiceLogoComponent
96
+ ],
97
+ host: { class: BEM_BLOCK },
98
+ template: "<ng-container rtBlock=\"rt-service-block\">\n <rt-service-logo rtElem=\"logo\" qa-dataid=\"service-block-logo\" [logos]=\"logos()\" />\n\n <div rtElem=\"text\">\n <p rtElem=\"name\" qa-dataid=\"service-block-name\">{{ name() }}</p>\n\n @if (description(); as text) {\n <p rtElem=\"description\" qa-dataid=\"service-block-description\">{{ text }}</p>\n }\n </div>\n</ng-container>\n",
99
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-service-block{--rt-service-block-gap: var(--rt-space-4);--rt-service-block-text-gap: var(--rt-space-0-5);--rt-service-block-padding-bottom: var(--rt-space-5);--rt-service-block-divider: var(--rt-border-width-thin) solid var(--rt-color-border-subtle);--rt-service-block-name-size: var(--rt-text-xl);--rt-service-block-name-weight: var(--rt-font-weight-semibold);--rt-service-block-name-line-height: var(--rt-leading-snug);--rt-service-block-name-color: var(--rt-color-text-primary);--rt-service-block-description-size: var(--rt-text-sm);--rt-service-block-description-weight: var(--rt-font-weight-regular);--rt-service-block-description-line-height: var(--rt-leading-normal);--rt-service-block-description-color: var(--rt-color-text-muted);display:flex;width:100%;align-items:center;padding-bottom:var(--rt-service-block-padding-bottom);border-bottom:var(--rt-service-block-divider);gap:var(--rt-service-block-gap)}.rt-service-block__logo{flex:none}.rt-service-block__text{display:flex;min-width:0;flex:1 1 0;flex-direction:column;gap:var(--rt-service-block-text-gap);overflow-wrap:anywhere}.rt-service-block__name{margin:0;color:var(--rt-service-block-name-color);font-size:var(--rt-service-block-name-size);font-weight:var(--rt-service-block-name-weight);line-height:var(--rt-service-block-name-line-height)}.rt-service-block__description{margin:0;color:var(--rt-service-block-description-color);font-size:var(--rt-service-block-description-size);font-weight:var(--rt-service-block-description-weight);line-height:var(--rt-service-block-description-line-height)}}\n"]
100
+ }]
101
+ }],
102
+ propDecorators: {
103
+ logos: [{
104
+ type: i0.Input,
105
+ args: [{
106
+ isSignal: true,
107
+ alias: "logos",
108
+ required: true
109
+ }]
110
+ }],
111
+ name: [{
112
+ type: i0.Input,
113
+ args: [{
114
+ isSignal: true,
115
+ alias: "name",
116
+ required: true
117
+ }]
118
+ }],
119
+ description: [{
120
+ type: i0.Input,
121
+ args: [{
122
+ isSignal: true,
123
+ alias: "description",
124
+ required: false
125
+ }]
126
+ }]
127
+ }
128
+ });
129
+ export { RtServiceBlockComponent };
130
+
131
+ //# sourceMappingURL=rt-tools-ui-kit-v2-service-block.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-service-block.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/service-block/rt-service-block.component.ts","../../../projects/ui-kit-v2/src/lib/components/service-block/rt-service-block.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input, InputSignal, ViewEncapsulation } from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { IRtServiceLogo, RtServiceLogoComponent } from '@rt-tools/ui-kit-v2/service-logo';\n\nconst BEM_BLOCK: string = 'rt-service-block';\n\n/**\n * Блок службы — первый блок тела панели настройки подключения: знак службы размера `md`, справа\n * имя службы и строка-описание, под блоком черта. Одна разметка на интеграции, способы оплаты и\n * мессенджеры. Своих текстов блок не несёт: имя, описание и подписи знаков даёт приложение.\n */\n@Component({\n selector: 'rt-service-block',\n templateUrl: './rt-service-block.component.html',\n styleUrl: './rt-service-block.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n RtServiceLogoComponent,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtServiceBlockComponent {\n /** Знаки службы — те же, что принимает `rt-service-logo`; несколько ложатся внахлёст. */\n public readonly logos: InputSignal<readonly IRtServiceLogo.Item[]> = input.required<readonly IRtServiceLogo.Item[]>();\n\n /** Имя службы — жирная строка справа от знака. */\n public readonly name: InputSignal<string> = input.required<string>();\n\n /** Строка-описание под именем. Пустая строка не рисуется. */\n public readonly description: InputSignal<string> = input<string>('');\n}\n","<ng-container rtBlock=\"rt-service-block\">\n <rt-service-logo rtElem=\"logo\" qa-dataid=\"service-block-logo\" [logos]=\"logos()\" />\n\n <div rtElem=\"text\">\n <p rtElem=\"name\" qa-dataid=\"service-block-name\">{{ name() }}</p>\n\n @if (description(); as text) {\n <p rtElem=\"description\" qa-dataid=\"service-block-description\">{{ text }}</p>\n }\n </div>\n</ng-container>\n"],"mappings":";;;;AAMA,MAAM,YAAoB;AAuB1B,IAAa,0BAAb,MAAa,wBAAuB;CAhBpC,cAAA;EAkBoB,KAAA,QAAqD,MAAM,SAA0C,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAGrG,KAAA,OAA4B,MAAM,SAAkB,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAGpD,KAAA,cAAmC,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;CACvE;CATY;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAuB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAvB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAuB,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,aAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,MAAA,EAAA,gBAAA,mBAAA;GAAA,UAAA;GAAA,UC7BpC;GAWA,QAAA,CAAA,glDAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MDUQ;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACb;KAAsB,UAAA;KAAA,QAAA,CAAA,SAAA,MAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAMjB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAuB,YAAA,CAAA;EAhBnC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAkB,iBAGX,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IAEL;IACA;IACA;GACH;GAAA,MACK,EACF,OAAO,UACV;GAAA,UAAA;GAAA,QAAA,CAAA,glDAAA;EAAA,CAAA"}
@@ -4,6 +4,7 @@ import { BlockDirective, ElemDirective } from "@rt-tools/core";
4
4
  import { RtIconComponent } from "@rt-tools/ui-kit-v2/icon";
5
5
  const BEM_BLOCK = "rt-service-logo";
6
6
  const ICON_SIZES = Object.freeze({
7
+ xs: "sm",
7
8
  sm: "md",
8
9
  md: "xl",
9
10
  lg: "3xl"
@@ -62,6 +63,7 @@ var RtServiceLogoComponent = class RtServiceLogoComponent {
62
63
  host: {
63
64
  attributes: { "role": "list" },
64
65
  properties: {
66
+ "class.rt-service-logo--size-xs": "size() === 'xs'",
65
67
  "class.rt-service-logo--size-sm": "size() === 'sm'",
66
68
  "class.rt-service-logo--size-lg": "size() === 'lg'"
67
69
  },
@@ -69,7 +71,7 @@ var RtServiceLogoComponent = class RtServiceLogoComponent {
69
71
  },
70
72
  ngImport: i0,
71
73
  template: "<ng-container rtBlock=\"rt-service-logo\">\n @for (mark of marks(); track $index) {\n <span rtElem=\"plate\" role=\"listitem\" qa-dataid=\"service-logo-plate\" [attr.data-label]=\"mark.label\">\n @if (mark.src !== null) {\n <img rtElem=\"image\" qa-dataid=\"service-logo-image\" [src]=\"mark.src\" [alt]=\"mark.label\" />\n } @else {\n <span rtElem=\"icon\" role=\"img\" qa-dataid=\"service-logo-icon\" [attr.aria-label]=\"mark.label\">\n <rt-icon [name]=\"mark.icon\" [size]=\"iconSize()\" />\n </span>\n }\n </span>\n }\n</ng-container>\n",
72
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-service-logo{--rt-service-logo-size: var(--rt-size-16);--rt-service-logo-mark-height: var(--rt-size-8);--rt-service-logo-step: var(--rt-size-10);--rt-service-logo-shadow: var(--rt-shadow-service-logo-md);--rt-service-logo-radius: var(--rt-radius-full);--rt-service-logo-bg: var(--rt-color-service-logo-bg);--rt-service-logo-color: var(--rt-color-service-logo-mark);display:inline-flex;align-items:center;vertical-align:middle}.rt-service-logo--size-sm{--rt-service-logo-size: var(--rt-size-10);--rt-service-logo-mark-height: var(--rt-size-5);--rt-service-logo-step: var(--rt-size-6);--rt-service-logo-shadow: var(--rt-shadow-service-logo-sm)}.rt-service-logo--size-lg{--rt-service-logo-size: var(--rt-size-24);--rt-service-logo-mark-height: var(--rt-size-12);--rt-service-logo-step: calc(var(--rt-size-12) + var(--rt-size-3));--rt-service-logo-shadow: var(--rt-shadow-service-logo-lg)}.rt-service-logo__plate{position:relative;display:inline-flex;width:var(--rt-service-logo-size);height:var(--rt-service-logo-size);flex:none;align-items:center;justify-content:center;border-radius:var(--rt-service-logo-radius);background:var(--rt-service-logo-bg);box-shadow:var(--rt-service-logo-shadow);color:var(--rt-service-logo-color)}.rt-service-logo__plate+.rt-service-logo__plate{margin-inline-start:calc(var(--rt-service-logo-step) - var(--rt-service-logo-size))}.rt-service-logo__image{display:block;width:calc(var(--rt-service-logo-mark-height) * 1.375);height:var(--rt-service-logo-mark-height);object-fit:contain}.rt-service-logo__icon{display:inline-flex}}\n"],
74
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-service-logo{--rt-service-logo-size: var(--rt-size-16);--rt-service-logo-mark-height: var(--rt-size-8);--rt-service-logo-step: var(--rt-size-10);--rt-service-logo-shadow: var(--rt-shadow-service-logo-md);--rt-service-logo-radius: var(--rt-radius-full);--rt-service-logo-bg: var(--rt-color-service-logo-bg);--rt-service-logo-color: var(--rt-color-service-logo-mark);display:inline-flex;align-items:center;vertical-align:middle}.rt-service-logo--size-xs{--rt-service-logo-size: var(--rt-size-8);--rt-service-logo-mark-height: var(--rt-size-4);--rt-service-logo-step: var(--rt-size-5);--rt-service-logo-shadow: var(--rt-shadow-service-logo-xs)}.rt-service-logo--size-sm{--rt-service-logo-size: var(--rt-size-10);--rt-service-logo-mark-height: var(--rt-size-5);--rt-service-logo-step: var(--rt-size-6);--rt-service-logo-shadow: var(--rt-shadow-service-logo-sm)}.rt-service-logo--size-lg{--rt-service-logo-size: var(--rt-size-24);--rt-service-logo-mark-height: var(--rt-size-12);--rt-service-logo-step: calc(var(--rt-size-12) + var(--rt-size-3));--rt-service-logo-shadow: var(--rt-shadow-service-logo-lg)}.rt-service-logo__plate{position:relative;display:inline-flex;width:var(--rt-service-logo-size);height:var(--rt-service-logo-size);flex:none;align-items:center;justify-content:center;border-radius:var(--rt-service-logo-radius);background:var(--rt-service-logo-bg);box-shadow:var(--rt-service-logo-shadow);color:var(--rt-service-logo-color)}.rt-service-logo__plate+.rt-service-logo__plate{margin-inline-start:calc(var(--rt-service-logo-step) - var(--rt-service-logo-size))}.rt-service-logo__image{display:block;width:calc(var(--rt-service-logo-mark-height) * 1.375);height:var(--rt-service-logo-mark-height);object-fit:contain}.rt-service-logo__icon{display:inline-flex}}\n"],
73
75
  dependencies: [
74
76
  {
75
77
  kind: "directive",
@@ -123,11 +125,12 @@ i0.ɵɵngDeclareClassMetadata({
123
125
  host: {
124
126
  class: BEM_BLOCK,
125
127
  role: "list",
128
+ "[class.rt-service-logo--size-xs]": "size() === 'xs'",
126
129
  "[class.rt-service-logo--size-sm]": "size() === 'sm'",
127
130
  "[class.rt-service-logo--size-lg]": "size() === 'lg'"
128
131
  },
129
132
  template: "<ng-container rtBlock=\"rt-service-logo\">\n @for (mark of marks(); track $index) {\n <span rtElem=\"plate\" role=\"listitem\" qa-dataid=\"service-logo-plate\" [attr.data-label]=\"mark.label\">\n @if (mark.src !== null) {\n <img rtElem=\"image\" qa-dataid=\"service-logo-image\" [src]=\"mark.src\" [alt]=\"mark.label\" />\n } @else {\n <span rtElem=\"icon\" role=\"img\" qa-dataid=\"service-logo-icon\" [attr.aria-label]=\"mark.label\">\n <rt-icon [name]=\"mark.icon\" [size]=\"iconSize()\" />\n </span>\n }\n </span>\n }\n</ng-container>\n",
130
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-service-logo{--rt-service-logo-size: var(--rt-size-16);--rt-service-logo-mark-height: var(--rt-size-8);--rt-service-logo-step: var(--rt-size-10);--rt-service-logo-shadow: var(--rt-shadow-service-logo-md);--rt-service-logo-radius: var(--rt-radius-full);--rt-service-logo-bg: var(--rt-color-service-logo-bg);--rt-service-logo-color: var(--rt-color-service-logo-mark);display:inline-flex;align-items:center;vertical-align:middle}.rt-service-logo--size-sm{--rt-service-logo-size: var(--rt-size-10);--rt-service-logo-mark-height: var(--rt-size-5);--rt-service-logo-step: var(--rt-size-6);--rt-service-logo-shadow: var(--rt-shadow-service-logo-sm)}.rt-service-logo--size-lg{--rt-service-logo-size: var(--rt-size-24);--rt-service-logo-mark-height: var(--rt-size-12);--rt-service-logo-step: calc(var(--rt-size-12) + var(--rt-size-3));--rt-service-logo-shadow: var(--rt-shadow-service-logo-lg)}.rt-service-logo__plate{position:relative;display:inline-flex;width:var(--rt-service-logo-size);height:var(--rt-service-logo-size);flex:none;align-items:center;justify-content:center;border-radius:var(--rt-service-logo-radius);background:var(--rt-service-logo-bg);box-shadow:var(--rt-service-logo-shadow);color:var(--rt-service-logo-color)}.rt-service-logo__plate+.rt-service-logo__plate{margin-inline-start:calc(var(--rt-service-logo-step) - var(--rt-service-logo-size))}.rt-service-logo__image{display:block;width:calc(var(--rt-service-logo-mark-height) * 1.375);height:var(--rt-service-logo-mark-height);object-fit:contain}.rt-service-logo__icon{display:inline-flex}}\n"]
133
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-service-logo{--rt-service-logo-size: var(--rt-size-16);--rt-service-logo-mark-height: var(--rt-size-8);--rt-service-logo-step: var(--rt-size-10);--rt-service-logo-shadow: var(--rt-shadow-service-logo-md);--rt-service-logo-radius: var(--rt-radius-full);--rt-service-logo-bg: var(--rt-color-service-logo-bg);--rt-service-logo-color: var(--rt-color-service-logo-mark);display:inline-flex;align-items:center;vertical-align:middle}.rt-service-logo--size-xs{--rt-service-logo-size: var(--rt-size-8);--rt-service-logo-mark-height: var(--rt-size-4);--rt-service-logo-step: var(--rt-size-5);--rt-service-logo-shadow: var(--rt-shadow-service-logo-xs)}.rt-service-logo--size-sm{--rt-service-logo-size: var(--rt-size-10);--rt-service-logo-mark-height: var(--rt-size-5);--rt-service-logo-step: var(--rt-size-6);--rt-service-logo-shadow: var(--rt-shadow-service-logo-sm)}.rt-service-logo--size-lg{--rt-service-logo-size: var(--rt-size-24);--rt-service-logo-mark-height: var(--rt-size-12);--rt-service-logo-step: calc(var(--rt-size-12) + var(--rt-size-3));--rt-service-logo-shadow: var(--rt-shadow-service-logo-lg)}.rt-service-logo__plate{position:relative;display:inline-flex;width:var(--rt-service-logo-size);height:var(--rt-service-logo-size);flex:none;align-items:center;justify-content:center;border-radius:var(--rt-service-logo-radius);background:var(--rt-service-logo-bg);box-shadow:var(--rt-service-logo-shadow);color:var(--rt-service-logo-color)}.rt-service-logo__plate+.rt-service-logo__plate{margin-inline-start:calc(var(--rt-service-logo-step) - var(--rt-service-logo-size))}.rt-service-logo__image{display:block;width:calc(var(--rt-service-logo-mark-height) * 1.375);height:var(--rt-service-logo-mark-height);object-fit:contain}.rt-service-logo__icon{display:inline-flex}}\n"]
131
134
  }]
132
135
  }],
133
136
  propDecorators: {
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-service-logo.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/service-logo/rt-service-logo.component.ts","../../../projects/ui-kit-v2/src/lib/components/service-logo/rt-service-logo.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input, InputSignal, Signal, ViewEncapsulation } from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\n\nimport { IRtServiceLogo } from './rt-service-logo.model';\n\nconst BEM_BLOCK: string = 'rt-service-logo';\n\n/** Высота знака — ступенью значка кита: 20 / 32 / 48, те же числа, что у знака-картинки. */\nconst ICON_SIZES: Readonly<Record<IRtServiceLogo.Size, IRtIcon.Size>> = Object.freeze({\n sm: 'md',\n md: 'xl',\n lg: '3xl',\n});\n\n/** Знак, готовый к отрисовке: картинка или значок, у каждого своё имя для диктора. */\ninterface IRtServiceLogoMark {\n readonly label: string;\n readonly src: string | null;\n readonly icon: IRtIcon.Name | null;\n}\n\nfunction toMark(item: IRtServiceLogo.Item): IRtServiceLogoMark {\n return 'src' in item ? { label: item.label, src: item.src, icon: null } : { label: item.label, src: null, icon: item.icon };\n}\n\n/**\n * Знак внешней службы в светлом круге с мягкой тенью. Несколько знаков ложатся внахлёст шагом\n * атома, и каждый следующий лежит поверх предыдущего. Знаки чужих компаний приложение передаёт\n * адресом картинки; знак без компании — значок кита в том же круге.\n */\n@Component({\n selector: 'rt-service-logo',\n templateUrl: './rt-service-logo.component.html',\n styleUrl: './rt-service-logo.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n RtIconComponent,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'list',\n '[class.rt-service-logo--size-sm]': \"size() === 'sm'\",\n '[class.rt-service-logo--size-lg]': \"size() === 'lg'\",\n },\n})\nexport class RtServiceLogoComponent {\n protected readonly marks: Signal<readonly IRtServiceLogoMark[]> = computed((): readonly IRtServiceLogoMark[] =>\n this.logos().map(toMark)\n );\n\n protected readonly iconSize: Signal<IRtIcon.Size> = computed((): IRtIcon.Size => ICON_SIZES[this.size()]);\n\n /** Знаки ряда в порядке отрисовки: следующий ложится поверх предыдущего. */\n public readonly logos: InputSignal<readonly IRtServiceLogo.Item[]> = input.required<readonly IRtServiceLogo.Item[]>();\n\n /** Размер круга и знака. */\n public readonly size: InputSignal<IRtServiceLogo.Size> = input<IRtServiceLogo.Size>('md');\n}\n","<ng-container rtBlock=\"rt-service-logo\">\n @for (mark of marks(); track $index) {\n <span rtElem=\"plate\" role=\"listitem\" qa-dataid=\"service-logo-plate\" [attr.data-label]=\"mark.label\">\n @if (mark.src !== null) {\n <img rtElem=\"image\" qa-dataid=\"service-logo-image\" [src]=\"mark.src\" [alt]=\"mark.label\" />\n } @else {\n <span rtElem=\"icon\" role=\"img\" qa-dataid=\"service-logo-icon\" [attr.aria-label]=\"mark.label\">\n <rt-icon [name]=\"mark.icon\" [size]=\"iconSize()\" />\n </span>\n }\n </span>\n }\n</ng-container>\n"],"mappings":";;;;AASA,MAAM,YAAoB;AAG1B,MAAM,aAAkE,OAAO,OAAO;CAClF,IAAI;CACJ,IAAI;CACJ,IAAI;AACP,CAAA;AASD,SAAS,OAAO,MAAyB;CACrC,OAAO,SAAS,OAAO;EAAE,OAAO,KAAK;EAAO,KAAK,KAAK;EAAK,MAAM;CAAI,IAAK;EAAE,OAAO,KAAK;EAAO,KAAK;EAAM,MAAM,KAAK;CAAI;AAC7H;AA0BA,IAAa,yBAAb,MAAa,uBAAsB;CAnBnC,cAAA;EAoBuB,KAAA,QAA+C,eAC9D,KAAK,MAAK,CAAE,CAAC,IAAI,MAAM,GAC1B,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAEkB,KAAA,WAAiC,eAA6B,WAAW,KAAK,KAAI,IAAI,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAGzF,KAAA,QAAqD,MAAM,SAA0C,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAGrG,KAAA,OAAyC,MAA2B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAC5F;CAZY;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;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,MAAA;IAAA,YAAA,EAAA,QAAA,OAAA;IAAA,YAAA;KAAA,kCAAA;KAAA,kCAAA;IAAA;IAAA,gBAAA;GAAA;GAAA,UAAA;GAAA,UCrDnC;GAaA,QAAA,CAAA,ukDAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MD6BQ;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACb;KAAe,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AASV,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAsB,YAAA,CAAA;EAnBlC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAiB,iBAGV,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IAEL;IACA;IACA;GACH;GAAA,MACK;IACF,OAAO;IACP,MAAM;IACN,oCAAoC;IACpC,oCAAoC;GACvC;GAAA,UAAA;GAAA,QAAA,CAAA,ukDAAA;EAAA,CAAA"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-service-logo.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/service-logo/rt-service-logo.component.ts","../../../projects/ui-kit-v2/src/lib/components/service-logo/rt-service-logo.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, input, InputSignal, Signal, ViewEncapsulation } from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\n\nimport { IRtServiceLogo } from './rt-service-logo.model';\n\nconst BEM_BLOCK: string = 'rt-service-logo';\n\n/** Высота знака — ступенью значка кита: 16 / 20 / 32 / 48, те же числа, что у знака-картинки. */\nconst ICON_SIZES: Readonly<Record<IRtServiceLogo.Size, IRtIcon.Size>> = Object.freeze({\n xs: 'sm',\n sm: 'md',\n md: 'xl',\n lg: '3xl',\n});\n\n/** Знак, готовый к отрисовке: картинка или значок, у каждого своё имя для диктора. */\ninterface IRtServiceLogoMark {\n readonly label: string;\n readonly src: string | null;\n readonly icon: IRtIcon.Name | null;\n}\n\nfunction toMark(item: IRtServiceLogo.Item): IRtServiceLogoMark {\n return 'src' in item ? { label: item.label, src: item.src, icon: null } : { label: item.label, src: null, icon: item.icon };\n}\n\n/**\n * Знак внешней службы в светлом круге с мягкой тенью. Несколько знаков ложатся внахлёст шагом\n * атома, и каждый следующий лежит поверх предыдущего. Знаки чужих компаний приложение передаёт\n * адресом картинки; знак без компании — значок кита в том же круге.\n */\n@Component({\n selector: 'rt-service-logo',\n templateUrl: './rt-service-logo.component.html',\n styleUrl: './rt-service-logo.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n RtIconComponent,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'list',\n '[class.rt-service-logo--size-xs]': \"size() === 'xs'\",\n '[class.rt-service-logo--size-sm]': \"size() === 'sm'\",\n '[class.rt-service-logo--size-lg]': \"size() === 'lg'\",\n },\n})\nexport class RtServiceLogoComponent {\n protected readonly marks: Signal<readonly IRtServiceLogoMark[]> = computed((): readonly IRtServiceLogoMark[] =>\n this.logos().map(toMark)\n );\n\n protected readonly iconSize: Signal<IRtIcon.Size> = computed((): IRtIcon.Size => ICON_SIZES[this.size()]);\n\n /** Знаки ряда в порядке отрисовки: следующий ложится поверх предыдущего. */\n public readonly logos: InputSignal<readonly IRtServiceLogo.Item[]> = input.required<readonly IRtServiceLogo.Item[]>();\n\n /** Размер круга и знака. */\n public readonly size: InputSignal<IRtServiceLogo.Size> = input<IRtServiceLogo.Size>('md');\n}\n","<ng-container rtBlock=\"rt-service-logo\">\n @for (mark of marks(); track $index) {\n <span rtElem=\"plate\" role=\"listitem\" qa-dataid=\"service-logo-plate\" [attr.data-label]=\"mark.label\">\n @if (mark.src !== null) {\n <img rtElem=\"image\" qa-dataid=\"service-logo-image\" [src]=\"mark.src\" [alt]=\"mark.label\" />\n } @else {\n <span rtElem=\"icon\" role=\"img\" qa-dataid=\"service-logo-icon\" [attr.aria-label]=\"mark.label\">\n <rt-icon [name]=\"mark.icon\" [size]=\"iconSize()\" />\n </span>\n }\n </span>\n }\n</ng-container>\n"],"mappings":";;;;AASA,MAAM,YAAoB;AAG1B,MAAM,aAAkE,OAAO,OAAO;CAClF,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACP,CAAA;AASD,SAAS,OAAO,MAAyB;CACrC,OAAO,SAAS,OAAO;EAAE,OAAO,KAAK;EAAO,KAAK,KAAK;EAAK,MAAM;CAAI,IAAK;EAAE,OAAO,KAAK;EAAO,KAAK;EAAM,MAAM,KAAK;CAAI;AAC7H;AA2BA,IAAa,yBAAb,MAAa,uBAAsB;CApBnC,cAAA;EAqBuB,KAAA,QAA+C,eAC9D,KAAK,MAAK,CAAE,CAAC,IAAI,MAAM,GAC1B,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAEkB,KAAA,WAAiC,eAA6B,WAAW,KAAK,KAAI,IAAI,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAGzF,KAAA,QAAqD,MAAM,SAA0C,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAGrG,KAAA,OAAyC,MAA2B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;CAC5F;CAZY;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;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,MAAA;IAAA,YAAA,EAAA,QAAA,OAAA;IAAA,YAAA;KAAA,kCAAA;KAAA,kCAAA;KAAA,kCAAA;IAAA;IAAA,gBAAA;GAAA;GAAA,UAAA;GAAA,UCvDnC;GAaA,QAAA,CAAA,8xDAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MD8BQ;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACb;KAAe,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAUV,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAsB,YAAA,CAAA;EApBlC,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAiB,iBAGV,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IAEL;IACA;IACA;GACH;GAAA,MACK;IACF,OAAO;IACP,MAAM;IACN,oCAAoC;IACpC,oCAAoC;IACpC,oCAAoC;GACvC;GAAA,UAAA;GAAA,QAAA,CAAA,8xDAAA;EAAA,CAAA"}
@@ -14,6 +14,7 @@ import { RtInputComponent } from "@rt-tools/ui-kit-v2/input";
14
14
  import { RtPopoverDirective } from "@rt-tools/ui-kit-v2/popover";
15
15
  import * as i1 from "@rt-tools/ui-kit-v2/radius";
16
16
  import { RtRadiusDirective } from "@rt-tools/ui-kit-v2/radius";
17
+ import { RtServiceLogoComponent } from "@rt-tools/ui-kit-v2/service-logo";
17
18
  import { RtSkeletonComponent } from "@rt-tools/ui-kit-v2/skeleton";
18
19
  var RtThreadListRowDirective = class RtThreadListRowDirective {
19
20
  constructor() {
@@ -391,8 +392,8 @@ var RtThreadListComponent = class RtThreadListComponent {
391
392
  inputs: ["radius", "radius"]
392
393
  }],
393
394
  ngImport: i0,
394
- template: "<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 <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </button>\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",
395
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-thread-list{--rt-thread-list-border-width: var(--rt-border-width-thin);--rt-thread-list-card-radius: var(--rt-radius-lg);--rt-thread-list-tag-radius: var(--rt-radius-sm);--rt-thread-list-dot-radius: var(--rt-radius-full);--rt-thread-list-avatar-radius: var(--rt-radius-full);--rt-thread-list-line-radius: var(--rt-radius-full);display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0}.rt-thread-list__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-thread-list-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-2);padding-inline:var(--rt-space-4)}.rt-thread-list__search{flex:1 1 auto;min-inline-size:0}.rt-thread-list__filter-trigger{flex:0 0 auto}.rt-thread-list__filters-panel{display:flex;flex-direction:column;padding:var(--rt-space-4);gap:var(--rt-space-2);min-inline-size:220px}.rt-thread-list__rows{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;overflow-y:auto}.rt-thread-list__row{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-2) var(--rt-space-4);border:none;background:none;border-inline-start:3px solid transparent;cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);gap:var(--rt-space-4);inline-size:100%;text-align:start}.rt-thread-list__row:hover{background:var(--rt-color-bg-subtle)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread{position:relative;background:var(--rt-color-bg-subtle);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread .rt-thread-list__row-title{font-weight:var(--rt-font-weight-semibold)}.rt-thread-list__row--unread:before{position:absolute;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-action-primary);block-size:var(--rt-space-2);content:\"\";inline-size:var(--rt-space-2);inset-block-start:50%;inset-inline-start:var(--rt-space-2);transform:translateY(-50%)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg)}.rt-thread-list__row--overdue .rt-thread-list__row-time{color:var(--rt-color-state-error-text)}.rt-thread-list__row-wrap{position:relative}.rt-thread-list__row-wrap:hover .rt-thread-list__row-actions,.rt-thread-list__row-wrap:focus-within .rt-thread-list__row-actions,.rt-thread-list__row-wrap:has(.rt-menu--open) .rt-thread-list__row-actions{opacity:1;pointer-events:auto}.rt-thread-list__row-actions{position:absolute;display:flex;align-items:center;background:var(--rt-color-bg-subtle);gap:var(--rt-space-1);inset-block:0;inset-inline-end:0;opacity:0;padding-inline:var(--rt-space-2) var(--rt-space-4);pointer-events:none}.rt-thread-list__row--active+.rt-thread-list__row-actions{background:var(--rt-color-state-info-bg)}.rt-thread-list__row-body{display:flex;flex-direction:column;gap:var(--rt-space-0-5);min-inline-size:0}.rt-thread-list__row-title{overflow:hidden;color:var(--rt-color-text-primary);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-id{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-thread-list__row:hover .rt-copy-cell__button,.rt-thread-list__row:focus-within .rt-copy-cell__button{opacity:1}.rt-thread-list__row-subtitle{overflow:hidden;color:var(--rt-color-text-muted);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-meta{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-2)}.rt-thread-list__row-time{color:var(--rt-color-text-muted);white-space:nowrap}.rt-thread-list__row-tag{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-thread-list-tag-radius);background:var(--rt-color-state-warning-bg);color:var(--rt-color-state-warning-text);font-size:var(--rt-text-xs);white-space:nowrap}.rt-thread-list__row-dot{display:inline-block;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-text-link);block-size:6px;inline-size:6px}.rt-thread-list__row-skeleton{display:flex;flex-direction:column;padding:var(--rt-space-2) var(--rt-space-4);gap:var(--rt-space-2)}.rt-thread-list__row-loader{display:flex;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4)}.rt-thread-list__load-anchor{block-size:1px}.rt-thread-list__empty{padding:var(--rt-space-6) var(--rt-space-4)}.rt-thread-list__empty-preview{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-thread-list__empty-card{display:flex;align-items:center;padding:var(--rt-space-2);border:var(--rt-thread-list-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-thread-list-card-radius);background:var(--rt-color-bg-surface-subtle);gap:var(--rt-space-2)}.rt-thread-list__empty-card--offset{transform:translate(20px)}.rt-thread-list__empty-avatar{display:grid;flex:0 0 auto;border-radius:var(--rt-thread-list-avatar-radius);background:var(--rt-color-text-muted);block-size:24px;color:var(--rt-color-bg-surface);inline-size:24px;place-items:center}.rt-thread-list__empty-lines{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-thread-list__empty-line{border-radius:var(--rt-thread-list-line-radius);background:var(--rt-color-border-strong);block-size:6px;inline-size:112px}.rt-thread-list__empty-line--short{inline-size:48px}.rt-thread-list[data-rt-radius=none]{--rt-thread-list-card-radius: var(--rt-radius-none)}.rt-thread-list[data-rt-radius=xs]{--rt-thread-list-card-radius: var(--rt-radius-xs)}.rt-thread-list[data-rt-radius=sm]{--rt-thread-list-card-radius: var(--rt-radius-sm)}.rt-thread-list[data-rt-radius=ms]{--rt-thread-list-card-radius: var(--rt-radius-ms)}.rt-thread-list[data-rt-radius=md]{--rt-thread-list-card-radius: var(--rt-radius-md)}.rt-thread-list[data-rt-radius=lg]{--rt-thread-list-card-radius: var(--rt-radius-lg)}.rt-thread-list[data-rt-radius=xl]{--rt-thread-list-card-radius: var(--rt-radius-xl)}.rt-thread-list[data-rt-radius=\"2xl\"]{--rt-thread-list-card-radius: var(--rt-radius-2xl)}.rt-thread-list[data-rt-radius=full]{--rt-thread-list-card-radius: var(--rt-radius-full)}}\n"],
395
+ template: "<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",
396
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-thread-list{--rt-thread-list-border-width: var(--rt-border-width-thin);--rt-thread-list-card-radius: var(--rt-radius-lg);--rt-thread-list-tag-radius: var(--rt-radius-sm);--rt-thread-list-dot-radius: var(--rt-radius-full);--rt-thread-list-avatar-radius: var(--rt-radius-full);--rt-thread-list-line-radius: var(--rt-radius-full);display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0}.rt-thread-list__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-thread-list-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-2);padding-inline:var(--rt-space-4)}.rt-thread-list__search{flex:1 1 auto;min-inline-size:0}.rt-thread-list__filter-trigger{flex:0 0 auto}.rt-thread-list__filters-panel{display:flex;flex-direction:column;padding:var(--rt-space-4);gap:var(--rt-space-2);min-inline-size:220px}.rt-thread-list__rows{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;overflow-y:auto}.rt-thread-list__row{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-2) var(--rt-space-4);border:none;background:none;border-inline-start:3px solid transparent;cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);gap:var(--rt-space-4);inline-size:100%;text-align:start}.rt-thread-list__row:hover{background:var(--rt-color-bg-subtle)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread{position:relative;background:var(--rt-color-bg-subtle);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread .rt-thread-list__row-title{font-weight:var(--rt-font-weight-semibold)}.rt-thread-list__row--unread:before{position:absolute;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-action-primary);block-size:var(--rt-space-2);content:\"\";inline-size:var(--rt-space-2);inset-block-start:50%;inset-inline-start:var(--rt-space-2);transform:translateY(-50%)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg)}.rt-thread-list__row--overdue .rt-thread-list__row-time{color:var(--rt-color-state-error-text)}.rt-thread-list__row-wrap{position:relative}.rt-thread-list__row-wrap:hover .rt-thread-list__row-actions,.rt-thread-list__row-wrap:focus-within .rt-thread-list__row-actions,.rt-thread-list__row-wrap:has(.rt-menu--open) .rt-thread-list__row-actions{opacity:1;pointer-events:auto}.rt-thread-list__row-actions{position:absolute;display:flex;align-items:center;background:var(--rt-color-bg-subtle);gap:var(--rt-space-1);inset-block:0;inset-inline-end:0;opacity:0;padding-inline:var(--rt-space-2) var(--rt-space-4);pointer-events:none}.rt-thread-list__row--active+.rt-thread-list__row-actions{background:var(--rt-color-state-info-bg)}.rt-thread-list__row-sign{flex:none}.rt-thread-list__row-content{display:flex;flex:1 1 auto;align-items:center;justify-content:space-between;gap:var(--rt-space-4);min-inline-size:0}.rt-thread-list__row-body{display:flex;flex-direction:column;gap:var(--rt-space-0-5);min-inline-size:0}.rt-thread-list__row-title{overflow:hidden;color:var(--rt-color-text-primary);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-id{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-thread-list__row:hover .rt-copy-cell__button,.rt-thread-list__row:focus-within .rt-copy-cell__button{opacity:1}.rt-thread-list__row-subtitle{overflow:hidden;color:var(--rt-color-text-muted);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-meta{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-2)}.rt-thread-list__row-time{color:var(--rt-color-text-muted);white-space:nowrap}.rt-thread-list__row-tag{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-thread-list-tag-radius);background:var(--rt-color-state-warning-bg);color:var(--rt-color-state-warning-text);font-size:var(--rt-text-xs);white-space:nowrap}.rt-thread-list__row-dot{display:inline-block;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-text-link);block-size:6px;inline-size:6px}.rt-thread-list__row-skeleton{display:flex;flex-direction:column;padding:var(--rt-space-2) var(--rt-space-4);gap:var(--rt-space-2)}.rt-thread-list__row-loader{display:flex;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4)}.rt-thread-list__load-anchor{block-size:1px}.rt-thread-list__empty{padding:var(--rt-space-6) var(--rt-space-4)}.rt-thread-list__empty-preview{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-thread-list__empty-card{display:flex;align-items:center;padding:var(--rt-space-2);border:var(--rt-thread-list-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-thread-list-card-radius);background:var(--rt-color-bg-surface-subtle);gap:var(--rt-space-2)}.rt-thread-list__empty-card--offset{transform:translate(20px)}.rt-thread-list__empty-avatar{display:grid;flex:0 0 auto;border-radius:var(--rt-thread-list-avatar-radius);background:var(--rt-color-text-muted);block-size:24px;color:var(--rt-color-bg-surface);inline-size:24px;place-items:center}.rt-thread-list__empty-lines{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-thread-list__empty-line{border-radius:var(--rt-thread-list-line-radius);background:var(--rt-color-border-strong);block-size:6px;inline-size:112px}.rt-thread-list__empty-line--short{inline-size:48px}.rt-thread-list[data-rt-radius=none]{--rt-thread-list-card-radius: var(--rt-radius-none)}.rt-thread-list[data-rt-radius=xs]{--rt-thread-list-card-radius: var(--rt-radius-xs)}.rt-thread-list[data-rt-radius=sm]{--rt-thread-list-card-radius: var(--rt-radius-sm)}.rt-thread-list[data-rt-radius=ms]{--rt-thread-list-card-radius: var(--rt-radius-ms)}.rt-thread-list[data-rt-radius=md]{--rt-thread-list-card-radius: var(--rt-radius-md)}.rt-thread-list[data-rt-radius=lg]{--rt-thread-list-card-radius: var(--rt-radius-lg)}.rt-thread-list[data-rt-radius=xl]{--rt-thread-list-card-radius: var(--rt-radius-xl)}.rt-thread-list[data-rt-radius=\"2xl\"]{--rt-thread-list-card-radius: var(--rt-radius-2xl)}.rt-thread-list[data-rt-radius=full]{--rt-thread-list-card-radius: var(--rt-radius-full)}}\n"],
396
397
  dependencies: [
397
398
  {
398
399
  kind: "directive",
@@ -511,6 +512,12 @@ var RtThreadListComponent = class RtThreadListComponent {
511
512
  outputs: ["rtPopoverOpened", "rtPopoverClosed"],
512
513
  exportAs: ["rtPopover"]
513
514
  },
515
+ {
516
+ kind: "component",
517
+ type: RtServiceLogoComponent,
518
+ selector: "rt-service-logo",
519
+ inputs: ["logos", "size"]
520
+ },
514
521
  {
515
522
  kind: "component",
516
523
  type: RtSkeletonComponent,
@@ -572,6 +579,7 @@ i0.ɵɵngDeclareClassMetadata({
572
579
  RtIconButtonComponent,
573
580
  RtInputComponent,
574
581
  RtPopoverDirective,
582
+ RtServiceLogoComponent,
575
583
  RtSkeletonComponent,
576
584
  BlockDirective,
577
585
  ElemDirective,
@@ -583,8 +591,8 @@ i0.ɵɵngDeclareClassMetadata({
583
591
  inputs: ["radius"]
584
592
  }],
585
593
  host: { class: BEM_BLOCK },
586
- template: "<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 <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </button>\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",
587
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-thread-list{--rt-thread-list-border-width: var(--rt-border-width-thin);--rt-thread-list-card-radius: var(--rt-radius-lg);--rt-thread-list-tag-radius: var(--rt-radius-sm);--rt-thread-list-dot-radius: var(--rt-radius-full);--rt-thread-list-avatar-radius: var(--rt-radius-full);--rt-thread-list-line-radius: var(--rt-radius-full);display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0}.rt-thread-list__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-thread-list-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-2);padding-inline:var(--rt-space-4)}.rt-thread-list__search{flex:1 1 auto;min-inline-size:0}.rt-thread-list__filter-trigger{flex:0 0 auto}.rt-thread-list__filters-panel{display:flex;flex-direction:column;padding:var(--rt-space-4);gap:var(--rt-space-2);min-inline-size:220px}.rt-thread-list__rows{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;overflow-y:auto}.rt-thread-list__row{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-2) var(--rt-space-4);border:none;background:none;border-inline-start:3px solid transparent;cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);gap:var(--rt-space-4);inline-size:100%;text-align:start}.rt-thread-list__row:hover{background:var(--rt-color-bg-subtle)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread{position:relative;background:var(--rt-color-bg-subtle);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread .rt-thread-list__row-title{font-weight:var(--rt-font-weight-semibold)}.rt-thread-list__row--unread:before{position:absolute;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-action-primary);block-size:var(--rt-space-2);content:\"\";inline-size:var(--rt-space-2);inset-block-start:50%;inset-inline-start:var(--rt-space-2);transform:translateY(-50%)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg)}.rt-thread-list__row--overdue .rt-thread-list__row-time{color:var(--rt-color-state-error-text)}.rt-thread-list__row-wrap{position:relative}.rt-thread-list__row-wrap:hover .rt-thread-list__row-actions,.rt-thread-list__row-wrap:focus-within .rt-thread-list__row-actions,.rt-thread-list__row-wrap:has(.rt-menu--open) .rt-thread-list__row-actions{opacity:1;pointer-events:auto}.rt-thread-list__row-actions{position:absolute;display:flex;align-items:center;background:var(--rt-color-bg-subtle);gap:var(--rt-space-1);inset-block:0;inset-inline-end:0;opacity:0;padding-inline:var(--rt-space-2) var(--rt-space-4);pointer-events:none}.rt-thread-list__row--active+.rt-thread-list__row-actions{background:var(--rt-color-state-info-bg)}.rt-thread-list__row-body{display:flex;flex-direction:column;gap:var(--rt-space-0-5);min-inline-size:0}.rt-thread-list__row-title{overflow:hidden;color:var(--rt-color-text-primary);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-id{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-thread-list__row:hover .rt-copy-cell__button,.rt-thread-list__row:focus-within .rt-copy-cell__button{opacity:1}.rt-thread-list__row-subtitle{overflow:hidden;color:var(--rt-color-text-muted);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-meta{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-2)}.rt-thread-list__row-time{color:var(--rt-color-text-muted);white-space:nowrap}.rt-thread-list__row-tag{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-thread-list-tag-radius);background:var(--rt-color-state-warning-bg);color:var(--rt-color-state-warning-text);font-size:var(--rt-text-xs);white-space:nowrap}.rt-thread-list__row-dot{display:inline-block;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-text-link);block-size:6px;inline-size:6px}.rt-thread-list__row-skeleton{display:flex;flex-direction:column;padding:var(--rt-space-2) var(--rt-space-4);gap:var(--rt-space-2)}.rt-thread-list__row-loader{display:flex;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4)}.rt-thread-list__load-anchor{block-size:1px}.rt-thread-list__empty{padding:var(--rt-space-6) var(--rt-space-4)}.rt-thread-list__empty-preview{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-thread-list__empty-card{display:flex;align-items:center;padding:var(--rt-space-2);border:var(--rt-thread-list-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-thread-list-card-radius);background:var(--rt-color-bg-surface-subtle);gap:var(--rt-space-2)}.rt-thread-list__empty-card--offset{transform:translate(20px)}.rt-thread-list__empty-avatar{display:grid;flex:0 0 auto;border-radius:var(--rt-thread-list-avatar-radius);background:var(--rt-color-text-muted);block-size:24px;color:var(--rt-color-bg-surface);inline-size:24px;place-items:center}.rt-thread-list__empty-lines{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-thread-list__empty-line{border-radius:var(--rt-thread-list-line-radius);background:var(--rt-color-border-strong);block-size:6px;inline-size:112px}.rt-thread-list__empty-line--short{inline-size:48px}.rt-thread-list[data-rt-radius=none]{--rt-thread-list-card-radius: var(--rt-radius-none)}.rt-thread-list[data-rt-radius=xs]{--rt-thread-list-card-radius: var(--rt-radius-xs)}.rt-thread-list[data-rt-radius=sm]{--rt-thread-list-card-radius: var(--rt-radius-sm)}.rt-thread-list[data-rt-radius=ms]{--rt-thread-list-card-radius: var(--rt-radius-ms)}.rt-thread-list[data-rt-radius=md]{--rt-thread-list-card-radius: var(--rt-radius-md)}.rt-thread-list[data-rt-radius=lg]{--rt-thread-list-card-radius: var(--rt-radius-lg)}.rt-thread-list[data-rt-radius=xl]{--rt-thread-list-card-radius: var(--rt-radius-xl)}.rt-thread-list[data-rt-radius=\"2xl\"]{--rt-thread-list-card-radius: var(--rt-radius-2xl)}.rt-thread-list[data-rt-radius=full]{--rt-thread-list-card-radius: var(--rt-radius-full)}}\n"]
594
+ template: "<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",
595
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-thread-list{--rt-thread-list-border-width: var(--rt-border-width-thin);--rt-thread-list-card-radius: var(--rt-radius-lg);--rt-thread-list-tag-radius: var(--rt-radius-sm);--rt-thread-list-dot-radius: var(--rt-radius-full);--rt-thread-list-avatar-radius: var(--rt-radius-full);--rt-thread-list-line-radius: var(--rt-radius-full);display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0}.rt-thread-list__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-thread-list-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-2);padding-inline:var(--rt-space-4)}.rt-thread-list__search{flex:1 1 auto;min-inline-size:0}.rt-thread-list__filter-trigger{flex:0 0 auto}.rt-thread-list__filters-panel{display:flex;flex-direction:column;padding:var(--rt-space-4);gap:var(--rt-space-2);min-inline-size:220px}.rt-thread-list__rows{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;overflow-y:auto}.rt-thread-list__row{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-2) var(--rt-space-4);border:none;background:none;border-inline-start:3px solid transparent;cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);gap:var(--rt-space-4);inline-size:100%;text-align:start}.rt-thread-list__row:hover{background:var(--rt-color-bg-subtle)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread{position:relative;background:var(--rt-color-bg-subtle);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread .rt-thread-list__row-title{font-weight:var(--rt-font-weight-semibold)}.rt-thread-list__row--unread:before{position:absolute;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-action-primary);block-size:var(--rt-space-2);content:\"\";inline-size:var(--rt-space-2);inset-block-start:50%;inset-inline-start:var(--rt-space-2);transform:translateY(-50%)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg)}.rt-thread-list__row--overdue .rt-thread-list__row-time{color:var(--rt-color-state-error-text)}.rt-thread-list__row-wrap{position:relative}.rt-thread-list__row-wrap:hover .rt-thread-list__row-actions,.rt-thread-list__row-wrap:focus-within .rt-thread-list__row-actions,.rt-thread-list__row-wrap:has(.rt-menu--open) .rt-thread-list__row-actions{opacity:1;pointer-events:auto}.rt-thread-list__row-actions{position:absolute;display:flex;align-items:center;background:var(--rt-color-bg-subtle);gap:var(--rt-space-1);inset-block:0;inset-inline-end:0;opacity:0;padding-inline:var(--rt-space-2) var(--rt-space-4);pointer-events:none}.rt-thread-list__row--active+.rt-thread-list__row-actions{background:var(--rt-color-state-info-bg)}.rt-thread-list__row-sign{flex:none}.rt-thread-list__row-content{display:flex;flex:1 1 auto;align-items:center;justify-content:space-between;gap:var(--rt-space-4);min-inline-size:0}.rt-thread-list__row-body{display:flex;flex-direction:column;gap:var(--rt-space-0-5);min-inline-size:0}.rt-thread-list__row-title{overflow:hidden;color:var(--rt-color-text-primary);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-id{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-thread-list__row:hover .rt-copy-cell__button,.rt-thread-list__row:focus-within .rt-copy-cell__button{opacity:1}.rt-thread-list__row-subtitle{overflow:hidden;color:var(--rt-color-text-muted);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-meta{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-2)}.rt-thread-list__row-time{color:var(--rt-color-text-muted);white-space:nowrap}.rt-thread-list__row-tag{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-thread-list-tag-radius);background:var(--rt-color-state-warning-bg);color:var(--rt-color-state-warning-text);font-size:var(--rt-text-xs);white-space:nowrap}.rt-thread-list__row-dot{display:inline-block;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-text-link);block-size:6px;inline-size:6px}.rt-thread-list__row-skeleton{display:flex;flex-direction:column;padding:var(--rt-space-2) var(--rt-space-4);gap:var(--rt-space-2)}.rt-thread-list__row-loader{display:flex;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4)}.rt-thread-list__load-anchor{block-size:1px}.rt-thread-list__empty{padding:var(--rt-space-6) var(--rt-space-4)}.rt-thread-list__empty-preview{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-thread-list__empty-card{display:flex;align-items:center;padding:var(--rt-space-2);border:var(--rt-thread-list-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-thread-list-card-radius);background:var(--rt-color-bg-surface-subtle);gap:var(--rt-space-2)}.rt-thread-list__empty-card--offset{transform:translate(20px)}.rt-thread-list__empty-avatar{display:grid;flex:0 0 auto;border-radius:var(--rt-thread-list-avatar-radius);background:var(--rt-color-text-muted);block-size:24px;color:var(--rt-color-bg-surface);inline-size:24px;place-items:center}.rt-thread-list__empty-lines{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-thread-list__empty-line{border-radius:var(--rt-thread-list-line-radius);background:var(--rt-color-border-strong);block-size:6px;inline-size:112px}.rt-thread-list__empty-line--short{inline-size:48px}.rt-thread-list[data-rt-radius=none]{--rt-thread-list-card-radius: var(--rt-radius-none)}.rt-thread-list[data-rt-radius=xs]{--rt-thread-list-card-radius: var(--rt-radius-xs)}.rt-thread-list[data-rt-radius=sm]{--rt-thread-list-card-radius: var(--rt-radius-sm)}.rt-thread-list[data-rt-radius=ms]{--rt-thread-list-card-radius: var(--rt-radius-ms)}.rt-thread-list[data-rt-radius=md]{--rt-thread-list-card-radius: var(--rt-radius-md)}.rt-thread-list[data-rt-radius=lg]{--rt-thread-list-card-radius: var(--rt-radius-lg)}.rt-thread-list[data-rt-radius=xl]{--rt-thread-list-card-radius: var(--rt-radius-xl)}.rt-thread-list[data-rt-radius=\"2xl\"]{--rt-thread-list-card-radius: var(--rt-radius-2xl)}.rt-thread-list[data-rt-radius=full]{--rt-thread-list-card-radius: var(--rt-radius-full)}}\n"]
588
596
  }]
589
597
  }],
590
598
  propDecorators: {
@@ -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 { 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 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 <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </button>\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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"}
@@ -72,6 +72,7 @@ export * from "@rt-tools/ui-kit-v2/radius";
72
72
  export * from "@rt-tools/ui-kit-v2/ripple";
73
73
  export * from "@rt-tools/ui-kit-v2/scroll-area";
74
74
  export * from "@rt-tools/ui-kit-v2/section-nav";
75
+ export * from "@rt-tools/ui-kit-v2/service-block";
75
76
  export * from "@rt-tools/ui-kit-v2/service-logo";
76
77
  export * from "@rt-tools/ui-kit-v2/select";
77
78
  export * from "@rt-tools/ui-kit-v2/side-menu";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rt-tools/ui-kit-v2",
3
- "version": "0.30.0",
3
+ "version": "0.32.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Yauheni Krumin",
6
6
  "type": "module",
@@ -365,6 +365,10 @@
365
365
  "types": "./types/rt-tools-ui-kit-v2-select.d.ts",
366
366
  "default": "./fesm2022/rt-tools-ui-kit-v2-select.mjs"
367
367
  },
368
+ "./service-block": {
369
+ "types": "./types/rt-tools-ui-kit-v2-service-block.d.ts",
370
+ "default": "./fesm2022/rt-tools-ui-kit-v2-service-block.mjs"
371
+ },
368
372
  "./service-logo": {
369
373
  "types": "./types/rt-tools-ui-kit-v2-service-logo.d.ts",
370
374
  "default": "./fesm2022/rt-tools-ui-kit-v2-service-logo.mjs"
@@ -0,0 +1,37 @@
1
+ # `rt-service-block`
2
+
3
+ ```html
4
+ <rt-service-block [logos]="[{ src: service.logoUrl, label: service.name }]" [name]="service.name" [description]="service.purpose" />
5
+ ```
6
+
7
+ | вход | тип | умолчание |
8
+ | ------------- | -------------------------------- | ---------- |
9
+ | `logos` | `readonly IRtServiceLogo.Item[]` | обязателен |
10
+ | `name` | `string` | обязателен |
11
+ | `description` | `string` | `''` |
12
+
13
+ Выходов нет.
14
+
15
+ Спек — `docs/specs/ui-kit-v2/service-block/`; здесь только устройство папки.
16
+
17
+ ## Главное, что нужно знать
18
+
19
+ **Знак — готовый `rt-service-logo` без входа размера, то есть `md`.** Знаки передаются тем же
20
+ типом `IRtServiceLogo.Item`, своей модели у блока нет: второе имя одного типа разошлось бы с
21
+ первым.
22
+
23
+ **Числа — компонента «Service Block», и все они в свойствах блока.** Промежутки, ступени шрифта,
24
+ цвета и черта объявлены на корне блока ступенями шкалы.
25
+
26
+ **Текст переносится, знак — нет.** Знак стоит `flex: none`, место текста ужимается до нуля и
27
+ переносит слова по любому знаку (`overflow-wrap: anywhere`).
28
+
29
+ ## Края
30
+
31
+ - Пустое описание не рисуется: имя остаётся одно, по центру знака.
32
+ - Корень шаблона — `ng-container`: класс блока висит только на хосте.
33
+ - Своих текстов нет: имя, описание и подписи знаков даёт приложение.
34
+
35
+ ## Рядом
36
+
37
+ - [`rt-service-logo`](../service-logo/rt-service-logo.component.ts) — знак службы в круге.