@rt-tools/ui-kit-v2 0.11.0 → 0.12.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 (165) hide show
  1. package/README.md +110 -5
  2. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +947 -0
  3. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -0
  4. package/fesm2022/rt-tools-ui-kit-v2.mjs +11327 -8086
  5. package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
  6. package/package.json +8 -1
  7. package/rt-tools-ui-kit-v2-0.12.0.tgz +0 -0
  8. package/src/assets/fonts/montserrat-cyrillic-ext-wght-italic.woff2 +0 -0
  9. package/src/assets/fonts/montserrat-cyrillic-ext-wght-normal.woff2 +0 -0
  10. package/src/assets/fonts/montserrat-cyrillic-wght-italic.woff2 +0 -0
  11. package/src/assets/fonts/montserrat-cyrillic-wght-normal.woff2 +0 -0
  12. package/src/assets/fonts/montserrat-latin-ext-wght-italic.woff2 +0 -0
  13. package/src/assets/fonts/montserrat-latin-ext-wght-normal.woff2 +0 -0
  14. package/src/assets/fonts/montserrat-latin-wght-italic.woff2 +0 -0
  15. package/src/assets/fonts/montserrat-latin-wght-normal.woff2 +0 -0
  16. package/src/assets/icons/arrows.svg +9 -0
  17. package/src/assets/icons/equals.svg +8 -0
  18. package/src/assets/icons/user-off.svg +16 -0
  19. package/src/assets/icons-material/NOTICE.md +6 -2
  20. package/src/assets/icons-material/arrow-left.fill.svg +3 -0
  21. package/src/assets/icons-material/arrow-left.svg +1 -1
  22. package/src/assets/icons-material/arrow-right.fill.svg +3 -0
  23. package/src/assets/icons-material/arrow-right.svg +3 -0
  24. package/src/assets/icons-material/arrows.fill.svg +5 -0
  25. package/src/assets/icons-material/arrows.svg +5 -0
  26. package/src/assets/icons-material/ban.fill.svg +5 -0
  27. package/src/assets/icons-material/ban.svg +1 -1
  28. package/src/assets/icons-material/bars.fill.svg +3 -0
  29. package/src/assets/icons-material/bars.svg +1 -1
  30. package/src/assets/icons-material/check.fill.svg +3 -0
  31. package/src/assets/icons-material/check.svg +1 -1
  32. package/src/assets/icons-material/chevron-down.fill.svg +3 -0
  33. package/src/assets/icons-material/chevron-down.svg +1 -1
  34. package/src/assets/icons-material/chevron-left.fill.svg +3 -0
  35. package/src/assets/icons-material/chevron-left.svg +1 -1
  36. package/src/assets/icons-material/chevron-right.fill.svg +3 -0
  37. package/src/assets/icons-material/chevron-right.svg +1 -1
  38. package/src/assets/icons-material/close.fill.svg +3 -0
  39. package/src/assets/icons-material/close.svg +1 -1
  40. package/src/assets/icons-material/cloud-upload.fill.svg +5 -0
  41. package/src/assets/icons-material/cloud-upload.svg +1 -1
  42. package/src/assets/icons-material/cog.fill.svg +5 -0
  43. package/src/assets/icons-material/cog.svg +1 -1
  44. package/src/assets/icons-material/copy.fill.svg +5 -0
  45. package/src/assets/icons-material/copy.svg +1 -1
  46. package/src/assets/icons-material/ellipsis-h.fill.svg +5 -0
  47. package/src/assets/icons-material/ellipsis-h.svg +1 -1
  48. package/src/assets/icons-material/ellipsis-v.fill.svg +5 -0
  49. package/src/assets/icons-material/ellipsis-v.svg +1 -1
  50. package/src/assets/icons-material/email.fill.svg +5 -0
  51. package/src/assets/icons-material/email.svg +5 -0
  52. package/src/assets/icons-material/equals.fill.svg +3 -0
  53. package/src/assets/icons-material/equals.svg +3 -0
  54. package/src/assets/icons-material/external-link.fill.svg +5 -0
  55. package/src/assets/icons-material/external-link.svg +1 -1
  56. package/src/assets/icons-material/eye-slash.fill.svg +5 -0
  57. package/src/assets/icons-material/eye-slash.svg +1 -1
  58. package/src/assets/icons-material/eye.fill.svg +5 -0
  59. package/src/assets/icons-material/eye.svg +1 -1
  60. package/src/assets/icons-material/ico-download.fill.svg +5 -0
  61. package/src/assets/icons-material/ico-download.svg +1 -1
  62. package/src/assets/icons-material/ico-plus.fill.svg +3 -0
  63. package/src/assets/icons-material/ico-plus.svg +1 -1
  64. package/src/assets/icons-material/info-circle.fill.svg +5 -0
  65. package/src/assets/icons-material/info-circle.svg +1 -1
  66. package/src/assets/icons-material/pencil.fill.svg +5 -0
  67. package/src/assets/icons-material/pencil.svg +1 -1
  68. package/src/assets/icons-material/refresh.fill.svg +5 -0
  69. package/src/assets/icons-material/refresh.svg +1 -1
  70. package/src/assets/icons-material/search.fill.svg +5 -0
  71. package/src/assets/icons-material/search.svg +1 -1
  72. package/src/assets/icons-material/star.fill.svg +3 -0
  73. package/src/assets/icons-material/star.svg +1 -1
  74. package/src/assets/icons-material/sync.fill.svg +5 -0
  75. package/src/assets/icons-material/sync.svg +1 -1
  76. package/src/assets/icons-material/table.fill.svg +5 -0
  77. package/src/assets/icons-material/table.svg +1 -1
  78. package/src/assets/icons-material/tag.fill.svg +5 -0
  79. package/src/assets/icons-material/tag.svg +1 -1
  80. package/src/assets/icons-material/trash.fill.svg +5 -0
  81. package/src/assets/icons-material/trash.svg +1 -1
  82. package/src/assets/icons-material/user-off.fill.svg +5 -0
  83. package/src/assets/icons-material/user-off.svg +5 -0
  84. package/src/assets/icons-material/user.fill.svg +5 -0
  85. package/src/assets/icons-material/user.svg +1 -1
  86. package/src/lib/components/CONTEXT.md +3 -0
  87. package/src/lib/components/action-bar/CONTEXT.md +53 -0
  88. package/src/lib/components/action-bar/rt-action-bar-holder.component.scss +70 -0
  89. package/src/lib/components/action-bar/rt-action-bar.component.scss +122 -0
  90. package/src/lib/components/aside/CONTEXT.md +5 -1
  91. package/src/lib/components/aside/_rt-aside-overlay.scss +9 -0
  92. package/src/lib/components/aside/header/rt-aside-header.component.scss +18 -2
  93. package/src/lib/components/aside/rt-aside.component.scss +5 -1
  94. package/src/lib/components/autocomplete/CONTEXT.md +2 -1
  95. package/src/lib/components/button/CONTEXT.md +11 -11
  96. package/src/lib/components/checkbox/rt-checkbox.component.scss +5 -1
  97. package/src/lib/components/data-list/CONTEXT.md +122 -0
  98. package/src/lib/components/data-list/rt-data-list.component.scss +57 -0
  99. package/src/lib/components/data-list/settings/rt-data-list-settings-aside.component.scss +256 -0
  100. package/src/lib/components/data-list/toolbar/rt-data-list-toolbar.component.scss +128 -0
  101. package/src/lib/components/data-table/CONTEXT.md +102 -0
  102. package/src/lib/components/data-table/cell/rt-data-table-cell.component.scss +115 -0
  103. package/src/lib/components/data-table/filter-cell/rt-data-table-filter-cell.component.scss +51 -0
  104. package/src/lib/components/data-table/header-cell/rt-data-table-header-cell.component.scss +111 -0
  105. package/src/lib/components/data-table/rt-data-table.component.scss +263 -0
  106. package/src/lib/components/date-picker/rt-date-picker.component.scss +13 -0
  107. package/src/lib/components/delta-view/CONTEXT.md +1 -1
  108. package/src/lib/components/dialog/CONTEXT.md +4 -0
  109. package/src/lib/components/dynamic-list/CONTEXT.md +90 -0
  110. package/src/lib/components/dynamic-list/rt-dynamic-list.component.scss +123 -0
  111. package/src/lib/components/empty-state/CONTEXT.md +5 -0
  112. package/src/lib/components/empty-state/rt-empty-state.component.scss +19 -5
  113. package/src/lib/components/file-card/rt-file-card.component.scss +14 -0
  114. package/src/lib/components/file-drop/rt-file-drop.component.scss +44 -8
  115. package/src/lib/components/icon-button/rt-icon-button.component.scss +28 -4
  116. package/src/lib/components/input/rt-input.component.scss +25 -1
  117. package/src/lib/components/input-number/rt-input-number.component.scss +13 -0
  118. package/src/lib/components/menu/CONTEXT.md +10 -0
  119. package/src/lib/components/menu/rt-menu-item.component.scss +35 -3
  120. package/src/lib/components/menu/rt-menu.component.scss +15 -5
  121. package/src/lib/components/multiselect/CONTEXT.md +3 -0
  122. package/src/lib/components/multiselect/rt-multiselect.component.scss +58 -1
  123. package/src/lib/components/pagination/CONTEXT.md +4 -1
  124. package/src/lib/components/pagination/rt-pagination.component.scss +43 -13
  125. package/src/lib/components/radio-button/CONTEXT.md +42 -0
  126. package/src/lib/components/radio-button/rt-radio-button.component.scss +105 -0
  127. package/src/lib/components/scroll-area/CONTEXT.md +52 -0
  128. package/src/lib/components/scroll-area/rt-scroll-area.component.scss +69 -0
  129. package/src/lib/components/select/CONTEXT.md +8 -1
  130. package/src/lib/components/select/rt-select.component.scss +110 -7
  131. package/src/lib/components/table/CONTEXT.md +46 -1
  132. package/src/lib/components/table/filter-header/CONTEXT.md +64 -0
  133. package/src/lib/components/table/filter-header/rt-table-filter-header.component.scss +76 -0
  134. package/src/lib/components/table/rt-table.component.scss +32 -1
  135. package/src/lib/components/tag/CONTEXT.md +9 -0
  136. package/src/lib/components/tag/rt-tag.component.scss +38 -0
  137. package/src/lib/components/textarea/CONTEXT.md +1 -1
  138. package/src/lib/components/toolbar/CONTEXT.md +3 -0
  139. package/src/lib/components/toolbar/rt-toolbar.component.scss +9 -2
  140. package/src/lib/components/tooltip/CONTEXT.md +4 -4
  141. package/src/lib/components/tooltip/rt-tooltip.component.scss +2 -2
  142. package/src/{lib → rich-editor/lib}/components/chat/CONTEXT.md +1 -1
  143. package/src/{lib → rich-editor/lib}/components/message-composer/CONTEXT.md +5 -1
  144. package/src/{lib → rich-editor/lib}/components/message-composer/rt-message-composer.component.scss +9 -0
  145. package/src/{lib → rich-editor/lib}/components/rich-editor/CONTEXT.md +2 -2
  146. package/src/styles/_coarse-pointer.scss +15 -0
  147. package/src/styles/_coexist.scss +28 -0
  148. package/src/styles/_fonts.scss +99 -0
  149. package/src/styles/_index.scss +13 -0
  150. package/src/styles/_preset-material.scss +201 -26
  151. package/src/styles/_primitives.scss +41 -5
  152. package/src/styles/_scrollbar.scss +16 -12
  153. package/src/styles/_semantic-lists.scss +89 -0
  154. package/src/styles/_semantic.scss +80 -9
  155. package/src/styles/_theme-dark.scss +36 -0
  156. package/src/styles/_theme-scope.scss +111 -0
  157. package/src/styles/tokens.coexist.scss +3 -0
  158. package/src/styles/tokens.package.scss +6 -0
  159. package/styles/tokens.coexist.css +27 -0
  160. package/styles/tokens.css +5443 -43
  161. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +529 -0
  162. package/types/rt-tools-ui-kit-v2.d.ts +2744 -1367
  163. package/rt-tools-ui-kit-v2-0.11.0.tgz +0 -0
  164. /package/src/{lib → rich-editor/lib}/components/chat/rt-chat.component.scss +0 -0
  165. /package/src/{lib → rich-editor/lib}/components/rich-editor/rt-rich-editor.component.scss +0 -0
