tot-ui-kit 2.0.0 → 2.2.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 +86 -31
- package/dist/index.cjs +17 -9
- package/dist/index.css +196 -0
- package/dist/index.js +11 -3
- package/package.json +2 -2
- package/src/global.css +37 -0
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# tot-ui-kit
|
|
2
2
|
|
|
3
|
-
UI-библиотека с `Layout`, `ScMainMenu` и поддержкой
|
|
3
|
+
UI-библиотека с `Layout`, `ScMainMenu` и поддержкой светлой/тёмной темы для React-приложений.
|
|
4
4
|
|
|
5
|
-
> **Важно**: Библиотека использует обычный CSS (без CSS Modules). В проектах на webpack убедитесь, что подключены `css-loader` и `style-loader
|
|
5
|
+
> **Важно**: Библиотека использует обычный CSS (без CSS Modules). В проектах на webpack убедитесь, что подключены `css-loader` и `style-loader`. В Vite всё работает из коробки.
|
|
6
6
|
|
|
7
7
|
## Установка
|
|
8
8
|
|
|
@@ -12,33 +12,27 @@ npm install tot-ui-kit @sberbusiness/triplex-next @sberbusiness/icons-next
|
|
|
12
12
|
|
|
13
13
|
## ⚠️ Критически важно: Подключение CSS
|
|
14
14
|
|
|
15
|
-
**Порядок
|
|
15
|
+
**Порядок CSS импортов критичен для корректной работы тем!**
|
|
16
16
|
|
|
17
|
-
В входном файле приложения (`src/main.tsx`)
|
|
18
|
-
1. **В начале файла** (до импорта React и компонентов)
|
|
19
|
-
2. **В строго определённом порядке**
|
|
17
|
+
В входном файле приложения (`src/main.tsx`):
|
|
20
18
|
|
|
21
19
|
```tsx
|
|
22
20
|
// src/main.tsx
|
|
23
21
|
|
|
24
22
|
// 1. CSS импорты — ПЕРВЫМИ и в этом порядке!
|
|
25
|
-
import '@sberbusiness/icons-next/styles/icons.css'
|
|
26
|
-
import '@sberbusiness/triplex-next/styles/triplex-next.css'
|
|
27
|
-
import 'tot-ui-kit/global.css
|
|
28
|
-
import '
|
|
29
|
-
import './styles/index.css' // ваши локальные стили последними
|
|
23
|
+
import '@sberbusiness/icons-next/styles/icons.css' // Стили иконок
|
|
24
|
+
import '@sberbusiness/triplex-next/styles/triplex-next.css' // Triplex базовые стили
|
|
25
|
+
import 'tot-ui-kit/dist/index.css' // Стили Layout + меню + темы (включает global.css)
|
|
26
|
+
import './styles/index.css' // Ваши локальные стили — последними
|
|
30
27
|
|
|
31
28
|
// 2. Только потом React и компоненты
|
|
32
29
|
import { StrictMode } from 'react'
|
|
33
30
|
import { createRoot } from 'react-dom/client'
|
|
34
|
-
import { BrowserRouter } from 'react-router-dom'
|
|
35
31
|
import App from './App'
|
|
36
32
|
|
|
37
33
|
createRoot(document.getElementById('root')!).render(
|
|
38
34
|
<StrictMode>
|
|
39
|
-
<
|
|
40
|
-
<App />
|
|
41
|
-
</BrowserRouter>
|
|
35
|
+
<App />
|
|
42
36
|
</StrictMode>,
|
|
43
37
|
)
|
|
44
38
|
```
|
|
@@ -47,21 +41,19 @@ createRoot(document.getElementById('root')!).render(
|
|
|
47
41
|
|
|
48
42
|
| Проблема | Симптом | Решение |
|
|
49
43
|
|----------|---------|---------|
|
|
50
|
-
| Отсутствует `tot-ui-kit/dist/index.css` | Меню
|
|
51
|
-
| Неправильный порядок CSS | Стили
|
|
52
|
-
| CSS после React импортов | Стили могут не применяться | CSS импорты
|
|
44
|
+
| Отсутствует `tot-ui-kit/dist/index.css` | Меню без стилей, тема не работает | Добавить импорт |
|
|
45
|
+
| Неправильный порядок CSS | Стили перебиваются | icons → triplex → tot-ui-kit → локальные |
|
|
46
|
+
| CSS после React импортов | Стили могут не применяться | CSS импорты в самом начале файла |
|
|
53
47
|
|
|
54
48
|
## Быстрый старт
|
|
55
49
|
|
|
56
50
|
```tsx
|
|
57
51
|
import { Layout } from 'tot-ui-kit'
|
|
58
52
|
|
|
59
|
-
const API_BASE = import.meta.env.VITE_API_BASE ?? 'http://localhost:4000'
|
|
60
|
-
|
|
61
53
|
export const App = () => (
|
|
62
54
|
<Layout
|
|
63
55
|
menuProps={{
|
|
64
|
-
baseUrl:
|
|
56
|
+
baseUrl: 'http://localhost:4000',
|
|
65
57
|
menuId: '<your-menu-id>',
|
|
66
58
|
activeAppId: 'my-app',
|
|
67
59
|
systemTitle: 'Моё приложение',
|
|
@@ -72,6 +64,62 @@ export const App = () => (
|
|
|
72
64
|
)
|
|
73
65
|
```
|
|
74
66
|
|
|
67
|
+
## Темы: светлая и тёмная
|
|
68
|
+
|
|
69
|
+
### Как это работает
|
|
70
|
+
|
|
71
|
+
Layout автоматически управляет темой:
|
|
72
|
+
|
|
73
|
+
1. **Triplex ThemeProvider** — инжектит CSS-переменные для всех Triplex-компонентов (Button, TextField, Select, Tabs и т.д.)
|
|
74
|
+
2. **CSS-переменные** — дополнительные переопределения в `global.css`
|
|
75
|
+
3. **CSS-хак для иконок** — принудительное переопределение цветов SVG из `@sberbusiness/icons-next`
|
|
76
|
+
|
|
77
|
+
При смене темы Layout:
|
|
78
|
+
- Устанавливает `data-theme="light"` / `data-theme="dark"` на `<html>`
|
|
79
|
+
- Добавляет классы `triplex-theme-light` / `triplex-theme-dark`
|
|
80
|
+
- Переключает `ThemeProvider` из triplex-next
|
|
81
|
+
- Сохраняет выбор в `localStorage`
|
|
82
|
+
|
|
83
|
+
**Кнопка переключения** встроена в боковое меню (иконка солнца/луны).
|
|
84
|
+
|
|
85
|
+
### Использование в коде
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { Layout, useTheme, getCurrentTheme } from 'tot-ui-kit'
|
|
89
|
+
|
|
90
|
+
// Хук — реактивно обновляется при смене темы
|
|
91
|
+
const theme = useTheme() // 'light' | 'dark'
|
|
92
|
+
|
|
93
|
+
// Функция — получить текущую тему синхронно
|
|
94
|
+
const currentTheme = getCurrentTheme()
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Применение темы к своим компонентам
|
|
98
|
+
|
|
99
|
+
```css
|
|
100
|
+
/* Используйте CSS-переменные из Triplex */
|
|
101
|
+
.my-card {
|
|
102
|
+
background: var(--triplex-next-Card-Static_General_Background-1-14-0);
|
|
103
|
+
color: var(--triplex-next-Typography-Primary_Color-1-14-0);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Или через data-theme */
|
|
107
|
+
html[data-theme='dark'] .my-card {
|
|
108
|
+
background: #2d2d30;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Поддерживаемые компоненты
|
|
113
|
+
|
|
114
|
+
Тёмная тема работает из коробки для:
|
|
115
|
+
- Typography, Button, Tabs
|
|
116
|
+
- TextField, SelectField, Checkbox, Radio
|
|
117
|
+
- Card, Modal, Dropdown
|
|
118
|
+
- Link, Tag, Divider, Island
|
|
119
|
+
- **Иконки** из `@sberbusiness/icons-next` (крестики, шевроны и т.д.)
|
|
120
|
+
|
|
121
|
+
> Подробная документация: см. **[DARK-THEME.md](./DARK-THEME.md)**
|
|
122
|
+
|
|
75
123
|
## Основные пропсы
|
|
76
124
|
|
|
77
125
|
### Layout
|
|
@@ -81,21 +129,15 @@ export const App = () => (
|
|
|
81
129
|
| `menuProps` | Пропсы для `ScMainMenu` (кроме `theme`/`layout`) |
|
|
82
130
|
| `initialMenuLayout` | Начальное состояние меню: `'full'` или `'compact'` |
|
|
83
131
|
| `initialTheme` | Начальная тема: `'light'` или `'dark'` |
|
|
84
|
-
| `headerTitle`, `headerSubtitle` | Заголовок и подзаголовок в шапке |
|
|
85
|
-
| `upperMenuSlot`, `pageLabelSlot` | Кастомные слоты для шапки |
|
|
86
|
-
| `footerLeft`, `footerRight` | Контент футера |
|
|
87
132
|
|
|
88
133
|
### ScMainMenu
|
|
89
134
|
|
|
90
135
|
| Проп | Описание |
|
|
91
136
|
|------|----------|
|
|
92
|
-
| `baseUrl` | Базовый URL API
|
|
137
|
+
| `baseUrl` | Базовый URL API |
|
|
93
138
|
| `menuId` | ID меню для загрузки данных |
|
|
94
|
-
| `dataUrl` | Полный URL для загрузки (альтернатива `baseUrl` + `menuId`) |
|
|
95
|
-
| `apps` | Готовый список приложений (вместо загрузки) |
|
|
96
139
|
| `activeAppId` | ID активного приложения |
|
|
97
140
|
| `useMockData` | Использовать встроенные mock-данные |
|
|
98
|
-
| `iconResolver` | Кастомная функция для построения `AppDescriptor` |
|
|
99
141
|
| `onLayoutChange` | Callback при переключении layout |
|
|
100
142
|
| `onThemeChange` | Callback при переключении темы |
|
|
101
143
|
|
|
@@ -103,14 +145,27 @@ export const App = () => (
|
|
|
103
145
|
|
|
104
146
|
```json
|
|
105
147
|
{
|
|
106
|
-
"@sberbusiness/triplex-next": "^1.
|
|
107
|
-
"@sberbusiness/icons-next": "^1.
|
|
148
|
+
"@sberbusiness/triplex-next": "^1.14.0",
|
|
149
|
+
"@sberbusiness/icons-next": "^1.11.0",
|
|
108
150
|
"react": "^18.0.0",
|
|
109
151
|
"react-dom": "^18.0.0"
|
|
110
152
|
}
|
|
111
153
|
```
|
|
112
154
|
|
|
113
|
-
|
|
155
|
+
## Структура файлов (темы)
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
tot-ui-kit/
|
|
159
|
+
├── src/
|
|
160
|
+
│ ├── global.css # CSS-переменные для тёмной темы + хаки для иконок
|
|
161
|
+
│ ├── components/
|
|
162
|
+
│ │ └── Layout/
|
|
163
|
+
│ │ └── Layout.tsx # ThemeProvider + логика переключения
|
|
164
|
+
│ └── theme/
|
|
165
|
+
│ └── index.ts # useTheme, getCurrentTheme
|
|
166
|
+
├── DARK-THEME.md # Подробная документация по темам
|
|
167
|
+
└── README.md # Этот файл
|
|
168
|
+
```
|
|
114
169
|
|
|
115
170
|
## Лицензия
|
|
116
171
|
|
package/dist/index.cjs
CHANGED
|
@@ -125,6 +125,7 @@ __export(index_exports, {
|
|
|
125
125
|
module.exports = __toCommonJS(index_exports);
|
|
126
126
|
|
|
127
127
|
// src/components/Layout/Layout.tsx
|
|
128
|
+
var import_triplex_next = require("@sberbusiness/triplex-next");
|
|
128
129
|
var import_react2 = require("react");
|
|
129
130
|
|
|
130
131
|
// src/components/MainMenu/ScMainMenu.tsx
|
|
@@ -1091,6 +1092,10 @@ var Layout = ({
|
|
|
1091
1092
|
root.classList.add(
|
|
1092
1093
|
theme === "dark" ? "triplex-theme-dark" : "triplex-theme-light"
|
|
1093
1094
|
);
|
|
1095
|
+
root.classList.remove("icons-light_tptl2v", "icons-dark_7mk9a3");
|
|
1096
|
+
root.classList.add(
|
|
1097
|
+
theme === "dark" ? "icons-dark_7mk9a3" : "icons-light_tptl2v"
|
|
1098
|
+
);
|
|
1094
1099
|
try {
|
|
1095
1100
|
window.localStorage.setItem(THEME_STORAGE_KEY, theme);
|
|
1096
1101
|
} catch {
|
|
@@ -1110,9 +1115,12 @@ var Layout = ({
|
|
|
1110
1115
|
setTheme(next);
|
|
1111
1116
|
menuProps.onThemeChange?.(next);
|
|
1112
1117
|
};
|
|
1113
|
-
|
|
1118
|
+
const triplexTheme = theme === "dark" ? import_triplex_next.ETriplexNextTheme.DARK : import_triplex_next.ETriplexNextTheme.LIGHT;
|
|
1119
|
+
const scopeRef = (0, import_react2.useRef)(null);
|
|
1120
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_triplex_next.ThemeProvider, { theme: triplexTheme, scopeRef, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1114
1121
|
"div",
|
|
1115
1122
|
{
|
|
1123
|
+
ref: scopeRef,
|
|
1116
1124
|
className: appClassName,
|
|
1117
1125
|
style: {
|
|
1118
1126
|
paddingLeft: `${sidebarWidth}px`,
|
|
@@ -1134,23 +1142,23 @@ var Layout = ({
|
|
|
1134
1142
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("main", { className: styles2.main, children })
|
|
1135
1143
|
]
|
|
1136
1144
|
}
|
|
1137
|
-
);
|
|
1145
|
+
) });
|
|
1138
1146
|
};
|
|
1139
1147
|
var Layout_default = Layout;
|
|
1140
1148
|
|
|
1141
1149
|
// src/components/PageLabel/PageLabel.tsx
|
|
1142
|
-
var
|
|
1150
|
+
var import_triplex_next2 = require("@sberbusiness/triplex-next");
|
|
1143
1151
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1144
1152
|
var PageLabel = ({ title, subtitle }) => {
|
|
1145
1153
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
|
|
1146
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1147
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1154
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_triplex_next2.Text, { size: import_triplex_next2.ETextSize.B2, type: import_triplex_next2.EFontType.PRIMARY, children: title }),
|
|
1155
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_triplex_next2.Text, { size: import_triplex_next2.ETextSize.B2, type: import_triplex_next2.EFontType.SECONDARY, children: subtitle })
|
|
1148
1156
|
] });
|
|
1149
1157
|
};
|
|
1150
1158
|
var PageLabel_default = PageLabel;
|
|
1151
1159
|
|
|
1152
1160
|
// src/components/UpperMenu/UpperMenu.tsx
|
|
1153
|
-
var
|
|
1161
|
+
var import_triplex_next3 = require("@sberbusiness/triplex-next");
|
|
1154
1162
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1155
1163
|
var styles3 = {
|
|
1156
1164
|
root: "sc-upper-menu",
|
|
@@ -1165,10 +1173,10 @@ var UpperMenu = ({
|
|
|
1165
1173
|
}) => {
|
|
1166
1174
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: styles3.root, children: [
|
|
1167
1175
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: styles3.left, children: [
|
|
1168
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1169
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1176
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_triplex_next3.Text, { size: import_triplex_next3.ETextSize.B2, type: import_triplex_next3.EFontType.PRIMARY, children: title }),
|
|
1177
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_triplex_next3.Text, { size: import_triplex_next3.ETextSize.B3, type: import_triplex_next3.EFontType.SECONDARY, children: subtitle })
|
|
1170
1178
|
] }),
|
|
1171
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: styles3.right, children: rightSlot ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1179
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: styles3.right, children: rightSlot ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_triplex_next3.Text, { size: import_triplex_next3.ETextSize.B3, type: import_triplex_next3.EFontType.SECONDARY, children: "\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C" }) })
|
|
1172
1180
|
] });
|
|
1173
1181
|
};
|
|
1174
1182
|
var UpperMenu_default = UpperMenu;
|
package/dist/index.css
CHANGED
|
@@ -1,3 +1,199 @@
|
|
|
1
|
+
/* src/global.css */
|
|
2
|
+
html {
|
|
3
|
+
--triplex-next-Typography-Primary_Color-1-14-0: rgba(31, 31, 34, 1);
|
|
4
|
+
--triplex-next-Typography-Complementary_Color-1-14-0: rgba(31, 31, 34, 0.85);
|
|
5
|
+
--triplex-next-Typography-Secondary_Color-1-14-0: rgba(31, 31, 34, 0.65);
|
|
6
|
+
--triplex-next-Typography-Tertiary_Color-1-14-0: rgba(31, 31, 34, 0.55);
|
|
7
|
+
--triplex-next-Typography-Disabled_Color-1-14-0: rgba(31, 31, 34, 0.35);
|
|
8
|
+
--triplex-next-ColorNeutral-90-1-14-0: #f2f4f7;
|
|
9
|
+
--triplex-next-ColorNeutral-100-1-14-0: #ffffff;
|
|
10
|
+
background-color: var(--triplex-next-ColorNeutral-90-1-14-0, #f2f4f7);
|
|
11
|
+
}
|
|
12
|
+
html[data-theme=light] {
|
|
13
|
+
--triplex-next-Typography-Primary_Color-1-14-0: rgba(31, 31, 34, 1);
|
|
14
|
+
--triplex-next-Typography-Complementary_Color-1-14-0: rgba(31, 31, 34, 0.85);
|
|
15
|
+
--triplex-next-Typography-Secondary_Color-1-14-0: rgba(31, 31, 34, 0.65);
|
|
16
|
+
--triplex-next-Typography-Tertiary_Color-1-14-0: rgba(31, 31, 34, 0.55);
|
|
17
|
+
--triplex-next-Typography-Disabled_Color-1-14-0: rgba(31, 31, 34, 0.35);
|
|
18
|
+
--triplex-next-ColorNeutral-90-1-14-0: #f2f4f7;
|
|
19
|
+
--triplex-next-ColorNeutral-100-1-14-0: #ffffff;
|
|
20
|
+
background-color: var(--triplex-next-ColorNeutral-90-1-14-0, #f2f4f7);
|
|
21
|
+
}
|
|
22
|
+
html[data-theme=dark] {
|
|
23
|
+
--triplex-next-Typography-Primary_Color-1-14-0: rgba(255, 255, 255, 1);
|
|
24
|
+
--triplex-next-Typography-Complementary_Color-1-14-0: rgba( 255, 255, 255, 0.85 );
|
|
25
|
+
--triplex-next-Typography-Secondary_Color-1-14-0: rgba(255, 255, 255, 0.65);
|
|
26
|
+
--triplex-next-Typography-Tertiary_Color-1-14-0: rgba(255, 255, 255, 0.55);
|
|
27
|
+
--triplex-next-Typography-Disabled_Color-1-14-0: rgba(255, 255, 255, 0.35);
|
|
28
|
+
--triplex-next-ColorNeutral-90-1-14-0: #1f1f22;
|
|
29
|
+
--triplex-next-ColorNeutral-100-1-14-0: #1f1f22;
|
|
30
|
+
--triplex-next-Tabs-Type1_Background-1-14-0: rgba(255, 255, 255, 0.08);
|
|
31
|
+
--triplex-next-Tabs-Type2_Background-1-14-0: rgba(255, 255, 255, 0.05);
|
|
32
|
+
--triplex-next-Tabs-Type1_Tab_Background_Default-1-14-0: transparent;
|
|
33
|
+
--triplex-next-Tabs-Type2_Tab_Background_Default-1-14-0: transparent;
|
|
34
|
+
--triplex-next-Tabs-Type1_Tab_Background_Selected-1-14-0: rgba(255, 255, 255, 0.15);
|
|
35
|
+
--triplex-next-Tabs-Type2_Tab_Background_Selected-1-14-0: rgba(255, 255, 255, 0.12);
|
|
36
|
+
--triplex-next-Tabs-Type1_Tab_Background_Hover-1-14-0: rgba(255, 255, 255, 0.1);
|
|
37
|
+
--triplex-next-Tabs-Type2_Tab_Background_Hover-1-14-0: rgba(255, 255, 255, 0.08);
|
|
38
|
+
--triplex-next-Tabs-Type1_Tab_Color_Default-1-14-0: rgba(255, 255, 255, 0.65);
|
|
39
|
+
--triplex-next-Tabs-Type2_Tab_Color_Default-1-14-0: rgba(255, 255, 255, 0.65);
|
|
40
|
+
--triplex-next-Tabs-Type1_Tab_Color_Selected-1-14-0: rgba(255, 255, 255, 1);
|
|
41
|
+
--triplex-next-Tabs-Type2_Tab_Color_Selected-1-14-0: rgba(255, 255, 255, 1);
|
|
42
|
+
--triplex-next-Tabs-Type1_Tab_Color_Hover-1-14-0: rgba(255, 255, 255, 1);
|
|
43
|
+
--triplex-next-Tabs-Type2_Tab_Color_Hover-1-14-0: rgba(255, 255, 255, 1);
|
|
44
|
+
--triplex-next-Button-Secondary_Background_Default-1-14-0: rgba(255, 255, 255, 0.08);
|
|
45
|
+
--triplex-next-Button-Secondary_Background_Hover-1-14-0: rgba(255, 255, 255, 0.12);
|
|
46
|
+
--triplex-next-Button-Secondary_Background_Active-1-14-0: rgba(255, 255, 255, 0.15);
|
|
47
|
+
--triplex-next-Button-Secondary_Background_Disabled-1-14-0: rgba(255, 255, 255, 0.05);
|
|
48
|
+
--triplex-next-Button-Secondary_Color_Default-1-14-0: #21A19A;
|
|
49
|
+
--triplex-next-Button-Secondary_Color_Hover-1-14-0: #19BDB0;
|
|
50
|
+
--triplex-next-Button-Secondary_Color_Active-1-14-0: #007777;
|
|
51
|
+
--triplex-next-Button-Secondary_Color_Disabled-1-14-0: rgba(255, 255, 255, 0.35);
|
|
52
|
+
--triplex-next-Button-SecondaryLight_Background_Default-1-14-0: rgba(255, 255, 255, 0.1);
|
|
53
|
+
--triplex-next-Button-SecondaryLight_Background_Hover-1-14-0: rgba(255, 255, 255, 0.15);
|
|
54
|
+
--triplex-next-Button-SecondaryLight_Background_Active-1-14-0: rgba(255, 255, 255, 0.18);
|
|
55
|
+
--triplex-next-Button-SecondaryLight_Background_Disabled-1-14-0: rgba(255, 255, 255, 0.05);
|
|
56
|
+
--triplex-next-Button-SecondaryLight_Color_Default-1-14-0: #21A19A;
|
|
57
|
+
--triplex-next-Button-SecondaryLight_Color_Hover-1-14-0: #19BDB0;
|
|
58
|
+
--triplex-next-Button-SecondaryLight_Color_Active-1-14-0: #007777;
|
|
59
|
+
--triplex-next-Button-SecondaryLight_Color_Disabled-1-14-0: rgba(255, 255, 255, 0.35);
|
|
60
|
+
--triplex-next-Button-General_Background_Disabled-1-14-0: rgba(255, 255, 255, 0.08);
|
|
61
|
+
--triplex-next-Button-General_Color_Disabled-1-14-0: rgba(255, 255, 255, 0.35);
|
|
62
|
+
--triplex-next-Button-Danger_Background_Disabled-1-14-0: rgba(255, 255, 255, 0.08);
|
|
63
|
+
--triplex-next-Button-Danger_Color_Disabled-1-14-0: rgba(255, 255, 255, 0.35);
|
|
64
|
+
--triplex-next-Button-Link_Color_Default-1-14-0: #19BDB0;
|
|
65
|
+
--triplex-next-Button-Link_Color_Hover-1-14-0: #4BD9CF;
|
|
66
|
+
--triplex-next-Button-Link_Color_Active-1-14-0: #008985;
|
|
67
|
+
--triplex-next-Button-Link_Color_Disabled-1-14-0: rgba(255, 255, 255, 0.35);
|
|
68
|
+
--triplex-next-FormField-Background_Default-1-14-0: rgba(255, 255, 255, 0.08);
|
|
69
|
+
--triplex-next-FormField-Background_Hover-1-14-0: rgba(255, 255, 255, 0.12);
|
|
70
|
+
--triplex-next-FormField-Background_Active-1-14-0: rgba(255, 255, 255, 0.08);
|
|
71
|
+
--triplex-next-FormField-Background_Disabled-1-14-0: rgba(255, 255, 255, 0.05);
|
|
72
|
+
--triplex-next-FormField-Background_Error-1-14-0: rgba(230, 0, 55, 0.15);
|
|
73
|
+
--triplex-next-FormField-Background_Error_Hover-1-14-0: rgba(230, 0, 55, 0.2);
|
|
74
|
+
--triplex-next-FormField-Background_Warning-1-14-0: rgba(253, 101, 8, 0.15);
|
|
75
|
+
--triplex-next-FormField-Background_Warning_Hover-1-14-0: rgba(253, 101, 8, 0.2);
|
|
76
|
+
--triplex-next-FormField-Input_Color_Default-1-14-0: rgba(255, 255, 255, 1);
|
|
77
|
+
--triplex-next-FormField-Input_Color_Disabled-1-14-0: rgba(255, 255, 255, 0.35);
|
|
78
|
+
--triplex-next-FormField-Target_Color_Default-1-14-0: rgba(255, 255, 255, 1);
|
|
79
|
+
--triplex-next-FormField-Target_Color_Disabled-1-14-0: rgba(255, 255, 255, 0.45);
|
|
80
|
+
--triplex-next-FormField-Target_PlaceholderColor_Default-1-14-0: rgba(255, 255, 255, 0.65);
|
|
81
|
+
--triplex-next-FormField-Label_Color_Default-1-14-0: rgba(255, 255, 255, 0.65);
|
|
82
|
+
--triplex-next-FormField-Label_Color_Disabled-1-14-0: rgba(255, 255, 255, 0.35);
|
|
83
|
+
--triplex-next-FormField-Placeholder_Color-1-14-0: rgba(255, 255, 255, 0.65);
|
|
84
|
+
--triplex-next-SmallInput-Background-1-14-0: rgba(255, 255, 255, 0.08);
|
|
85
|
+
--triplex-next-SmallInput-Color-1-14-0: rgba(255, 255, 255, 1);
|
|
86
|
+
--triplex-next-SmallInput-PlaceholderColor-1-14-0: rgba(255, 255, 255, 0.65);
|
|
87
|
+
--triplex-next-Dropdown-Background-1-14-0: #2a2d31;
|
|
88
|
+
--triplex-next-Dropdown-Shadow-1-14-0: 0px 2px 12px rgba(0, 0, 0, 0.4);
|
|
89
|
+
--triplex-next-DropdownList-Background_Default-1-14-0: transparent;
|
|
90
|
+
--triplex-next-DropdownList-Background_Active-1-14-0: rgba(255, 255, 255, 0.1);
|
|
91
|
+
--triplex-next-DropdownList-Background_Selected-1-14-0: rgba(255, 255, 255, 0.15);
|
|
92
|
+
--triplex-next-DropdownList-Color-1-14-0: rgba(255, 255, 255, 1);
|
|
93
|
+
--triplex-next-Checkbox-Background_Default-1-14-0: rgba(255, 255, 255, 0.08);
|
|
94
|
+
--triplex-next-Checkbox-Background_Disabled-1-14-0: rgba(255, 255, 255, 0.05);
|
|
95
|
+
--triplex-next-Checkbox-Background_Checked_Disabled-1-14-0: rgba(255, 255, 255, 0.1);
|
|
96
|
+
--triplex-next-Checkbox-BorderColor_Default-1-14-0: 0 0 0 1px rgba(255, 255, 255, 0.25) inset;
|
|
97
|
+
--triplex-next-Checkbox-BorderColor_Disabled-1-14-0: 0 0 0 1px rgba(255, 255, 255, 0.1) inset;
|
|
98
|
+
--triplex-next-Checkbox-Checkmark_Fill_Disabled-1-14-0: rgba(255, 255, 255, 0.35);
|
|
99
|
+
--triplex-next-Radio-Background_Default-1-14-0: rgba(255, 255, 255, 0.08);
|
|
100
|
+
--triplex-next-Radio-Background_Disabled-1-14-0: rgba(255, 255, 255, 0.05);
|
|
101
|
+
--triplex-next-Radio-Background_Checked_Disabled-1-14-0: rgba(255, 255, 255, 0.1);
|
|
102
|
+
--triplex-next-Radio-BorderColor_Default-1-14-0: 0 0 0 1px rgba(255, 255, 255, 0.25) inset;
|
|
103
|
+
--triplex-next-Radio-BorderColor_Disabled-1-14-0: 0 0 0 1px rgba(255, 255, 255, 0.1) inset;
|
|
104
|
+
--triplex-next-Radio-Dot_Disabled-1-14-0: rgba(255, 255, 255, 0.35);
|
|
105
|
+
--triplex-next-Card-Static_General_Background-1-14-0: rgba(255, 255, 255, 0.08);
|
|
106
|
+
--triplex-next-Card-Static_Secondary_Background-1-14-0: rgba(255, 255, 255, 0.05);
|
|
107
|
+
--triplex-next-Card-Action_General_Background-1-14-0: rgba(255, 255, 255, 0.08);
|
|
108
|
+
--triplex-next-Card-Action_General_Background_Hover-1-14-0: rgba(255, 255, 255, 0.1);
|
|
109
|
+
--triplex-next-Card-Action_General_Background_Selected-1-14-0: rgba(255, 255, 255, 0.12);
|
|
110
|
+
--triplex-next-Card-Action_General_Background_Selected_Hover-1-14-0: rgba(255, 255, 255, 0.15);
|
|
111
|
+
--triplex-next-Card-Action_Secondary_Background-1-14-0: rgba(255, 255, 255, 0.05);
|
|
112
|
+
--triplex-next-Card-Action_Secondary_Background_Hover-1-14-0: rgba(255, 255, 255, 0.08);
|
|
113
|
+
--triplex-next-Card-Action_Secondary_Background_Selected-1-14-0: rgba(255, 255, 255, 0.1);
|
|
114
|
+
--triplex-next-Card-Action_Secondary_Background_Selected_Hover-1-14-0: rgba(255, 255, 255, 0.12);
|
|
115
|
+
--triplex-next-Card-Shadow_Default-1-14-0: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
|
|
116
|
+
--triplex-next-Card-Shadow_Hover-1-14-0: 0 4px 16px 0 rgba(0, 0, 0, 0.4);
|
|
117
|
+
--triplex-next-ModalWindow-Background-1-14-0: #2a2d31;
|
|
118
|
+
--triplex-next-ModalWindow-Backdrop_Background-1-14-0: rgba(0, 0, 0, 0.6);
|
|
119
|
+
--triplex-next-Island-Type1_Background-1-14-0: rgba(255, 255, 255, 0.08);
|
|
120
|
+
--triplex-next-Island-Type2_Background-1-14-0: rgba(255, 255, 255, 0.05);
|
|
121
|
+
--triplex-next-Island-Type3_Background-1-14-0: rgba(255, 255, 255, 0.03);
|
|
122
|
+
--triplex-next-Island-Type2_Shadow-1-14-0: 0 0 0 1px rgba(255, 255, 255, 0.1) inset;
|
|
123
|
+
--triplex-next-ListItem-Background-1-14-0: rgba(255, 255, 255, 0.08);
|
|
124
|
+
--triplex-next-ListItem-Background_Dragging-1-14-0: rgba(255, 255, 255, 0.12);
|
|
125
|
+
--triplex-next-ListItem-Background_Selected-1-14-0: rgba(255, 255, 255, 0.15);
|
|
126
|
+
--triplex-next-ListItem-Shadow-1-14-0: 0 2px 8px rgba(0, 0, 0, 0.4);
|
|
127
|
+
--triplex-next-ListItemControlsButton-Background_Default-1-14-0: transparent;
|
|
128
|
+
--triplex-next-ListItemControlsButton-Background_Hover-1-14-0: rgba(255, 255, 255, 0.1);
|
|
129
|
+
--triplex-next-ListItemControlsButton-Background_Active-1-14-0: rgba(255, 255, 255, 0.15);
|
|
130
|
+
--triplex-next-ListItemControlsButton-Color_Default-1-14-0: rgba(255, 255, 255, 0.65);
|
|
131
|
+
--triplex-next-ListItemControlsButton-Color_Hover-1-14-0: rgba(255, 255, 255, 0.85);
|
|
132
|
+
--triplex-next-ListItemControlsButton-Color_Active-1-14-0: rgba(255, 255, 255, 1);
|
|
133
|
+
--triplex-next-Divider-Background-1-14-0: rgba(255, 255, 255, 0.12);
|
|
134
|
+
--triplex-next-Link-Text_Color_Default-1-14-0: #19BDB0;
|
|
135
|
+
--triplex-next-Link-Text_Color_Hover-1-14-0: #4BD9CF;
|
|
136
|
+
--triplex-next-Link-Text_Color_Active-1-14-0: #008985;
|
|
137
|
+
--triplex-next-Tag-Background-1-14-0: rgba(255, 255, 255, 0.12);
|
|
138
|
+
--triplex-next-MultiselectField-Divider_Color-1-14-0: rgba(255, 255, 255, 0.2);
|
|
139
|
+
background-color: var(--triplex-next-ColorNeutral-90-1-14-0, #1f1f22);
|
|
140
|
+
}
|
|
141
|
+
*,
|
|
142
|
+
*::before,
|
|
143
|
+
*::after {
|
|
144
|
+
box-sizing: border-box;
|
|
145
|
+
}
|
|
146
|
+
html,
|
|
147
|
+
body {
|
|
148
|
+
margin: 0;
|
|
149
|
+
padding: 0;
|
|
150
|
+
min-height: 100%;
|
|
151
|
+
}
|
|
152
|
+
body {
|
|
153
|
+
font-family:
|
|
154
|
+
system-ui,
|
|
155
|
+
-apple-system,
|
|
156
|
+
BlinkMacSystemFont,
|
|
157
|
+
"Segoe UI",
|
|
158
|
+
sans-serif;
|
|
159
|
+
line-height: 1.5;
|
|
160
|
+
background-color: inherit;
|
|
161
|
+
color: rgb(46, 52, 56);
|
|
162
|
+
background: rgb(246, 249, 252);
|
|
163
|
+
}
|
|
164
|
+
html[data-theme=dark] body {
|
|
165
|
+
color: rgb(201, 205, 207);
|
|
166
|
+
background: rgb(34, 36, 37);
|
|
167
|
+
}
|
|
168
|
+
#root {
|
|
169
|
+
min-height: 100vh;
|
|
170
|
+
}
|
|
171
|
+
a {
|
|
172
|
+
color: inherit;
|
|
173
|
+
text-decoration: none;
|
|
174
|
+
}
|
|
175
|
+
button {
|
|
176
|
+
font-family: inherit;
|
|
177
|
+
}
|
|
178
|
+
html[data-theme=dark] ._505n0h {
|
|
179
|
+
fill: #FFFFFF !important;
|
|
180
|
+
fill-opacity: 0.35 !important;
|
|
181
|
+
}
|
|
182
|
+
html[data-theme=dark] .hoverable:hover ._505n0h {
|
|
183
|
+
fill: #FFFFFF !important;
|
|
184
|
+
fill-opacity: 1 !important;
|
|
185
|
+
}
|
|
186
|
+
html[data-theme=dark] .hoverable:not(:disabled):active ._505n0h,
|
|
187
|
+
html[data-theme=dark] .hoverable.active ._505n0h {
|
|
188
|
+
fill: #FFFFFF !important;
|
|
189
|
+
fill-opacity: 1 !important;
|
|
190
|
+
}
|
|
191
|
+
html[data-theme=dark] .hoverable:disabled ._505n0h,
|
|
192
|
+
html[data-theme=dark] .hoverable.disabled ._505n0h {
|
|
193
|
+
fill: #FFFFFF !important;
|
|
194
|
+
fill-opacity: 0.15 !important;
|
|
195
|
+
}
|
|
196
|
+
|
|
1
197
|
/* src/components/Layout/styles.css */
|
|
2
198
|
.sc-layout {
|
|
3
199
|
height: 100vh;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/components/Layout/Layout.tsx
|
|
2
|
-
import {
|
|
2
|
+
import { ThemeProvider, ETriplexNextTheme } from "@sberbusiness/triplex-next";
|
|
3
|
+
import { useEffect as useEffect2, useRef, useState as useState2 } from "react";
|
|
3
4
|
|
|
4
5
|
// src/components/MainMenu/ScMainMenu.tsx
|
|
5
6
|
import { useEffect, useState } from "react";
|
|
@@ -965,6 +966,10 @@ var Layout = ({
|
|
|
965
966
|
root.classList.add(
|
|
966
967
|
theme === "dark" ? "triplex-theme-dark" : "triplex-theme-light"
|
|
967
968
|
);
|
|
969
|
+
root.classList.remove("icons-light_tptl2v", "icons-dark_7mk9a3");
|
|
970
|
+
root.classList.add(
|
|
971
|
+
theme === "dark" ? "icons-dark_7mk9a3" : "icons-light_tptl2v"
|
|
972
|
+
);
|
|
968
973
|
try {
|
|
969
974
|
window.localStorage.setItem(THEME_STORAGE_KEY, theme);
|
|
970
975
|
} catch {
|
|
@@ -984,9 +989,12 @@ var Layout = ({
|
|
|
984
989
|
setTheme(next);
|
|
985
990
|
menuProps.onThemeChange?.(next);
|
|
986
991
|
};
|
|
987
|
-
|
|
992
|
+
const triplexTheme = theme === "dark" ? ETriplexNextTheme.DARK : ETriplexNextTheme.LIGHT;
|
|
993
|
+
const scopeRef = useRef(null);
|
|
994
|
+
return /* @__PURE__ */ jsx5(ThemeProvider, { theme: triplexTheme, scopeRef, children: /* @__PURE__ */ jsxs3(
|
|
988
995
|
"div",
|
|
989
996
|
{
|
|
997
|
+
ref: scopeRef,
|
|
990
998
|
className: appClassName,
|
|
991
999
|
style: {
|
|
992
1000
|
paddingLeft: `${sidebarWidth}px`,
|
|
@@ -1008,7 +1016,7 @@ var Layout = ({
|
|
|
1008
1016
|
/* @__PURE__ */ jsx5("main", { className: styles2.main, children })
|
|
1009
1017
|
]
|
|
1010
1018
|
}
|
|
1011
|
-
);
|
|
1019
|
+
) });
|
|
1012
1020
|
};
|
|
1013
1021
|
var Layout_default = Layout;
|
|
1014
1022
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tot-ui-kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "UI Kit with Layout, MainMenu, and theme support for React applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"lint:fix": "eslint . --fix",
|
|
28
28
|
"typecheck": "tsc --noEmit",
|
|
29
29
|
"prepublishOnly": "npm run build",
|
|
30
|
-
"
|
|
30
|
+
"send": "npm publish --access public"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
|
33
33
|
"react",
|
package/src/global.css
CHANGED
|
@@ -163,6 +163,14 @@ html[data-theme='dark'] {
|
|
|
163
163
|
--triplex-next-ListItem-Background_Selected-1-14-0: rgba(255, 255, 255, 0.15);
|
|
164
164
|
--triplex-next-ListItem-Shadow-1-14-0: 0 2px 8px rgba(0, 0, 0, 0.4);
|
|
165
165
|
|
|
166
|
+
/* ===== ListItemControlsButton (иконки: крестик очистки, шеврон и т.д.) ===== */
|
|
167
|
+
--triplex-next-ListItemControlsButton-Background_Default-1-14-0: transparent;
|
|
168
|
+
--triplex-next-ListItemControlsButton-Background_Hover-1-14-0: rgba(255, 255, 255, 0.1);
|
|
169
|
+
--triplex-next-ListItemControlsButton-Background_Active-1-14-0: rgba(255, 255, 255, 0.15);
|
|
170
|
+
--triplex-next-ListItemControlsButton-Color_Default-1-14-0: rgba(255, 255, 255, 0.65);
|
|
171
|
+
--triplex-next-ListItemControlsButton-Color_Hover-1-14-0: rgba(255, 255, 255, 0.85);
|
|
172
|
+
--triplex-next-ListItemControlsButton-Color_Active-1-14-0: rgba(255, 255, 255, 1);
|
|
173
|
+
|
|
166
174
|
/* ===== Divider ===== */
|
|
167
175
|
--triplex-next-Divider-Background-1-14-0: rgba(255, 255, 255, 0.12);
|
|
168
176
|
|
|
@@ -174,6 +182,9 @@ html[data-theme='dark'] {
|
|
|
174
182
|
/* ===== Tag ===== */
|
|
175
183
|
--triplex-next-Tag-Background-1-14-0: rgba(255, 255, 255, 0.12);
|
|
176
184
|
|
|
185
|
+
/* ===== MultiselectField ===== */
|
|
186
|
+
--triplex-next-MultiselectField-Divider_Color-1-14-0: rgba(255, 255, 255, 0.2);
|
|
187
|
+
|
|
177
188
|
background-color: var(--triplex-next-ColorNeutral-90-1-14-0, #1f1f22);
|
|
178
189
|
}
|
|
179
190
|
|
|
@@ -218,3 +229,29 @@ a {
|
|
|
218
229
|
button {
|
|
219
230
|
font-family: inherit;
|
|
220
231
|
}
|
|
232
|
+
|
|
233
|
+
/* ===== Icons-next: переопределение цветов иконок для тёмной темы ===== */
|
|
234
|
+
/* Иконки из @sberbusiness/icons-next используют класс _505n0h для светлой темы (тёмная заливка)
|
|
235
|
+
и _1h7ffvx для тёмной темы (белая заливка). Поскольку Context не работает между
|
|
236
|
+
библиотекой и проектом (разные копии React), принудительно меняем цвета через CSS */
|
|
237
|
+
html[data-theme='dark'] ._505n0h {
|
|
238
|
+
fill: #FFFFFF !important;
|
|
239
|
+
fill-opacity: 0.35 !important;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
html[data-theme='dark'] .hoverable:hover ._505n0h {
|
|
243
|
+
fill: #FFFFFF !important;
|
|
244
|
+
fill-opacity: 1 !important;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
html[data-theme='dark'] .hoverable:not(:disabled):active ._505n0h,
|
|
248
|
+
html[data-theme='dark'] .hoverable.active ._505n0h {
|
|
249
|
+
fill: #FFFFFF !important;
|
|
250
|
+
fill-opacity: 1 !important;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
html[data-theme='dark'] .hoverable:disabled ._505n0h,
|
|
254
|
+
html[data-theme='dark'] .hoverable.disabled ._505n0h {
|
|
255
|
+
fill: #FFFFFF !important;
|
|
256
|
+
fill-opacity: 0.15 !important;
|
|
257
|
+
}
|