@rt-tools/ui-kit-v2 0.16.0 → 0.18.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 (321) hide show
  1. package/README.md +25 -0
  2. package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs +79 -0
  3. package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs.map +1 -0
  4. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +227 -0
  5. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -0
  6. package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs +47 -0
  7. package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs.map +1 -0
  8. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +702 -0
  9. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -0
  10. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +214 -0
  11. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -0
  12. package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs +53 -0
  13. package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs.map +1 -0
  14. package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs +88 -0
  15. package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs.map +1 -0
  16. package/fesm2022/rt-tools-ui-kit-v2-button.mjs +365 -0
  17. package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -0
  18. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +152 -0
  19. package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -0
  20. package/fesm2022/rt-tools-ui-kit-v2-card.mjs +72 -0
  21. package/fesm2022/rt-tools-ui-kit-v2-card.mjs.map +1 -0
  22. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +111 -0
  23. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -0
  24. package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs +76 -0
  25. package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs.map +1 -0
  26. package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs +255 -0
  27. package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs.map +1 -0
  28. package/fesm2022/rt-tools-ui-kit-v2-container.mjs +1326 -0
  29. package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -0
  30. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +2590 -0
  31. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -0
  32. package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs +45 -0
  33. package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs.map +1 -0
  34. package/fesm2022/rt-tools-ui-kit-v2-counter.mjs +158 -0
  35. package/fesm2022/rt-tools-ui-kit-v2-counter.mjs.map +1 -0
  36. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +894 -0
  37. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -0
  38. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +1217 -0
  39. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -0
  40. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +779 -0
  41. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -0
  42. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +573 -0
  43. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -0
  44. package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs +141 -0
  45. package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs.map +1 -0
  46. package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs +68 -0
  47. package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs.map +1 -0
  48. package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs +478 -0
  49. package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs.map +1 -0
  50. package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs +183 -0
  51. package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs.map +1 -0
  52. package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs +44 -0
  53. package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs.map +1 -0
  54. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +260 -0
  55. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -0
  56. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +937 -0
  57. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -0
  58. package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs +56 -0
  59. package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs.map +1 -0
  60. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +107 -0
  61. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -0
  62. package/fesm2022/rt-tools-ui-kit-v2-field.mjs +183 -0
  63. package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -0
  64. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +219 -0
  65. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -0
  66. package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs +214 -0
  67. package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs.map +1 -0
  68. package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs +117 -0
  69. package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs.map +1 -0
  70. package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs +32 -0
  71. package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs.map +1 -0
  72. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +91 -0
  73. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -0
  74. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +220 -0
  75. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -0
  76. package/fesm2022/rt-tools-ui-kit-v2-header.mjs +72 -0
  77. package/fesm2022/rt-tools-ui-kit-v2-header.mjs.map +1 -0
  78. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +163 -0
  79. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -0
  80. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +674 -0
  81. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -0
  82. package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs +540 -0
  83. package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs.map +1 -0
  84. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +227 -0
  85. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -0
  86. package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs +37 -0
  87. package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs.map +1 -0
  88. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +361 -0
  89. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -0
  90. package/fesm2022/rt-tools-ui-kit-v2-input.mjs +143 -0
  91. package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -0
  92. package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs +49 -0
  93. package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs.map +1 -0
  94. package/fesm2022/rt-tools-ui-kit-v2-logo.mjs +97 -0
  95. package/fesm2022/rt-tools-ui-kit-v2-logo.mjs.map +1 -0
  96. package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs +57 -0
  97. package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs.map +1 -0
  98. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +537 -0
  99. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -0
  100. package/fesm2022/rt-tools-ui-kit-v2-message.mjs +105 -0
  101. package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -0
  102. package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs +71 -0
  103. package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs.map +1 -0
  104. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +315 -0
  105. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -0
  106. package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs +51 -0
  107. package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs.map +1 -0
  108. package/fesm2022/rt-tools-ui-kit-v2-note.mjs +44 -0
  109. package/fesm2022/rt-tools-ui-kit-v2-note.mjs.map +1 -0
  110. package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs +54 -0
  111. package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs.map +1 -0
  112. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +339 -0
  113. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -0
  114. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +187 -0
  115. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -0
  116. package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs +170 -0
  117. package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs.map +1 -0
  118. package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +312 -0
  119. package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -0
  120. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +174 -0
  121. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -0
  122. package/fesm2022/rt-tools-ui-kit-v2-radius.mjs +56 -0
  123. package/fesm2022/rt-tools-ui-kit-v2-radius.mjs.map +1 -0
  124. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +96 -41
  125. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  126. package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs +118 -0
  127. package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs.map +1 -0
  128. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +290 -0
  129. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -0
  130. package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +37 -0
  131. package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -0
  132. package/fesm2022/rt-tools-ui-kit-v2-select.mjs +495 -0
  133. package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -0
  134. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +1493 -0
  135. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -0
  136. package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs +49 -0
  137. package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs.map +1 -0
  138. package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs +123 -0
  139. package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs.map +1 -0
  140. package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs +70 -0
  141. package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs.map +1 -0
  142. package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +92 -0
  143. package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -0
  144. package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +147 -0
  145. package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -0
  146. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +117 -0
  147. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -0
  148. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +1636 -0
  149. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -0
  150. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +350 -0
  151. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -0
  152. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +122 -0
  153. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -0
  154. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +85 -0
  155. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -0
  156. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +73 -0
  157. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -0
  158. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +196 -0
  159. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -0
  160. package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs +39 -0
  161. package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs.map +1 -0
  162. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +338 -0
  163. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -0
  164. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +132 -0
  165. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -0
  166. package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +162 -0
  167. package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -0
  168. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +135 -0
  169. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -0
  170. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +214 -0
  171. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -0
  172. package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs +64 -0
  173. package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs.map +1 -0
  174. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +263 -0
  175. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -0
  176. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +296 -0
  177. package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -0
  178. package/fesm2022/rt-tools-ui-kit-v2.mjs +91 -23164
  179. package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
  180. package/package.json +349 -1
  181. package/rt-tools-ui-kit-v2-0.18.0.tgz +0 -0
  182. package/src/lib/components/action-bar/CONTEXT.md +5 -0
  183. package/src/lib/components/action-bar/rt-action-bar.component.scss +30 -16
  184. package/src/lib/components/aside/CONTEXT.md +9 -1
  185. package/src/lib/components/aside/footer/rt-aside-footer.component.scss +7 -8
  186. package/src/lib/components/aside/header/rt-aside-header.component.scss +16 -1
  187. package/src/lib/components/aside/rt-aside.component.scss +17 -1
  188. package/src/lib/components/button/CONTEXT.md +12 -11
  189. package/src/lib/components/button/rt-button.directive.scss +36 -0
  190. package/src/lib/components/data-list/settings/rt-data-list-settings-aside.component.scss +2 -2
  191. package/src/lib/components/data-table/cell/rt-data-table-cell.component.scss +1 -1
  192. package/src/lib/components/data-table/filter-cell/rt-data-table-filter-cell.component.scss +1 -1
  193. package/src/lib/components/data-table/rt-data-table.component.scss +1 -1
  194. package/src/lib/components/dialog/CONTEXT.md +9 -0
  195. package/src/lib/components/dialog/content/rt-dialog-content.component.scss +20 -0
  196. package/src/lib/components/dialog/footer/rt-dialog-footer.component.scss +18 -2
  197. package/src/lib/components/dialog/header/rt-dialog-header.component.scss +21 -3
  198. package/src/lib/components/dialog/rt-dialog.component.scss +9 -3
  199. package/src/lib/components/dot-field/CONTEXT.md +31 -0
  200. package/src/lib/components/dot-field/rt-dot-field.component.scss +20 -0
  201. package/src/lib/components/dot-field/stories/component/CONTEXT.md +14 -0
  202. package/src/lib/components/dot-field/stories/component/test-dot-field.component.scss +31 -0
  203. package/src/lib/components/dynamic-selector/CONTEXT.md +6 -0
  204. package/src/lib/components/field/CONTEXT.md +18 -2
  205. package/src/lib/components/header/CONTEXT.md +2 -2
  206. package/src/lib/components/icon/CONTEXT.md +11 -7
  207. package/src/lib/components/icon/rt-icon.component.scss +47 -0
  208. package/src/lib/components/icon-button/CONTEXT.md +27 -20
  209. package/src/lib/components/icon-button/rt-icon-button.component.scss +51 -25
  210. package/src/lib/components/image-upload/CONTEXT.md +20 -15
  211. package/src/lib/components/image-upload/rt-image-upload.component.scss +14 -2
  212. package/src/lib/components/pagination/rt-pagination.component.scss +1 -1
  213. package/src/lib/components/scroll-area/CONTEXT.md +2 -0
  214. package/src/lib/components/scroll-area/rt-scroll-area.component.scss +20 -3
  215. package/src/lib/components/select/rt-select.component.scss +4 -0
  216. package/src/lib/components/side-menu/CONTEXT.md +7 -2
  217. package/src/lib/components/spinner/CONTEXT.md +15 -8
  218. package/src/lib/components/spinner/rt-spinner.component.scss +108 -9
  219. package/src/lib/components/tag/rt-tag.component.scss +43 -23
  220. package/src/lib/components/toast/CONTEXT.md +8 -0
  221. package/src/lib/components/toast/rt-toast.component.scss +74 -15
  222. package/src/lib/components/toast/rt-toaster.component.scss +5 -1
  223. package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +35 -37
  224. package/src/lib/components/toggle-switch/CONTEXT.md +11 -3
  225. package/src/lib/components/toggle-switch/rt-toggle-switch.component.scss +53 -14
  226. package/src/lib/components/toolbar/rt-toolbar.component.scss +15 -4
  227. package/src/lib/components/tooltip/CONTEXT.md +5 -5
  228. package/src/rich-editor/lib/components/chat/CONTEXT.md +7 -2
  229. package/src/rich-editor/lib/components/chat/rt-chat.component.scss +25 -0
  230. package/src/styles/_semantic.scss +1 -1
  231. package/styles/tokens.css +43 -8
  232. package/types/rt-tools-ui-kit-v2-accordion.d.ts +30 -0
  233. package/types/rt-tools-ui-kit-v2-action-bar.d.ts +140 -0
  234. package/types/rt-tools-ui-kit-v2-aside-section.d.ts +25 -0
  235. package/types/rt-tools-ui-kit-v2-aside.d.ts +436 -0
  236. package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +78 -0
  237. package/types/rt-tools-ui-kit-v2-bar-list.d.ts +41 -0
  238. package/types/rt-tools-ui-kit-v2-bottom-sheet.d.ts +20 -0
  239. package/types/rt-tools-ui-kit-v2-button.d.ts +76 -0
  240. package/types/rt-tools-ui-kit-v2-calendar.d.ts +96 -0
  241. package/types/rt-tools-ui-kit-v2-card.d.ts +38 -0
  242. package/types/rt-tools-ui-kit-v2-checkbox.d.ts +46 -0
  243. package/types/rt-tools-ui-kit-v2-collapsible-text.d.ts +20 -0
  244. package/types/rt-tools-ui-kit-v2-confirm-popover.d.ts +85 -0
  245. package/types/rt-tools-ui-kit-v2-container.d.ts +425 -0
  246. package/types/rt-tools-ui-kit-v2-core.d.ts +1222 -0
  247. package/types/rt-tools-ui-kit-v2-counter-row.d.ts +22 -0
  248. package/types/rt-tools-ui-kit-v2-counter.d.ts +70 -0
  249. package/types/rt-tools-ui-kit-v2-data-list.d.ts +334 -0
  250. package/types/rt-tools-ui-kit-v2-data-table.d.ts +494 -0
  251. package/types/rt-tools-ui-kit-v2-date-picker.d.ts +181 -0
  252. package/types/rt-tools-ui-kit-v2-date-range.d.ts +98 -0
  253. package/types/rt-tools-ui-kit-v2-delta-view.d.ts +20 -0
  254. package/types/rt-tools-ui-kit-v2-detail-list.d.ts +33 -0
  255. package/types/rt-tools-ui-kit-v2-dialog.d.ts +287 -0
  256. package/types/rt-tools-ui-kit-v2-dot-field.d.ts +17 -0
  257. package/types/rt-tools-ui-kit-v2-download-link.d.ts +17 -0
  258. package/types/rt-tools-ui-kit-v2-dynamic-list.d.ts +139 -0
  259. package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +384 -0
  260. package/types/rt-tools-ui-kit-v2-empty-state.d.ts +29 -0
  261. package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +57 -0
  262. package/types/rt-tools-ui-kit-v2-field.d.ts +82 -0
  263. package/types/rt-tools-ui-kit-v2-file-card.d.ts +114 -0
  264. package/types/rt-tools-ui-kit-v2-file-drop.d.ts +75 -0
  265. package/types/rt-tools-ui-kit-v2-file-input.d.ts +48 -0
  266. package/types/rt-tools-ui-kit-v2-file-list.d.ts +13 -0
  267. package/types/rt-tools-ui-kit-v2-filter-control.d.ts +72 -0
  268. package/types/rt-tools-ui-kit-v2-form-control.d.ts +74 -0
  269. package/types/rt-tools-ui-kit-v2-header.d.ts +40 -0
  270. package/types/rt-tools-ui-kit-v2-icon-button.d.ts +113 -0
  271. package/types/rt-tools-ui-kit-v2-icon.d.ts +238 -0
  272. package/types/rt-tools-ui-kit-v2-image-cropper.d.ts +168 -0
  273. package/types/rt-tools-ui-kit-v2-image-upload.d.ts +102 -0
  274. package/types/rt-tools-ui-kit-v2-info-item.d.ts +13 -0
  275. package/types/rt-tools-ui-kit-v2-input-number.d.ts +67 -0
  276. package/types/rt-tools-ui-kit-v2-input.d.ts +54 -0
  277. package/types/rt-tools-ui-kit-v2-live-badge.d.ts +23 -0
  278. package/types/rt-tools-ui-kit-v2-logo.d.ts +58 -0
  279. package/types/rt-tools-ui-kit-v2-markdown-text.d.ts +30 -0
  280. package/types/rt-tools-ui-kit-v2-menu.d.ts +217 -0
  281. package/types/rt-tools-ui-kit-v2-message.d.ts +56 -0
  282. package/types/rt-tools-ui-kit-v2-money-list.d.ts +34 -0
  283. package/types/rt-tools-ui-kit-v2-multiselect.d.ts +93 -0
  284. package/types/rt-tools-ui-kit-v2-night-grid.d.ts +39 -0
  285. package/types/rt-tools-ui-kit-v2-note.d.ts +21 -0
  286. package/types/rt-tools-ui-kit-v2-notifications-bell.d.ts +23 -0
  287. package/types/rt-tools-ui-kit-v2-page-header.d.ts +173 -0
  288. package/types/rt-tools-ui-kit-v2-pagination.d.ts +64 -0
  289. package/types/rt-tools-ui-kit-v2-photo-viewer.d.ts +98 -0
  290. package/types/rt-tools-ui-kit-v2-popover.d.ts +79 -0
  291. package/types/rt-tools-ui-kit-v2-radio-button.d.ts +61 -0
  292. package/types/rt-tools-ui-kit-v2-radius.d.ts +37 -0
  293. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +16 -20
  294. package/types/rt-tools-ui-kit-v2-ripple.d.ts +39 -0
  295. package/types/rt-tools-ui-kit-v2-scroll-area.d.ts +91 -0
  296. package/types/rt-tools-ui-kit-v2-section-nav.d.ts +23 -0
  297. package/types/rt-tools-ui-kit-v2-select.d.ts +215 -0
  298. package/types/rt-tools-ui-kit-v2-side-menu.d.ts +483 -0
  299. package/types/rt-tools-ui-kit-v2-skeleton-wrapper.d.ts +32 -0
  300. package/types/rt-tools-ui-kit-v2-skeleton.d.ts +41 -0
  301. package/types/rt-tools-ui-kit-v2-spinner.d.ts +56 -0
  302. package/types/rt-tools-ui-kit-v2-split-button.d.ts +72 -0
  303. package/types/rt-tools-ui-kit-v2-stat-tile.d.ts +81 -0
  304. package/types/rt-tools-ui-kit-v2-stepper.d.ts +51 -0
  305. package/types/rt-tools-ui-kit-v2-table.d.ts +739 -0
  306. package/types/rt-tools-ui-kit-v2-tabs.d.ts +153 -0
  307. package/types/rt-tools-ui-kit-v2-tag.d.ts +70 -0
  308. package/types/rt-tools-ui-kit-v2-textarea.d.ts +36 -0
  309. package/types/rt-tools-ui-kit-v2-theme-toggle.d.ts +43 -0
  310. package/types/rt-tools-ui-kit-v2-thread-list.d.ts +111 -0
  311. package/types/rt-tools-ui-kit-v2-timeline.d.ts +35 -0
  312. package/types/rt-tools-ui-kit-v2-toast.d.ts +103 -0
  313. package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +109 -0
  314. package/types/rt-tools-ui-kit-v2-toggle-switch.d.ts +85 -0
  315. package/types/rt-tools-ui-kit-v2-toolbar.d.ts +66 -0
  316. package/types/rt-tools-ui-kit-v2-tooltip.d.ts +74 -0
  317. package/types/rt-tools-ui-kit-v2-welcome-dialog.d.ts +33 -0
  318. package/types/rt-tools-ui-kit-v2-workspace-details.d.ts +128 -0
  319. package/types/rt-tools-ui-kit-v2-workspace.d.ts +84 -0
  320. package/types/rt-tools-ui-kit-v2.d.ts +87 -9290
  321. package/rt-tools-ui-kit-v2-0.16.0.tgz +0 -0
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { viewChild, signal, computed, input, output, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component, inject, booleanAttribute, numberAttribute, model, effect, TemplateRef, Directive, Pipe, contentChild, afterRenderEffect } from '@angular/core';
2
+ import { viewChild, signal, computed, input, output, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component, inject, booleanAttribute, numberAttribute, model, effect, TemplateRef, Directive, Pipe, DestroyRef, contentChild, afterRenderEffect } from '@angular/core';
3
3
  import { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
4
4
  import { RtFormControlBase, coerceQuillDeltaOutput, rtKitLabel, RT_KIT_LABELS, RtFileCardComponent, RtIconButtonComponent, RT_KIT_LOCALE, RtButtonDirective, RtConfirmDirective, RtDeltaViewComponent, RtFileDropComponent, RtIconComponent, RtMenuComponent, RtNoteComponent, RtSkeletonWrapperComponent, RtSpinnerComponent, RtToolbarComponent, RtToolbarLeftDirective, RtToolbarRightDirective, fileNameFromUrl } from '@rt-tools/ui-kit-v2';
5
5
  import { CdkTextareaAutosize } from '@angular/cdk/text-field';
@@ -393,7 +393,7 @@ class RtMessageComposerComponent {
393
393
  // cdk
394
394
  CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type:
395
395
  // standalone components / directives
396
- RtFileCardComponent, selector: "rt-file-card", inputs: ["name", "sizeBytes", "size", "showDownload", "showRemove", "showRename", "disabled"], outputs: ["download", "removed", "rename"] }, { kind: "component", type: RtIconButtonComponent, selector: "rt-icon-button", inputs: ["icon", "ariaLabel", "variant", "iconColor", "iconFill", "size", "iconSize", "type", "tooltip", "tabIndex", "loading", "disabled", "active", "indicator"], outputs: ["clicked"] }, { kind: "component", type: RtRichEditorComponent, selector: "rt-rich-editor", inputs: ["placeholder", "toolbar"], outputs: ["enterPressed"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
396
+ RtFileCardComponent, selector: "rt-file-card", inputs: ["name", "sizeBytes", "size", "showDownload", "showRemove", "showRename", "disabled"], outputs: ["download", "removed", "rename"] }, { kind: "component", type: RtIconButtonComponent, selector: "rt-icon-button", inputs: ["icon", "glyph", "ariaLabel", "variant", "iconColor", "iconFill", "size", "iconSize", "type", "tooltip", "tabIndex", "loading", "disabled", "active", "indicator"], outputs: ["clicked"] }, { kind: "component", type: RtRichEditorComponent, selector: "rt-rich-editor", inputs: ["placeholder", "toolbar"], outputs: ["enterPressed"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
397
397
  }
398
398
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtMessageComposerComponent, decorators: [{
399
399
  type: Component,
@@ -572,33 +572,84 @@ function nextAtBottom(previous, lastScrollTop, metrics) {
572
572
  return metrics.scrollTop < lastScrollTop - 1 ? nearBottom : previous || nearBottom;
573
573
  }
574
574
 
575
+ /** Пауза без ввода, после которой отрезок набора считается законченным. */
576
+ const RT_CHAT_TYPING_PAUSE_MS = 3000;
577
+ /**
578
+ * Текст поля ответа из узла, где случился ввод. Поле обычного режима — textarea, поле с
579
+ * оформлением — редактируемый узел; всё прочее, например выбор файла, набором не считается и
580
+ * даёт `null`.
581
+ */
582
+ function typingDraft(target) {
583
+ if (target instanceof HTMLTextAreaElement) {
584
+ return target.value;
585
+ }
586
+ const editor = target instanceof HTMLElement ? target.closest('[contenteditable="true"]') : null;
587
+ return editor === null ? null : (editor.textContent ?? '');
588
+ }
589
+ /**
590
+ * Отрезок набора: одно «начал» и одно «перестал» на отрезок, а не событие на каждую клавишу.
591
+ * Отрезок кончается пустым полем, отправкой или паузой без ввода. Создаётся в контексте
592
+ * внедрения: таймер паузы снимается вместе с компонентом, и выход уничтоженного компонента не
593
+ * зовётся.
594
+ */
595
+ class RtChatTypingTracker {
596
+ #typing = false;
597
+ #timer = null;
598
+ #notify;
599
+ #pauseMs;
600
+ constructor(notify, pauseMs = RT_CHAT_TYPING_PAUSE_MS) {
601
+ this.#notify = notify;
602
+ this.#pauseMs = pauseMs;
603
+ inject(DestroyRef).onDestroy(() => this.#clearTimer());
604
+ }
605
+ /** Ввод в поле ответа с его текущим текстом: пустой текст кончает отрезок. */
606
+ input(draft) {
607
+ if (draft.trim().length === 0) {
608
+ this.stop();
609
+ return;
610
+ }
611
+ if (!this.#typing) {
612
+ this.#typing = true;
613
+ this.#notify(true);
614
+ }
615
+ this.#clearTimer();
616
+ this.#timer = setTimeout(() => this.stop(), this.#pauseMs);
617
+ }
618
+ /** Конец отрезка; отрезок, который уже кончился, ничего не шлёт. */
619
+ stop() {
620
+ this.#clearTimer();
621
+ if (this.#typing) {
622
+ this.#typing = false;
623
+ this.#notify(false);
624
+ }
625
+ }
626
+ #clearTimer() {
627
+ if (this.#timer !== null) {
628
+ clearTimeout(this.#timer);
629
+ this.#timer = null;
630
+ }
631
+ }
632
+ }
633
+
575
634
  const BEM_BLOCK = 'rt-chat';
576
635
  /** Ключ заглушки имени вложения, когда домен не отдал `fileName` (только URL). */
577
636
  const ATTACHMENT_FALLBACK_KEY = 'chatAttachmentFallback';
578
637
  /**
579
- * Общий презентационный чат: тред сообщений + композер. Никакого data-access/api — история
580
- * приходит готовым массивом `IRtChat.Message[]`, отправка/обновление/скачивание уходят наружу
581
- * через outputs, а стор и blob-загрузка остаются в feature-компоненте каждого домена.
582
- *
583
- * Композер держит свой `FormGroup` — наружу торчит только `send`. Полноэкранный
584
- * режим (expand) — overlay внутри самого компонента (`--expanded`), потребителю
585
- * лишь опционально сообщается через `expandedChange`.
586
- *
587
- * Шапка (тулбар «Чат» + refresh/expand) рендерится только когда включена хотя бы
588
- * одна из иконок (`showRefresh`/`showExpand`): в диалогах своя header-обёртка,
589
- * туда тулбар не нужен.
638
+ * Общий презентационный чат: тред сообщений + композер. История приходит готовым массивом
639
+ * `IRtChat.Message[]`, отправка, обновление, скачивание и набор текста уходят наружу выходами;
640
+ * стор и blob-загрузка остаются у потребителя. Композер держит свой `FormGroup`. Полноэкранный
641
+ * режим — overlay внутри компонента (`--expanded`). Шапка рисуется, только когда включена хотя бы
642
+ * одна из иконок `showRefresh`/`showExpand`: в диалогах своя header-обёртка.
590
643
  */
591
644
  class RtChatComponent {
592
- /**
593
- * Пользователь у нижнего края треда. Плоское поле (не сигнал), чтобы
594
- * afterRenderEffect не перезапускался на каждый scroll — обновляется в
595
- * обработчике scroll и читается при автоскролле.
596
- */
645
+ /** Читатель у нижнего края. Плоское поле, не сигнал: afterRenderEffect не перезапускается на scroll. */
597
646
  #atBottom;
598
647
  /** Прошлый scrollTop треда — для различения прокрутки вверх и роста контента. */
599
648
  #lastScrollTop;
600
649
  /** One-shot: своё отправленное сообщение всегда прокручивает тред вниз. */
601
650
  #forceScroll;
651
+ /** Отрезок набора в поле ответа: наружу уходит одно «начал» и одно «перестал» на отрезок. */
652
+ #typingTracker;
602
653
  /** Текущее значение композера — источник реактивности для `canSend`. */
603
654
  #formValue;
604
655
  #defaultTitle;
@@ -606,25 +657,20 @@ class RtChatComponent {
606
657
  #defaultEmptyHint;
607
658
  constructor() {
608
659
  /**
609
- * Дата сообщения форматируется по активной локали приложения, а не по
610
- * `LOCALE_ID`: тот вычисляется на подъёме приложения и там, где язык
611
- * переключают на ходу, оставил бы часы в прежнем формате до перезагрузки.
612
- *
613
- * Данные локали для `DatePipe` регистрирует приложение: без них пайп падает
614
- * `Missing locale data`, и кит за это не отвечает.
660
+ * Дата форматируется по активной локали приложения, а не по `LOCALE_ID`: тот вычисляется на
661
+ * подъёме и при смене языка на ходу оставил бы прежний формат. Данные локали для `DatePipe`
662
+ * регистрирует приложение: без них пайп падает `Missing locale data`.
615
663
  */
616
664
  this.t = inject(RT_KIT_LABELS);
617
665
  this.locale = inject(RT_KIT_LOCALE);
618
- /**
619
- * Пользователь у нижнего края треда. Плоское поле (не сигнал), чтобы
620
- * afterRenderEffect не перезапускался на каждый scroll — обновляется в
621
- * обработчике scroll и читается при автоскролле.
622
- */
666
+ /** Читатель у нижнего края. Плоское поле, не сигнал: afterRenderEffect не перезапускается на scroll. */
623
667
  this.#atBottom = true;
624
668
  /** Прошлый scrollTop треда — для различения прокрутки вверх и роста контента. */
625
669
  this.#lastScrollTop = 0;
626
670
  /** One-shot: своё отправленное сообщение всегда прокручивает тред вниз. */
627
671
  this.#forceScroll = false;
672
+ /** Отрезок набора в поле ответа: наружу уходит одно «начал» и одно «перестал» на отрезок. */
673
+ this.#typingTracker = new RtChatTypingTracker((typing) => this.typing.emit(typing));
628
674
  /**
629
675
  * Скролл-контейнер треда — для автопрокрутки к последнему сообщению.
630
676
  * `viewChild` не работает на ES-private (`#`) поле, поэтому `protected`.
@@ -763,11 +809,15 @@ class RtChatComponent {
763
809
  this.send = output();
764
810
  /** Клик refresh — consumer перетягивает тред. */
765
811
  this.refresh = output();
766
- /** Клик по вложению — consumer качает blob своим api. Шаблон зовёт выход прямо: релей-метод,
767
- * который только повторял `emit`, ничего не добавлял, а файл при этом рос. */
812
+ /** Клик по вложению — consumer качает blob своим api; шаблон зовёт выход прямо, без релея. */
768
813
  this.downloadFile = output();
769
814
  /** Клик по карточке вложения из `attachments[]` — консюмер качает по `publicId`. */
770
815
  this.downloadAttachment = output();
816
+ /** Набор текста в поле ответа: `true` — отрезок начался, `false` — кончился. */
817
+ this.typing = output();
818
+ /** Строка о том, что печатает вторая сторона, поверх низа ленты; пустая прячет плашку. */
819
+ this.typingText = input('', /* @ts-ignore */
820
+ ...(ngDevMode ? [{ debugName: "typingText" }] : /* istanbul ignore next */ []));
771
821
  /** Смена fullscreen-состояния. */
772
822
  this.expandedChange = output();
773
823
  this.deleteMessage = output();
@@ -784,12 +834,8 @@ class RtChatComponent {
784
834
  this.#formValue = toSignal(this.replyForm.valueChanges, {
785
835
  initialValue: this.replyForm.value,
786
836
  });
787
- // Поведение мессенджера: после каждого рендера, зависящего от треда
788
- // (новые сообщения, окончание загрузки, fullscreen), прокручиваем к
789
- // последнему сообщению — но только если это своё сообщение (forceScroll)
790
- // или пользователь уже у нижнего края. Если он ушёл вверх читать историю,
791
- // входящее сообщение его не дёргает. afterRenderEffect гарантирует, что DOM
792
- // уже обновлён и scrollHeight посчитан по реальной высоте.
837
+ // После рендера, зависящего от треда, лента прокручивается к последнему сообщению — если оно
838
+ // своё (forceScroll) или читатель у нижнего края; ушедшего читать историю входящее не дёргает.
793
839
  afterRenderEffect(() => {
794
840
  this.messages();
795
841
  this.loading();
@@ -829,6 +875,7 @@ class RtChatComponent {
829
875
  const files = this.replyForm.controls.files.value;
830
876
  // Своё сообщение всегда прокручивает тред вниз — независимо от позиции.
831
877
  this.#forceScroll = true;
878
+ this.#typingTracker.stop();
832
879
  this.send.emit({ text, files: this.attachments() ? files : undefined });
833
880
  this.replyForm.reset({ message: '', files: [] });
834
881
  }
@@ -842,12 +889,20 @@ class RtChatComponent {
842
889
  onComposerSubmit(payload) {
843
890
  // Своё сообщение всегда прокручивает тред вниз — независимо от позиции.
844
891
  this.#forceScroll = true;
892
+ this.#typingTracker.stop();
845
893
  this.send.emit({
846
894
  text: payload.text,
847
895
  files: this.attachments() ? payload.files : undefined,
848
896
  delta: payload.delta,
849
897
  });
850
898
  }
899
+ /** Ввод в поле ответа любого из двух режимов; выбор файла набором не считается. */
900
+ onReplyInput(event) {
901
+ const draft = typingDraft(event.target);
902
+ if (draft !== null) {
903
+ this.#typingTracker.input(draft);
904
+ }
905
+ }
851
906
  /**
852
907
  * Файлы выброшены в обёртку чата: в rich-режиме отдаём массив композеру через
853
908
  * input, в классическом — добавляем к уже выбранным в собственном `replyForm`.
@@ -908,11 +963,11 @@ class RtChatComponent {
908
963
  this.expandedChange.emit(next);
909
964
  }
910
965
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
911
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtChatComponent, isStandalone: true, selector: "rt-chat", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fetching: { classPropertyName: "fetching", publicName: "fetching", isSignal: true, isRequired: false, transformFunction: null }, canReply: { classPropertyName: "canReply", publicName: "canReply", isSignal: true, isRequired: false, transformFunction: null }, replyBlockReason: { classPropertyName: "replyBlockReason", publicName: "replyBlockReason", isSignal: true, isRequired: false, transformFunction: null }, sending: { classPropertyName: "sending", publicName: "sending", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, emptyHint: { classPropertyName: "emptyHint", publicName: "emptyHint", isSignal: true, isRequired: false, transformFunction: null }, hasThread: { classPropertyName: "hasThread", publicName: "hasThread", isSignal: true, isRequired: false, transformFunction: null }, attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, richComposer: { classPropertyName: "richComposer", publicName: "richComposer", isSignal: true, isRequired: false, transformFunction: null }, formatting: { classPropertyName: "formatting", publicName: "formatting", isSignal: true, isRequired: false, transformFunction: null }, formattingToolbar: { classPropertyName: "formattingToolbar", publicName: "formattingToolbar", isSignal: true, isRequired: false, transformFunction: null }, fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null }, showRefresh: { classPropertyName: "showRefresh", publicName: "showRefresh", isSignal: true, isRequired: false, transformFunction: null }, showExpand: { classPropertyName: "showExpand", publicName: "showExpand", isSignal: true, isRequired: false, transformFunction: null }, messageHasActions: { classPropertyName: "messageHasActions", publicName: "messageHasActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { send: "send", refresh: "refresh", downloadFile: "downloadFile", downloadAttachment: "downloadAttachment", expandedChange: "expandedChange", deleteMessage: "deleteMessage", retryMessage: "retryMessage" }, host: { properties: { "class.rt-chat--expanded": "expanded()", "class.rt-chat--fill": "fill()" }, classAttribute: "rt-chat" }, queries: [{ propertyName: "messageActions", first: true, predicate: RtChatMessageActionsDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "thread", first: true, predicate: ["thread"], descendants: true, isSignal: true }, { propertyName: "composerFileEl", first: true, predicate: ["composerFileEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container rtBlock=\"rt-chat\">\n <rt-file-drop\n [overlayLabel]=\"t().chatDropOverlay\"\n [accept]=\"accept()\"\n [disabled]=\"dropDisabled()\"\n (filesDropped)=\"onFilesDropped($event)\">\n @if (showHeader()) {\n <rt-toolbar rtElem=\"header\" dense>\n <ng-template rtToolbarLeft>\n <h3 rtElem=\"title\" qa-dataid=\"chat-title\">{{ title() }}</h3>\n </ng-template>\n <ng-template rtToolbarRight>\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"chat-refresh\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRefreshAria\"\n [tooltip]=\"t().chatRefreshTooltip\"\n [loading]=\"fetching()\"\n [disabled]=\"!hasThread()\"\n (clicked)=\"refresh.emit()\" />\n }\n @if (showExpand()) {\n <rt-icon-button\n qa-dataid=\"chat-expand\"\n variant=\"ghost\"\n [icon]=\"expanded() ? 'window-minimize' : 'window-maximize'\"\n [ariaLabel]=\"expandLabel()\"\n [tooltip]=\"expandLabel()\"\n (clicked)=\"toggleExpand()\" />\n }\n <ng-content select=\"[rtChatHeaderActions]\" />\n </ng-template>\n </rt-toolbar>\n }\n\n @if (!hasThread()) {\n <rt-note qa-dataid=\"chat-empty-hint\">{{ emptyHint() }}</rt-note>\n } @else {\n <div rtElem=\"thread-viewport\" qa-dataid=\"chat-thread-viewport\">\n @if (loading()) {\n <!-- \u0421\u043A\u0435\u043B\u0435\u0442\u043E\u043D \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u0442 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0443 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F (\u0430\u0432\u0442\u043E\u0440 \u2192 \u0442\u0435\u043A\u0441\u0442 \u2192 \u0434\u0430\u0442\u0430),\n \u0447\u0435\u0440\u0435\u0434\u0443\u044F \u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u0435, \u0447\u0442\u043E\u0431\u044B \u0442\u0440\u0435\u0434 \u043D\u0435 \u00AB\u043F\u0440\u044B\u0433\u0430\u043B\u00BB \u043F\u0440\u0438 \u043F\u043E\u0434\u043C\u0435\u043D\u0435 \u043D\u0430 \u0440\u0435\u0430\u043B\u044C\u043D\u044B\u0435. -->\n <div rtElem=\"thread\" qa-dataid=\"chat-thread-skeleton\">\n @for (row of skeletonRows; track row; let even = $even) {\n <div rtElem=\"message-skeleton\" qa-dataid=\"chat-message-skeleton\" [rtMod]=\"{ own: even }\">\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"72px\" height=\"10px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"100%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"55%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"56px\" height=\"10px\" [isLoading]=\"true\" />\n </div>\n }\n </div>\n } @else {\n <div\n #thread\n rtElem=\"thread\"\n qa-dataid=\"chat-thread\"\n [rtMod]=\"{ frozen: fetching() }\"\n [attr.aria-busy]=\"fetching() ? 'true' : null\"\n (scroll)=\"onThreadScroll()\">\n @for (m of messages(); track m.id) {\n <div\n rtElem=\"message-row\"\n qa-dataid=\"chat-message\"\n [attr.data-own]=\"m.own\"\n [attr.data-status]=\"m.status || null\"\n [attr.data-deleted]=\"m.deleted || null\"\n [rtMod]=\"{ own: m.own }\">\n @if (m.canDelete && !m.deleted) {\n @if (m.deleteConfirm) {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n [rtConfirm]=\"m.deleteConfirm\"\n (confirmed)=\"deleteMessage.emit(m)\" />\n } @else {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n (clicked)=\"deleteMessage.emit(m)\" />\n }\n }\n @if (messageActions()?.template; as actionsTpl) {\n @if (m | rtChatMessageHasActions: messageHasActions()) {\n <div rtElem=\"message-actions\" qa-dataid=\"chat-message-actions\">\n <rt-menu>\n <ng-container\n [ngTemplateOutlet]=\"actionsTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: m }\" />\n </rt-menu>\n </div>\n }\n }\n <div rtElem=\"message\" [rtMod]=\"{ own: m.own, deleted: m.deleted }\">\n <p rtElem=\"message-author\" qa-dataid=\"chat-message-author\">{{ m.author }}</p>\n @if (m.deleted) {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-deleted\" rtMod=\"deleted\">\n {{ t().chatMessageDeleted }}\n </p>\n } @else {\n @if (m.delta) {\n <rt-delta-view rtElem=\"message-text\" qa-dataid=\"chat-message-text\" [delta]=\"m.delta\" />\n } @else {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-text\">{{ m.text }}</p>\n }\n @if (m.attachments?.length) {\n @for (att of m.attachments; track att.id) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"att.name || attachmentFallbackName()\"\n (download)=\"downloadAttachment.emit(att)\" />\n </span>\n }\n } @else if (m.fileUrl) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"m.fileName || attachmentFallbackName()\"\n (download)=\"downloadFile.emit(m)\" />\n </span>\n }\n @if (m.deepLink) {\n <span rtElem=\"message-deeplink\">\n <a\n rtButton\n qa-dataid=\"chat-message-deeplink\"\n appearance=\"outlined\"\n icon=\"send\"\n rel=\"noopener\"\n target=\"_blank\"\n [href]=\"m.deepLink\"\n [label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"\n [attr.aria-label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"></a>\n </span>\n }\n }\n <span rtElem=\"message-footer\">\n <span rtElem=\"message-date\" qa-dataid=\"chat-message-date\">\n {{ m.createdAt | date: 'short' : undefined : locale() }}\n </span>\n @if (m.status) {\n <span\n rtElem=\"message-status\"\n qa-dataid=\"chat-message-status\"\n [attr.data-status]=\"m.status\"\n [rtMod]=\"{ status: m.status }\"\n [attr.aria-label]=\"m.status | rtChatStatusLabel\">\n @if (m.status === MessageStatus.Failed) {\n <rt-icon rtElem=\"status-icon\" name=\"exclamation-circle\" size=\"sm\" />\n <rt-icon-button\n qa-dataid=\"chat-message-retry\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRetryAria\"\n [tooltip]=\"t().chatRetryTooltip\"\n (clicked)=\"retryMessage.emit(m)\" />\n } @else {\n <!-- \u0427\u0430\u0441\u044B, \u043F\u043E\u043A\u0430 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0432 \u043F\u0443\u0442\u0438; \u0434\u0430\u043B\u044C\u0448\u0435 \u0434\u0432\u043E\u0439\u043D\u043E\u0439 \u0447\u0435\u043A, \u0446\u0432\u0435\u0442 \u043A\u043E\u0442\u043E\u0440\u043E\u0433\u043E\n (\u0441\u0435\u0440\u044B\u0439/\u0441\u0438\u043D\u0438\u0439) \u0440\u0430\u0437\u043B\u0438\u0447\u0430\u0435\u0442 \u0434\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u043E \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043E. -->\n <rt-icon\n rtElem=\"status-icon\"\n size=\"sm\"\n [name]=\"m.status === MessageStatus.Sending ? 'clock' : 'check-double'\" />\n }\n </span>\n }\n </span>\n </div>\n </div>\n } @empty {\n <rt-note qa-dataid=\"chat-empty-thread\">{{ t().chatEmptyThread }}</rt-note>\n }\n </div>\n }\n @if (!loading() && fetching()) {\n <div rtElem=\"thread-overlay\" qa-dataid=\"chat-thread-overlay\" role=\"status\" [attr.aria-label]=\"t().chatRefreshAria\">\n <rt-spinner diameter=\"32\" />\n </div>\n }\n </div>\n\n @if (canReply()) {\n @if (richComposer()) {\n <rt-message-composer\n rtElem=\"composer-rich\"\n qa-dataid=\"chat-composer-rich\"\n [placeholder]=\"placeholder()\"\n [accept]=\"accept()\"\n [attachments]=\"attachments()\"\n [formatting]=\"formatting()\"\n [toolbar]=\"formattingToolbar()\"\n [sending]=\"sending()\"\n [disabled]=\"loading() || fetching()\"\n [droppedFiles]=\"droppedFiles()\"\n (submitted)=\"onComposerSubmit($event)\" />\n } @else {\n <form rtElem=\"composer\" qa-dataid=\"chat-composer\" [formGroup]=\"replyForm\" (ngSubmit)=\"onSubmit()\">\n @if (attachments() && selectedFiles().length > 0) {\n <div rtElem=\"composer-files\" qa-dataid=\"chat-composer-files\">\n @for (file of selectedFiles(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"chat-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"composerDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n <div rtElem=\"composer-field\" [rtMod]=\"{ attach: attachments() }\">\n @if (attachments()) {\n <input\n #composerFileEl\n qa-dataid=\"chat-composer-file-input\"\n type=\"file\"\n hidden\n multiple\n [attr.accept]=\"accept() || null\"\n (change)=\"onFilesPicked($event)\" />\n <rt-icon-button\n qa-dataid=\"chat-composer-attach\"\n icon=\"paperclip\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"composerDisabled()\"\n (clicked)=\"openFilePicker()\" />\n }\n <textarea\n rtElem=\"composer-input\"\n qa-dataid=\"chat-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"4\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"onComposerKeydown($event)\"></textarea>\n </div>\n <button\n rtButton\n rtElem=\"composer-send\"\n qa-dataid=\"chat-composer-send\"\n type=\"submit\"\n theme=\"primary\"\n appearance=\"filled\"\n [label]=\"t().chatSendLabel\"\n [attr.aria-label]=\"t().chatSendAria\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"></button>\n </form>\n }\n } @else if (replyBlockReason()) {\n <rt-note rtElem=\"reply-block\" qa-dataid=\"chat-reply-block\">{{ replyBlockReason() }}</rt-note>\n }\n\n <!-- \u0421\u043B\u043E\u0442 \u0434\u043E\u043C\u0435\u043D\u043D\u044B\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u044F \u043F\u043E\u0434 \u043A\u043E\u043C\u043F\u043E\u0437\u0435\u0440\u043E\u043C: \u0432 fullscreen\n \u043F\u043E\u043F\u0430\u0434\u0430\u0435\u0442 \u0432\u043D\u0443\u0442\u0440\u044C overlay, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043A\u043D\u043E\u043F\u043A\u0438 \u043E\u0441\u0442\u0430\u044E\u0442\u0441\u044F \u0432\u0438\u0434\u043D\u044B. -->\n <div rtElem=\"footer-slot\" qa-dataid=\"chat-footer\" [rtMod]=\"{ blocked: fetching() }\" [attr.inert]=\"fetching() ? '' : null\">\n <ng-content select=\"[rtChatFooter]\" />\n </div>\n }\n </rt-file-drop>\n</ng-container>\n", styles: ["@layer rt-kit.components{.rt-chat{--rt-chat-bubble-radius: var(--rt-radius-lg);--rt-chat-message-border-width: var(--rt-border-width-thin);--rt-chat-transition-duration: var(--rt-duration-fast);display:flex;flex-direction:column}.rt-chat>.rt-file-drop{display:flex;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-4);min-block-size:0}.rt-chat--expanded{position:fixed;z-index:var(--rt-z-modal);box-sizing:border-box;padding:var(--rt-space-md);background:var(--rt-color-bg-surface);inset:0}.rt-chat--expanded>.rt-file-drop{block-size:100%}@media(width>=1441px){.rt-chat--expanded>.rt-file-drop{inline-size:1000px;margin-inline:auto;max-inline-size:100%}}.rt-chat--expanded .rt-chat__thread-viewport{flex:1 1 auto;min-block-size:0}.rt-chat--expanded .rt-chat__thread{max-height:none}.rt-chat--fill{block-size:100%}.rt-chat--fill .rt-chat__thread-viewport{flex:1 1 auto;min-block-size:0}.rt-chat--fill .rt-chat__thread{max-height:none}.rt-chat__title{margin:0;color:var(--rt-color-text-primary);font-family:var(--rt-font-family-sans);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-bold);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-chat__thread-viewport{position:relative;display:flex;flex-direction:column;contain:inline-size;min-block-size:0}.rt-chat__thread{display:flex;max-height:280px;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-4);min-block-size:0;overflow-y:auto}.rt-chat__thread--frozen{overflow-y:hidden}.rt-chat__thread-overlay{position:absolute;z-index:1;display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--rt-color-bg-surface) 60%,transparent);inset:0}.rt-chat__footer-slot{display:flex;flex-direction:column}.rt-chat__footer-slot:empty{display:none}.rt-chat__footer-slot--blocked{opacity:.6;pointer-events:none}.rt-chat__message-row{display:flex;max-width:min(80%,480px);align-items:center;align-self:flex-start;gap:var(--rt-space-2)}.rt-chat__message-row--own{align-self:flex-end}.rt-chat__message-row:hover .rt-chat__message-delete,.rt-chat__message-row:focus-within .rt-chat__message-delete,.rt-chat__message-row:hover .rt-chat__message-actions,.rt-chat__message-row:focus-within .rt-chat__message-actions{opacity:1;pointer-events:auto}.rt-chat__message{display:flex;min-width:0;flex:0 1 auto;flex-direction:column;padding:var(--rt-space-2);border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;background:var(--rt-chat-bubble-in-bg);gap:var(--rt-space-2)}.rt-chat__message--own{border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);background:var(--rt-chat-bubble-own-bg)}.rt-chat__message--deleted{border:var(--rt-chat-message-border-width) dashed var(--rt-color-border-default);background:transparent}.rt-chat__message-author{margin:0;color:var(--rt-chat-bubble-in-author);font-size:var(--rt-text-2xs);font-weight:var(--rt-font-weight-bold);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-chat__message--own .rt-chat__message-author{color:var(--rt-chat-bubble-own-author)}.rt-chat__message-text{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-regular);line-height:var(--rt-leading-snug);white-space:pre-wrap}.rt-chat__message-text--deleted{color:var(--rt-color-text-muted);font-style:italic}.rt-chat__message-delete,.rt-chat__message-actions{flex:0 0 auto;opacity:0;pointer-events:none;transition:opacity var(--rt-chat-transition-duration) ease}.rt-chat__message-attachment{display:block}.rt-chat__message-footer{display:flex;align-items:center;gap:var(--rt-space-1)}.rt-chat__message-date{color:var(--rt-chat-bubble-date);font-size:var(--rt-text-xs);line-height:var(--rt-leading-none)}.rt-chat__message-status{display:inline-flex;align-items:center;color:var(--rt-color-text-muted);gap:var(--rt-space-0-5)}.rt-chat__message-status--status--read{color:var(--rt-chat-status-read)}.rt-chat__message-status--status--failed{color:var(--rt-color-state-danger)}.rt-chat__status-icon{font-size:var(--rt-text-sm)}.rt-chat__message-skeleton{display:flex;max-width:min(80%,480px);flex-direction:column;align-self:flex-start;padding:var(--rt-space-2);border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;background:var(--rt-chat-bubble-in-bg);gap:var(--rt-space-1)}.rt-chat__message-skeleton--own{align-self:flex-end;border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);background:var(--rt-chat-bubble-own-bg)}.rt-chat__skeleton-line{display:block}.rt-chat__message-deeplink{display:flex;justify-content:flex-start;margin-top:var(--rt-space-1)}.rt-chat__composer,.rt-chat__composer-rich,.rt-chat__reply-block{margin-top:var(--rt-space-4)}.rt-chat__composer{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-chat__composer-files{display:flex;flex-wrap:wrap;gap:var(--rt-space-2)}.rt-chat__composer-field{display:flex;box-sizing:border-box;align-items:center;border:var(--rt-input-border-width) solid var(--rt-input-color-border);border-radius:var(--rt-input-radius);background-color:var(--rt-input-color-bg);gap:var(--rt-space-1);min-block-size:var(--rt-input-height);padding-inline:var(--rt-input-padding-x);transition:var(--rt-input-transition)}.rt-chat__composer-field:focus-within{border-color:var(--rt-input-color-border-focus);box-shadow:var(--rt-input-focus-shadow)}.rt-chat__composer-field--attach{padding-inline-start:var(--rt-space-1)}.rt-chat__composer-input{box-sizing:content-box;flex:1 1 auto;border:0;background:transparent;color:var(--rt-input-color-text);font-family:inherit;font-size:var(--rt-input-font-size);inline-size:100%;line-height:var(--rt-textarea-line-height);padding-block:var(--rt-space-2);resize:none}.rt-chat__composer-input::placeholder{color:var(--rt-input-color-text-placeholder);opacity:1}.rt-chat__composer-input:focus-visible{outline:none}.rt-chat__composer-input:disabled{cursor:not-allowed}.rt-chat__composer-send{inline-size:100%}}\n"], dependencies: [{ kind: "directive", type:
966
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtChatComponent, isStandalone: true, selector: "rt-chat", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fetching: { classPropertyName: "fetching", publicName: "fetching", isSignal: true, isRequired: false, transformFunction: null }, canReply: { classPropertyName: "canReply", publicName: "canReply", isSignal: true, isRequired: false, transformFunction: null }, replyBlockReason: { classPropertyName: "replyBlockReason", publicName: "replyBlockReason", isSignal: true, isRequired: false, transformFunction: null }, sending: { classPropertyName: "sending", publicName: "sending", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, emptyHint: { classPropertyName: "emptyHint", publicName: "emptyHint", isSignal: true, isRequired: false, transformFunction: null }, hasThread: { classPropertyName: "hasThread", publicName: "hasThread", isSignal: true, isRequired: false, transformFunction: null }, attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, richComposer: { classPropertyName: "richComposer", publicName: "richComposer", isSignal: true, isRequired: false, transformFunction: null }, formatting: { classPropertyName: "formatting", publicName: "formatting", isSignal: true, isRequired: false, transformFunction: null }, formattingToolbar: { classPropertyName: "formattingToolbar", publicName: "formattingToolbar", isSignal: true, isRequired: false, transformFunction: null }, fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null }, showRefresh: { classPropertyName: "showRefresh", publicName: "showRefresh", isSignal: true, isRequired: false, transformFunction: null }, showExpand: { classPropertyName: "showExpand", publicName: "showExpand", isSignal: true, isRequired: false, transformFunction: null }, typingText: { classPropertyName: "typingText", publicName: "typingText", isSignal: true, isRequired: false, transformFunction: null }, messageHasActions: { classPropertyName: "messageHasActions", publicName: "messageHasActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { send: "send", refresh: "refresh", downloadFile: "downloadFile", downloadAttachment: "downloadAttachment", typing: "typing", expandedChange: "expandedChange", deleteMessage: "deleteMessage", retryMessage: "retryMessage" }, host: { properties: { "class.rt-chat--expanded": "expanded()", "class.rt-chat--fill": "fill()" }, classAttribute: "rt-chat" }, queries: [{ propertyName: "messageActions", first: true, predicate: RtChatMessageActionsDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "thread", first: true, predicate: ["thread"], descendants: true, isSignal: true }, { propertyName: "composerFileEl", first: true, predicate: ["composerFileEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container rtBlock=\"rt-chat\">\n <rt-file-drop\n [overlayLabel]=\"t().chatDropOverlay\"\n [accept]=\"accept()\"\n [disabled]=\"dropDisabled()\"\n (filesDropped)=\"onFilesDropped($event)\">\n @if (showHeader()) {\n <rt-toolbar rtElem=\"header\" dense>\n <ng-template rtToolbarLeft>\n <h3 rtElem=\"title\" qa-dataid=\"chat-title\">{{ title() }}</h3>\n </ng-template>\n <ng-template rtToolbarRight>\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"chat-refresh\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRefreshAria\"\n [tooltip]=\"t().chatRefreshTooltip\"\n [loading]=\"fetching()\"\n [disabled]=\"!hasThread()\"\n (clicked)=\"refresh.emit()\" />\n }\n @if (showExpand()) {\n <rt-icon-button\n qa-dataid=\"chat-expand\"\n variant=\"ghost\"\n [icon]=\"expanded() ? 'window-minimize' : 'window-maximize'\"\n [ariaLabel]=\"expandLabel()\"\n [tooltip]=\"expandLabel()\"\n (clicked)=\"toggleExpand()\" />\n }\n <ng-content select=\"[rtChatHeaderActions]\" />\n </ng-template>\n </rt-toolbar>\n }\n\n @if (!hasThread()) {\n <rt-note qa-dataid=\"chat-empty-hint\">{{ emptyHint() }}</rt-note>\n } @else {\n <div rtElem=\"thread-viewport\" qa-dataid=\"chat-thread-viewport\">\n @if (loading()) {\n <!-- \u0421\u043A\u0435\u043B\u0435\u0442\u043E\u043D \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u0442 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0443 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F (\u0430\u0432\u0442\u043E\u0440 \u2192 \u0442\u0435\u043A\u0441\u0442 \u2192 \u0434\u0430\u0442\u0430),\n \u0447\u0435\u0440\u0435\u0434\u0443\u044F \u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u0435, \u0447\u0442\u043E\u0431\u044B \u0442\u0440\u0435\u0434 \u043D\u0435 \u00AB\u043F\u0440\u044B\u0433\u0430\u043B\u00BB \u043F\u0440\u0438 \u043F\u043E\u0434\u043C\u0435\u043D\u0435 \u043D\u0430 \u0440\u0435\u0430\u043B\u044C\u043D\u044B\u0435. -->\n <div rtElem=\"thread\" qa-dataid=\"chat-thread-skeleton\">\n @for (row of skeletonRows; track row; let even = $even) {\n <div rtElem=\"message-skeleton\" qa-dataid=\"chat-message-skeleton\" [rtMod]=\"{ own: even }\">\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"72px\" height=\"10px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"100%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"55%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"56px\" height=\"10px\" [isLoading]=\"true\" />\n </div>\n }\n </div>\n } @else {\n <div\n #thread\n rtElem=\"thread\"\n qa-dataid=\"chat-thread\"\n [rtMod]=\"{ frozen: fetching() }\"\n [attr.aria-busy]=\"fetching() ? 'true' : null\"\n (scroll)=\"onThreadScroll()\">\n @for (m of messages(); track m.id) {\n <div\n rtElem=\"message-row\"\n qa-dataid=\"chat-message\"\n [attr.data-own]=\"m.own\"\n [attr.data-status]=\"m.status || null\"\n [attr.data-deleted]=\"m.deleted || null\"\n [rtMod]=\"{ own: m.own }\">\n @if (m.canDelete && !m.deleted) {\n @if (m.deleteConfirm) {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n [rtConfirm]=\"m.deleteConfirm\"\n (confirmed)=\"deleteMessage.emit(m)\" />\n } @else {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n (clicked)=\"deleteMessage.emit(m)\" />\n }\n }\n @if (messageActions()?.template; as actionsTpl) {\n @if (m | rtChatMessageHasActions: messageHasActions()) {\n <div rtElem=\"message-actions\" qa-dataid=\"chat-message-actions\">\n <rt-menu>\n <ng-container\n [ngTemplateOutlet]=\"actionsTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: m }\" />\n </rt-menu>\n </div>\n }\n }\n <div rtElem=\"message\" [rtMod]=\"{ own: m.own, deleted: m.deleted }\">\n <p rtElem=\"message-author\" qa-dataid=\"chat-message-author\">{{ m.author }}</p>\n @if (m.deleted) {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-deleted\" rtMod=\"deleted\">\n {{ t().chatMessageDeleted }}\n </p>\n } @else {\n @if (m.delta) {\n <rt-delta-view rtElem=\"message-text\" qa-dataid=\"chat-message-text\" [delta]=\"m.delta\" />\n } @else {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-text\">{{ m.text }}</p>\n }\n @if (m.attachments?.length) {\n @for (att of m.attachments; track att.id) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"att.name || attachmentFallbackName()\"\n (download)=\"downloadAttachment.emit(att)\" />\n </span>\n }\n } @else if (m.fileUrl) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"m.fileName || attachmentFallbackName()\"\n (download)=\"downloadFile.emit(m)\" />\n </span>\n }\n @if (m.deepLink) {\n <span rtElem=\"message-deeplink\">\n <a\n rtButton\n qa-dataid=\"chat-message-deeplink\"\n appearance=\"outlined\"\n icon=\"send\"\n rel=\"noopener\"\n target=\"_blank\"\n [href]=\"m.deepLink\"\n [label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"\n [attr.aria-label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"></a>\n </span>\n }\n }\n <span rtElem=\"message-footer\">\n <span rtElem=\"message-date\" qa-dataid=\"chat-message-date\">\n {{ m.createdAt | date: 'short' : undefined : locale() }}\n </span>\n @if (m.status) {\n <span\n rtElem=\"message-status\"\n qa-dataid=\"chat-message-status\"\n [attr.data-status]=\"m.status\"\n [rtMod]=\"{ status: m.status }\"\n [attr.aria-label]=\"m.status | rtChatStatusLabel\">\n @if (m.status === MessageStatus.Failed) {\n <rt-icon rtElem=\"status-icon\" name=\"exclamation-circle\" size=\"sm\" />\n <rt-icon-button\n qa-dataid=\"chat-message-retry\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRetryAria\"\n [tooltip]=\"t().chatRetryTooltip\"\n (clicked)=\"retryMessage.emit(m)\" />\n } @else {\n <!-- \u0427\u0430\u0441\u044B, \u043F\u043E\u043A\u0430 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0432 \u043F\u0443\u0442\u0438; \u0434\u0430\u043B\u044C\u0448\u0435 \u0434\u0432\u043E\u0439\u043D\u043E\u0439 \u0447\u0435\u043A, \u0446\u0432\u0435\u0442 \u043A\u043E\u0442\u043E\u0440\u043E\u0433\u043E\n (\u0441\u0435\u0440\u044B\u0439/\u0441\u0438\u043D\u0438\u0439) \u0440\u0430\u0437\u043B\u0438\u0447\u0430\u0435\u0442 \u0434\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u043E \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043E. -->\n <rt-icon\n rtElem=\"status-icon\"\n size=\"sm\"\n [name]=\"m.status === MessageStatus.Sending ? 'clock' : 'check-double'\" />\n }\n </span>\n }\n </span>\n </div>\n </div>\n } @empty {\n <rt-note qa-dataid=\"chat-empty-thread\">{{ t().chatEmptyThread }}</rt-note>\n }\n </div>\n }\n @if (!loading() && fetching()) {\n <div rtElem=\"thread-overlay\" qa-dataid=\"chat-thread-overlay\" role=\"status\" [attr.aria-label]=\"t().chatRefreshAria\">\n <rt-spinner diameter=\"32\" />\n </div>\n }\n <div rtElem=\"typing\" qa-dataid=\"chat-typing\" aria-live=\"polite\" [rtMod]=\"{ shown: typingText() !== '' }\">\n {{ typingText() }}\n </div>\n </div>\n\n @if (canReply()) {\n @if (richComposer()) {\n <rt-message-composer\n rtElem=\"composer-rich\"\n qa-dataid=\"chat-composer-rich\"\n [placeholder]=\"placeholder()\"\n [accept]=\"accept()\"\n [attachments]=\"attachments()\"\n [formatting]=\"formatting()\"\n [toolbar]=\"formattingToolbar()\"\n [sending]=\"sending()\"\n [disabled]=\"loading() || fetching()\"\n [droppedFiles]=\"droppedFiles()\"\n (submitted)=\"onComposerSubmit($event)\"\n (input)=\"onReplyInput($event)\" />\n } @else {\n <form\n rtElem=\"composer\"\n qa-dataid=\"chat-composer\"\n [formGroup]=\"replyForm\"\n (ngSubmit)=\"onSubmit()\"\n (input)=\"onReplyInput($event)\">\n @if (attachments() && selectedFiles().length > 0) {\n <div rtElem=\"composer-files\" qa-dataid=\"chat-composer-files\">\n @for (file of selectedFiles(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"chat-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"composerDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n <div rtElem=\"composer-field\" [rtMod]=\"{ attach: attachments() }\">\n @if (attachments()) {\n <input\n #composerFileEl\n qa-dataid=\"chat-composer-file-input\"\n type=\"file\"\n hidden\n multiple\n [attr.accept]=\"accept() || null\"\n (change)=\"onFilesPicked($event)\" />\n <rt-icon-button\n qa-dataid=\"chat-composer-attach\"\n icon=\"paperclip\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"composerDisabled()\"\n (clicked)=\"openFilePicker()\" />\n }\n <textarea\n rtElem=\"composer-input\"\n qa-dataid=\"chat-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"4\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"onComposerKeydown($event)\"></textarea>\n </div>\n <button\n rtButton\n rtElem=\"composer-send\"\n qa-dataid=\"chat-composer-send\"\n type=\"submit\"\n theme=\"primary\"\n appearance=\"filled\"\n [label]=\"t().chatSendLabel\"\n [attr.aria-label]=\"t().chatSendAria\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"></button>\n </form>\n }\n } @else if (replyBlockReason()) {\n <rt-note rtElem=\"reply-block\" qa-dataid=\"chat-reply-block\">{{ replyBlockReason() }}</rt-note>\n }\n\n <!-- \u0421\u043B\u043E\u0442 \u0434\u043E\u043C\u0435\u043D\u043D\u044B\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u044F \u043F\u043E\u0434 \u043A\u043E\u043C\u043F\u043E\u0437\u0435\u0440\u043E\u043C: \u0432 fullscreen\n \u043F\u043E\u043F\u0430\u0434\u0430\u0435\u0442 \u0432\u043D\u0443\u0442\u0440\u044C overlay, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043A\u043D\u043E\u043F\u043A\u0438 \u043E\u0441\u0442\u0430\u044E\u0442\u0441\u044F \u0432\u0438\u0434\u043D\u044B. -->\n <div rtElem=\"footer-slot\" qa-dataid=\"chat-footer\" [rtMod]=\"{ blocked: fetching() }\" [attr.inert]=\"fetching() ? '' : null\">\n <ng-content select=\"[rtChatFooter]\" />\n </div>\n }\n </rt-file-drop>\n</ng-container>\n", styles: ["@layer rt-kit.components{.rt-chat{--rt-chat-bubble-radius: var(--rt-radius-lg);--rt-chat-message-border-width: var(--rt-border-width-thin);--rt-chat-transition-duration: var(--rt-duration-fast);--rt-chat-typing-radius: var(--rt-radius-full);--rt-chat-typing-shadow: var(--rt-shadow-sm);display:flex;flex-direction:column}.rt-chat>.rt-file-drop{display:flex;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-4);min-block-size:0}.rt-chat--expanded{position:fixed;z-index:var(--rt-z-modal);box-sizing:border-box;padding:var(--rt-space-md);background:var(--rt-color-bg-surface);inset:0}.rt-chat--expanded>.rt-file-drop{block-size:100%}@media(width>=1441px){.rt-chat--expanded>.rt-file-drop{inline-size:1000px;margin-inline:auto;max-inline-size:100%}}.rt-chat--expanded .rt-chat__thread-viewport{flex:1 1 auto;min-block-size:0}.rt-chat--expanded .rt-chat__thread{max-height:none}.rt-chat--fill{block-size:100%}.rt-chat--fill .rt-chat__thread-viewport{flex:1 1 auto;min-block-size:0}.rt-chat--fill .rt-chat__thread{max-height:none}.rt-chat__title{margin:0;color:var(--rt-color-text-primary);font-family:var(--rt-font-family-sans);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-bold);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-chat__thread-viewport{position:relative;display:flex;flex-direction:column;contain:inline-size;min-block-size:0}.rt-chat__thread{display:flex;max-height:280px;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-4);min-block-size:0;overflow-y:auto}.rt-chat__thread--frozen{overflow-y:hidden}.rt-chat__thread-overlay{position:absolute;z-index:1;display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--rt-color-bg-surface) 60%,transparent);inset:0}.rt-chat__typing{position:absolute;z-index:1;bottom:var(--rt-space-1);left:var(--rt-space-2);box-sizing:border-box;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);max-inline-size:calc(100% - 2 * var(--rt-space-2));overflow-wrap:anywhere;pointer-events:none}.rt-chat__typing--shown{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-chat-typing-radius);background:var(--rt-color-bg-surface);box-shadow:var(--rt-chat-typing-shadow)}.rt-chat__footer-slot{display:flex;flex-direction:column}.rt-chat__footer-slot:empty{display:none}.rt-chat__footer-slot--blocked{opacity:.6;pointer-events:none}.rt-chat__message-row{display:flex;max-width:min(80%,480px);align-items:center;align-self:flex-start;gap:var(--rt-space-2)}.rt-chat__message-row--own{align-self:flex-end}.rt-chat__message-row:hover .rt-chat__message-delete,.rt-chat__message-row:focus-within .rt-chat__message-delete,.rt-chat__message-row:hover .rt-chat__message-actions,.rt-chat__message-row:focus-within .rt-chat__message-actions{opacity:1;pointer-events:auto}.rt-chat__message{display:flex;min-width:0;flex:0 1 auto;flex-direction:column;padding:var(--rt-space-2);border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;background:var(--rt-chat-bubble-in-bg);gap:var(--rt-space-2)}.rt-chat__message--own{border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);background:var(--rt-chat-bubble-own-bg)}.rt-chat__message--deleted{border:var(--rt-chat-message-border-width) dashed var(--rt-color-border-default);background:transparent}.rt-chat__message-author{margin:0;color:var(--rt-chat-bubble-in-author);font-size:var(--rt-text-2xs);font-weight:var(--rt-font-weight-bold);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-chat__message--own .rt-chat__message-author{color:var(--rt-chat-bubble-own-author)}.rt-chat__message-text{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-regular);line-height:var(--rt-leading-snug);white-space:pre-wrap}.rt-chat__message-text--deleted{color:var(--rt-color-text-muted);font-style:italic}.rt-chat__message-delete,.rt-chat__message-actions{flex:0 0 auto;opacity:0;pointer-events:none;transition:opacity var(--rt-chat-transition-duration) ease}.rt-chat__message-attachment{display:block}.rt-chat__message-footer{display:flex;align-items:center;gap:var(--rt-space-1)}.rt-chat__message-date{color:var(--rt-chat-bubble-date);font-size:var(--rt-text-xs);line-height:var(--rt-leading-none)}.rt-chat__message-status{display:inline-flex;align-items:center;color:var(--rt-color-text-muted);gap:var(--rt-space-0-5)}.rt-chat__message-status--status--read{color:var(--rt-chat-status-read)}.rt-chat__message-status--status--failed{color:var(--rt-color-state-danger)}.rt-chat__status-icon{font-size:var(--rt-text-sm)}.rt-chat__message-skeleton{display:flex;max-width:min(80%,480px);flex-direction:column;align-self:flex-start;padding:var(--rt-space-2);border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;background:var(--rt-chat-bubble-in-bg);gap:var(--rt-space-1)}.rt-chat__message-skeleton--own{align-self:flex-end;border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);background:var(--rt-chat-bubble-own-bg)}.rt-chat__skeleton-line{display:block}.rt-chat__message-deeplink{display:flex;justify-content:flex-start;margin-top:var(--rt-space-1)}.rt-chat__composer,.rt-chat__composer-rich,.rt-chat__reply-block{margin-top:var(--rt-space-4)}.rt-chat__composer{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-chat__composer-files{display:flex;flex-wrap:wrap;gap:var(--rt-space-2)}.rt-chat__composer-field{display:flex;box-sizing:border-box;align-items:center;border:var(--rt-input-border-width) solid var(--rt-input-color-border);border-radius:var(--rt-input-radius);background-color:var(--rt-input-color-bg);gap:var(--rt-space-1);min-block-size:var(--rt-input-height);padding-inline:var(--rt-input-padding-x);transition:var(--rt-input-transition)}.rt-chat__composer-field:focus-within{border-color:var(--rt-input-color-border-focus);box-shadow:var(--rt-input-focus-shadow)}.rt-chat__composer-field--attach{padding-inline-start:var(--rt-space-1)}.rt-chat__composer-input{box-sizing:content-box;flex:1 1 auto;border:0;background:transparent;color:var(--rt-input-color-text);font-family:inherit;font-size:var(--rt-input-font-size);inline-size:100%;line-height:var(--rt-textarea-line-height);padding-block:var(--rt-space-2);resize:none}.rt-chat__composer-input::placeholder{color:var(--rt-input-color-text-placeholder);opacity:1}.rt-chat__composer-input:focus-visible{outline:none}.rt-chat__composer-input:disabled{cursor:not-allowed}.rt-chat__composer-send{inline-size:100%}}\n"], dependencies: [{ kind: "directive", type:
912
967
  // Angular
913
968
  CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type:
914
969
  // standalone components / directives
915
- RtButtonDirective, selector: "button[rtButton], a[rtButton]", inputs: ["label", "icon", "iconPos", "theme", "appearance", "size", "loading", "loadingIcon", "pressed"] }, { kind: "directive", type: RtConfirmDirective, selector: "[rtConfirm]", inputs: ["rtConfirm", "rtConfirmTitle", "rtConfirmLabel", "rtConfirmCancelLabel", "rtConfirmTone", "rtConfirmDisabled"], outputs: ["confirmed"], exportAs: ["rtConfirm"] }, { kind: "component", type: RtDeltaViewComponent, selector: "rt-delta-view", inputs: ["delta"] }, { kind: "component", type: RtFileCardComponent, selector: "rt-file-card", inputs: ["name", "sizeBytes", "size", "showDownload", "showRemove", "showRename", "disabled"], outputs: ["download", "removed", "rename"] }, { kind: "component", type: RtFileDropComponent, selector: "rt-file-drop", inputs: ["disabled", "overlayLabel", "zones", "accept"], outputs: ["filesDropped", "zoneFilesDropped", "draggingChange"] }, { kind: "component", type: RtIconButtonComponent, selector: "rt-icon-button", inputs: ["icon", "ariaLabel", "variant", "iconColor", "iconFill", "size", "iconSize", "type", "tooltip", "tabIndex", "loading", "disabled", "active", "indicator"], outputs: ["clicked"] }, { kind: "component", type: RtIconComponent, selector: "rt-icon", inputs: ["name", "size", "color", "fill", "rotate"] }, { kind: "component", type: RtMenuComponent, selector: "rt-menu", inputs: ["icon", "ariaLabel", "align", "panelClass", "size", "disabled"], outputs: ["openedChange"] }, { kind: "component", type: RtMessageComposerComponent, selector: "rt-message-composer", inputs: ["placeholder", "accept", "hint", "attachments", "sending", "stoppable", "disabled", "formatting", "toolbar", "minRows", "maxRows", "droppedFiles", "text"], outputs: ["submitted", "textChange", "stopped"] }, { kind: "component", type: RtNoteComponent, selector: "rt-note" }, { kind: "component", type: RtSkeletonWrapperComponent, selector: "rt-skeleton-wrapper", inputs: ["width", "height", "shape", "size", "radius", "animation", "isLoading"] }, { kind: "component", type: RtSpinnerComponent, selector: "rt-spinner", inputs: ["diameter", "color"] }, { kind: "component", type: RtToolbarComponent, selector: "rt-toolbar", inputs: ["dense"] }, { kind: "directive", type: RtToolbarLeftDirective, selector: "[rtToolbarLeft]" }, { kind: "directive", type: RtToolbarRightDirective, selector: "[rtToolbarRight]" }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: RtChatStatusLabelPipe, name: "rtChatStatusLabel" }, { kind: "pipe", type: RtChatMessageHasActionsPipe, name: "rtChatMessageHasActions" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
970
+ RtButtonDirective, selector: "button[rtButton], a[rtButton]", inputs: ["label", "icon", "iconPos", "theme", "appearance", "size", "loading", "loadingIcon", "loadingLabel", "pressed"] }, { kind: "directive", type: RtConfirmDirective, selector: "[rtConfirm]", inputs: ["rtConfirm", "rtConfirmTitle", "rtConfirmLabel", "rtConfirmCancelLabel", "rtConfirmTone", "rtConfirmDisabled"], outputs: ["confirmed"], exportAs: ["rtConfirm"] }, { kind: "component", type: RtDeltaViewComponent, selector: "rt-delta-view", inputs: ["delta"] }, { kind: "component", type: RtFileCardComponent, selector: "rt-file-card", inputs: ["name", "sizeBytes", "size", "showDownload", "showRemove", "showRename", "disabled"], outputs: ["download", "removed", "rename"] }, { kind: "component", type: RtFileDropComponent, selector: "rt-file-drop", inputs: ["disabled", "overlayLabel", "zones", "accept"], outputs: ["filesDropped", "zoneFilesDropped", "draggingChange"] }, { kind: "component", type: RtIconButtonComponent, selector: "rt-icon-button", inputs: ["icon", "glyph", "ariaLabel", "variant", "iconColor", "iconFill", "size", "iconSize", "type", "tooltip", "tabIndex", "loading", "disabled", "active", "indicator"], outputs: ["clicked"] }, { kind: "component", type: RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "size", "color", "fill", "spin", "rotate"] }, { kind: "component", type: RtMenuComponent, selector: "rt-menu", inputs: ["icon", "ariaLabel", "align", "panelClass", "size", "disabled"], outputs: ["openedChange"] }, { kind: "component", type: RtMessageComposerComponent, selector: "rt-message-composer", inputs: ["placeholder", "accept", "hint", "attachments", "sending", "stoppable", "disabled", "formatting", "toolbar", "minRows", "maxRows", "droppedFiles", "text"], outputs: ["submitted", "textChange", "stopped"] }, { kind: "component", type: RtNoteComponent, selector: "rt-note" }, { kind: "component", type: RtSkeletonWrapperComponent, selector: "rt-skeleton-wrapper", inputs: ["width", "height", "shape", "size", "radius", "animation", "isLoading"] }, { kind: "component", type: RtSpinnerComponent, selector: "rt-spinner", inputs: ["diameter", "color", "appearance", "overlay", "backdrop", "plate"] }, { kind: "component", type: RtToolbarComponent, selector: "rt-toolbar", inputs: ["dense"] }, { kind: "directive", type: RtToolbarLeftDirective, selector: "[rtToolbarLeft]" }, { kind: "directive", type: RtToolbarRightDirective, selector: "[rtToolbarRight]" }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: RtChatStatusLabelPipe, name: "rtChatStatusLabel" }, { kind: "pipe", type: RtChatMessageHasActionsPipe, name: "rtChatMessageHasActions" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
916
971
  }
917
972
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtChatComponent, decorators: [{
918
973
  type: Component,
@@ -947,8 +1002,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
947
1002
  class: BEM_BLOCK,
948
1003
  '[class.rt-chat--expanded]': 'expanded()',
949
1004
  '[class.rt-chat--fill]': 'fill()',
950
- }, template: "<ng-container rtBlock=\"rt-chat\">\n <rt-file-drop\n [overlayLabel]=\"t().chatDropOverlay\"\n [accept]=\"accept()\"\n [disabled]=\"dropDisabled()\"\n (filesDropped)=\"onFilesDropped($event)\">\n @if (showHeader()) {\n <rt-toolbar rtElem=\"header\" dense>\n <ng-template rtToolbarLeft>\n <h3 rtElem=\"title\" qa-dataid=\"chat-title\">{{ title() }}</h3>\n </ng-template>\n <ng-template rtToolbarRight>\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"chat-refresh\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRefreshAria\"\n [tooltip]=\"t().chatRefreshTooltip\"\n [loading]=\"fetching()\"\n [disabled]=\"!hasThread()\"\n (clicked)=\"refresh.emit()\" />\n }\n @if (showExpand()) {\n <rt-icon-button\n qa-dataid=\"chat-expand\"\n variant=\"ghost\"\n [icon]=\"expanded() ? 'window-minimize' : 'window-maximize'\"\n [ariaLabel]=\"expandLabel()\"\n [tooltip]=\"expandLabel()\"\n (clicked)=\"toggleExpand()\" />\n }\n <ng-content select=\"[rtChatHeaderActions]\" />\n </ng-template>\n </rt-toolbar>\n }\n\n @if (!hasThread()) {\n <rt-note qa-dataid=\"chat-empty-hint\">{{ emptyHint() }}</rt-note>\n } @else {\n <div rtElem=\"thread-viewport\" qa-dataid=\"chat-thread-viewport\">\n @if (loading()) {\n <!-- \u0421\u043A\u0435\u043B\u0435\u0442\u043E\u043D \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u0442 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0443 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F (\u0430\u0432\u0442\u043E\u0440 \u2192 \u0442\u0435\u043A\u0441\u0442 \u2192 \u0434\u0430\u0442\u0430),\n \u0447\u0435\u0440\u0435\u0434\u0443\u044F \u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u0435, \u0447\u0442\u043E\u0431\u044B \u0442\u0440\u0435\u0434 \u043D\u0435 \u00AB\u043F\u0440\u044B\u0433\u0430\u043B\u00BB \u043F\u0440\u0438 \u043F\u043E\u0434\u043C\u0435\u043D\u0435 \u043D\u0430 \u0440\u0435\u0430\u043B\u044C\u043D\u044B\u0435. -->\n <div rtElem=\"thread\" qa-dataid=\"chat-thread-skeleton\">\n @for (row of skeletonRows; track row; let even = $even) {\n <div rtElem=\"message-skeleton\" qa-dataid=\"chat-message-skeleton\" [rtMod]=\"{ own: even }\">\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"72px\" height=\"10px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"100%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"55%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"56px\" height=\"10px\" [isLoading]=\"true\" />\n </div>\n }\n </div>\n } @else {\n <div\n #thread\n rtElem=\"thread\"\n qa-dataid=\"chat-thread\"\n [rtMod]=\"{ frozen: fetching() }\"\n [attr.aria-busy]=\"fetching() ? 'true' : null\"\n (scroll)=\"onThreadScroll()\">\n @for (m of messages(); track m.id) {\n <div\n rtElem=\"message-row\"\n qa-dataid=\"chat-message\"\n [attr.data-own]=\"m.own\"\n [attr.data-status]=\"m.status || null\"\n [attr.data-deleted]=\"m.deleted || null\"\n [rtMod]=\"{ own: m.own }\">\n @if (m.canDelete && !m.deleted) {\n @if (m.deleteConfirm) {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n [rtConfirm]=\"m.deleteConfirm\"\n (confirmed)=\"deleteMessage.emit(m)\" />\n } @else {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n (clicked)=\"deleteMessage.emit(m)\" />\n }\n }\n @if (messageActions()?.template; as actionsTpl) {\n @if (m | rtChatMessageHasActions: messageHasActions()) {\n <div rtElem=\"message-actions\" qa-dataid=\"chat-message-actions\">\n <rt-menu>\n <ng-container\n [ngTemplateOutlet]=\"actionsTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: m }\" />\n </rt-menu>\n </div>\n }\n }\n <div rtElem=\"message\" [rtMod]=\"{ own: m.own, deleted: m.deleted }\">\n <p rtElem=\"message-author\" qa-dataid=\"chat-message-author\">{{ m.author }}</p>\n @if (m.deleted) {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-deleted\" rtMod=\"deleted\">\n {{ t().chatMessageDeleted }}\n </p>\n } @else {\n @if (m.delta) {\n <rt-delta-view rtElem=\"message-text\" qa-dataid=\"chat-message-text\" [delta]=\"m.delta\" />\n } @else {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-text\">{{ m.text }}</p>\n }\n @if (m.attachments?.length) {\n @for (att of m.attachments; track att.id) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"att.name || attachmentFallbackName()\"\n (download)=\"downloadAttachment.emit(att)\" />\n </span>\n }\n } @else if (m.fileUrl) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"m.fileName || attachmentFallbackName()\"\n (download)=\"downloadFile.emit(m)\" />\n </span>\n }\n @if (m.deepLink) {\n <span rtElem=\"message-deeplink\">\n <a\n rtButton\n qa-dataid=\"chat-message-deeplink\"\n appearance=\"outlined\"\n icon=\"send\"\n rel=\"noopener\"\n target=\"_blank\"\n [href]=\"m.deepLink\"\n [label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"\n [attr.aria-label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"></a>\n </span>\n }\n }\n <span rtElem=\"message-footer\">\n <span rtElem=\"message-date\" qa-dataid=\"chat-message-date\">\n {{ m.createdAt | date: 'short' : undefined : locale() }}\n </span>\n @if (m.status) {\n <span\n rtElem=\"message-status\"\n qa-dataid=\"chat-message-status\"\n [attr.data-status]=\"m.status\"\n [rtMod]=\"{ status: m.status }\"\n [attr.aria-label]=\"m.status | rtChatStatusLabel\">\n @if (m.status === MessageStatus.Failed) {\n <rt-icon rtElem=\"status-icon\" name=\"exclamation-circle\" size=\"sm\" />\n <rt-icon-button\n qa-dataid=\"chat-message-retry\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRetryAria\"\n [tooltip]=\"t().chatRetryTooltip\"\n (clicked)=\"retryMessage.emit(m)\" />\n } @else {\n <!-- \u0427\u0430\u0441\u044B, \u043F\u043E\u043A\u0430 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0432 \u043F\u0443\u0442\u0438; \u0434\u0430\u043B\u044C\u0448\u0435 \u0434\u0432\u043E\u0439\u043D\u043E\u0439 \u0447\u0435\u043A, \u0446\u0432\u0435\u0442 \u043A\u043E\u0442\u043E\u0440\u043E\u0433\u043E\n (\u0441\u0435\u0440\u044B\u0439/\u0441\u0438\u043D\u0438\u0439) \u0440\u0430\u0437\u043B\u0438\u0447\u0430\u0435\u0442 \u0434\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u043E \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043E. -->\n <rt-icon\n rtElem=\"status-icon\"\n size=\"sm\"\n [name]=\"m.status === MessageStatus.Sending ? 'clock' : 'check-double'\" />\n }\n </span>\n }\n </span>\n </div>\n </div>\n } @empty {\n <rt-note qa-dataid=\"chat-empty-thread\">{{ t().chatEmptyThread }}</rt-note>\n }\n </div>\n }\n @if (!loading() && fetching()) {\n <div rtElem=\"thread-overlay\" qa-dataid=\"chat-thread-overlay\" role=\"status\" [attr.aria-label]=\"t().chatRefreshAria\">\n <rt-spinner diameter=\"32\" />\n </div>\n }\n </div>\n\n @if (canReply()) {\n @if (richComposer()) {\n <rt-message-composer\n rtElem=\"composer-rich\"\n qa-dataid=\"chat-composer-rich\"\n [placeholder]=\"placeholder()\"\n [accept]=\"accept()\"\n [attachments]=\"attachments()\"\n [formatting]=\"formatting()\"\n [toolbar]=\"formattingToolbar()\"\n [sending]=\"sending()\"\n [disabled]=\"loading() || fetching()\"\n [droppedFiles]=\"droppedFiles()\"\n (submitted)=\"onComposerSubmit($event)\" />\n } @else {\n <form rtElem=\"composer\" qa-dataid=\"chat-composer\" [formGroup]=\"replyForm\" (ngSubmit)=\"onSubmit()\">\n @if (attachments() && selectedFiles().length > 0) {\n <div rtElem=\"composer-files\" qa-dataid=\"chat-composer-files\">\n @for (file of selectedFiles(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"chat-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"composerDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n <div rtElem=\"composer-field\" [rtMod]=\"{ attach: attachments() }\">\n @if (attachments()) {\n <input\n #composerFileEl\n qa-dataid=\"chat-composer-file-input\"\n type=\"file\"\n hidden\n multiple\n [attr.accept]=\"accept() || null\"\n (change)=\"onFilesPicked($event)\" />\n <rt-icon-button\n qa-dataid=\"chat-composer-attach\"\n icon=\"paperclip\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"composerDisabled()\"\n (clicked)=\"openFilePicker()\" />\n }\n <textarea\n rtElem=\"composer-input\"\n qa-dataid=\"chat-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"4\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"onComposerKeydown($event)\"></textarea>\n </div>\n <button\n rtButton\n rtElem=\"composer-send\"\n qa-dataid=\"chat-composer-send\"\n type=\"submit\"\n theme=\"primary\"\n appearance=\"filled\"\n [label]=\"t().chatSendLabel\"\n [attr.aria-label]=\"t().chatSendAria\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"></button>\n </form>\n }\n } @else if (replyBlockReason()) {\n <rt-note rtElem=\"reply-block\" qa-dataid=\"chat-reply-block\">{{ replyBlockReason() }}</rt-note>\n }\n\n <!-- \u0421\u043B\u043E\u0442 \u0434\u043E\u043C\u0435\u043D\u043D\u044B\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u044F \u043F\u043E\u0434 \u043A\u043E\u043C\u043F\u043E\u0437\u0435\u0440\u043E\u043C: \u0432 fullscreen\n \u043F\u043E\u043F\u0430\u0434\u0430\u0435\u0442 \u0432\u043D\u0443\u0442\u0440\u044C overlay, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043A\u043D\u043E\u043F\u043A\u0438 \u043E\u0441\u0442\u0430\u044E\u0442\u0441\u044F \u0432\u0438\u0434\u043D\u044B. -->\n <div rtElem=\"footer-slot\" qa-dataid=\"chat-footer\" [rtMod]=\"{ blocked: fetching() }\" [attr.inert]=\"fetching() ? '' : null\">\n <ng-content select=\"[rtChatFooter]\" />\n </div>\n }\n </rt-file-drop>\n</ng-container>\n", styles: ["@layer rt-kit.components{.rt-chat{--rt-chat-bubble-radius: var(--rt-radius-lg);--rt-chat-message-border-width: var(--rt-border-width-thin);--rt-chat-transition-duration: var(--rt-duration-fast);display:flex;flex-direction:column}.rt-chat>.rt-file-drop{display:flex;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-4);min-block-size:0}.rt-chat--expanded{position:fixed;z-index:var(--rt-z-modal);box-sizing:border-box;padding:var(--rt-space-md);background:var(--rt-color-bg-surface);inset:0}.rt-chat--expanded>.rt-file-drop{block-size:100%}@media(width>=1441px){.rt-chat--expanded>.rt-file-drop{inline-size:1000px;margin-inline:auto;max-inline-size:100%}}.rt-chat--expanded .rt-chat__thread-viewport{flex:1 1 auto;min-block-size:0}.rt-chat--expanded .rt-chat__thread{max-height:none}.rt-chat--fill{block-size:100%}.rt-chat--fill .rt-chat__thread-viewport{flex:1 1 auto;min-block-size:0}.rt-chat--fill .rt-chat__thread{max-height:none}.rt-chat__title{margin:0;color:var(--rt-color-text-primary);font-family:var(--rt-font-family-sans);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-bold);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-chat__thread-viewport{position:relative;display:flex;flex-direction:column;contain:inline-size;min-block-size:0}.rt-chat__thread{display:flex;max-height:280px;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-4);min-block-size:0;overflow-y:auto}.rt-chat__thread--frozen{overflow-y:hidden}.rt-chat__thread-overlay{position:absolute;z-index:1;display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--rt-color-bg-surface) 60%,transparent);inset:0}.rt-chat__footer-slot{display:flex;flex-direction:column}.rt-chat__footer-slot:empty{display:none}.rt-chat__footer-slot--blocked{opacity:.6;pointer-events:none}.rt-chat__message-row{display:flex;max-width:min(80%,480px);align-items:center;align-self:flex-start;gap:var(--rt-space-2)}.rt-chat__message-row--own{align-self:flex-end}.rt-chat__message-row:hover .rt-chat__message-delete,.rt-chat__message-row:focus-within .rt-chat__message-delete,.rt-chat__message-row:hover .rt-chat__message-actions,.rt-chat__message-row:focus-within .rt-chat__message-actions{opacity:1;pointer-events:auto}.rt-chat__message{display:flex;min-width:0;flex:0 1 auto;flex-direction:column;padding:var(--rt-space-2);border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;background:var(--rt-chat-bubble-in-bg);gap:var(--rt-space-2)}.rt-chat__message--own{border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);background:var(--rt-chat-bubble-own-bg)}.rt-chat__message--deleted{border:var(--rt-chat-message-border-width) dashed var(--rt-color-border-default);background:transparent}.rt-chat__message-author{margin:0;color:var(--rt-chat-bubble-in-author);font-size:var(--rt-text-2xs);font-weight:var(--rt-font-weight-bold);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-chat__message--own .rt-chat__message-author{color:var(--rt-chat-bubble-own-author)}.rt-chat__message-text{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-regular);line-height:var(--rt-leading-snug);white-space:pre-wrap}.rt-chat__message-text--deleted{color:var(--rt-color-text-muted);font-style:italic}.rt-chat__message-delete,.rt-chat__message-actions{flex:0 0 auto;opacity:0;pointer-events:none;transition:opacity var(--rt-chat-transition-duration) ease}.rt-chat__message-attachment{display:block}.rt-chat__message-footer{display:flex;align-items:center;gap:var(--rt-space-1)}.rt-chat__message-date{color:var(--rt-chat-bubble-date);font-size:var(--rt-text-xs);line-height:var(--rt-leading-none)}.rt-chat__message-status{display:inline-flex;align-items:center;color:var(--rt-color-text-muted);gap:var(--rt-space-0-5)}.rt-chat__message-status--status--read{color:var(--rt-chat-status-read)}.rt-chat__message-status--status--failed{color:var(--rt-color-state-danger)}.rt-chat__status-icon{font-size:var(--rt-text-sm)}.rt-chat__message-skeleton{display:flex;max-width:min(80%,480px);flex-direction:column;align-self:flex-start;padding:var(--rt-space-2);border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;background:var(--rt-chat-bubble-in-bg);gap:var(--rt-space-1)}.rt-chat__message-skeleton--own{align-self:flex-end;border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);background:var(--rt-chat-bubble-own-bg)}.rt-chat__skeleton-line{display:block}.rt-chat__message-deeplink{display:flex;justify-content:flex-start;margin-top:var(--rt-space-1)}.rt-chat__composer,.rt-chat__composer-rich,.rt-chat__reply-block{margin-top:var(--rt-space-4)}.rt-chat__composer{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-chat__composer-files{display:flex;flex-wrap:wrap;gap:var(--rt-space-2)}.rt-chat__composer-field{display:flex;box-sizing:border-box;align-items:center;border:var(--rt-input-border-width) solid var(--rt-input-color-border);border-radius:var(--rt-input-radius);background-color:var(--rt-input-color-bg);gap:var(--rt-space-1);min-block-size:var(--rt-input-height);padding-inline:var(--rt-input-padding-x);transition:var(--rt-input-transition)}.rt-chat__composer-field:focus-within{border-color:var(--rt-input-color-border-focus);box-shadow:var(--rt-input-focus-shadow)}.rt-chat__composer-field--attach{padding-inline-start:var(--rt-space-1)}.rt-chat__composer-input{box-sizing:content-box;flex:1 1 auto;border:0;background:transparent;color:var(--rt-input-color-text);font-family:inherit;font-size:var(--rt-input-font-size);inline-size:100%;line-height:var(--rt-textarea-line-height);padding-block:var(--rt-space-2);resize:none}.rt-chat__composer-input::placeholder{color:var(--rt-input-color-text-placeholder);opacity:1}.rt-chat__composer-input:focus-visible{outline:none}.rt-chat__composer-input:disabled{cursor:not-allowed}.rt-chat__composer-send{inline-size:100%}}\n"] }]
951
- }], ctorParameters: () => [], propDecorators: { thread: [{ type: i0.ViewChild, args: ['thread', { isSignal: true }] }], composerFileEl: [{ type: i0.ViewChild, args: ['composerFileEl', { isSignal: true }] }], messageActions: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RtChatMessageActionsDirective), { isSignal: true }] }], messages: [{ type: i0.Input, args: [{ isSignal: true, alias: "messages", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], fetching: [{ type: i0.Input, args: [{ isSignal: true, alias: "fetching", required: false }] }], canReply: [{ type: i0.Input, args: [{ isSignal: true, alias: "canReply", required: false }] }], replyBlockReason: [{ type: i0.Input, args: [{ isSignal: true, alias: "replyBlockReason", required: false }] }], sending: [{ type: i0.Input, args: [{ isSignal: true, alias: "sending", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], emptyHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyHint", required: false }] }], hasThread: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasThread", required: false }] }], attachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachments", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], richComposer: [{ type: i0.Input, args: [{ isSignal: true, alias: "richComposer", required: false }] }], formatting: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatting", required: false }] }], formattingToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "formattingToolbar", required: false }] }], fill: [{ type: i0.Input, args: [{ isSignal: true, alias: "fill", required: false }] }], showRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRefresh", required: false }] }], showExpand: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExpand", required: false }] }], send: [{ type: i0.Output, args: ["send"] }], refresh: [{ type: i0.Output, args: ["refresh"] }], downloadFile: [{ type: i0.Output, args: ["downloadFile"] }], downloadAttachment: [{ type: i0.Output, args: ["downloadAttachment"] }], expandedChange: [{ type: i0.Output, args: ["expandedChange"] }], deleteMessage: [{ type: i0.Output, args: ["deleteMessage"] }], retryMessage: [{ type: i0.Output, args: ["retryMessage"] }], messageHasActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageHasActions", required: false }] }] } });
1005
+ }, template: "<ng-container rtBlock=\"rt-chat\">\n <rt-file-drop\n [overlayLabel]=\"t().chatDropOverlay\"\n [accept]=\"accept()\"\n [disabled]=\"dropDisabled()\"\n (filesDropped)=\"onFilesDropped($event)\">\n @if (showHeader()) {\n <rt-toolbar rtElem=\"header\" dense>\n <ng-template rtToolbarLeft>\n <h3 rtElem=\"title\" qa-dataid=\"chat-title\">{{ title() }}</h3>\n </ng-template>\n <ng-template rtToolbarRight>\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"chat-refresh\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRefreshAria\"\n [tooltip]=\"t().chatRefreshTooltip\"\n [loading]=\"fetching()\"\n [disabled]=\"!hasThread()\"\n (clicked)=\"refresh.emit()\" />\n }\n @if (showExpand()) {\n <rt-icon-button\n qa-dataid=\"chat-expand\"\n variant=\"ghost\"\n [icon]=\"expanded() ? 'window-minimize' : 'window-maximize'\"\n [ariaLabel]=\"expandLabel()\"\n [tooltip]=\"expandLabel()\"\n (clicked)=\"toggleExpand()\" />\n }\n <ng-content select=\"[rtChatHeaderActions]\" />\n </ng-template>\n </rt-toolbar>\n }\n\n @if (!hasThread()) {\n <rt-note qa-dataid=\"chat-empty-hint\">{{ emptyHint() }}</rt-note>\n } @else {\n <div rtElem=\"thread-viewport\" qa-dataid=\"chat-thread-viewport\">\n @if (loading()) {\n <!-- \u0421\u043A\u0435\u043B\u0435\u0442\u043E\u043D \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u0442 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0443 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F (\u0430\u0432\u0442\u043E\u0440 \u2192 \u0442\u0435\u043A\u0441\u0442 \u2192 \u0434\u0430\u0442\u0430),\n \u0447\u0435\u0440\u0435\u0434\u0443\u044F \u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u0435, \u0447\u0442\u043E\u0431\u044B \u0442\u0440\u0435\u0434 \u043D\u0435 \u00AB\u043F\u0440\u044B\u0433\u0430\u043B\u00BB \u043F\u0440\u0438 \u043F\u043E\u0434\u043C\u0435\u043D\u0435 \u043D\u0430 \u0440\u0435\u0430\u043B\u044C\u043D\u044B\u0435. -->\n <div rtElem=\"thread\" qa-dataid=\"chat-thread-skeleton\">\n @for (row of skeletonRows; track row; let even = $even) {\n <div rtElem=\"message-skeleton\" qa-dataid=\"chat-message-skeleton\" [rtMod]=\"{ own: even }\">\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"72px\" height=\"10px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"100%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"55%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"56px\" height=\"10px\" [isLoading]=\"true\" />\n </div>\n }\n </div>\n } @else {\n <div\n #thread\n rtElem=\"thread\"\n qa-dataid=\"chat-thread\"\n [rtMod]=\"{ frozen: fetching() }\"\n [attr.aria-busy]=\"fetching() ? 'true' : null\"\n (scroll)=\"onThreadScroll()\">\n @for (m of messages(); track m.id) {\n <div\n rtElem=\"message-row\"\n qa-dataid=\"chat-message\"\n [attr.data-own]=\"m.own\"\n [attr.data-status]=\"m.status || null\"\n [attr.data-deleted]=\"m.deleted || null\"\n [rtMod]=\"{ own: m.own }\">\n @if (m.canDelete && !m.deleted) {\n @if (m.deleteConfirm) {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n [rtConfirm]=\"m.deleteConfirm\"\n (confirmed)=\"deleteMessage.emit(m)\" />\n } @else {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n (clicked)=\"deleteMessage.emit(m)\" />\n }\n }\n @if (messageActions()?.template; as actionsTpl) {\n @if (m | rtChatMessageHasActions: messageHasActions()) {\n <div rtElem=\"message-actions\" qa-dataid=\"chat-message-actions\">\n <rt-menu>\n <ng-container\n [ngTemplateOutlet]=\"actionsTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: m }\" />\n </rt-menu>\n </div>\n }\n }\n <div rtElem=\"message\" [rtMod]=\"{ own: m.own, deleted: m.deleted }\">\n <p rtElem=\"message-author\" qa-dataid=\"chat-message-author\">{{ m.author }}</p>\n @if (m.deleted) {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-deleted\" rtMod=\"deleted\">\n {{ t().chatMessageDeleted }}\n </p>\n } @else {\n @if (m.delta) {\n <rt-delta-view rtElem=\"message-text\" qa-dataid=\"chat-message-text\" [delta]=\"m.delta\" />\n } @else {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-text\">{{ m.text }}</p>\n }\n @if (m.attachments?.length) {\n @for (att of m.attachments; track att.id) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"att.name || attachmentFallbackName()\"\n (download)=\"downloadAttachment.emit(att)\" />\n </span>\n }\n } @else if (m.fileUrl) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"m.fileName || attachmentFallbackName()\"\n (download)=\"downloadFile.emit(m)\" />\n </span>\n }\n @if (m.deepLink) {\n <span rtElem=\"message-deeplink\">\n <a\n rtButton\n qa-dataid=\"chat-message-deeplink\"\n appearance=\"outlined\"\n icon=\"send\"\n rel=\"noopener\"\n target=\"_blank\"\n [href]=\"m.deepLink\"\n [label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"\n [attr.aria-label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"></a>\n </span>\n }\n }\n <span rtElem=\"message-footer\">\n <span rtElem=\"message-date\" qa-dataid=\"chat-message-date\">\n {{ m.createdAt | date: 'short' : undefined : locale() }}\n </span>\n @if (m.status) {\n <span\n rtElem=\"message-status\"\n qa-dataid=\"chat-message-status\"\n [attr.data-status]=\"m.status\"\n [rtMod]=\"{ status: m.status }\"\n [attr.aria-label]=\"m.status | rtChatStatusLabel\">\n @if (m.status === MessageStatus.Failed) {\n <rt-icon rtElem=\"status-icon\" name=\"exclamation-circle\" size=\"sm\" />\n <rt-icon-button\n qa-dataid=\"chat-message-retry\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRetryAria\"\n [tooltip]=\"t().chatRetryTooltip\"\n (clicked)=\"retryMessage.emit(m)\" />\n } @else {\n <!-- \u0427\u0430\u0441\u044B, \u043F\u043E\u043A\u0430 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0432 \u043F\u0443\u0442\u0438; \u0434\u0430\u043B\u044C\u0448\u0435 \u0434\u0432\u043E\u0439\u043D\u043E\u0439 \u0447\u0435\u043A, \u0446\u0432\u0435\u0442 \u043A\u043E\u0442\u043E\u0440\u043E\u0433\u043E\n (\u0441\u0435\u0440\u044B\u0439/\u0441\u0438\u043D\u0438\u0439) \u0440\u0430\u0437\u043B\u0438\u0447\u0430\u0435\u0442 \u0434\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u043E \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043E. -->\n <rt-icon\n rtElem=\"status-icon\"\n size=\"sm\"\n [name]=\"m.status === MessageStatus.Sending ? 'clock' : 'check-double'\" />\n }\n </span>\n }\n </span>\n </div>\n </div>\n } @empty {\n <rt-note qa-dataid=\"chat-empty-thread\">{{ t().chatEmptyThread }}</rt-note>\n }\n </div>\n }\n @if (!loading() && fetching()) {\n <div rtElem=\"thread-overlay\" qa-dataid=\"chat-thread-overlay\" role=\"status\" [attr.aria-label]=\"t().chatRefreshAria\">\n <rt-spinner diameter=\"32\" />\n </div>\n }\n <div rtElem=\"typing\" qa-dataid=\"chat-typing\" aria-live=\"polite\" [rtMod]=\"{ shown: typingText() !== '' }\">\n {{ typingText() }}\n </div>\n </div>\n\n @if (canReply()) {\n @if (richComposer()) {\n <rt-message-composer\n rtElem=\"composer-rich\"\n qa-dataid=\"chat-composer-rich\"\n [placeholder]=\"placeholder()\"\n [accept]=\"accept()\"\n [attachments]=\"attachments()\"\n [formatting]=\"formatting()\"\n [toolbar]=\"formattingToolbar()\"\n [sending]=\"sending()\"\n [disabled]=\"loading() || fetching()\"\n [droppedFiles]=\"droppedFiles()\"\n (submitted)=\"onComposerSubmit($event)\"\n (input)=\"onReplyInput($event)\" />\n } @else {\n <form\n rtElem=\"composer\"\n qa-dataid=\"chat-composer\"\n [formGroup]=\"replyForm\"\n (ngSubmit)=\"onSubmit()\"\n (input)=\"onReplyInput($event)\">\n @if (attachments() && selectedFiles().length > 0) {\n <div rtElem=\"composer-files\" qa-dataid=\"chat-composer-files\">\n @for (file of selectedFiles(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"chat-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"composerDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n <div rtElem=\"composer-field\" [rtMod]=\"{ attach: attachments() }\">\n @if (attachments()) {\n <input\n #composerFileEl\n qa-dataid=\"chat-composer-file-input\"\n type=\"file\"\n hidden\n multiple\n [attr.accept]=\"accept() || null\"\n (change)=\"onFilesPicked($event)\" />\n <rt-icon-button\n qa-dataid=\"chat-composer-attach\"\n icon=\"paperclip\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"composerDisabled()\"\n (clicked)=\"openFilePicker()\" />\n }\n <textarea\n rtElem=\"composer-input\"\n qa-dataid=\"chat-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"4\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"onComposerKeydown($event)\"></textarea>\n </div>\n <button\n rtButton\n rtElem=\"composer-send\"\n qa-dataid=\"chat-composer-send\"\n type=\"submit\"\n theme=\"primary\"\n appearance=\"filled\"\n [label]=\"t().chatSendLabel\"\n [attr.aria-label]=\"t().chatSendAria\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"></button>\n </form>\n }\n } @else if (replyBlockReason()) {\n <rt-note rtElem=\"reply-block\" qa-dataid=\"chat-reply-block\">{{ replyBlockReason() }}</rt-note>\n }\n\n <!-- \u0421\u043B\u043E\u0442 \u0434\u043E\u043C\u0435\u043D\u043D\u044B\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u044F \u043F\u043E\u0434 \u043A\u043E\u043C\u043F\u043E\u0437\u0435\u0440\u043E\u043C: \u0432 fullscreen\n \u043F\u043E\u043F\u0430\u0434\u0430\u0435\u0442 \u0432\u043D\u0443\u0442\u0440\u044C overlay, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043A\u043D\u043E\u043F\u043A\u0438 \u043E\u0441\u0442\u0430\u044E\u0442\u0441\u044F \u0432\u0438\u0434\u043D\u044B. -->\n <div rtElem=\"footer-slot\" qa-dataid=\"chat-footer\" [rtMod]=\"{ blocked: fetching() }\" [attr.inert]=\"fetching() ? '' : null\">\n <ng-content select=\"[rtChatFooter]\" />\n </div>\n }\n </rt-file-drop>\n</ng-container>\n", styles: ["@layer rt-kit.components{.rt-chat{--rt-chat-bubble-radius: var(--rt-radius-lg);--rt-chat-message-border-width: var(--rt-border-width-thin);--rt-chat-transition-duration: var(--rt-duration-fast);--rt-chat-typing-radius: var(--rt-radius-full);--rt-chat-typing-shadow: var(--rt-shadow-sm);display:flex;flex-direction:column}.rt-chat>.rt-file-drop{display:flex;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-4);min-block-size:0}.rt-chat--expanded{position:fixed;z-index:var(--rt-z-modal);box-sizing:border-box;padding:var(--rt-space-md);background:var(--rt-color-bg-surface);inset:0}.rt-chat--expanded>.rt-file-drop{block-size:100%}@media(width>=1441px){.rt-chat--expanded>.rt-file-drop{inline-size:1000px;margin-inline:auto;max-inline-size:100%}}.rt-chat--expanded .rt-chat__thread-viewport{flex:1 1 auto;min-block-size:0}.rt-chat--expanded .rt-chat__thread{max-height:none}.rt-chat--fill{block-size:100%}.rt-chat--fill .rt-chat__thread-viewport{flex:1 1 auto;min-block-size:0}.rt-chat--fill .rt-chat__thread{max-height:none}.rt-chat__title{margin:0;color:var(--rt-color-text-primary);font-family:var(--rt-font-family-sans);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-bold);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-chat__thread-viewport{position:relative;display:flex;flex-direction:column;contain:inline-size;min-block-size:0}.rt-chat__thread{display:flex;max-height:280px;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-4);min-block-size:0;overflow-y:auto}.rt-chat__thread--frozen{overflow-y:hidden}.rt-chat__thread-overlay{position:absolute;z-index:1;display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--rt-color-bg-surface) 60%,transparent);inset:0}.rt-chat__typing{position:absolute;z-index:1;bottom:var(--rt-space-1);left:var(--rt-space-2);box-sizing:border-box;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);max-inline-size:calc(100% - 2 * var(--rt-space-2));overflow-wrap:anywhere;pointer-events:none}.rt-chat__typing--shown{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-chat-typing-radius);background:var(--rt-color-bg-surface);box-shadow:var(--rt-chat-typing-shadow)}.rt-chat__footer-slot{display:flex;flex-direction:column}.rt-chat__footer-slot:empty{display:none}.rt-chat__footer-slot--blocked{opacity:.6;pointer-events:none}.rt-chat__message-row{display:flex;max-width:min(80%,480px);align-items:center;align-self:flex-start;gap:var(--rt-space-2)}.rt-chat__message-row--own{align-self:flex-end}.rt-chat__message-row:hover .rt-chat__message-delete,.rt-chat__message-row:focus-within .rt-chat__message-delete,.rt-chat__message-row:hover .rt-chat__message-actions,.rt-chat__message-row:focus-within .rt-chat__message-actions{opacity:1;pointer-events:auto}.rt-chat__message{display:flex;min-width:0;flex:0 1 auto;flex-direction:column;padding:var(--rt-space-2);border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;background:var(--rt-chat-bubble-in-bg);gap:var(--rt-space-2)}.rt-chat__message--own{border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);background:var(--rt-chat-bubble-own-bg)}.rt-chat__message--deleted{border:var(--rt-chat-message-border-width) dashed var(--rt-color-border-default);background:transparent}.rt-chat__message-author{margin:0;color:var(--rt-chat-bubble-in-author);font-size:var(--rt-text-2xs);font-weight:var(--rt-font-weight-bold);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-chat__message--own .rt-chat__message-author{color:var(--rt-chat-bubble-own-author)}.rt-chat__message-text{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-regular);line-height:var(--rt-leading-snug);white-space:pre-wrap}.rt-chat__message-text--deleted{color:var(--rt-color-text-muted);font-style:italic}.rt-chat__message-delete,.rt-chat__message-actions{flex:0 0 auto;opacity:0;pointer-events:none;transition:opacity var(--rt-chat-transition-duration) ease}.rt-chat__message-attachment{display:block}.rt-chat__message-footer{display:flex;align-items:center;gap:var(--rt-space-1)}.rt-chat__message-date{color:var(--rt-chat-bubble-date);font-size:var(--rt-text-xs);line-height:var(--rt-leading-none)}.rt-chat__message-status{display:inline-flex;align-items:center;color:var(--rt-color-text-muted);gap:var(--rt-space-0-5)}.rt-chat__message-status--status--read{color:var(--rt-chat-status-read)}.rt-chat__message-status--status--failed{color:var(--rt-color-state-danger)}.rt-chat__status-icon{font-size:var(--rt-text-sm)}.rt-chat__message-skeleton{display:flex;max-width:min(80%,480px);flex-direction:column;align-self:flex-start;padding:var(--rt-space-2);border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0;background:var(--rt-chat-bubble-in-bg);gap:var(--rt-space-1)}.rt-chat__message-skeleton--own{align-self:flex-end;border-radius:var(--rt-chat-bubble-radius) var(--rt-chat-bubble-radius) 0 var(--rt-chat-bubble-radius);background:var(--rt-chat-bubble-own-bg)}.rt-chat__skeleton-line{display:block}.rt-chat__message-deeplink{display:flex;justify-content:flex-start;margin-top:var(--rt-space-1)}.rt-chat__composer,.rt-chat__composer-rich,.rt-chat__reply-block{margin-top:var(--rt-space-4)}.rt-chat__composer{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-chat__composer-files{display:flex;flex-wrap:wrap;gap:var(--rt-space-2)}.rt-chat__composer-field{display:flex;box-sizing:border-box;align-items:center;border:var(--rt-input-border-width) solid var(--rt-input-color-border);border-radius:var(--rt-input-radius);background-color:var(--rt-input-color-bg);gap:var(--rt-space-1);min-block-size:var(--rt-input-height);padding-inline:var(--rt-input-padding-x);transition:var(--rt-input-transition)}.rt-chat__composer-field:focus-within{border-color:var(--rt-input-color-border-focus);box-shadow:var(--rt-input-focus-shadow)}.rt-chat__composer-field--attach{padding-inline-start:var(--rt-space-1)}.rt-chat__composer-input{box-sizing:content-box;flex:1 1 auto;border:0;background:transparent;color:var(--rt-input-color-text);font-family:inherit;font-size:var(--rt-input-font-size);inline-size:100%;line-height:var(--rt-textarea-line-height);padding-block:var(--rt-space-2);resize:none}.rt-chat__composer-input::placeholder{color:var(--rt-input-color-text-placeholder);opacity:1}.rt-chat__composer-input:focus-visible{outline:none}.rt-chat__composer-input:disabled{cursor:not-allowed}.rt-chat__composer-send{inline-size:100%}}\n"] }]
1006
+ }], ctorParameters: () => [], propDecorators: { thread: [{ type: i0.ViewChild, args: ['thread', { isSignal: true }] }], composerFileEl: [{ type: i0.ViewChild, args: ['composerFileEl', { isSignal: true }] }], messageActions: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RtChatMessageActionsDirective), { isSignal: true }] }], messages: [{ type: i0.Input, args: [{ isSignal: true, alias: "messages", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], fetching: [{ type: i0.Input, args: [{ isSignal: true, alias: "fetching", required: false }] }], canReply: [{ type: i0.Input, args: [{ isSignal: true, alias: "canReply", required: false }] }], replyBlockReason: [{ type: i0.Input, args: [{ isSignal: true, alias: "replyBlockReason", required: false }] }], sending: [{ type: i0.Input, args: [{ isSignal: true, alias: "sending", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], emptyHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyHint", required: false }] }], hasThread: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasThread", required: false }] }], attachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachments", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], richComposer: [{ type: i0.Input, args: [{ isSignal: true, alias: "richComposer", required: false }] }], formatting: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatting", required: false }] }], formattingToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "formattingToolbar", required: false }] }], fill: [{ type: i0.Input, args: [{ isSignal: true, alias: "fill", required: false }] }], showRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRefresh", required: false }] }], showExpand: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExpand", required: false }] }], send: [{ type: i0.Output, args: ["send"] }], refresh: [{ type: i0.Output, args: ["refresh"] }], downloadFile: [{ type: i0.Output, args: ["downloadFile"] }], downloadAttachment: [{ type: i0.Output, args: ["downloadAttachment"] }], typing: [{ type: i0.Output, args: ["typing"] }], typingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "typingText", required: false }] }], expandedChange: [{ type: i0.Output, args: ["expandedChange"] }], deleteMessage: [{ type: i0.Output, args: ["deleteMessage"] }], retryMessage: [{ type: i0.Output, args: ["retryMessage"] }], messageHasActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageHasActions", required: false }] }] } });
952
1007
 
953
1008
  /**
954
1009
  * Статус уже сохранённого своего сообщения: сервер знает только, дошло ли оно до