@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
@@ -5,16 +5,27 @@
5
5
  .rt-menu-item {
6
6
  --rt-menu-item-radius: var(--rt-radius-sm);
7
7
  --rt-menu-item-transition-duration: var(--rt-duration-fast);
8
+ --rt-menu-item-weight: var(--rt-overlay-menu-item-weight);
9
+ --rt-menu-item-danger-color: var(--rt-overlay-menu-danger-color);
10
+ --rt-menu-item-current-bg: var(--rt-overlay-menu-current-bg);
11
+ --rt-menu-item-min-height: var(--rt-overlay-menu-item-min-height);
12
+ --rt-menu-item-padding-y: var(--rt-overlay-menu-item-padding-y);
13
+ --rt-menu-item-padding-x: var(--rt-overlay-menu-item-padding-x);
14
+ --rt-menu-item-icon-size: var(--rt-overlay-menu-item-icon-size);
15
+ --rt-menu-item-danger-label-color: var(--rt-overlay-menu-danger-label-color);
16
+ --rt-menu-item-success-color: var(--rt-color-state-success-text);
8
17
 
9
18
  display: flex;
10
19
  width: 100%;
20
+ min-height: var(--rt-menu-item-min-height);
11
21
  box-sizing: border-box;
12
22
  align-items: center;
13
- padding: var(--rt-space-sm) var(--rt-space-md);
23
+ padding: var(--rt-menu-item-padding-y) var(--rt-menu-item-padding-x);
14
24
  border-radius: var(--rt-menu-item-radius);
15
25
  color: var(--rt-color-text-primary);
16
26
  cursor: pointer;
17
27
  font-size: var(--rt-text-sm);
28
+ font-weight: var(--rt-menu-item-weight);
18
29
  gap: var(--rt-space-sm);
19
30
  text-align: start;
20
31
  transition: background-color var(--rt-menu-item-transition-duration) ease;
@@ -28,7 +39,14 @@
28
39
  outline: none;
29
40
  }
30
41
 
42
+ /* Значок кит рисует размером sm строкой стиля. Границы размера её перебивают: нижняя — когда
43
+ больше, верхняя — когда меньше. Так набор растит значок пункта до значка первого кита и
44
+ ужимает значок компактного пункта. */
31
45
  &__icon {
46
+ min-width: var(--rt-menu-item-icon-size);
47
+ max-width: var(--rt-menu-item-icon-size);
48
+ min-height: var(--rt-menu-item-icon-size);
49
+ max-height: var(--rt-menu-item-icon-size);
32
50
  flex-shrink: 0;
33
51
  color: var(--rt-color-text-muted);
34
52
  }
@@ -38,11 +56,25 @@
38
56
  white-space: nowrap;
39
57
  }
40
58
 
59
+ &--current {
60
+ background: var(--rt-menu-item-current-bg);
61
+ }
62
+
41
63
  &--danger {
42
- color: var(--rt-color-state-error-text);
64
+ color: var(--rt-menu-item-danger-label-color);
65
+
66
+ .rt-menu-item__icon {
67
+ color: var(--rt-menu-item-danger-color);
68
+ }
69
+ }
70
+
71
+ /* Подпись и значок — текстовой ступенью успеха: сам статус как текст 14px порога
72
+ контраста не берёт ни в одном наборе. */
73
+ &--success {
74
+ color: var(--rt-menu-item-success-color);
43
75
 
44
76
  .rt-menu-item__icon {
45
- color: var(--rt-color-state-error-text);
77
+ color: var(--rt-menu-item-success-color);
46
78
  }
47
79
  }
48
80
 
