@rt-tools/ui-kit-v2 0.16.0 → 0.17.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.
- package/README.md +7 -0
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +96 -41
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2.mjs +1106 -451
- package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
- package/package.json +1 -1
- package/rt-tools-ui-kit-v2-0.17.0.tgz +0 -0
- package/src/lib/components/action-bar/CONTEXT.md +5 -0
- package/src/lib/components/action-bar/rt-action-bar.component.scss +30 -16
- package/src/lib/components/aside/CONTEXT.md +9 -1
- package/src/lib/components/aside/footer/rt-aside-footer.component.scss +7 -8
- package/src/lib/components/aside/header/rt-aside-header.component.scss +16 -1
- package/src/lib/components/aside/rt-aside.component.scss +17 -1
- package/src/lib/components/button/CONTEXT.md +12 -11
- package/src/lib/components/button/rt-button.directive.scss +36 -0
- package/src/lib/components/data-list/settings/rt-data-list-settings-aside.component.scss +2 -2
- package/src/lib/components/data-table/cell/rt-data-table-cell.component.scss +1 -1
- package/src/lib/components/data-table/filter-cell/rt-data-table-filter-cell.component.scss +1 -1
- package/src/lib/components/data-table/rt-data-table.component.scss +1 -1
- package/src/lib/components/dialog/CONTEXT.md +9 -0
- package/src/lib/components/dialog/content/rt-dialog-content.component.scss +20 -0
- package/src/lib/components/dialog/footer/rt-dialog-footer.component.scss +18 -2
- package/src/lib/components/dialog/header/rt-dialog-header.component.scss +21 -3
- package/src/lib/components/dialog/rt-dialog.component.scss +9 -3
- package/src/lib/components/dynamic-selector/CONTEXT.md +6 -0
- package/src/lib/components/header/CONTEXT.md +2 -2
- package/src/lib/components/icon/CONTEXT.md +11 -7
- package/src/lib/components/icon/rt-icon.component.scss +47 -0
- package/src/lib/components/icon-button/CONTEXT.md +27 -20
- package/src/lib/components/icon-button/rt-icon-button.component.scss +51 -25
- package/src/lib/components/image-upload/CONTEXT.md +20 -15
- package/src/lib/components/image-upload/rt-image-upload.component.scss +14 -2
- package/src/lib/components/pagination/rt-pagination.component.scss +1 -1
- package/src/lib/components/scroll-area/CONTEXT.md +2 -0
- package/src/lib/components/scroll-area/rt-scroll-area.component.scss +20 -3
- package/src/lib/components/side-menu/CONTEXT.md +7 -2
- package/src/lib/components/spinner/CONTEXT.md +15 -8
- package/src/lib/components/spinner/rt-spinner.component.scss +108 -9
- package/src/lib/components/tag/rt-tag.component.scss +43 -23
- package/src/lib/components/toast/CONTEXT.md +8 -0
- package/src/lib/components/toast/rt-toast.component.scss +74 -15
- package/src/lib/components/toast/rt-toaster.component.scss +5 -1
- package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +35 -37
- package/src/lib/components/toggle-switch/CONTEXT.md +11 -3
- package/src/lib/components/toggle-switch/rt-toggle-switch.component.scss +53 -14
- package/src/lib/components/toolbar/rt-toolbar.component.scss +15 -4
- package/src/lib/components/tooltip/CONTEXT.md +5 -5
- package/src/rich-editor/lib/components/chat/CONTEXT.md +7 -2
- package/src/rich-editor/lib/components/chat/rt-chat.component.scss +25 -0
- package/styles/tokens.css +35 -0
- package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +16 -20
- package/types/rt-tools-ui-kit-v2.d.ts +371 -62
- package/rt-tools-ui-kit-v2-0.16.0.tgz +0 -0
package/package.json
CHANGED
|
Binary file
|
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
всегда, и признак значка стоит модификатором — условие в шаблоне было бы оформлением, уехавшим
|
|
39
39
|
в код.
|
|
40
40
|
|
|
41
|
+
- **Меню действия со списком живёт в оверлее, вне полосы.** Свойства полосы до него не доходят,
|
|
42
|
+
поэтому `--rt-action-bar-menu-*` читаются с запасным значением и задаются на корне страницы. Без
|
|
43
|
+
них меню скруглено ступенью `md` и отбрасывает тень карточки.
|
|
44
|
+
- **Цвета, отступы и шрифт полосы — свойства блока** `--rt-action-bar-*` со значениями прежнего вида.
|
|
45
|
+
|
|
41
46
|
## Края
|
|
42
47
|
|
|
43
48
|
- Ноль выбранного показан числом: счётчик, прячущийся на нуле, дёргал бы ширину полосы ровно в
|
|
@@ -7,12 +7,19 @@
|
|
|
7
7
|
.rt-action-bar {
|
|
8
8
|
--rt-action-bar-radius: var(--rt-radius-lg);
|
|
9
9
|
--rt-action-bar-shadow: var(--rt-shadow-card);
|
|
10
|
+
--rt-action-bar-bg: var(--rt-color-bg-inverse);
|
|
11
|
+
--rt-action-bar-color: var(--rt-color-text-inverse);
|
|
12
|
+
--rt-action-bar-padding: var(--rt-space-2) var(--rt-space-4);
|
|
13
|
+
--rt-action-bar-gap: var(--rt-space-4);
|
|
14
|
+
--rt-action-bar-font-size: var(--rt-text-sm);
|
|
15
|
+
--rt-action-bar-counter-weight: var(--rt-font-weight-medium);
|
|
10
16
|
--rt-action-bar-action-radius: var(--rt-radius-md);
|
|
11
|
-
--rt-action-bar-action-
|
|
17
|
+
--rt-action-bar-action-padding-block: var(--rt-space-1);
|
|
18
|
+
--rt-action-bar-action-padding-inline: var(--rt-space-2);
|
|
19
|
+
--rt-action-bar-action-weight: var(--rt-font-weight-medium);
|
|
20
|
+
--rt-action-bar-action-bg-hover: color-mix(in srgb, var(--rt-action-bar-color) 16%, transparent);
|
|
12
21
|
--rt-action-bar-action-color-danger: var(--rt-color-action-danger-on-surface);
|
|
13
22
|
--rt-action-bar-action-focus-shadow: var(--rt-shadow-focus-ring);
|
|
14
|
-
--rt-action-bar-menu-radius: var(--rt-radius-md);
|
|
15
|
-
--rt-action-bar-menu-shadow: var(--rt-shadow-card);
|
|
16
23
|
|
|
17
24
|
// Предел ширины стоит и на самом элементе. Содержащий блок полосы — этот элемент, и
|
|
18
25
|
// без предела он растёт по содержимому: сто процентов считались бы тогда от выросшего,
|
|
@@ -22,16 +29,16 @@
|
|
|
22
29
|
max-width: 100%;
|
|
23
30
|
box-sizing: border-box;
|
|
24
31
|
align-items: center;
|
|
25
|
-
padding: var(--rt-
|
|
32
|
+
padding: var(--rt-action-bar-padding);
|
|
26
33
|
border-radius: var(--rt-action-bar-radius);
|
|
27
|
-
background: var(--rt-
|
|
34
|
+
background: var(--rt-action-bar-bg);
|
|
28
35
|
box-shadow: var(--rt-action-bar-shadow);
|
|
29
|
-
color: var(--rt-
|
|
30
|
-
font-size: var(--rt-
|
|
31
|
-
gap: var(--rt-
|
|
36
|
+
color: var(--rt-action-bar-color);
|
|
37
|
+
font-size: var(--rt-action-bar-font-size);
|
|
38
|
+
gap: var(--rt-action-bar-gap);
|
|
32
39
|
|
|
33
40
|
&__counter {
|
|
34
|
-
font-weight: var(--rt-
|
|
41
|
+
font-weight: var(--rt-action-bar-counter-weight);
|
|
35
42
|
white-space: nowrap;
|
|
36
43
|
}
|
|
37
44
|
|
|
@@ -47,7 +54,7 @@
|
|
|
47
54
|
&__action {
|
|
48
55
|
display: flex;
|
|
49
56
|
align-items: center;
|
|
50
|
-
padding: var(--rt-
|
|
57
|
+
padding: var(--rt-action-bar-action-padding-block) var(--rt-action-bar-action-padding-inline);
|
|
51
58
|
border: 0;
|
|
52
59
|
border-radius: var(--rt-action-bar-action-radius);
|
|
53
60
|
background: transparent;
|
|
@@ -58,7 +65,7 @@
|
|
|
58
65
|
|
|
59
66
|
// Нажатие в этом ките набрано средним начертанием — так набрана кнопка кита, и
|
|
60
67
|
// действие полосы такое же нажатие. Первый кит ставил здесь шестьсот.
|
|
61
|
-
font-weight: var(--rt-
|
|
68
|
+
font-weight: var(--rt-action-bar-action-weight);
|
|
62
69
|
gap: var(--rt-space-2);
|
|
63
70
|
|
|
64
71
|
&:hover {
|
|
@@ -94,21 +101,28 @@
|
|
|
94
101
|
// белому, и крестика не было видно ни в одном кадре. Своё свойство блока перебивают —
|
|
95
102
|
// так делает просмотр фотографии, где кнопка стоит на снимке.
|
|
96
103
|
&__close {
|
|
97
|
-
--rt-icon-button-color: var(--rt-
|
|
104
|
+
--rt-icon-button-color: var(--rt-action-bar-color);
|
|
98
105
|
--rt-icon-button-color-bg-hover: var(--rt-action-bar-action-bg-hover);
|
|
99
106
|
|
|
100
107
|
flex: none;
|
|
101
108
|
margin-left: auto;
|
|
102
109
|
}
|
|
103
110
|
|
|
111
|
+
// Меню рисуется в оверлее, вне полосы: объявление на полосе до него не доходит, и раньше
|
|
112
|
+
// меню выходило без скругления и тени. Свои свойства меню читает с запасным значением —
|
|
113
|
+
// объявленное на самом меню перебило бы правило приложения на корне страницы, а только
|
|
114
|
+
// оттуда свойство до оверлея и доходит.
|
|
104
115
|
&__menu {
|
|
116
|
+
--rt-action-bar-menu-radius-default: var(--rt-radius-md);
|
|
117
|
+
--rt-action-bar-menu-shadow-default: var(--rt-shadow-card);
|
|
118
|
+
|
|
105
119
|
display: flex;
|
|
106
120
|
flex-direction: column;
|
|
107
121
|
padding: var(--rt-space-2);
|
|
108
|
-
border-radius: var(--rt-action-bar-menu-radius);
|
|
109
|
-
background: var(--rt-color-bg-surface);
|
|
110
|
-
box-shadow: var(--rt-action-bar-menu-shadow);
|
|
111
|
-
color: var(--rt-color-text-primary);
|
|
122
|
+
border-radius: var(--rt-action-bar-menu-radius, var(--rt-action-bar-menu-radius-default));
|
|
123
|
+
background: var(--rt-action-bar-menu-bg, var(--rt-color-bg-surface));
|
|
124
|
+
box-shadow: var(--rt-action-bar-menu-shadow, var(--rt-action-bar-menu-shadow-default));
|
|
125
|
+
color: var(--rt-action-bar-menu-color, var(--rt-color-text-primary));
|
|
112
126
|
}
|
|
113
127
|
|
|
114
128
|
// Полоса живёт на нижней кромке, и пальцу нужно место, которое занимают подписи. Решает
|
|
@@ -25,6 +25,8 @@ ref.afterClosed().subscribe((result?: ITour): void => …);
|
|
|
25
25
|
| `width` | `string \| null` | `null` |
|
|
26
26
|
| `ariaLabel` | `string \| null` | `null` |
|
|
27
27
|
| `requestError` | `unknown` | `null` |
|
|
28
|
+
| `trapFocus` | `boolean` | `false` |
|
|
29
|
+
| `pending` | `boolean` | `false` |
|
|
28
30
|
|
|
29
31
|
| настройка `open()` | умолчание |
|
|
30
32
|
| ---------------------------------------- | ----------------------------------------- |
|
|
@@ -32,6 +34,7 @@ ref.afterClosed().subscribe((result?: ITour): void => …);
|
|
|
32
34
|
| `position` | `'right'` |
|
|
33
35
|
| `closeOnBackdropClick` / `closeOnEscape` | `true`; второе — из настроек кита |
|
|
34
36
|
| `backdropClass` / `panelClass` | `rt-aside-backdrop` / `rt-aside-overlay` |
|
|
37
|
+
| `injector` | корневой — уничтожение хозяина закрывает |
|
|
35
38
|
|
|
36
39
|
## Главное, что нужно знать
|
|
37
40
|
|
|
@@ -54,7 +57,12 @@ ref.afterClosed().subscribe((result?: ITour): void => …);
|
|
|
54
57
|
переопределяет своими правилами. Стережёт это `rt-aside-overlay.styles.spec.ts`.
|
|
55
58
|
|
|
56
59
|
**`disableClose`** на `RtAsideRef` держит панель под кликом по подложке и под Escape — ставится
|
|
57
|
-
самим содержимым, когда в форме есть несохранённое.
|
|
60
|
+
самим содержимым, когда в форме есть несохранённое. Отказанный жест — под `disableClose` или
|
|
61
|
+
выключенный настройкой — приходит в `closeRequests()`: `'escape'` или `'backdrop'`.
|
|
62
|
+
|
|
63
|
+
**Снятый без `close()` слой завершает `afterClosed()` значением `undefined`.** Переход по адресу
|
|
64
|
+
(`disposeOnNavigation`) и уничтожение хозяина больше не оставляют подписчика ждать. То же у
|
|
65
|
+
`RtDialogRef`.
|
|
58
66
|
|
|
59
67
|
**Ошибку запроса показывает сама панель.** Вход `requestError` ставит между шапкой и содержимым
|
|
60
68
|
блок `rt-aside-error-box` с кнопкой копирования ошибки; `null` и `undefined` его убирают. Своя
|
|
@@ -4,19 +4,18 @@
|
|
|
4
4
|
.rt-aside-footer {
|
|
5
5
|
--rt-aside-footer-border-width: var(--rt-border-width-thin);
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
margin: var(--rt-aside-inset);
|
|
7
|
+
/* Отступ и поля футера — ручки приложения; без них отступ только сверху, а поля — инсет
|
|
8
|
+
панели. Верхний разделитель не на всю ширину: поля отбивают футер по горизонтали на тот
|
|
9
|
+
же инсет, что и контентная зона, и border-block-start совпадает по краям с контентом. */
|
|
10
|
+
padding: var(--rt-aside-footer-inset, var(--rt-aside-inset) 0 0);
|
|
11
|
+
margin: var(--rt-aside-footer-margin, var(--rt-aside-inset));
|
|
13
12
|
border-block-start: var(--rt-aside-footer-border-width) solid var(--rt-color-border-subtle);
|
|
14
13
|
|
|
15
14
|
&__content {
|
|
16
15
|
display: flex;
|
|
17
16
|
flex-wrap: wrap;
|
|
18
|
-
justify-content: space-between;
|
|
19
|
-
gap: var(--rt-space-sm);
|
|
17
|
+
justify-content: var(--rt-aside-footer-justify, space-between);
|
|
18
|
+
gap: var(--rt-aside-footer-gap, var(--rt-space-sm));
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
&:empty {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
--rt-aside-header-gap: var(--rt-space-sm);
|
|
10
10
|
--rt-aside-header-min-height: auto;
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/* Отступ шапки — ручка приложения; без неё общий инсет панели. */
|
|
13
|
+
padding: var(--rt-aside-header-inset, var(--rt-aside-inset));
|
|
13
14
|
|
|
14
15
|
&__content {
|
|
15
16
|
display: flex;
|
|
@@ -51,6 +52,9 @@
|
|
|
51
52
|
font-size: var(--rt-aside-header-title-size);
|
|
52
53
|
font-weight: var(--rt-aside-header-title-weight);
|
|
53
54
|
|
|
55
|
+
/* Высота строки — ручка приложения; без неё наследуется, как было. */
|
|
56
|
+
line-height: var(--rt-aside-header-title-leading, inherit);
|
|
57
|
+
|
|
54
58
|
/* Ellipsis для длинного заголовка: skeleton-wrapper рендерит `{{ title }}`
|
|
55
59
|
как ng-content внутри inline-flex; чтобы `text-overflow: ellipsis`
|
|
56
60
|
cработал, нужен block-level контейнер с overflow: hidden над текстом. */
|
|
@@ -90,6 +94,17 @@
|
|
|
90
94
|
}
|
|
91
95
|
}
|
|
92
96
|
|
|
97
|
+
/* Строка под заголовком на всю ширину шапки — слот `[asideHeaderContent]`. Пустая места
|
|
98
|
+
не занимает. */
|
|
99
|
+
&__row {
|
|
100
|
+
min-width: 0;
|
|
101
|
+
margin-top: var(--rt-aside-header-gap);
|
|
102
|
+
|
|
103
|
+
&:empty {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
93
108
|
/* Ряд action-иконок справа от title (отклонить / на доработку / снять с
|
|
94
109
|
публикации и т.п.). Пустой при отсутствии проекции — нулевой ширины. */
|
|
95
110
|
&__actions {
|
|
@@ -35,6 +35,9 @@
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
rt-aside .rt-aside {
|
|
38
|
+
/* Точка отсчёта для слоя ожидания. Рамка и так занимает панель целиком, поэтому прочим
|
|
39
|
+
потомкам она ничего не меняет. */
|
|
40
|
+
position: relative;
|
|
38
41
|
display: flex;
|
|
39
42
|
width: var(--rt-aside-width, var(--rt-aside-width-md));
|
|
40
43
|
|
|
@@ -75,6 +78,7 @@
|
|
|
75
78
|
&__error {
|
|
76
79
|
min-width: 0;
|
|
77
80
|
flex-shrink: 0;
|
|
81
|
+
margin-block: var(--rt-aside-error-margin-block, 0);
|
|
78
82
|
padding-inline: var(--rt-aside-inset);
|
|
79
83
|
}
|
|
80
84
|
|
|
@@ -87,12 +91,24 @@
|
|
|
87
91
|
min-height: 0;
|
|
88
92
|
flex: 1 1 auto;
|
|
89
93
|
flex-direction: column;
|
|
90
|
-
padding: var(--rt-aside-inset);
|
|
94
|
+
padding: var(--rt-aside-content-inset, var(--rt-aside-inset));
|
|
91
95
|
gap: var(--rt-aside-content-gap);
|
|
92
96
|
overflow-y: auto;
|
|
93
97
|
overscroll-behavior: contain;
|
|
94
98
|
}
|
|
95
99
|
|
|
100
|
+
/* Слой ожидания поверх всей панели: шапка, содержимое и футер под ним не нажимаются. Тот же
|
|
101
|
+
вид, что у слоя дозагрузки таблицы. */
|
|
102
|
+
&__pending {
|
|
103
|
+
position: absolute;
|
|
104
|
+
z-index: var(--rt-z-sticky);
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
justify-content: center;
|
|
108
|
+
background-color: color-mix(in srgb, var(--rt-color-bg-surface) 60%, transparent);
|
|
109
|
+
inset: 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
96
112
|
&--size--sm {
|
|
97
113
|
width: var(--rt-aside-width, var(--rt-aside-width-sm));
|
|
98
114
|
}
|
|
@@ -10,17 +10,18 @@
|
|
|
10
10
|
<a rtButton label="На главную" [routerLink]="'/'"></a>
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
| вход
|
|
14
|
-
|
|
|
15
|
-
| `label`
|
|
16
|
-
| `icon`
|
|
17
|
-
| `iconPos`
|
|
18
|
-
| `theme`
|
|
19
|
-
| `appearance`
|
|
20
|
-
| `size`
|
|
21
|
-
| `radius`
|
|
22
|
-
| `loading`
|
|
23
|
-
| `loadingIcon`
|
|
13
|
+
| вход | тип | умолчание |
|
|
14
|
+
| -------------- | -------------------------------------------------------------------------- | ---------------------------------- |
|
|
15
|
+
| `label` | `string \| null` | `null` |
|
|
16
|
+
| `icon` | `string \| null` (имя из набора `rt-icon`) | `null` |
|
|
17
|
+
| `iconPos` | `'left' \| 'right'` | `'left'` |
|
|
18
|
+
| `theme` | `'primary' \| 'secondary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | `'primary'` |
|
|
19
|
+
| `appearance` | `'filled' \| 'outlined' \| 'text'` | настройки кита или `'filled'` |
|
|
20
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'` (30 / 40 / 50 / 60 / 70 px) | настройки кита или `'md'` |
|
|
21
|
+
| `radius` | `TRtRadius \| null` — шаг общей шкалы | настройки кита или `null` |
|
|
22
|
+
| `loading` | `boolean` | `false` |
|
|
23
|
+
| `loadingIcon` | `string \| null` | `null` → встроенное кольцо |
|
|
24
|
+
| `loadingLabel` | `'keep' \| 'hide'` | `'keep'` — кольцо рядом с подписью |
|
|
24
25
|
|
|
25
26
|
Своего выхода нет — клик слушается нативным `(click)` на самом элементе.
|
|
26
27
|
|
|
@@ -91,6 +91,25 @@
|
|
|
91
91
|
font-size: var(--rt-btn-icon-size);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/* Лигатура шрифта Material Symbols для имени без пары — размер ей даёт `__icon` рядом.
|
|
95
|
+
Шрифт подключает приложение, семью можно переназначить свойством сверху. До готовности
|
|
96
|
+
шрифтов лигатура скрыта: иначе на её месте видно слово. */
|
|
97
|
+
&__glyph {
|
|
98
|
+
overflow: hidden;
|
|
99
|
+
font-family: var(--rt-icon-glyph-font, 'Material Symbols Outlined'), sans-serif;
|
|
100
|
+
font-feature-settings: 'liga';
|
|
101
|
+
font-style: normal;
|
|
102
|
+
font-weight: var(--rt-font-weight-regular);
|
|
103
|
+
letter-spacing: normal;
|
|
104
|
+
line-height: 1;
|
|
105
|
+
text-transform: none;
|
|
106
|
+
white-space: nowrap;
|
|
107
|
+
|
|
108
|
+
&--pending {
|
|
109
|
+
visibility: hidden;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
94
113
|
&__label {
|
|
95
114
|
display: inline-flex;
|
|
96
115
|
align-items: center;
|
|
@@ -264,6 +283,23 @@
|
|
|
264
283
|
pointer-events: none;
|
|
265
284
|
}
|
|
266
285
|
|
|
286
|
+
/* Подпись спрятана на время загрузки: содержимое гаснет прозрачностью, а не
|
|
287
|
+
`visibility` — так оно держит ширину и остаётся именем кнопки для скринридера.
|
|
288
|
+
Загрузчик встаёт поверх по центру. */
|
|
289
|
+
&--loading-label-hidden {
|
|
290
|
+
position: relative;
|
|
291
|
+
|
|
292
|
+
> :not(.rt-button__loader) {
|
|
293
|
+
opacity: 0;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
&__loader {
|
|
298
|
+
position: absolute;
|
|
299
|
+
margin: auto;
|
|
300
|
+
inset: 0;
|
|
301
|
+
}
|
|
302
|
+
|
|
267
303
|
/* Состояние стоит ниже всех вариантов оформления и палитры того же блока.
|
|
268
304
|
Специфичность у них равная, и правила равной силы разбираются порядком в
|
|
269
305
|
файле: отсюда, снизу, отключённость отменяет и заливку, и цвет подписи.
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
|
|
146
146
|
/* Кнопка «назад» — круглая `mat-icon-button` первого кита, как и кнопки подвала панели. */
|
|
147
147
|
.rt-aside-header__back .rt-icon-button {
|
|
148
|
-
--rt-icon-button-size: var(--rt-data-list-settings-aside-control-size);
|
|
148
|
+
--rt-icon-button-size-step: var(--rt-data-list-settings-aside-control-size);
|
|
149
149
|
--rt-icon-button-color: var(--rt-list-settings-icon-color);
|
|
150
150
|
--rt-icon-button-radius: var(--rt-radius-full);
|
|
151
151
|
}
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
.rt-data-list-settings-aside__toggle .rt-icon-button {
|
|
239
|
-
--rt-icon-button-size: var(--rt-data-list-settings-aside-control-size);
|
|
239
|
+
--rt-icon-button-size-step: var(--rt-data-list-settings-aside-control-size);
|
|
240
240
|
--rt-icon-button-color: var(--rt-list-settings-icon-color);
|
|
241
241
|
}
|
|
242
242
|
}
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
--rt-icon-button-color: var(--rt-list-copy-button-color);
|
|
88
88
|
|
|
89
89
|
.rt-icon-button {
|
|
90
|
-
--rt-icon-button-size: var(--rt-list-copy-button-size);
|
|
90
|
+
--rt-icon-button-size-step: var(--rt-list-copy-button-size);
|
|
91
91
|
--rt-icon-button-radius: var(--rt-list-copy-button-radius);
|
|
92
92
|
--rt-icon-button-color-hover: var(--rt-color-text-primary);
|
|
93
93
|
--rt-icon-button-color-bg-hover: var(--rt-list-copy-button-bg-hover);
|
|
@@ -44,6 +44,15 @@ ref.afterClosed().subscribe((ok?: boolean): void => …);
|
|
|
44
44
|
`RtDialogRef.disableClose` держит окно и под кликом по подложке, и под Escape — ставится самим
|
|
45
45
|
содержимым, когда закрывать нельзя.
|
|
46
46
|
|
|
47
|
+
**Фокус служба по умолчанию не трогает.** `trapFocus`, `restoreFocus` и `autoFocus` в настройке
|
|
48
|
+
открытия включают ловушку CDK, возврат фокуса и первый фокус (`'dialog'` — на рамку,
|
|
49
|
+
`'first-tabbable'` — на первый элемент под Tab). Ловушка и первый фокус ставятся после отрисовки
|
|
50
|
+
окна, ловушка уходит вместе с оверлеем.
|
|
51
|
+
|
|
52
|
+
**Части окна.** `rt-dialog-content` — тело с отступом и прокруткой; `rtDialogHeaderLead` — узел
|
|
53
|
+
перед заголовком шапки; `align` подвала — `start`, `center`, `end` (по умолчанию) или `between`.
|
|
54
|
+
Вид окна задают ручки `--rt-dialog-*` на корне страницы, перечень — на странице Theming.
|
|
55
|
+
|
|
47
56
|
**Крестик в шапке ищет `RtDialogRef` необязательным инжектом.** Поэтому `rt-dialog-header` можно
|
|
48
57
|
поставить и вне диалога — нажатие просто ничего не сделает, а не упадёт.
|
|
49
58
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@layer rt-kit.components {
|
|
2
|
+
/* rt-dialog-content — тело модалки. ViewEncapsulation.None.
|
|
3
|
+
Хост адресуется по имени элемента, как у шапки и подвала: класс блока висит и на хосте, и на
|
|
4
|
+
узле внутри. Хост боксом не становится — тело должно быть прямым flex-ребёнком рамки, чтобы
|
|
5
|
+
сжиматься между шапкой и подвалом и прокручиваться само.
|
|
6
|
+
|
|
7
|
+
Свойства читаются с запасным значением на месте: окно живёт в оверлее, вне блоков
|
|
8
|
+
приложения, и приложение задаёт их на корне страницы. */
|
|
9
|
+
rt-dialog-content {
|
|
10
|
+
display: contents;
|
|
11
|
+
|
|
12
|
+
.rt-dialog-content {
|
|
13
|
+
overflow: auto;
|
|
14
|
+
min-height: 0;
|
|
15
|
+
max-height: var(--rt-dialog-content-max-height, none);
|
|
16
|
+
flex: 1 1 auto;
|
|
17
|
+
padding: var(--rt-dialog-content-padding, var(--rt-space-lg));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -11,13 +11,29 @@
|
|
|
11
11
|
rt-dialog-footer {
|
|
12
12
|
display: contents;
|
|
13
13
|
|
|
14
|
+
/* Свойства читаются с запасным значением на месте — окно живёт в оверлее. Разделитель
|
|
15
|
+
кита лежит в частном `-default`, как у шапки. */
|
|
14
16
|
.rt-dialog-footer {
|
|
17
|
+
--rt-dialog-footer-border-default: var(--rt-border-width-thin) solid var(--rt-color-border-subtle);
|
|
18
|
+
|
|
15
19
|
display: flex;
|
|
16
20
|
justify-content: flex-end;
|
|
17
|
-
padding: var(--rt-space-lg);
|
|
18
|
-
border-block-start:
|
|
21
|
+
padding: var(--rt-dialog-footer-padding, var(--rt-space-lg));
|
|
22
|
+
border-block-start: var(--rt-dialog-footer-border, var(--rt-dialog-footer-border-default));
|
|
19
23
|
gap: var(--rt-space-sm);
|
|
20
24
|
|
|
25
|
+
&--align--start {
|
|
26
|
+
justify-content: flex-start;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&--align--center {
|
|
30
|
+
justify-content: center;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&--align--between {
|
|
34
|
+
justify-content: space-between;
|
|
35
|
+
}
|
|
36
|
+
|
|
21
37
|
&:empty {
|
|
22
38
|
display: none;
|
|
23
39
|
}
|
|
@@ -13,18 +13,36 @@
|
|
|
13
13
|
rt-dialog-header {
|
|
14
14
|
display: contents;
|
|
15
15
|
|
|
16
|
+
/* Свойства читаются с запасным значением на месте: окно живёт в оверлее, и приложение
|
|
17
|
+
задаёт их на корне страницы. Разделитель кита лежит в частном `-default` — проверка
|
|
18
|
+
токенов не пускает шаг толщины рамки запасным значением напрямую. */
|
|
16
19
|
.rt-dialog-header {
|
|
20
|
+
--rt-dialog-header-border-default: var(--rt-border-width-thin) solid var(--rt-color-border-subtle);
|
|
21
|
+
|
|
17
22
|
display: flex;
|
|
18
23
|
align-items: center;
|
|
19
24
|
justify-content: space-between;
|
|
20
|
-
padding: var(--rt-space-lg);
|
|
21
|
-
border-block-end:
|
|
25
|
+
padding: var(--rt-dialog-header-padding, var(--rt-space-lg));
|
|
26
|
+
border-block-end: var(--rt-dialog-header-border, var(--rt-dialog-header-border-default));
|
|
22
27
|
gap: var(--rt-space-sm);
|
|
23
28
|
|
|
29
|
+
/* Место перед заголовком: пустое ничего не занимает и не добавляет промежутка. */
|
|
30
|
+
&__lead {
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
flex-shrink: 0;
|
|
33
|
+
align-items: center;
|
|
34
|
+
|
|
35
|
+
&:empty {
|
|
36
|
+
display: none;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
24
40
|
&__title {
|
|
25
41
|
margin: 0;
|
|
26
42
|
color: var(--rt-color-text-primary);
|
|
27
|
-
font-size: var(--rt-text-xl);
|
|
43
|
+
font-size: var(--rt-dialog-title-font-size, var(--rt-text-xl));
|
|
44
|
+
font-weight: var(--rt-dialog-title-weight, var(--rt-font-weight-bold));
|
|
45
|
+
text-transform: var(--rt-dialog-title-transform, none);
|
|
28
46
|
}
|
|
29
47
|
|
|
30
48
|
&__close {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
@layer rt-kit.components {
|
|
4
4
|
/* rt-dialog — styled frame модалки поверх CDK Overlay.
|
|
5
5
|
ViewEncapsulation.None — селекторы префиксованы `.rt-dialog`.
|
|
6
|
-
Видимость
|
|
6
|
+
Видимость и подложку даёт CDK Overlay, ловушку и первый фокус — RtDialogService по флагам. */
|
|
7
7
|
|
|
8
8
|
/* Хост адресуется по имени элемента, а не по классу блока: класс `.rt-dialog`
|
|
9
9
|
висит и на `<rt-dialog>`, и на рамке внутри него, поэтому правила рамки
|
|
@@ -37,12 +37,18 @@
|
|
|
37
37
|
max-height: 90dvh;
|
|
38
38
|
flex-direction: column;
|
|
39
39
|
padding: 0;
|
|
40
|
-
border: none;
|
|
40
|
+
border: var(--rt-dialog-border, none);
|
|
41
41
|
border-radius: var(--rt-dialog-radius);
|
|
42
|
-
background: var(--rt-color-bg-surface);
|
|
42
|
+
background: var(--rt-dialog-bg, var(--rt-color-bg-surface));
|
|
43
43
|
box-shadow: var(--rt-dialog-shadow);
|
|
44
44
|
color: var(--rt-color-text-primary);
|
|
45
45
|
|
|
46
|
+
/* Рамку фокус берёт только по `autoFocus: 'dialog'` — как точку отсчёта для скринридера,
|
|
47
|
+
а не как элемент управления: кольцо вокруг всего окна читалось бы как выбор окна. */
|
|
48
|
+
&:focus {
|
|
49
|
+
outline: none;
|
|
50
|
+
}
|
|
51
|
+
|
|
46
52
|
&--size--sm {
|
|
47
53
|
width: var(--rt-dialog-width, var(--rt-dialog-width-sm));
|
|
48
54
|
}
|
|
@@ -35,6 +35,12 @@
|
|
|
35
35
|
- Свои кнопки у строки — `<ng-template rtDynamicSelectorRowControls let-item>`, своё название —
|
|
36
36
|
`<ng-template rtDynamicSelectorRowTitle let-item>`. Корзина и ручка перетаскивания остаются китовыми.
|
|
37
37
|
- Приглашение (`invitation`) встаёт вместо полосы кнопок; его кнопка открывает тот же выбор.
|
|
38
|
+
`listActionsShown = false` убирает сброс и очистку, оставляя кнопку добавления;
|
|
39
|
+
`removeShown = false` убирает корзину строк.
|
|
40
|
+
- Правки в своём шаблоне строки — `extraChanged`: сброс и очистка включены при прежних ключах и
|
|
41
|
+
сообщают `listReset` и `listCleared`, значение сброс тогда не трогает.
|
|
42
|
+
- Начальный запрос окна — `searchTerm`, событием поиска он не уходит. Открыто ли окно — сигнал
|
|
43
|
+
`popupOpen` и выход `popupOpenChange`.
|
|
38
44
|
|
|
39
45
|
## Рядом
|
|
40
46
|
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
|
|
27
27
|
## Края
|
|
28
28
|
|
|
29
|
-
- Кнопки действий
|
|
30
|
-
|
|
29
|
+
- Кнопки действий идут шагом `md`, 40px. Прежний инлайновый `--rt-icon-button-size: 35px` до кнопки
|
|
30
|
+
не доходил и снят: после того как кнопка-значок научилась брать размер с тега, он уменьшил бы их.
|
|
31
31
|
- Логотип рисуется вариантом `wordmark` высотой 15px; сами файлы даёт приложение
|
|
32
32
|
(см. [`rt-logo`](../logo/CONTEXT.md)).
|
|
33
33
|
|
|
@@ -4,15 +4,19 @@
|
|
|
4
4
|
<rt-icon name="check" size="md" color="current" [rotate]="null" />
|
|
5
5
|
```
|
|
6
6
|
|
|
7
|
-
| вход | тип | умолчание
|
|
8
|
-
| -------- | ----------------------------------------------------------------------------------- |
|
|
9
|
-
| `name` | `IRtIcon.Name` — литеральный union из `rt-icon-names.ts`
|
|
10
|
-
| `
|
|
11
|
-
| `
|
|
12
|
-
| `
|
|
7
|
+
| вход | тип | умолчание |
|
|
8
|
+
| -------- | ----------------------------------------------------------------------------------- | ----------- |
|
|
9
|
+
| `name` | `IRtIcon.Name \| null` — литеральный union из `rt-icon-names.ts`; побеждает `glyph` | `null` |
|
|
10
|
+
| `glyph` | `string \| null` — имя Material: пара кита или лигатура шрифта | `null` |
|
|
11
|
+
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl' \| number` — число в пикселях | `'md'` |
|
|
12
|
+
| `color` | `'current' \| 'muted' \| 'info' \| 'success' \| 'warning' \| 'danger' \| 'inverse'` | `'current'` |
|
|
13
|
+
| `rotate` | `number \| string \| null` | `null` |
|
|
14
|
+
| `fill` | `boolean` — залитый рисунок материального набора и заливка шрифта лигатуры | `false` |
|
|
15
|
+
| `spin` | `boolean` — вращение, медленнее при просьбе системы о меньшем движении | `false` |
|
|
13
16
|
|
|
14
17
|
Выходов нет. Размер и цвет едут инлайновым стилем host-а (`width`/`height`/`color`), не классом:
|
|
15
|
-
`xs` 12px, `sm` 16px, `md` 20px, `lg` 24px, `xl` 32px, `2xl` 40px
|
|
18
|
+
`xs` 12px, `sm` 16px, `md` 20px, `lg` 24px, `xl` 32px, `2xl` 40px, или число пикселей. Лигатура
|
|
19
|
+
глифа скрыта, пока шрифты страницы не готовы: её ждёт `RtIconFontService`.
|
|
16
20
|
|
|
17
21
|
## Главное, что нужно знать
|
|
18
22
|
|