@skbkontur/side-menu 0.7.3 → 0.8.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/hooks/useAnimateOnMount.d.ts +2 -0
  3. package/hooks/useAnimateOnMount.js +18 -0
  4. package/hooks/useNumberOfTextLinesInItem.d.ts +1 -1
  5. package/hooks/useNumberOfTextLinesInItem.js +35 -10
  6. package/hooks/useNumberOfTextLinesInSubItem.d.ts +2 -0
  7. package/hooks/useNumberOfTextLinesInSubItem.js +13 -0
  8. package/package.json +3 -3
  9. package/src/SideMenu/SideMenu.d.ts +2 -0
  10. package/src/SideMenu/SideMenu.js +65 -55
  11. package/src/SideMenu/SideMenu.styles.d.ts +1 -3
  12. package/src/SideMenu/SideMenu.styles.js +15 -22
  13. package/src/SideMenuBody/SideMenuBody.d.ts +2 -1
  14. package/src/SideMenuBody/SideMenuBody.js +24 -3
  15. package/src/SideMenuBody/SideMenuBody.styles.js +2 -1
  16. package/src/SideMenuContext.d.ts +5 -2
  17. package/src/SideMenuDropdown/SideMenuDropdown.js +26 -23
  18. package/src/SideMenuDropdown/SideMenuDropdown.styles.js +2 -1
  19. package/src/SideMenuFooter/SideMenuFooter.d.ts +1 -1
  20. package/src/SideMenuFooter/SideMenuFooter.js +10 -2
  21. package/src/SideMenuFooter/SideMenuFooter.styles.d.ts +2 -0
  22. package/src/SideMenuFooter/SideMenuFooter.styles.js +9 -2
  23. package/src/SideMenuHeader/SideMenuHeader.js +4 -23
  24. package/src/SideMenuHeader/SideMenuHeader.styles.d.ts +1 -0
  25. package/src/SideMenuHeader/SideMenuHeader.styles.js +10 -7
  26. package/src/internal/Backdrop.d.ts +4 -1
  27. package/src/internal/Backdrop.js +3 -5
  28. package/src/internal/Backdrop.styles.js +2 -1
  29. package/src/internal/ClickableElement.styles.js +1 -1
  30. package/src/internal/ItemContent/Caption.js +2 -2
  31. package/src/internal/ItemContent/Caption.styles.js +1 -1
  32. package/src/internal/ItemContent/Icon.js +1 -2
  33. package/src/internal/ItemContent/Icon.styles.d.ts +0 -1
  34. package/src/internal/ItemContent/Icon.styles.js +6 -9
  35. package/src/internal/ItemContent/ItemContent.js +24 -7
  36. package/src/internal/ItemContent/ItemContent.styles.d.ts +4 -1
  37. package/src/internal/ItemContent/ItemContent.styles.js +18 -11
  38. package/src/internal/ItemContent/Marker.styles.js +1 -1
  39. package/src/internal/SeparatedSubMenu.js +26 -20
  40. package/src/internal/SeparatedSubMenu.styles.d.ts +2 -0
  41. package/src/internal/SeparatedSubMenu.styles.js +9 -3
  42. package/src/internal/SideMenuLogotype.js +14 -6
  43. package/src/internal/SideMenuLogotype.styles.d.ts +5 -1
  44. package/src/internal/SideMenuLogotype.styles.js +19 -4
  45. package/src/internal/SubMenu.js +1 -1
  46. package/hooks/useMobileSeparatedMenuScroll.d.ts +0 -1
  47. package/hooks/useMobileSeparatedMenuScroll.js +0 -21
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.8.0](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@0.7.4...@skbkontur/side-menu@0.8.0) (2023-03-31)
7
+
8
+
9
+ ### Features
10
+
11
+ * **SideMenu:** improve minimize animation ([acc6f27](https://git.skbkontur.ru/ui/ui-parking/commits/acc6f27df7c96a8a4e0fc6d595c40ad962a75b4d))
12
+
13
+
14
+
15
+
16
+
17
+ ## [0.7.4](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@0.7.3...@skbkontur/side-menu@0.7.4) (2023-03-30)
18
+
19
+ **Note:** Version bump only for package @skbkontur/side-menu
20
+
21
+
22
+
23
+
24
+
6
25
  ## [0.7.3](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@0.7.2...@skbkontur/side-menu@0.7.3) (2023-03-30)
7
26
 
8
27
  **Note:** Version bump only for package @skbkontur/side-menu
@@ -0,0 +1,2 @@
1
+ import { CSSProperties } from 'react';
2
+ export declare function useAnimateOnMount(isMounted: boolean, delayTime: number, mountStyles: CSSProperties, unmountStyles: CSSProperties): [boolean, CSSProperties];
@@ -0,0 +1,18 @@
1
+ import { useEffect, useState } from 'react';
2
+ export function useAnimateOnMount(isMounted, delayTime, mountStyles, unmountStyles) {
3
+ var _a = useState(isMounted ? mountStyles : unmountStyles), style = _a[0], setStyle = _a[1];
4
+ var _b = useState(isMounted), shouldShowComponent = _b[0], setShouldShowComponent = _b[1];
5
+ useEffect(function () {
6
+ var timeoutId;
7
+ if (isMounted) {
8
+ setShouldShowComponent(true);
9
+ timeoutId = setTimeout(function () { return setStyle(mountStyles); }, 0);
10
+ }
11
+ else {
12
+ timeoutId = setTimeout(function () { return setShouldShowComponent(false); }, delayTime);
13
+ setStyle(unmountStyles);
14
+ }
15
+ return function () { return clearTimeout(timeoutId); };
16
+ }, [isMounted, delayTime]);
17
+ return [shouldShowComponent, style];
18
+ }
@@ -1,2 +1,2 @@
1
1
  import React from 'react';
2
- export declare const useNumberOfTextLinesInItem: (textRef: React.RefObject<HTMLDivElement>, setIsMultilineText: React.Dispatch<React.SetStateAction<boolean>>) => void;
2
+ export declare const useNumberOfTextLinesInItem: (textRef: React.RefObject<HTMLDivElement>, setLinesNumber: React.Dispatch<React.SetStateAction<number>>, text?: string, marker?: string, size?: string) => void;
@@ -1,13 +1,38 @@
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 = typeof window !== undefined ? parseInt(window.getComputedStyle(el_1).getPropertyValue('line-height')) : 0;
7
- var lines = textHeight / lineHeight;
8
- if (lines >= 2) {
9
- setIsMultilineText(true);
1
+ export var useNumberOfTextLinesInItem = function (textRef, setLinesNumber, text, marker, size) {
2
+ if (text === void 0) { text = ''; }
3
+ if (marker === void 0) { marker = ''; }
4
+ if (size === void 0) { size = 'small'; }
5
+ var getContainerWidth = function (ctx, marker) {
6
+ var containerWidth = 232 - 2 * 16 - 24 - 2 * 8; //TODO после перехода на переменные темы заменить на формулу: side-menu-width - 2 * side-menu-paddingX - iconWidth - 2 * iconPaddingX
7
+ var markerPaddings = marker ? 2 * 6 + 8 : 0; //TODO после перехода на переменные темы заменить на marker-padding-x и marker-margin-right
8
+ var markerWidth = ctx.measureText(marker).width + markerPaddings;
9
+ return containerWidth - markerWidth - 8; //TODO после перехода на переменные темы заменить на caption-margin-right
10
+ };
11
+ var getNumberOfLines = function (ctx, words, containerWidth) {
12
+ var line = '';
13
+ var lineCount = 1;
14
+ words.forEach(function (word, i) {
15
+ var testLine = (line + " " + word).trim();
16
+ var testWidth = ctx.measureText(testLine).width;
17
+ if (testWidth > containerWidth && i > 0) {
18
+ line = '';
19
+ lineCount++;
10
20
  }
11
- }, 0);
21
+ else {
22
+ line = testLine;
23
+ }
24
+ });
25
+ return lineCount;
26
+ };
27
+ var fontSize = size === 'small' ? 14 : 16; //TODO после перехода на переменные темы заменить на side-menu-font-size-small и side-menu-font-size-large
28
+ var fontFamily = textRef.current && typeof window !== undefined
29
+ ? window.getComputedStyle(textRef.current).getPropertyValue('font-family')
30
+ : "'Lab Grotesque', 'Segoe UI', 'Helvetica Neue', Roboto, Arial, sans-serif";
31
+ var canvas = document.createElement('canvas');
32
+ var ctx = canvas.getContext('2d');
33
+ if (ctx) {
34
+ ctx.font = fontSize + "px " + fontFamily;
35
+ var words = text.split(' ');
36
+ setLinesNumber(getNumberOfLines(ctx, words, getContainerWidth(ctx, marker)));
12
37
  }
13
38
  };
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const useNumberOfTextLinesInSubItem: (textRef: React.RefObject<HTMLDivElement>, setIsMultilineText: React.Dispatch<React.SetStateAction<boolean>>) => void;
@@ -0,0 +1,13 @@
1
+ export var useNumberOfTextLinesInSubItem = 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 = typeof window !== undefined ? parseInt(window.getComputedStyle(el_1).getPropertyValue('line-height')) : 0;
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.7.3",
3
+ "version": "0.8.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -14,13 +14,13 @@
14
14
  },
