@skbkontur/side-menu 2.0.0 → 2.1.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,33 @@
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
+ # [2.1.0](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@2.0.2...@skbkontur/side-menu@2.1.0) (2024-07-19)
7
+
8
+
9
+ ### Features
10
+
11
+ * **SideMenu:** add isPinned prop ([3e6e080](https://git.skbkontur.ru/ui/ui-parking/commits/3e6e080f37054e0e86ded3034a4975b0c99a2942))
12
+
13
+
14
+
15
+
16
+
17
+ ## [2.0.2](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@2.0.0...@skbkontur/side-menu@2.0.2) (2024-07-18)
18
+
19
+ **Note:** Version bump only for package @skbkontur/side-menu
20
+
21
+
22
+
23
+
24
+
25
+ ## [2.0.1](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@2.0.0...@skbkontur/side-menu@2.0.1) (2024-07-18)
26
+
27
+ **Note:** Version bump only for package @skbkontur/side-menu
28
+
29
+
30
+
31
+
32
+
6
33
  # [2.0.0](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@1.12.9...@skbkontur/side-menu@2.0.0) (2024-07-09)
7
34
 
8
35
 
package/README.md CHANGED
@@ -525,6 +525,42 @@ const [isOpen, setIsOpen] = React.useState(true);
525
525
  </div>
526
526
  ```
527
527
 
528
+ #### Пример с использованием пропа `isPinned`
529
+
530
+ ```jsx harmony
531
+ import { Kontur, Ofd } from '@skbkontur/logos';
532
+ import { SideMenu } from './index';
533
+ import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
534
+ import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
535
+ import { ThemeContext, ThemeFactory, Button } from '@skbkontur/react-ui';
536
+
537
+ const [isPinned, setIsPinned] = React.useState(localStorage.getItem('sideMenuIsPinned') === 'true');
538
+
539
+ React.useEffect(() => {
540
+ window.addEventListener('storage', () => {
541
+ setIsPinned(localStorage.getItem('sideMenuIsPinned') === 'true');
542
+ });
543
+ }, []);
544
+
545
+ <div style={{ height: '200px', position: 'relative', display: 'flex' }}>
546
+ <ThemeContext.Provider
547
+ value={ThemeFactory.create({ sideMenuWidth: '300px', sideMenuProductColor: '#64b419' })}>
548
+ <SideMenu isPinned={isPinned}
549
+ onPinnedValueChange={(isPinned) => {
550
+ localStorage.setItem('sideMenuIsPinned', String(isPinned));
551
+ }}>
552
+ <SideMenu.Header konturLogo={<Kontur />} productLogo={<Ofd />} />
553
+ <SideMenu.Body>
554
+ <SideMenu.Item icon={<DocTextIcon24Regular />} caption={'Документы к подписанию'} />
555
+ </SideMenu.Body>
556
+ <SideMenu.Footer>
557
+ <SideMenu.Item icon={<SettingsGearIcon24Regular />} caption={'Реквизиты и настройки'} />
558
+ </SideMenu.Footer>
559
+ </SideMenu>
560
+ </ThemeContext.Provider>
561
+ </div>
562
+ ```
563
+
528
564
  #### Переменные кастомизации (см. [ThemeContext](https://tech.skbkontur.ru/react-ui/#/Customization/ThemeContext))
529
565
 
530
566
  ```typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skbkontur/side-menu",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@skbkontur/icons": "^1.10.0",
26
- "@skbkontur/react-ui-addons": "^4.11.2",
26
+ "@skbkontur/react-ui-addons": "^4.11.4",
27
27
  "tslib": "^1"
28
28
  }
29
29
  }
