@rt-tools/ui-kit-v2 0.1.0 → 0.3.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 (111) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2.mjs +313 -205
  2. package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
  3. package/package.json +1 -1
  4. package/rt-tools-ui-kit-v2-0.3.0.tgz +0 -0
  5. package/src/lib/components/CONTEXT.md +49 -0
  6. package/src/lib/components/aside/CONTEXT.md +51 -0
  7. package/src/lib/components/aside/_rt-aside-overlay.scss +88 -0
  8. package/src/lib/components/aside/rt-aside.component.scss +19 -94
  9. package/src/lib/components/aside-section/CONTEXT.md +26 -0
  10. package/src/lib/components/autocomplete/CONTEXT.md +58 -0
  11. package/src/lib/components/bar-list/CONTEXT.md +27 -0
  12. package/src/lib/components/bar-list/rt-bar-list.component.scss +5 -2
  13. package/src/lib/components/bottom-sheet/CONTEXT.md +54 -0
  14. package/src/lib/components/bottom-sheet/rt-bottom-sheet.component.scss +53 -53
  15. package/src/lib/components/button/CONTEXT.md +53 -0
  16. package/src/lib/components/button/rt-button.directive.scss +16 -0
  17. package/src/lib/components/calendar/CONTEXT.md +41 -0
  18. package/src/lib/components/calendar/rt-calendar.component.scss +96 -99
  19. package/src/lib/components/card/CONTEXT.md +34 -0
  20. package/src/lib/components/card/rt-card.component.scss +5 -2
  21. package/src/lib/components/chat/CONTEXT.md +41 -0
  22. package/src/lib/components/checkbox/CONTEXT.md +37 -0
  23. package/src/lib/components/checkbox/rt-checkbox.component.scss +7 -2
  24. package/src/lib/components/collapsible-text/CONTEXT.md +29 -0
  25. package/src/lib/components/confirm-popover/CONTEXT.md +47 -0
  26. package/src/lib/components/container/CONTEXT.md +42 -0
  27. package/src/lib/components/container/rt-container.component.scss +5 -69
  28. package/src/lib/components/counter/CONTEXT.md +40 -0
  29. package/src/lib/components/counter/rt-counter.component.scss +10 -9
  30. package/src/lib/components/counter-row/CONTEXT.md +24 -0
  31. package/src/lib/components/counter-row/rt-counter-row.component.scss +23 -22
  32. package/src/lib/components/date-picker/CONTEXT.md +41 -0
  33. package/src/lib/components/delta-view/CONTEXT.md +31 -0
  34. package/src/lib/components/detail-list/CONTEXT.md +29 -0
  35. package/src/lib/components/dialog/CONTEXT.md +50 -0
  36. package/src/lib/components/dialog/rt-dialog.component.scss +6 -2
  37. package/src/lib/components/download-link/CONTEXT.md +26 -0
  38. package/src/lib/components/empty-state/CONTEXT.md +35 -0
  39. package/src/lib/components/field/CONTEXT.md +72 -0
  40. package/src/lib/components/file-card/CONTEXT.md +28 -0
  41. package/src/lib/components/file-drop/CONTEXT.md +39 -0
  42. package/src/lib/components/file-input/CONTEXT.md +36 -0
  43. package/src/lib/components/file-list/CONTEXT.md +15 -0
  44. package/src/lib/components/filter-control/CONTEXT.md +33 -0
  45. package/src/lib/components/form-control/CONTEXT.md +50 -0
  46. package/src/lib/components/header/CONTEXT.md +36 -0
  47. package/src/lib/components/icon/CONTEXT.md +46 -0
  48. package/src/lib/components/icon/rt-icon.component.scss +3 -5
  49. package/src/lib/components/icon-button/CONTEXT.md +49 -0
  50. package/src/lib/components/icon-button/rt-icon-button.component.scss +14 -1
  51. package/src/lib/components/info-item/CONTEXT.md +30 -0
  52. package/src/lib/components/input/CONTEXT.md +47 -0
  53. package/src/lib/components/input-number/CONTEXT.md +52 -0
  54. package/src/lib/components/live-badge/CONTEXT.md +31 -0
  55. package/src/lib/components/live-badge/rt-live-badge.component.scss +5 -2
  56. package/src/lib/components/logo/CONTEXT.md +42 -0
  57. package/src/lib/components/logo/rt-logo.component.scss +4 -6
  58. package/src/lib/components/menu/CONTEXT.md +65 -0
  59. package/src/lib/components/message/CONTEXT.md +35 -0
  60. package/src/lib/components/message/rt-message.component.scss +5 -2
  61. package/src/lib/components/message-composer/CONTEXT.md +46 -0
  62. package/src/lib/components/money-list/CONTEXT.md +32 -0
  63. package/src/lib/components/multiselect/CONTEXT.md +43 -0
  64. package/src/lib/components/night-grid/CONTEXT.md +31 -0
  65. package/src/lib/components/night-grid/rt-night-grid.component.scss +5 -2
  66. package/src/lib/components/note/CONTEXT.md +27 -0
  67. package/src/lib/components/notifications-bell/CONTEXT.md +29 -0
  68. package/src/lib/components/page-header/CONTEXT.md +33 -0
  69. package/src/lib/components/pagination/CONTEXT.md +43 -0
  70. package/src/lib/components/photo-viewer/CONTEXT.md +30 -0
  71. package/src/lib/components/photo-viewer/rt-photo-viewer.component.scss +95 -96
  72. package/src/lib/components/popover/CONTEXT.md +54 -0
  73. package/src/lib/components/rich-editor/CONTEXT.md +36 -0
  74. package/src/lib/components/section-nav/CONTEXT.md +27 -0
  75. package/src/lib/components/section-nav/rt-section-nav.component.scss +7 -1
  76. package/src/lib/components/select/CONTEXT.md +54 -0
  77. package/src/lib/components/skeleton/CONTEXT.md +41 -0
  78. package/src/lib/components/skeleton-wrapper/CONTEXT.md +24 -0
  79. package/src/lib/components/skeleton-wrapper/rt-skeleton-wrapper.component.scss +5 -1
  80. package/src/lib/components/spinner/CONTEXT.md +39 -0
  81. package/src/lib/components/split-button/CONTEXT.md +39 -0
  82. package/src/lib/components/stat-tile/CONTEXT.md +35 -0
  83. package/src/lib/components/stat-tile/rt-stat-tile.component.scss +5 -2
  84. package/src/lib/components/stepper/CONTEXT.md +36 -0
  85. package/src/lib/components/stepper/rt-stepper.component.scss +5 -2
  86. package/src/lib/components/table/CONTEXT.md +53 -0
  87. package/src/lib/components/table/settings-aside/rt-table-settings-aside.component.scss +4 -2
  88. package/src/lib/components/table/settings-panel/rt-table-settings-panel.component.scss +1 -1
  89. package/src/lib/components/tabs/CONTEXT.md +56 -0
  90. package/src/lib/components/tag/CONTEXT.md +47 -0
  91. package/src/lib/components/tag/rt-tag.component.scss +5 -2
  92. package/src/lib/components/textarea/CONTEXT.md +38 -0
  93. package/src/lib/components/theme-toggle/CONTEXT.md +28 -0
  94. package/src/lib/components/theme-toggle/rt-theme-toggle.component.scss +5 -1
  95. package/src/lib/components/thread-list/CONTEXT.md +42 -0
  96. package/src/lib/components/timeline/CONTEXT.md +33 -0
  97. package/src/lib/components/timeline/rt-timeline.component.scss +5 -2
  98. package/src/lib/components/toast/CONTEXT.md +53 -0
  99. package/src/lib/components/toggle-button-group/CONTEXT.md +38 -0
  100. package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +12 -7
  101. package/src/lib/components/toggle-switch/CONTEXT.md +35 -0
  102. package/src/lib/components/toggle-switch/rt-toggle-switch.component.scss +7 -2
  103. package/src/lib/components/toolbar/CONTEXT.md +22 -0
  104. package/src/lib/components/tooltip/CONTEXT.md +34 -0
  105. package/src/lib/components/welcome-dialog/CONTEXT.md +20 -0
  106. package/src/lib/components/welcome-dialog/rt-welcome-dialog.component.scss +6 -2
  107. package/src/lib/components/workspace/CONTEXT.md +46 -0
  108. package/src/lib/components/workspace-details/CONTEXT.md +42 -0
  109. package/styles/tokens.css +14 -0
  110. package/types/rt-tools-ui-kit-v2.d.ts +50 -29
  111. package/rt-tools-ui-kit-v2-0.1.0.tgz +0 -0
