@skbkontur/side-menu 0.3.1 → 0.4.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/CHANGELOG.md +19 -0
- package/README.md +224 -0
- package/hooks/useNumberOfTextLinesInItem.d.ts +2 -0
- package/hooks/useNumberOfTextLinesInItem.js +13 -0
- package/package.json +1 -1
- package/src/InnerSubMenu.d.ts +1 -1
- package/src/InnerSubMenu.js +11 -2
- package/src/SeparatedSubMenu.d.ts +1 -0
- package/src/SeparatedSubMenu.js +15 -2
- package/src/SideMenu.d.ts +4 -0
- package/src/SideMenu.js +19 -11
- package/src/SideMenuAvatar.d.ts +1 -1
- package/src/SideMenuBodyChildren.d.ts +6 -0
- package/src/SideMenuBodyChildren.js +45 -2
- package/src/SideMenuContext.d.ts +3 -4
- package/src/SideMenuDropdown.d.ts +1 -0
- package/src/SideMenuDropdown.js +2 -2
- package/src/SideMenuFooter.js +9 -1
- package/src/SideMenuHeader.js +2 -2
- package/src/SideMenuItem.d.ts +2 -1
- package/src/SideMenuItem.js +31 -62
- package/src/SideMenuSubItem.js +31 -17
- package/utils/scripts.d.ts +7 -0
- package/utils/scripts.js +58 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.4.0](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@0.3.2...@skbkontur/side-menu@0.4.0) (2022-11-30)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **SideMenu:** allow control active MenuItem ([c4d898d](https://git.skbkontur.ru/ui/ui-parking/commits/c4d898d894f1a72a6ddcf97c5520ecec19650b2a))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [0.3.2](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@0.3.1...@skbkontur/side-menu@0.3.2) (2022-11-30)
|
|
18
|
+
|
|
19
|
+
**Note:** Version bump only for package @skbkontur/side-menu
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
## [0.3.1](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@0.3.0...@skbkontur/side-menu@0.3.1) (2022-11-10)
|
|
7
26
|
|
|
8
27
|
**Note:** Version bump only for package @skbkontur/side-menu
|
package/README.md
CHANGED
|
@@ -187,3 +187,227 @@ const renderModal = () => {
|
|
|
187
187
|
</SideMenu>
|
|
188
188
|
</div>
|
|
189
189
|
```
|
|
190
|
+
|
|
191
|
+
SideMenu с ручным управлением
|
|
192
|
+
|
|
193
|
+
```jsx harmony
|
|
194
|
+
import { useState } from 'react';
|
|
195
|
+
import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
|
|
196
|
+
import { Kontur, Ofd } from '@skbkontur/logos';
|
|
197
|
+
import { MenuItem, Select } from '@skbkontur/react-ui';
|
|
198
|
+
import { SideMenu } from './index';
|
|
199
|
+
import {
|
|
200
|
+
DocTextIcon24Regular,
|
|
201
|
+
CommentRectTextIcon24Regular,
|
|
202
|
+
LightbulbIcon24Regular,
|
|
203
|
+
BookOpenTextIcon24Regular,
|
|
204
|
+
BookmarkIcon24Regular,
|
|
205
|
+
StackHDownIcon24Regular,
|
|
206
|
+
SettingsGearIcon24Regular,
|
|
207
|
+
FaceAHappyIcon24Regular
|
|
208
|
+
} from '@skbkontur/icons';
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
const [activeItem, setActiveItem] = useState('122');
|
|
212
|
+
const items = [
|
|
213
|
+
"100",
|
|
214
|
+
"110",
|
|
215
|
+
"120",
|
|
216
|
+
"121",
|
|
217
|
+
"122",
|
|
218
|
+
"130",
|
|
219
|
+
"140",
|
|
220
|
+
"150",
|
|
221
|
+
"160",
|
|
222
|
+
"170",
|
|
223
|
+
"200",
|
|
224
|
+
"300",
|
|
225
|
+
"310",
|
|
226
|
+
"320",
|
|
227
|
+
"330",
|
|
228
|
+
"340",
|
|
229
|
+
"350",
|
|
230
|
+
"400",
|
|
231
|
+
"500",
|
|
232
|
+
"600",
|
|
233
|
+
];
|
|
234
|
+
|
|
235
|
+
<div style={{height: '600px', display: 'flex'}}>
|
|
236
|
+
<SideMenu value={activeItem} onValueChange={setActiveItem}>
|
|
237
|
+
<SideMenu.Header konturLogo={<Kontur/>} productLogo={<Ofd/>}/>
|
|
238
|
+
<SideMenu.Body>
|
|
239
|
+
<SideMenu.Item icon={<DocTextIcon24Regular/>} caption={'Документы к подписанию id=100'} marker={'новое'} id={'100'}>
|
|
240
|
+
<SideMenu.SubItem caption={'Входящие id=110'} id={'110'}/>
|
|
241
|
+
<SideMenu.SubItem caption={'Исходящие id=120'} marker={'2'} id={'120'}>
|
|
242
|
+
<SideMenu.SubItem caption={'Исходящие1 id=121'} id={'121'}/>
|
|
243
|
+
<SideMenu.SubItem caption={'Исходящие2 id=122'} id={'122'}/>
|
|
244
|
+
</SideMenu.SubItem>
|
|
245
|
+
<SideMenu.SubItem caption={'Внутренние id=130'} id={'130'}/>
|
|
246
|
+
<SideMenu.SubItem caption={'Черновики id=140'} id={'140'}/>
|
|
247
|
+
<SideMenu.SubItem caption={'Удаленные id=150'} id={'150'}/>
|
|
248
|
+
<SideMenu.SubItemHeader>Согласованные</SideMenu.SubItemHeader>
|
|
249
|
+
<SideMenu.SubItem caption={'Требуют обработки id=160'} id={'160'}/>
|
|
250
|
+
<SideMenu.SubItem caption={'Обработанные id=170'} id={'170'}/>
|
|
251
|
+
</SideMenu.Item>
|
|
252
|
+
<SideMenu.Item icon={<FaceAHappyIcon24Regular />} caption={'Контрагенты id=200'} id={'200'}/>
|
|
253
|
+
<SideMenu.Item icon={<CommentRectTextIcon24Regular/>} caption={'Сообщения id=300'} marker={'5'} id={'300'}>
|
|
254
|
+
<SideMenu.SubItem caption={'Входящие id=310'} marker={'5'} id={'310'}/>
|
|
255
|
+
<SideMenu.SubItem caption={'Исходящие id=320'} id={'320'}/>
|
|
256
|
+
<SideMenu.SubItem caption={'Внутренние id=330'} id={'330'}/>
|
|
257
|
+
<SideMenu.SubItem caption={'Черновики id=340'} id={'340'}/>
|
|
258
|
+
<SideMenu.SubItem caption={'Удаленные id=350'} id={'350'}/>
|
|
259
|
+
</SideMenu.Item>
|
|
260
|
+
<SideMenu.Item icon={<LightbulbIcon24Regular/>} caption={'Справочная id=400'} id={'400'}/>
|
|
261
|
+
<SideMenu.Divider/>
|
|
262
|
+
<SideMenu.Item icon={<BookOpenTextIcon24Regular/>} caption={'Еще раздел id=500'} id={'500'}/>
|
|
263
|
+
<SideMenu.Item icon={<BookmarkIcon24Regular/>} caption={'Отчетность id=600'} id={'600'}/>
|
|
264
|
+
</SideMenu.Body>
|
|
265
|
+
<SideMenu.Footer>
|
|
266
|
+
<SideMenu.Dropdown icon={<StackHDownIcon24Regular/>}>
|
|
267
|
+
<MenuItem>СКБ Контур</MenuItem>
|
|
268
|
+
<MenuItem>Сириус Базинес</MenuItem>
|
|
269
|
+
<MenuItem>Контур НТТ</MenuItem>
|
|
270
|
+
<MenuItem>Промэлектроника</MenuItem>
|
|
271
|
+
<SideMenu.Divider/>
|
|
272
|
+
<MenuItem>Список организаций</MenuItem>
|
|
273
|
+
</SideMenu.Dropdown>
|
|
274
|
+
<SideMenu.Item icon={<SettingsGearIcon24Regular/>} caption={'Реквизиты и настройки'}/>
|
|
275
|
+
<SideMenu.Avatar
|
|
276
|
+
userName={'Ишматова Елена'}
|
|
277
|
+
avatarUrl={getKonturAvatarUrl({
|
|
278
|
+
userId: '992408aa-050e-41e9-9a48-6bf2f2f20d94'
|
|
279
|
+
})}
|
|
280
|
+
>
|
|
281
|
+
<MenuItem href={'https://cabinet.kontur.ru'} target="_blank">
|
|
282
|
+
Личный кабинет
|
|
283
|
+
</MenuItem>
|
|
284
|
+
<MenuItem >Безопасность</MenuItem>
|
|
285
|
+
<SideMenu.Divider />
|
|
286
|
+
<MenuItem >Выйти</MenuItem>
|
|
287
|
+
</SideMenu.Avatar>
|
|
288
|
+
</SideMenu.Footer>
|
|
289
|
+
</SideMenu>
|
|
290
|
+
<div>
|
|
291
|
+
<p>Active Item: {activeItem}</p>
|
|
292
|
+
<Select items={items} value={activeItem} onValueChange={setActiveItem} />
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Если не хочется передавать свой `id`, то для ручного управления можно воспользоваться автоматически сгенерированными айдишниками. А также комбинировать свои `id` с автоматически сгенерированными.
|
|
298
|
+
|
|
299
|
+
Автоматическая генерация айдишников происходит по следующей схеме:
|
|
300
|
+
элементы меню первого уровня получают `id` равный `body-x`, где `x` - индекс элемента.
|
|
301
|
+
Элементы меню следующих уровней добавляют свой индекс: `body-x-y`.
|
|
302
|
+
|
|
303
|
+
Например, в пункте `Документы к подписанию` передан проп `id='documents'`, а также есть автоматически сгенерированный `id='body-0'`. Управлять можно по любому из них.
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
```jsx harmony
|
|
307
|
+
import { useState } from 'react';
|
|
308
|
+
import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
|
|
309
|
+
import { Kontur, Ofd } from '@skbkontur/logos';
|
|
310
|
+
import { MenuItem, Select } from '@skbkontur/react-ui';
|
|
311
|
+
import { SideMenu } from './index';
|
|
312
|
+
import {
|
|
313
|
+
DocTextIcon24Regular,
|
|
314
|
+
CommentRectTextIcon24Regular,
|
|
315
|
+
LightbulbIcon24Regular,
|
|
316
|
+
BookOpenTextIcon24Regular,
|
|
317
|
+
BookmarkIcon24Regular,
|
|
318
|
+
StackHDownIcon24Regular,
|
|
319
|
+
SettingsGearIcon24Regular,
|
|
320
|
+
FaceAHappyIcon24Regular
|
|
321
|
+
} from '@skbkontur/icons';
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
const [activeItem, setActiveItem] = useState(undefined);
|
|
325
|
+
const items = [
|
|
326
|
+
'body-0',
|
|
327
|
+
'documents',
|
|
328
|
+
'body-0-0',
|
|
329
|
+
'my-id-for-incoming-documents',
|
|
330
|
+
'body-0-1',
|
|
331
|
+
'body-0-1-0',
|
|
332
|
+
'body-0-1-1',
|
|
333
|
+
'body-0-2',
|
|
334
|
+
'body-0-3',
|
|
335
|
+
'body-0-4',
|
|
336
|
+
'body-0-5',
|
|
337
|
+
'body-0-6',
|
|
338
|
+
'body-1',
|
|
339
|
+
'body-2',
|
|
340
|
+
'body-2-0',
|
|
341
|
+
'body-2-1',
|
|
342
|
+
'body-2-2',
|
|
343
|
+
'body-2-3',
|
|
344
|
+
'body-2-4',
|
|
345
|
+
'body-3',
|
|
346
|
+
'body-4',
|
|
347
|
+
'body-5',
|
|
348
|
+
'footer-0',
|
|
349
|
+
'footer-1',
|
|
350
|
+
'footer-2',
|
|
351
|
+
];
|
|
352
|
+
|
|
353
|
+
<div style={{height: '600px', display: 'flex'}}>
|
|
354
|
+
<SideMenu value={activeItem} onValueChange={setActiveItem}>
|
|
355
|
+
<SideMenu.Header konturLogo={<Kontur/>} productLogo={<Ofd/>}/>
|
|
356
|
+
<SideMenu.Body>
|
|
357
|
+
<SideMenu.Item icon={<DocTextIcon24Regular/>} caption={'Документы к подписанию'} marker={'новое'} id={'documents'}>
|
|
358
|
+
<SideMenu.SubItem caption={'Входящие'} id={'my-id-for-incoming-documents'}/>
|
|
359
|
+
<SideMenu.SubItem caption={'Исходящие'} marker={'2'}>
|
|
360
|
+
<SideMenu.SubItem caption={'Исходящие1'}/>
|
|
361
|
+
<SideMenu.SubItem caption={'Исходящие2'}/>
|
|
362
|
+
</SideMenu.SubItem>
|
|
363
|
+
<SideMenu.SubItem caption={'Внутренние'}/>
|
|
364
|
+
<SideMenu.SubItem caption={'Черновики'}/>
|
|
365
|
+
<SideMenu.SubItem caption={'Удаленные'}/>
|
|
366
|
+
<SideMenu.SubItemHeader>Согласованные</SideMenu.SubItemHeader>
|
|
367
|
+
<SideMenu.SubItem caption={'Требуют обработки'}/>
|
|
368
|
+
<SideMenu.SubItem caption={'Обработанные'}/>
|
|
369
|
+
</SideMenu.Item>
|
|
370
|
+
<SideMenu.Item icon={<FaceAHappyIcon24Regular />} caption={'Контрагенты'}/>
|
|
371
|
+
<SideMenu.Item icon={<CommentRectTextIcon24Regular/>} caption={'Сообщения'} marker={'5'}>
|
|
372
|
+
<SideMenu.SubItem caption={'Входящие'} marker={'5'}/>
|
|
373
|
+
<SideMenu.SubItem caption={'Исходящие'}/>
|
|
374
|
+
<SideMenu.SubItem caption={'Внутренние'}/>
|
|
375
|
+
<SideMenu.SubItem caption={'Черновики'}/>
|
|
376
|
+
<SideMenu.SubItem caption={'Удаленные'}/>
|
|
377
|
+
</SideMenu.Item>
|
|
378
|
+
<SideMenu.Item icon={<LightbulbIcon24Regular/>} caption={'Справочная'}/>
|
|
379
|
+
<SideMenu.Divider/>
|
|
380
|
+
<SideMenu.Item icon={<BookOpenTextIcon24Regular/>} caption={'Еще раздел'}/>
|
|
381
|
+
<SideMenu.Item icon={<BookmarkIcon24Regular/>} caption={'Отчетность'} id={'600'}/>
|
|
382
|
+
</SideMenu.Body>
|
|
383
|
+
<SideMenu.Footer>
|
|
384
|
+
<SideMenu.Organisations icon={<StackHDownIcon24Regular/>}>
|
|
385
|
+
<MenuItem>СКБ Контур</MenuItem>
|
|
386
|
+
<MenuItem>Сириус Базинес</MenuItem>
|
|
387
|
+
<MenuItem>Контур НТТ</MenuItem>
|
|
388
|
+
<MenuItem>Промэлектроника</MenuItem>
|
|
389
|
+
<SideMenu.Divider/>
|
|
390
|
+
<MenuItem>Список организаций</MenuItem>
|
|
391
|
+
</SideMenu.Organisations>
|
|
392
|
+
<SideMenu.Item icon={<SettingsGearIcon24Regular/>} caption={'Реквизиты и настройки'}/>
|
|
393
|
+
<SideMenu.Avatar
|
|
394
|
+
userName={'Ишматова Елена'}
|
|
395
|
+
avatarUrl={getKonturAvatarUrl({
|
|
396
|
+
userId: '992408aa-050e-41e9-9a48-6bf2f2f20d94'
|
|
397
|
+
})}
|
|
398
|
+
>
|
|
399
|
+
<MenuItem href={'https://cabinet.kontur.ru'} target="_blank">
|
|
400
|
+
Личный кабинет
|
|
401
|
+
</MenuItem>
|
|
402
|
+
<MenuItem >Безопасность</MenuItem>
|
|
403
|
+
<SideMenu.Divider />
|
|
404
|
+
<MenuItem >Выйти</MenuItem>
|
|
405
|
+
</SideMenu.Avatar>
|
|
406
|
+
</SideMenu.Footer>
|
|
407
|
+
</SideMenu>
|
|
408
|
+
<div>
|
|
409
|
+
<p>Active Item: {activeItem}</p>
|
|
410
|
+
<Select items={items} value={activeItem} onValueChange={setActiveItem} />
|
|
411
|
+
</div>
|
|
412
|
+
</div>
|
|
413
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export var useNumberOfTextLinesInItem = function (textRef, setIsMultilineText) {
|
|
2
|
+
if (textRef.current) {
|
|
3
|
+
var el_1 = textRef.current;
|
|
4
|
+
setTimeout(function () {
|
|
5
|
+
var textHeight = +el_1.offsetHeight;
|
|
6
|
+
var lineHeight = parseInt(window.getComputedStyle(el_1).getPropertyValue('line-height'));
|
|
7
|
+
var lines = textHeight / lineHeight;
|
|
8
|
+
if (lines >= 2) {
|
|
9
|
+
setIsMultilineText(true);
|
|
10
|
+
}
|
|
11
|
+
}, 0);
|
|
12
|
+
}
|
|
13
|
+
};
|
package/package.json
CHANGED
package/src/InnerSubMenu.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
interface InnerSubMenuProps {
|
|
3
3
|
children?: React.ReactNode;
|
|
4
|
-
|
|
4
|
+
generatedId?: string;
|
|
5
5
|
}
|
|
6
6
|
declare const InnerSubMenuWithStaticFields: React.ForwardRefExoticComponent<InnerSubMenuProps & React.RefAttributes<HTMLDivElement>> & {
|
|
7
7
|
__KONTUR_REACT_UI__: string;
|
package/src/InnerSubMenu.js
CHANGED
|
@@ -5,10 +5,19 @@ import React, { forwardRef } from 'react';
|
|
|
5
5
|
* @visibleName InnerSubMenu
|
|
6
6
|
*/
|
|
7
7
|
var InnerSubMenu = forwardRef(function (_a, ref) {
|
|
8
|
-
var children = _a.children,
|
|
8
|
+
var children = _a.children, generatedId = _a.generatedId;
|
|
9
|
+
var levelIndex = 0;
|
|
9
10
|
return (React.createElement(React.Fragment, null, React.Children.map(children, function (child) {
|
|
10
11
|
if (React.isValidElement(child)) {
|
|
11
|
-
|
|
12
|
+
// @ts-expect-error: accessing private property
|
|
13
|
+
if ((child === null || child === void 0 ? void 0 : child.type.__KONTUR_REACT_UI__) === 'SideMenuSubItem') {
|
|
14
|
+
var oldIndex = levelIndex;
|
|
15
|
+
levelIndex++;
|
|
16
|
+
return React.cloneElement(child, {
|
|
17
|
+
_generatedId: generatedId + "-" + oldIndex,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return React.cloneElement(child, { ref: ref });
|
|
12
21
|
}
|
|
13
22
|
return child;
|
|
14
23
|
})));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
interface SeparatedSubMenuProps {
|
|
3
3
|
children?: React.ReactNode;
|
|
4
|
+
generatedId?: string;
|
|
4
5
|
}
|
|
5
6
|
declare const SeparatedSubMenuWithStaticFields: React.ForwardRefExoticComponent<SeparatedSubMenuProps & React.RefAttributes<HTMLDivElement>> & {
|
|
6
7
|
__KONTUR_REACT_UI__: string;
|
package/src/SeparatedSubMenu.js
CHANGED
|
@@ -10,7 +10,7 @@ import { SideMenuContext } from './SideMenuContext';
|
|
|
10
10
|
*/
|
|
11
11
|
var SeparatedSubMenu = forwardRef(function (_a, ref) {
|
|
12
12
|
var _b;
|
|
13
|
-
var children = _a.children;
|
|
13
|
+
var children = _a.children, generatedId = _a.generatedId;
|
|
14
14
|
var context = useContext(SideMenuContext);
|
|
15
15
|
var isSubItemWithChildren = function (child) {
|
|
16
16
|
// @ts-expect-error: accessing private property
|
|
@@ -24,8 +24,21 @@ var SeparatedSubMenu = forwardRef(function (_a, ref) {
|
|
|
24
24
|
return child;
|
|
25
25
|
});
|
|
26
26
|
};
|
|
27
|
+
var levelIndex = 0;
|
|
27
28
|
return (React.createElement("div", { className: cx((_b = {}, _b[jsStyles.root()] = true, _b[jsStyles.separatedMenu()] = true, _b)), ref: ref },
|
|
28
|
-
React.createElement(SideMenuContext.Provider, { value: __assign({ hasSubIcons: hasSubItems(children) }, context) }, children)
|
|
29
|
+
React.createElement(SideMenuContext.Provider, { value: __assign({ hasSubIcons: hasSubItems(children) }, context) }, React.Children.map(children, function (child) {
|
|
30
|
+
if (React.isValidElement(child)) {
|
|
31
|
+
// @ts-expect-error: accessing private property
|
|
32
|
+
if ((child === null || child === void 0 ? void 0 : child.type.__KONTUR_REACT_UI__) === 'SideMenuSubItem') {
|
|
33
|
+
var oldIndex = levelIndex;
|
|
34
|
+
levelIndex++;
|
|
35
|
+
return React.cloneElement(child, {
|
|
36
|
+
_generatedId: generatedId + "-" + oldIndex,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return child;
|
|
40
|
+
}
|
|
41
|
+
}))));
|
|
29
42
|
});
|
|
30
43
|
SeparatedSubMenu.displayName = 'SeparatedSubMenu';
|
|
31
44
|
var SeparatedSubMenuWithStaticFields = Object.assign(SeparatedSubMenu, { __KONTUR_REACT_UI__: 'SeparatedSubMenu' });
|
package/src/SideMenu.d.ts
CHANGED
|
@@ -9,11 +9,14 @@ import { SideMenuAvatar } from './SideMenuAvatar';
|
|
|
9
9
|
import { SideMenuSubItem } from './SideMenuSubItem';
|
|
10
10
|
import { SideMenuDivider } from './SideMenuDivider';
|
|
11
11
|
import { SideMenuSubItemHeader } from './SideMenuSubItemHeader';
|
|
12
|
+
import { SideMenuDropdown } from './SideMenuDropdown';
|
|
12
13
|
export interface SideMenuProps extends CommonProps {
|
|
13
14
|
children?: React.ReactNode;
|
|
14
15
|
size?: 'small' | 'large';
|
|
15
16
|
isSeparatedMenu?: boolean;
|
|
16
17
|
disableSwipe?: boolean;
|
|
18
|
+
value?: string;
|
|
19
|
+
onValueChange?: (value: string) => void;
|
|
17
20
|
}
|
|
18
21
|
interface SubComponents {
|
|
19
22
|
Body: typeof SideMenuBody;
|
|
@@ -25,6 +28,7 @@ interface SubComponents {
|
|
|
25
28
|
Avatar: typeof SideMenuAvatar;
|
|
26
29
|
Organisations: typeof SideMenuOrganisations;
|
|
27
30
|
Divider: typeof SideMenuDivider;
|
|
31
|
+
Dropdown: typeof SideMenuDropdown;
|
|
28
32
|
__KONTUR_REACT_UI__: string;
|
|
29
33
|
}
|
|
30
34
|
export declare const SideMenuDataTids: {
|
package/src/SideMenu.js
CHANGED
|
@@ -14,22 +14,22 @@ import { SideMenuSubItem } from './SideMenuSubItem';
|
|
|
14
14
|
import { SideMenuDivider } from './SideMenuDivider';
|
|
15
15
|
import { SideMenuSubItemHeader } from './SideMenuSubItemHeader';
|
|
16
16
|
import { RightBorder } from './RightBorder';
|
|
17
|
+
import { SideMenuDropdown } from './SideMenuDropdown';
|
|
17
18
|
export var SideMenuDataTids = {
|
|
18
19
|
root: 'SideMenu__root',
|
|
19
20
|
};
|
|
20
21
|
var SideMenu = forwardRef(function (_a, ref) {
|
|
21
22
|
var _b, _c;
|
|
22
|
-
var children = _a.children, _d = _a.size, size = _d === void 0 ? 'small' : _d, _e = _a.isSeparatedMenu, isSeparatedMenu = _e === void 0 ? false : _e, className = _a.className, _f = _a.disableSwipe, disableSwipe = _f === void 0 ? false : _f, rest = __rest(_a, ["children", "size", "isSeparatedMenu", "className", "disableSwipe"]);
|
|
23
|
+
var children = _a.children, value = _a.value, onValueChange = _a.onValueChange, _d = _a.size, size = _d === void 0 ? 'small' : _d, _e = _a.isSeparatedMenu, isSeparatedMenu = _e === void 0 ? false : _e, className = _a.className, _f = _a.disableSwipe, disableSwipe = _f === void 0 ? false : _f, rest = __rest(_a, ["children", "value", "onValueChange", "size", "isSeparatedMenu", "className", "disableSwipe"]);
|
|
23
24
|
var scrollTimer = null;
|
|
24
25
|
var transitionTimer = null;
|
|
25
26
|
var widgetTimer;
|
|
26
27
|
var _g = useState(false), isMinimised = _g[0], setIsMinimised = _g[1];
|
|
27
|
-
var _h = useState(
|
|
28
|
-
var _j = useState(
|
|
29
|
-
var _k = useState(
|
|
30
|
-
var _l = useState(false),
|
|
31
|
-
var _m = useState(
|
|
32
|
-
var _o = useState(false), showWidget = _o[0], setShowWidget = _o[1];
|
|
28
|
+
var _h = useState(false), hasScrollBar = _h[0], setHasScrollBar = _h[1];
|
|
29
|
+
var _j = useState(false), isTransitioned = _j[0], setIsTransitioned = _j[1];
|
|
30
|
+
var _k = useState('#2291ff'), productColor = _k[0], setProductColor = _k[1];
|
|
31
|
+
var _l = useState(false), showWidget = _l[0], setShowWidget = _l[1];
|
|
32
|
+
var _m = useState(value), activeMenuItem = _m[0], setActiveMenuItem = _m[1];
|
|
33
33
|
useEffect(function () {
|
|
34
34
|
return function () {
|
|
35
35
|
if (scrollTimer) {
|
|
@@ -37,6 +37,9 @@ var SideMenu = forwardRef(function (_a, ref) {
|
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
});
|
|
40
|
+
useEffect(function () {
|
|
41
|
+
setActiveMenuItem(value);
|
|
42
|
+
}, [value]);
|
|
40
43
|
var showMinimisedRoot = function () {
|
|
41
44
|
if (isMinimised) {
|
|
42
45
|
setIsTransitioned(true);
|
|
@@ -75,18 +78,22 @@ var SideMenu = forwardRef(function (_a, ref) {
|
|
|
75
78
|
}
|
|
76
79
|
setShowWidget(false);
|
|
77
80
|
};
|
|
81
|
+
var handleSwitchActiveItem = function (id) {
|
|
82
|
+
if (id !== value) {
|
|
83
|
+
onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(id);
|
|
84
|
+
setActiveMenuItem(id);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
78
87
|
return (React.createElement(SideMenuContext.Provider, { value: {
|
|
79
88
|
isMinimised: isMinimised,
|
|
80
89
|
isTransitioned: isTransitioned,
|
|
81
90
|
isSeparatedMenu: isSeparatedMenu,
|
|
82
91
|
size: size,
|
|
83
|
-
activeItem: activeItem,
|
|
84
92
|
productColor: productColor,
|
|
85
|
-
setActiveItem: setActiveItem,
|
|
86
|
-
activeSubItem: activeSubItem,
|
|
87
|
-
setActiveSubItem: setActiveSubItem,
|
|
88
93
|
setProductColor: setProductColor,
|
|
89
94
|
showWidget: showWidget,
|
|
95
|
+
activeMenuItem: activeMenuItem,
|
|
96
|
+
switchActiveMenuItem: handleSwitchActiveItem,
|
|
90
97
|
} },
|
|
91
98
|
React.createElement("aside", __assign({ className: cx((_b = {}, _b[jsStyles.rootWrapper()] = true, _b[jsStyles.rootWrapperIE()] = isIE11, _b), className), "data-tid": SideMenuDataTids.root, ref: ref }, rest, { onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave }),
|
|
92
99
|
React.createElement("div", { className: cx((_c = {},
|
|
@@ -109,6 +116,7 @@ var STATIC_PROPS = {
|
|
|
109
116
|
Avatar: SideMenuAvatar,
|
|
110
117
|
Organisations: SideMenuOrganisations,
|
|
111
118
|
Divider: SideMenuDivider,
|
|
119
|
+
Dropdown: SideMenuDropdown,
|
|
112
120
|
__KONTUR_REACT_UI__: 'SideMenu',
|
|
113
121
|
};
|
|
114
122
|
var SideMenuWithStaticFields = Object.assign(SideMenu, STATIC_PROPS);
|
package/src/SideMenuAvatar.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { UserAvatarProps } from '@skbkontur/react-ui-addons/components/UserAvatar';
|
|
3
3
|
import { SideMenuDropdownProps } from './SideMenuDropdown';
|
|
4
|
-
export interface SideMenuAvatarProps extends UserAvatarProps, Omit<SideMenuDropdownProps, 'icon'>, Partial<Pick<SideMenuDropdownProps, 'icon'>> {
|
|
4
|
+
export interface SideMenuAvatarProps extends UserAvatarProps, Omit<SideMenuDropdownProps, 'icon'>, Partial<Pick<SideMenuDropdownProps, 'icon' | 'onOpen' | 'onClose'>> {
|
|
5
5
|
}
|
|
6
6
|
declare const SideMenuAvatarWithStaticFields: React.ForwardRefExoticComponent<SideMenuAvatarProps & React.RefAttributes<HTMLDivElement>> & {
|
|
7
7
|
__KONTUR_REACT_UI__: string;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { CommonProps } from '@skbkontur/react-ui/internal/CommonWrapper';
|
|
3
|
+
export interface FlattedArrayElementType {
|
|
4
|
+
id: string;
|
|
5
|
+
generatedId: string;
|
|
6
|
+
parentId: string | null;
|
|
7
|
+
generatedParentId: string | null;
|
|
8
|
+
}
|
|
3
9
|
declare const SideMenuBodyChildrenWithStaticFields: React.FC<CommonProps> & {
|
|
4
10
|
__KONTUR_REACT_UI__: string;
|
|
5
11
|
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { __assign } from "tslib";
|
|
2
|
+
import React, { isValidElement, useContext, useEffect, useRef, useState } from 'react';
|
|
2
3
|
import { jsStyles } from './SideMenu.styles';
|
|
4
|
+
import { SideMenuContext } from './SideMenuContext';
|
|
5
|
+
import { getAllParents, getElementsChildren, getItemId } from '../utils/scripts';
|
|
3
6
|
/**
|
|
4
7
|
* Внутренняя часть SideMenuBody
|
|
5
8
|
*
|
|
@@ -7,7 +10,39 @@ import { jsStyles } from './SideMenu.styles';
|
|
|
7
10
|
*/
|
|
8
11
|
var SideMenuBodyChildren = function (_a) {
|
|
9
12
|
var children = _a.children;
|
|
10
|
-
|
|
13
|
+
var context = useContext(SideMenuContext);
|
|
14
|
+
var _b = useState([]), parents = _b[0], setParents = _b[1];
|
|
15
|
+
var flattedArrayOfAllElements = useRef([]);
|
|
16
|
+
var getFlattedArrayOfAllElements = function () {
|
|
17
|
+
var levelIndex = 0;
|
|
18
|
+
React.Children.map(children, function (child) {
|
|
19
|
+
if (isValidElement(child) &&
|
|
20
|
+
// @ts-expect-error: accessing private property
|
|
21
|
+
child.type.__KONTUR_REACT_UI__ === 'SideMenuItem') {
|
|
22
|
+
var generatedId = getItemId('body', levelIndex++);
|
|
23
|
+
flattedArrayOfAllElements.current.push({
|
|
24
|
+
id: child.props.id,
|
|
25
|
+
generatedId: generatedId,
|
|
26
|
+
parentId: null,
|
|
27
|
+
generatedParentId: null,
|
|
28
|
+
});
|
|
29
|
+
getElementsChildren(child, generatedId).forEach(function (el) { return flattedArrayOfAllElements.current.push(el); });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
var getOpenedParents = function () {
|
|
34
|
+
if (context.activeMenuItem) {
|
|
35
|
+
setParents(getAllParents(context.activeMenuItem, flattedArrayOfAllElements.current));
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
useEffect(function () {
|
|
39
|
+
getFlattedArrayOfAllElements();
|
|
40
|
+
}, []);
|
|
41
|
+
useEffect(function () {
|
|
42
|
+
getOpenedParents();
|
|
43
|
+
}, [context.activeMenuItem]);
|
|
44
|
+
var levelIndex = 0;
|
|
45
|
+
return (React.createElement(SideMenuContext.Provider, { value: __assign({ openedParents: parents }, context) }, React.Children.map(children, function (child) {
|
|
11
46
|
if (React.isValidElement(child)) {
|
|
12
47
|
// @ts-expect-error: accessing private property
|
|
13
48
|
if ((child === null || child === void 0 ? void 0 : child.type.__KONTUR_REACT_UI__) === 'SideMenuDivider') {
|
|
@@ -15,6 +50,14 @@ var SideMenuBodyChildren = function (_a) {
|
|
|
15
50
|
className: jsStyles.dividerInSideMenu(),
|
|
16
51
|
});
|
|
17
52
|
}
|
|
53
|
+
// @ts-expect-error: accessing private property
|
|
54
|
+
if ((child === null || child === void 0 ? void 0 : child.type.__KONTUR_REACT_UI__) === 'SideMenuItem') {
|
|
55
|
+
var oldIndex = levelIndex;
|
|
56
|
+
levelIndex++;
|
|
57
|
+
return React.cloneElement(child, {
|
|
58
|
+
_generatedId: getItemId('body', oldIndex),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
18
61
|
return child;
|
|
19
62
|
}
|
|
20
63
|
})));
|
package/src/SideMenuContext.d.ts
CHANGED
|
@@ -3,13 +3,12 @@ export interface SideMenuContextType {
|
|
|
3
3
|
isTransitioned?: boolean;
|
|
4
4
|
isSeparatedMenu?: boolean;
|
|
5
5
|
size?: 'small' | 'large';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
activeSubItem?: string | null;
|
|
9
|
-
setActiveSubItem?: (item: string | null) => void;
|
|
6
|
+
activeMenuItem?: string | null;
|
|
7
|
+
switchActiveMenuItem?: (id: string) => void;
|
|
10
8
|
hasSubIcons?: boolean;
|
|
11
9
|
productColor?: string;
|
|
12
10
|
setProductColor?: (color: string) => void;
|
|
13
11
|
showWidget?: boolean;
|
|
12
|
+
openedParents?: string[];
|
|
14
13
|
}
|
|
15
14
|
export declare const SideMenuContext: import("react").Context<SideMenuContextType>;
|
|
@@ -7,6 +7,7 @@ export interface SideMenuDropdownProps extends CommonProps, Omit<DropdownMenuPro
|
|
|
7
7
|
caption?: string;
|
|
8
8
|
disableAnimations?: boolean;
|
|
9
9
|
_avatar?: React.ReactElement;
|
|
10
|
+
id?: string;
|
|
10
11
|
}
|
|
11
12
|
declare const SideMenuDropdownWithStaticFields: React.ForwardRefExoticComponent<SideMenuDropdownProps & React.RefAttributes<HTMLDivElement>> & {
|
|
12
13
|
__KONTUR_REACT_UI__: string;
|
package/src/SideMenuDropdown.js
CHANGED
|
@@ -13,13 +13,13 @@ import { SideMenuContext } from './SideMenuContext';
|
|
|
13
13
|
*/
|
|
14
14
|
var SideMenuDropdown = forwardRef(function (_a, ref) {
|
|
15
15
|
var _b, _c;
|
|
16
|
-
var icon = _a.icon, _avatar = _a._avatar, children = _a.children, _d = _a.caption, caption = _d === void 0 ? 'СКБ Контур' : _d, className = _a.className, _e = _a.disableAnimations, disableAnimations = _e === void 0 ? false : _e, menuWidth = _a.menuWidth, rest = __rest(_a, ["icon", "_avatar", "children", "caption", "className", "disableAnimations", "menuWidth"]);
|
|
16
|
+
var icon = _a.icon, id = _a.id, _avatar = _a._avatar, children = _a.children, _d = _a.caption, caption = _d === void 0 ? 'СКБ Контур' : _d, className = _a.className, _e = _a.disableAnimations, disableAnimations = _e === void 0 ? false : _e, menuWidth = _a.menuWidth, rest = __rest(_a, ["icon", "id", "_avatar", "children", "caption", "className", "disableAnimations", "menuWidth"]);
|
|
17
17
|
var context = useContext(SideMenuContext);
|
|
18
18
|
var label = (React.createElement("div", { className: cx((_b = {},
|
|
19
19
|
_b[jsStyles.dropdownLabel()] = true,
|
|
20
20
|
_b[jsStyles.dropdownLabelMinimized()] = context.isMinimised,
|
|
21
21
|
_b)) },
|
|
22
|
-
React.createElement(SideMenuItem, { icon: icon, caption: caption, _avatar: _avatar })));
|
|
22
|
+
React.createElement(SideMenuItem, { icon: icon, caption: caption, _avatar: _avatar, id: id })));
|
|
23
23
|
return (React.createElement(ThemeContext.Provider, { value: ThemeFactory.create({
|
|
24
24
|
menuItemHoverBg: '#f6f6f6',
|
|
25
25
|
menuItemHoverColor: '#222',
|
package/src/SideMenuFooter.js
CHANGED
|
@@ -2,6 +2,7 @@ import { __assign, __rest } from "tslib";
|
|
|
2
2
|
import React, { forwardRef } from 'react';
|
|
3
3
|
import { cx } from '@skbkontur/react-ui/lib/theming/Emotion';
|
|
4
4
|
import { jsStyles } from './SideMenu.styles';
|
|
5
|
+
import { getItemId } from '../utils/scripts';
|
|
5
6
|
/**
|
|
6
7
|
* Нижняя часть меню
|
|
7
8
|
*
|
|
@@ -10,7 +11,14 @@ import { jsStyles } from './SideMenu.styles';
|
|
|
10
11
|
var SideMenuFooter = forwardRef(function (_a, ref) {
|
|
11
12
|
var _b;
|
|
12
13
|
var className = _a.className, children = _a.children, rest = __rest(_a, ["className", "children"]);
|
|
13
|
-
return (React.createElement("footer", __assign({ className: cx((_b = {}, _b[jsStyles.footer()] = true, _b), className), ref: ref }, rest), children)
|
|
14
|
+
return (React.createElement("footer", __assign({ className: cx((_b = {}, _b[jsStyles.footer()] = true, _b), className), ref: ref }, rest), React.Children.map(children, function (child, index) {
|
|
15
|
+
if (React.isValidElement(child)) {
|
|
16
|
+
return React.cloneElement(child, {
|
|
17
|
+
_generatedId: getItemId('footer', index++),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return child;
|
|
21
|
+
})));
|
|
14
22
|
});
|
|
15
23
|
SideMenuFooter.displayName = 'SideMenuFooter';
|
|
16
24
|
var SideMenuFooterWithStaticFields = Object.assign(SideMenuFooter, { __KONTUR_REACT_UI__: 'SideMenuFooter' });
|
package/src/SideMenuHeader.js
CHANGED
|
@@ -12,7 +12,7 @@ import { SideMenuLogotype } from './SideMenuLogotype';
|
|
|
12
12
|
*/
|
|
13
13
|
var SideMenuHeader = forwardRef(function (_a, ref) {
|
|
14
14
|
var _b;
|
|
15
|
-
var className = _a.className, productLogo = _a.productLogo, konturLogo = _a.konturLogo, iconUrl = _a.iconUrl, rest = __rest(_a, ["className", "productLogo", "konturLogo", "iconUrl"]);
|
|
15
|
+
var className = _a.className, productLogo = _a.productLogo, konturLogo = _a.konturLogo, iconUrl = _a.iconUrl, withWidget = _a.withWidget, rest = __rest(_a, ["className", "productLogo", "konturLogo", "iconUrl", "withWidget"]);
|
|
16
16
|
var context = useContext(SideMenuContext);
|
|
17
17
|
var headerWrapperRef = useRef(null);
|
|
18
18
|
var _c = useState(false), fixed = _c[0], setFixed = _c[1];
|
|
@@ -35,7 +35,7 @@ var SideMenuHeader = forwardRef(function (_a, ref) {
|
|
|
35
35
|
_b[jsStyles.headerFixedWrapper()] = fixed,
|
|
36
36
|
_b[jsStyles.headerMinimisedWrapper()] = context.isMinimised || context.isTransitioned,
|
|
37
37
|
_b), className), ref: mergeRefs([headerWrapperRef, ref]) }, rest),
|
|
38
|
-
React.createElement(SideMenuLogotype, __assign({ productLogo: productLogo, konturLogo: konturLogo, iconUrl: iconUrl }, rest))));
|
|
38
|
+
React.createElement(SideMenuLogotype, __assign({ productLogo: productLogo, konturLogo: konturLogo, iconUrl: iconUrl, withWidget: withWidget }, rest))));
|
|
39
39
|
});
|
|
40
40
|
SideMenuHeader.displayName = 'SideMenuHeader';
|
|
41
41
|
var SideMenuHeaderWithStaticFields = Object.assign(SideMenuHeader, { __KONTUR_REACT_UI__: 'SideMenuHeader' });
|
package/src/SideMenuItem.d.ts
CHANGED
|
@@ -7,8 +7,9 @@ export interface SideMenuItemProps extends CommonProps {
|
|
|
7
7
|
icon: React.ReactElement;
|
|
8
8
|
marker?: string;
|
|
9
9
|
caption?: string;
|
|
10
|
+
id?: string;
|
|
11
|
+
_generatedId?: string;
|
|
10
12
|
_isSubMenu?: boolean;
|
|
11
|
-
_parent?: string;
|
|
12
13
|
_isNestedSubMenu?: boolean;
|
|
13
14
|
_avatar?: React.ReactElement;
|
|
14
15
|
}
|
package/src/SideMenuItem.js
CHANGED
|
@@ -6,6 +6,8 @@ import { jsStyles } from './SideMenu.styles';
|
|
|
6
6
|
import { SideMenuContext } from './SideMenuContext';
|
|
7
7
|
import { SeparatedSubMenu } from './SeparatedSubMenu';
|
|
8
8
|
import { InnerSubMenu } from './InnerSubMenu';
|
|
9
|
+
import { useNumberOfTextLinesInItem } from '../hooks/useNumberOfTextLinesInItem';
|
|
10
|
+
import { isIdActive, isOpenedParents } from '../utils/scripts';
|
|
9
11
|
/**
|
|
10
12
|
* Элемент списка
|
|
11
13
|
*
|
|
@@ -13,59 +15,35 @@ import { InnerSubMenu } from './InnerSubMenu';
|
|
|
13
15
|
*/
|
|
14
16
|
var SideMenuItem = forwardRef(function (_a, ref) {
|
|
15
17
|
var _b, _c, _d, _e, _f, _g;
|
|
16
|
-
var
|
|
18
|
+
var _h;
|
|
19
|
+
var className = _a.className, onClick = _a.onClick, onKeyDown = _a.onKeyDown, icon = _a.icon, _avatar = _a._avatar, marker = _a.marker, caption = _a.caption, id = _a.id, _isSubMenu = _a._isSubMenu, children = _a.children, _isNestedSubMenu = _a._isNestedSubMenu, _generatedId = _a._generatedId, rest = __rest(_a, ["className", "onClick", "onKeyDown", "icon", "_avatar", "marker", "caption", "id", "_isSubMenu", "children", "_isNestedSubMenu", "_generatedId"]);
|
|
17
20
|
var context = useContext(SideMenuContext);
|
|
18
21
|
var textRef = useRef(null);
|
|
19
|
-
var
|
|
20
|
-
var
|
|
21
|
-
var
|
|
22
|
-
var
|
|
23
|
-
var id = useState('id' + Math.floor(Math.random() * 10000))[0];
|
|
24
|
-
var getNumberOfTextLines = function () {
|
|
25
|
-
if (textRef.current) {
|
|
26
|
-
var el = textRef.current;
|
|
27
|
-
var textHeight = +el.offsetHeight;
|
|
28
|
-
var lineHeight = parseInt(window.getComputedStyle(textRef.current).getPropertyValue('line-height'));
|
|
29
|
-
var lines = textHeight / lineHeight;
|
|
30
|
-
if (lines >= 2) {
|
|
31
|
-
setIsMultiline(true);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
};
|
|
22
|
+
var _j = useState(false), isOpened = _j[0], setIsOpened = _j[1];
|
|
23
|
+
var _k = useState(false), isActive = _k[0], setIsActive = _k[1];
|
|
24
|
+
var _l = useState(false), focusedByTab = _l[0], setFocusedByTab = _l[1];
|
|
25
|
+
var _m = useState(false), isMultiline = _m[0], setIsMultiline = _m[1];
|
|
35
26
|
useEffect(function () {
|
|
36
|
-
|
|
37
|
-
});
|
|
27
|
+
useNumberOfTextLinesInItem(textRef, setIsMultiline);
|
|
28
|
+
}, [textRef.current]);
|
|
38
29
|
useEffect(function () {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (_parent) {
|
|
48
|
-
(_a = context.setActiveItem) === null || _a === void 0 ? void 0 : _a.call(context, _parent);
|
|
49
|
-
}
|
|
50
|
-
(_b = context.setActiveSubItem) === null || _b === void 0 ? void 0 : _b.call(context, id);
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
if (!context.isSeparatedMenu) {
|
|
54
|
-
(_c = context.setActiveSubItem) === null || _c === void 0 ? void 0 : _c.call(context, null);
|
|
55
|
-
}
|
|
56
|
-
(_d = context.setActiveItem) === null || _d === void 0 ? void 0 : _d.call(context, id);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
var active = false;
|
|
60
|
-
if (context) {
|
|
61
|
-
active = context.activeItem === id || context.activeSubItem === id;
|
|
62
|
-
}
|
|
30
|
+
var isOpenedParent = isOpenedParents(id, _generatedId, context.openedParents);
|
|
31
|
+
setIsOpened(!!children && (isOpenedParent || isActive));
|
|
32
|
+
}, [(_h = context.openedParents) === null || _h === void 0 ? void 0 : _h.toString(), isActive]);
|
|
33
|
+
useEffect(function () {
|
|
34
|
+
var idIsActive = isIdActive(id, context.activeMenuItem);
|
|
35
|
+
var generatedIdIsActive = isIdActive(_generatedId, context.activeMenuItem);
|
|
36
|
+
setIsActive(idIsActive || generatedIdIsActive);
|
|
37
|
+
}, [context.activeMenuItem]);
|
|
63
38
|
var handleClick = function (e) {
|
|
64
|
-
|
|
65
|
-
|
|
39
|
+
var _a, _b;
|
|
40
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(e);
|
|
41
|
+
if (id) {
|
|
42
|
+
(_a = context.switchActiveMenuItem) === null || _a === void 0 ? void 0 : _a.call(context, id);
|
|
43
|
+
}
|
|
44
|
+
else if (_generatedId) {
|
|
45
|
+
(_b = context.switchActiveMenuItem) === null || _b === void 0 ? void 0 : _b.call(context, _generatedId);
|
|
66
46
|
}
|
|
67
|
-
setActive();
|
|
68
|
-
setIsOpened(!!children);
|
|
69
47
|
};
|
|
70
48
|
var handleFocus = function () {
|
|
71
49
|
requestAnimationFrame(function () {
|
|
@@ -77,35 +55,26 @@ var SideMenuItem = forwardRef(function (_a, ref) {
|
|
|
77
55
|
var handleBlur = function () {
|
|
78
56
|
setFocusedByTab(false);
|
|
79
57
|
};
|
|
80
|
-
var handleKeyDown = function (e) {
|
|
81
|
-
if (e.key === 'Enter') {
|
|
82
|
-
setIsOpened(!isOpened);
|
|
83
|
-
setActive();
|
|
84
|
-
}
|
|
85
|
-
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
|
|
86
|
-
};
|
|
87
58
|
var renderSubMenu = function () {
|
|
88
59
|
if (children && isOpened && !_isSubMenu && !context.isMinimised) {
|
|
89
60
|
if (context.isSeparatedMenu) {
|
|
90
|
-
return React.createElement(SeparatedSubMenu,
|
|
61
|
+
return React.createElement(SeparatedSubMenu, { generatedId: _generatedId }, children);
|
|
91
62
|
}
|
|
92
63
|
else {
|
|
93
|
-
return React.createElement(InnerSubMenu, {
|
|
64
|
+
return React.createElement(InnerSubMenu, { generatedId: _generatedId }, children);
|
|
94
65
|
}
|
|
95
66
|
}
|
|
96
67
|
};
|
|
97
68
|
var hasShortcutImage = icon || _avatar;
|
|
69
|
+
var isOpenedFirstLevelItemInSeparatedMenu = isOpened && !_isSubMenu && context.isSeparatedMenu;
|
|
98
70
|
return (React.createElement("div", null,
|
|
99
71
|
React.createElement("button", __assign({ className: cx((_b = {},
|
|
100
72
|
_b[jsStyles.item()] = true,
|
|
101
73
|
_b[jsStyles.subItem()] = context.isSeparatedMenu && _isSubMenu,
|
|
102
74
|
_b[jsStyles.focusedItem()] = focusedByTab,
|
|
103
|
-
_b[jsStyles.activeItem()] =
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
(active && context.isSeparatedMenu),
|
|
107
|
-
_b[jsStyles.activeSubItem()] = active && context.isSeparatedMenu && _isSubMenu,
|
|
108
|
-
_b), className), onClick: handleClick, onKeyDown: handleKeyDown, tabIndex: 0, onFocus: handleFocus, onBlur: handleBlur, ref: ref }, rest),
|
|
75
|
+
_b[jsStyles.activeItem()] = isActive || isOpenedFirstLevelItemInSeparatedMenu,
|
|
76
|
+
_b[jsStyles.activeSubItem()] = isActive && context.isSeparatedMenu && _isSubMenu,
|
|
77
|
+
_b), className), onClick: handleClick, tabIndex: 0, onFocus: handleFocus, onBlur: handleBlur, ref: ref }, rest),
|
|
109
78
|
React.createElement("div", { className: cx((_c = {},
|
|
110
79
|
_c[jsStyles.itemWrapper()] = true,
|
|
111
80
|
_c[jsStyles.itemMultilineWrapper()] = isMultiline,
|
package/src/SideMenuSubItem.js
CHANGED
|
@@ -1,27 +1,31 @@
|
|
|
1
|
-
import { __assign } from "tslib";
|
|
2
|
-
import React, { forwardRef, useMemo, useState } from 'react';
|
|
1
|
+
import { __assign, __rest } from "tslib";
|
|
2
|
+
import React, { forwardRef, useContext, useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { ArrowCDownIcon16Regular, ArrowCRightIcon16Regular } from '@skbkontur/icons';
|
|
4
4
|
import { SideMenuItem } from './SideMenuItem';
|
|
5
5
|
import { jsStyles } from './SideMenu.styles';
|
|
6
|
+
import { SideMenuContext } from './SideMenuContext';
|
|
7
|
+
import { isIdActive, isOpenedParents } from '../utils/scripts';
|
|
6
8
|
/**
|
|
7
9
|
* Элемент списка второго уровня
|
|
8
10
|
*
|
|
9
11
|
* @visibleName SideMenu.SubItem
|
|
10
12
|
*/
|
|
11
|
-
var SideMenuSubItem = forwardRef(function (
|
|
12
|
-
var
|
|
13
|
+
var SideMenuSubItem = forwardRef(function (_a, ref) {
|
|
14
|
+
var _b;
|
|
15
|
+
var children = _a.children, _generatedId = _a._generatedId, id = _a.id, props = __rest(_a, ["children", "_generatedId", "id"]);
|
|
16
|
+
var _c = useState(false), isOpened = _c[0], setIsOpened = _c[1];
|
|
17
|
+
var context = useContext(SideMenuContext);
|
|
13
18
|
var handleClick = function () {
|
|
14
19
|
setIsOpened(true);
|
|
15
20
|
};
|
|
16
|
-
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
};
|
|
21
|
+
useEffect(function () {
|
|
22
|
+
var isOpenedParent = isOpenedParents(id, _generatedId, context.openedParents);
|
|
23
|
+
var idIsActive = isIdActive(id, context.activeMenuItem);
|
|
24
|
+
var generatedIdIsActive = isIdActive(_generatedId, context.activeMenuItem);
|
|
25
|
+
setIsOpened(isOpenedParent || isOpened || idIsActive || generatedIdIsActive);
|
|
26
|
+
}, [(_b = context.openedParents) === null || _b === void 0 ? void 0 : _b.toString()]);
|
|
23
27
|
var icon = useMemo(function () {
|
|
24
|
-
if (
|
|
28
|
+
if (children) {
|
|
25
29
|
if (isOpened) {
|
|
26
30
|
return React.createElement(ArrowCDownIcon16Regular, null);
|
|
27
31
|
}
|
|
@@ -29,12 +33,22 @@ var SideMenuSubItem = forwardRef(function (props, ref) {
|
|
|
29
33
|
return React.createElement(ArrowCRightIcon16Regular, null);
|
|
30
34
|
}
|
|
31
35
|
}
|
|
32
|
-
}, [isOpened,
|
|
36
|
+
}, [isOpened, children]);
|
|
37
|
+
var levelIndex = 0;
|
|
33
38
|
return (React.createElement("div", { ref: ref },
|
|
34
|
-
React.createElement(SideMenuItem, __assign({ onClick: handleClick,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
React.createElement(SideMenuItem, __assign({ onClick: handleClick,
|
|
40
|
+
/*@ts-expect-error: SideMenuItem should have icon */
|
|
41
|
+
icon: icon, _isSubMenu: true, id: id, _generatedId: _generatedId }, props)),
|
|
42
|
+
children && isOpened && (React.createElement("div", { className: jsStyles.subItemMenu() }, React.Children.map(children, function (child) {
|
|
43
|
+
// @ts-expect-error: accessing private property
|
|
44
|
+
if (React.isValidElement(child) && (child === null || child === void 0 ? void 0 : child.type.__KONTUR_REACT_UI__) === 'SideMenuSubItem') {
|
|
45
|
+
var oldIndex = levelIndex;
|
|
46
|
+
levelIndex++;
|
|
47
|
+
return React.cloneElement(child, {
|
|
48
|
+
_generatedId: _generatedId + "-" + oldIndex,
|
|
49
|
+
_isNestedSubMenu: true,
|
|
50
|
+
ref: ref,
|
|
51
|
+
});
|
|
38
52
|
}
|
|
39
53
|
return child;
|
|
40
54
|
})))));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { FlattedArrayElementType } from '../src/SideMenuBodyChildren';
|
|
3
|
+
export declare const getItemId: (prefix: 'body' | 'footer', id: string | number) => string;
|
|
4
|
+
export declare const getAllParents: (id: string, flattedArrayOfAllElements: FlattedArrayElementType[]) => string[];
|
|
5
|
+
export declare const getElementsChildren: (element: ReactElement, levelIndex: string) => FlattedArrayElementType[];
|
|
6
|
+
export declare const isOpenedParents: (id: string | undefined, generatedId: string | undefined, openedParents: string[] | undefined) => boolean;
|
|
7
|
+
export declare const isIdActive: (id: string | undefined, activeMenuItem: string | undefined | null) => boolean;
|
package/utils/scripts.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React, { isValidElement } from 'react';
|
|
2
|
+
import { isNonNullable } from '@skbkontur/react-ui/lib/utils';
|
|
3
|
+
export var getItemId = function (prefix, id) {
|
|
4
|
+
return prefix + "-" + id;
|
|
5
|
+
};
|
|
6
|
+
export var getAllParents = function (id, flattedArrayOfAllElements) {
|
|
7
|
+
var parentsArray = [];
|
|
8
|
+
var element = flattedArrayOfAllElements.find(function (element) { return element.id === id || element.generatedId === id; });
|
|
9
|
+
if (element && isNonNullable(element.parentId)) {
|
|
10
|
+
parentsArray.push(element.parentId);
|
|
11
|
+
parentsArray.push.apply(parentsArray, getAllParents(element.parentId, flattedArrayOfAllElements));
|
|
12
|
+
}
|
|
13
|
+
else if (element && isNonNullable(element.generatedParentId)) {
|
|
14
|
+
parentsArray.push(element.generatedParentId);
|
|
15
|
+
parentsArray.push.apply(parentsArray, getAllParents(element.generatedParentId, flattedArrayOfAllElements));
|
|
16
|
+
}
|
|
17
|
+
return parentsArray;
|
|
18
|
+
};
|
|
19
|
+
export var getElementsChildren = function (element, levelIndex) {
|
|
20
|
+
var childrenArray = [];
|
|
21
|
+
if (element.props.children) {
|
|
22
|
+
var childLevelIndex_1 = 0;
|
|
23
|
+
React.Children.map(element.props.children, function (child) {
|
|
24
|
+
var isActionableComponent =
|
|
25
|
+
// @ts-expect-error: accessing private property
|
|
26
|
+
child.type.__KONTUR_REACT_UI__ === 'SideMenuItem' ||
|
|
27
|
+
// @ts-expect-error: accessing private property
|
|
28
|
+
child.type.__KONTUR_REACT_UI__ === 'SideMenuSubItem';
|
|
29
|
+
if (isValidElement(child) && isActionableComponent) {
|
|
30
|
+
childrenArray.push({
|
|
31
|
+
id: child.props.id,
|
|
32
|
+
generatedId: levelIndex + "-" + childLevelIndex_1,
|
|
33
|
+
parentId: element.props.id,
|
|
34
|
+
generatedParentId: "" + levelIndex,
|
|
35
|
+
});
|
|
36
|
+
var subChildrenArray = getElementsChildren(child, levelIndex + "-" + childLevelIndex_1);
|
|
37
|
+
childrenArray.push.apply(childrenArray, subChildrenArray);
|
|
38
|
+
childLevelIndex_1++;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return childrenArray;
|
|
43
|
+
};
|
|
44
|
+
export var isOpenedParents = function (id, generatedId, openedParents) {
|
|
45
|
+
if (!openedParents || (openedParents === null || openedParents === void 0 ? void 0 : openedParents.length) === 0) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
if (id) {
|
|
49
|
+
return openedParents.includes(id);
|
|
50
|
+
}
|
|
51
|
+
if (generatedId) {
|
|
52
|
+
return openedParents.includes(generatedId);
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
};
|
|
56
|
+
export var isIdActive = function (id, activeMenuItem) {
|
|
57
|
+
return !!id && !!activeMenuItem && id === activeMenuItem;
|
|
58
|
+
};
|