@rt-tools/ui-kit-v2 0.13.1 → 0.15.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 (69) hide show
  1. package/README.md +25 -5
  2. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +90 -12
  3. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  4. package/fesm2022/rt-tools-ui-kit-v2.mjs +2267 -664
  5. package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
  6. package/package.json +1 -1
  7. package/rt-tools-ui-kit-v2-0.15.0.tgz +0 -0
  8. package/src/lib/components/CONTEXT.md +1 -1
  9. package/src/lib/components/action-bar/rt-action-bar.component.scss +5 -0
  10. package/src/lib/components/autocomplete/rt-autocomplete.component.scss +8 -1
  11. package/src/lib/components/bottom-sheet/rt-bottom-sheet.component.scss +5 -0
  12. package/src/lib/components/button/CONTEXT.md +1 -1
  13. package/src/lib/components/button/rt-button.directive.scss +5 -7
  14. package/src/lib/components/calendar/CONTEXT.md +16 -2
  15. package/src/lib/components/calendar/rt-calendar.component.scss +81 -4
  16. package/src/lib/components/card/rt-card.component.scss +5 -0
  17. package/src/lib/components/checkbox/rt-checkbox.component.scss +5 -0
  18. package/src/lib/components/data-list/settings/rt-data-list-settings-aside.component.scss +1 -1
  19. package/src/lib/components/data-list/toolbar/rt-data-list-toolbar.component.scss +1 -1
  20. package/src/lib/components/data-table/cell/rt-data-table-cell.component.scss +1 -1
  21. package/src/lib/components/data-table/filter-cell/rt-data-table-filter-cell.component.scss +1 -1
  22. package/src/lib/components/data-table/rt-data-table.component.scss +1 -1
  23. package/src/lib/components/date-picker/CONTEXT.md +33 -14
  24. package/src/lib/components/date-picker/panel/rt-date-panel.component.scss +155 -0
  25. package/src/lib/components/date-picker/rt-date-picker.component.scss +18 -2
  26. package/src/lib/components/date-range/CONTEXT.md +53 -0
  27. package/src/lib/components/date-range/panel/rt-date-range-panel.component.scss +103 -0
  28. package/src/lib/components/date-range/rt-date-range.component.scss +120 -0
  29. package/src/lib/components/dialog/rt-dialog.component.scss +5 -0
  30. package/src/lib/components/empty-state/rt-empty-state.component.scss +5 -0
  31. package/src/lib/components/file-card/rt-file-card.component.scss +5 -0
  32. package/src/lib/components/file-drop/rt-file-drop.component.scss +5 -0
  33. package/src/lib/components/header/rt-header.component.scss +5 -0
  34. package/src/lib/components/icon-button/CONTEXT.md +1 -1
  35. package/src/lib/components/icon-button/rt-icon-button.component.scss +9 -29
  36. package/src/lib/components/input/rt-input.component.scss +7 -1
  37. package/src/lib/components/input-number/rt-input-number.component.scss +7 -1
  38. package/src/lib/components/markdown-text/rt-markdown-text.component.scss +5 -0
  39. package/src/lib/components/menu/rt-menu-item.component.scss +5 -0
  40. package/src/lib/components/message/rt-message.component.scss +5 -0
  41. package/src/lib/components/money-list/rt-money-list.component.scss +5 -0
  42. package/src/lib/components/multiselect/CONTEXT.md +12 -5
  43. package/src/lib/components/multiselect/rt-multiselect.component.scss +32 -1
  44. package/src/lib/components/note/rt-note.component.scss +5 -0
  45. package/src/lib/components/notifications-bell/rt-notifications-bell.component.scss +5 -0
  46. package/src/lib/components/pagination/rt-pagination.component.scss +6 -1
  47. package/src/lib/components/radio-button/rt-radio-button.component.scss +5 -0
  48. package/src/lib/components/section-nav/rt-section-nav.component.scss +5 -0
  49. package/src/lib/components/select/CONTEXT.md +10 -7
  50. package/src/lib/components/select/rt-select.component.scss +36 -1
  51. package/src/lib/components/skeleton/CONTEXT.md +14 -16
  52. package/src/lib/components/skeleton/rt-skeleton.component.scss +7 -1
  53. package/src/lib/components/skeleton-wrapper/CONTEXT.md +6 -6
  54. package/src/lib/components/split-button/rt-split-button.component.scss +6 -0
  55. package/src/lib/components/stepper/rt-stepper.component.scss +5 -0
  56. package/src/lib/components/table/rt-table.component.scss +12 -0
  57. package/src/lib/components/tag/CONTEXT.md +14 -15
  58. package/src/lib/components/tag/rt-tag.component.scss +6 -30
  59. package/src/lib/components/textarea/rt-textarea.component.scss +8 -1
  60. package/src/lib/components/thread-list/rt-thread-list.component.scss +5 -0
  61. package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +7 -6
  62. package/src/lib/components/toggle-switch/rt-toggle-switch.component.scss +5 -0
  63. package/src/rich-editor/lib/components/message-composer/CONTEXT.md +26 -2
  64. package/src/rich-editor/lib/components/message-composer/rt-message-composer.component.scss +78 -34
  65. package/src/styles/_mixins.scss +39 -0
  66. package/styles/tokens.css +30 -5
  67. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +32 -6
  68. package/types/rt-tools-ui-kit-v2.d.ts +396 -109
  69. package/rt-tools-ui-kit-v2-0.13.1.tgz +0 -0