@@ -28,4 +28,4 @@
28
28
 
29
29
  ## Рядом
30
30
 
31
- - [`rt-rich-editor`](../rich-editor/CONTEXT.md) — редактор, который эту модель производит.
31
+ - [`rt-rich-editor`](../../../rich-editor/lib/components/rich-editor/CONTEXT.md) — редактор, который эту модель производит.
@@ -34,6 +34,10 @@ ref.afterClosed().subscribe((ok?: boolean): void => …);
34
34
 
35
35
  ## Главное, что нужно знать
36
36
 
37
+ **Окно берёт материальный набор от кнопки в фокусе.** Панель лежит в конце страницы, вне
38
+ контейнера с признаком набора, и класс набора получает, если признак стоит над узлом в фокусе в
39
+ минуту открытия. Открытая не по нажатию — через `panelClass` приложения.
40
+
37
41
  **Прокрутка страницы блокируется на время диалога** (`scrollStrategies.block()`), а окно
38
42
  объявлено `role="dialog"` с `aria-modal="true"`.
39
43
 
@@ -0,0 +1,90 @@
1
+ # `rt-dynamic-list`
2
+
3
+ ```html
4
+ <rt-dynamic-list
5
+ [pageModel]="page()"
6
+ [showRefresh]="true"
7
+ [showClearFilters]="true"
8
+ [filtered]="hasFilters()"
9
+ (searchChange)="onSearch($event)"
10
+ (refreshed)="reload()"
11
+ (pageChange)="onPage($event)">
12
+ <ng-container *rtDynamicListSelectors>
13
+ <rt-select [options]="stages()" />
14
+ </ng-container>
15
+
16
+ <rt-table [rows]="rows()" />
17
+ </rt-dynamic-list>
18
+ ```
19
+
20
+ | вход | тип | умолчание |
21
+ | -------------------- | -------------------- | --------- |
22
+ | `pageModel` | `IPageModel \| null` | `null` |
23
+ | `loading` | `boolean` | `false` |
24
+ | `fetching` | `boolean` | `false` |
25
+ | `empty` | `boolean` | `false` |
26
+ | `filtered` | `boolean` | `false` |
27
+ | `showSearch` | `boolean` | `true` |
28
+ | `showRefresh` | `boolean` | `false` |
29
+ | `showClearFilters` | `boolean` | `false` |
30
+ | `showColumnSettings` | `boolean` | `false` |
31
+ | `selectable` | `boolean` | `false` |
32
+ | `allSelected` | `boolean` | `false` |
33
+ | `someSelected` | `boolean` | `false` |
34
+ | `selectAllDisabled` | `boolean` | `false` |
35
+ | `selectedCount` | `number` | `0` |
36
+ | `emptyTitle` | `string` | `''` |
37
+ | `emptyDescription` | `string \| null` | `null` |
38
+ | `searchTerm` | `string \| null` | `''` |
39
+
40
+ Выходы: `searchChange`, `refreshed`, `filtersCleared`, `columnSettingsOpened`, `pageChange`,
41
+ `perPageChange`, `allSelectedChange`. Стороны панели объявляются двумя директивами:
42
+ `rtDynamicListSelectors` и `rtDynamicListActions`.
43
+
44
+ ## Главное, что нужно знать
45
+
46
+ **Записи проецируются, а не приходят входом.** Таблица между панелью и страницами — потребителя:
47
+ его колонки, его ячейки, его действия строки. Семья стоит вокруг и в неё не заглядывает.
48
+
49
+ **Незаказанное действие не рисуется вовсе, а выключенное держит место.** Экран без обновления не
50
+ показывает кнопку обновления; кнопка сброса отбора стоит и выключена, пока сбрасывать нечего, —
51
+ это разные утверждения, и оба сделаны намеренно.
52
+
53
+ **Пустых мест два.** Раздел без записей и отбор, ничего не нашедший, говорят человеку разное: из
54
+ второго ему дают дорогу назад — сброс того, что он поставил.
55
+
56
+ **Поиск не ходит наружу на каждое нажатие.** Значение сперва устаивается — готовым оператором
57
+ ожидания кита, тем же, что стоит в списке переписок.
58
+
59
+ **Полоса страниц рисуется, пока записей больше наименьшего размера страницы.** Это правило самой
60
+ полосы: под списком из трёх записей она шум, а выбравший крупный размер, при котором всё легло на
61
+ одну страницу, иначе не вернул бы размер поменьше.
62
+
63
+ **Поле поиска следует за входом `searchTerm`, но эхо своего же поиска не ставит.** Новое значение
64
+ потребителя ставится в поле, а значение, равное последнему отправленному, поле не трогает: ответ
65
+ сервера или адресной строки, пришедший позже, не стирает дописанное человеком.
66
+
67
+ **`filtersCleared` значит, что снят и поиск.** Сброс отбора очищает поле молча, отдельного пустого
68
+ `searchChange` нет: потребитель по `filtersCleared` сам сбрасывает свой поиск и запрашивает список
69
+ один раз.
70
+
71
+ **Флажок «выбрать все» стоит, пока выбор включён, и счётчик встаёт рядом с ним.** Выбрав что-то,
72
+ человек сохраняет способ снять весь выбор одним нажатием.
73
+
74
+ **Полоса панели переносит непоместившееся сама.** Поиск уходит на свою строку, когда рядом с
75
+ действиями ему места нет: без этого список раздался бы шире хозяина и уехал за его край.
76
+
77
+ **Ниже порога кита поиск занимает всю строку.** Порог — 1080 точек, объявлен медиазапросом по
78
+ общему файлу порогов. Ни описанием, ни входом его не включить: он виден только на кадре.
79
+
80
+ ## Как этим пользоваться
81
+
82
+ - Высоту списка задаёт потребитель: он берёт сто процентов своего хоста.
83
+ - Настройка колонок открывается потребителем: семья только говорит о нажатии.
84
+ - Подписи приходят из словаря кита — `provideRtKitLabels`.
85
+ - Расстояния и ширину поиска переопределяют свойствами блока — `--rt-dynamic-list-gap`,
86
+ `--rt-dynamic-list-search-width`.
87
+
88
+ ## Договорённость
89
+
90
+ `docs/specs/ui-kit-v2/dynamic-list/` — восемь правил и сценарии `SC-UKV-165`…`SC-UKV-174`.
@@ -0,0 +1,123 @@
1
+ @use '../../../styles/breakpoints' as bp;
2
+
3
+ @layer rt-kit.components {
4
+ .rt-dynamic-list {
5
+ --rt-dynamic-list-gap: var(--rt-space-4);
6
+ --rt-dynamic-list-search-width: var(--rt-size-64);
7
+ --rt-dynamic-list-veil-bg: var(--rt-color-bg-surface);
8
+
9
+ position: relative;
10
+ display: flex;
11
+ flex-direction: column;
12
+ block-size: 100%;
13
+ gap: var(--rt-dynamic-list-gap);
14
+ inline-size: 100%;
15
+ min-block-size: 0;
16
+
17
+ &__loader {
18
+ display: flex;
19
+ flex: 1 1 auto;
20
+ align-items: center;
21
+ justify-content: center;
22
+ padding: var(--rt-space-8);
23
+ }
24
+
25
+ // Вертушка подгрузки стоит над нарисованным: записи остаются на месте, и человек видит,
26
+ // что список тот же самый, а не подменённый. Над шапкой таблицы потребителя её держит
27
+ // замкнутый ярус области записей: шапка со своим ярусом sticky поднимается только внутри
28
+ // него.
29
+ &__veil {
30
+ position: absolute;
31
+ z-index: 1;
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ background-color: color-mix(in srgb, var(--rt-dynamic-list-veil-bg) 60%, transparent);
36
+ inset: 0;
37
+ }
38
+
39
+ // Полоса панели: отбор слева, действия и поиск справа. Переносится, когда не влезает —
40
+ // судьба непоместившегося названа здесь, у самой полосы.
41
+ &__toolbar {
42
+ display: flex;
43
+ flex: 0 0 auto;
44
+ flex-wrap: wrap;
45
+ align-items: center;
46
+ gap: var(--rt-space-2);
47
+ min-inline-size: 0;
48
+ }
49
+
50
+ &__selectors {
51
+ display: flex;
52
+ flex: 0 1 auto;
53
+ align-items: center;
54
+ gap: var(--rt-space-2);
55
+ min-inline-size: 0;
56
+ }
57
+
58
+ &__counter {
59
+ color: var(--rt-color-text-muted);
60
+ font-size: var(--rt-text-sm);
61
+ }
62
+
63
+ // Панель переносит поиск на свою строку, когда он не влезает рядом с действиями. Судьба
64
+ // непоместившегося названа здесь, а не оставлена на волю потребителя: без переноса список
65
+ // раздаётся шире хозяина и уезжает за его край — медиазапрос этого не ловит, ширина там
66
+ // своя, а не оконная.
67
+ &__right {
68
+ display: flex;
69
+ flex: 1 1 auto;
70
+ flex-wrap: wrap;
71
+ align-items: center;
72
+ justify-content: flex-end;
73
+ gap: var(--rt-space-2);
74
+ min-inline-size: 0;
75
+ }
76
+
77
+ &__actions {
78
+ display: flex;
79
+ flex: 0 0 auto;
80
+ align-items: center;
81
+ gap: var(--rt-space-1);
82
+ }
83
+
84
+ // Поле поиска ужимается вместе с панелью: ширина названа потолком, а не размером. Жёсткая
85
+ // ширина выталкивала бы действия за край у потребителя с узкой панелью, и никакой запрос
86
+ // этого не поймал бы — ширина там своя, а не оконная.
87
+ &__search {
88
+ flex: 1 1 auto;
89
+ max-inline-size: var(--rt-dynamic-list-search-width);
90
+ min-inline-size: 0;
91
+ }
92
+
93
+ // Свой ярус: что бы потребитель ни поднял внутри таблицы, над вертушкой подгрузки оно не встанет.
94
+ &__content {
95
+ display: flex;
96
+ overflow: auto;
97
+ flex: 1 1 auto;
98
+ flex-direction: column;
99
+ isolation: isolate;
100
+ min-block-size: 0;
101
+ }
102
+
103
+ &__empty {
104
+ flex: 1 1 auto;
105
+ }
106
+
107
+ &__pagination {
108
+ flex: 0 0 auto;
109
+ }
110
+
111
+ // Узкий экран объявлен запросом, а не условием в разметке. Порог тот же, о котором
112
+ // отвечает служба порогов кита, и берётся он из общего файла порогов.
113
+ @media (width <= #{bp.$rt-bp-lg}) {
114
+ &__right {
115
+ flex-wrap: wrap;
116
+ }
117
+
118
+ &__search {
119
+ max-inline-size: none;
120
+ }
121
+ }
122
+ }
123
+ }
@@ -29,6 +29,11 @@
29
29
  - Иконка рисуется крупной (`xl`, 32px) и приглушённой: это заглушка, а не аффорданс. Кликабельным
