@rt-tools/ui-kit-v2 0.33.0 → 0.34.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 (217) hide show
  1. package/README.md +4 -3
  2. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +1 -0
  3. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -1
  4. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +92 -5
  5. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
  6. package/fesm2022/rt-tools-ui-kit-v2-badge.mjs +191 -0
  7. package/fesm2022/rt-tools-ui-kit-v2-badge.mjs.map +1 -0
  8. package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs +3 -2
  9. package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs.map +1 -1
  10. package/fesm2022/rt-tools-ui-kit-v2-button.mjs +6 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -1
  12. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +35 -4
  13. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -1
  14. package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs +13 -4
  15. package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs.map +1 -1
  16. package/fesm2022/rt-tools-ui-kit-v2-container.mjs +245 -60
  17. package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -1
  18. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +30 -5
  19. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -1
  20. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +113 -2
  21. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  22. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +14 -3
  23. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
  24. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +17 -3
  25. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
  26. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +6 -3
  27. package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
  28. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +2 -2
  29. package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
  30. package/fesm2022/rt-tools-ui-kit-v2-divider.mjs +112 -0
  31. package/fesm2022/rt-tools-ui-kit-v2-divider.mjs.map +1 -0
  32. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +1 -0
  33. package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -1
  34. package/fesm2022/rt-tools-ui-kit-v2-drawer.mjs +854 -0
  35. package/fesm2022/rt-tools-ui-kit-v2-drawer.mjs.map +1 -0
  36. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +16 -5
  37. package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
  38. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +580 -65
  39. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
  40. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +203 -15
  41. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -1
  42. package/fesm2022/rt-tools-ui-kit-v2-field.mjs +40 -8
  43. package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -1
  44. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +1 -0
  45. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
  46. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +7 -3
  47. package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -1
  48. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +53 -2
  49. package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -1
  50. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs +14 -4
  51. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs.map +1 -1
  52. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +6 -3
  53. package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -1
  54. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +16 -5
  55. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
  56. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +1 -0
  57. package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -1
  58. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs +14 -4
  59. package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs.map +1 -1
  60. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +3 -2
  61. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -1
  62. package/fesm2022/rt-tools-ui-kit-v2-input.mjs +207 -7
  63. package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -1
  64. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +1 -0
  65. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
  66. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +3 -2
  67. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
  68. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +2 -0
  69. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
  70. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +3 -2
  71. package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -1
  72. package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs +3 -2
  73. package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs.map +1 -1
  74. package/fesm2022/rt-tools-ui-kit-v2-progress-bar.mjs +171 -0
  75. package/fesm2022/rt-tools-ui-kit-v2-progress-bar.mjs.map +1 -0
  76. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +176 -6
  77. package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -1
  78. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +2 -1
  79. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  80. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +1 -0
  81. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
  82. package/fesm2022/rt-tools-ui-kit-v2-select.mjs +142 -23
  83. package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
  84. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +22 -9
  85. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
  86. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +3 -2
  87. package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -1
  88. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +105 -8
  89. package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -1
  90. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +13 -2
  91. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
  92. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +609 -33
  93. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
  94. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +1 -0
  95. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
  96. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +45 -7
  97. package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -1
  98. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +2 -2
  99. package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -1
  100. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +11 -2
  101. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
  102. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +152 -11
  103. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
  104. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +199 -17
  105. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
  106. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +35 -5
  107. package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
  108. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +14 -4
  109. package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -1
  110. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +6 -3
  111. package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -1
  112. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +21 -6
  113. package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
  114. package/fesm2022/rt-tools-ui-kit-v2.mjs +4 -0
  115. package/package.json +17 -1
  116. package/src/assets/icons/volume-off.svg +2 -1
  117. package/src/lib/components/autocomplete/CONTEXT.md +25 -14
  118. package/src/lib/components/autocomplete/rt-autocomplete.component.scss +19 -0
  119. package/src/lib/components/badge/CONTEXT.md +33 -0
  120. package/src/lib/components/badge/rt-badge.directive.scss +104 -0
  121. package/src/lib/components/breadcrumbs/rt-breadcrumbs.component.scss +2 -2
  122. package/src/lib/components/button/CONTEXT.md +5 -0
  123. package/src/lib/components/button/rt-button.directive.scss +3 -1
  124. package/src/lib/components/checkbox/CONTEXT.md +15 -8
  125. package/src/lib/components/color-palette/rt-color-palette.component.scss +2 -2
  126. package/src/lib/components/container/CONTEXT.md +23 -6
  127. package/src/lib/components/container/rt-container.component.scss +90 -1
  128. package/src/lib/components/copy-value/CONTEXT.md +6 -5
  129. package/src/lib/components/copy-value/rt-copy-value.component.scss +16 -0
  130. package/src/lib/components/date-picker/rt-date-picker.component.scss +7 -0
  131. package/src/lib/components/date-range/rt-date-range.component.scss +7 -0
  132. package/src/lib/components/divider/CONTEXT.md +21 -0
  133. package/src/lib/components/divider/rt-divider.component.scss +34 -0
  134. package/src/lib/components/drawer/CONTEXT.md +73 -0
  135. package/src/lib/components/drawer/rt-drawer-container.component.scss +19 -0
  136. package/src/lib/components/drawer/rt-drawer.component.scss +168 -0
  137. package/src/lib/components/drawer/rt-resize-handle.component.scss +42 -0
  138. package/src/lib/components/dynamic-selector/CONTEXT.md +5 -0
  139. package/src/lib/components/expansion-panel/CONTEXT.md +32 -8
  140. package/src/lib/components/expansion-panel/rt-expansion-panel.component.scss +67 -2
  141. package/src/lib/components/field/CONTEXT.md +43 -0
  142. package/src/lib/components/field/rt-field-label-inside.scss +179 -0
  143. package/src/lib/components/field/rt-field.component.scss +51 -2
  144. package/src/lib/components/icon-button/CONTEXT.md +17 -15
  145. package/src/lib/components/icon-button/rt-icon-button.component.scss +3 -1
  146. package/src/lib/components/inline-edit/rt-inline-edit.component.scss +4 -4
  147. package/src/lib/components/input/CONTEXT.md +45 -11
  148. package/src/lib/components/input/rt-input-floating-label.scss +192 -0
  149. package/src/lib/components/input/rt-input-icons.scss +105 -0
  150. package/src/lib/components/input/rt-input.component.scss +91 -13
  151. package/src/lib/components/input-number/CONTEXT.md +7 -0
  152. package/src/lib/components/input-number/rt-input-number.component.scss +58 -1
  153. package/src/lib/components/menu/CONTEXT.md +1 -0
  154. package/src/lib/components/multiselect/CONTEXT.md +2 -1
  155. package/src/lib/components/multiselect/rt-multiselect.component.scss +7 -0
  156. package/src/lib/components/pagination/CONTEXT.md +3 -0
  157. package/src/lib/components/pagination/rt-pagination.component.scss +7 -0
  158. package/src/lib/components/progress-bar/CONTEXT.md +22 -0
  159. package/src/lib/components/progress-bar/rt-progress-bar.component.scss +77 -0
  160. package/src/lib/components/radio-button/CONTEXT.md +9 -0
  161. package/src/lib/components/radio-button/rt-radio-group.component.scss +13 -0
  162. package/src/lib/components/select/CONTEXT.md +28 -0
  163. package/src/lib/components/select/rt-select-clear.scss +88 -0
  164. package/src/lib/components/select/rt-select-floating-label.scss +155 -0
  165. package/src/lib/components/select/rt-select-material.scss +54 -0
  166. package/src/lib/components/select/rt-select.component.scss +54 -16
  167. package/src/lib/components/side-menu/CONTEXT.md +5 -0
  168. package/src/lib/components/speed-menu/rt-speed-menu.component.scss +5 -5
  169. package/src/lib/components/stepper/CONTEXT.md +13 -5
  170. package/src/lib/components/stepper/rt-stepper.component.scss +93 -0
  171. package/src/lib/components/tabs/CONTEXT.md +57 -9
  172. package/src/lib/components/tabs/rt-tabs.component.scss +201 -5
  173. package/src/lib/components/textarea/CONTEXT.md +12 -1
  174. package/src/lib/components/textarea/rt-textarea.component.scss +116 -1
  175. package/src/lib/components/toast/CONTEXT.md +23 -0
  176. package/src/lib/components/toast/rt-toast.component.scss +37 -0
  177. package/src/lib/components/toggle-button-group/CONTEXT.md +24 -4
  178. package/src/lib/components/toggle-button-group/rt-toggle-button-group-chips.scss +151 -0
  179. package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +35 -0
  180. package/src/lib/components/tooltip/CONTEXT.md +7 -1
  181. package/src/lib/components/tree/rt-tree.component.scss +2 -2
  182. package/src/styles/_color-scheme.scss +1 -1
  183. package/src/styles/_density.scss +48 -0
  184. package/src/styles/_index.scss +8 -0
  185. package/src/styles/_preset-material.scss +160 -70
  186. package/src/styles/_primitives.scss +1 -0
  187. package/src/styles/_semantic-navigation.scss +117 -0
  188. package/src/styles/_semantic.scss +29 -98
  189. package/src/styles/_theme-dark.scss +8 -0
  190. package/styles/tokens.css +2066 -1134
  191. package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +34 -0
  192. package/types/rt-tools-ui-kit-v2-badge.d.ts +71 -0
  193. package/types/rt-tools-ui-kit-v2-checkbox.d.ts +17 -3
  194. package/types/rt-tools-ui-kit-v2-container.d.ts +65 -9
  195. package/types/rt-tools-ui-kit-v2-copy-value.d.ts +11 -1
  196. package/types/rt-tools-ui-kit-v2-core.d.ts +109 -4
  197. package/types/rt-tools-ui-kit-v2-divider.d.ts +29 -0
  198. package/types/rt-tools-ui-kit-v2-drawer.d.ts +257 -0
  199. package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +240 -25
  200. package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +87 -3
  201. package/types/rt-tools-ui-kit-v2-field.d.ts +18 -1
  202. package/types/rt-tools-ui-kit-v2-form-control.d.ts +42 -4
  203. package/types/rt-tools-ui-kit-v2-icon-button.d.ts +2 -1
  204. package/types/rt-tools-ui-kit-v2-input-number.d.ts +1 -0
  205. package/types/rt-tools-ui-kit-v2-input.d.ts +98 -4
  206. package/types/rt-tools-ui-kit-v2-progress-bar.d.ts +53 -0
  207. package/types/rt-tools-ui-kit-v2-radio-button.d.ts +80 -1
  208. package/types/rt-tools-ui-kit-v2-select.d.ts +65 -1
  209. package/types/rt-tools-ui-kit-v2-side-menu.d.ts +3 -0
  210. package/types/rt-tools-ui-kit-v2-stepper.d.ts +57 -4
  211. package/types/rt-tools-ui-kit-v2-tabs.d.ts +291 -6
  212. package/types/rt-tools-ui-kit-v2-textarea.d.ts +16 -0
  213. package/types/rt-tools-ui-kit-v2-toast.d.ts +38 -2
  214. package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +83 -3
  215. package/types/rt-tools-ui-kit-v2-tooltip.d.ts +17 -2
  216. package/types/rt-tools-ui-kit-v2.d.ts +4 -0
  217. package/src/lib/components/dynamic-selector/stories/component/test-dynamic-selector-popup-frame.component.scss +0 -6
