@skbkontur/side-menu 1.12.9 → 2.0.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 (50) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +61 -195
  3. package/SideMenuDataTids.d.ts +1 -0
  4. package/SideMenuDataTids.js +1 -0
  5. package/hooks/useAnimateOnMount.js +3 -2
  6. package/lib/theming/ThemeHelpers.js +14 -3
  7. package/lib/utils/scripts.d.ts +2 -10
  8. package/lib/utils/scripts.js +3 -75
  9. package/package.json +2 -2
  10. package/src/Navigation.d.ts +50 -0
  11. package/src/Navigation.js +150 -0
  12. package/src/SideMenu/SideMenu.d.ts +8 -0
  13. package/src/SideMenu/SideMenu.js +53 -34
  14. package/src/SideMenu/SideMenu.styles.d.ts +1 -0
  15. package/src/SideMenu/SideMenu.styles.js +5 -2
  16. package/src/SideMenuBody/SideMenuBody.js +7 -9
  17. package/src/SideMenuContext.d.ts +2 -9
  18. package/src/SideMenuDropdown/SideMenuDropdown.d.ts +1 -3
  19. package/src/SideMenuDropdown/SideMenuDropdown.js +1 -1
  20. package/src/SideMenuFooter/SideMenuFooter.js +3 -11
  21. package/src/SideMenuHeader/SideMenuHeader.js +3 -2
  22. package/src/SideMenuSubItem/SideMenuSubItem.js +3 -16
  23. package/src/SideMenuSubLink/SideMenuSubLink.js +4 -17
  24. package/src/Tree.d.ts +17 -0
  25. package/src/Tree.js +133 -0
  26. package/src/internal/BackButton.d.ts +0 -1
  27. package/src/internal/BackButton.js +3 -15
  28. package/src/internal/ClickableElement.d.ts +1 -5
  29. package/src/internal/ClickableElement.js +48 -45
  30. package/src/internal/InnerSubMenu.d.ts +1 -1
  31. package/src/internal/InnerSubMenu.js +10 -19
  32. package/src/internal/ItemContent/Caption.d.ts +2 -1
  33. package/src/internal/ItemContent/Caption.js +6 -5
  34. package/src/internal/ItemContent/ItemContent.d.ts +3 -1
  35. package/src/internal/ItemContent/ItemContent.js +6 -4
  36. package/src/internal/NestedMenu.d.ts +2 -2
  37. package/src/internal/NestedMenu.js +6 -16
  38. package/src/internal/SeparatedSubMenu.d.ts +2 -3
  39. package/src/internal/SeparatedSubMenu.js +17 -43
  40. package/src/internal/SideMenuLogotype.js +3 -3
  41. package/src/internal/SubMenu.d.ts +1 -4
  42. package/src/internal/SubMenu.js +8 -10
  43. package/hooks/useActiveState.d.ts +0 -1
  44. package/hooks/useActiveState.js +0 -12
  45. package/hooks/useOpenedState.d.ts +0 -2
  46. package/hooks/useOpenedState.js +0 -14
  47. package/hooks/useOpenedSubElementState.d.ts +0 -1
  48. package/hooks/useOpenedSubElementState.js +0 -12
  49. package/src/internal/InnerBody.d.ts +0 -14
  50. package/src/internal/InnerBody.js +0 -108