@@ -34,7 +34,7 @@ export declare class MenuNavigation {
34
34
  private readonly isOpened?;
35
35
  private readonly isDesktop?;
36
36
  private readonly isMobile?;
37
- private readonly isCollapsable?;
37
+ isCollapsable?: boolean;
38
38
  constructor(options: MenuNavigationOptions);
39
39
  updateNavigationTree(): void;
40
40
  addValue(id: string, value: NavigableElement): void;
@@ -16,7 +16,18 @@ export declare type showScrollBarType = 'always' | 'scroll' | 'hover' | 'never';
16
16
  export interface SideMenuProps extends CommonProps {
17
17
  children?: React.ReactNode;
18
18
  size?: 'small' | 'large';
19
+ /**
20
+ * Проп для отображения подменю в отдельной колонке
21
+ */
19
22
  isSeparatedMenu?: boolean;
23
+ /**
24
+ * Проп для закрепленного состояния (работает только на широких экранах)
25
+ */
26
+ isPinned?: boolean;
27
+ /**
28
+ * Коллбэк для закрепленного состояния (работает только на широких экранах)
29
+ */
30
+ onPinnedValueChange?: (isPinned: boolean) => void;
20
31
  /**
21
32
  * @deprecated use disableCollapsing
22
33
  */
@@ -33,7 +33,7 @@ export var burgerTransitionDuration = (transitionDuration * 2) / 3;
33
33
  var SideMenuInner = forwardRef(function (_a, ref) {
34
34
  var _b, _c, _d, _e;
35
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"]);
36
+ var children = _a.children, value = _a.value, activeItem = _a.activeItem, _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, isPinned = _a.isPinned, onValueChange = _a.onValueChange, onActiveItemChange = _a.onActiveItemChange, onOpen = _a.onOpen, onClose = _a.onClose, onPinnedValueChange = _a.onPinnedValueChange, rest = __rest(_a, ["children", "value", "activeItem", "size", "isSeparatedMenu", "className", "disableSwipe", "disableCollapsing", "desktopMediaQuery", "narrowDesktopMediaQuery", "tabletMediaQuery", "mobileMediaQuery", "hideScrollBar", "showScrollBar", "isOpen", "isPinned", "onValueChange", "onActiveItemChange", "onOpen", "onClose", "onPinnedValueChange"]);
37
37
  var transitionTimer = useRef(null);
38
38
  var sideMenuRef = useRef(null);
39
39
  var contentWrapperRef = useRef(null);
@@ -55,7 +55,7 @@ var SideMenuInner = forwardRef(function (_a, ref) {
55
55
  var isTabletOrMobile = isTablet || isMobile;
56
56
  var isTouchScreen = isTouchDevice() || isMobile || isTablet;
57
57
  var manual = isOpen !== undefined;
58
- var _q = __read(useState(isDesktopQuery), 2), isOpened = _q[0], setIsOpened = _q[1];
58
+ var _q = __read(useState(isDesktopQuery && !isPinned), 2), isOpened = _q[0], setIsOpened = _q[1];
59
59
  var _r = __read(useState(false), 2), isBeingTransitioned = _r[0], setIsBeingTransitioned = _r[1];
60
60
  var _s = __read(useState(value !== null && value !== void 0 ? value : activeItem), 2), activeMenuItem = _s[0], setActiveMenuItem = _s[1];
61
61
  var _t = __read(useState(false), 2), isSeparatedMenuShown = _t[0], setIsSeparatedMenuShown = _t[1];
@@ -64,7 +64,7 @@ var SideMenuInner = forwardRef(function (_a, ref) {
64
64
  var _w = __read(useState(false), 2), hasScrollBar = _w[0], setHasScrollBar = _w[1];
65
65
  var _x = __read(useState(0), 2), mousePositionX = _x[0], setMousePositionX = _x[1];
66
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];
67
+ var _z = __read(useState(isNarrowDesktop || (isDesktopQuery && isPinned)), 2), isCollapsable = _z[0], setIsCollapsable = _z[1];
68
68
  var _0 = __read(useState(0), 2), leftPosition = _0[0], setLeftPosition = _0[1];
69
69
  var _1 = __read(useState(false), 2), isHovered = _1[0], setIsHovered = _1[1];
70
70
  var switchActiveMenuItem = function (id) {
@@ -107,6 +107,9 @@ var SideMenuInner = forwardRef(function (_a, ref) {
107
107
  setHasScrollBar(scrollContainer.clientHeight < contentWrapper.scrollHeight);
108
108
  }, 50);
109
109
  }, [activeMenuItem, isOpened, isBeingTransitioned]);
110
+ useEffect(function () {
111
+ isDesktopQuery && setIsOpened(!isPinned);
112
+ }, [isPinned, isDesktopQuery]);
110
113
  var handleIsOpened = function (newIsOpened, shouldSetState) {
111
114
  if (newIsOpened === isOpened || !shouldSetState)
112
115
  return;
@@ -119,7 +122,7 @@ var SideMenuInner = forwardRef(function (_a, ref) {
119
122
  }
120
123
  };
121
124
  useEffect(function () {
122
- if (isDesktopQuery) {
125
+ if (isDesktopQuery && !isPinned) {
123
126
  setIsOpened(true);
124
127
  setIsCollapsable(false);
125
128
  }
@@ -127,7 +130,13 @@ var SideMenuInner = forwardRef(function (_a, ref) {
127
130
  setIsOpened(false);
128
131
  }
129
132
  isNarrowDesktop && setIsCollapsable(true);
130
- }, [isNarrowDesktop, isDesktopQuery, isTablet, isMobile]);
133
+ if (isDesktopQuery && isPinned) {
134
+ setIsCollapsable(true);
135
+ if (navigation.current) {
136
+ navigation.current.isCollapsable = true;
137
+ }
138
+ }
139
+ }, [isNarrowDesktop, isDesktopQuery, isTablet, isMobile, isPinned]);
131
140
  useEffect(function () {
132
141
  var _a;
133
142
  !activeItem && ((_a = navigation.current) === null || _a === void 0 ? void 0 : _a.switchActiveMenuItem(value));
@@ -155,17 +164,21 @@ var SideMenuInner = forwardRef(function (_a, ref) {
155
164
  }, transitionDuration + 200);
156
165
  }
157
166
  };
167
+ var shouldNotOpenOnHover = (isSeparatedMenu && isSeparatedMenuShown && isNarrowDesktop && manual) || isTouchScreen;
158
168
  var handleMouseEnter = function () {
159
- setIsHovered(true);
160
- if ((isSeparatedMenu && isSeparatedMenuShown && isNarrowDesktop && manual) || isTouchScreen) {
169
+ if (shouldNotOpenOnHover) {
161
170
  return;
162
171
  }
172
+ setIsHovered(true);
163
173
  if (isCollapsable && !isOpened && !isSeparatedMenuShown) {
164
174
  isMouseOutside && showMinimizedRoot(false);
165
175
  setIsMouseOutside(false);
166
176
  }
167
177
  };
168
178
  var handleMouseLeave = function () {
179
+ if (shouldNotOpenOnHover) {
180
+ return;
181
+ }
169
182
  setIsHovered(false);
170
183
  if (isCollapsable) {
171
184
  handleIsOpened(false, !manual);
@@ -216,13 +229,11 @@ var SideMenuInner = forwardRef(function (_a, ref) {
216
229
  return 'never';
217
230
  };
218
231
  var handleRightBorderClick = function () {
219
- if (isCollapsable) {
220
- setIsCollapsable(false);
221
- }
222
- else {
232
+ if (!isCollapsable) {
223
233
  setIsOpened(false);
224
- setIsCollapsable(true);
225
234
  }
235
+ onPinnedValueChange === null || onPinnedValueChange === void 0 ? void 0 : onPinnedValueChange(!isCollapsable);
236
+ setIsCollapsable(!isCollapsable);
226
237
  };
227
238
  return (React.createElement(SideMenuContext.Provider, { value: {
228
239
  isOpened: isOpened,