urfu-ui-kit-vanilla 2.3.1 → 2.3.2

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 (3) hide show
  1. package/main.js +419 -357
  2. package/package.json +2 -1
  3. package/src/ui-icons.css +426 -0
package/main.js CHANGED
@@ -1,357 +1,419 @@
1
- // UrFU UI-Kit Vanilla - Основной файл
2
- // Автоматически подключает CSS и добавляет поддержку динамических утилит
3
- //
4
- // Использование в HTML:
5
- // <script src="node_modules/urfu-ui-kit-vanilla/main.js"></script>
6
- //
7
- // Использование в TypeScript/JavaScript:
8
- // import 'urfu-ui-kit-vanilla/main.js';
9
- // или
10
- // require('urfu-ui-kit-vanilla/main.js');
11
-
12
- (function() {
13
- 'use strict';
14
-
15
- // Автоматически подключаем CSS
16
- function loadCSS() {
17
- // Определяем путь к CSS относительно текущего скрипта
18
- const currentScript = document.currentScript;
19
- let cssPath = 'node_modules/urfu-ui-kit-vanilla/src/main.css';
20
-
21
- if (currentScript) {
22
- const scriptPath = currentScript.src;
23
- const scriptDir = scriptPath.substring(0, scriptPath.lastIndexOf('/'));
24
- cssPath = scriptDir + '/src/main.css';
25
- }
26
-
27
- const link = document.createElement('link');
28
- link.rel = 'stylesheet';
29
- link.href = cssPath;
30
- link.id = 'urfu-ui-kit-css';
31
-
32
- // Проверяем, не подключен ли уже CSS
33
- if (!document.getElementById('urfu-ui-kit-css')) {
34
- document.head.appendChild(link);
35
- }
36
- }
37
-
38
- // Подключаем CSS при загрузке
39
- if (document.readyState === 'loading') {
40
- document.addEventListener('DOMContentLoaded', loadCSS);
41
- } else {
42
- loadCSS();
43
- }
44
-
45
- // Кэш для уже созданных стилей
46
- const styleCache = new Set();
47
-
48
- // Функция для создания CSS-правила
49
- function createStyle(selector, property, value) {
50
- const rule = `${selector} { ${property}: ${value}; }`;
51
- if (styleCache.has(rule)) return;
52
-
53
- styleCache.add(rule);
54
-
55
- // Создаем или находим элемент style
56
- let styleElement = document.getElementById('dynamic-utils-styles');
57
- if (!styleElement) {
58
- styleElement = document.createElement('style');
59
- styleElement.id = 'dynamic-utils-styles';
60
- document.head.appendChild(styleElement);
61
- }
62
-
63
- // Добавляем правило
64
- styleElement.textContent += rule + '\n';
65
- }
66
-
67
- // Функция для парсинга классов и создания стилей
68
- function processElement(element) {
69
- const classList = Array.from(element.classList);
70
-
71
- classList.forEach(className => {
72
- // Проверяем паттерны для margin
73
- const marginMatch = className.match(/^um([lrtb]?)(\d+)$/);
74
- if (marginMatch) {
75
- const [, direction, value] = marginMatch;
76
- const pxValue = value + 'px';
77
-
78
- switch (direction) {
79
- case 'l':
80
- createStyle(`.${className}`, 'margin-left', pxValue);
81
- break;
82
- case 'r':
83
- createStyle(`.${className}`, 'margin-right', pxValue);
84
- break;
85
- case 't':
86
- createStyle(`.${className}`, 'margin-top', pxValue);
87
- break;
88
- case 'b':
89
- createStyle(`.${className}`, 'margin-bottom', pxValue);
90
- break;
91
- default:
92
- createStyle(`.${className}`, 'margin', pxValue);
93
- break;
94
- }
95
- }
96
-
97
- // Проверяем паттерны для padding
98
- const paddingMatch = className.match(/^up([lrtb]?)(\d+)$/);
99
- if (paddingMatch) {
100
- const [, direction, value] = paddingMatch;
101
- const pxValue = value + 'px';
102
-
103
- switch (direction) {
104
- case 'l':
105
- createStyle(`.${className}`, 'padding-left', pxValue);
106
- break;
107
- case 'r':
108
- createStyle(`.${className}`, 'padding-right', pxValue);
109
- break;
110
- case 't':
111
- createStyle(`.${className}`, 'padding-top', pxValue);
112
- break;
113
- case 'b':
114
- createStyle(`.${className}`, 'padding-bottom', pxValue);
115
- break;
116
- default:
117
- createStyle(`.${className}`, 'padding', pxValue);
118
- break;
119
- }
120
- }
121
-
122
- // Проверяем паттерны для width/height
123
- const sizeMatch = className.match(/^u([wh])(\d+)$/);
124
- if (sizeMatch) {
125
- const [, property, value] = sizeMatch;
126
- const pxValue = value + 'px';
127
-
128
- if (property === 'w') {
129
- createStyle(`.${className}`, 'width', pxValue);
130
- } else if (property === 'h') {
131
- createStyle(`.${className}`, 'height', pxValue);
132
- }
133
- }
134
-
135
- // Проверяем паттерны для font-size
136
- const fontSizeMatch = className.match(/^ufos(\d+)$/);
137
- if (fontSizeMatch) {
138
- const [, value] = fontSizeMatch;
139
- const pxValue = value + 'px';
140
- createStyle(`.${className}`, 'font-size', pxValue);
141
- }
142
-
143
- // Проверяем паттерны для gap
144
- const gapMatch = className.match(/^ug(\d+)$/);
145
- if (gapMatch) {
146
- const [, value] = gapMatch;
147
- const pxValue = value + 'px';
148
- createStyle(`.${className}`, 'gap', pxValue);
149
- }
150
-
151
- // Проверяем паттерны для column-gap
152
- const columnGapMatch = className.match(/^ucg(\d+)$/);
153
- if (columnGapMatch) {
154
- const [, value] = columnGapMatch;
155
- const pxValue = value + 'px';
156
- createStyle(`.${className}`, 'column-gap', pxValue);
157
- }
158
-
159
- // Проверяем паттерны для row-gap
160
- const rowGapMatch = className.match(/^urg(\d+)$/);
161
- if (rowGapMatch) {
162
- const [, value] = rowGapMatch;
163
- const pxValue = value + 'px';
164
- createStyle(`.${className}`, 'row-gap', pxValue);
165
- }
166
-
167
- // Проверяем паттерны для min-width
168
- const minWidthMatch = className.match(/^umnw(\d+)$/);
169
- if (minWidthMatch) {
170
- const [, value] = minWidthMatch;
171
- const pxValue = value + 'px';
172
- createStyle(`.${className}`, 'min-width', pxValue);
173
- }
174
-
175
- // Проверяем паттерны для min-height
176
- const minHeightMatch = className.match(/^umnh(\d+)$/);
177
- if (minHeightMatch) {
178
- const [, value] = minHeightMatch;
179
- const pxValue = value + 'px';
180
- createStyle(`.${className}`, 'min-height', pxValue);
181
- }
182
-
183
- // Проверяем паттерны для max-width
184
- const maxWidthMatch = className.match(/^umxw(\d+)$/);
185
- if (maxWidthMatch) {
186
- const [, value] = maxWidthMatch;
187
- const pxValue = value + 'px';
188
- createStyle(`.${className}`, 'max-width', pxValue);
189
- }
190
-
191
- // Проверяем паттерны для max-height
192
- const maxHeightMatch = className.match(/^umxh(\d+)$/);
193
- if (maxHeightMatch) {
194
- const [, value] = maxHeightMatch;
195
- const pxValue = value + 'px';
196
- createStyle(`.${className}`, 'max-height', pxValue);
197
- }
198
-
199
- // Проверяем паттерны для line-height
200
- const lineHeightMatch = className.match(/^ulh(\d+)$/);
201
- if (lineHeightMatch) {
202
- const [, value] = lineHeightMatch;
203
- const pxValue = value + 'px';
204
- createStyle(`.${className}`, 'line-height', pxValue);
205
- }
206
-
207
- // Проверяем паттерны для border-width
208
- const borderWidthMatch = className.match(/^ub(\d+)$/);
209
- if (borderWidthMatch) {
210
- const [, value] = borderWidthMatch;
211
- const pxValue = value + 'px';
212
- createStyle(`.${className}`, 'border-width', pxValue);
213
- createStyle(`.${className}`, 'border-style', 'solid');
214
- }
215
-
216
- // Проверяем паттерны для border-radius
217
- const borderRadiusMatch = className.match(/^ubr(\d+)$/);
218
- if (borderRadiusMatch) {
219
- const [, value] = borderRadiusMatch;
220
- const pxValue = value + 'px';
221
- createStyle(`.${className}`, 'border-radius', pxValue);
222
- }
223
-
224
- // Проверяем паттерны для opacity
225
- const opacityMatch = className.match(/^uop(\d+)$/);
226
- if (opacityMatch) {
227
- const [, value] = opacityMatch;
228
- const opacityValue = (parseInt(value) / 100).toString();
229
- createStyle(`.${className}`, 'opacity', opacityValue);
230
- }
231
-
232
- // Проверяем паттерны для z-index
233
- const zIndexMatch = className.match(/^uzi(\d+)$/);
234
- if (zIndexMatch) {
235
- const [, value] = zIndexMatch;
236
- createStyle(`.${className}`, 'z-index', value);
237
- }
238
-
239
- // Проверяем паттерны для top
240
- const topMatch = className.match(/^utop(\d+)$/);
241
- if (topMatch) {
242
- const [, value] = topMatch;
243
- const pxValue = value + 'px';
244
- createStyle(`.${className}`, 'top', pxValue);
245
- }
246
-
247
- // Проверяем паттерны для right
248
- const rightMatch = className.match(/^uright(\d+)$/);
249
- if (rightMatch) {
250
- const [, value] = rightMatch;
251
- const pxValue = value + 'px';
252
- createStyle(`.${className}`, 'right', pxValue);
253
- }
254
-
255
- // Проверяем паттерны для bottom
256
- const bottomMatch = className.match(/^ubottom(\d+)$/);
257
- if (bottomMatch) {
258
- const [, value] = bottomMatch;
259
- const pxValue = value + 'px';
260
- createStyle(`.${className}`, 'bottom', pxValue);
261
- }
262
-
263
- // Проверяем паттерны для left
264
- const leftMatch = className.match(/^uleft(\d+)$/);
265
- if (leftMatch) {
266
- const [, value] = leftMatch;
267
- const pxValue = value + 'px';
268
- createStyle(`.${className}`, 'left', pxValue);
269
- }
270
-
271
- // Проверяем паттерны для flex-grow
272
- const flexGrowMatch = className.match(/^ufg(\d+)$/);
273
- if (flexGrowMatch) {
274
- const [, value] = flexGrowMatch;
275
- createStyle(`.${className}`, 'flex-grow', value);
276
- }
277
-
278
- // Проверяем паттерны для flex-shrink
279
- const flexShrinkMatch = className.match(/^ufs(\d+)$/);
280
- if (flexShrinkMatch) {
281
- const [, value] = flexShrinkMatch;
282
- createStyle(`.${className}`, 'flex-shrink', value);
283
- }
284
-
285
- // Проверяем паттерны для flex-basis
286
- const flexBasisMatch = className.match(/^ufb(\d+)$/);
287
- if (flexBasisMatch) {
288
- const [, value] = flexBasisMatch;
289
- const pxValue = value + 'px';
290
- createStyle(`.${className}`, 'flex-basis', pxValue);
291
- }
292
-
293
- // Проверяем паттерны для order
294
- const orderMatch = className.match(/^uo(\d+)$/);
295
- if (orderMatch) {
296
- const [, value] = orderMatch;
297
- createStyle(`.${className}`, 'order', value);
298
- }
299
-
300
- // Проверяем паттерны для grid-template-columns
301
- const gridColsMatch = className.match(/^ugtc(\d+)$/);
302
- if (gridColsMatch) {
303
- const [, value] = gridColsMatch;
304
- const gridValue = `repeat(${value}, 1fr)`;
305
- createStyle(`.${className}`, 'grid-template-columns', gridValue);
306
- }
307
-
308
- // Проверяем паттерны для grid-template-rows
309
- const gridRowsMatch = className.match(/^ugtr(\d+)$/);
310
- if (gridRowsMatch) {
311
- const [, value] = gridRowsMatch;
312
- const gridValue = `repeat(${value}, 1fr)`;
313
- createStyle(`.${className}`, 'grid-template-rows', gridValue);
314
- }
315
- });
316
- }
317
-
318
- // Функция для обработки всех элементов на странице
319
- function processAllElements() {
320
- const allElements = document.querySelectorAll('*');
321
- allElements.forEach(processElement);
322
- }
323
-
324
- // Обработка новых элементов при изменении DOM
325
- const observer = new MutationObserver(function(mutations) {
326
- mutations.forEach(function(mutation) {
327
- mutation.addedNodes.forEach(function(node) {
328
- if (node.nodeType === 1) { // Element node
329
- processElement(node);
330
- // Обрабатываем также дочерние элементы
331
- const children = node.querySelectorAll('*');
332
- children.forEach(processElement);
333
- }
334
- });
335
- });
336
- });
337
-
338
- // Запуск при загрузке страницы
339
- if (document.readyState === 'loading') {
340
- document.addEventListener('DOMContentLoaded', processAllElements);
341
- } else {
342
- processAllElements();
343
- }
344
-
345
- // Наблюдение за изменениями DOM
346
- observer.observe(document.body, {
347
- childList: true,
348
- subtree: true
349
- });
350
-
351
- // Экспорт для ручного вызова
352
- window.dynamicUtils = {
353
- processAll: processAllElements,
354
- processElement: processElement
355
- };
356
-
357
- })();
1
+ // UrFU UI-Kit Vanilla - Основной файл
2
+ // Автоматически подключает CSS и добавляет поддержку динамических утилит
3
+ //
4
+ // Использование в HTML:
5
+ // <script src="node_modules/urfu-ui-kit-vanilla/main.js"></script>
6
+ //
7
+ // Использование в TypeScript/JavaScript:
8
+ // import 'urfu-ui-kit-vanilla/main.js';
9
+ // или
10
+ // require('urfu-ui-kit-vanilla/main.js');
11
+
12
+ (function() {
13
+ 'use strict';
14
+
15
+ // Автоматически подключаем CSS
16
+ function loadCSS() {
17
+ // Определяем путь к CSS относительно текущего скрипта
18
+ const currentScript = document.currentScript;
19
+ let cssPath = 'node_modules/urfu-ui-kit-vanilla/src/main.css';
20
+
21
+ if (currentScript) {
22
+ const scriptPath = currentScript.src;
23
+ const scriptDir = scriptPath.substring(0, scriptPath.lastIndexOf('/'));
24
+ cssPath = scriptDir + '/src/main.css';
25
+ }
26
+
27
+ const link = document.createElement('link');
28
+ link.rel = 'stylesheet';
29
+ link.href = cssPath;
30
+ link.id = 'urfu-ui-kit-css';
31
+
32
+ // Проверяем, не подключен ли уже CSS
33
+ if (!document.getElementById('urfu-ui-kit-css')) {
34
+ document.head.appendChild(link);
35
+ }
36
+ }
37
+
38
+ // Подключаем CSS при загрузке
39
+ if (document.readyState === 'loading') {
40
+ document.addEventListener('DOMContentLoaded', loadCSS);
41
+ } else {
42
+ loadCSS();
43
+ }
44
+
45
+ // Кэш для уже созданных стилей
46
+ const styleCache = new Set();
47
+
48
+ // Функция для создания CSS-правила
49
+ function createStyle(selector, property, value) {
50
+ const rule = `${selector} { ${property}: ${value}; }`;
51
+ if (styleCache.has(rule)) return;
52
+
53
+ styleCache.add(rule);
54
+
55
+ // Создаем или находим элемент style
56
+ let styleElement = document.getElementById('dynamic-utils-styles');
57
+ if (!styleElement) {
58
+ styleElement = document.createElement('style');
59
+ styleElement.id = 'dynamic-utils-styles';
60
+ document.head.appendChild(styleElement);
61
+ }
62
+
63
+ // Добавляем правило
64
+ styleElement.textContent += rule + '\n';
65
+ }
66
+
67
+ // Функция для парсинга классов и создания стилей
68
+ function processElement(element) {
69
+ const classList = Array.from(element.classList);
70
+
71
+ classList.forEach(className => {
72
+ // Проверяем паттерны для margin
73
+ const marginMatch = className.match(/^um([lrtb]?)(\d+)$/);
74
+ if (marginMatch) {
75
+ const [, direction, value] = marginMatch;
76
+ const pxValue = value + 'px';
77
+
78
+ switch (direction) {
79
+ case 'l':
80
+ createStyle(`.${className}`, 'margin-left', pxValue);
81
+ break;
82
+ case 'r':
83
+ createStyle(`.${className}`, 'margin-right', pxValue);
84
+ break;
85
+ case 't':
86
+ createStyle(`.${className}`, 'margin-top', pxValue);
87
+ break;
88
+ case 'b':
89
+ createStyle(`.${className}`, 'margin-bottom', pxValue);
90
+ break;
91
+ default:
92
+ createStyle(`.${className}`, 'margin', pxValue);
93
+ break;
94
+ }
95
+ }
96
+
97
+ // Проверяем паттерны для padding
98
+ const paddingMatch = className.match(/^up([lrtb]?)(\d+)$/);
99
+ if (paddingMatch) {
100
+ const [, direction, value] = paddingMatch;
101
+ const pxValue = value + 'px';
102
+
103
+ switch (direction) {
104
+ case 'l':
105
+ createStyle(`.${className}`, 'padding-left', pxValue);
106
+ break;
107
+ case 'r':
108
+ createStyle(`.${className}`, 'padding-right', pxValue);
109
+ break;
110
+ case 't':
111
+ createStyle(`.${className}`, 'padding-top', pxValue);
112
+ break;
113
+ case 'b':
114
+ createStyle(`.${className}`, 'padding-bottom', pxValue);
115
+ break;
116
+ default:
117
+ createStyle(`.${className}`, 'padding', pxValue);
118
+ break;
119
+ }
120
+ }
121
+
122
+ // Проверяем паттерны для width/height
123
+ const sizeMatch = className.match(/^u([wh])(\d+)$/);
124
+ if (sizeMatch) {
125
+ const [, property, value] = sizeMatch;
126
+ const pxValue = value + 'px';
127
+
128
+ if (property === 'w') {
129
+ createStyle(`.${className}`, 'width', pxValue);
130
+ } else if (property === 'h') {
131
+ createStyle(`.${className}`, 'height', pxValue);
132
+ }
133
+ }
134
+
135
+ // Проверяем паттерны для font-size
136
+ const fontSizeMatch = className.match(/^ufos(\d+)$/);
137
+ if (fontSizeMatch) {
138
+ const [, value] = fontSizeMatch;
139
+ const pxValue = value + 'px';
140
+ createStyle(`.${className}`, 'font-size', pxValue);
141
+ }
142
+
143
+ // Проверяем паттерны для gap
144
+ const gapMatch = className.match(/^ug(\d+)$/);
145
+ if (gapMatch) {
146
+ const [, value] = gapMatch;
147
+ const pxValue = value + 'px';
148
+ createStyle(`.${className}`, 'gap', pxValue);
149
+ }
150
+
151
+ // Проверяем паттерны для column-gap
152
+ const columnGapMatch = className.match(/^ucg(\d+)$/);
153
+ if (columnGapMatch) {
154
+ const [, value] = columnGapMatch;
155
+ const pxValue = value + 'px';
156
+ createStyle(`.${className}`, 'column-gap', pxValue);
157
+ }
158
+
159
+ // Проверяем паттерны для row-gap
160
+ const rowGapMatch = className.match(/^urg(\d+)$/);
161
+ if (rowGapMatch) {
162
+ const [, value] = rowGapMatch;
163
+ const pxValue = value + 'px';
164
+ createStyle(`.${className}`, 'row-gap', pxValue);
165
+ }
166
+
167
+ // Проверяем паттерны для min-width
168
+ const minWidthMatch = className.match(/^umnw(\d+)$/);
169
+ if (minWidthMatch) {
170
+ const [, value] = minWidthMatch;
171
+ const pxValue = value + 'px';
172
+ createStyle(`.${className}`, 'min-width', pxValue);
173
+ }
174
+
175
+ // Проверяем паттерны для min-height
176
+ const minHeightMatch = className.match(/^umnh(\d+)$/);
177
+ if (minHeightMatch) {
178
+ const [, value] = minHeightMatch;
179
+ const pxValue = value + 'px';
180
+ createStyle(`.${className}`, 'min-height', pxValue);
181
+ }
182
+
183
+ // Проверяем паттерны для max-width
184
+ const maxWidthMatch = className.match(/^umxw(\d+)$/);
185
+ if (maxWidthMatch) {
186
+ const [, value] = maxWidthMatch;
187
+ const pxValue = value + 'px';
188
+ createStyle(`.${className}`, 'max-width', pxValue);
189
+ }
190
+
191
+ // Проверяем паттерны для max-height
192
+ const maxHeightMatch = className.match(/^umxh(\d+)$/);
193
+ if (maxHeightMatch) {
194
+ const [, value] = maxHeightMatch;
195
+ const pxValue = value + 'px';
196
+ createStyle(`.${className}`, 'max-height', pxValue);
197
+ }
198
+
199
+ // Проверяем паттерны для line-height
200
+ const lineHeightMatch = className.match(/^ulh(\d+)$/);
201
+ if (lineHeightMatch) {
202
+ const [, value] = lineHeightMatch;
203
+ const pxValue = value + 'px';
204
+ createStyle(`.${className}`, 'line-height', pxValue);
205
+ }
206
+
207
+ // Проверяем паттерны для border-width
208
+ const borderWidthMatch = className.match(/^ub(\d+)$/);
209
+ if (borderWidthMatch) {
210
+ const [, value] = borderWidthMatch;
211
+ const pxValue = value + 'px';
212
+ createStyle(`.${className}`, 'border-width', pxValue);
213
+ createStyle(`.${className}`, 'border-style', 'solid');
214
+ }
215
+
216
+ // Проверяем паттерны для border-radius
217
+ const borderRadiusMatch = className.match(/^ubr(\d+)$/);
218
+ if (borderRadiusMatch) {
219
+ const [, value] = borderRadiusMatch;
220
+ const pxValue = value + 'px';
221
+ createStyle(`.${className}`, 'border-radius', pxValue);
222
+ }
223
+
224
+ // Проверяем паттерны для opacity
225
+ const opacityMatch = className.match(/^uop(\d+)$/);
226
+ if (opacityMatch) {
227
+ const [, value] = opacityMatch;
228
+ const opacityValue = (parseInt(value) / 100).toString();
229
+ createStyle(`.${className}`, 'opacity', opacityValue);
230
+ }
231
+
232
+ // Проверяем паттерны для z-index
233
+ const zIndexMatch = className.match(/^uzi(\d+)$/);
234
+ if (zIndexMatch) {
235
+ const [, value] = zIndexMatch;
236
+ createStyle(`.${className}`, 'z-index', value);
237
+ }
238
+
239
+ // Проверяем паттерны для top
240
+ const topMatch = className.match(/^utop(\d+)$/);
241
+ if (topMatch) {
242
+ const [, value] = topMatch;
243
+ const pxValue = value + 'px';
244
+ createStyle(`.${className}`, 'top', pxValue);
245
+ }
246
+
247
+ // Проверяем паттерны для right
248
+ const rightMatch = className.match(/^uright(\d+)$/);
249
+ if (rightMatch) {
250
+ const [, value] = rightMatch;
251
+ const pxValue = value + 'px';
252
+ createStyle(`.${className}`, 'right', pxValue);
253
+ }
254
+
255
+ // Проверяем паттерны для bottom
256
+ const bottomMatch = className.match(/^ubottom(\d+)$/);
257
+ if (bottomMatch) {
258
+ const [, value] = bottomMatch;
259
+ const pxValue = value + 'px';
260
+ createStyle(`.${className}`, 'bottom', pxValue);
261
+ }
262
+
263
+ // Проверяем паттерны для left
264
+ const leftMatch = className.match(/^uleft(\d+)$/);
265
+ if (leftMatch) {
266
+ const [, value] = leftMatch;
267
+ const pxValue = value + 'px';
268
+ createStyle(`.${className}`, 'left', pxValue);
269
+ }
270
+
271
+ // Проверяем паттерны для flex-grow
272
+ const flexGrowMatch = className.match(/^ufg(\d+)$/);
273
+ if (flexGrowMatch) {
274
+ const [, value] = flexGrowMatch;
275
+ createStyle(`.${className}`, 'flex-grow', value);
276
+ }
277
+
278
+ // Проверяем паттерны для flex-shrink
279
+ const flexShrinkMatch = className.match(/^ufs(\d+)$/);
280
+ if (flexShrinkMatch) {
281
+ const [, value] = flexShrinkMatch;
282
+ createStyle(`.${className}`, 'flex-shrink', value);
283
+ }
284
+
285
+ // Проверяем паттерны для flex-basis
286
+ const flexBasisMatch = className.match(/^ufb(\d+)$/);
287
+ if (flexBasisMatch) {
288
+ const [, value] = flexBasisMatch;
289
+ const pxValue = value + 'px';
290
+ createStyle(`.${className}`, 'flex-basis', pxValue);
291
+ }
292
+
293
+ // Проверяем паттерны для order
294
+ const orderMatch = className.match(/^uo(\d+)$/);
295
+ if (orderMatch) {
296
+ const [, value] = orderMatch;
297
+ createStyle(`.${className}`, 'order', value);
298
+ }
299
+
300
+ // Проверяем паттерны для grid-template-columns
301
+ const gridColsMatch = className.match(/^ugtc(\d+)$/);
302
+ if (gridColsMatch) {
303
+ const [, value] = gridColsMatch;
304
+ const gridValue = `repeat(${value}, 1fr)`;
305
+ createStyle(`.${className}`, 'grid-template-columns', gridValue);
306
+ }
307
+
308
+ // Проверяем паттерны для grid-template-rows
309
+ const gridRowsMatch = className.match(/^ugtr(\d+)$/);
310
+ if (gridRowsMatch) {
311
+ const [, value] = gridRowsMatch;
312
+ const gridValue = `repeat(${value}, 1fr)`;
313
+ createStyle(`.${className}`, 'grid-template-rows', gridValue);
314
+ }
315
+ });
316
+ }
317
+
318
+ // Функция для обработки всех элементов на странице
319
+ function processAllElements() {
320
+ const allElements = document.querySelectorAll('*');
321
+ allElements.forEach(processElement);
322
+ }
323
+
324
+ // Кэш обработанных элементов для избежания дублирования
325
+ const processedElements = new WeakSet();
326
+
327
+ // Улучшенная функция обработки элемента
328
+ function processElementSafe(element) {
329
+ if (processedElements.has(element)) return;
330
+ processedElements.add(element);
331
+ processElement(element);
332
+ }
333
+
334
+ // Обработка новых элементов при изменении DOM
335
+ const observer = new MutationObserver(function(mutations) {
336
+ mutations.forEach(function(mutation) {
337
+ mutation.addedNodes.forEach(function(node) {
338
+ if (node.nodeType === 1) { // Element node
339
+ processElementSafe(node);
340
+ // Обрабатываем также дочерние элементы
341
+ const children = node.querySelectorAll('*');
342
+ children.forEach(processElementSafe);
343
+ }
344
+ });
345
+
346
+ // Обрабатываем изменения атрибутов (включая class)
347
+ if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
348
+ processElementSafe(mutation.target);
349
+ }
350
+ });
351
+ });
352
+
353
+ // Периодическая проверка для React компонентов
354
+ let checkInterval;
355
+ function startPeriodicCheck() {
356
+ if (checkInterval) clearInterval(checkInterval);
357
+ checkInterval = setInterval(function() {
358
+ const allElements = document.querySelectorAll('*');
359
+ allElements.forEach(function(element) {
360
+ if (!processedElements.has(element)) {
361
+ processElementSafe(element);
362
+ }
363
+ });
364
+ }, 1000); // Проверяем каждую секунду
365
+ }
366
+
367
+ // Запуск при загрузке страницы
368
+ if (document.readyState === 'loading') {
369
+ document.addEventListener('DOMContentLoaded', function() {
370
+ processAllElements();
371
+ startPeriodicCheck();
372
+ });
373
+ } else {
374
+ processAllElements();
375
+ startPeriodicCheck();
376
+ }
377
+
378
+ // Наблюдение за изменениями DOM
379
+ if (document.body) {
380
+ observer.observe(document.body, {
381
+ childList: true,
382
+ subtree: true,
383
+ attributes: true,
384
+ attributeFilter: ['class']
385
+ });
386
+ } else {
387
+ // Если body еще не готов, ждем его
388
+ const bodyObserver = new MutationObserver(function() {
389
+ if (document.body) {
390
+ bodyObserver.disconnect();
391
+ observer.observe(document.body, {
392
+ childList: true,
393
+ subtree: true,
394
+ attributes: true,
395
+ attributeFilter: ['class']
396
+ });
397
+ }
398
+ });
399
+ bodyObserver.observe(document.documentElement, {
400
+ childList: true,
401
+ subtree: true
402
+ });
403
+ }
404
+
405
+ // Функция для принудительной обработки всех элементов
406
+ function forceProcessAll() {
407
+ processedElements.clear();
408
+ processAllElements();
409
+ }
410
+
411
+ // Экспорт для ручного вызова
412
+ window.dynamicUtils = {
413
+ processAll: processAllElements,
414
+ processElement: processElement,
415
+ forceProcessAll: forceProcessAll,
416
+ processElementSafe: processElementSafe
417
+ };
418
+
419
+ })();
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "UrFU UI-Kit for Vanilla Web",
4
4
  "license": "Apache-2.0",