package/README.md CHANGED
@@ -157,10 +157,10 @@ export const appConfig: ApplicationConfig = {
157
157
  ## Что внутри
158
158
 
159
159
  **Компоненты** — 73 семейства: поля формы (`rt-input`, `rt-select`, `rt-multiselect`,
160
- `rt-date-picker`, `rt-file-input`, `rt-rich-editor`, `rt-field`), таблица с настройкой колонок и
161
- пагинацией, панель правки записи с маршрутом и защитой несохранённого, диалоги, чат с композером,
162
- календарь, шапка страницы с навигацией, тосты, просмотрщик фотографий, показ размеченного текста
163
- (`rt-markdown-text`) и остальное.
160
+ `rt-date-picker`, `rt-date-range`, `rt-file-input`, `rt-rich-editor`, `rt-field`), таблица с
161
+ настройкой колонок и пагинацией, панель правки записи с маршрутом и защитой несохранённого,
162
+ диалоги, чат с композером, календарь, шапка страницы с навигацией, тосты, просмотрщик фотографий,
163
+ показ размеченного текста (`rt-markdown-text`) и остальное.
164
164
 
165
165
  **Дизайн-система** — `src/styles`:
166
166
 
@@ -225,6 +225,27 @@ provideRtKitLabels({
225
225
  доживает до рантайма) и то, что на них отвечают готовой строкой: подстановки вида `{{name}}`
226
226
  переводчик делает сам. Подпись, которой он не дал, берётся английской — поштучно, не набором.
227
227
 
228
+ ## Скругление одним входом
229
+
230
+ Каждый компонент с поверхностью принимает вход `radius` — шаг общей шкалы: `none`, `xs`, `sm`,
231
+ `ms`, `md`, `lg`, `xl`, `2xl`, `full`. Без входа компонент скруглён по макету, и умолчание у
232
+ каждого своё.
233
+
234
+ ```html
235
+ <rt-card radius="none">…</rt-card>
236
+ <rt-input radius="full" />
237
+ <button rtButton label="Сохранить" radius="sm"></button>
238
+ ```
239
+
240
+ Шаг ложится на хост атрибутом `data-rt-radius` и переназначает своё свойство главной поверхности.
241
+ Вложенный компонент его не наследует: скруглённая карточка не скругляет кнопки внутри.
242
+ Внутренние части — точка, значок, кольцо фокуса — держат своё скругление. Круглую кнопку для
243
+ всего приложения задаёт настройка кита `components.button.radius`.
244
+
245
+ Входа нет у подтверждения, всплывающего уведомления, подсказки и просмотра фото: их рисует
246
+ директива или сервис поверх страницы, и тега для шага у приложения нет. Все шаги всех компонентов
247
+ показаны на странице витрины `Foundation / Radius`.
248
+
228
249
  ## Настройка компонента снаружи
229
250
 
230
251
  Компонент не берёт ступень шкалы там, где рисует себя: между ступенью и местом употребления
@@ -305,4 +326,3 @@ pnpm exec stylelint "projects/ui-kit-v2/**/*.scss"
305
326
  - **Кит больше не настаивает на своём восклицательным знаком.** Таблица в карточном виде
306
327
  перестала перебивать `min-width` приложения: приложению, которому нужен и горизонтальный
307
328
  скролл, и карточный вид, остаётся сузить свой селектор до широкого экрана.
308
-
@@ -1,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { viewChild, signal, computed, input, output, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component, inject, booleanAttribute, numberAttribute, 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, 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';
6
- import { toSignal } from '@angular/core/rxjs-interop';
6
+ import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
7
  import * as i1 from '@angular/forms';
8
8
  import { FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
9
9
  import { NgTemplateOutlet, DatePipe } from '@angular/common';
@@ -102,6 +102,10 @@ class RtRichEditorComponent extends RtFormControlBase {
102
102
  quill.on('text-change', () => this.#onEditorChange());
103
103
  this.mounted.set(true);
104
104
  }
105
+ /** Ставит фокус в редактор; до загрузки Quill ничего не делает. */
106
+ focus() {
107
+ this.#quill?.focus();
108
+ }
105
109
  ngOnDestroy() {
106
110
  this.#quill = null;
107
111
  this.mounted.set(false);
@@ -175,24 +179,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
175
179
  }], propDecorators: { editorHost: [{ type: i0.ViewChild, args: ['editor', { isSignal: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], toolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbar", required: false }] }], enterPressed: [{ type: i0.Output, args: ["enterPressed"] }] } });
176
180
 
177
181
  const BEM_BLOCK$1 = 'rt-message-composer';
182
+ /** Текст в поле выше полутора строк — он перенёсся, и капсула берёт скругление высокой. */
183
+ function rtComposerWraps(node) {
184
+ const style = getComputedStyle(node);
185
+ const line = parseFloat(style.lineHeight) || parseFloat(style.fontSize) * 1.5;
186
+ const text = node.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);
187
+ return text > line * 1.5;
188
+ }
178
189
  /**
179
- * Композер сообщения: авто-растущая textarea сверху, под разделительной линией —
180
- * ряд контролов (слева — прикрепить файл, справа — отправить). Презентационный,
181
- * без data-access: наружу торчит только `submitted` с текстом и файлами.
190
+ * Композер сообщения — капсула: слева круглая кнопка вложения, по центру авто-растущая
191
+ * textarea, справа круглая кнопка отправки; вложения стоят внутри капсулы над строкой.
192
+ * Презентационный, без data-access: наружу торчит только `submitted` с текстом и файлами.
182
193
  *
183
194
  * Отправка — `Enter` (без Shift) или клик по иконке; `Shift+Enter` — перенос
184
195
  * строки. Кнопка отправки активна, пока есть непустой текст или вложения.
196
+ *
197
+ * Со `stoppable` во время `sending` вместо стрелки стоит кнопка «Стоп», а поле
198
+ * остаётся открытым: следующий вопрос набирается, пока идёт ответ.
185
199
  */
186
200
  class RtMessageComposerComponent {
187
201
  #formValue;
188
202
  #t_chatPlaceholder;
203
+ /** Текст перенёсся на вторую строку — меряется по высоте textarea после отрисовки. */
204
+ #multiRow;
189
205
  constructor() {
190
206
  this.#t_chatPlaceholder = rtKitLabel('chatPlaceholder');
207
+ /** Текст перенёсся на вторую строку — меряется по высоте textarea после отрисовки. */
208
+ this.#multiRow = signal(false, /* @ts-ignore */
209
+ ...(ngDevMode ? [{ debugName: "#multiRow" }] : /* istanbul ignore next */ []));
191
210
  this.t = inject(RT_KIT_LABELS);
192
211
  this.placeholderText = computed(() => this.placeholder() || this.#t_chatPlaceholder(), /* @ts-ignore */
193
212
  ...(ngDevMode ? [{ debugName: "placeholderText" }] : /* istanbul ignore next */ []));
194
213
  this.fileInput = viewChild('fileEl', /* @ts-ignore */
195
214
  ...(ngDevMode ? [{ debugName: "fileInput" }] : /* istanbul ignore next */ []));
215
+ this.textInput = viewChild('textEl', /* @ts-ignore */
216
+ ...(ngDevMode ? [{ debugName: "textInput" }] : /* istanbul ignore next */ []));
217
+ this.richEditor = viewChild(RtRichEditorComponent, /* @ts-ignore */
218
+ ...(ngDevMode ? [{ debugName: "richEditor" }] : /* istanbul ignore next */ []));
196
219
  this.form = new FormGroup({
197
220
  message: new FormControl('', { nonNullable: true }),
198
221
  files: new FormControl([], { nonNullable: true }),
@@ -214,16 +237,34 @@ class RtMessageComposerComponent {
214
237
  return hasText || hasFiles;
215
238
  }, /* @ts-ignore */
216
239
  ...(ngDevMode ? [{ debugName: "canSend" }] : /* istanbul ignore next */ []));
240
+ /** Капсула выше одной строки: перенос текста, вложения или режим форматирования. */
241
+ this.tall = computed(() => this.#multiRow() || this.formatting() || (this.attachments() && this.files().length > 0), /* @ts-ignore */
242
+ ...(ngDevMode ? [{ debugName: "tall" }] : /* istanbul ignore next */ []));
243
+ /** Идёт ответ, который можно остановить: вместо стрелки — «Стоп», поле открыто. */
244
+ this.isStoppable = computed(() => this.stoppable() && this.sending() && !this.disabled(), /* @ts-ignore */
245
+ ...(ngDevMode ? [{ debugName: "isStoppable" }] : /* istanbul ignore next */ []));
246
+ this.capsuleMods = computed(() => ({
247
+ tall: this.tall(),
248
+ disabled: this.disabled(),
249
+ }), /* @ts-ignore */
250
+ ...(ngDevMode ? [{ debugName: "capsuleMods" }] : /* istanbul ignore next */ []));
217
251
  /** Текст-подсказка textarea. Пусто — берётся переведённое умолчание. */
218
252
  this.placeholder = input('', /* @ts-ignore */
219
253
  ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
220
254
  /** Фильтр типов для file-input (`.pdf,.doc,...`). */
221
255
  this.accept = input('', /* @ts-ignore */
222
256
  ...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
257
+ /** Строка под капсулой про Enter и Shift + Enter. */
258
+ this.hint = input(false, { ...(ngDevMode ? { debugName: "hint" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
223
259
  /** Показывать кнопку вложения и список файлов. */
224
260
  this.attachments = input(false, { ...(ngDevMode ? { debugName: "attachments" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
225
- /** Отправка в процессе — блокирует submit и показывает её недоступность. */
261
+ /** Отправка в процессе — блокирует submit, кнопка отправки крутит индикатор. */
226
262
  this.sending = input(false, { ...(ngDevMode ? { debugName: "sending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
263
+ /**
264
+ * Ответ на сообщение можно остановить. Во время `sending` стрелку сменяет кнопка
265
+ * «Стоп», а поле не блокируется; без входа `sending` блокирует поле, как раньше.
266
+ */
267
+ this.stoppable = input(false, { ...(ngDevMode ? { debugName: "stoppable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
227
268
  /** Полная блокировка композера. */
228
269
  this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
229
270
  /** Rich-режим: вместо textarea — Quill-редактор, отправка уходит delta-каналом. */
@@ -244,11 +285,23 @@ class RtMessageComposerComponent {
244
285
  ...(ngDevMode ? [{ debugName: "droppedFiles" }] : /* istanbul ignore next */ []));
245
286
  /** Отправка сообщения: текст + файлы (последние — только при `attachments`). */
246
287
  this.submitted = output();
288
+ /** Черновик поля без форматирования: задаётся снаружи, правки уходят наружу, после отправки пуст. */
289
+ this.text = model('', /* @ts-ignore */
290
+ ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
291
+ /** Клик по кнопке «Стоп» во время ответа, который можно остановить. */
292
+ this.stopped = output();
247
293
  this.#formValue = toSignal(this.form.valueChanges, {
248
294
  initialValue: this.form.value,
249
295
  });
250
296
  effect(() => {
251
- const blocked = this.disabled() || this.sending();
297
+ const draft = this.text();
298
+ if (this.form.controls.message.value !== draft) {
299
+ this.form.controls.message.setValue(draft);
300
+ }
301
+ });
302
+ this.form.controls.message.valueChanges.pipe(takeUntilDestroyed()).subscribe((value) => this.text.set(value));
303
+ effect(() => {
304
+ const blocked = this.disabled() || (this.sending() && !this.stoppable());
252
305
  if (blocked && this.form.enabled) {
253
306
  this.form.disable({ emitEvent: false });
254
307
  }
@@ -256,6 +309,17 @@ class RtMessageComposerComponent {
256
309
  this.form.enable({ emitEvent: false });
257
310
  }
258
311
  });
312
+ // Поле пересоздаётся при смене режима форматирования: наблюдатель идёт за текущим узлом.
313
+ effect((onCleanup) => {
314
+ const node = this.textInput()?.nativeElement;
315
+ if (!node || typeof ResizeObserver === 'undefined') {
316
+ this.#multiRow.set(false);
317
+ return;
318
+ }
319
+ const observer = new ResizeObserver(() => this.#multiRow.set(rtComposerWraps(node)));
320
+ observer.observe(node);
321
+ onCleanup(() => observer.disconnect());
322
+ });
259
323
  effect(() => {
260
324
  const dropped = this.droppedFiles();
261
325
  if (dropped !== null && dropped.length > 0 && this.attachments()) {
@@ -263,6 +327,14 @@ class RtMessageComposerComponent {
263
327
  }
264
328
  });
265
329
  }
330
+ /** Ставит фокус в поле: в textarea, а в режиме форматирования — в rich-редактор. */
331
+ focus() {
332
+ if (this.formatting()) {
333
+ this.richEditor()?.focus();
334
+ return;
335
+ }
336
+ this.textInput()?.nativeElement.focus();
337
+ }
266
338
  onKeydown(event) {
267
339
  // Enter без модификаторов — отправка; Shift+Enter оставляем переносом строки.
268
340
  // isComposing — не перехватываем подтверждение IME-композиции.
@@ -271,6 +343,11 @@ class RtMessageComposerComponent {
271
343
  this.submit();
272
344
  }
273
345
  }
346
+ stop() {
347
+ if (this.isStoppable()) {
348
+ this.stopped.emit();
349
+ }
350
+ }
274
351
  openPicker() {
275
352
  if (this.disabled() || this.sending()) {
276
353
  return;
@@ -310,13 +387,13 @@ class RtMessageComposerComponent {
310
387
  this.form.reset({ message: '', files: [], delta: null });
311
388
  }
312
389
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtMessageComposerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
313
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtMessageComposerComponent, isStandalone: true, selector: "rt-message-composer", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, sending: { classPropertyName: "sending", publicName: "sending", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, formatting: { classPropertyName: "formatting", publicName: "formatting", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, minRows: { classPropertyName: "minRows", publicName: "minRows", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, droppedFiles: { classPropertyName: "droppedFiles", publicName: "droppedFiles", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitted: "submitted" }, host: { classAttribute: "rt-message-composer" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container rtBlock=\"rt-message-composer\" [formGroup]=\"form\">\n @if (formatting()) {\n <rt-rich-editor\n qa-dataid=\"message-composer-rich\"\n formControlName=\"delta\"\n [placeholder]=\"placeholderText()\"\n [toolbar]=\"toolbar()\"\n (enterPressed)=\"submit()\" />\n } @else {\n <textarea\n rtElem=\"input\"\n qa-dataid=\"message-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholderText()\"\n [cdkAutosizeMinRows]=\"minRows()\"\n [cdkAutosizeMaxRows]=\"maxRows()\"\n (keydown)=\"onKeydown($event)\"></textarea>\n }\n\n @if (attachments() && files().length) {\n <div rtElem=\"files\" qa-dataid=\"message-composer-files\">\n @for (file of files(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"message-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"disabled() || sending()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n\n <div rtElem=\"divider\"></div>\n\n <div rtElem=\"controls\">\n @if (attachments()) {\n <input\n #fileEl\n qa-dataid=\"message-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=\"message-composer-attach\"\n icon=\"paperclip\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"disabled() || sending()\"\n (clicked)=\"openPicker()\" />\n }\n\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-send\"\n icon=\"send\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatSendAria\"\n [tooltip]=\"t().chatSendLabel\"\n [disabled]=\"!canSend()\"\n (clicked)=\"submit()\" />\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-message-composer{--rt-message-composer-radius: var(--rt-radius-md);--rt-message-composer-border-width: var(--rt-border-width-thin);--rt-message-composer-divider-width: var(--rt-border-width-thin);display:flex;flex-direction:column;padding:var(--rt-space-4);border:var(--rt-message-composer-border-width) solid var(--rt-color-border-default);border-radius:var(--rt-message-composer-radius);background:var(--rt-color-bg-surface);gap:var(--rt-space-2);inline-size:100%}.rt-message-composer:focus-within{border-color:var(--rt-color-border-strong)}.rt-message-composer__input{padding:0;border:0;margin:0;background:transparent;color:inherit;font:inherit;font-size:var(--rt-text-sm);inline-size:100%;line-height:var(--rt-leading-snug);min-inline-size:0;outline:0;resize:none}.rt-message-composer__input::placeholder{color:var(--rt-color-text-muted)}.rt-message-composer__input:disabled{cursor:not-allowed}.rt-message-composer__files{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-message-composer__divider{background:var(--rt-color-border-default);block-size:var(--rt-message-composer-divider-width);margin-inline:calc(-1 * var(--rt-space-4))}.rt-message-composer__controls{display:flex;align-items:center;gap:var(--rt-space-2)}.rt-message-composer__send{margin-inline-start:auto}}\n"], dependencies: [{ kind: "ngmodule", type:
390
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtMessageComposerComponent, isStandalone: true, selector: "rt-message-composer", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, attachments: { classPropertyName: "attachments", publicName: "attachments", isSignal: true, isRequired: false, transformFunction: null }, sending: { classPropertyName: "sending", publicName: "sending", isSignal: true, isRequired: false, transformFunction: null }, stoppable: { classPropertyName: "stoppable", publicName: "stoppable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, formatting: { classPropertyName: "formatting", publicName: "formatting", isSignal: true, isRequired: false, transformFunction: null }, toolbar: { classPropertyName: "toolbar", publicName: "toolbar", isSignal: true, isRequired: false, transformFunction: null }, minRows: { classPropertyName: "minRows", publicName: "minRows", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, droppedFiles: { classPropertyName: "droppedFiles", publicName: "droppedFiles", isSignal: true, isRequired: false, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitted: "submitted", text: "textChange", stopped: "stopped" }, host: { classAttribute: "rt-message-composer" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileEl"], descendants: true, isSignal: true }, { propertyName: "textInput", first: true, predicate: ["textEl"], descendants: true, isSignal: true }, { propertyName: "richEditor", first: true, predicate: RtRichEditorComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container rtBlock=\"rt-message-composer\" [formGroup]=\"form\">\n <div rtElem=\"capsule\" qa-dataid=\"message-composer-capsule\" [rtMod]=\"capsuleMods()\">\n @if (attachments() && files().length) {\n <div rtElem=\"files\" qa-dataid=\"message-composer-files\">\n @for (file of files(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"message-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"disabled() || sending()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n\n @if (formatting()) {\n <rt-rich-editor\n rtElem=\"rich\"\n qa-dataid=\"message-composer-rich\"\n formControlName=\"delta\"\n [placeholder]=\"placeholderText()\"\n [toolbar]=\"toolbar()\"\n (enterPressed)=\"submit()\" />\n }\n\n <div rtElem=\"row\">\n @if (attachments()) {\n <input\n #fileEl\n qa-dataid=\"message-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=\"message-composer-attach\"\n icon=\"paperclip\"\n iconColor=\"muted\"\n radius=\"full\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"disabled() || sending()\"\n (clicked)=\"openPicker()\" />\n }\n\n @if (!formatting()) {\n <textarea\n #textEl\n rtElem=\"input\"\n qa-dataid=\"message-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholderText()\"\n [cdkAutosizeMinRows]=\"minRows()\"\n [cdkAutosizeMaxRows]=\"maxRows()\"\n (keydown)=\"onKeydown($event)\"></textarea>\n }\n\n @if (isStoppable()) {\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-stop\"\n icon=\"stop\"\n radius=\"full\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatStopAria\"\n [tooltip]=\"t().chatStopLabel\"\n (clicked)=\"stop()\" />\n } @else {\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-send\"\n icon=\"arrow-up\"\n radius=\"full\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatSendAria\"\n [tooltip]=\"t().chatSendLabel\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"\n (clicked)=\"submit()\" />\n }\n </div>\n </div>\n\n @if (hint()) {\n <p rtElem=\"hint\" qa-dataid=\"message-composer-hint\">{{ t().chatComposerHint }}</p>\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-message-composer{--rt-message-composer-radius: var(--rt-radius-full);--rt-message-composer-tall-radius: var(--rt-radius-2xl);--rt-message-composer-border-width: var(--rt-border-width-thin);display:flex;flex-direction:column;gap:calc(var(--rt-space-1) * 1.5);inline-size:100%}.rt-message-composer__capsule{display:flex;flex-direction:column;padding:calc(var(--rt-space-1) * 1.5);border:var(--rt-message-composer-border-width) solid var(--rt-input-color-border);border-radius:var(--rt-message-composer-radius);background:var(--rt-input-color-bg);gap:calc(var(--rt-space-1) * 1.5)}.rt-message-composer__capsule:focus-within{border-color:var(--rt-input-color-border-focus);background:var(--rt-color-bg-surface);box-shadow:var(--rt-input-focus-shadow)}.rt-message-composer__capsule--tall{--rt-message-composer-radius: var(--rt-message-composer-tall-radius)}.rt-message-composer__capsule--disabled{background:var(--rt-input-color-bg-disabled)}.rt-message-composer__files{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-message-composer__rich{inline-size:100%}.rt-message-composer__row{display:flex;align-items:flex-end;gap:var(--rt-space-2)}.rt-message-composer__input{box-sizing:content-box;flex:1 1 auto;border:0;margin:0;background:transparent;color:var(--rt-input-color-text);font:inherit;font-size:var(--rt-input-font-size);inline-size:100%;line-height:var(--rt-leading-normal);margin-inline-start:calc(var(--rt-space-1) * 1.5);min-inline-size:0;outline:0;padding-block:calc((var(--rt-control-height-md) - 1lh) / 2);resize:none;scrollbar-color:var(--rt-color-border-default) transparent;scrollbar-gutter:stable;scrollbar-width:thin}.rt-message-composer__input::placeholder{color:var(--rt-input-color-text-placeholder)}.rt-message-composer__input:disabled{cursor:not-allowed}.rt-message-composer__input:disabled::placeholder{color:var(--rt-color-text-disabled)}.rt-message-composer__send{margin-inline-start:auto}.rt-message-composer__hint{margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug)}}\n"], dependencies: [{ kind: "ngmodule", type:
314
391
  // angular
315
392
  ReactiveFormsModule }, { 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:
316
393
  // cdk
317
394
  CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "component", type:
318
395
  // standalone components / directives
319
- 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", "shape", "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"] }], 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", "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 }); }
320
397
  }
321
398
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtMessageComposerComponent, decorators: [{
322
399
  type: Component,
@@ -331,10 +408,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
331
408
  RtRichEditorComponent,
332
409
  BlockDirective,
333
410
  ElemDirective,
411
+ ModDirective,
334
412
  ], host: {
335
413
  class: BEM_BLOCK$1,
336
- }, template: "<ng-container rtBlock=\"rt-message-composer\" [formGroup]=\"form\">\n @if (formatting()) {\n <rt-rich-editor\n qa-dataid=\"message-composer-rich\"\n formControlName=\"delta\"\n [placeholder]=\"placeholderText()\"\n [toolbar]=\"toolbar()\"\n (enterPressed)=\"submit()\" />\n } @else {\n <textarea\n rtElem=\"input\"\n qa-dataid=\"message-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholderText()\"\n [cdkAutosizeMinRows]=\"minRows()\"\n [cdkAutosizeMaxRows]=\"maxRows()\"\n (keydown)=\"onKeydown($event)\"></textarea>\n }\n\n @if (attachments() && files().length) {\n <div rtElem=\"files\" qa-dataid=\"message-composer-files\">\n @for (file of files(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"message-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"disabled() || sending()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n\n <div rtElem=\"divider\"></div>\n\n <div rtElem=\"controls\">\n @if (attachments()) {\n <input\n #fileEl\n qa-dataid=\"message-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=\"message-composer-attach\"\n icon=\"paperclip\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"disabled() || sending()\"\n (clicked)=\"openPicker()\" />\n }\n\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-send\"\n icon=\"send\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatSendAria\"\n [tooltip]=\"t().chatSendLabel\"\n [disabled]=\"!canSend()\"\n (clicked)=\"submit()\" />\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-message-composer{--rt-message-composer-radius: var(--rt-radius-md);--rt-message-composer-border-width: var(--rt-border-width-thin);--rt-message-composer-divider-width: var(--rt-border-width-thin);display:flex;flex-direction:column;padding:var(--rt-space-4);border:var(--rt-message-composer-border-width) solid var(--rt-color-border-default);border-radius:var(--rt-message-composer-radius);background:var(--rt-color-bg-surface);gap:var(--rt-space-2);inline-size:100%}.rt-message-composer:focus-within{border-color:var(--rt-color-border-strong)}.rt-message-composer__input{padding:0;border:0;margin:0;background:transparent;color:inherit;font:inherit;font-size:var(--rt-text-sm);inline-size:100%;line-height:var(--rt-leading-snug);min-inline-size:0;outline:0;resize:none}.rt-message-composer__input::placeholder{color:var(--rt-color-text-muted)}.rt-message-composer__input:disabled{cursor:not-allowed}.rt-message-composer__files{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-message-composer__divider{background:var(--rt-color-border-default);block-size:var(--rt-message-composer-divider-width);margin-inline:calc(-1 * var(--rt-space-4))}.rt-message-composer__controls{display:flex;align-items:center;gap:var(--rt-space-2)}.rt-message-composer__send{margin-inline-start:auto}}\n"] }]
337
- }], ctorParameters: () => [], propDecorators: { fileInput: [{ type: i0.ViewChild, args: ['fileEl', { isSignal: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], attachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachments", required: false }] }], sending: [{ type: i0.Input, args: [{ isSignal: true, alias: "sending", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], formatting: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatting", required: false }] }], toolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbar", required: false }] }], minRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "minRows", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], droppedFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "droppedFiles", required: false }] }], submitted: [{ type: i0.Output, args: ["submitted"] }] } });
414
+ }, template: "<ng-container rtBlock=\"rt-message-composer\" [formGroup]=\"form\">\n <div rtElem=\"capsule\" qa-dataid=\"message-composer-capsule\" [rtMod]=\"capsuleMods()\">\n @if (attachments() && files().length) {\n <div rtElem=\"files\" qa-dataid=\"message-composer-files\">\n @for (file of files(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"message-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"disabled() || sending()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n\n @if (formatting()) {\n <rt-rich-editor\n rtElem=\"rich\"\n qa-dataid=\"message-composer-rich\"\n formControlName=\"delta\"\n [placeholder]=\"placeholderText()\"\n [toolbar]=\"toolbar()\"\n (enterPressed)=\"submit()\" />\n }\n\n <div rtElem=\"row\">\n @if (attachments()) {\n <input\n #fileEl\n qa-dataid=\"message-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=\"message-composer-attach\"\n icon=\"paperclip\"\n iconColor=\"muted\"\n radius=\"full\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"disabled() || sending()\"\n (clicked)=\"openPicker()\" />\n }\n\n @if (!formatting()) {\n <textarea\n #textEl\n rtElem=\"input\"\n qa-dataid=\"message-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholderText()\"\n [cdkAutosizeMinRows]=\"minRows()\"\n [cdkAutosizeMaxRows]=\"maxRows()\"\n (keydown)=\"onKeydown($event)\"></textarea>\n }\n\n @if (isStoppable()) {\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-stop\"\n icon=\"stop\"\n radius=\"full\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatStopAria\"\n [tooltip]=\"t().chatStopLabel\"\n (clicked)=\"stop()\" />\n } @else {\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-send\"\n icon=\"arrow-up\"\n radius=\"full\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatSendAria\"\n [tooltip]=\"t().chatSendLabel\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"\n (clicked)=\"submit()\" />\n }\n </div>\n </div>\n\n @if (hint()) {\n <p rtElem=\"hint\" qa-dataid=\"message-composer-hint\">{{ t().chatComposerHint }}</p>\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-message-composer{--rt-message-composer-radius: var(--rt-radius-full);--rt-message-composer-tall-radius: var(--rt-radius-2xl);--rt-message-composer-border-width: var(--rt-border-width-thin);display:flex;flex-direction:column;gap:calc(var(--rt-space-1) * 1.5);inline-size:100%}.rt-message-composer__capsule{display:flex;flex-direction:column;padding:calc(var(--rt-space-1) * 1.5);border:var(--rt-message-composer-border-width) solid var(--rt-input-color-border);border-radius:var(--rt-message-composer-radius);background:var(--rt-input-color-bg);gap:calc(var(--rt-space-1) * 1.5)}.rt-message-composer__capsule:focus-within{border-color:var(--rt-input-color-border-focus);background:var(--rt-color-bg-surface);box-shadow:var(--rt-input-focus-shadow)}.rt-message-composer__capsule--tall{--rt-message-composer-radius: var(--rt-message-composer-tall-radius)}.rt-message-composer__capsule--disabled{background:var(--rt-input-color-bg-disabled)}.rt-message-composer__files{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-message-composer__rich{inline-size:100%}.rt-message-composer__row{display:flex;align-items:flex-end;gap:var(--rt-space-2)}.rt-message-composer__input{box-sizing:content-box;flex:1 1 auto;border:0;margin:0;background:transparent;color:var(--rt-input-color-text);font:inherit;font-size:var(--rt-input-font-size);inline-size:100%;line-height:var(--rt-leading-normal);margin-inline-start:calc(var(--rt-space-1) * 1.5);min-inline-size:0;outline:0;padding-block:calc((var(--rt-control-height-md) - 1lh) / 2);resize:none;scrollbar-color:var(--rt-color-border-default) transparent;scrollbar-gutter:stable;scrollbar-width:thin}.rt-message-composer__input::placeholder{color:var(--rt-input-color-text-placeholder)}.rt-message-composer__input:disabled{cursor:not-allowed}.rt-message-composer__input:disabled::placeholder{color:var(--rt-color-text-disabled)}.rt-message-composer__send{margin-inline-start:auto}.rt-message-composer__hint{margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug)}}\n"] }]
415
+ }], ctorParameters: () => [], propDecorators: { fileInput: [{ type: i0.ViewChild, args: ['fileEl', { isSignal: true }] }], textInput: [{ type: i0.ViewChild, args: ['textEl', { isSignal: true }] }], richEditor: [{ type: i0.ViewChild, args: [i0.forwardRef(() => RtRichEditorComponent), { isSignal: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], attachments: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachments", required: false }] }], sending: [{ type: i0.Input, args: [{ isSignal: true, alias: "sending", required: false }] }], stoppable: [{ type: i0.Input, args: [{ isSignal: true, alias: "stoppable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], formatting: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatting", required: false }] }], toolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolbar", required: false }] }], minRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "minRows", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], droppedFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "droppedFiles", required: false }] }], submitted: [{ type: i0.Output, args: ["submitted"] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }, { type: i0.Output, args: ["textChange"] }], stopped: [{ type: i0.Output, args: ["stopped"] }] } });
338
416
 
339
417
  /**
340
418
  * Захватывает `<ng-template rtChatMessageActions let-message>` — содержимое «…»-меню
@@ -834,7 +912,7 @@ class RtChatComponent {
834
912
  // Angular
835
913
  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:
836
914
  // standalone components / directives
837
- RtButtonDirective, selector: "button[rtButton], a[rtButton]", inputs: ["label", "icon", "iconPos", "theme", "appearance", "size", "rounded", "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", "shape", "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", "attachments", "sending", "disabled", "formatting", "toolbar", "minRows", "maxRows", "droppedFiles"], outputs: ["submitted"] }, { kind: "component", type: RtNoteComponent, selector: "rt-note" }, { kind: "component", type: RtSkeletonWrapperComponent, selector: "rt-skeleton-wrapper", inputs: ["width", "height", "shape", "size", "borderRadius", "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 }); }
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 }); }
838
916
  }
839
917
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtChatComponent, decorators: [{
840
918
  type: Component,