@skbkontur/side-menu 1.0.2 → 1.2.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,29 @@
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
+ # [1.2.0](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@1.1.0...@skbkontur/side-menu@1.2.0) (2023-08-18)
7
+
8
+
9
+ ### Features
10
+
11
+ * **SideMenuAvatar:** add caption prop ([275f38b](https://git.skbkontur.ru/ui/ui-parking/commits/275f38b68e12e0d294a8be49222e60a9efb5f8bf))
12
+ * **SideMenuDropdown:** add prop marker ([ae9e880](https://git.skbkontur.ru/ui/ui-parking/commits/ae9e8803d01ce4ffeeb74541e62a10cec3ccb233))
13
+
14
+
15
+
16
+
17
+
18
+ # [1.1.0](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@1.0.2...@skbkontur/side-menu@1.1.0) (2023-08-07)
19
+
20
+
21
+ ### Features
22
+
23
+ * **SideMenu:** add component prop to link ([2beb8b3](https://git.skbkontur.ru/ui/ui-parking/commits/2beb8b3cbd81830542554a18fbc26a9a7b2119b0))
24
+
25
+
26
+
27
+
28
+
6
29
  ## [1.0.2](https://git.skbkontur.ru/ui/ui-parking/compare/@skbkontur/side-menu@1.0.1...@skbkontur/side-menu@1.0.2) (2023-08-04)
7
30
 
8
31
 
package/README.md CHANGED
@@ -1,5 +1,3 @@
1
- ### Бета-версия компонента SideMenu
2
-
3
1
  SideMenu в фирменном стиле (макеты живут [здесь](https://www.figma.com/file/XA8Ytcx8bxemYAkF7eGVSv/%D0%9A%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82-%D0%BB%D0%B5%D0%B2%D0%BE%D0%B3%D0%BE-%D0%BC%D0%B5%D0%BD%D1%8E?node-id=0%3A1)).
4
2
 
5
3
  [Пример в песочнице](https://codesandbox.io/s/competent-wiles-k85wlm)
@@ -9,17 +7,15 @@ import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
9
7
  import { Kontur, Ofd } from '@skbkontur/logos';
10
8
  import { ThemeContext, ThemeFactory, MenuItem, MenuSeparator, THEME_2022 } from '@skbkontur/react-ui';
11
9
  import { SideMenu } from './index';
12
- import {
13
- DocTextIcon24Regular,
14
- CommentRectTextIcon24Regular,
15
- LightbulbIcon24Regular,
16
- BookOpenTextIcon24Regular,
17
- BookmarkIcon24Regular,
18
- StackHDownIcon24Regular,
19
- SettingsGearIcon24Regular,
20
- FaceAHappyIcon24Regular,
21
- AttachLinkIcon,
22
- } from '@skbkontur/icons';
10
+ import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
11
+ import { CommentRectTextIcon24Regular } from '@skbkontur/icons/icons/CommentRectTextIcon/CommentRectTextIcon24Regular';
12
+ import { LightbulbIcon24Regular } from '@skbkontur/icons/icons/LightbulbIcon/LightbulbIcon24Regular';
13
+ import { BookOpenTextIcon24Regular } from '@skbkontur/icons/icons/BookOpenTextIcon/BookOpenTextIcon24Regular';
14
+ import { BookmarkIcon24Regular } from '@skbkontur/icons/icons/BookmarkIcon/BookmarkIcon24Regular';
15
+ import { StackHDownIcon24Regular } from '@skbkontur/icons/icons/StackHDownIcon/StackHDownIcon24Regular';
16
+ import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
17
+ import { FaceAHappyIcon24Regular } from '@skbkontur/icons/icons/FaceAHappyIcon/FaceAHappyIcon24Regular';
18
+ import { AttachLinkIcon } from '@skbkontur/icons/icons/AttachLinkIcon';
23
19
 
24
20
  <div style={{height: '600px', position: 'relative'}}>
25
21
  <ThemeContext.Provider value={ThemeFactory.create({ sideMenuProductColor: '#64b419' }, THEME_2022)}>
@@ -32,7 +28,7 @@ import {
32
28
  <SideMenu.SubItem caption={'Исходящие1'}/>
33
29
  <SideMenu.SubItem caption={'Исходящие2'}/>
34
30
  </SideMenu.SubItem>
35
- <SideMenu.SubItem caption={'Внутренние'}/>
31
+ <SideMenu.SubItem caption={'Внутренние'} marker/>
36
32
  <SideMenu.SubItem caption={'Черновики'}/>
37
33
  <SideMenu.SubItem caption={'Удаленные'}/>
38
34
  <SideMenu.SubLink caption={'Cсылка в подменю'} href={'https://www.google.com/search?q=test'} target={'_blank'}/>
@@ -40,7 +36,7 @@ import {
40
36
  <SideMenu.SubItem caption={'Требуют обработки'}/>
41
37
  <SideMenu.SubItem caption={'Обработанные'}/>
42
38
  </SideMenu.Item>
43
- <SideMenu.Item icon={<FaceAHappyIcon24Regular />} caption={'Контрагенты'}/>
39
+ <SideMenu.Item icon={<FaceAHappyIcon24Regular />} caption={'Контрагенты'} marker/>
44
40
  <SideMenu.Item icon={<CommentRectTextIcon24Regular/>} caption={'Сообщения'} marker={'5'}>
45
41
  <SideMenu.SubItem caption={'Входящие'} marker={'5'}/>
46
42
  <SideMenu.SubItem caption={'Исходящие'}/>
@@ -90,16 +86,14 @@ import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
90
86
  import { Buhgalteria, Kontur } from '@skbkontur/logos';
91
87
  import { ThemeContext, ThemeFactory, MenuItem, Modal, Input, MenuSeparator, THEME_2022 } from '@skbkontur/react-ui';
92
88
  import { SideMenu } from './index';
93
- import {
94
- DocTextIcon24Regular,
95
- CommentRectTextIcon24Regular,
96
- LightbulbIcon24Regular,
97
- BookOpenTextIcon24Regular,
98
- BookmarkIcon24Regular,
99
- StackHDownIcon24Regular,
100
- SettingsGearIcon24Regular,
101
- FaceAHappyIcon24Regular
102
- } from '@skbkontur/icons';
89
+ import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
90
+ import { CommentRectTextIcon24Regular } from '@skbkontur/icons/icons/CommentRectTextIcon/CommentRectTextIcon24Regular';
91
+ import { LightbulbIcon24Regular } from '@skbkontur/icons/icons/LightbulbIcon/LightbulbIcon24Regular';
92
+ import { BookOpenTextIcon24Regular } from '@skbkontur/icons/icons/BookOpenTextIcon/BookOpenTextIcon24Regular';
93
+ import { BookmarkIcon24Regular } from '@skbkontur/icons/icons/BookmarkIcon/BookmarkIcon24Regular';
94
+ import { StackHDownIcon24Regular } from '@skbkontur/icons/icons/StackHDownIcon/StackHDownIcon24Regular';
95
+ import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
96
+ import { FaceAHappyIcon24Regular } from '@skbkontur/icons/icons/FaceAHappyIcon/FaceAHappyIcon24Regular';
103
97
 
104
98
  const [opened, setOpened] = React.useState(false);
105
99
  const [panel, setPanel] = React.useState(false);
@@ -217,17 +211,15 @@ import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
217
211
  import { Kontur, Ofd } from '@skbkontur/logos';
218
212
  import { ThemeContext, ThemeFactory, MenuItem, Select, Switcher, MenuSeparator, THEME_2022 } from '@skbkontur/react-ui';
219
213
  import { SideMenu } from './index';
220
- import {
221
- DocTextIcon24Regular,
222
- CommentRectTextIcon24Regular,
223
- LightbulbIcon24Regular,
224
- BookOpenTextIcon24Regular,
225
- BookmarkIcon24Regular,
226
- StackHDownIcon24Regular,
227
- SettingsGearIcon24Regular,
228
- FaceAHappyIcon24Regular,
229
- AttachLinkIcon24Regular
230
- } from '@skbkontur/icons';
214
+ import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
215
+ import { CommentRectTextIcon24Regular } from '@skbkontur/icons/icons/CommentRectTextIcon/CommentRectTextIcon24Regular';
216
+ import { LightbulbIcon24Regular } from '@skbkontur/icons/icons/LightbulbIcon/LightbulbIcon24Regular';
217
+ import { BookOpenTextIcon24Regular } from '@skbkontur/icons/icons/BookOpenTextIcon/BookOpenTextIcon24Regular';
218
+ import { BookmarkIcon24Regular } from '@skbkontur/icons/icons/BookmarkIcon/BookmarkIcon24Regular';
219
+ import { StackHDownIcon24Regular } from '@skbkontur/icons/icons/StackHDownIcon/StackHDownIcon24Regular';
220
+ import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
221
+ import { FaceAHappyIcon24Regular } from '@skbkontur/icons/icons/FaceAHappyIcon/FaceAHappyIcon24Regular';
222
+ import { AttachLinkIcon } from '@skbkontur/icons/icons/AttachLinkIcon';
231
223
 
232
224
 
233
225
  const [activeItem, setActiveItem] = useState('122');
@@ -352,16 +344,15 @@ import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
352
344
  import { Kontur, Ofd } from '@skbkontur/logos';
353
345
  import { ThemeContext, ThemeFactory, MenuItem, Select, Switcher, MenuSeparator, THEME_2022 } from '@skbkontur/react-ui';
354
346
  import { SideMenu } from './index';
355
- import {
356
- DocTextIcon24Regular,
357
- CommentRectTextIcon24Regular,
358
- LightbulbIcon24Regular,
359
- BookOpenTextIcon24Regular,
360
- BookmarkIcon24Regular,
361
- StackHDownIcon24Regular,
362
- SettingsGearIcon24Regular,
363
- FaceAHappyIcon24Regular
364
- } from '@skbkontur/icons';
347
+ import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
348
+ import { CommentRectTextIcon24Regular } from '@skbkontur/icons/icons/CommentRectTextIcon/CommentRectTextIcon24Regular';
349
+ import { LightbulbIcon24Regular } from '@skbkontur/icons/icons/LightbulbIcon/LightbulbIcon24Regular';
350
+ import { BookOpenTextIcon24Regular } from '@skbkontur/icons/icons/BookOpenTextIcon/BookOpenTextIcon24Regular';
351
+ import { BookmarkIcon24Regular } from '@skbkontur/icons/icons/BookmarkIcon/BookmarkIcon24Regular';
352
+ import { StackHDownIcon24Regular } from '@skbkontur/icons/icons/StackHDownIcon/StackHDownIcon24Regular';
353
+ import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
354
+ import { FaceAHappyIcon24Regular } from '@skbkontur/icons/icons/FaceAHappyIcon/FaceAHappyIcon24Regular';
355
+
365
356
 
366
357
 
367
358
  const [activeItem, setActiveItem] = useState(undefined);
@@ -591,15 +582,37 @@ import { useHistory } from "react-router-dom";
591
582
 
592
583
  При необходимости вы можете повторить часть этой логики в своей обёртке.
593
584
 
585
+ ---
586
+
587
+ Также можно использовать `SideMenu.Link` передав туда компонент ссылки, например обертку со ссылкой из `react-router-dom`:
588
+
589
+ ```ts static
590
+ import { Link } from 'react-router-dom';
591
+
592
+ interface SideMenuReactRouterLinkProps extends SideMenuLinkProps {
593
+ href: string;
594
+ }
595
+
596
+ const LinkWrapper = React.forwardRef<HTMLAnchorElement, SideMenuReactRouterLinkProps>(({ href, ...rest }, ref) => (
597
+ <Link {...rest} to={href} ref={ref} />
598
+ ));
599
+
600
+ const SideMenuReactRouterLink: React.FunctionComponent<SideMenuReactRouterLinkProps> = (props) => (
601
+ <SideMenu.Link {...props} component={LinkWrapper} />
602
+ );
603
+ ```
604
+
605
+ Если вы используете кастомную ссылку, то убедитесь, что она прокидывает `ref` и остальные пропсы в корневой элемент.
606
+
607
+ Пример в [песочнице](https://codesandbox.io/s/side-menu-react-router-dom-vtv6r8)
608
+
594
609
  #### Пример кастомизации
595
610
 
596
611
  ```jsx harmony
597
612
  import { Kontur, Ofd } from '@skbkontur/logos';
598
613
  import { SideMenu } from './index';
599
- import {
600
- DocTextIcon24Regular,
601
- SettingsGearIcon24Regular,
602
- } from '@skbkontur/icons';
614
+ import { DocTextIcon24Regular } from '@skbkontur/icons/icons/DocTextIcon/DocTextIcon24Regular';
615
+ import { SettingsGearIcon24Regular } from '@skbkontur/icons/icons/SettingsGearIcon/SettingsGearIcon24Regular';
603
616
  import { ThemeContext, ThemeFactory } from '@skbkontur/react-ui';
604
617
 
605
618
  <div style={{ height: '200px', position: 'relative' }}>
@@ -1,5 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
- import { ArrowCDownIcon16Regular, ArrowCRightIcon16Regular } from '@skbkontur/icons';
2
+ import { ArrowCDownIcon16Regular } from '@skbkontur/icons/icons/ArrowCDownIcon/ArrowCDownIcon16Regular';
3
+ import { ArrowCRightIcon16Regular } from '@skbkontur/icons/icons/ArrowCRightIcon/ArrowCRightIcon16Regular';
3
4
  export var useMemoIcon = function (children, isOpened) {
4
5
  return useMemo(function () {
5
6
  if (children) {
@@ -5,7 +5,7 @@ interface UseNumberOfTextLinesInItem {
5
5
  setLinesNumber: React.Dispatch<React.SetStateAction<number>>;
6
6
  theme: SideMenuTheme;
7
7
  caption?: string;
8
- marker?: string;
8
+ marker?: string | boolean;
9
9
  size?: 'small' | 'large';
10
10
  isTouchScreen?: boolean;
11
11
  }
@@ -16,7 +16,7 @@ var getNumberOfLines = function (ctx, words, containerWidth) {
16
16
  });
17
17
  return lineCount;
18
18
  };
19
- var getContainerWidth = function (ctx, marker, theme, isTouchScreen) {
19
+ var getContainerWidth = function (ctx, theme, marker, isTouchScreen) {
20
20
  var containerWidth = parseInt(isTouchScreen ? theme.sideMenuWidthForTouchScreens : theme.sideMenuWidth) -
21
21
  2 * parseInt(theme.sideMenuMarginX) -
22
22
  parseInt(theme.sideMenuIconSize) -
@@ -24,7 +24,17 @@ var getContainerWidth = function (ctx, marker, theme, isTouchScreen) {
24
24
  var markerPaddings = marker
25
25
  ? 2 * parseInt(theme.sideMenuMarkerPaddingX) + parseInt(theme.sideMenuMarkerMarginRight)
26
26
  : 0;
27
- var markerWidth = ctx.measureText(marker).width + markerPaddings;
27
+ var emptyMarker = marker === true || marker === '';
28
+ var markerWidth;
29
+ if (emptyMarker) {
30
+ markerWidth = 8;
31
+ }
32
+ else if (typeof marker === 'string') {
33
+ markerWidth = ctx.measureText(marker).width + markerPaddings;
34
+ }
35
+ else {
36
+ markerWidth = 0;
37
+ }
28
38
  return containerWidth - markerWidth - parseInt(sideMenuCaptionMarginRight);
29
39
  };
30
40
  var getFontSize = function (theme, isTouchScreen, size) {
@@ -39,7 +49,7 @@ var getFontSize = function (theme, isTouchScreen, size) {
39
49
  }
40
50
  };
41
51
  export var useNumberOfTextLinesInItem = function (_a) {
42
- var textRef = _a.textRef, setLinesNumber = _a.setLinesNumber, theme = _a.theme, _b = _a.caption, caption = _b === void 0 ? '' : _b, _c = _a.marker, marker = _c === void 0 ? '' : _c, size = _a.size, isTouchScreen = _a.isTouchScreen;
52
+ var textRef = _a.textRef, setLinesNumber = _a.setLinesNumber, theme = _a.theme, _b = _a.caption, caption = _b === void 0 ? '' : _b, marker = _a.marker, size = _a.size, isTouchScreen = _a.isTouchScreen;
43
53
  var fontSize = getFontSize(theme, isTouchScreen, size);
44
54
  var fontFamily = textRef.current && isBrowser
45
55
  ? window.getComputedStyle(textRef.current).getPropertyValue('font-family')
@@ -49,6 +59,6 @@ export var useNumberOfTextLinesInItem = function (_a) {
49
59
  if (ctx) {
50
60
  ctx.font = fontSize + "px " + fontFamily;
51
61
  var words = caption.split(' ');
52
- setLinesNumber(getNumberOfLines(ctx, words, getContainerWidth(ctx, marker, theme, isTouchScreen)));
62
+ setLinesNumber(getNumberOfLines(ctx, words, getContainerWidth(ctx, theme, marker, isTouchScreen)));
53
63
  }
54
64
  };
@@ -71,6 +71,7 @@ export declare class SideMenuTheme extends SideMenuTheme_base {
71
71
  static sideMenuMarkerPaddingY: string;
72
72
  static get sideMenuMarkerBg(): string;
73
73
  static sideMenuMarkerColor: string;
74
+ static sideMenuSubItemEmptyMarkerBg: string;
74
75
  static get sideMenuMarkerSubItemColor(): string;
75
76
  static sideMenuMarkerMarginRight: string;
76
77
  static sideMenuMarkerFontWeight: string;
@@ -185,6 +185,7 @@ var SideMenuTheme = /** @class */ (function (_super) {
185
185
  SideMenuTheme.sideMenuMarkerPaddingX = '6px';
186
186
  SideMenuTheme.sideMenuMarkerPaddingY = '0px';
187
187
  SideMenuTheme.sideMenuMarkerColor = '#fff';
188
+ SideMenuTheme.sideMenuSubItemEmptyMarkerBg = '#adadad';
188
189
  SideMenuTheme.sideMenuMarkerMarginRight = '8px';
189
190
  SideMenuTheme.sideMenuMarkerFontWeight = '600';
190
191
  SideMenuTheme.sideMenuSubItemMarkerFontWeight = '400';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skbkontur/side-menu",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -22,7 +22,7 @@
22
22
  "@skbkontur/react-ui": "4.13.0"
23
23
  },
24
24
  "dependencies": {
25
- "@skbkontur/icons": "^0.17.2",
25
+ "@skbkontur/icons": "^1.4.3",
26
26
  "@skbkontur/react-ui-addons": "^4.9.0",
27
27
  "tslib": "^1"
28
28
  }
@@ -7,7 +7,7 @@ var styles = {
7
7
  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 "])));
8
8
  },
9
9
  shownRootForTabletsOrMobiles: function () {
10
- return css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n height: 100vh;\n transition: height ", "ms ease-out;\n "], ["\n height: 100vh;\n transition: height ", "ms ease-out;\n "])), burgerTransitionDuration);
10
+ return css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n @supports (height: 100dvh) {\n height: 100dvh;\n }\n height: 100%;\n transition: height ", "ms ease-out;\n "], ["\n @supports (height: 100dvh) {\n height: 100dvh;\n }\n height: 100%;\n transition: height ", "ms ease-out;\n "])), burgerTransitionDuration);
11
11
  },
12
12
  rootForNarrowDesktops: function (t) {
13
13
  return css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n width: ", ";\n "], ["\n width: ", ";\n "])), t.sideMenuMinimizedWidth);
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { UserAvatarProps } from '@skbkontur/react-ui-addons/';
3
3
  import { SideMenuDropdownProps } from '../SideMenuDropdown/SideMenuDropdown';
4
- export interface SideMenuAvatarProps extends Omit<UserAvatarProps, 'style'>, Omit<SideMenuDropdownProps, 'icon' | 'caption'>, Partial<Pick<SideMenuDropdownProps, 'icon' | 'onOpen' | 'onClose'>> {
4
+ export interface SideMenuAvatarProps extends Omit<UserAvatarProps, 'style'>, Omit<SideMenuDropdownProps, 'icon'>, Partial<Pick<SideMenuDropdownProps, 'icon' | 'onOpen' | 'onClose'>> {
5
5
  }
6
6
  /**
7
7
  * Аватар пользователя
@@ -5,9 +5,9 @@ import { SideMenuDropdown } from '../SideMenuDropdown/SideMenuDropdown';
5
5
  import { getSideMenuTheme } from '../../lib/theming/ThemeHelpers';
6
6
  import { ThemeContext } from '@skbkontur/react-ui';
7
7
  var SideMenuAvatarInner = forwardRef(function (_a, ref) {
8
- var userName = _a.userName, avatarUrl = _a.avatarUrl, children = _a.children, icon = _a.icon, rest = __rest(_a, ["userName", "avatarUrl", "children", "icon"]);
8
+ var userName = _a.userName, avatarUrl = _a.avatarUrl, children = _a.children, icon = _a.icon, caption = _a.caption, rest = __rest(_a, ["userName", "avatarUrl", "children", "icon", "caption"]);
9
9
  var theme = getSideMenuTheme(useContext(ThemeContext));
10
- return (React.createElement(SideMenuDropdown, __assign({ icon: React.createElement(UserAvatar, { userName: userName, avatarUrl: avatarUrl, style: { width: theme.sideMenuAvatarSize, height: theme.sideMenuAvatarSize } }), caption: userName, menuWidth: 200, positions: ['top left'], _isAvatar: true, ref: ref }, rest), children));
10
+ return (React.createElement(SideMenuDropdown, __assign({ icon: React.createElement(UserAvatar, { userName: userName, avatarUrl: avatarUrl, style: { width: theme.sideMenuAvatarSize, height: theme.sideMenuAvatarSize } }), caption: userName || caption, menuWidth: 200, positions: ['top left'], _isAvatar: true, ref: ref }, rest), children));
11
11
  });
12
12
  SideMenuAvatarInner.displayName = 'SideMenuAvatar';
13
13
  /**
@@ -1,3 +1,24 @@
1
+ Передача пропа `userName` позволяет использовать иконку с инициалами, а передача пропа `caption` позволяет использовать иконку силуэта
2
+ ```jsx harmony
3
+ import { SideMenu } from '../../index';
4
+ import { getKonturAvatarUrl } from '@skbkontur/react-ui-addons';
5
+
6
+ <SideMenu>
7
+ <SideMenu.Footer>
8
+ <SideMenu.Avatar caption={'Елена Ишматова'} />
9
+ <SideMenu.Avatar
10
+ userName={'Елена Ишматова'}
11
+ />
12
+ <SideMenu.Avatar
13
+ userName={'Елена Ишматова'}
14
+ avatarUrl={getKonturAvatarUrl({
15
+ userId: '992408aa-050e-41e9-9a48-6bf2f2f20d94'
16
+ })}
17
+ />
18
+ </SideMenu.Footer>
19
+ </SideMenu>
20
+ ```
21
+
1
22
  #### Переменные кастомизации (см. [ThemeContext](https://tech.skbkontur.ru/react-ui/#/Customization/ThemeContext))
2
23
 
3
24
  ```typescript
@@ -5,3 +26,4 @@
5
26
  sideMenuAvatarMargin: string;
6
27
  }
7
28
  ```
29
+
@@ -2,7 +2,7 @@ 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' | 'id' | '_generatedId' | 'subCaption' | '_isAvatar'> {
5
+ export interface SideMenuDropdownProps extends CommonProps, Omit<DropdownMenuProps, 'caption' | 'disableAnimations'>, Pick<SideMenuItemProps, 'icon' | 'caption' | 'marker' | 'id' | '_generatedId' | 'subCaption' | '_isAvatar'> {
6
6
  children?: React.ReactNode;
7
7
  disableAnimations?: boolean;
8
8
  id?: string;
@@ -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, _d = _a.caption, caption = _d === void 0 ? 'СКБ Контур' : _d, subCaption = _a.subCaption, className = _a.className, _e = _a.disableAnimations, disableAnimations = _e === void 0 ? false : _e, menuWidth = _a.menuWidth, _isAvatar = _a._isAvatar, rest = __rest(_a, ["icon", "id", "_generatedId", "children", "caption", "subCaption", "className", "disableAnimations", "menuWidth", "_isAvatar"]);
11
+ var icon = _a.icon, id = _a.id, _generatedId = _a._generatedId, children = _a.children, _d = _a.caption, caption = _d === void 0 ? 'СКБ Контур' : _d, marker = _a.marker, subCaption = _a.subCaption, className = _a.className, _e = _a.disableAnimations, disableAnimations = _e === void 0 ? false : _e, menuWidth = _a.menuWidth, _isAvatar = _a._isAvatar, rest = __rest(_a, ["icon", "id", "_generatedId", "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 },
@@ -17,7 +17,7 @@ var SideMenuDropdownInner = forwardRef(function (_a, ref) {
17
17
  _c[jsStyles.labelForTouchScreens(theme)] = context.isTouchScreen,
18
18
  _c[jsStyles.minimizedLabel()] = context.isMinimized,
19
19
  _c)) },
20
- React.createElement(SideMenuItem, { icon: icon, caption: caption, subCaption: subCaption, id: id, _isDropdown: true, _isAvatar: _isAvatar })), positions: ['top left'], disableAnimations: true, menuWidth: menuWidth }, rest), React.Children.map(children, function (child) {
20
+ React.createElement(SideMenuItem, { icon: icon, caption: caption, subCaption: subCaption, marker: marker, id: id, _isDropdown: true, _isAvatar: _isAvatar })), positions: ['top left'], disableAnimations: true, menuWidth: menuWidth }, rest), React.Children.map(children, function (child) {
21
21
  // @ts-expect-error: accessing private property
22
22
  if (React.isValidElement(child) && (child === null || child === void 0 ? void 0 : child.type.__KONTUR_REACT_UI__) === 'MenuItem') {
23
23
  return React.cloneElement(child, {
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { CommonClickableElementProps } from '../internal/ClickableElement';
3
3
  export interface SideMenuItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, CommonClickableElementProps {
4
+ component?: React.ComponentType<any>;
4
5
  }
5
6
  /**
6
7
  * Элемент списка
@@ -1,8 +1,9 @@
1
- import { __assign } from "tslib";
1
+ import { __assign, __rest } from "tslib";
2
2
  import React, { forwardRef } from 'react';
3
3
  import { ClickableElement } from '../internal/ClickableElement';
4
- var SideMenuItemInner = forwardRef(function (props, ref) {
5
- return React.createElement(ClickableElement, __assign({}, props, { ref: ref, element: 'button' }));
4
+ var SideMenuItemInner = forwardRef(function (_a, ref) {
5
+ var component = _a.component, rest = __rest(_a, ["component"]);
6
+ return React.createElement(ClickableElement, __assign({}, rest, { ref: ref, element: component !== null && component !== void 0 ? component : 'button' }));
6
7
  });
7
8
  SideMenuItemInner.displayName = 'SideMenuItem';
8
9
  /**
@@ -58,6 +58,7 @@
58
58
  sideMenuMarkerPaddingX: string;
59
59
  sideMenuMarkerPaddingY: string;
60
60
  sideMenuMarkerBg: string;
61
+ sideMenuSubItemEmptyMarkerBg: string;
61
62
  sideMenuMarkerColor: string;
62
63
  sideMenuMarkerSubItemColor: string;
63
64
  sideMenuMarkerMarginRight: string;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { CommonClickableElementProps } from '../internal/ClickableElement';
3
3
  export interface SideMenuLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement>, CommonClickableElementProps {
4
+ component?: React.ComponentType<any>;
4
5
  }
5
6
  /**
6
7
  * Ссылка для `SideMenu`
@@ -5,8 +5,8 @@ import { jsStyles } from './SideMenuLink.styles';
5
5
  import { cx } from '@skbkontur/react-ui/lib/theming/Emotion';
6
6
  var SideMenuLinkInner = forwardRef(function (_a, ref) {
7
7
  var _b;
8
- var className = _a.className, rest = __rest(_a, ["className"]);
9
- return React.createElement(ClickableElement, __assign({}, rest, { ref: ref, element: 'a', className: cx((_b = {}, _b[jsStyles.link()] = true, _b), className) }));
8
+ var className = _a.className, component = _a.component, rest = __rest(_a, ["className", "component"]);
9
+ return (React.createElement(ClickableElement, __assign({}, rest, { ref: ref, element: component !== null && component !== void 0 ? component : 'a', className: cx((_b = {}, _b[jsStyles.link()] = true, _b), className) })));
10
10
  });
11
11
  SideMenuLinkInner.displayName = 'SideMenuLink';
12
12
  /**
@@ -1,6 +1,6 @@
1
1
  import React, { forwardRef, useContext } from 'react';
2
2
  import { SideMenuDataTids } from '../../SideMenuDataTids';
3
- import { ArrowALeftIcon20Regular } from '@skbkontur/icons';
3
+ import { ArrowALeftIcon20Regular } from '@skbkontur/icons/icons/ArrowALeftIcon/ArrowALeftIcon20Regular';
4
4
  import { SideMenuItem } from '../SideMenuItem/SideMenuItem';
5
5
  import { SideMenuContext } from '../SideMenuContext';
6
6
  /**
@@ -1,7 +1,7 @@
1
1
  import React, { useContext } from 'react';
2
2
  import { jsStyles } from './Burger.styles';
3
3
  import { SideMenuContext } from '../SideMenuContext';
4
- import { UiMenuBars3HIcon24Regular } from '@skbkontur/icons';
4
+ import { UiMenuBars3HIcon24Regular } from '@skbkontur/icons/icons/UiMenuBars3HIcon/UiMenuBars3HIcon24Regular';
5
5
  import { SideMenuDataTids } from '../../SideMenuDataTids';
6
6
  import { getSideMenuTheme } from '../../lib/theming/ThemeHelpers';
7
7
  import { ThemeContext } from '@skbkontur/react-ui';
@@ -3,7 +3,7 @@ import { CommonProps } from '@skbkontur/react-ui/internal/CommonWrapper';
3
3
  export interface CommonClickableElementProps extends CommonProps {
4
4
  children?: React.ReactNode;
5
5
  icon: React.ReactElement;
6
- marker?: string;
6
+ marker?: string | true;
7
7
  caption?: string;
8
8
  subCaption?: ReactNode;
9
9
  id?: string;
@@ -21,12 +21,12 @@ export interface CommonClickableElementProps extends CommonProps {
21
21
  _isBackButton?: boolean;
22
22
  }
23
23
  export interface ClickableElementProps extends CommonClickableElementProps {
24
- element: 'a' | 'button';
24
+ element: 'a' | 'button' | React.ComponentType<any>;
25
25
  href?: string;
26
- onClick?: React.EventHandler<React.MouseEvent<Element>>;
27
- onKeyDown?: React.EventHandler<React.KeyboardEvent<Element>>;
28
- onFocus?: React.EventHandler<React.FocusEvent<Element>>;
29
- onBlur?: React.EventHandler<React.FocusEvent<Element>>;
26
+ onClick?: React.EventHandler<React.MouseEvent>;
27
+ onKeyDown?: React.EventHandler<React.KeyboardEvent>;
28
+ onFocus?: React.EventHandler<React.FocusEvent>;
29
+ onBlur?: React.EventHandler<React.FocusEvent>;
30
30
  }
31
31
  declare const ClickableElementWithStaticFields: React.ForwardRefExoticComponent<ClickableElementProps & React.RefAttributes<HTMLButtonElement | HTMLAnchorElement>> & {
32
32
  __KONTUR_REACT_UI__: string;
@@ -25,7 +25,7 @@ var ClickableElement = forwardRef(function (_a, ref) {
25
25
  var isOpened = useOpenedState(id || rest.href, _generatedId, context.openedParents, isActive, children, context.isSeparatedMenuShown, context.isMobile && context.isSeparatedMenu);
26
26
  var hasChildren = function (id, generatedId) {
27
27
  var _a, _b;
28
- var parentId = id ? 'id' : 'generatedParentId';
28
+ var parentId = id ? 'parentId' : 'generatedParentId';
29
29
  var childId = id !== null && id !== void 0 ? id : generatedId;
30
30
  return (_b = (_a = context.flattedArrayOfAllElements) === null || _a === void 0 ? void 0 : _a.filter(function (el) { return el[parentId] === childId; })) === null || _b === void 0 ? void 0 : _b.length;
31
31
  };
@@ -5,7 +5,7 @@ export var sideMenuMultilineCaptionPaddingTop = '4px';
5
5
  export var sideMenuCaptionMarginRight = '8px';
6
6
  var styles = {
7
7
  root: function () {
8
- return css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n max-width: 100%;\n "], ["\n display: flex;\n flex-direction: column;\n max-width: 100%;\n "])));
8
+ return css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n "], ["\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n "])));
9
9
  },
10
10
  rootBeingTransitioned: function () {
11
11
  return css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n white-space: nowrap;\n overflow-x: hidden;\n text-overflow: ellipsis;\n "], ["\n white-space: nowrap;\n overflow-x: hidden;\n text-overflow: ellipsis;\n "])));
@@ -74,7 +74,7 @@ var ItemContent = forwardRef(function (_a, ref) {
74
74
  _c[customStyles.textAndMarkerWrapperMultiline(getItemContentHeight(theme, linesNumber, size))] = isMultiline && !_isSubMenu,
75
75
  _c)) },
76
76
  React.createElement(Caption, { _isSubMenu: _isSubMenu, _isNestedSubMenu: _isNestedSubMenu, hasIcon: !!icon, isMultiline: isMultiline, caption: caption, subCaption: subCaption, _isBackButton: _isBackButton, _isDropdown: _isDropdown, _isAvatar: _isAvatar, ref: textRef }),
77
- marker && (!context.isMinimized || isSeparatedSubMenuInNarrowDesktop) && (React.createElement(Marker, { isMultiline: isMultiline, marker: marker, _isSubMenu: _isSubMenu }))))));
77
+ marker !== undefined && (!context.isMinimized || isSeparatedSubMenuInNarrowDesktop) && (React.createElement(Marker, { isMultiline: isMultiline, marker: marker, _isSubMenu: _isSubMenu }))))));
78
78
  });
79
79
  ItemContent.displayName = 'ItemContent';
80
80
  var ItemContentWithStaticFields = Object.assign(ItemContent, { __KONTUR_REACT_UI__: 'ItemContent' });
@@ -7,9 +7,12 @@ export var Marker = function (_a) {
7
7
  var _b;
8
8
  var isMultiline = _a.isMultiline, marker = _a.marker, _isSubMenu = _a._isSubMenu;
9
9
  var theme = getSideMenuTheme(useContext(ThemeContext));
10
+ var emptyMarker = marker === true || marker === '';
10
11
  return (React.createElement("span", { className: cx((_b = {},
11
12
  _b[jsStyles.root(theme)] = true,
13
+ _b[jsStyles.rootEmpty(theme)] = emptyMarker,
12
14
  _b[jsStyles.rootMultiline(theme)] = isMultiline,
13
15
  _b[jsStyles.rootSubMenu(theme)] = _isSubMenu,
16
+ _b[jsStyles.rootSubMenuEmpty(theme)] = _isSubMenu && emptyMarker,
14
17
  _b)) }, marker));
15
18
  };
@@ -1,6 +1,8 @@
1
1
  import { SideMenuTheme } from '../../../lib/theming/ThemeTypes';
2
2
  export declare const jsStyles: {
3
3
  root(t: SideMenuTheme): string;
4
+ rootEmpty(t: SideMenuTheme): string;
4
5
  rootMultiline(t: SideMenuTheme): string;
5
6
  rootSubMenu(t: SideMenuTheme): string;
7
+ rootSubMenuEmpty(t: SideMenuTheme): string;
6
8
  };
@@ -3,14 +3,20 @@ import { css } from '@skbkontur/react-ui/lib/theming/Emotion';
3
3
  import { memoizeStyle } from '../../../lib/theming/ThemeHelpers';
4
4
  var styles = {
5
5
  root: function (t) {
6
- return css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n padding: ", " ", ";\n background: ", ";\n border-radius: 9999px;\n margin-left: auto;\n margin-right: ", ";\n color: ", ";\n font-size: 14px;\n line-height: ", ";\n font-weight: ", ";\n min-width: 8px;\n text-align: center;\n flex-shrink: 0;\n "], ["\n padding: ", " ", ";\n background: ", ";\n border-radius: 9999px;\n margin-left: auto;\n margin-right: ", ";\n color: ", ";\n font-size: 14px;\n line-height: ", ";\n font-weight: ", ";\n min-width: 8px;\n text-align: center;\n flex-shrink: 0;\n "])), t.sideMenuMarkerPaddingY, t.sideMenuMarkerPaddingX, t.sideMenuMarkerBg, t.sideMenuMarkerMarginRight, t.sideMenuMarkerColor, t.sideMenuMarkerLineHeight, t.sideMenuMarkerFontWeight);
6
+ return css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n padding: ", " ", ";\n background: ", ";\n border-radius: 9999px;\n margin-left: auto;\n margin-right: ", ";\n color: ", ";\n font-size: 14px;\n line-height: ", ";\n font-weight: ", ";\n min-width: 8px;\n min-height: 8px;\n text-align: center;\n flex-shrink: 0;\n "], ["\n padding: ", " ", ";\n background: ", ";\n border-radius: 9999px;\n margin-left: auto;\n margin-right: ", ";\n color: ", ";\n font-size: 14px;\n line-height: ", ";\n font-weight: ", ";\n min-width: 8px;\n min-height: 8px;\n text-align: center;\n flex-shrink: 0;\n "])), t.sideMenuMarkerPaddingY, t.sideMenuMarkerPaddingX, t.sideMenuMarkerBg, t.sideMenuMarkerMarginRight, t.sideMenuMarkerColor, t.sideMenuMarkerLineHeight, t.sideMenuMarkerFontWeight);
7
+ },
8
+ rootEmpty: function (t) {
9
+ return css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n padding: 0;\n margin-right: calc(", " + ", ");\n "], ["\n padding: 0;\n margin-right: calc(", " + ", ");\n "])), t.sideMenuMarkerMarginRight, t.sideMenuMarkerPaddingX);
7
10
  },
8
11
  rootMultiline: function (t) {
9
- return css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n align-self: flex-start;\n margin-top: ", ";\n "], ["\n align-self: flex-start;\n margin-top: ", ";\n "])), t.sideMenuMarkerMultilineMarginTop);
12
+ return css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n align-self: flex-start;\n margin-top: ", ";\n "], ["\n align-self: flex-start;\n margin-top: ", ";\n "])), t.sideMenuMarkerMultilineMarginTop);
10
13
  },
11
14
  rootSubMenu: function (t) {
12
- return css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n background: transparent;\n color: ", ";\n font-weight: ", ";\n "], ["\n background: transparent;\n color: ", ";\n font-weight: ", ";\n "])), t.sideMenuMarkerSubItemColor, t.sideMenuSubItemMarkerFontWeight);
15
+ return css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n background: transparent;\n color: ", ";\n font-weight: ", ";\n "], ["\n background: transparent;\n color: ", ";\n font-weight: ", ";\n "])), t.sideMenuMarkerSubItemColor, t.sideMenuSubItemMarkerFontWeight);
16
+ },
17
+ rootSubMenuEmpty: function (t) {
18
+ return css(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n background: ", ";\n "], ["\n background: ", ";\n "])), t.sideMenuSubItemEmptyMarkerBg);
13
19
  },
14
20
  };
15
21
  export var jsStyles = memoizeStyle(styles);
16
- var templateObject_1, templateObject_2, templateObject_3;
22
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5;