30
30
  должно быть проецируемое действие.
31
31
  - Слот действия существует всегда, даже пустым; прячет его `:empty` в стилях.
32
+ - Размеры и подложка — свойства блока: `--rt-empty-state-icon-wrap-size`,
33
+ `--rt-empty-state-icon-wrap-bg`, `--rt-empty-state-icon-size`, `--rt-empty-state-title-size`,
34
+ `--rt-empty-state-title-weight`. Список ставит им назначения `--rt-list-empty-*`. Под
35
+ материальным набором его заглушка рисуется как у первого кита: значок 48px без круга, заголовок
36
+ 32px весом 400.
32
37
 
33
38
  ## Рядом
34
39
 
@@ -4,7 +4,13 @@
4
4
  Палитра приглушённая (как rt-note), центрированная вертикальная стопка. */
5
5
 
6
6
  .rt-empty-state {
7
+ /* Свои свойства блока — круг под значком, значок и заголовок; обёртка переставляет их снаружи. */
7
8
  --rt-empty-state-icon-radius: var(--rt-radius-full);
9
+ --rt-empty-state-icon-wrap-size: var(--rt-size-16);
10
+ --rt-empty-state-icon-wrap-bg: var(--rt-color-bg-subtle);
11
+ --rt-empty-state-icon-size: var(--rt-size-8);
12
+ --rt-empty-state-title-size: var(--rt-text-md);
13
+ --rt-empty-state-title-weight: var(--rt-font-weight-medium);
8
14
 
9
15
  display: flex;
10
16
  flex-direction: column;
@@ -25,21 +31,29 @@
25
31
 
26
32
  &__icon-wrap {
27
33
  display: flex;
28
- width: 64px;
29
- height: 64px;
34
+ width: var(--rt-empty-state-icon-wrap-size);
35
+ height: var(--rt-empty-state-icon-wrap-size);
30
36
  align-items: center;
31
37
  justify-content: center;
32
38
  border-radius: var(--rt-empty-state-icon-radius);
33
39
  margin-bottom: var(--rt-space-xs);
34
- background: var(--rt-color-bg-subtle);
40
+ background: var(--rt-empty-state-icon-wrap-bg);
35
41
  color: var(--rt-color-text-muted);
42
+
43
+ /* rt-icon ставит размер строкой стиля — свойство блока берёт верх через min и max. */
44
+ .rt-icon {
45
+ min-width: var(--rt-empty-state-icon-size);
46
+ max-width: var(--rt-empty-state-icon-size);
47
+ min-height: var(--rt-empty-state-icon-size);
48
+ max-height: var(--rt-empty-state-icon-size);
49
+ }
36
50
  }
37
51
 
38
52
  &__title {
39
53
  margin: 0;
40
54
  color: var(--rt-color-text-primary);
41
- font-size: var(--rt-text-md);
42
- font-weight: var(--rt-font-weight-medium);
55
+ font-size: var(--rt-empty-state-title-size);
56
+ font-weight: var(--rt-empty-state-title-weight);
43
57
  }
44
58
 
45
59
  &__description {
@@ -24,6 +24,13 @@
24
24
  background-color: var(--rt-color-bg-surface);
25
25
  gap: var(--rt-file-card-gap);
26
26
 
27
+ /* Карточка берёт ширину места, которое ей дали, и не растёт за него. В ячейке сетки
28
+ элемент по умолчанию не ужимается ниже своего содержимого — min-inline-size снимает
29
+ этот пол, max-inline-size держит верх. Без пары карточка мерилась 613 при ячейке 272
30
+ и ложилась на соседнюю. */
31
+ max-inline-size: 100%;
32
+ min-inline-size: 0;
33
+
27
34
  &--sm {
28
35
  --rt-file-card-padding-block: var(--rt-space-xs);
29
36
  --rt-file-card-padding-inline: var(--rt-space-sm);
@@ -74,9 +81,16 @@
74
81
  white-space: nowrap;
75
82
  }
76
83
 
84
+ /* Имя приходит от потребителя, и его длину кит не выбирает. Без судьбы того, что не
85
+ влезло, имя переносилось на вторую строку, растило строку карточки и уезжало под
86
+ плашку веса: ни имени, ни веса было не прочесть. Одна строка с многоточием — то же,
87
+ что уже стоит у заголовка над ним; целое имя показывает подсказка. */
77
88
  &__name {
89
+ overflow: hidden;
78
90
  color: var(--rt-color-text-muted);
79
91
  font-size: var(--rt-file-card-name-size);
92
+ text-overflow: ellipsis;
93
+ white-space: nowrap;
80
94
  }
81
95
 
82
96
  &__meta {
@@ -9,6 +9,13 @@
9
9
  --rt-file-drop-border-width: var(--rt-border-width-thin);
10
10
  --rt-file-drop-transition-duration: var(--rt-duration-fast);
11
11
 
12
+ /* Отступы рамки-приглашения и кегль подписи: на низкой области их перебивает запрос
13
+ о размере коробки, написанный ниже. Значения по умолчанию — те, что стояли тут
14
+ прямыми шагами, так что вид не сдвинулся. */
15
+ --rt-file-drop-frame-inset: var(--rt-space-lg);
16
+ --rt-file-drop-frame-padding: var(--rt-space-md);
17
+ --rt-file-drop-label-size: var(--rt-text-lg);
18
+
12
19
  position: relative;
13
20
  display: block;
14
21
  height: 100%;
@@ -16,15 +23,26 @@
16
23
  &__overlay {
17
24
  position: absolute;
18
25
  z-index: 50;
26
+
27
+ /* Оверлей — единица измерения для запроса о размере коробки. Признак стоит на нём,
28
+ а не на host'е: у host'а высота приходит от содержимого, и containment по обеим
29
+ осям схлопнул бы её в ноль. Оверлей же всегда меряется по host'у — размер у него
30
+ определён независимо от того, что внутри. Своих отступов у него поэтому нет:
31
+ запрос не достаёт до собственной коробки контейнера, и зазор рамки задан ей
32
+ самой. */
19
33
  display: flex;
34
+
35
+ /* Кит не рисует за пределами своей коробки: подпись, которой не хватило места даже
36
+ в сжатом виде, обрезается здесь, а не ложится на соседа потребителя. */
37
+ overflow: hidden;
20
38
  align-items: center;
21
39
  justify-content: center;
22
- padding: var(--rt-space-lg);
23
40
  border-radius: var(--rt-file-drop-radius);
24
41
  /* stylelint-disable-next-line property-no-vendor-prefix -- Safari < 18 */
25
42
  -webkit-backdrop-filter: blur(4px);
26
43
  backdrop-filter: blur(4px);
27
44
  background: rgb(0 0 0 / 45%);
45
+ container-type: size;
28
46
 
29
47
  /* Отступ от краёв host'а — рамка-приглашение не прижата к границе зоны. */
30
48
  inset: var(--rt-space-sm);
@@ -40,20 +58,22 @@
40
58
  }
41
59
 
42
60
  &__frame {
61
+ position: absolute;
43
62
  display: flex;
44
- width: 100%;
45
- height: 100%;
46
63
 
47
- /* border-box: иначе height:100% + padding переполняет контейнер по
48
- вертикали (flex-shrink ужимает только ширину) — зазор рамки сверху/снизу
49
- выходит меньше, чем слева/справа. */
64
+ /* border-box: иначе отступ рамки прибавлялся бы к её коробке и зазор сверху и
65
+ снизу выходил бы меньше, чем слева и справа. */
50
66
  box-sizing: border-box;
51
67
  align-items: center;
52
68
  justify-content: center;
53
- padding: var(--rt-space-md);
69
+ padding: var(--rt-file-drop-frame-padding);
54
70
  border: var(--rt-file-drop-border-width) dashed var(--rt-color-action-on-primary);
55
71
  border-radius: var(--rt-file-drop-radius);
56
72
  gap: var(--rt-space-sm);
73
+
74
+ /* Зазор от краёв оверлея задан рамке, а не отступом оверлея: оверлей — контейнер
75
+ запроса, и до его собственной коробки запрос не достаёт, а до рамки достаёт. */
76
+ inset: var(--rt-file-drop-frame-inset);
57
77
  text-align: center;
58
78
  }
59
79
 
@@ -84,7 +104,7 @@
84
104
 
85
105
  &__label {
86
106
  color: var(--rt-color-action-on-primary);
87
- font-size: var(--rt-text-lg);
107
+ font-size: var(--rt-file-drop-label-size);
88
108
  font-weight: var(--rt-font-weight-semibold);
89
109
  }
90
110
 
@@ -94,4 +114,20 @@
94
114
  opacity: 0.8;
95
115
  }
96
116
  }
117
+
118
+ /* Сжатый вид подсказки. Слова подсказки пишет сам кит, и на низкой области они не
119
+ помещаются в полный размер: подпись мерилась 84 при коробке 66 и торчала за верхнюю и
120
+ нижнюю границы разом. Обрезать её посередине слова нельзя — читатель не узнает, что
121
+ слово унесли, — поэтому уменьшаются отступы и кегль.
122
+
123
+ Запрос обращён к оверлею: признак `container-type: size` стоит на нём. Порог выбран по
124
+ измерению — при 66 подпись в полный размер не помещается, при 130 помещается вместе с
125
+ подписью зоны. */
126
+ @container (max-height: 6rem) {
127
+ .rt-file-drop__frame {
128
+ --rt-file-drop-frame-inset: var(--rt-space-2xs);
129
+ --rt-file-drop-frame-padding: var(--rt-space-2xs);
130
+ --rt-file-drop-label-size: var(--rt-text-xs);
131
+ }
132
+ }
97
133
  }