@@ -14,6 +14,13 @@
14
14
  flex-direction: row;
15
15
  }
16
16
 
17
+ /* Пока панель сменяется, уходящая стоит поверх области содержимого от хоста, а сдвиг обеих
18
+ не выходит за его ширину. Обрезка только поперёк: вниз содержимое не режется. */
19
+ &--animating {
20
+ position: relative;
21
+ overflow-x: clip;
22
+ }
23
+
17
24
  &__header {
18
25
  display: flex;
19
26
  align-items: center;
@@ -28,6 +35,7 @@
28
35
  }
29
36
 
30
37
  &__tab-list {
38
+ position: relative;
31
39
  display: flex;
32
40
  border-bottom: var(--rt-tabs-border-width) solid var(--rt-color-border-default);
33
41
  margin: 0;
@@ -54,6 +62,41 @@
54
62
  &--stretch {
55
63
  justify-content: space-between;
56
64
  }
65
+
66
+ /* Полосу рисует общий элемент, и своя полоса выбранной вкладки гаснет. У неверной
67
+ вкладки своя полоса остаётся: она красная и у невыбранной. */
68
+ &--ink .rt-tab-item--selected:not(.rt-tab-item--invalid):after {
69
+ background-color: transparent;
70
+ }
71
+ }
72
+
73
+ /* Полоса выбранной вкладки. Место — от замера вкладки: сдвиг к её левому краю и низу,
74
+ подъём на свою высоту и спуск на толщину черты, как у полосы самой вкладки. До замера её
75
+ нет, и полосу рисует вкладка. */
76
+ &__ink {
77
+ position: absolute;
78
+ top: 0;
79
+ left: 0;
80
+ display: none;
81
+ height: 2px;
82
+ margin-top: var(--rt-tabs-border-width);
83
+ background-color: var(--rt-color-action-primary);
84
+ pointer-events: none;
85
+ transform: translateY(-100%);
86
+
87
+ &--placed {
88
+ display: block;
89
+ }
90
+
91
+ &--animated {
92
+ transition:
93
+ translate var(--rt-tabs-indicator-duration) var(--rt-tabs-indicator-easing),
94
+ width var(--rt-tabs-indicator-duration) var(--rt-tabs-indicator-easing);
95
+ }
96
+
97
+ &--invalid {
98
+ background-color: var(--rt-color-state-danger);
99
+ }
57
100
  }