@@ -0,0 +1,47 @@
1
+ # `rt-tag`
2
+
3
+ ```html
4
+ <rt-tag value="Активен" severity="success" shape="pill" appearance="solid" icon="check" [closable]="true" (closed)="onClosed($event)" />
5
+ ```
6
+
7
+ | вход | тип | умолчание |
8
+ | ------------------ | -------------------------------------------------------------------------- | -------------- |
9
+ | `value` | `string` | **обязателен** |
10
+ | `severity` | `'info' \| 'success' \| 'warning' \| 'danger' \| 'secondary' \| 'neutral'` | `'neutral'` |
11
+ | `shape` | `'pill' \| 'square'` | `'pill'` |
12
+ | `appearance` | `'solid' \| 'outlined'` | `'solid'` |
13
+ | `radius` | `'none' \| 'sm' \| 'md' \| 'lg' \| 'full' \| null` | `null` |
14
+ | `icon` / `iconEnd` | `IRtIcon.Name \| null` | `null` |
15
+ | `closable` | `boolean` | `false` |
16
+
17
+ | выход | тип |
18
+ | -------- | ------------ |
19
+ | `closed` | `MouseEvent` |
20
+
21
+ ## Главное, что нужно знать
22
+
23
+ **Крестик не закрывает тег.** `closed` только сообщает о клике — убрать тег из списка обязан
24
+ потребитель. Компонент состояния не держит.
25
+
26
+ Клик по крестику **не всплывает** (`stopPropagation`): пилюля целиком часто сама кликабельна,
27
+ и без этого одно нажатие срабатывало бы дважды.
28
+
29
+ ## Как этим пользоваться
30
+
31
+ - `radius` перебивает скругление, заданное формой. Без него класс скругления не выводится
32
+ вовсе — радиус берётся из `shape`.
33
+ - Палитра дублируется атрибутом `data-severity` — по нему тег находят проверки и внешние стили,
34
+ не завязываясь на BEM-класс.
35
+ - Подпись крестика для скринридера берётся из словаря кита (`rtKit.uiRemove`). Без
36
+ `provideRtKitTranslations()` там будет пусто.
37
+
38
+ ## Края
39
+
40
+ - `value` — обязательный вход: тег без текста не бывает. Иконка без текста — это
41
+ [`rt-icon-button`](../icon-button/CONTEXT.md), а не тег.
42
+ - Модификаторы выводятся BEM-директивами: `rt-tag--severity--success`, `rt-tag--shape--square`,
43
+ булев `closable` даёт `rt-tag--closable` без значения.
44
+
45
+ ## Рядом
46
+
47
+ - [`rt-live-badge`](../live-badge/CONTEXT.md) — пилюля живого счётчика, а не статуса.
@@ -1,6 +1,9 @@
1
- /* rt-tag — status pill в common/ui (Emulated encapsulation; :host обязательно). */
1
+ /* rt-tag — status pill в common/ui. ViewEncapsulation.None.
2
+ Хост адресуется по имени элемента, а не по классу блока: класс `.rt-tag` висит
3
+ и на `<rt-tag>`, и на корне шаблона, поэтому правила блока вложены в хост —
4
+ так они достаются только корню шаблона. */
2
5
 