@@ -42,8 +42,14 @@
42
42
  `box-shadow` целиком и тень покоя на это время снимает — списком они встанут
43
43
  только тогда, когда покой перестанет быть `none`. */
44
44
  --rt-icon-button-shadow: var(--rt-shadow-none);
45
+ --rt-icon-button-shadow-hover: var(--rt-icon-button-shadow);
46
+ --rt-icon-button-color-hover: var(--rt-icon-button-color);
45
47
  --rt-icon-button-transition-duration: var(--rt-duration-fast);
46
48
 
49
+ /* Заливка покоя — своим свойством: неактивная кнопка берёт из неё долю, которую задаёт
50
+ набор оформления. */
51
+ --rt-icon-button-bg: transparent;
52
+
47
53
  position: relative;
48
54
  display: inline-flex;
49
55
  width: var(--rt-icon-button-size);
@@ -52,7 +58,7 @@
52
58
  justify-content: center;
53
59
  padding: 0;
54
60
  border: 0;
55
- background: transparent;
61
+ background-color: var(--rt-icon-button-bg);
56
62
  box-shadow: var(--rt-icon-button-shadow);
57
63
  color: var(--rt-icon-button-color);
58
64
  cursor: pointer;
@@ -96,9 +102,16 @@
96
102
  border-radius: var(--rt-icon-button-square-radius);