15
15
  "author": "Kontur",
16
16
  "peerDependencies": {
17
- "@skbkontur/react-ui": ">=4 <5",
17
+ "@skbkontur/react-ui": ">=4.5.0 <5",
18
18
  "@skbkontur/react-ui-addons": ">=4.0.1",
19
19
  "react": ">=16.9",
20
20
  "react-dom": ">=16.9"
21
21
  },
22
22
  "devDependencies": {
23
- "@skbkontur/react-ui": "4.5.0"
23
+ "@skbkontur/react-ui": "4.13.0"
24
24
  },
25
25
  "dependencies": {
26
26
  "@skbkontur/icons": "^0.15.0",
@@ -40,5 +40,7 @@ interface SubComponents {
40
40
  SubLink: typeof SideMenuSubLink;
41
41
  __KONTUR_REACT_UI__: string;
42
42
  }
43
+ export declare const transitionDuration = 300;
44
+ export declare const burgerTransitionDuration: number;
43
45
  export declare const SideMenu: React.ForwardRefExoticComponent<SideMenuProps & React.RefAttributes<HTMLElement>> & SubComponents;
44
46
  export {};
@@ -1,7 +1,7 @@
1
1
  import { __assign, __rest } from "tslib";
2
2
  import React, { forwardRef, useEffect, useState } from 'react';
3
3
  import { cx } from '@skbkontur/react-ui/lib/theming/Emotion';
4
- import { isIE11, isSafari } from '@skbkontur/react-ui/lib/client';
4
+ import { isIE11 } from '@skbkontur/react-ui/lib/client';
5
5
  import { jsStyles, sideMenuMinimizedWidth, sideMenuStandardWidth } from './SideMenu.styles';
6
6
  import { SideMenuOrganisations } from '../SideMenuOrganisations/SideMenuOrganisations';
7
7
  import { SideMenuContext } from '../SideMenuContext';
@@ -17,16 +17,18 @@ import { RightBorder } from '../internal/RightBorder';
17
17
  import { SideMenuDropdown } from '../SideMenuDropdown/SideMenuDropdown';
18
18
  import { SideMenuLink } from '../SideMenuLink/SideMenuLink';
19
19
  import { SideMenuSubLink } from '../SideMenuSubLink/SideMenuSubLink';
20
- import { useResponsiveLayout } from '@skbkontur/react-ui';
20
+ import { DEFAULT_THEME, useResponsiveLayout } from '@skbkontur/react-ui';
21
21
  import { Backdrop } from '../internal/Backdrop';
22
22
  import { RenderLayer } from '@skbkontur/react-ui/internal/RenderLayer';
23
23
  import { isTouchDevice } from '../../utils/scripts';
24
24
  import { SideMenuDataTids } from '../../SideMenuDataTids';
25
25
  import { ZIndex } from '@skbkontur/react-ui/internal/ZIndex';
26
+ import { useAnimateOnMount } from '../../hooks/useAnimateOnMount';
27
+ export var transitionDuration = 300; //ms
28
+ export var burgerTransitionDuration = (transitionDuration * 2) / 3;
26
29
  var SideMenuInner = forwardRef(function (_a, ref) {
27
30
  var _b, _c, _d, _e;
28
31
  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 ? true : _h, _j = _a.desktopMediaQuery, desktopMediaQuery = _j === void 0 ? '(min-width: 1200px)' : _j, _k = _a.narrowDesktopMediaQuery, narrowDesktopMediaQuery = _k === void 0 ? '(min-width: 992px)' : _k, _l = _a.tabletMediaQuery, tabletMediaQuery = _l === void 0 ? '(min-width: 768px)' : _l, _m = _a.mobileMediaQuery, mobileMediaQuery = _m === void 0 ? '(min-width: 0px)' : _m, _o = _a.separatedMenuWithOverlay, separatedMenuWithOverlay = _o === void 0 ? false : _o, rest = __rest(_a, ["children", "value", "onValueChange", "size", "isSeparatedMenu", "className", "disableSwipe", "desktopMediaQuery", "narrowDesktopMediaQuery", "tabletMediaQuery", "mobileMediaQuery", "separatedMenuWithOverlay"]);
29
- var scrollTimer = null;
30
32
  var transitionTimer = null;
31
33
  var widgetTimer;
32
34
  var customMediaQueries = {
@@ -45,22 +47,26 @@ var SideMenuInner = forwardRef(function (_a, ref) {
45
47
  var isTouchScreen = isTouchDevice() || isMobile || isTablet;
46
48
  var separatedMenuWithoutOverlay = isSeparatedMenu && !separatedMenuWithOverlay;
47
49
  var _q = useState(isNarrowDesktop), isMinimized = _q[0], setIsMinimized = _q[1];
48
- var _r = useState(false), hasScrollBar = _r[0], setHasScrollBar = _r[1];
49
- var _s = useState(false), isBeingTransitioned = _s[0], setIsBeingTransitioned = _s[1];
50
- var _t = useState('#2291ff'), productColor = _t[0], setProductColor = _t[1];
51
- var _u = useState(false), showWidget = _u[0], setShowWidget = _u[1];
52
- var _v = useState(value), activeMenuItem = _v[0], setActiveMenuItem = _v[1];
53
- var _w = useState(isDesktopQuery || isNarrowDesktop), isShown = _w[0], setIsShown = _w[1];
54
- var _x = useState(false), isSeparatedMenuShown = _x[0], setIsSeparatedMenuShown = _x[1];
55
- var _y = useState(true), isMouseOutside = _y[0], setIsMouseOutside = _y[1];
56
- var _z = useState(false), isMobileSeparatedMenuScrolling = _z[0], setIsMobileSeparatedMenuScrolling = _z[1];
50
+ var _r = useState(false), isBeingTransitioned = _r[0], setIsBeingTransitioned = _r[1];
51
+ var _s = useState('#2291ff'), productColor = _s[0], setProductColor = _s[1];
52
+ var _t = useState(false), showWidget = _t[0], setShowWidget = _t[1];
53
+ var _u = useState(value), activeMenuItem = _u[0], setActiveMenuItem = _u[1];
54
+ var _v = useState(isDesktopQuery || isNarrowDesktop), isShown = _v[0], setIsShown = _v[1];
55
+ var _w = useState(false), isSeparatedMenuShown = _w[0], setIsSeparatedMenuShown = _w[1];
56
+ var _x = useState(true), isMouseOutside = _x[0], setIsMouseOutside = _x[1];
57
+ var _y = useState('top'), scrollState = _y[0], setScrollState = _y[1];
58
+ var _z = useState(false), hasScrollBar = _z[0], setHasScrollBar = _z[1];
59
+ var _0 = useState(0), mousePositionX = _0[0], setMousePositionX = _0[1];
57
60
  useEffect(function () {
58
61
  return function () {
59
- if (scrollTimer) {
60
- clearTimeout(scrollTimer);
62
+ if (transitionTimer) {
63
+ clearTimeout(transitionTimer);
64
+ }
65
+ if (widgetTimer) {
66
+ clearTimeout(widgetTimer);
61
67
  }
62
68
  };
63
- });
69
+ }, []);
64
70
  useEffect(function () {
65
71
  if (isNarrowDesktop || isDesktopQuery) {
66
72
  setIsShown(true);
@@ -72,6 +78,12 @@ var SideMenuInner = forwardRef(function (_a, ref) {
72
78
  setIsMinimized(true);
73
79
  }
74
80
  }, [isNarrowDesktop, isDesktopQuery]);
81
+ useEffect(function () {
82
+ if (isTablet || isMobile) {
83
+ setIsMinimized(false);
84
+ setIsShown(false);
85
+ }
86
+ }, [isTablet, isMobile]);
75
87
  useEffect(function () {
76
88
  setActiveMenuItem(value);
77
89
  }, [value]);
@@ -85,24 +97,9 @@ var SideMenuInner = forwardRef(function (_a, ref) {
85
97
  }
86
98
  transitionTimer = setTimeout(function () {
87
99
  setIsBeingTransitioned(false);
88
- }, 1000);
100
+ }, transitionDuration);
89
101
  }
90
102
  };
91
- var handleScroll = function (event) {
92
- var element = event.target;
93
- if (Math.floor(element.scrollHeight - element.scrollTop) === element.clientHeight) {
94
- return;
95
- }
96
- if (!hasScrollBar) {
97
- setHasScrollBar(true);
98
- }
99
- if (scrollTimer) {
100
- clearTimeout(scrollTimer);
101
- }
102
- scrollTimer = setTimeout(function () {
103
- setHasScrollBar(false);
104
- }, 200);
105
- };
106
103
  var handleMouseEnter = function () {
107
104
  if (separatedMenuWithoutOverlay && isSeparatedMenuShown && isNarrowDesktop) {
108
105
  return;
@@ -124,14 +121,15 @@ var SideMenuInner = forwardRef(function (_a, ref) {
124
121
  setIsMouseOutside(true);
125
122
  };
126
123
  var showMinimizedRootForNarrowDesktopWithOverlay = function (e) {
127
- if (separatedMenuWithoutOverlay && isNarrowDesktop) {
128
- if (e.clientX < parseInt(sideMenuMinimizedWidth)) {
129
- showMinimizedRoot(false);
130
- }
131
- if (e.clientX > parseInt(sideMenuStandardWidth)) {
132
- showMinimizedRoot(true);
133
- }
124
+ if (!separatedMenuWithoutOverlay || !isNarrowDesktop)
125
+ return;
126
+ if (e.clientX < parseInt(sideMenuMinimizedWidth) && mousePositionX > parseInt(sideMenuMinimizedWidth)) {
127
+ showMinimizedRoot(false);
128
+ }
129
+ if (e.clientX > parseInt(sideMenuStandardWidth)) {
130
+ showMinimizedRoot(true);
134
131
  }
132
+ setMousePositionX(e.clientX);
135
133
  };
136
134
  var switchActiveMenuItem = function (id) {
137
135
  if (id !== value) {
@@ -139,13 +137,26 @@ var SideMenuInner = forwardRef(function (_a, ref) {
139
137
  setActiveMenuItem(id);
140
138
  }
141
139
  };
142
- var toggleIsShown = function () {
143
- isTabletOrMobile && setIsShown(!isShown);
144
- };
145
- var turnOffIsShown = function () {
146
- isTabletOrMobile && setIsShown(false);
140
+ var handleIsShown = function (newIsShown) {
141
+ if (!isTabletOrMobile)
142
+ return;
143
+ if (!isBeingTransitioned && newIsShown !== isShown) {
144
+ setIsBeingTransitioned(true);
145
+ setIsShown(newIsShown);
146
+ if (transitionTimer) {
147
+ clearTimeout(transitionTimer);
148
+ }
149
+ transitionTimer = setTimeout(function () {
150
+ setIsBeingTransitioned(false);
151
+ }, burgerTransitionDuration);
152
+ }
147
153
  };
148
154
  var isSideMenuOverContent = (isNarrowDesktop && !isMinimized) || (isMobile && isShown) || (isTablet && isShown && !isSeparatedMenuShown);
155
+ var _1 = useAnimateOnMount(!!isTabletOrMobile && !!isShown, burgerTransitionDuration, {
156
+ opacity: DEFAULT_THEME.sidePageBackingBgOpacity,
157
+ }, {
158
+ opacity: 0,
159
+ }), shouldShowBackdrop = _1[0], backdropStyle = _1[1];
149
160
  return (React.createElement(SideMenuContext.Provider, { value: {
150
161
  isMinimized: isMinimized,
151
162
  setIsMinimized: showMinimizedRoot,
@@ -163,15 +174,17 @@ var SideMenuInner = forwardRef(function (_a, ref) {
163
174
  isMobile: isMobile,
164
175
  isTouchScreen: isTouchScreen,
165
176
  isShown: isShown,
166
- toggleIsShown: toggleIsShown,
177
+ toggleIsShown: function () { return handleIsShown(!isShown); },
167
178
  isSeparatedMenuShown: isSeparatedMenuShown,
168
179
  setIsSeparatedMenuShown: setIsSeparatedMenuShown,
169
180
  separatedMenuWithoutOverlay: separatedMenuWithoutOverlay,
170
181
  setIsMouseOutside: setIsMouseOutside,
171
- isMobileSeparatedMenuScrolling: isMobileSeparatedMenuScrolling,
172
- setIsMobileSeparatedMenuScrolling: setIsMobileSeparatedMenuScrolling,
182
+ scrollState: scrollState,
183
+ setScrollState: setScrollState,
184
+ hasScrollBar: hasScrollBar,
185
+ setHasScrollBar: setHasScrollBar,
173
186
  } },
174
- React.createElement(ZIndex, { priority: isTabletOrMobile ? 'Sidepage' : 0, className: cx((_b = {},
187
+ React.createElement(ZIndex, { priority: isTabletOrMobile || isNarrowDesktop ? 'Sidepage' : 0, className: cx((_b = {},
175
188
  _b[jsStyles.root()] = true,
176
189
  _b[jsStyles.rootForTabletsOrMobiles()] = isTabletOrMobile,
177
190
  _b[jsStyles.shownRootForTabletsOrMobiles()] = isShown && isTabletOrMobile,
@@ -180,8 +193,8 @@ var SideMenuInner = forwardRef(function (_a, ref) {
180
193
  _b[jsStyles.separatedRootForDesktops()] = separatedMenuWithoutOverlay && isSeparatedMenuShown && isDesktopQuery,
181
194
  _b)) },
182
195
  React.createElement(React.Fragment, null,
183
- isTabletOrMobile && isShown && React.createElement(Backdrop, null),
184
- React.createElement(RenderLayer, { onClickOutside: turnOffIsShown },
196
+ shouldShowBackdrop && React.createElement(Backdrop, { style: backdropStyle }),
197
+ React.createElement(RenderLayer, { onClickOutside: function () { return handleIsShown(false); } },
185
198
  React.createElement("aside", __assign({ className: cx((_c = {},
186
199
  _c[jsStyles.wrapper()] = true,
187
200
  _c[jsStyles.wrapperIE()] = isIE11,
@@ -189,17 +202,14 @@ var SideMenuInner = forwardRef(function (_a, ref) {
189
202
  _c), className), "data-tid": SideMenuDataTids.root, ref: ref }, rest, { onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onMouseMove: showMinimizedRootForNarrowDesktopWithOverlay }),
190
203
  React.createElement("div", { className: cx((_d = {},
191
204
  _d[jsStyles.container()] = true,
192
- _d[jsStyles.collapsedContainerForTabletsOrMobiles()] = !isShown,
193
- _d[jsStyles.containerSafari()] = isSafari,
205
+ _d[jsStyles.collapsedContainerForTabletsOrMobiles()] = !isShown && !isBeingTransitioned,
194
206
  _d[jsStyles.minimizedContainer()] = isMinimized,
195
207
  _d[jsStyles.innerContainer()] = !isSeparatedMenu,
196
208
  _d[jsStyles.containerForTouchScreens()] = isTouchScreen,
197
- _d[jsStyles.separatedContainerForMobiles()] = isMobile && isSeparatedMenuShown && isShown,
198
- _d)), onScroll: handleScroll },
209
+ _d[jsStyles.separatedContainerForMobiles()] = isMobile && isSeparatedMenuShown && (isShown || isBeingTransitioned),
210
+ _d)) },
199
211
  React.createElement("div", { className: cx((_e = {},
200
212
  _e[jsStyles.contentWrapper()] = true,
201
- _e[jsStyles.contentWrapperWithoutScrollBar()] = !hasScrollBar,
202
- _e[jsStyles.collapsedContentWrapperForTabletsOrMobiles()] = !isShown || isSeparatedMenuShown,
203
213
  _e)) }, children)),
204
214
  !disableSwipe && isDesktopQuery && !isSeparatedMenuShown && (React.createElement(RightBorder, { setIsMinimized: setIsMinimized }))))))));
205
215
  });
@@ -2,6 +2,7 @@ export declare const sideMenuMinimizedWidth = "72px";
2
2
  export declare const sideMenuStandardWidth = "232px";
3
3
  export declare const sideMenuForTouchScreenWidth = "328px";
4
4
  export declare const sideMenuBoxShadow = "4px 4px 24px rgba(0, 0, 0, 0.24)";
5
+ export declare const sideMenuMarginX = "16px";
5
6
  export declare const jsStyles: {
6
7
  root(): string;
7
8
  rootForTabletsOrMobiles(): string;
@@ -10,9 +11,6 @@ export declare const jsStyles: {
10
11
  separatedRootForNarrowDesktops(): string;
11
12
  separatedRootForDesktops(): string;
12
13
  container(): string;
13
- containerSafari(): string;
14
- contentWrapperWithoutScrollBar(): string;
15
- collapsedContentWrapperForTabletsOrMobiles(): string;
16
14
  minimizedContainer(): string;
17
15
  innerContainer(): string;
18
16
  containerForTouchScreens(): string;
@@ -1,18 +1,20 @@
1
1
  import { __makeTemplateObject } from "tslib";
2
2
  import { css, memoizeStyle } from '@skbkontur/react-ui/lib/theming/Emotion';
3
+ import { burgerTransitionDuration, transitionDuration } from './SideMenu';
3
4
  export var sideMenuMinimizedWidth = '72px';
4
5
  export var sideMenuStandardWidth = '232px';
5
6
  export var sideMenuForTouchScreenWidth = '328px';
6
7
  export var sideMenuBoxShadow = '4px 4px 24px rgba(0, 0, 0, 0.24)';
8
+ export var sideMenuMarginX = '16px';
7
9
  var styles = {
8
10
  root: function () {
9
11
  return css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: relative;\n height: 100%;\n flex-shrink: 0;\n "], ["\n position: relative;\n height: 100%;\n flex-shrink: 0;\n "])));
10
12
  },
11
13
  rootForTabletsOrMobiles: function () {
12
- return css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n height: 68px;\n position: absolute;\n top: 0;\n "], ["\n height: 68px;\n position: absolute;\n top: 0;\n "])));
14
+ return css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n height: 68px;\n position: absolute;\n top: 0;\n transition: height ", "ms ease-out;\n "], ["\n height: 68px;\n position: absolute;\n top: 0;\n transition: height ", "ms ease-out;\n "])), burgerTransitionDuration);
13
15
  },
14
16
  shownRootForTabletsOrMobiles: function () {
15
- return css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n height: 100vh;\n "], ["\n height: 100vh;\n "])));
17
+ return css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n height: 100vh;\n transition: height ", "ms ease-out;\n "], ["\n height: 100vh;\n transition: height ", "ms ease-out;\n "])), burgerTransitionDuration);
16
18
  },
17
19
  rootForNarrowDesktops: function () {
18
20
  return css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n width: ", ";\n "], ["\n width: ", ";\n "])), sideMenuMinimizedWidth);
@@ -24,45 +26,36 @@ var styles = {
24
26
  return css(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n width: calc(", " + ", ");\n background: #fff;\n "], ["\n width: calc(", " + ", ");\n background: #fff;\n "])), sideMenuStandardWidth, sideMenuStandardWidth);
25
27
  },
26
28
  container: function () {
27
- return css(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n width: ", ";\n height: 100%;\n background: #f6f6f6;\n position: relative;\n box-sizing: border-box;\n transition: width 1s;\n "], ["\n width: ", ";\n height: 100%;\n background: #f6f6f6;\n position: relative;\n box-sizing: border-box;\n transition: width 1s;\n "])), sideMenuStandardWidth);
28
- },
29
- containerSafari: function () {
30
- return css(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n &::-webkit-scrollbar {\n display: block;\n width: 10px;\n }\n &::-webkit-scrollbar-track {\n background: #f1f1f1;\n }\n &::-webkit-scrollbar-thumb {\n background: #888;\n }\n "], ["\n &::-webkit-scrollbar {\n display: block;\n width: 10px;\n }\n &::-webkit-scrollbar-track {\n background: #f1f1f1;\n }\n &::-webkit-scrollbar-thumb {\n background: #888;\n }\n "])));
31
- },
32
- contentWrapperWithoutScrollBar: function () {
33
- return css(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n -ms-overflow-style: none;\n scrollbar-width: none;\n &::-webkit-scrollbar {\n display: none;\n width: 0;\n }\n "], ["\n -ms-overflow-style: none;\n scrollbar-width: none;\n &::-webkit-scrollbar {\n display: none;\n width: 0;\n }\n "])));
34
- },
35
- collapsedContentWrapperForTabletsOrMobiles: function () {
36
- return css(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n overflow: hidden;\n "], ["\n overflow: hidden;\n "])));
29
+ return css(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n width: ", ";\n height: 100%;\n background: #f6f6f6;\n position: relative;\n box-sizing: border-box;\n transition: width ", "ms ease-out;\n "], ["\n width: ", ";\n height: 100%;\n background: #f6f6f6;\n position: relative;\n box-sizing: border-box;\n transition: width ", "ms ease-out;\n "])), sideMenuStandardWidth, transitionDuration);
37
30
  },
38
31
  minimizedContainer: function () {
39
- return css(templateObject_11 || (templateObject_11 = __makeTemplateObject(["\n width: ", " !important;\n "], ["\n width: ", " !important;\n "])), sideMenuMinimizedWidth);
32
+ return css(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n width: ", " !important;\n "], ["\n width: ", " !important;\n "])), sideMenuMinimizedWidth);
40
33
  },
41
34
  innerContainer: function () {
42
- return css(templateObject_12 || (templateObject_12 = __makeTemplateObject(["\n overflow-x: hidden;\n "], ["\n overflow-x: hidden;\n "])));
35
+ return css(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n overflow-x: hidden;\n "], ["\n overflow-x: hidden;\n "])));
43
36
  },
44
37
  containerForTouchScreens: function () {
45
- return css(templateObject_13 || (templateObject_13 = __makeTemplateObject(["\n width: ", ";\n "], ["\n width: ", ";\n "])), sideMenuForTouchScreenWidth);
38
+ return css(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n width: ", ";\n "], ["\n width: ", ";\n "])), sideMenuForTouchScreenWidth);
46
39
  },
47
40
  separatedContainerForMobiles: function () {
48
- return css(templateObject_14 || (templateObject_14 = __makeTemplateObject(["\n background: #fff;\n "], ["\n background: #fff;\n "])));
41
+ return css(templateObject_11 || (templateObject_11 = __makeTemplateObject(["\n background: #fff;\n "], ["\n background: #fff;\n "])));
49
42
  },
50
43
  contentWrapper: function () {
51
- return css(templateObject_15 || (templateObject_15 = __makeTemplateObject(["\n height: calc(100% - 24px);\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n overflow-x: hidden;\n overflow-y: auto;\n padding: 0 16px 24px;\n "], ["\n height: calc(100% - 24px);\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n overflow-x: hidden;\n overflow-y: auto;\n padding: 0 16px 24px;\n "])));
44
+ return css(templateObject_12 || (templateObject_12 = __makeTemplateObject(["\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n overflow: hidden;\n "], ["\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n overflow: hidden;\n "])));
52
45
  },
53
46
  wrapper: function () {
54
- return css(templateObject_16 || (templateObject_16 = __makeTemplateObject(["\n height: 100%;\n display: inline-flex;\n position: relative;\n "], ["\n height: 100%;\n display: inline-flex;\n position: relative;\n "])));
47
+ return css(templateObject_13 || (templateObject_13 = __makeTemplateObject(["\n height: 100%;\n display: inline-flex;\n position: relative;\n "], ["\n height: 100%;\n display: inline-flex;\n position: relative;\n "])));
55
48
  },
56
49
  wrapperIE: function () {
57
50
  var ieRootWrapperCorrection = 15;
58
- return css(templateObject_17 || (templateObject_17 = __makeTemplateObject(["\n position: relative;\n top: -", "px;\n height: calc(100% + ", "px);\n "], ["\n position: relative;\n top: -", "px;\n height: calc(100% + ", "px);\n "])), ieRootWrapperCorrection, ieRootWrapperCorrection);
51
+ return css(templateObject_14 || (templateObject_14 = __makeTemplateObject(["\n position: relative;\n top: -", "px;\n height: calc(100% + ", "px);\n "], ["\n position: relative;\n top: -", "px;\n height: calc(100% + ", "px);\n "])), ieRootWrapperCorrection, ieRootWrapperCorrection);
59
52
  },
60
53
  wrapperWithShadow: function () {
61
- return css(templateObject_18 || (templateObject_18 = __makeTemplateObject(["\n box-shadow: ", ";\n "], ["\n box-shadow: ", ";\n "])), sideMenuBoxShadow);
54
+ return css(templateObject_15 || (templateObject_15 = __makeTemplateObject(["\n box-shadow: ", ";\n "], ["\n box-shadow: ", ";\n "])), sideMenuBoxShadow);
62
55
  },
63
56
  collapsedContainerForTabletsOrMobiles: function () {
64
- return css(templateObject_19 || (templateObject_19 = __makeTemplateObject(["\n background-color: transparent;\n "], ["\n background-color: transparent;\n "])));
57
+ return css(templateObject_16 || (templateObject_16 = __makeTemplateObject(["\n background-color: transparent;\n "], ["\n background-color: transparent;\n "])));
65
58
  },
66
59
  };
67
60
  export var jsStyles = memoizeStyle(styles);
68
- 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;
61
+ 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;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { CommonProps } from '@skbkontur/react-ui/internal/CommonWrapper';
3
+ import { ScrollContainer } from '@skbkontur/react-ui';
3
4
  export interface SideMenuBodyProps extends CommonProps {
4
5
  children?: React.ReactNode;
5
6
  }
@@ -8,6 +9,6 @@ export interface SideMenuBodyProps extends CommonProps {
8
9
  *
9
10
  * @visibleName SideMenu.Body
10
11
  */
11
- export declare const SideMenuBody: React.ForwardRefExoticComponent<SideMenuBodyProps & React.RefAttributes<HTMLDivElement>> & {
12
+ export declare const SideMenuBody: React.ForwardRefExoticComponent<SideMenuBodyProps & React.RefAttributes<ScrollContainer>> & {
12
13
  __KONTUR_REACT_UI__: string;
13
14
  };
@@ -1,16 +1,37 @@
1
1
  import { __assign, __rest } from "tslib";
2
- import React, { forwardRef, useContext } from 'react';
2
+ import React, { forwardRef, useContext, useEffect, useRef } from 'react';
3
3
  import { cx } from '@skbkontur/react-ui/lib/theming/Emotion';
4
4
  import { jsStyles } from './SideMenuBody.styles';
5
5
  import { InnerBody } from '../internal/InnerBody';
6
6
  import { SideMenuContext } from '../SideMenuContext';
7
+ import { ScrollContainer, ScrollContainerDataTids } from '@skbkontur/react-ui';
8
+ import { mergeRefs } from '@skbkontur/react-ui/lib/utils';
7
9
  var SideMenuBodyInner = forwardRef(function (_a, ref) {
8
10
  var _b;
9
11
  var className = _a.className, children = _a.children, rest = __rest(_a, ["className", "children"]);
10
12
  var context = useContext(SideMenuContext);
13
+ var scrollContainerRef = useRef(null);
14
+ var setScrollContainerInnerPosition = function () {
15
+ var scrollContainerInner = document.querySelector("[data-tid=" + ScrollContainerDataTids.inner + "]");
16
+ if (scrollContainerInner) {
17
+ scrollContainerInner.style.position = 'static';
18
+ }
19
+ };
20
+ useEffect(function () {
21
+ setTimeout(function () {
22
+ var _a, _b;
23
+ // @ts-expect-error: accessing private method
24
+ (_a = context.setHasScrollBar) === null || _a === void 0 ? void 0 : _a.call(context, (_b = scrollContainerRef.current) === null || _b === void 0 ? void 0 : _b.hasScrollBar('y'));
25
+ }, 50);
26
+ setScrollContainerInnerPosition();
27
+ }, [context.activeMenuItem, context.isShown]);
11
28
  if (context.isShown) {
12
- return (React.createElement("div", __assign({ className: cx((_b = {}, _b[jsStyles.root()] = true, _b), className), ref: ref }, rest),
13
- React.createElement(InnerBody, null, children)));
29
+ return (React.createElement(ScrollContainer, { style: { position: 'static' }, onScrollStateChangeY: function (state) {
30
+ var _a;
31
+ (_a = context.setScrollState) === null || _a === void 0 ? void 0 : _a.call(context, state);
32
+ }, hideScrollBar: true, ref: mergeRefs([ref, scrollContainerRef]) },
33
+ React.createElement("div", __assign({ className: cx((_b = {}, _b[jsStyles.root()] = true, _b), className) }, rest),
34
+ React.createElement(InnerBody, null, children))));
14
35
  }
15
36
  return null;
16
37
  });
@@ -1,8 +1,9 @@
1
1
  import { __makeTemplateObject } from "tslib";
2
2
  import { css, memoizeStyle } from '@skbkontur/react-ui/lib/theming/Emotion';
3
+ import { sideMenuMarginX } from '../SideMenu/SideMenu.styles';
3
4
  var styles = {
4
5
  root: function () {
5
- return css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n flex-grow: 1;\n padding-bottom: 16px;\n margin-top: 0;\n "], ["\n flex-grow: 1;\n padding-bottom: 16px;\n margin-top: 0;\n "])));
6
+ return css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n flex-grow: 1;\n padding-bottom: 8px;\n margin: 0 ", ";\n "], ["\n flex-grow: 1;\n padding-bottom: 8px;\n margin: 0 ", ";\n "])), sideMenuMarginX);
6
7
  },
7
8
  };
8
9
  export var jsStyles = memoizeStyle(styles);
@@ -1,4 +1,5 @@
1
1
  import { FlattedArrayElementType } from './internal/InnerBody';
2
+ import { ScrollContainerScrollStateY } from '@skbkontur/react-ui';
2
3
  export interface SideMenuContextType {
3
4
  isMinimized?: boolean;
4
5
  setIsMinimized?: (isMinimized: boolean) => void;
@@ -24,7 +25,9 @@ export interface SideMenuContextType {
24
25
  setIsSeparatedMenuShown?: (separatedMenuIsShown: boolean) => void;
25
26
  separatedMenuWithoutOverlay?: boolean;
26
27
  setIsMouseOutside?: (v: boolean) => void;
27
- isMobileSeparatedMenuScrolling?: boolean;
28
- setIsMobileSeparatedMenuScrolling?: (isScrolling: boolean) => void;
28
+ scrollState?: ScrollContainerScrollStateY;
29
+ setScrollState?: (state: ScrollContainerScrollStateY) => void;
30
+ hasScrollBar?: boolean;
31
+ setHasScrollBar?: (hasScrollBar: boolean) => void;
29
32
  }
30
33
  export declare const SideMenuContext: import("react").Context<SideMenuContextType>;