58
101
 
59
102
  &__rest {
@@ -90,6 +133,33 @@
90
133
  }
91
134
  }
92
135
 
136
+ /* Стрелки в своих местах: при переполнении обе стоят по краям, полоса между ними уже.
137
+ Стрелка в сторону, куда прокручивать некуда, бледнеет и не нажимается. Черта снизу
138
+ продолжает черту полосы под стрелками. */
139
+ &__tab-list-wrapper--inline {
140
+ align-items: stretch;
141
+
142
+ .rt-tabs__rest {
143
+ position: static;
144
+ display: none;
145
+ flex-shrink: 0;
146
+ border: 0;
147
+ border-bottom: var(--rt-tabs-border-width) solid var(--rt-color-border-default);
148
+ background-color: transparent;
149
+ }
150
+
151
+ &.rt-tabs__tab-list-wrapper--overflowing .rt-tabs__rest {
152
+ display: flex;
153
+ visibility: visible;
154
+ }
155
+
156
+ .rt-tabs__rest--inactive {
157
+ color: var(--rt-color-text-disabled);
158
+ cursor: default;
159
+ pointer-events: none;
160
+ }
161
+ }
162
+
93
163
  &__controls {
94
164
  display: flex;
95
165
  flex-shrink: 0;
@@ -116,6 +186,59 @@
116
186
  &--scrollable {
117
187
  overflow: auto;
118
188
  }
189
+
190
+ /* Сохранённое тело неактивной вкладки: живёт в разметке, но не рисуется. Своё display
191
+ панели сильнее правила браузера для hidden, поэтому скрытие задано явно. */
192
+ &--idle {
193
+ display: none;
194
+ }
195
+
196
+ /* Уходящая панель снята с потока и стоит в точке, где была. */
197
+ &--leaving {
198
+ position: absolute;
199
+ right: 0;
200
+ bottom: 0;
201
+ animation: rt-tabs-panel-leave var(--rt-tabs-panel-duration) var(--rt-tabs-panel-easing) forwards;
202
+ pointer-events: none;
203
+ }
204
+
205
+ &--entering {
206
+ animation: rt-tabs-panel-enter var(--rt-tabs-panel-duration) var(--rt-tabs-panel-easing);
207
+ }
208
+
209
+ /* К вкладке правее старая уходит влево, новая въезжает справа; к левее — зеркально. */
210
+ &--shift--forward {
211
+ --rt-tabs-panel-leave-to: -100%;
212
+ --rt-tabs-panel-enter-from: 100%;
213
+ }
214
+
215
+ &--shift--backward {
216
+ --rt-tabs-panel-leave-to: 100%;
217
+ --rt-tabs-panel-enter-from: -100%;
218
+ }
219
+ }
220
+ }
221
+
222
+ @keyframes rt-tabs-panel-leave {
223
+ to {
224
+ translate: var(--rt-tabs-panel-leave-to) 0;
225
+ }
226
+ }
227
+
228
+ @keyframes rt-tabs-panel-enter {
229
+ from {
230
+ translate: var(--rt-tabs-panel-enter-from) 0;
231
+ }
232
+ }
233
+
234
+ @media (prefers-reduced-motion: reduce) {
235
+ .rt-tabs__ink--animated {
236
+ transition: none;
237
+ }
238
+
239
+ .rt-tabs__content--leaving,
240
+ .rt-tabs__content--entering {
241
+ animation: none;
119
242
  }
120
243
  }
