@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 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,2 @@
1
+ import React from 'react';
2
+ export declare const useNumberOfTextLinesInItem: (textRef: React.RefObject<HTMLDivElement>, setIsMultilineText: React.Dispatch<React.SetStateAction<boolean>>) => void;
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skbkontur/side-menu",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  interface InnerSubMenuProps {
3
3
  children?: React.ReactNode;
4
- id: string;
4
+ generatedId?: string;
5
5
  }
6
6
  declare const InnerSubMenuWithStaticFields: React.ForwardRefExoticComponent<InnerSubMenuProps & React.RefAttributes<HTMLDivElement>> & {
7
7
  __KONTUR_REACT_UI__: string;
@@ -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, id = _a.id;
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
- return React.cloneElement(child, { _parent: id, ref: ref });
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;
@@ -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(null), activeItem = _h[0], setActiveItem = _h[1];
28
- var _j = useState(null), activeSubItem = _j[0], setActiveSubItem = _j[1];
29
- var _k = useState(false), hasScrollBar = _k[0], setHasScrollBar = _k[1];
30
- var _l = useState(false), isTransitioned = _l[0], setIsTransitioned = _l[1];
31
- var _m = useState('#2291ff'), productColor = _m[0], setProductColor = _m[1];
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);
@@ -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 React from 'react';
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
- return (React.createElement(React.Fragment, null, React.Children.map(children, function (child) {
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
  })));
@@ -3,13 +3,12 @@ export interface SideMenuContextType {
3
3
  isTransitioned?: boolean;
4
4
  isSeparatedMenu?: boolean;
5
5
  size?: 'small' | 'large';
6
- activeItem?: string | null;
7
- setActiveItem?: (item: string | null) => void;
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;
@@ -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',
@@ -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' });
@@ -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' });
@@ -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
  }
@@ -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 className = _a.className, onClick = _a.onClick, onKeyDown = _a.onKeyDown, icon = _a.icon, _avatar = _a._avatar, marker = _a.marker, caption = _a.caption, _parent = _a._parent, _isSubMenu = _a._isSubMenu, children = _a.children, _isNestedSubMenu = _a._isNestedSubMenu, rest = __rest(_a, ["className", "onClick", "onKeyDown", "icon", "_avatar", "marker", "caption", "_parent", "_isSubMenu", "children", "_isNestedSubMenu"]);
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 _h = useState(false), isOpened = _h[0], setIsOpened = _h[1];
20
- var _j = useState(false), focusedByTab = _j[0], setFocusedByTab = _j[1];
21
- var _k = useState(false), isMultiline = _k[0], setIsMultiline = _k[1];
22
- var _l = useState(context), oldContext = _l[0], setOldContext = _l[1];
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
- getNumberOfTextLines();
37
- });
27
+ useNumberOfTextLinesInItem(textRef, setIsMultiline);
28
+ }, [textRef.current]);
38
29
  useEffect(function () {
39
- if (oldContext.activeItem !== context.activeItem && context.activeItem !== id) {
40
- setIsOpened(false);
41
- }
42
- setOldContext(context);
43
- }, [context.activeItem]);
44
- var setActive = function () {
45
- var _a, _b, _c, _d;
46
- if (_isSubMenu) {
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
- if (onClick) {
65
- onClick(e);
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, null, children);
61
+ return React.createElement(SeparatedSubMenu, { generatedId: _generatedId }, children);
91
62
  }
92
63
  else {
93
- return React.createElement(InnerSubMenu, { id: id }, children);
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()] = (active && !isOpened) ||
104
- (active && isOpened && !context.activeSubItem) ||
105
- (active && isOpened && _isSubMenu) ||
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,
@@ -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 (props, ref) {
12
- var _a = useState(false), isOpened = _a[0], setIsOpened = _a[1];
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
- var handleKeyDown = function (e) {
17
- var _a;
18
- if (e.key === 'Enter') {
19
- setIsOpened(true);
20
- }
21
- (_a = props.onKeyDown) === null || _a === void 0 ? void 0 : _a.call(props, e);
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 (props.children) {
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, props.children]);
36
+ }, [isOpened, children]);
37
+ var levelIndex = 0;
33
38
  return (React.createElement("div", { ref: ref },
34
- React.createElement(SideMenuItem, __assign({ onClick: handleClick, icon: icon, _isSubMenu: true, onKeyDown: handleKeyDown }, props)),
35
- props.children && isOpened && (React.createElement("div", { className: jsStyles.subItemMenu() }, React.Children.map(props.children, function (child) {
36
- if (React.isValidElement(child)) {
37
- return React.cloneElement(child, { _isNestedSubMenu: true });
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;
@@ -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
+ };