5
5
  "private": false,
6
- "version": "2.3.1",
6
+ "version": "2.3.2",
7
7
  "type": "module",
8
8
  "scripts": {
9
9
  "start": "npm-run-all --parallel less:watch vite",
@@ -23,6 +23,7 @@
23
23
  },
24
24
  "files": [
25
25
  "src/main.css",
26
+ "src/ui-icons.css",
26
27
  "src/fonts/*",
27
28
  "main.js",
28
29
  "LICENSE"
@@ -0,0 +1,426 @@
1
+ @font-face {
2
+ font-family: 'urfu-ui-icon-font';
3
+ src: url('fonts/urfu-ui-icon-font.eot?z3h48');
4
+ src: url('fonts/urfu-ui-icon-font.eot?z3h48#iefix') format('embedded-opentype'),
5
+ url('fonts/urfu-ui-icon-font.ttf?z3h48') format('truetype'),
6
+ url('fonts/urfu-ui-icon-font.woff?z3h48') format('woff'),
7
+ url('fonts/urfu-ui-icon-font.svg?z3h48#urfu-ui-icon-font') format('svg');
8
+ font-weight: normal;
9
+ font-style: normal;
10
+ font-display: block;
11
+ }
12
+
13
+ .u-icon {
14
+ /* use !important to prevent issues with browser extensions that change fonts */
15
+ font-family: 'urfu-ui-icon-font' !important;
16
+ speak: never;
17
+ font-style: normal;
18
+ font-weight: normal;
19
+ font-variant: normal;
20
+ text-transform: none;
21
+ line-height: 1;
22
+
23
+ /* Better Font Rendering =========== */
24
+ -webkit-font-smoothing: antialiased;
25
+ -moz-osx-font-smoothing: grayscale;
26
+ }
27
+
28
+ .icon-active:before {
29
+ content: "\e900";
30
+ color: #1e4391;
31
+ }
32
+ .icon-application:before {
33
+ content: "\e901";
34
+ color: #1e4391;
35
+ }
36
+ .icon-arrow-sideways:before {
37
+ content: "\e902";
38
+ color: #1e4391;
39
+ }
40
+ .icon-attention:before {
41
+ content: "\e903";
42
+ color: #ef302b;
43
+ }
44
+ .icon-audit:before {
45
+ content: "\e904";
46
+ color: #ef302b;
47
+ }
48
+ .icon-basket:before {
49
+ content: "\e905";
50
+ color: #1e4391;
51
+ }
52
+ .icon-block:before {
53
+ content: "\e906";
54
+ color: #1e4391;
55
+ }
56
+ .icon-briefcase:before {
57
+ content: "\e907";
58
+ color: #1e4391;
59
+ }
60
+ .icon-calculator:before {
61
+ content: "\e908";
62
+ color: #1e4391;
63
+ }
64
+ .icon-calendar:before {
65
+ content: "\e909";
66
+ color: #1e4391;
67
+ }
68
+ .icon-catalog:before {
69
+ content: "\e90a";
70
+ color: #1e4391;
71
+ }
72
+ .icon-chat:before {
73
+ content: "\e90b";
74
+ color: #1e4391;
75
+ }
76
+ .icon-check:before {
77
+ content: "\e90c";
78
+ color: #3ba68c;
79
+ }
80
+ .icon-clock:before {
81
+ content: "\e90d";
82
+ color: #1e4391;
83
+ }
84
+ .icon-cloud:before {
85
+ content: "\e90e";
86
+ color: #1e4391;
87
+ }
88
+ .icon-context:before {
89
+ content: "\e90f";
90
+ color: #ef302b;
91
+ }
92
+ .icon-copy:before {
93
+ content: "\e910";
94
+ color: #1e4391;
95
+ }
96
+ .icon-correct:before {
97
+ content: "\e911";
98
+ color: #1e4391;
99
+ }
100
+ .icon-cross:before {
101
+ content: "\e912";
102
+ color: #ef302b;
103
+ }
104
+ .icon-cross-small:before {
105
+ content: "\e913";
106
+ color: #9faecd;
107
+ }
108
+ .icon-cup:before {
109
+ content: "\e914";
110
+ color: #1e4391;
111
+ }
112
+ .icon-directory:before {
113
+ content: "\e915";
114
+ color: #1e4391;
115
+ }
116
+ .icon-doc:before {
117
+ content: "\e916";
118
+ color: #1e4391;
119
+ }
120
+ .icon-document:before {
121
+ content: "\e917";
122
+ color: #1e4391;
123
+ }
124
+ .icon-documents:before {
125
+ content: "\e918";
126
+ color: #1e4391;
127
+ }
128
+ .icon-down:before {
129
+ content: "\e919";
130
+ color: #1e4391;
131
+ }
132
+ .icon-down-arrow:before {
133
+ content: "\e91a";
134
+ color: #1e4391;
135
+ }
136
+ .icon-download:before {
137
+ content: "\e91b";
138
+ color: #1e4391;
139
+ }
140
+ .icon-download-line:before {
141
+ content: "\e91c";
142
+ color: #1e4391;
143
+ }
144
+ .icon-dropdown:before {
145
+ content: "\e91d";
146
+ color: #1e4391;
147
+ }
148
+ .icon-dropdown-horisontal:before {
149
+ content: "\e91e";
150
+ color: #1e4391;
151
+ }
152
+ .icon-entrance:before {
153
+ content: "\e91f";
154
+ color: #1e4391;
155
+ }
156
+ .icon-events:before {
157
+ content: "\e920";
158
+ color: #ef302b;
159
+ }
160
+ .icon-extracurricular-activities:before {
161
+ content: "\e921";
162
+ color: #1e4391;
163
+ }
164
+ .icon-filter:before {
165
+ content: "\e922";
166
+ color: #1e4391;
167
+ }
168
+ .icon-filter-mobile:before {
169
+ content: "\e923";
170
+ color: #1e4391;
171
+ }
172
+ .icon-folder:before {
173
+ content: "\e924";
174
+ color: #e98446;
175
+ }
176
+ .icon-folders:before {
177
+ content: "\e925";
178
+ color: #a7a7a7;
179
+ }
180
+ .icon-full-screen:before {
181
+ content: "\e926";
182
+ color: #1e4391;
183
+ }
184
+ .icon-hidden:before {
185
+ content: "\e927";
186
+ color: #1e4391;
187
+ }
188
+ .icon-home:before {
189
+ content: "\e928";
190
+ color: #1e4391;
191
+ }
192
+ .icon-img:before {
193
+ content: "\e929";
194
+ color: #467be3;
195
+ }
196
+ .icon-information:before {
197
+ content: "\e92a";
198
+ color: #1e4391;
199
+ }
200
+ .icon-jpg:before {
201
+ content: "\e92b";
202
+ color: #467be3;
203
+ }
204
+ .icon-left:before {
205
+ content: "\e92c";
206
+ color: #1e4391;
207
+ }
208
+ .icon-left-arrow:before {
209
+ content: "\e92d";
210
+ color: #1e4391;
211
+ }
212
+ .icon-letter:before {
213
+ content: "\e92e";
214
+ color: #1e4391;
215
+ }
216
+ .icon-like:before {
217
+ content: "\e92f";
218
+ color: #1e4391;
219
+ }
220
+ .icon-link:before {
221
+ content: "\e930";
222
+ color: #1e4391;
223
+ }
224
+ .icon-list-view:before {
225
+ content: "\e931";
226
+ color: #7a7a7a;
227
+ }
228
+ .icon-lk-role:before {
229
+ content: "\e932";
230
+ color: #1e4391;
231
+ }
232
+ .icon-map:before {
233
+ content: "\e933";
234
+ color: #ef302b;
235
+ }
236
+ .icon-minus:before {
237
+ content: "\e934";
238
+ color: #1e4391;
239
+ }
240
+ .icon-mobile:before {
241
+ content: "\e935";
242
+ color: #1e4391;
243
+ }
244
+ .icon-moderation:before {
245
+ content: "\e936";
246
+ color: #1e4391;
247
+ }
248
+ .icon-news:before {
249
+ content: "\e937";
250
+ color: #1e4391;
251
+ }
252
+ .icon-notify:before {
253
+ content: "\e938";
254
+ color: #ef302b;
255
+ }
256
+ .icon-ok:before {
257
+ content: "\e939";
258
+ color: #1e4391;
259
+ }
260
+ .icon-participant:before {
261
+ content: "\e93a";
262
+ color: #ef302b;
263
+ }
264
+ .icon-pdf:before {
265
+ content: "\e93b";
266
+ color: #ef302b;
267
+ }
268
+ .icon-pencil:before {
269
+ content: "\e93c";
270
+ color: #1e4391;
271
+ }
272
+ .icon-people:before {
273
+ content: "\e93d";
274
+ color: #1e4391;
275
+ }
276
+ .icon-plus:before {
277
+ content: "\e93e";
278
+ color: #1e4391;
279
+ }
280
+ .icon-png:before {
281
+ content: "\e93f";
282
+ color: #467be3;
283
+ }
284
+ .icon-ppt:before {
285
+ content: "\e940";
286
+ color: #e98446;
287
+ }
288
+ .icon-question:before {
289
+ content: "\e941";
290
+ color: #1e4391;
291
+ }
292
+ .icon-rating:before {
293
+ content: "\e942";
294
+ color: #1e4391;
295
+ }
296
+ .icon-right:before {
297
+ content: "\e943";
298
+ color: #1e4391;
299
+ }
300
+ .icon-right-arrow:before {
301
+ content: "\e944";
302
+ color: #1e4391;
303
+ }
304
+ .icon-role:before {
305
+ content: "\e945";
306
+ color: #1e4391;
307
+ }
308
+ .icon-save:before {
309
+ content: "\e946";
310
+ color: #1e4391;
311
+ }
312
+ .icon-search:before {
313
+ content: "\e947";
314
+ color: #1e4391;
315
+ }
316
+ .icon-setting:before {
317
+ content: "\e948";
318
+ color: #1e4391;
319
+ }
320
+ .icon-settlement:before {
321
+ content: "\e949";
322
+ color: #1e4391;
323
+ }
324
+ .icon-shell:before {
325
+ content: "\e94a";
326
+ color: #1e4391;
327
+ }
328
+ .icon-sorting:before {
329
+ content: "\e94b";
330
+ color: #1e4391;
331
+ }
332
+ .icon-star:before {
333
+ content: "\e94c";
334
+ color: #1e4391;
335
+ }
336
+ .icon-star2:before {
337
+ content: "\e94d";
338
+ color: #ef302b;
339
+ }
340
+ .icon-star-top20:before {
341
+ content: "\e94e";
342
+ color: #147246;
343
+ }
344
+ .icon-star-top50:before {
345
+ content: "\e94f";
346
+ color: #1e4391;
347
+ }
348
+ .icon-submenu:before {
349
+ content: "\e950";
350
+ color: #ef302b;
351
+ }
352
+ .icon-svg:before {
353
+ content: "\e951";
354
+ color: #a872bc;
355
+ }
356
+ .icon-table-view:before {
357
+ content: "\e952";
358
+ color: #1e4391;
359
+ }
360
+ .icon-telephone:before {
361
+ content: "\e953";
362
+ color: #1e4391;
363
+ }
364
+ .icon-test-tube:before {
365
+ content: "\e954";
366
+ color: #1e4391;
367
+ }
368
+ .icon-top20:before {
369
+ content: "\e955";
370
+ color: #147246;
371
+ }
372
+ .icon-top50:before {
373
+ content: "\e956";
374
+ color: #1e4391;
375
+ }
376
+ .icon-top100:before {
377
+ content: "\e957";
378
+ color: #ef302b;
379
+ }
380
+ .icon-university:before {
381
+ content: "\e958";
382
+ color: #1e4391;
383
+ }
384
+ .icon-unlink:before {
385
+ content: "\e959";
386
+ color: #1e4391;
387
+ }
388
+ .icon-unlink2:before {
389
+ content: "\e95a";
390
+ color: #ef302b;
391
+ }
392
+ .icon-up:before {
393
+ content: "\e95b";
394
+ color: #1e4391;
395
+ }
396
+ .icon-up-arrow:before {
397
+ content: "\e95c";
398
+ color: #1e4391;
399
+ }
400
+ .icon-upload:before {
401
+ content: "\e95d";
402
+ color: #1e4391;
403
+ }
404
+ .icon-user:before {
405
+ content: "\e95e";
406
+ color: #1e4391;
407
+ }
408
+ .icon-video:before {
409
+ content: "\e95f";
410
+ color: #0f2b5e;
411
+ }
412
+ .icon-video-instruction:before {
413
+ content: "\e960";
414
+ }
415
+ .icon-warning:before {
416
+ content: "\e961";
417
+ color: #ef302b;
418
+ }
419
+ .icon-xls:before {
420
+ content: "\e962";
421
+ color: #3ba68c;
422
+ }
423
+ .icon-zip:before {
424
+ content: "\e963";
425
+ color: #0987ae;
426
+ }