121
244
 
@@ -123,13 +246,20 @@
123
246
  --rt-tab-item-border-width: var(--rt-border-width-thin);
124
247
  --rt-tab-item-badge-radius: var(--rt-radius-full);
125
248
  --rt-tab-item-transition-duration: var(--rt-duration-fast);
249
+ --rt-tab-item-close-size: var(--rt-size-5);
250
+ --rt-tab-item-close-radius: var(--rt-radius-full);
251
+ --rt-tab-item-close-bg: transparent;
252
+ --rt-tab-item-close-bg-hover: var(--rt-color-bg-hover);
253
+ --rt-tab-item-close-color: var(--rt-color-text-muted);
254
+ --rt-tab-item-close-color-hover: var(--rt-color-text-primary);
255
+ --rt-tab-item-close-icon-size: var(--rt-icon-step-xs);
256
+ --rt-tab-item-close-margin-inline-start: 0;
257
+ --rt-tab-item-close-margin-inline-end: calc(-1 * var(--rt-space-2));
126
258
 
127
259
  position: relative;
128
260
  display: inline-flex;
129
261
  align-items: center;
130
262
  justify-content: center;
131
- padding: var(--rt-space-2) var(--rt-space-4);
132
- border: 0;
133
263
  margin: 0;
134
264
  background-color: transparent;
135
265
  color: var(--rt-color-text-muted);
@@ -144,15 +274,18 @@
144
274
  background-color var(--rt-tab-item-transition-duration) linear;
145
275
  white-space: nowrap;
146
276
 
147
- /* Нижний индикатор активной вкладки — поверх border-bottom полосы. */
277
+ /* Нижний индикатор активной вкладки — поверх border-bottom полосы. Сдвиг вниз на толщину
278
+ черты задан через translate, а не calc: `calc(-1 * 0)` даёт число без единиц, bottom
279
+ с ним недействителен, и при токене `0` полоса уходила в середину вкладки. */
148
280
  &:after {
149
281
  position: absolute;
150
- bottom: calc(-1 * var(--rt-tab-item-border-width));
282
+ bottom: 0;
151
283
  height: 2px;
152
284
  background-color: transparent;
153
285
  content: '';
154
286
  inset-inline: 0;
155
287
  pointer-events: none;
288
+ translate: 0 var(--rt-tab-item-border-width);
156
289
  }
157
290
 