3
- :host {
6
+ rt-tag {
4
7
  display: inline-flex;
5
8
 
6
9
  .rt-tag {
@@ -0,0 +1,38 @@
1
+ # `rt-textarea`
2
+
3
+ ```html
4
+ <rt-field label="Комментарий">
5
+ <rt-textarea resize="vertical" placeholder="Что уточнить" [formControl]="comment" [rows]="5" />
6
+ </rt-field>
7
+ ```
8
+
9
+ Свои входы поверх общих из [`RtFormControlBase`](../form-control/CONTEXT.md):
10
+
11
+ | вход | тип | умолчание |
12
+ | ------------- | ---------------------- | ------------ |
13
+ | `placeholder` | `string` | `''` |
14
+ | `rows` | `number \| string` | `3` |
15
+ | `resize` | `'none' \| 'vertical'` | `'vertical'` |
16
+ | `readonly` | `boolean` | `false` |
17
+
18
+ Значение — `string`.
19
+
20
+ ## Главное, что нужно знать
21
+
22
+ **Крестик очистки не рисуется.** Вход `clearable` наследуется от общей основы полей, но разметка
23
+ многострочного поля его не использует: в многострочном вводе он нетипичен.
24
+
25
+ **Два разных «только для чтения»:**
26
+
27
+ - свой вход `[readonly]` оставляет `<textarea>` на месте и запрещает правку (нативный `readOnly`);
28
+ - режим от вмещающего [`rt-field`](../field/CONTEXT.md) подменяет контрол плоским текстом.
29
+
30
+ ## Края
31
+
32
+ - `font-family: inherit` прописан явно: без него `<textarea>` падает на моноширинный шрифт
33
+ браузера.
34
+ - Горизонтальное растягивание не предусмотрено — только `none` и `vertical`.
35
+
36
+ ## Рядом
37
+
38
+ - [`rt-rich-editor`](../rich-editor/CONTEXT.md) — когда нужна разметка внутри текста.
@@ -0,0 +1,28 @@
1
+ # `rt-theme-toggle`
2
+
3
+ Переключатель светлой и тёмной темы.
4
+
5
+ ```html
6
+ <rt-theme-toggle appearance="icon" />
7
+ ```
8
+
9
+ | вход | тип | умолчание |
10
+ | ------------ | -------------------- | --------- |
11
+ | `appearance` | `'icon' \| 'switch'` | `'icon'` |
12
+
13
+ Выходов нет.
14
+
15
+ ## Главное, что нужно знать
16
+
17
+ **Своего состояния у контрола нет — тему держит `ThemeService`.**
18
+ Он пишет `data-theme` на `<html>` и сохраняет выбор в хранилище устройства, поэтому тема
19
+ переживает перезагрузку, а два переключателя на странице всегда согласованы.
20
+
21
+ **Иконка показывает, куда переключит**, а не текущее состояние: в светлой теме это луна.
22
+ В виде кнопки текущая тёмная тема помечается `aria-pressed="true"`.
23
+
24
+ ## Края
25
+
26
+ - Подпись берётся из словаря кита (`rtKit.themeToggleLabel`) и вычисляется один раз при создании.
27
+ - В тестах между случаями надо чистить хранилище: иначе выбор предыдущего теста становится
28
+ начальным состоянием следующего.
@@ -1,3 +1,7 @@
1
- :host {
1
+ /* rt-theme-toggle — ViewEncapsulation.None: правило таргетирует BEM-класс блока.
2
+ `.rt-theme-toggle` — сам хост: своей разметки блока у компонента нет, внутри
3
+ только rt-toggle-switch либо rt-icon-button. */
4
+
5
+ .rt-theme-toggle {
2
6
  display: inline-flex;
3
7
  }
@@ -0,0 +1,42 @@
1
+ # `rt-thread-list`
2
+
3
+ Список переписок/заявок с поиском, фильтрами и бесконечной прокруткой. Строку рисует шаблон
4
+ потребителя.
5
+
6
+ ```html
7
+ <rt-thread-list
8
+ [rows]="rows()"
9
+ [activeId]="activeId()"
10
+ [loading]="loading()"
11
+ [hasMore]="hasMore()"
12
+ (selectRow)="open($event)"
13
+ (openInNewTab)="openInTab($event)"
14
+ (searchChange)="search($event)"
15
+ (loadMore)="next()">
16
+ <ng-template rtThreadListRow let-row>…</ng-template>
17
+ <ng-template rtThreadListFilters>…</ng-template>
18
+ </rt-thread-list>
19
+ ```
20
+
21
+ Входы: `rows`, `activeId`, `searchPlaceholder`, `emptyText`, `loading`, `fetching`, `hasMore`,
22
+ `filtersActive`. Выходы: `selectRow`, `openInNewTab`, `searchChange`, `loadMore`.
23
+
24
+ Строка обязана иметь `id`, `hasUnread` и (необязательно) `overdue` — это всё, что список о ней знает.
25
+
26
+ ## Главное, что нужно знать
27
+
28
+ **Ctrl/Cmd+клик просит открыть в новой вкладке, а не выбирает строку.** Список — это навигация,
29
+ и привычка «Ctrl+клик открывает рядом» должна работать.
30
+
31
+ **`loading` подменяет строки заглушками только при пустом списке.** Загрузка поверх уже
32
+ показанных строк их не трогает — иначе список мигал бы при каждой смене фильтра.
33
+
34
+ **Поиск отдаёт значение с задержкой** и без повторов (`searchDebounce` + `distinctUntilChanged`),
35
+ уже обрезанное по краям.
36
+
37
+ ## Края
38
+
39
+ - Якорь догрузки (`rtInfiniteScroll`) появляется только при `hasMore`.
40
+ - Кнопка фильтров рисуется, только если объявлен шаблон `[rtThreadListFilters]`;
41
+ `filtersActive` рисует на ней точку.
42
+ - Собственное поле поиска можно заменить шаблоном `[rtThreadListSearch]`.
@@ -0,0 +1,33 @@
1
+ # `rt-timeline`
2
+
3
+ ```html
4
+ <rt-timeline
5
+ [steps]="[
6
+ { label: 'Заявка создана', meta: '12 марта, 10:00', actor: 'Иванов', status: 'complete' },
7
+ { label: 'На проверке', meta: '12 марта, 12:30', status: 'current' },
8
+ { label: 'Решение', status: 'pending' },
9
+ ]" />
10
+ ```
11
+
12
+ | вход | тип | умолчание |
13
+ | ------- | --------------------------------------------- | --------- |
14
+ | `steps` | `readonly { label, meta?, actor?, status }[]` | `[]` |
15
+
16
+ `status` — `'complete' \| 'current' \| 'pending'`. Выходов нет: лента только показывает.
17
+
18
+ ## Главное, что нужно знать
19
+
20
+ **Порядок шагов — часть смысла**, поэтому лента рисуется тегом `<ol>`, а не набором блоков.
21
+
22
+ Соединительная линия рисуется **между** пунктами и не рисуется после последнего: хвост под
23
+ последним шагом читался бы как «продолжение есть».
24
+
25
+ ## Края
26
+
27
+ - `meta` и `actor` необязательны и рисуются по отдельности: исполнитель без времени допустим.
28
+ - Состояние дублируется атрибутом `data-status` — по нему шаг находят проверки.
29
+ - Пустой набор рисует пустой `<ol>`, а не заглушку: текст «событий нет» подставляет потребитель.
30
+
31
+ ## Рядом
32
+
33
+ - [`rt-stepper`](../stepper/CONTEXT.md) — линейный прогресс по шагам, а не журнал событий.
@@ -1,6 +1,9 @@
1
- /* rt-timeline — вертикальный таймлайн-степпер в common/ui (Emulated; :host обязателен). */
1
+ /* rt-timeline — вертикальный таймлайн-степпер в common/ui. ViewEncapsulation.None.
2
+ Хост адресуется по имени элемента, а не по классу блока: класс `.rt-timeline` висит
3
+ и на `<rt-timeline>`, и на корне шаблона, поэтому правила блока вложены в хост —
4
+ так они достаются только корню шаблона. */
2
5
 
3
- :host {
6
+ rt-timeline {
4
7
  display: block;
5
8
 
6
9
  .rt-timeline {
@@ -0,0 +1,53 @@
1
+ # `rt-toaster` + `rt-toast`
2
+
3
+ Стопка всплывающих уведомлений. В разметку ставится **один** `rt-toaster` — обычно в корне
4
+ приложения; отдельные `rt-toast` он создаёт сам.
5
+
6
+ ```html
7
+ <!-- один раз на приложение -->
8
+ <rt-toaster position="bottom-right" [duration]="4000" [visibleToasts]="3" />
9
+ ```
10
+
11
+ ```typescript
12
+ readonly #notifications: NotificationBus = inject(NotificationBus);
13
+
14
+ this.#notifications.success('Сохранено');
15
+ this.#notifications.error('Не удалось сохранить', 'danger', {
16
+ description: 'Проверьте соединение',
17
+ action: { label: 'Повторить', handler: (): void => this.retry() },
18
+ });
19
+ ```
20
+
21
+ | вход `rt-toaster` | тип | умолчание |
22
+ | ----------------- | ------------------------------------------------------------------------------------------------- | ---------------- |
23
+ | `position` | `'top-left' \| 'top-center' \| 'top-right' \| 'bottom-left' \| 'bottom-center' \| 'bottom-right'` | `'bottom-right'` |
24
+ | `duration` | `number \| string` (мс) | `4000` |
25
+ | `visibleToasts` | `number \| string` | `3` |
26
+ | `expand` | `boolean` | `false` |
27
+
28
+ ## Главное, что нужно знать
29
+
30
+ **Тосты показываются не входом, а шиной.** Стопка подписана на
31
+ `NotificationBus` и других способов показать тост
32
+ нет. Шина — `providedIn: 'root'`, поэтому её достаточно инжектировать где угодно.
33
+
34
+ Четыре метода шины задают палитру и иконку: `success` → `check-circle`, `info` → `info-circle`,
35
+ `warning` → `exclamation-circle`, `error` → `times-circle`.
36
+
37
+ ## Как этим пользоваться
38
+
39
+ - Новый тост встаёт **первым** — стопка растёт сверху.
40
+ - Наведение на стопку разворачивает её и приостанавливает исчезновение; нажатая кнопка мыши
41
+ удерживает развёрнутое состояние до отпускания.
42
+ - `action` и `secondaryAction` рисуются кнопками внутри тоста и зовут переданные обработчики.
43
+ - `meta` — приписка над сообщением (номер заявки), `description` — вторая строка под ним.
44
+ - Положение раскладывается на два модификатора: `rt-toaster--y--bottom` и `rt-toaster--x--right`.
45
+
46
+ ## Доступность
47
+
48
+ Стопка — `role="region"` с переведённой подписью, каждый тост — `role="status"` с
49
+ `aria-atomic="true"`: скринридер читает уведомление целиком, а не по изменившимся кускам.
50
+
51
+ ## Рядом
52
+
53
+ - [`rt-message`](../message/CONTEXT.md) — постоянное сообщение внутри страницы, а не всплывающее.
@@ -0,0 +1,38 @@
1
+ # `rt-toggle-button-group<T>`
2
+
3
+ Группа сегментированных кнопок: один выбранный вариант из нескольких.
4
+
5
+ ```html
6
+ <rt-toggle-button-group
7
+ ariaLabel="Период"
8
+ [options]="[{ value: 'day', label: 'День' }, { value: 'week', label: 'Неделя' }]"
9
+ [value]="period()"
10
+ (valueChange)="period.set($event)" />
11
+ ```
12
+
13
+ | вход | тип | умолчание |
14
+ | ------------------------ | ------------------------------------------------ | -------------- |
15
+ | `options` | `ReadonlyArray<{ value, label, icon?, title? }>` | **обязателен** |
16
+ | `value` | `T \| undefined` | `undefined` |
17
+ | `ariaLabel` | `string \| null` | `null` |
18
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` |
19
+ | `disabled` / `fullWidth` | `boolean` | `false` |
20
+
21
+ Выход: `valueChange`.
22
+
23
+ ## Главное, что нужно знать
24
+
25
+ **Группа не держит состояния.** Нажатие только просит сменить значение; подсветка сдвинется,
26
+ когда потребитель вернёт новое `value`. Повторное нажатие по выбранному тоже поднимает событие —
27
+ снимать выбор группа не умеет.
28
+
29
+ ## Края
30
+
31
+ - Крайние кнопки помечены модификаторами `--first` / `--last`: по ним скругляются углы группы.
32
+ - `title` варианта превращается во всплывающую подсказку.
33
+ - Размер иконки выводится из размера группы: `sm` → 12px, `md`/`lg` → 16px.
34
+
35
+ ## Рядом
36
+
37
+ - [`rt-filter-control`](../filter-control/CONTEXT.md) — та же группа, но с автоматическим
38
+ переключением на список на узком экране.
@@ -1,10 +1,13 @@
1
- /* rt-toggle-button-group — segmented control.
2
- ViewEncapsulation = default (Emulated) → стили обёрнуты в :host { ... }.
1
+ /* rt-toggle-button-group — segmented control. ViewEncapsulation.None.
2
+ Хост адресуется по имени элемента, а не по классу блока: класс
3
+ `.rt-toggle-button-group` висит и на `<rt-toggle-button-group>`, и на корне
4
+ шаблона, поэтому правила блока вложены в хост — так они достаются только
5
+ корню шаблона.
3
6
  Размеры — три тира sm/md/lg, общая высота совпадает с rt-button
4
7
  (sm 30 / md 40 / lg 50px).
5
8
  Цвета — только семантические --rt-* токены. */
6
9
 
7
- :host {
10
+ rt-toggle-button-group {
8
11
  display: inline-flex;
9
12
 
10
13
  /* Локальные overridable custom properties — позволяют потребителю
@@ -114,7 +117,7 @@
114
117
  }
115
118
 
116
119
  /* full-width: группа растягивается на контейнер, опции делят ширину поровну. */
117
- :host(.rt-toggle-button-group--full-width) {
120
+ rt-toggle-button-group.rt-toggle-button-group--full-width {
118
121
  display: flex;
119
122
  width: 100%;
120
123
 
@@ -131,8 +134,10 @@
131
134
 
132
135
  /* Dark theme: `--rt-color-bg-surface-subtle` совпадает с `--rt-color-bg-surface`
133
136
  в палитре (см. styles/_theme-dark.scss), поэтому track теряет контраст с
134
- активным сегментом. Локально перекрашиваем track в более тёмный neutral. */
135
- :host-context(:root[data-theme='dark']),
136
- :host-context(html.rt-theme-dark) {
137
+ активным сегментом. Локально перекрашиваем track в более тёмный neutral.
138
+ Раньше правило было записано через `:host-context`, который под None не
139
+ совпадает ни с чем: тему задаёт предок, им же и адресуемся. */
140
+ :root[data-theme='dark'] rt-toggle-button-group,
141
+ html.rt-theme-dark rt-toggle-button-group {
137
142
  --rt-toggle-button-group-track-bg: var(--rt-neutral-900);
138
143
  }
@@ -0,0 +1,35 @@
1
+ # `rt-toggle-switch`
2
+
3
+ ```html
4
+ <rt-toggle-switch ariaLabel="Тёмная тема" size="md" iconOff="ico-sun" iconOn="ico-moon" [formControl]="darkTheme" />
5
+ ```
6
+
7
+ | вход | тип | умолчание |
8
+ | -------------------- | ---------------------- | --------- |
9
+ | `inputId` | `string \| null` | `null` |
10
+ | `ariaLabel` | `string \| null` | `null` |
11
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` |
12
+ | `iconOff` / `iconOn` | `IRtIcon.Name \| null` | `null` |
13
+ | `disabled` | `boolean` | `false` |
14
+
15
+ Значение — `boolean` через `ControlValueAccessor`. Своей подписи на экране нет.
16
+
17
+ ## Главное, что нужно знать
18
+
19
+ **`role="switch"`, а не `checkbox`.** Скринридер произносит «switch off/on» вместо «checkbox
20
+ unchecked» — для тумблера это точнее. Своего текста у контрола нет, поэтому подпись задаётся
21
+ входом `ariaLabel` или внешним `<label for>` через `inputId`.
22
+
23
+ ## Как этим пользоваться
24
+
25
+ - Умолчание размера — `sm`: он совпадает по высоте с плотными контролами формы, где тумблер
26
+ стоит в одном ряду с текстом.
27
+ - Достаточно одной из двух иконок, чтобы включился режим с иконками
28
+ (`rt-toggle-switch--with-icons`). Бегунок непрозрачен и наезжает на иконку текущего состояния,
29
+ так что видна всегда иконка того состояния, куда переключится контрол.
30
+ - Отключение приходит двумя путями — вход и `FormControl.disable()` — и оба пишут в один сигнал.
31
+
32
+ ## Рядом
33
+
34
+ - [`rt-checkbox`](../checkbox/CONTEXT.md) — для «отмечено», а не «включено».
35
+ - [`rt-theme-toggle`](../theme-toggle/CONTEXT.md) — готовый переключатель темы поверх этого.
@@ -1,8 +1,13 @@
1
- :host {
1
+ /* rt-toggle-switch — переключатель в common/ui. ViewEncapsulation.None.
2
+ Хост адресуется по имени элемента, а не по классу блока: класс `.rt-toggle-switch` висит
3
+ и на `<rt-toggle-switch>`, и на корне шаблона, поэтому правила блока вложены в хост —
4
+ так они достаются только корню шаблона. */
5
+
6
+ rt-toggle-switch {
2
7
  display: inline-flex;
3
8
  }
4
9
 
5
- .rt-toggle-switch {
10
+ rt-toggle-switch .rt-toggle-switch {
6
11
  /* Геометрия размера. База — `sm`; модификаторы перекрывают только числа,
7
12
  правила ниже к размерам не привязаны. `thumb-travel` держим явным
8
13
  числом, а не calc из ширины: каждое значение сверяется с макетом. */
@@ -0,0 +1,22 @@
1
+ # `rt-toolbar`
2
+
3
+ Полоса действий с тремя слотами. Слоты объявляются директивами на `ng-template`.
4
+
5
+ ```html
6
+ <rt-toolbar dense>
7
+ <ng-template rtToolbarLeft><rt-icon-button icon="arrow-left" ariaLabel="Назад" /></ng-template>
8
+ <ng-template rtToolbarCenter><h3>Заявка №12</h3></ng-template>
9
+ <ng-template rtToolbarRight><rt-menu … /></ng-template>
10
+ </rt-toolbar>
11
+ ```
12
+
13
+ | вход | тип | умолчание |
14
+ | ------- | --------- | --------- |
15
+ | `dense` | `boolean` | `false` |
16
+
17
+ Выходов нет.
18
+
19
+ ## Главное, что нужно знать
20
+
21
+ **Без единого слота панель не рисуется вовсе** — ни одного узла в DOM. Необъявленный слот тоже
22
+ не создаёт пустой полосы: пустая полоса занимала бы место и растягивала соседние.
@@ -0,0 +1,34 @@
1
+ # `[rtTooltip]`
2
+
3
+ ```html
4
+ <button rtButton rtTooltipPlacement="top" [rtTooltip]="'Удалить строку'">…</button>
5
+ <rt-icon-button icon="ico-trash" ariaLabel="Удалить" tooltip="Удалить" />
6
+ ```
7
+
8
+ | вход | тип | умолчание |
9
+ | -------------------- | ----------------------------- | --------- |
10
+ | `rtTooltip` | `string \| null \| undefined` | `''` |
11
+ | `rtTooltipPlacement` | `'top' \| 'bottom'` | `'top'` |
12
+
13
+ Выходов нет. Панель — `rt-tooltip` в оверлее CDK, `role="tooltip"`.
14
+
15
+ ## Главное, что нужно знать
16
+
17
+ **Пустой текст выключает директиву целиком.** `''`, пробелы, `null`, `undefined` — всё это
18
+ no-op, а не пустая панель под курсором. Поэтому директиву вешают на иконочные кнопки
19
+ безусловно и «включают», выставив строку. Вход принимает `null`/`undefined` и нормализует их
20
+ сам — так `[rtTooltip]="value | date"` не ломает строгую типизацию шаблона.
21
+
22
+ **Подсказка появляется с задержкой 300 мс.** Она гасит мелькание при быстром проходе курсора по
23
+ ряду кнопок. Уход курсора до истечения задержки не показывает ничего.
24
+
25
+ ## Как этим пользоваться
26
+
27
+ - Показывают и наведение, и фокус с клавиатуры; прячут уход курсора, потеря фокуса и **клик**
28
+ (панель мешала бы смотреть на результат нажатия).
29
+ - `rt-icon-button` уже несёт эту директиву — там достаточно входа `tooltip`.
30
+ - Подсказка не заменяет `aria-label`: она вспомогательная, а имя контрола задаётся отдельно.
31
+
32
+ ## Рядом
33
+
34
+ - [`[rtPopover]`](../popover/CONTEXT.md) — когда в панель нужно положить разметку.
@@ -0,0 +1,20 @@
1
+ # `rt-welcome-dialog`
2
+
3
+ Приветственное окно с текстом и одной кнопкой. Открывается через
4
+ [`RtDialogService`](../dialog/CONTEXT.md).
5
+
6
+ ```typescript
7
+ this.#dialog.open<RtWelcomeDialogComponent, IRtWelcomeDialog.Data>(RtWelcomeDialogComponent, {
8
+ data: { message: 'Добро пожаловать\n\nЗдесь появятся ваши заявки.', ctaLabel: 'Поехали' },
9
+ });
10
+ ```
11
+
12
+ Данные приходят токеном `RT_DIALOG_DATA`: `message`, необязательный `ctaLabel`.
13
+
14
+ ## Главное, что нужно знать
15
+
16
+ **Заголовок компонент выбирает сам — это первый абзац сообщения.** Приветствие приходит одной
17
+ строкой из настроек приложения, и делить её на заголовок и текст приходится здесь: абзацы
18
+ разделяются пустой строкой, пустые отбрасываются.
19
+
20
+ Без данных окно рисуется пустым, но не падает — остаётся одна кнопка.
@@ -1,7 +1,11 @@
1
1
  /* Welcome-модалка первого входа — открывается через RtDialogService.open().
2
- rt-dialog даёт styled-frame, контент внутри получает свой padding. */
2
+ rt-dialog даёт styled-frame, контент внутри получает свой padding.
3
3
 
4
- :host {
4
+ ViewEncapsulation.None. Хост адресуется по имени элемента, а не по классу
5
+ блока: класс `.rt-welcome-dialog` висит и на `<rt-welcome-dialog>`, и на
6
+ обёртке содержимого внутри него, поэтому правила обёртки вложены в хост. */
7
+
8
+ rt-welcome-dialog {
5
9
  display: contents;
6
10
 
7
11
  .rt-welcome-dialog {
@@ -0,0 +1,46 @@
1
+ # `rt-workspace`
2
+
3
+ Трёхколоночный рабочий стол: список, карточка, панель подробностей. Колонки тянутся мышью и
4
+ клавиатурой, ширины запоминаются.
5
+
6
+ ```html
7
+ <rt-workspace storageKey="inbox" [hasActive]="!!active()" (backClicked)="clearActive()">
8
+ <ng-template rtWorkspaceList let-api><rt-thread-list … /></ng-template>
9
+ <ng-template rtWorkspaceCenter><app-card /></ng-template>
10
+ <ng-template rtWorkspaceAside><rt-workspace-details … /></ng-template>
11
+ </rt-workspace>
12
+ ```
13
+
14
+ | вход | тип | умолчание |
15
+ | ------------------------------------------------------- | ------------------ | --------------- |
16
+ | `storageKey` | `string \| null` | `null` |
17
+ | `hasActive` | `boolean` | `false` |
18
+ | `listMinWidth` / `listMaxWidth` / `listDefaultWidth` | `number \| string` | 240 / 480 / 320 |
19
+ | `asideMinWidth` / `asideMaxWidth` / `asideDefaultWidth` | `number \| string` | 280 / 560 / 360 |
20
+ | `centerMinWidth` | `number \| string` | 360 |
21
+
22
+ Выход: `backClicked`. API панели: `openAside()`, `closeAside()`, `toggleAside()`,
23
+ `toggleAsideCollapsed()`, сигналы `asideOpen()`, `asideCollapsed()`, `listWidth()`, `asideWidth()`.
24
+
25
+ ## Главное, что нужно знать
26
+
27
+ **Без `storageKey` ширины не запоминаются.** С ключом они переживают пересоздание компонента:
28
+ раскладку рабочего стола настраивают один раз, и сбрасывать её на каждом заходе было бы хуже.
29
+
30
+ **Ручки — полноценные разделители**: `role="separator"`, в таб-порядке, стрелки двигают их с
31
+ шагом 16px, двойной клик возвращает умолчание. Текущая ширина и границы объявлены через
32
+ `aria-valuenow/min/max`.
33
+
34
+ **Стрелки у правой ручки работают зеркально**: `ArrowLeft` расширяет панель подробностей, потому
35
+ что она растёт влево.
36
+
37
+ ## Края
38
+
39
+ - Ширина всегда зажимается в границы — и при перетаскивании, и с клавиатуры.
40
+ - На узком экране появляется полоса с кнопками «назад» и «подробности» (только при `hasActive`);
41
+ «назад» закрывает панель подробностей и поднимает событие.
42
+ - `asideCollapsed` — это «свернуть на широком экране», `asideOpen` — «показать на узком».
43
+
44
+ ## Рядом
45
+
46
+ - [`rt-workspace-details`](../workspace-details/CONTEXT.md) — типовое наполнение правой панели.
@@ -0,0 +1,42 @@
1
+ # `rt-workspace-details`
2
+
3
+ Типовое наполнение правой панели рабочего стола: перечень полей, суммы, переключатели, переход
4
+ по этапам, история и кнопки действий.
5
+
6
+ ```html
7
+ <rt-workspace-details
8
+ title="Заявка №12"
9
+ [rows]="rows()"
10
+ [money]="money()"
11
+ [toggles]="toggles()"
12
+ [transition]="transition()"
13
+ [audit]="audit()"
14
+ [actions]="actions()"
15
+ [loading]="loading()"
16
+ (toggleChange)="onToggle($event)"
17
+ (transitionSubmit)="moveStage($event)"
18
+ (auditLoadMore)="loadMoreAudit()"
19
+ (actionClicked)="runAction($event)" />
20
+ ```
21
+
22
+ Входы: `title`, `entityId`, `loading`, `busy`, `rows`, `agentEdit`, `money`, `toggles`,
23
+ `toggleHint`, `transition`, `audit`, `actions`, `error`.
24
+ Выходы: `toggleChange`, `agentReassign`, `transitionSubmit`, `transitionSuccessClose`,
25
+ `transitionErrorClose`, `auditLoadMore`, `actionClicked`.
26
+
27
+ ## Главное, что нужно знать
28
+
29
+ **Вкладки появляются только вместе с переходом или историей.** Пока есть одни поля, они рисуются
30
+ сразу: одна вкладка вместо содержимого была бы лишним щелчком.
31
+
32
+ **Ошибка не рисуется внутри панели — она уходит в [`NotificationBus`](../toast/CONTEXT.md).**
33
+ Панель узкая, и сообщение в ней сдвигало бы данные; тост показывает ошибку поверх. Одна и та же
34
+ строка не повторяется на каждой перерисовке.
35
+
36
+ ## Края
37
+
38
+ - `loading` подменяет заглушками значения полей и сумм, подписи остаются.
39
+ - Действие с `confirm` открывает [`[rtConfirm]`](../confirm-popover/CONTEXT.md), и
40
+ `actionClicked` приходит только после подтверждения.
41
+ - Смена исполнителя (`agentEdit`) — отдельный сценарий с выбором и подтверждением; событие
42
+ `agentReassign` отдаёт идентификатор нового исполнителя.
package/styles/tokens.css CHANGED
@@ -774,6 +774,20 @@ html.rt-theme-dark .rt-logo {
774
774
  --rt-btn-icon-size: 1.125rem;
775
775
  --rt-btn-spinner-size: 1.125rem;
776
776
  }
777
+ .rt-button--xl {
778
+ --rt-btn-height: 60px;
779
+ --rt-btn-padding: 0 1.75rem;
780
+ --rt-btn-font-size: 1.125rem;
781
+ --rt-btn-icon-size: 1.25rem;
782
+ --rt-btn-spinner-size: 1.25rem;
783
+ }
784
+ .rt-button--2xl {
785
+ --rt-btn-height: 70px;
786
+ --rt-btn-padding: 0 2rem;
787
+ --rt-btn-font-size: 1.1875rem;
788
+ --rt-btn-icon-size: 1.375rem;
789
+ --rt-btn-spinner-size: 1.375rem;
790
+ }
777
791
  .rt-button--icon-only {
778
792
  width: var(--rt-btn-height);
779
793
  padding: 0;