97
103
  }
98
104
 
105
+ /* Подъём под указателем — ручка для потребителя, как тень покоя; по умолчанию равен
106
+ тени покоя, и кнопка без подъёма под указателем не меняется. */
107
+ &:hover:not(:disabled) {
108
+ box-shadow: var(--rt-icon-button-shadow-hover);
109
+ }
110
+
99
111
  &--ghost {
100
112
  &:hover:not(:disabled) {
101
113
  background-color: var(--rt-icon-button-color-bg-hover);
114
+ color: var(--rt-icon-button-color-hover);
102
115
  }
103
116
 
104
117
  &.rt-icon-button--active {
@@ -107,7 +120,8 @@
107
120
  }
108
121
 
109
122
  &--primary {
110
- background-color: var(--rt-color-action-primary);
123
+ --rt-icon-button-bg: var(--rt-color-action-primary);
124
+
111
125
  color: var(--rt-color-action-on-primary);
112
126
 
113
127
  &:hover:not(:disabled) {
@@ -116,7 +130,8 @@
116
130
  }
117
131
 
118
132
  &--secondary {
119
- background-color: var(--rt-color-bg-surface-subtle);
133
+ --rt-icon-button-bg: var(--rt-color-bg-surface-subtle);
134
+
120
135
  color: var(--rt-color-text-primary);
121
136
 
122
137
  &:hover:not(:disabled) {
@@ -160,9 +175,18 @@
160
175
  }
161
176
  }
162
177
 
178
+ /* Цвет неактивной кнопки ставится рисунку значка: по умолчанию `currentcolor`, то есть цвет
179
+ значка, и свой вид остаётся прежним. Не самому значку — переданный цвет он ставит себе
180
+ встроенным стилем, и правилом его не перебить. Заливка остаётся долей заливки покоя: по умолчанию
181
+ вся, и свой вид прежний. */
163
182
  &:disabled {
183
+ background-color: color-mix(in srgb, var(--rt-icon-button-bg) var(--rt-icon-button-disabled-fill), transparent);
164
184
  cursor: not-allowed;
165
- opacity: 0.5;
185
+ opacity: var(--rt-icon-button-disabled-opacity);
186
+
187
+ .rt-icon svg {
188
+ color: var(--rt-icon-button-disabled-color);
189
+ }
166
190
  }
167
191
 
168
192
  &:focus-visible {
@@ -1,5 +1,6 @@
1
1
  @layer rt-kit.components {
2
2
  .rt-input {
3
+ --rt-input-fill-radius: var(--rt-radius-sm);
3
4
  --rt-input-toggle-radius: var(--rt-radius-sm);
4
5
 
5
6
  position: relative;
@@ -15,7 +16,7 @@
15
16
  color: var(--rt-input-color-text);
16
17
  cursor: text;
17
18
  font-size: var(--rt-input-font-size);
18
- gap: var(--rt-space-sm);
19
+ gap: var(--rt-input-gap);
19
20
  line-height: var(--rt-input-line-height);
20
21
  transition: var(--rt-input-transition);
21
22
 
@@ -32,6 +33,17 @@
32
33
  border-color: transparent;
33
34
  }
34
35
 
36
+ /* Вид «fill» — залитое поле с чертой снизу, как у материального поля первого кита: скругление
37
+ у него своё и малое — скругление поля бывает «таблеткой», а у залитого поля низ прямой.
38
+ Объявлен до блоков состояний: фокус, ошибка и «только чтение» идут ниже и
39
+ перекрывают его рамку. */
40
+ &--appearance--fill {
41
+ border-color: transparent;
42
+ border-radius: var(--rt-input-fill-radius) var(--rt-input-fill-radius) 0 0;
43
+ border-bottom-color: var(--rt-color-field-fill-underline);
44
+ background-color: var(--rt-color-bg-surface-subtle-2);
45
+ }
46
+
35
47
  &--invalid {
36
48
  border-color: var(--rt-input-color-border-error);
37
49
 
@@ -98,6 +110,18 @@
98
110
  flex-shrink: 0;
99
111
  }
100
112
 
113
+ /* Размер и цвет значка приходят от самого значка встроенным стилем и правилом не перебиваются.
114
+ Нижняя граница размер расширяет, а приглушённый тон значок берёт из свойства, которое читает
115
+ его встроенный стиль: так набор оформления даёт значку поля вид первого кита, не трогая входов
116
+ значка. По умолчанию оба равны нынешним, и вид не меняется. */
117
+ &__icon-left,
118
+ &__icon-right {
119
+ --rt-icon-color-muted: var(--rt-input-icon-color);
120
+
121
+ min-width: var(--rt-input-icon-size);
122
+ min-height: var(--rt-input-icon-size);
123
+ }
124
+
101
125
  &__toggle {
102
126
  display: inline-flex;
103
127
  flex-shrink: 0;
@@ -1,5 +1,7 @@
1
1
  @layer rt-kit.components {
2
2
  .rt-input-number {
3
+ --rt-input-number-fill-radius: var(--rt-radius-sm);
4
+
3
5
  position: relative;
4
6
  display: inline-flex;
5
7
  width: 100%;
@@ -30,6 +32,17 @@
30
32
  border-color: transparent;
31
33
  }
32
34
 
35
+ /* Вид «fill» — залитое поле с чертой снизу, как у материального поля первого кита: скругление
36
+ у него своё и малое — скругление поля бывает «таблеткой», а у залитого поля низ прямой.
37
+ Объявлен до блоков состояний: фокус, ошибка и «только чтение» идут ниже и
38
+ перекрывают его рамку. */
39
+ &--appearance--fill {
40
+ border-color: transparent;
41
+ border-radius: var(--rt-input-number-fill-radius) var(--rt-input-number-fill-radius) 0 0;
42
+ border-bottom-color: var(--rt-color-field-fill-underline);
43
+ background-color: var(--rt-color-bg-surface-subtle-2);
44
+ }
45
+
33
46
  &--invalid {
34
47
  border-color: var(--rt-input-color-border-error);
35
48
 
@@ -24,6 +24,13 @@
24
24
  | `align` | `'start' \| 'end'` | `'end'` |
25
25
  | `disabled` | `boolean` | `false` |
26
26
 
27
+ | выход | тип |
28
+ | -------------- | --------- |
29
+ | `openedChange` | `boolean` |
30
+
31
+ `openedChange` приходит, когда панель открылась или закрылась — нажатием, выбором пункта,
32
+ щелчком мимо или клавишей Escape. По нему таблица отмечает строку, чьё меню открыто.
33
+
27
34
  ## `rt-menu-item`
28
35
 
29
36
  | вход | тип | умолчание |
@@ -31,6 +38,7 @@
31
38
  | `label` | `string` | `''` |
32
39
  | `icon` | `IRtIcon.Name \| null` | `null` |
33
40
  | `danger` / `disabled` | `boolean` | `false` |
41
+ | `current` | `boolean` | `false` |
34
42
  | `tooltip` | `string` | — (через `[rtTooltip]` на host-е) |
35
43
  | `confirmMessage` | `string` | `''` |
36
44
  | `confirmTitle` | `string \| null` | `null` |
@@ -57,6 +65,8 @@
57
65
  - Отключённый пункт не выбирается и меню не закрывает: он выпадает из таб-порядка (`tabindex`
58
66
  снимается) и помечается `aria-disabled`.
59
67
  - Enter и Space на пункте работают как клик.
68
+ - Пункты для хода стрелками меню берёт из разметки панели, а не запросом компонентов: таблица
69
+ кладёт их шаблоном приложения, и запрос содержимого меню их не видит.
60
70
  - Панель объявлена `role="menu"`, пункт — `role="menuitem"`.
61
71
 
62
72
  ## Рядом