158
291
  &:hover:not(.rt-tab-item--disabled, .rt-tab-item--selected) {
@@ -163,11 +296,35 @@
163
296
  /* Inset-outline вместо box-shadow ring: полоса вкладок — scroll-контейнер
164
297
  (overflow), который обрезал бы внешнее кольцо. Inset рисуется внутри
165
298
  элемента, не клиппится и переживает forced-colors. */
166
- &:focus-visible {
299
+ &:has(> .rt-tab-item__trigger:focus-visible) {
167
300
  outline: 2px solid var(--rt-color-action-primary);
168
301
  outline-offset: -3px;
169
302
  }
170
303
 
304
+ /* Сама вкладка внутри обёртки: несёт отступы и содержимое, вид берёт у обёртки. Кольцо
305
+ фокуса рисует обёртка, чтобы оно обходило и крестик. У закрываемой вкладки правый
306
+ отступ переходит к крестику: он стоит после кнопки, и место до края вкладки — его. */
307
+ &__trigger {
308
+ display: inline-flex;
309
+ min-width: 0;
310
+ align-items: center;
311
+ justify-content: center;
312
+ padding: var(--rt-space-2) var(--rt-space-4);
313
+ border: 0;
314
+ margin: 0;
315
+ background: none;
316
+ color: inherit;
317
+ cursor: inherit;
318
+ font: inherit;
319
+ gap: inherit;
320
+ line-height: inherit;
321
+ outline: none;
322
+
323
+ &--closable {
324
+ padding-inline-end: 0;
325
+ }
326
+ }
327
+
171
328
  &__title {
172
329
  overflow: hidden;
173
330
  max-width: 200px;
@@ -193,6 +350,45 @@
193
350
  line-height: var(--rt-leading-none);
194
351
  }
195
352
 
353
+ /* Крестик закрываемой вкладки: подложка при наведении отделяет его от самой вкладки,
354
+ иначе нажатие по нему читается как выбор вкладки. Отрицательный отступ по вертикали
355
+ держит высоту вкладки: крестик выше строки подписи, и без него полоса росла бы.
356
+ Размер иконки идёт через шаг `xs` самой иконки: её ширина задана стилем на теге.
357
+ Крестик — своя кнопка рядом с кнопкой вкладки, поэтому правый отступ вкладки входит в
358
+ его отступ до края: вид тот же, что у крестика внутри вкладки. */
359
+ &__close {
360
+ --rt-icon-step-xs: var(--rt-tab-item-close-icon-size);
361
+
362
+ display: inline-flex;
363
+ width: var(--rt-tab-item-close-size);
364
+ height: var(--rt-tab-item-close-size);
365
+ flex-shrink: 0;
366
+ align-items: center;
367
+ justify-content: center;
368
+ padding: 0;
369
+ border: 0;
370
+ border-radius: var(--rt-tab-item-close-radius);
371
+ background-color: var(--rt-tab-item-close-bg);
372
+ color: var(--rt-tab-item-close-color);
373
+ cursor: pointer;
374
+ font: inherit;
375
+ margin-block: calc(-1 * var(--rt-space-1));
376
+ margin-inline: var(--rt-tab-item-close-margin-inline-start) calc(var(--rt-space-4) + var(--rt-tab-item-close-margin-inline-end));
377
+ transition:
378
+ color var(--rt-tab-item-transition-duration) linear,
379
+ background-color var(--rt-tab-item-transition-duration) linear;
380
+
381
+ &:hover {
382
+ background-color: var(--rt-tab-item-close-bg-hover);
383
+ color: var(--rt-tab-item-close-color-hover);
384
+ }
385
+
386
+ &:focus-visible {
387
+ outline: 2px solid var(--rt-color-action-primary);
388
+ outline-offset: 0;
389
+ }
390
+ }
391
+
196
392
  &--selected {
197
393
  color: var(--rt-color-action-primary);
198
394
  cursor: default;
@@ -14,8 +14,10 @@
14
14
  | `rows` | `number \| string` | `3` |
15
15
  | `resize` | `'none' \| 'vertical'` | `'vertical'` |
16
16
  | `readonly` | `boolean` | `false` |
17
+ | `appearance` | `'outline' \| 'fill'` | `'outline'` |
18
+ | `maxlength` | `number \| null` | `null` |
17
19
 
18
- Значение — `string`.
20
+ Значение — `string`. `maxlength` уходит атрибутом на поле, как у `rt-input`.
19
21
 
20
22
  ## Главное, что нужно знать
21
23
 
@@ -32,6 +34,15 @@
32
34
  - `font-family: inherit` прописан явно: без него `<textarea>` падает на моноширинный шрифт
33
35
  браузера.
34
36
  - Горизонтальное растягивание не предусмотрено — только `none` и `vertical`.
37
+ - Под материальным набором подпись вмещающего `rt-field` ложится внутрь поля: на место подсказки
38
+ в покое и на рамку при значении или фокусе. Признак — `fieldLabelInside` основы полей.
39
+ - `appearance="fill"` рисует залитое поле, как у поля ввода: только черта снизу, под набором
40
+ подпись лежит внутри поля.
41
+
42
+ ## Межбуквенный интервал
43
+
44
+ Текст берёт интервал из ручки `--rt-input-letter-spacing`, общей с полем, числом и выбором. Кит её
45
+ не объявляет: без неё интервал `normal`.
35
46
 
36
47
  ## Рядом
37
48
 
@@ -1,8 +1,18 @@
1
1
  @use '../../../styles/mixins' as kv;
2
2
 
3
3
  @layer rt-kit.components {
4
+ /* Признак набора — на предке или на самом поле: приложение ставит его и на тег контрола. */
5
+ $preset: ':is(.rt-preset-material *, [data-preset="material"] *, .rt-preset-material, [data-preset="material"])';
6
+ $preset-weak: ':where(.rt-preset-material *, [data-preset="material"] *, .rt-preset-material, [data-preset="material"])';
7
+
4
8
  .rt-textarea {
5
9
  --rt-textarea-radius: var(--rt-input-radius);
10
+ --rt-textarea-color-border-hover: var(--rt-color-text-primary);
11
+ --rt-textarea-fill-radius: var(--rt-radius-sm);
12
+
13
+ /* Боковая рамка поля: от неё отсчитывается текст. У залитого поля материального набора
14
+ боковой рамки нет. */
15
+ --rt-textarea-edge: var(--rt-input-border-width);
6
16
 
7
17
  display: block;
8
18
  width: 100%;
@@ -28,6 +38,9 @@
28
38
  monospace) — задаём inherit явно, иначе шрифт отваливается. */
29
39
  font-family: inherit;
30
40
  font-size: var(--rt-input-font-size);
41
+
42
+ /* Межбуквенный интервал значения — ручка приложения: кит её не объявляет, без неё normal. */
43
+ letter-spacing: var(--rt-input-letter-spacing, normal);
31
44
  line-height: var(--rt-textarea-line-height);
32
45
  transition: var(--rt-input-transition);
33
46
 
@@ -49,6 +62,82 @@
49
62
  }
50
63
  }
51
64
 
65
+ /* Наведение в материальном наборе — как у поля Material: рамка цвета текста. Сила правила —
66
+ на уровне поля, поэтому фокус, ошибка и «без рамки» его перекрывают. */
67
+ &#{$preset-weak} &__control:where(:hover:not(:disabled)) {
68
+ border-color: var(--rt-textarea-color-border-hover);
69
+ }
70
+
71
+ /* Вид «fill» — залитое поле с чертой снизу, как залитое поле ввода: скругление малое и
72
+ только сверху. Объявлен после наведения и до блоков состояний: ошибка ниже перекрывает его
73
+ рамку, а заливка остаётся и у отключённого поля. */
74
+ &--appearance--fill {
75
+ --rt-textarea-edge: var(--rt-input-fill-edge);
76
+ }
77
+
78
+ &--appearance--fill &__control {
79
+ border-width: var(--rt-input-fill-edge) var(--rt-input-fill-edge) var(--rt-input-border-width);
80
+ border-color: transparent;
81
+ border-radius: var(--rt-textarea-fill-radius) var(--rt-textarea-fill-radius) 0 0;
82
+ border-bottom-color: var(--rt-color-field-fill-underline);
83
+ background-color: var(--rt-color-bg-surface-subtle-2);
84
+
85
+ /* Фокус: в материальном наборе — черта снизу вдвое толще, а не кольцо по периметру. */
86
+ &:focus-visible {
87
+ border-color: var(--rt-input-color-border-focus);
88
+ box-shadow: var(--rt-input-fill-focus-shadow);
89
+ }
90
+ }
91
+
92
+ &--appearance--fill.rt-textarea--invalid &__control:focus-visible {
93
+ border-color: var(--rt-input-color-border-error);
94
+ box-shadow: var(--rt-input-fill-focus-shadow-error);
95
+ }
96
+
97
+ /* Залитая область текста в поле материального набора: подпись лежит внутри поля, первая
98
+ строка — там же, где значение залитого поля ввода, и 6 px под последней строкой вместе с
99
+ чертой, как у области текста Material. Без подписи места под неё нет: первая строка стоит
100
+ там, где стояла бы посередине однострочного поля, и снизу столько же, как у области текста
101
+ Material без mat-label. Правило лежит здесь, а не в листе подписи поля: тот держится под
102
+ порогом в 8 КБ. */
103
+ @at-root .rt-field--label-inside:is(
104
+ .rt-preset-material *,
105
+ [data-preset='material'] *,
106
+ .rt-preset-material,
107
+ [data-preset='material']
108
+ )
109
+ .rt-textarea--appearance--fill
110
+ .rt-textarea__control {
111
+ padding-top: calc(var(--rt-input-height) / 2 - var(--rt-space-6) / 2 - var(--rt-input-fill-edge));
112
+ padding-bottom: calc(var(--rt-input-height) / 2 - var(--rt-space-6) / 2 - var(--rt-input-border-width));
113
+ line-height: var(--rt-leading-normal);
114
+ }
115
+
116
+ @at-root .rt-field--label-inside:has(.rt-field__label-row):is(
117
+ .rt-preset-material *,
118
+ [data-preset='material'] *,
119
+ .rt-preset-material,
120
+ [data-preset='material']
121
+ )
122
+ .rt-textarea--appearance--fill
123
+ .rt-textarea__control {
124
+ padding-top: calc(var(--rt-input-height) / 2 - var(--rt-space-1) - var(--rt-input-fill-edge));
125
+ padding-bottom: calc(var(--rt-space-1) * 1.5 - var(--rt-input-border-width));
126
+ }
127
+
128
+ /* Под набором поле стоит в строке по верху, а не по базовой линии: так под ним нет зазора, и
129
+ область текста не выше поля Material. Своим видом кита зазор остаётся. */
130
+ &#{$preset-weak} &__control {
131
+ vertical-align: top;
132
+ }
133
+
134
+ /* Шаг входа `radius` у залитого поля скругляет все четыре угла, и черта снизу не рисуется —
135
+ как у залитого поля ввода. */
136
+ &--appearance--fill:where([data-rt-radius]) &__control {
137
+ border-radius: var(--rt-textarea-radius);
138
+ border-bottom-color: transparent;
139
+ }
140
+
52
141
  &--size--sm &__control {
53
142
  min-height: var(--rt-textarea-min-height-sm);
54
143
  }