@@ -0,0 +1,150 @@
1
+ import { __read, __spread } from "tslib";
2
+ import { SideMenuDataTids } from '../SideMenuDataTids';
3
+ import { Tree } from './Tree';
4
+ var MENU_ROOT_ID = 'menu-root-id';
5
+ export var navigationAttribute = 'data-navigation-id';
6
+ export var navigationAttributeForSeparatedMenu = 'data-parent-navigation-id';
7
+ var MenuNavigation = /** @class */ (function () {
8
+ function MenuNavigation(options) {
9
+ this.navigationTree = null;
10
+ this.navigationTree = new Tree(MENU_ROOT_ID);
11
+ this.activeMenuItemTreeNode = this.navigationTree.find(options.activeMenuItem);
12
+ this.rootRef = options.rootRef;
13
+ this.activeMenuItem = options.activeMenuItem;
14
+ this.setActiveMenuItem = options.setActiveMenuItem;
15
+ this.isSeparatedMenu = options.isSeparatedMenu;
16
+ this.isSeparatedMenuShown = options.isSeparatedMenuShown;
17
+ this.setIsSeparatedMenuShown = options.setIsSeparatedMenuShown;
18
+ this.isOpened = options.isOpened;
19
+ this.isDesktop = options.isDesktopQuery;
20
+ this.isMobile = options.isMobile;
21
+ this.isCollapsable = options.isCollapsable;
22
+ }
23
+ MenuNavigation.prototype.updateNavigationTree = function () {
24
+ var _this = this;
25
+ var _a;
26
+ if ((_a = this.rootRef) === null || _a === void 0 ? void 0 : _a.current) {
27
+ var menuItems = Array.from(this.rootRef.current.querySelectorAll("[data-tid=" + SideMenuDataTids.clickableElement + "]")).filter(function (item) { return !item.querySelector("button[data-tid=" + SideMenuDataTids.backButton + "]"); });
28
+ menuItems.forEach(function (menuItem) {
29
+ var _a, _b, _c;
30
+ var id = menuItem.getAttribute(navigationAttribute);
31
+ var parentId = _this.getParentId(menuItem);
32
+ var oldValue = (_b = (_a = _this.navigationTree) === null || _a === void 0 ? void 0 : _a.find(id)) === null || _b === void 0 ? void 0 : _b.value;
33
+ (_c = _this.navigationTree) === null || _c === void 0 ? void 0 : _c.insert(parentId, id, oldValue);
34
+ });
35
+ }
36
+ };
37
+ MenuNavigation.prototype.addValue = function (id, value) {
38
+ var _a, _b, _c;
39
+ this.updateNavigationTree();
40
+ var foundTreeNode = (_a = this.navigationTree) === null || _a === void 0 ? void 0 : _a.find(id);
41
+ if (foundTreeNode) {
42
+ foundTreeNode.value = value;
43
+ }
44
+ if ((foundTreeNode === null || foundTreeNode === void 0 ? void 0 : foundTreeNode.parent) && foundTreeNode.parent.parent && foundTreeNode.parent.parent.id !== MENU_ROOT_ID) {
45
+ (_b = foundTreeNode.value) === null || _b === void 0 ? void 0 : _b.setIsNestedSubMenu(true);
46
+ }
47
+ if (this.isSeparatedMenu && (foundTreeNode === null || foundTreeNode === void 0 ? void 0 : foundTreeNode.hasChildren)) {
48
+ (_c = foundTreeNode.value) === null || _c === void 0 ? void 0 : _c.setHasSubIcons(true);
49
+ }
50
+ };
51
+ MenuNavigation.prototype.switchActiveMenuItem = function (id, isButton) {
52
+ var _a, _b, _c, _d;
53
+ !isButton &&
54
+ __spread((_a = this.navigationTree) === null || _a === void 0 ? void 0 : _a.preOrderTraversal()).map(function (x) {
55
+ var _a;
56
+ (_a = x.value) === null || _a === void 0 ? void 0 : _a.setIsActive(false);
57
+ });
58
+ var foundTreeNode = (_b = this.navigationTree) === null || _b === void 0 ? void 0 : _b.find(id);
59
+ var oldFirstLevelParent = this.getFirstLevelParent(this.activeMenuItemTreeNode);
60
+ var firstLevelParent = this.getFirstLevelParent(foundTreeNode);
61
+ var firstLevelParentChanged = oldFirstLevelParent !== firstLevelParent;
62
+ if (foundTreeNode) {
63
+ if (!isButton) {
64
+ this.activeMenuItem = foundTreeNode.id;
65
+ this.activeMenuItemTreeNode = foundTreeNode;
66
+ (_c = this.setActiveMenuItem) === null || _c === void 0 ? void 0 : _c.call(this, foundTreeNode.id);
67
+ this.setHighlightedFirstLevelMenuItemInMinimizedInnerMenu(firstLevelParent);
68
+ (_d = foundTreeNode.value) === null || _d === void 0 ? void 0 : _d.setIsActive(true);
69
+ }
70
+ this.isSeparatedMenu && this.switchVisibilityOfSeparatedMenu();
71
+ this.openMenuItems(foundTreeNode, firstLevelParentChanged);
72
+ }
73
+ };
74
+ MenuNavigation.prototype.switchIsSeparatedMenu = function (value) {
75
+ this.isSeparatedMenu = value;
76
+ this.switchVisibilityOfSeparatedMenu();
77
+ };
78
+ MenuNavigation.prototype.setHighlightedFirstLevelMenuItemInMinimizedInnerMenu = function (firstLevelParent) {
79
+ var _a, _b;
80
+ __spread((_a = this.navigationTree) === null || _a === void 0 ? void 0 : _a.preOrderTraversal()).map(function (x) {
81
+ var _a;
82
+ (_a = x.value) === null || _a === void 0 ? void 0 : _a.setIsFirstLevelParentOfActiveMenuItem(false);
83
+ });
84
+ (_b = firstLevelParent === null || firstLevelParent === void 0 ? void 0 : firstLevelParent.value) === null || _b === void 0 ? void 0 : _b.setIsFirstLevelParentOfActiveMenuItem(true);
85
+ };
86
+ MenuNavigation.prototype.getFirstLevelParent = function (treeNode) {
87
+ if (!treeNode)
88
+ return;
89
+ var parentTreeNode = treeNode.parent;
90
+ while (parentTreeNode) {
91
+ var foundNode = parentTreeNode.parent;
92
+ if ((foundNode === null || foundNode === void 0 ? void 0 : foundNode.id) === MENU_ROOT_ID) {
93
+ break;
94
+ }
95
+ parentTreeNode = foundNode;
96
+ }
97
+ return parentTreeNode;
98
+ };
99
+ MenuNavigation.prototype.openMenuItems = function (treeNode, firstLevelParentChanged) {
100
+ var _a, _b, _c;
101
+ (!((_a = treeNode.value) === null || _a === void 0 ? void 0 : _a.isSubMenu) || firstLevelParentChanged) &&
102
+ __spread((_b = this.navigationTree) === null || _b === void 0 ? void 0 : _b.preOrderTraversal()).map(function (x) { var _a; return (_a = x.value) === null || _a === void 0 ? void 0 : _a.setIsOpened(false); });
103
+ if (treeNode.children.length > 0) {
104
+ (_c = treeNode.value) === null || _c === void 0 ? void 0 : _c.setIsOpened(true);
105
+ }
106
+ this.openAllParents(treeNode);
107
+ };
108
+ MenuNavigation.prototype.openAllParents = function (treeNode) {
109
+ var _a;
110
+ var parentTreeNode = treeNode.parent;
111
+ while (parentTreeNode && parentTreeNode.id !== MENU_ROOT_ID) {
112
+ (_a = parentTreeNode.value) === null || _a === void 0 ? void 0 : _a.setIsOpened(true);
113
+ parentTreeNode = parentTreeNode.parent;
114
+ }
115
+ };
116
+ MenuNavigation.prototype.getParentId = function (menuItem) {
117
+ var _a, _b, _c;
118
+ var parentElement;
119
+ var clickableElementSelector = "[data-tid=" + SideMenuDataTids.clickableElement + "]";
120
+ var separatedMenuSelector = "[data-tid=" + SideMenuDataTids.separatedSubMenu + "]";
121
+ parentElement = (_a = menuItem.parentElement) === null || _a === void 0 ? void 0 : _a.closest(clickableElementSelector);
122
+ if (!parentElement) {
123
+ var separatedMenu = menuItem.closest(separatedMenuSelector);
124
+ if (separatedMenu) {
125
+ var firstLevelMenuId = separatedMenu.getAttribute(navigationAttributeForSeparatedMenu);
126
+ parentElement = (_c = (_b = this.rootRef) === null || _b === void 0 ? void 0 : _b.current) === null || _c === void 0 ? void 0 : _c.querySelector("[" + navigationAttribute + "=\"" + firstLevelMenuId + "\"]");
127
+ }
128
+ }
129
+ return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.getAttribute(navigationAttribute)) || MENU_ROOT_ID;
130
+ };
131
+ MenuNavigation.prototype.switchVisibilityOfSeparatedMenu = function () {
132
+ var _a, _b, _c, _d, _e, _f;
133
+ if (!this.isSeparatedMenu) {
134
+ this.isSeparatedMenuShown = false;
135
+ return (_a = this.setIsSeparatedMenuShown) === null || _a === void 0 ? void 0 : _a.call(this, false);
136
+ }
137
+ var activeItemHasParent = (_c = (_b = this.activeMenuItemTreeNode) === null || _b === void 0 ? void 0 : _b.value) === null || _c === void 0 ? void 0 : _c.isSubMenu;
138
+ var activeMenuItemHasChildren = (_d = this.activeMenuItemTreeNode) === null || _d === void 0 ? void 0 : _d.hasChildren;
139
+ var isActive = activeItemHasParent || activeMenuItemHasChildren || false;
140
+ var isMinimizedInWideDesktop = !this.isOpened && this.isDesktop && !this.isCollapsable;
141
+ if (this.isMobile && !activeItemHasParent && this.isSeparatedMenuShown) {
142
+ this.isSeparatedMenuShown = false;
143
+ return (_e = this.setIsSeparatedMenuShown) === null || _e === void 0 ? void 0 : _e.call(this, false);
144
+ }
145
+ this.isSeparatedMenuShown = isActive && !isMinimizedInWideDesktop;
146
+ (_f = this.setIsSeparatedMenuShown) === null || _f === void 0 ? void 0 : _f.call(this, this.isSeparatedMenuShown);
147
+ };
148
+ return MenuNavigation;
149
+ }());
150
+ export { MenuNavigation };
@@ -25,8 +25,16 @@ export interface SideMenuProps extends CommonProps {
25
25
  * Заблокировать возможность сворачивания меню до иконок на широких экранах
26
26
  */
27
27
  disableCollapsing?: boolean;
28
+ /**
29
+ * @deprecated use activeItem
30
+ */
28
31
  value?: string;
32
+ /**
33
+ * @deprecated use onActiveItemChange
34
+ */
29
35
  onValueChange?: (value: string) => void;
36
+ activeItem?: string;
37
+ onActiveItemChange?: (value: string) => void;
30
38
  desktopMediaQuery?: string;
31
39
  narrowDesktopMediaQuery?: string;
32
40
  tabletMediaQuery?: string;
@@ -1,4 +1,4 @@
1
- import { __assign, __rest } from "tslib";
1
+ import { __assign, __read, __rest } from "tslib";
2
2
  import React, { forwardRef, useContext, useEffect, useRef, useState } from 'react';
3
3
  import { cx } from '@skbkontur/react-ui/lib/theming/Emotion';
4
4
  import { isIE11 } from '@skbkontur/react-ui/lib/client';
@@ -27,15 +27,18 @@ import { ZIndex } from '@skbkontur/react-ui/internal/ZIndex';
27
27
  import { useAnimateOnMount } from '../../hooks/useAnimateOnMount';
28
28
  import { getSideMenuTheme } from '../../lib/theming/ThemeHelpers';
29
29
  import { mergeRefs } from '@skbkontur/react-ui/lib/utils';
30
+ import { MenuNavigation } from '../Navigation';
30
31
  export var transitionDuration = 300; //ms
31
32
  export var burgerTransitionDuration = (transitionDuration * 2) / 3;
32
33
  var SideMenuInner = forwardRef(function (_a, ref) {
33
34
  var _b, _c, _d, _e;
34
- var children = _a.children, value = _a.value, onValueChange = _a.onValueChange, _f = _a.size, size = _f === void 0 ? 'small' : _f, _g = _a.isSeparatedMenu, isSeparatedMenu = _g === void 0 ? false : _g, className = _a.className, _h = _a.disableSwipe, disableSwipe = _h === void 0 ? false : _h, _j = _a.disableCollapsing, disableCollapsing = _j === void 0 ? false : _j, desktopMediaQuery = _a.desktopMediaQuery, narrowDesktopMediaQuery = _a.narrowDesktopMediaQuery, tabletMediaQuery = _a.tabletMediaQuery, mobileMediaQuery = _a.mobileMediaQuery, _k = _a.hideScrollBar, hideScrollBar = _k === void 0 ? undefined : _k, _l = _a.showScrollBar, showScrollBar = _l === void 0 ? 'hover' : _l, isOpen = _a.isOpen, onOpen = _a.onOpen, onClose = _a.onClose, rest = __rest(_a, ["children", "value", "onValueChange", "size", "isSeparatedMenu", "className", "disableSwipe", "disableCollapsing", "desktopMediaQuery", "narrowDesktopMediaQuery", "tabletMediaQuery", "mobileMediaQuery", "hideScrollBar", "showScrollBar", "isOpen", "onOpen", "onClose"]);
35
+ var _f, _g;
36
+ var children = _a.children, value = _a.value, onValueChange = _a.onValueChange, activeItem = _a.activeItem, onActiveItemChange = _a.onActiveItemChange, _h = _a.size, size = _h === void 0 ? 'small' : _h, _j = _a.isSeparatedMenu, isSeparatedMenu = _j === void 0 ? false : _j, className = _a.className, _k = _a.disableSwipe, disableSwipe = _k === void 0 ? false : _k, _l = _a.disableCollapsing, disableCollapsing = _l === void 0 ? false : _l, desktopMediaQuery = _a.desktopMediaQuery, narrowDesktopMediaQuery = _a.narrowDesktopMediaQuery, tabletMediaQuery = _a.tabletMediaQuery, mobileMediaQuery = _a.mobileMediaQuery, _m = _a.hideScrollBar, hideScrollBar = _m === void 0 ? undefined : _m, _o = _a.showScrollBar, showScrollBar = _o === void 0 ? 'hover' : _o, isOpen = _a.isOpen, onOpen = _a.onOpen, onClose = _a.onClose, rest = __rest(_a, ["children", "value", "onValueChange", "activeItem", "onActiveItemChange", "size", "isSeparatedMenu", "className", "disableSwipe", "disableCollapsing", "desktopMediaQuery", "narrowDesktopMediaQuery", "tabletMediaQuery", "mobileMediaQuery", "hideScrollBar", "showScrollBar", "isOpen", "onOpen", "onClose"]);
35
37
  var transitionTimer = useRef(null);
36
38
  var sideMenuRef = useRef(null);
37
39
  var contentWrapperRef = useRef(null);
38
40
  var scrollContainerRef = useRef(null);
41
+ var navigation = useRef(null);
39
42
  var theme = getSideMenuTheme(useContext(ThemeContext));
40
43
  var customMediaQueries = {
41
44
  isMobileQuery: mobileMediaQuery || theme.sideMenuMobileMediaQuery,
@@ -43,31 +46,49 @@ var SideMenuInner = forwardRef(function (_a, ref) {
43
46
  isNarrowDesktopQuery: narrowDesktopMediaQuery || theme.sideMenuNarrowDesktopMediaQuery,
44
47
  isDesktopQuery: desktopMediaQuery || theme.sideMenuDesktopMediaQuery,
45
48
  };
46
- var _m = useResponsiveLayout({
49
+ var _p = useResponsiveLayout({
47
50
  customMediaQueries: customMediaQueries,
48
- }), isMobileQuery = _m.isMobileQuery, isTabletQuery = _m.isTabletQuery, isNarrowDesktopQuery = _m.isNarrowDesktopQuery, isDesktopQuery = _m.isDesktopQuery;
51
+ }), isMobileQuery = _p.isMobileQuery, isTabletQuery = _p.isTabletQuery, isNarrowDesktopQuery = _p.isNarrowDesktopQuery, isDesktopQuery = _p.isDesktopQuery;
49
52
  var isNarrowDesktop = isNarrowDesktopQuery && !isDesktopQuery;
50
53
  var isTablet = isTabletQuery && !isNarrowDesktopQuery;
51
54
  var isMobile = isMobileQuery && !isTabletQuery;
52
55
  var isTabletOrMobile = isTablet || isMobile;
53
56
  var isTouchScreen = isTouchDevice() || isMobile || isTablet;
54
57
  var manual = isOpen !== undefined;
55
- var _o = useState(isDesktopQuery), isOpened = _o[0], setIsOpened = _o[1];
56
- var _p = useState(false), isBeingTransitioned = _p[0], setIsBeingTransitioned = _p[1];
57
- var _q = useState(value), activeMenuItem = _q[0], setActiveMenuItem = _q[1];
58
- var _r = useState(null), clickedButton = _r[0], setClickedButton = _r[1];
59
- var _s = useState(false), isSeparatedMenuShown = _s[0], setIsSeparatedMenuShown = _s[1];
60
- var _t = useState(true), isMouseOutside = _t[0], setIsMouseOutside = _t[1];
61
- var _u = useState('top'), scrollState = _u[0], setScrollState = _u[1];
62
- var _v = useState(false), hasScrollBar = _v[0], setHasScrollBar = _v[1];
63
- var _w = useState(0), mousePositionX = _w[0], setMousePositionX = _w[1];
64
- var _x = useState(0), headerHeight = _x[0], setHeaderHeight = _x[1];
65
- var _y = useState(isNarrowDesktop), isCollapsable = _y[0], setIsCollapsable = _y[1];
66
- var _z = useState(0), leftPosition = _z[0], setLeftPosition = _z[1];
67
- var _0 = useState(false), isHovered = _0[0], setIsHovered = _0[1];
58
+ var _q = __read(useState(isDesktopQuery), 2), isOpened = _q[0], setIsOpened = _q[1];
59
+ var _r = __read(useState(false), 2), isBeingTransitioned = _r[0], setIsBeingTransitioned = _r[1];
60
+ var _s = __read(useState(value !== null && value !== void 0 ? value : activeItem), 2), activeMenuItem = _s[0], setActiveMenuItem = _s[1];
61
+ var _t = __read(useState(false), 2), isSeparatedMenuShown = _t[0], setIsSeparatedMenuShown = _t[1];
62
+ var _u = __read(useState(true), 2), isMouseOutside = _u[0], setIsMouseOutside = _u[1];
63
+ var _v = __read(useState('top'), 2), scrollState = _v[0], setScrollState = _v[1];
64
+ var _w = __read(useState(false), 2), hasScrollBar = _w[0], setHasScrollBar = _w[1];
65
+ var _x = __read(useState(0), 2), mousePositionX = _x[0], setMousePositionX = _x[1];
66
+ var _y = __read(useState(0), 2), headerHeight = _y[0], setHeaderHeight = _y[1];
67
+ var _z = __read(useState(isNarrowDesktop), 2), isCollapsable = _z[0], setIsCollapsable = _z[1];
68
+ var _0 = __read(useState(0), 2), leftPosition = _0[0], setLeftPosition = _0[1];
69
+ var _1 = __read(useState(false), 2), isHovered = _1[0], setIsHovered = _1[1];
70
+ var switchActiveMenuItem = function (id) {
71
+ if (id !== value && id !== activeItem) {
72
+ onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(id);
73
+ onActiveItemChange === null || onActiveItemChange === void 0 ? void 0 : onActiveItemChange(id);
74
+ setActiveMenuItem(id);
75
+ }
76
+ };
68
77
  useEffect(function () {
69
78
  var _a;
70
79
  setLeftPosition(((_a = sideMenuRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().left) || 0);
80
+ navigation.current = new MenuNavigation({
81
+ rootRef: sideMenuRef,
82
+ activeMenuItem: activeMenuItem,
83
+ setActiveMenuItem: switchActiveMenuItem,
84
+ isSeparatedMenu: isSeparatedMenu,
85
+ isSeparatedMenuShown: isSeparatedMenuShown,
86
+ setIsSeparatedMenuShown: setIsSeparatedMenuShown,
87
+ isOpened: isOpened,
88
+ isDesktopQuery: isDesktopQuery,
89
+ isMobile: isMobile,
90
+ isCollapsable: isCollapsable,
91
+ });
71
92
  return function () {
72
93
  if (transitionTimer.current) {
73
94
  clearTimeout(transitionTimer.current);
@@ -108,8 +129,17 @@ var SideMenuInner = forwardRef(function (_a, ref) {
108
129
  isNarrowDesktop && setIsCollapsable(true);
109
130
  }, [isNarrowDesktop, isDesktopQuery, isTablet, isMobile]);
110
131
  useEffect(function () {
111
- setActiveMenuItem(value);
112
- }, [value]);
132
+ var _a;
133
+ !activeItem && ((_a = navigation.current) === null || _a === void 0 ? void 0 : _a.switchActiveMenuItem(value));
134
+ }, [value, (_f = navigation.current) === null || _f === void 0 ? void 0 : _f.navigationTree]);
135
+ useEffect(function () {
136
+ var _a;
137
+ !value && ((_a = navigation.current) === null || _a === void 0 ? void 0 : _a.switchActiveMenuItem(activeItem));
138
+ }, [activeItem, (_g = navigation.current) === null || _g === void 0 ? void 0 : _g.navigationTree]);
139
+ useEffect(function () {
140
+ var _a;
141
+ (_a = navigation.current) === null || _a === void 0 ? void 0 : _a.switchIsSeparatedMenu(isSeparatedMenu);
142
+ }, [isSeparatedMenu]);
113
143
  useEffect(function () {
114
144
  handleIsOpened(isOpen, manual);
115
145
  }, [isOpen]);
@@ -122,7 +152,7 @@ var SideMenuInner = forwardRef(function (_a, ref) {
122
152
  }
123
153
  transitionTimer.current = setTimeout(function () {
124
154
  setIsBeingTransitioned(false);
125
- }, transitionDuration);
155
+ }, transitionDuration + 200);
126
156
  }
127
157
  };
128
158
  var handleMouseEnter = function () {
@@ -157,12 +187,6 @@ var SideMenuInner = forwardRef(function (_a, ref) {
157
187
  }
158
188
  setMousePositionX(relativeXCoordinate);
159
189
  };
160
- var switchActiveMenuItem = function (id) {
161
- if (id !== value) {
162
- onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(id);
163
- setActiveMenuItem(id);
164
- }
165
- };
166
190
  var showMenu = function (newIsShown) {
167
191
  if (!isTabletOrMobile)
168
192
  return;
@@ -178,11 +202,11 @@ var SideMenuInner = forwardRef(function (_a, ref) {
178
202
  }
179
203
  };
180
204
  var isSideMenuOverContent = (isCollapsable || isMobile || (isTablet && !isSeparatedMenuShown)) && isOpened;
181
- var _1 = useAnimateOnMount(!!isTabletOrMobile && !!isOpened, burgerTransitionDuration, {
205
+ var _2 = __read(useAnimateOnMount(!!isTabletOrMobile && !!isOpened, burgerTransitionDuration, {
182
206
  opacity: DEFAULT_THEME.sidePageBackingBgOpacity,
183
207
  }, {
184
208
  opacity: 0,
185
- }), shouldShowBackdrop = _1[0], backdropStyle = _1[1];
209
+ }), 2), shouldShowBackdrop = _2[0], backdropStyle = _2[1];
186
210
  var isSideMenuOverflowing = (isTabletOrMobile || isCollapsable) && isOpened;
187
211
  var setScrollBar = function () {
188
212
  var isSeparatedMenuShownInMobile = isMobile && isSeparatedMenuShown;
@@ -208,17 +232,11 @@ var SideMenuInner = forwardRef(function (_a, ref) {
208
232
  isBeingTransitioned: isBeingTransitioned,
209
233
  isSeparatedMenu: isSeparatedMenu,
210
234
  size: size,
211
- activeMenuItem: activeMenuItem,
212
- switchActiveMenuItem: switchActiveMenuItem,
213
- clickedButton: clickedButton,
214
- setClickedButton: setClickedButton,
215
235
  isDesktop: isDesktopQuery,
216
236
  isNarrowDesktop: isNarrowDesktop,
217
237
  isTablet: isTablet,
218
238
  isMobile: isMobile,
219
239
  isTouchScreen: isTouchScreen,
220
- isSeparatedMenuShown: isSeparatedMenuShown,
221
- setIsSeparatedMenuShown: setIsSeparatedMenuShown,
222
240
  setIsMouseOutside: setIsMouseOutside,
223
241
  scrollState: scrollState,
224
242
  setScrollState: setScrollState,
@@ -229,6 +247,7 @@ var SideMenuInner = forwardRef(function (_a, ref) {
229
247
  hideScrollBar: hideScrollBar,
230
248
  showScrollBar: showScrollBar,
231
249
  sideMenuRef: sideMenuRef,
250
+ navigation: navigation.current,
232
251
  } },
233
252
  (isOpened || isBeingTransitioned) && isTabletOrMobile && React.createElement("div", { style: { height: headerHeight } }),
234
253
  React.createElement(ZIndex, { priority: isSideMenuOverflowing ? 8 : 0, className: cx((_b = {},
@@ -23,4 +23,5 @@ export declare const jsStylesForSideMenu: {
23
23
  wrapperWithShadow(t: SideMenuTheme): string;
24
24
  collapsedContainerForTabletsOrMobiles(): string;
25
25
  list(): string;
26
+ hidden(): string;
26
27
  };
@@ -64,11 +64,14 @@ var styles = {
64
64
  list: function () {
65
65
  return css(templateObject_20 || (templateObject_20 = __makeTemplateObject(["\n list-style: none;\n padding: 0;\n margin: 0;\n "], ["\n list-style: none;\n padding: 0;\n margin: 0;\n "])));
66
66
  },
67
+ hidden: function () {
68
+ return css(templateObject_21 || (templateObject_21 = __makeTemplateObject(["\n display: none;\n "], ["\n display: none;\n "])));
69
+ },
67
70
  };
68
71
  export var customStyles = {
69
72
  rootForTabletsOrMobiles: function (headerHeight) {
70
- return css(templateObject_21 || (templateObject_21 = __makeTemplateObject(["\n height: ", "px;\n top: 0;\n transition: height ", "ms ease-out;\n "], ["\n height: ", "px;\n top: 0;\n transition: height ", "ms ease-out;\n "])), headerHeight, burgerTransitionDuration);
73
+ return css(templateObject_22 || (templateObject_22 = __makeTemplateObject(["\n height: ", "px;\n top: 0;\n transition: height ", "ms ease-out;\n "], ["\n height: ", "px;\n top: 0;\n transition: height ", "ms ease-out;\n "])), headerHeight, burgerTransitionDuration);
71
74
  },
72
75
  };
73
76
  export var jsStylesForSideMenu = memoizeStyle(styles);
74
- var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21;
77
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22;
@@ -3,22 +3,20 @@ import React, { forwardRef, useContext } from 'react';
3
3
  import { cx } from '@skbkontur/react-ui/lib/theming/Emotion';
4
4
  import { ThemeContext } from '@skbkontur/react-ui/lib/theming/ThemeContext';
5
5
  import { jsStyles } from './SideMenuBody.styles';
6
- import { InnerBody } from '../internal/InnerBody';
7
6
  import { SideMenuContext } from '../SideMenuContext';
8
7
  import { getSideMenuTheme } from '../../lib/theming/ThemeHelpers';
9
8
  import { jsStylesForSideMenu } from '../SideMenu/SideMenu.styles';
10
9
  var SideMenuBodyInner = forwardRef(function (_a, ref) {
11
- var _b;
10
+ var _b, _c;
12
11
  var className = _a.className, children = _a.children, rest = __rest(_a, ["className", "children"]);
13
12
  var context = useContext(SideMenuContext);
14
13
  var theme = getSideMenuTheme(useContext(ThemeContext));
15
- if (!(context.isMobile || context.isTablet) || (context.isOpened && (context.isMobile || context.isTablet))) {
16
- return (React.createElement("div", { ref: ref, className: cx(jsStyles.root(theme), className) },
17
- React.createElement("nav", null,
18
- React.createElement("ul", __assign({ className: cx((_b = {}, _b[jsStylesForSideMenu.list()] = true, _b[jsStyles.wrapper(theme)] = true, _b)) }, rest),
19
- React.createElement(InnerBody, null, children)))));
20
- }
21
- return null;
14
+ return (React.createElement("div", { ref: ref, className: cx((_b = {},
15
+ _b[jsStyles.root(theme)] = true,
16
+ _b[jsStylesForSideMenu.hidden()] = !context.isOpened && (context.isMobile || context.isTablet),
17
+ _b)) },
18
+ React.createElement("nav", null,
19
+ React.createElement("ul", __assign({ className: cx((_c = {}, _c[jsStylesForSideMenu.list()] = true, _c[jsStyles.wrapper(theme)] = true, _c)) }, rest), children))));
22
20
  });
23
21
  SideMenuBodyInner.displayName = 'SideMenuBody';
24
22
  /**
@@ -1,17 +1,12 @@
1
1
  import { RefObject } from 'react';
2
- import { FlattedArrayElementType } from './internal/InnerBody';
3
2
  import { ScrollContainerScrollStateY } from '@skbkontur/react-ui';
4
3
  import { showScrollBarType } from './SideMenu/SideMenu';
4
+ import { MenuNavigation } from './Navigation';
5
5
  export interface SideMenuContextType {
6
6
  isBeingTransitioned?: boolean;
7
7
  isSeparatedMenu?: boolean;
8
8
  size?: 'small' | 'large';
9
- activeMenuItem?: string | null;
10
- switchActiveMenuItem?: (id: string) => void;
11
- clickedButton?: string | null;
12
- setClickedButton?: (id: string | null) => void;
13
9
  hasSubIcons?: boolean;
14
- openedParents?: string[];
15
10
  isDesktop?: boolean;
16
11
  isNarrowDesktop?: boolean;
17
12
  isTablet?: boolean;
@@ -21,9 +16,6 @@ export interface SideMenuContextType {
21
16
  isCollapsable?: boolean;
22
17
  toggleIsOpened?: () => void;
23
18
  setIsMinimized?: (isMinimized: boolean) => void;
24
- flattedArrayOfAllElements?: FlattedArrayElementType[];
25
- isSeparatedMenuShown?: boolean;
26
- setIsSeparatedMenuShown?: (separatedMenuIsShown: boolean) => void;
27
19
  setIsMouseOutside?: (v: boolean) => void;
28
20
  scrollState?: ScrollContainerScrollStateY;
29
21
  setScrollState?: (state: ScrollContainerScrollStateY) => void;
@@ -34,5 +26,6 @@ export interface SideMenuContextType {
34
26
  hideScrollBar?: boolean;
35
27
  showScrollBar?: showScrollBarType;
36
28
  sideMenuRef?: RefObject<HTMLDivElement>;
29
+ navigation?: MenuNavigation | null;
37
30
  }
38
31
  export declare const SideMenuContext: import("react").Context<SideMenuContextType>;
@@ -2,12 +2,10 @@ import React from 'react';
2
2
  import { DropdownMenuProps } from '@skbkontur/react-ui';
3
3
  import { CommonProps } from '@skbkontur/react-ui/internal/CommonWrapper';
4
4
  import { SideMenuItemProps } from '../SideMenuItem/SideMenuItem';
5
- export interface SideMenuDropdownProps extends CommonProps, Omit<DropdownMenuProps, 'caption' | 'disableAnimations'>, Pick<SideMenuItemProps, 'icon' | 'caption' | 'marker' | 'id' | '_generatedId' | 'subCaption' | '_isAvatar'> {
5
+ export interface SideMenuDropdownProps extends CommonProps, Omit<DropdownMenuProps, 'caption' | 'disableAnimations'>, Pick<SideMenuItemProps, 'icon' | 'caption' | 'marker' | 'id' | 'subCaption' | '_isAvatar'> {
6
6
  children?: React.ReactNode;
7
7
  disableAnimations?: boolean;
8
8
  id?: string;
9
- /** @ignore */
10
- _generatedId?: string;
11
9
  }
12
10
  /**
13
11
  * Элемент списка с выпадающим меню
@@ -8,7 +8,7 @@ import { SideMenuContext } from '../SideMenuContext';
8
8
  import { getSideMenuTheme } from '../../lib/theming/ThemeHelpers';
9
9
  var SideMenuDropdownInner = forwardRef(function (_a, ref) {
10
10
  var _b, _c;
11
- var icon = _a.icon, id = _a.id, _generatedId = _a._generatedId, children = _a.children, caption = _a.caption, marker = _a.marker, subCaption = _a.subCaption, className = _a.className, _d = _a.disableAnimations, disableAnimations = _d === void 0 ? false : _d, menuWidth = _a.menuWidth, _isAvatar = _a._isAvatar, rest = __rest(_a, ["icon", "id", "_generatedId", "children", "caption", "marker", "subCaption", "className", "disableAnimations", "menuWidth", "_isAvatar"]);
11
+ var icon = _a.icon, id = _a.id, children = _a.children, caption = _a.caption, marker = _a.marker, subCaption = _a.subCaption, className = _a.className, _d = _a.disableAnimations, disableAnimations = _d === void 0 ? false : _d, menuWidth = _a.menuWidth, _isAvatar = _a._isAvatar, rest = __rest(_a, ["icon", "id", "children", "caption", "marker", "subCaption", "className", "disableAnimations", "menuWidth", "_isAvatar"]);
12
12
  var context = useContext(SideMenuContext);
13
13
  var theme = getSideMenuTheme(useContext(ThemeContext));
14
14
  return (React.createElement("li", { className: cx((_b = {}, _b[jsStyles.wrapper()] = true, _b), className), ref: ref },
@@ -1,9 +1,8 @@
1
- import { __assign, __rest } from "tslib";
1
+ import { __assign, __read, __rest } from "tslib";
2
2
  import React, { forwardRef, useContext, useEffect, useState } from 'react';
3
3
  import { cx } from '@skbkontur/react-ui/lib/theming/Emotion';
4
4
  import { ThemeContext } from '@skbkontur/react-ui/lib/theming/ThemeContext';
5
5
  import { jsStyles } from './SideMenuFooter.styles';
6
- import { getItemId } from '../../lib/utils/scripts';
7
6
  import { SideMenuContext } from '../SideMenuContext';
8
7
  import { jsStylesForSideMenu } from '../SideMenu/SideMenu.styles';
9
8
  import { getSideMenuTheme } from '../../lib/theming/ThemeHelpers';
@@ -12,7 +11,7 @@ var SideMenuFooterInner = forwardRef(function (_a, ref) {
12
11
  var className = _a.className, children = _a.children, rest = __rest(_a, ["className", "children"]);
13
12
  var context = useContext(SideMenuContext);
14
13
  var theme = getSideMenuTheme(useContext(ThemeContext));
15
- var _c = useState(false), isFixed = _c[0], setIsFixed = _c[1];
14
+ var _c = __read(useState(false), 2), isFixed = _c[0], setIsFixed = _c[1];
16
15
  useEffect(function () {
17
16
  setIsFixed(!!context.hasScrollBar && !(context.scrollState === 'bottom'));
18
17
  }, [context.hasScrollBar, context.scrollState]);
@@ -22,14 +21,7 @@ var SideMenuFooterInner = forwardRef(function (_a, ref) {
22
21
  _b[jsStyles.rootFixed(theme)] = isFixed,
23
22
  _b[jsStyles.rootTransitionedForTabletsOrMobiles()] = context.isBeingTransitioned && (context.isMobile || context.isTablet),
24
23
  _b), className), ref: ref }, rest),
25
- React.createElement("ul", { className: jsStylesForSideMenu.list() }, React.Children.map(children, function (child, index) {
26
- if (React.isValidElement(child)) {
27
- return React.cloneElement(child, {
28
- _generatedId: getItemId('footer', index++),
29
- });
30
- }
31
- return child;
32
- }))));
24
+ React.createElement("ul", { className: jsStylesForSideMenu.list() }, children)));
33
25
  }
34
26
  return null;
35
27
  });
@@ -10,7 +10,8 @@ import { getSideMenuTheme } from '../../lib/theming/ThemeHelpers';
10
10
  import { getDOMRect } from '@skbkontur/react-ui/lib/dom/getDOMRect';
11
11
  var SideMenuHeaderInner = forwardRef(function (_a, ref) {
12
12
  var _b;
13
- var className = _a.className, productLogo = _a.productLogo, konturLogo = _a.konturLogo, iconUrl = _a.iconUrl, style = _a.style, _c = _a.withWidget, withWidget = _c === void 0 ? true : _c, dataTid = _a["data-tid"], rest = __rest(_a, ["className", "productLogo", "konturLogo", "iconUrl", "style", "withWidget", 'data-tid']);
13
+ var _c;
14
+ var className = _a.className, productLogo = _a.productLogo, konturLogo = _a.konturLogo, iconUrl = _a.iconUrl, style = _a.style, _d = _a.withWidget, withWidget = _d === void 0 ? true : _d, dataTid = _a["data-tid"], rest = __rest(_a, ["className", "productLogo", "konturLogo", "iconUrl", "style", "withWidget", 'data-tid']);
14
15
  var context = useContext(SideMenuContext);
15
16
  var theme = getSideMenuTheme(useContext(ThemeContext));
16
17
  var headerWrapperRef = useRef(null);
@@ -25,7 +26,7 @@ var SideMenuHeaderInner = forwardRef(function (_a, ref) {
25
26
  _b[jsStyles.rootForTabletsOrMobiles(theme)] = context.isMobile || context.isTablet,
26
27
  _b[jsStyles.fixedRoot(theme)] = context.isOpened && !!context.hasScrollBar && !(context.scrollState === 'top'),
27
28
  _b[jsStyles.collapsedRootForTabletsOrMobiles()] = !context.isOpened && (context.isMobile || context.isTablet),
28
- _b[jsStyles.rootWithSeparatedMenuShown(theme)] = context.isOpened && context.isMobile && context.isSeparatedMenuShown,
29
+ _b[jsStyles.rootWithSeparatedMenuShown(theme)] = context.isOpened && context.isMobile && ((_c = context.navigation) === null || _c === void 0 ? void 0 : _c.isSeparatedMenuShown),
29
30
  _b), className), ref: mergeRefs([headerWrapperRef, ref]), style: style, "data-tid": dataTid },
30
31
  React.createElement(SideMenuLogotype, __assign({ productLogo: productLogo, konturLogo: konturLogo, iconUrl: iconUrl, withWidget: withWidget }, rest))));
31
32
  });
@@ -1,23 +1,10 @@
1
1
  import { __assign, __rest } from "tslib";
2
- import React, { forwardRef, useContext } from 'react';
2
+ import React, { forwardRef } from 'react';
3
3
  import { SideMenuItem } from '../SideMenuItem/SideMenuItem';
4
- import { SideMenuContext } from '../SideMenuContext';
5
- import { NestedMenu } from '../internal/NestedMenu';
6
- import { useOpenedSubElementState } from '../../hooks/useOpenedSubElementState';
7
- import { useMemoIcon } from '../../hooks/useMemoIcon';
8
4
  var SideMenuSubItemInner = forwardRef(function (_a, ref) {
9
- var children = _a.children, _generatedId = _a._generatedId, id = _a.id, rest = __rest(_a, ["children", "_generatedId", "id"]);
10
- var context = useContext(SideMenuContext);
11
- var isOpened = useOpenedSubElementState(id, _generatedId, context.openedParents, context.activeMenuItem);
12
- var isOpenedButton = useOpenedSubElementState(id, _generatedId, context.openedParents, context.clickedButton);
13
- var icon = useMemoIcon(children, isOpened || isOpenedButton);
5
+ var props = __rest(_a, []);
14
6
  return (React.createElement("li", { ref: ref },
15
- React.createElement(SideMenuItem
16
- /*@ts-expect-error: SideMenuItem should have icon */
17
- , __assign({
18
- /*@ts-expect-error: SideMenuItem should have icon */
19
- icon: icon, _isSubMenu: true, id: id, _generatedId: _generatedId, "aria-expanded": children ? isOpened || isOpenedButton : undefined, "aria-controls": children ? "" + (id || _generatedId) : undefined }, rest)),
20
- children && (isOpened || isOpenedButton) && (React.createElement(NestedMenu, { _generatedId: _generatedId, htmlId: "" + (id || _generatedId) }, children))));
7
+ React.createElement(SideMenuItem, __assign({ _isSubMenu: true }, props))));
21
8
  });
22
9
  SideMenuSubItemInner.displayName = 'SideMenuSubItem';
23
10
  /**
@@ -1,22 +1,9 @@
1
- import { __assign, __rest } from "tslib";
2
- import React, { forwardRef, useContext } from 'react';
3
- import { SideMenuContext } from '../SideMenuContext';
1
+ import { __assign } from "tslib";
2
+ import React, { forwardRef } from 'react';
4
3
  import { SideMenuLink } from '../SideMenuLink/SideMenuLink';
5
- import { NestedMenu } from '../internal/NestedMenu';
6
- import { useOpenedSubElementState } from '../../hooks/useOpenedSubElementState';
7
- import { useMemoIcon } from '../../hooks/useMemoIcon';
8
- var SideMenuSubLinkInner = forwardRef(function (_a, ref) {
9
- var id = _a.id, _generatedId = _a._generatedId, _isSubMenu = _a._isSubMenu, _isNestedSubMenu = _a._isNestedSubMenu, children = _a.children, rest = __rest(_a, ["id", "_generatedId", "_isSubMenu", "_isNestedSubMenu", "children"]);
10
- var context = useContext(SideMenuContext);
11
- var isOpened = useOpenedSubElementState(id, _generatedId, context.openedParents, context.activeMenuItem);
12
- var icon = useMemoIcon(children, isOpened);
4
+ var SideMenuSubLinkInner = forwardRef(function (props, ref) {
13
5
  return (React.createElement("li", { ref: ref },
14
- React.createElement(SideMenuLink
15
- /*@ts-expect-error: SideMenuItem should have icon */
16
- , __assign({
17
- /*@ts-expect-error: SideMenuItem should have icon */
18
- icon: icon, _isSubMenu: true, _isNestedSubMenu: _isNestedSubMenu, id: id, _generatedId: _generatedId, "aria-expanded": children ? isOpened : undefined, "aria-controls": children ? "" + (id || _generatedId) : undefined }, rest)),
19
- children && isOpened && (React.createElement(NestedMenu, { _generatedId: _generatedId, htmlId: "" + (id || _generatedId) }, children))));
6
+ React.createElement(SideMenuLink, __assign({ _isSubMenu: true }, props))));
20
7
  });
21
8
  SideMenuSubLinkInner.displayName = 'SideMenuSubLink';
22
9
  /**
package/src/Tree.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { NavigableElement } from './Navigation';
2
+ export declare class TreeNode {
3
+ id: string;
4
+ value: NavigableElement | null;
5
+ parent: TreeNode | null;
6
+ children: TreeNode[];
7
+ constructor(id: string, value?: NavigableElement | null, parent?: TreeNode | null);
8
+ get hasChildren(): boolean;
9
+ }
10
+ export declare class Tree {
11
+ private root;
12
+ constructor(id: string, value?: NavigableElement | null);
13
+ preOrderTraversal(node?: TreeNode): Generator<TreeNode, void, undefined>;
14
+ insert(parentId: string, id: string | undefined | null, value?: NavigableElement | null): boolean;
15
+ remove(id: string): boolean;
16
+ find(id?: string | null): TreeNode | undefined;
17
+ }