@@ -10,18 +10,28 @@
10
10
  &__panel {
11
11
  /* Панель рисуется в CDK Overlay, вне поддерева блока: свойство
12
12
  объявляется на ней самой — с корня блока оно бы не докатилось. */
13
- --rt-menu-panel-radius: var(--rt-radius-md);
13
+ --rt-menu-panel-radius: var(--rt-overlay-menu-radius);
14
14
  --rt-menu-panel-border-width: var(--rt-border-width-thin);
15
- --rt-menu-panel-shadow: var(--rt-shadow-lg);
15
+ --rt-menu-panel-shadow: var(--rt-overlay-menu-shadow);
16
+ --rt-menu-panel-bg: var(--rt-overlay-menu-bg);
17
+ --rt-menu-panel-padding-y: var(--rt-overlay-menu-padding-y);
18
+ --rt-menu-panel-min-width: var(--rt-overlay-menu-min-width);
16
19
 
17
20
  display: flex;
18
- min-width: 180px;
21
+ min-width: var(--rt-menu-panel-min-width);
19
22
  flex-direction: column;
20
- padding: var(--rt-space-xs);
23
+ padding: var(--rt-menu-panel-padding-y) var(--rt-space-xs);
21
24
  border: var(--rt-menu-panel-border-width) solid var(--rt-color-border-subtle);
22
25
  border-radius: var(--rt-menu-panel-radius);
23
- background: var(--rt-color-bg-surface);
26
+ background: var(--rt-menu-panel-bg);
24
27
  box-shadow: var(--rt-menu-panel-shadow);
28
+
29
+ /* Компактная панель переназначает пунктам высоту и размер значка: пункт читает их из
30
+ этих имён, а панель лежит над пунктами. */
31
+ &--size--sm {
32
+ --rt-overlay-menu-item-min-height: var(--rt-overlay-menu-sm-item-min-height);
33
+ --rt-overlay-menu-item-icon-size: var(--rt-overlay-menu-sm-item-icon-size);
34
+ }
25
35
  }
26
36
  }
27
37
  }
@@ -29,6 +29,9 @@
29
29
  - Значение всегда заменяется новым массивом, прежний не правится: форма видит новую ссылку.
30
30
  - `null` в форме читается как пустой выбор.
31
31
  - Закрытие панели помечает контрол тронутым; `FormControl.disable()` закрывает раскрытую панель.
32
+ - Ширина панели не меньше ширины триггера и дальше растёт по содержимому; высота упирается в
33
+ предел кита, длинный список прокручивается внутри. Задаётся входами `panelWidth` и
34
+ `panelMaxHeight` (`none` снимает предел) — так же, как у `rt-select`.
32
35
  - Подпись фишки берётся из `options` пайпом `rtMultiselectLabel`; для значения вне набора
33
36
  подставляется его строковое представление.
34
37
  - Отключённые опции не выбираются, пустой набор даёт `uiNoOptions`.
@@ -1,6 +1,7 @@
1
1
  @layer rt-kit.components {
2
2
  .rt-multiselect {
3
3
  --rt-multiselect-caret-transition-duration: var(--rt-duration-fast);
4
+ --rt-multiselect-own-outline-width: var(--rt-border-width-medium);
4
5
 
5
6
  position: relative;
6
7
  display: block;
@@ -49,10 +50,48 @@
49
50
  }
50
51
  }
51
52
 
53
+ /* Свой указатель потребителя: полевой вид кнопки снимается — ground, рамка, высота и
54
+ отступы. Останется он — значок или метка потребителя окажутся внутри чужого поля, и
55
+ вход теряет смысл. Поведение при этом на кнопке, снимается только вид.
56
+
57
+ Ширина входит в полевой вид наравне с рамкой: поле берёт всю ширину хозяина, а разметка
58
+ потребителя уже. В покое этого не видно — фон и рамка сняты, — а на нажатии полевое
59
+ кольцо обводит кнопку, и она оказывается шире нарисованного. Поэтому кнопка меряется
60
+ своим содержимым, а полевые состояния — кольцо на фокусе и рамка открытого списка — на
61
+ своём указателе не рисуются вовсе. Открытость потребитель рисует сам: обстановка шаблона
62
+ несёт её признаком. */
63
+ &__trigger--own {
64
+ width: auto;
65
+ min-height: 0;
66
+ padding: 0;
67
+ border-color: transparent;
68
+ background-color: transparent;
69
+
70
+ &:focus {
71
+ border-color: transparent;
72
+ box-shadow: none;
73
+ }
74
+
75
+ /* Ход клавишами остаётся видимым: снять полевое кольцо значит снять единственную
76
+ примету фокуса. Обводка идёт по содержимому кнопки — кнопка теперь по нему и
77
+ меряется. :focus-visible, а не :focus: щелчку мышью примета не нужна, её даёт
78
+ разметка потребителя. */
79
+ &:focus-visible {
80
+ outline: var(--rt-multiselect-own-outline-width) solid var(--rt-input-color-border-focus);
81
+ outline-offset: var(--rt-input-focus-outline-offset);
82
+ }
83
+ }
84
+
52
85
  &--open &__trigger {
53
86
  border-color: var(--rt-input-color-border-focus);
54
87
  }