@@ -65,8 +154,34 @@
65
154
  }
66
155
  }
67
156
 
157
+ /* Текст поля Material начинается в 16 px от внешнего края поля, рамка входит в этот отступ.
158
+ Своим видом кита отступ считается от рамки. */
159
+ &#{$preset-weak} &__control {
160
+ padding-inline: calc(var(--rt-input-padding-x) - var(--rt-textarea-edge));
161
+ }
162
+
163
+ /* Отключённое поле в материальном наборе не тускнеет, а красит рамку, текст и подсказку —
164
+ как поле ввода. Своим видом цвета равны обычным. */
68
165
  &--disabled {
69
- opacity: var(--rt-input-disabled-opacity);
166
+ opacity: var(--rt-input-disabled-field-opacity);
167
+ }
168
+
169
+ &--disabled &__control {
170
+ color: var(--rt-input-color-text-disabled);
171
+
172
+ &::placeholder {
173
+ color: var(--rt-input-color-placeholder-disabled);
174
+ }
175
+ }
176
+
177
+ /* Отключённая залитая область текста в наборе залита, как поле Material: on-surface 4 %. */
178
+ &--disabled.rt-textarea--appearance--fill &__control {
179
+ background-color: var(--rt-input-fill-color-bg-disabled);
180
+ }
181
+
182
+ &--disabled:not(.rt-textarea--invalid, .rt-textarea--appearance--fill, .rt-textarea--borderless, .rt-textarea--readonly)
183
+ &__control {
184
+ border-color: var(--rt-input-color-border-disabled);
70
185
  }
71
186
 
72
187
  /* Read-only: многострочное значение как плоский текст (переносы сохраняем). */
@@ -25,9 +25,28 @@ this.#notifications.error('Не удалось сохранить', 'danger', {
25
25
  | `visibleToasts` | `number \| string` | `3` |
26
26
  | `expand` | `boolean` | `false` |
27
27
  | `mode` | `'stack' \| 'replace'` | `'stack'` |
28
+ | `channel` | `string` | `'default'` |
28
29
 
29
30
  ## Главное, что нужно знать
30
31
 
32
+ **Ручку возвращают `open` и `openFromComponent`, короткие способы — нет.** `NotificationRef`:
33
+ `update(patch)`, `dismiss()`, `afterDismissed()`. `success`/`info`/`warning`/`error`/`emit`
34
+ остались `void`: их зовут из стрелок с типом `void`. Тостер слушает ручку до ухода тоста, тост
35
+ сообщает ей причину через `markClosed`; `onDismiss` получает только уход без действия и без
36
+ `dismiss()`. Тост, уничтоженный вместе с тостером, сообщает ручке `destroyed`.
37
+
38
+ **Свой компонент стоит на месте сообщения.** Данные — токеном `RT_TOAST_DATA`, ручка — инъекцией
39
+ `NotificationRef`. Инжектор пересоздаётся только при смене данных или ручки, поэтому живая доля
40
+ компонент не пересоздаёт.
41
+
42
+ **`bare: true` снимает с тоста оболочку.** Нет фона, рамки, отступов, тени, скругления, значка,
43
+ крестика и полосы срока: свой компонент рисует карточку и свою кнопку закрытия сам и закрывает тост
44
+ ручкой. Место в стопке, появление и уход, ручка и имя для чтения с экрана остаются. Модификатор
45
+ `rt-toast--bare` стоит после залитого и сильнее его, чтобы ни залитый, ни набор оболочку не вернули.
46
+
47
+ **`progressValue` и `details` — поля тоста.** Доля рисуется `rt-progress-bar`, подробности —
48
+ `rt-copy-value` с `wrap` под кнопкой «Детали»; высота тоста пересчитывается после каждого изменения.
49
+
31
50
  **Тосты показываются не входом, а шиной.** Стопка подписана на
32
51
  `NotificationBus` и других способов показать тост
33
52
  нет. Шина — `providedIn: 'root'`, поэтому её достаточно инжектировать где угодно.
@@ -47,6 +66,10 @@ this.#notifications.error('Не удалось сохранить', 'danger', {
47
66
  - `progress: true` рисует полосу срока; она встаёт тем же признаком `rt-toast--paused`, что и таймер.