55
88
 
89
+ /* Рамка открытого списка — тот же полевой вид, только приходит позже. Правило выше бьёт
90
+ объявление у --own по силе, поэтому снимается отдельной строкой. */
91
+ &--open &__trigger--own {
92
+ border-color: transparent;
93
+ }
94
+
56
95
  &--invalid &__trigger {
57
96
  border-color: var(--rt-input-color-border-error);
58
97
 
@@ -61,6 +100,16 @@
61
100
  }
62
101
  }
63
102
 
103
+ /* Рамка ошибки — тоже полевой вид. Неверность своего указателя потребитель показывает
104
+ своей разметкой: чужая красная рамка легла бы вокруг его метки. */
105
+ &--invalid &__trigger--own {
106
+ border-color: transparent;
107
+
108
+ &:focus {
109
+ box-shadow: none;
110
+ }
111
+ }
112
+
64
113
  &--disabled {
65
114
  opacity: var(--rt-input-disabled-opacity);
66
115
  }
@@ -141,8 +190,16 @@
141
190
  объявляется на ней самой — с корня блока оно бы не докатилось. */
142
191
  --rt-multiselect-panel-shadow: var(--rt-shadow-md);
143
192
 
193
+ /* Предел высоты по умолчанию — предел кита: длинный список прокручивается внутри
194
+ панели, а не уходит за нижний край экрана. Вход `panelMaxHeight` ставит свой
195
+ предел на саму панель, а `none` снимает его для короткого списка. */
196
+ --rt-multiselect-panel-max-height: var(--rt-input-panel-max-height);
197
+
198
+ /* Ширина берётся от коробки наложения: её нижнюю границу ставит указатель,
199
+ а выше она растёт по содержимому. Без этой строки панель мерилась бы
200
+ содержимым внутри коробки и не дотягивалась до ширины поля. */
144
201
  width: 100%;
145
- max-height: var(--rt-input-panel-max-height);
202
+ max-height: var(--rt-multiselect-panel-max-height);
146
203
  box-sizing: border-box;
147
204
  border: var(--rt-input-border-width) solid var(--rt-color-border-subtle);
148
205
  border-radius: var(--rt-input-radius);
@@ -13,6 +13,7 @@
13
13
  | ---------------- | ----------------------------------------------------- | --------------- |
14
14
  | `pageModel` | `IPageModel` (`pageNumber`, `pageSize`, `totalCount`) | **обязателен** |
15
15
  | `perPageOptions` | `ReadonlyArray<number>` | `[20, 50, 100]` |
16
+ | `numbering` | `'neighbours' \| 'seven'` | `'neighbours'` |
16
17
  | `loading` | `boolean` | `false` |
17
18
 
18
19
  | выход | тип |
@@ -34,7 +35,9 @@
34
35
  - Во время загрузки заблокированы и номера, и стрелки — иначе второй клик ушёл бы поверх ещё
35
36
  не пришедшего ответа.
36
37
  - Полоса номеров показывает первую, последнюю и по одному соседу открытой страницы; между ними —
37
- «…». При единственной странице номеров нет вовсе.
38
+ «…». При единственной странице номеров нет вовсе. `numbering="seven"` считает номера по семи
39
+ местам, как первый кит: `1 2 3 … 11 12 13` у краёв, одна страница — номер 1 между стрелками.
40
+ Так её просит список под материальным набором.
38
41
  - Узкая и широкая разметки живут в DOM **одновременно** (`pagination-compact` и
39
42
  `pagination-nav`): какую показать, решает медиазапрос, а не условная отрисовка.
40
43
  - **У пустого набора нет своего вида строки диапазона — бар при нём спрятан целиком.** Ветка на
@@ -1,22 +1,35 @@
1
1
  @layer rt-kit.components {
2
2
  .rt-pagination {
3
- --rt-pagination-page-radius: var(--rt-radius-md);
3
+ --rt-pagination-page-radius: var(--rt-pagination-box-radius);
4
4
  --rt-pagination-page-border-width: var(--rt-border-width-thin);
5
5
  --rt-pagination-focus-shadow: var(--rt-shadow-focus-ring);
6
6
  --rt-pagination-transition-duration: var(--rt-duration-fast);
7
7
 
8
8
  display: flex;
9
9
  align-items: center;
10
- justify-content: space-between;
11
- padding: var(--rt-space-4) var(--rt-space-xs);
10
+ justify-content: var(--rt-pagination-justify);
11
+ padding: var(--rt-pagination-padding-y) var(--rt-pagination-padding-x);
12
12
 
13
13
  // Адаптив завязан на собственную ширину компонента, а не на viewport:
14
14
  // в узком контейнере (зажатая таблица / aside) числовая полоса прячется,
15
15
  // показывается compact-форма «‹ Стр. N из M ›».
16
16
  container-type: inline-size;
17
- gap: var(--rt-space-md);
17
+ gap: var(--rt-pagination-gap);
18
+
19
+ // Стрелки — кнопки-значки кита; ячейкой полосы их делают её имена: размер, скругление,
20
+ // рамка тенью и цвет значка. Свой вид оставляет их прежними кнопками-значками.
21
+ rt-icon-button {
22
+ --rt-icon-button-color: var(--rt-pagination-arrow-color);
23
+ }
24
+
25
+ .rt-icon-button {
26
+ --rt-icon-button-size: var(--rt-pagination-arrow-size);
27
+ --rt-icon-button-square-radius: var(--rt-pagination-arrow-radius);
28
+ --rt-icon-button-shadow: var(--rt-pagination-arrow-shadow);
29
+ }
18
30
 
19
31
  &__range {
32
+ display: var(--rt-pagination-range-display);
20
33
  color: var(--rt-color-text-muted);
21
34
  font-size: var(--rt-text-sm);
22
35
  white-space: nowrap;
@@ -25,7 +38,7 @@
25
38
  &__nav {
26
39
  display: flex;
27
40
  align-items: center;
28
- gap: var(--rt-space-xs);
41
+ gap: var(--rt-pagination-nav-gap);
29
42
  }
30
43
 
31
44
  // Compact-форма по умолчанию скрыта — показывается только в узком контейнере.
@@ -42,14 +55,18 @@
42
55
  }
43
56
 
44
57
  &__page {
45
- min-width: var(--rt-space-xl);
46
- height: var(--rt-space-xl);
58
+ min-width: var(--rt-pagination-box-size);
59
+ height: var(--rt-pagination-box-size);
47
60
  padding: 0 var(--rt-space-sm);
48
- border: var(--rt-pagination-page-border-width) solid var(--rt-color-border-default);
61
+ border: var(--rt-pagination-page-border-width) solid var(--rt-pagination-box-color-border);
49
62
  border-radius: var(--rt-pagination-page-radius);
50
63
  background: transparent;
51
- color: var(--rt-color-text-primary);
64
+ color: var(--rt-pagination-box-color-text);
52
65
  cursor: pointer;
66
+
67
+ // Кнопке браузер даёт свой шрифт, а не шрифт страницы.
68
+ font: inherit;
69
+ font-size: var(--rt-text-sm);
53
70
  transition:
54
71
  background-color var(--rt-pagination-transition-duration) ease,
55
72
  border-color var(--rt-pagination-transition-duration) ease,
@@ -67,9 +84,10 @@
67
84
  }
68
85
 
69
86
  &--current {
70
- border-color: var(--rt-color-border-strong);
71
- background: var(--rt-color-bg-surface-subtle);
72
- font-weight: var(--rt-font-weight-semibold);
87
+ border-color: var(--rt-pagination-box-current-color-border);
88
+ background: var(--rt-pagination-box-current-color-bg);
89
+ color: var(--rt-pagination-box-current-color-text);
90
+ font-weight: var(--rt-pagination-box-current-font-weight);
73
91
  }
74
92
 
75
93
  &:disabled {
@@ -83,15 +101,27 @@
83
101
  color: var(--rt-color-text-muted);
84
102
  }
85
103
 
104
+ // Поле размера — выпадающий список кита; высоту, скругление, рамку и отступ ему дают имена
105
+ // полосы через свойства поля.
86
106
  &__per-page {
107
+ --rt-input-height: var(--rt-pagination-field-height);
108
+ --rt-input-radius: var(--rt-pagination-field-radius);
109
+ --rt-input-color-border: var(--rt-pagination-field-color-border);
110
+ --rt-input-padding-x: var(--rt-pagination-field-padding-x);
111
+ --rt-input-color-bg: var(--rt-pagination-field-color-bg);
112
+ --rt-input-color-text: var(--rt-pagination-field-color-text);
113
+
87
114
  display: flex;
88
115
  align-items: center;
89
- gap: var(--rt-space-sm);
116
+ gap: var(--rt-pagination-per-page-gap);
90
117
  }
91
118
 
119
+ // Свой вид переносит подпись: на узком экране поле иначе уходит за край. Материальный набор
120
+ // держит её в строку, как первый кит.
92
121
  &__per-page-label {
93
122
  color: var(--rt-color-text-muted);
94
123
  font-size: var(--rt-text-sm);
124
+ white-space: var(--rt-pagination-per-page-label-white-space);
95
125
  }
96
126
  }
97
127
 
@@ -0,0 +1,42 @@
1
+ # `rt-radio-button`
2
+
3
+ ```html
4
+ <rt-radio-button label="Москва" [value]="moscow" [formControl]="city" />
5
+ <rt-radio-button ariaLabel="Выбрать запись" [value]="row.id" [checked]="chosen() === row.id" (checkedChange)="chosen.set(row.id)" />
6
+ ```
7
+
8
+ | вход | тип | умолчание |
9
+ | ------------- | ----------------- | --------- |
10
+ | `value` | `unknown` | — |
11
+ | `checked` | `boolean \| null` | `null` |
12
+ | `disabled` | `boolean` | `false` |
13
+ | `card` | `boolean` | `false` |
14
+ | `label` | `string` | `''` |
15
+ | `description` | `string` | `''` |
16
+ | `ariaLabel` | `string \| null` | `null` |
17
+
18
+ Выходы: `clickAction` — каждое нажатие указателем, `checkedChange` — радиокнопка стала выбранной.
19
+
20
+ ## Главное, что нужно знать
21
+
22
+ **Выбрана та, чьё значение — сама модель, а не равное ей.** Две записи с одинаковым содержимым —
23
+ два разных значения.
24
+
25
+ **Выбор приходит двумя путями.** Форма пишет модель через `ControlValueAccessor`; без формы
26
+ выбранность ставится входом `checked`, и он решает раньше модели. Не заданный `checked` — `null`.
27
+
28
+ **Нажатие на выбранную ничего не меняет**, но помечает контрол тронутым и сообщается `clickAction`.
29
+ Нажатие дальше радиокнопки не идёт. Выбор клавишей `clickAction` не сообщает.
30
+
31
+ ## Как этим пользоваться
32
+
33
+ - Отключение приходит двумя путями — вход `[disabled]` и `FormControl.disable()`; недоступна, если
34
+ так сказал любой.
35
+ - Несколько радиокнопок на одном поле формы: выбор одной снимает точку с прежней — каждая слушает
36
+ сам контрол, и только нынешний: сменённый `[formControl]` или `[formGroup]` прежний бросает.
37
+ Для таблицы и списков — вход `checked`.
38
+ - Кружок без подписи получает имя через `ariaLabel`.
39
+
40
+ ## Рядом
41
+
42
+ - [`rt-checkbox`](../checkbox/CONTEXT.md) — независимый выбор «да / нет».
@@ -0,0 +1,105 @@
1
+ @layer rt-kit.components {
2
+ /* rt-radio-button — радиокнопка. ViewEncapsulation.None, как у галочки: класс блока висит и на
3
+ хосте, и на корне шаблона, поэтому правила блока вложены в хост. Размеры образца лежат на
4
+ шкале кита: кружок 16px — ступень габарита, точка 6px округлена к ближней ступени 8px,
5
+ поля карточки 12 и 16px — к ступеням отступа 8 и 16px. Текст выравнивается по началу, что бы
6
+ ни стояло вокруг: ячейка, центрующая текст, уводила пояснение под середину подписи. */
7
+
8
+ rt-radio-button {
9
+ display: inline-block;
10
+ }
11
+
12
+ rt-radio-button .rt-radio-button {
13
+ --rt-radio-button-size: var(--rt-size-4);
14
+ --rt-radio-button-dot-size: var(--rt-size-2);
15
+ --rt-radio-button-rim-width: var(--rt-border-width-medium);
16
+ --rt-radio-button-round: var(--rt-radius-full);
17
+ --rt-radio-button-focus-radius: var(--rt-radius-sm);
18
+ --rt-radio-button-focus-shadow: var(--rt-shadow-focus-ring);
19
+ --rt-radio-button-card-radius: var(--rt-radius-md);
20
+ --rt-radio-button-card-border-width: var(--rt-border-width-thin);
21
+ --rt-radio-button-transition-duration: var(--rt-duration-fast);
22
+
23
+ display: flex;
24
+ align-items: center;
25
+ cursor: pointer;
26
+ gap: var(--rt-space-sm);
27
+ text-align: start;
28
+
29
+ &:focus-visible {
30
+ border-radius: var(--rt-radio-button-focus-radius);
31
+ box-shadow: var(--rt-radio-button-focus-shadow);
32
+ outline: 2px solid transparent;
33
+ outline-offset: 2px;
34
+ }
35
+
36
+ &__indicator {
37
+ display: inline-flex;
38
+ width: var(--rt-radio-button-size);
39
+ height: var(--rt-radio-button-size);
40
+ flex-shrink: 0;
41
+ align-items: center;
42
+ justify-content: center;
43
+ border: var(--rt-radio-button-rim-width) solid var(--rt-color-border-strong);
44
+ border-radius: var(--rt-radio-button-round);
45
+ transition: border-color var(--rt-radio-button-transition-duration) ease;
46
+ }
47
+
48
+ &__dot {
49
+ width: var(--rt-radio-button-dot-size);
50
+ height: var(--rt-radio-button-dot-size);
51
+ border-radius: var(--rt-radio-button-round);
52
+ background: var(--rt-color-action-primary);
53
+ }
54
+
55
+ &__content {
56
+ display: flex;
57
+ min-width: 0;
58
+ flex: 1;
59
+ flex-direction: column;
60
+ gap: var(--rt-space-xs);
61
+ }
62
+
63
+ &__label {
64
+ color: var(--rt-color-text-primary);
65
+ font-size: var(--rt-text-sm);
66
+ user-select: none;
67
+ }
68
+
69
+ &__description {
70
+ color: var(--rt-color-text-muted);
71
+ font-size: var(--rt-text-xs);
72
+ }
73
+
74
+ /* Элемент адресуется классом, а не вторым `&`: родитель составной, и второй `&`
75
+ развернулся бы в селектор вложенной радиокнопки — так уже промахнулась галочка. */
76
+ &--checked .rt-radio-button__indicator {
77
+ border-color: var(--rt-color-action-primary);
78
+ }
79
+
80
+ &--card {
81
+ flex-direction: row-reverse;
82
+ align-items: flex-start;
83
+ justify-content: space-between;
84
+ padding: var(--rt-space-sm) var(--rt-space-md);
85
+ border: var(--rt-radio-button-card-border-width) solid var(--rt-color-border-subtle);
86
+ border-radius: var(--rt-radio-button-card-radius);
87
+ transition: border-color var(--rt-radio-button-transition-duration) ease;
88
+ }
89
+
90
+ &--card .rt-radio-button__label {
91
+ font-weight: var(--rt-font-weight-medium);
92
+ }
93
+
94
+ &--card.rt-radio-button--checked {
95
+ border-color: var(--rt-color-action-primary);
96
+ }
97
+
98
+ /* Состояние стоит ниже вида: отключение гасит карточку и выбор, обратного не бывает. */
99
+ &--disabled {
100
+ cursor: not-allowed;
101
+ opacity: var(--rt-opacity-disabled);
102
+ pointer-events: none;
103
+ }
104
+ }
105
+ }
@@ -0,0 +1,52 @@
1
+ # `rt-scroll-area`
2
+
3
+ ```html
4
+ <rt-scroll-area [isScrollHintShown]="true">
5
+ <ng-container *rtScrollAreaHeader>
6
+ <h3>Заявки смены</h3>
7
+ </ng-container>
8
+ <ng-container *rtScrollAreaContent>
9
+ @for (row of rows(); track row.id) {
10
+ <rt-info-item [title]="row.title" />
11
+ }
12
+ </ng-container>
13
+ <ng-container *rtScrollAreaFooter>
14
+ <span>Всего: {{ rows().length }}</span>
15
+ </ng-container>
16
+ </rt-scroll-area>
17
+ ```
18
+
19
+ | вход | тип | умолчание |
20
+ | ------------------- | --------- | --------- |
21
+ | `isScrollHintShown` | `boolean` | `false` |
22
+
23
+ Выходов нет. Части объявляются тремя директивами: `rtScrollAreaHeader`, `rtScrollAreaContent`,
24
+ `rtScrollAreaFooter`.
25
+
26
+ ## Главное, что нужно знать
27
+
28
+ **Необъявленная часть не рисуется вовсе.** Пустая шапка — это полоса отступа над списком, и
29
+ высоту она забирает у тела. Подан только `rtScrollAreaContent` — в разметке будет одно тело.
30
+
31
+ **Признак непоказанного снизу выключен по умолчанию.** Область рисуют десятки экранов, и признак,
32
+ поставленный безусловно, сдвинул бы вид каждому. Включается входом.
33
+
34
+ **Признак встаёт до первого движения руки.** Событие прокрутки приходит только после того, как
35
+ кто-то прокрутил, а список не влезает уже на первой отрисовке: за размером тела и подвала следит
36
+ наблюдатель. Наблюдатели живут, только пока признак включён: без входа область не следит ни за чем
37
+ и раскладку не читает.
38
+
39
+ **Полоса растушёвки доходит до содержимого подвала, а не до края тела.** Разделитель потребитель
40
+ рисует первой строкой подвала, и подъём полосы область измеряет сама — это высота подвала без его
41
+ верхнего отступа. Без подвала полоса стоит у самого низа.
42
+
43
+ ## Как этим пользоваться
44
+
45
+ - Высоту области задаёт потребитель: она берёт сто процентов своего хоста.
46
+ - Нажатие на значок уводит тело к самому низу и в содержимое под значком не уходит.
47
+ - Полоса не ловит указатель — нажатия по списку под ней проходят насквозь; значок ловит сам.
48
+ - Перекрасить растушёвку можно свойством `--rt-scroll-area-hint-color` на блоке.
49
+
50
+ ## Договорённость
51
+
52
+ `docs/specs/ui-kit-v2/scroll-area/` — девять правил и сценарии `SC-UKV-148`…`SC-UKV-156`.
@@ -0,0 +1,69 @@
1
+ @layer rt-kit.components {
2
+ .rt-scroll-area {
3
+ --rt-scroll-area-hint-height: var(--rt-space-10);
4
+ --rt-scroll-area-hint-color: var(--rt-color-bg-surface);
5
+ --rt-scroll-area-hint-radius: var(--rt-radius-full);
6
+
7
+ // Полоса растушёвки считает своё место от хоста: тело обрезает всё по своему краю, а
8
+ // полоса обязана дойти до содержимого подвала.
9
+ position: relative;
10
+ display: flex;
11
+ flex-direction: column;
12
+ block-size: 100%;
13
+ inline-size: 100%;
14
+ min-block-size: 0;
15
+
16
+ &__header {
17
+ flex: 0 0 auto;
18
+ padding: var(--rt-space-2) var(--rt-space-4);
19
+ }
20
+
21
+ &__body {
22
+ display: flex;
23
+ overflow: auto;
24
+ flex: 1 1 auto;
25
+ flex-direction: column;
26
+ padding: var(--rt-space-4);
27
+ min-block-size: 0;
28
+ }
29
+
30
+ &__footer {
31
+ flex: 0 0 auto;
32
+ padding: var(--rt-space-4);
33
+ }
34
+
35
+ // Полоса стоит поверх стыка тела и подвала и не ловит указатель: под ней живой список,
36
+ // и перехваченное нажатие уводило бы человека мимо пункта. Значок ловит его сам — иначе
37
+ // подсказку не прочитать. Места в колонке полоса не занимает: занятое, оно отодвинуло бы
38
+ // последний пункт от края у каждого потребителя области.
39
+ &__scroll-hint {
40
+ position: absolute;
41
+ z-index: 1;
42
+ display: flex;
43
+ align-items: flex-end;
44
+ justify-content: center;
45
+
46
+ // Растушёвка красится фоном темы, а не уходит в `transparent`: прозрачный — это
47
+ // чёрный с нулевой прозрачностью, и на тёмной теме такой градиент идёт через грязь.
48
+ // Начало берётся тем же цветом с нулевой прозрачностью — переход остаётся чистым в
49
+ // обеих темах, а потребитель, перекрасивший область, получает свой цвет даром.
50
+ background: linear-gradient(to bottom, rgb(from var(--rt-scroll-area-hint-color) r g b / 0%), var(--rt-scroll-area-hint-color));
51
+ block-size: var(--rt-scroll-area-hint-height);
52
+ inset-inline: 0;
53
+ pointer-events: none;
54
+ }
55
+
56
+ // Значок сидит на своей подложке: без неё он ложится поверх растворяющегося содержимого
57
+ // и читается как его часть — на кадре его не отличить от полустёртого пункта.
58
+ &__scroll-hint-icon {
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ border-radius: var(--rt-scroll-area-hint-radius);
63
+ background-color: var(--rt-color-bg-surface);
64
+ color: var(--rt-color-text-muted);
65
+ cursor: pointer;
66
+ pointer-events: auto;
67
+ }
68
+ }
69
+ }
@@ -39,6 +39,9 @@
39
39
  - `Enter`/`Space` выбирают подсвеченную, `Escape` закрывает без выбора.
40
40
  - Опции не фокусируются поодиночке: подсвеченная называется скринридеру через
41
41
  `aria-activedescendant` на триггере.
42
+ - Подсвеченная опция **прокручивается в видимую часть панели** (`block: 'nearest'`): у панели
43
+ предел высоты, а фокус на триггере, и сам браузер её не прокручивает. То же у `rt-multiselect` и
44
+ `rt-autocomplete`.
42
45
 
43
46
  ## Края
44
47
 
@@ -46,7 +49,11 @@
46
49
  - `FormControl.disable()` **закрывает уже раскрытый** список — иначе панель висела бы над
47
50
  контролом, которым уже нельзя пользоваться.
48
51
  - Пустой набор опций рисует строку `uiNoOptions`.
49
- - Ширина панели равна ширине триггера (`rtPopoverWidth="trigger"`).
52
+ - Ширина панели не меньше ширины триггера и дальше растёт по содержимому
53
+ (`rtPopoverWidth="trigger-min"`); вход `panelWidth` возвращает прежнее `trigger` или пускает
54
+ панель по содержимому целиком.
55
+ - Высота панели упирается в предел кита `--rt-input-panel-max-height`, длинный список
56
+ прокручивается внутри. Вход `panelMaxHeight` ставит свой предел, `none` снимает его.
50
57
 
51
58
  ## Рядом
52
59