48
67
  - `icon` у тоста важнее карты `RT_TOAST_SEVERITY_ICONS`; `icon: null` снимает значок.
49
68
  - `mode="replace"` помечает прежние тосты вытесненными, и они уходят той же анимацией, что по крестику.
69
+ - `channel` у тостера и у тоста разводит потоки. Тостер показывает только тосты своего канала; тост
70
+ без `channel` и тостер без входа стоят в канале `'default'`. Второй тостер со своим каналом держит
71
+ закреплённые тосты в своём углу: обычный тост в режиме `replace` их не вытесняет. Тост канала,
72
+ у которого нет тостера, не показывается никем.
50
73
  - `onDismiss` сообщает один раз, почему тост ушёл без действия: `close`, `timeout` или `replaced`.
51
74
  Ушедший по `action` или `secondaryAction` ничего не сообщает — его обработчик уже вызван.
52
75
 
@@ -114,6 +114,17 @@
114
114
  }
115
115
  }
116
116
 
117
+ /* Голый тост: оболочку рисует свой компонент. Два класса и место после залитого — чтобы
118
+ залитый и набор, задающий ручки тоста, оболочку не вернули. */
119
+ &.rt-toast--bare {
120
+ --rt-toast-radius: 0;
121
+ --rt-toast-border-width: 0;
122
+ --rt-toast-shadow: none;
123
+
124
+ padding: 0;
125
+ background: transparent;
126
+ }
127
+
117
128
  &--mounted {
118
129
  --y: translateY(0);
119
130
 
@@ -213,6 +224,32 @@
213
224
  font-weight: var(--rt-font-weight-regular);
214
225
  }
215
226
 
227
+ /* Сообщение тоста со своим компонентом: видно только чтению с экрана. */
228
+ &__sr-message {
229
+ position: absolute;
230
+ overflow: hidden;
231
+ width: 1px;
232
+ height: 1px;
233
+ clip-path: inset(50%);
234
+ white-space: nowrap;
235
+ }
236
+
237
+ &__custom {
238
+ min-width: 0;
239
+ }
240
+
241
+ &__value {
242
+ margin-block: var(--rt-space-1);
243
+ }
244
+
245
+ & &__details-toggle {
246
+ align-self: flex-start;
247
+ }
248
+
249
+ &__details {
250
+ display: flex;
251
+ }
252
+
216
253
  &__actions {
217
254
  display: flex;
218
255
  flex-wrap: wrap;
@@ -17,14 +17,34 @@
17
17
  | `ariaLabel` | `string \| null` | `null` |
18
18
  | `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` |
19
19
  | `disabled` / `fullWidth` | `boolean` | `false` |
20
+ | `multiple` | `boolean` | `false` |
21
+ | `values` | `ReadonlyArray<T>` | `[]` |
22
+ | `layout` | `'row' \| 'wrap' \| 'column'` | `'row'` |
23
+ | `appearance` | `'segmented' \| 'chips'` | `'segmented'` |
24
+ | `checkmark` | `boolean` | `false` |
20
25
 
21
- Выход: `valueChange`.
26
+ Выходы: `valueChange`, при `multiple` — `valuesChange` со всем набором выбранного.
22
27
 
23
28
  ## Главное, что нужно знать
24
29
 
25
- **Группа не держит состояния.** Нажатие только просит сменить значение; подсветка сдвинется,
26
- когда потребитель вернёт новое `value`. Повторное нажатие по выбранному тоже поднимает событие —
27
- снимать выбор группа не умеет.
30
+ **Без формы группа не держит состояния.** Нажатие только просит сменить значение; подсветка
31
+ сдвинется, когда потребитель вернёт новое `value`. Повторное нажатие по выбранному тоже поднимает
32
+ событие — снимать одиночный выбор группа не умеет.
33
+
34
+ **В форме группа — контрол.** `[formControl]` и `formControlName` пишут значение сами: одно при
35
+ одиночном выборе, набор при `multiple`. `FormControl.disable()` отключает группу.
36
+
37
+ **Свой сегмент — шаблон `<ng-template rtToggleButtonOption let-option let-active="active">`.** Он
38
+ встаёт внутрь кнопки на место подписи и иконки; кнопка, выбор и подсказка остаются у группы.
39
+
40
+ **`layout`** раскладывает сегменты в строку, с переносом или столбиком: перенос нужен длинным
41
+ спискам во всплывающих окнах, столбик — спискам вроде дней недели.
42
+
43
+ **`appearance="chips"` — отдельные пункты вместо дорожки.** Каждый чип с обводкой, выбранный
44
+ залит, между чипами 8 px; поведение то же, что у сегментов. В столбике чипы тянутся на ширину места
45
+ и сами берут свободную ширину строчного гибкого родителя. `checkmark` ставит галочку перед подписью
46
+ выбранного. Под материальным набором чип — фильтр-чип Material: 28 px, отступы 12 px, поле 8 px
47
+ сверху и снизу, строки через 16 px. Цвета — свойства `--rt-toggle-chip-color-*`.
28
48
 
29
49
  ## Края
30
50