@cloud-ru/ds-uikit-product-header 1.1.1 → 1.1.2-preview-d405de03.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/README.md +70 -4
- package/dist/cjs/components/MainMenu/helperComponents/Content/Content.js +7 -8
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/ContentToolbar/styles.module.css +1 -0
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.d.ts +3 -3
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.js +2 -2
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +3 -3
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +8 -2
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +1 -0
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.d.ts +1 -1
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +10 -7
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/styles.module.css +13 -3
- package/dist/cjs/components/MainMenu/types.d.ts +14 -9
- package/dist/cjs/components/MainMenu/utils/getLinkEmblem.d.ts +1 -1
- package/dist/cjs/components/MainMenu/utils/getLinkEmblem.js +1 -9
- package/dist/cjs/components/MainMenu/utils/index.d.ts +0 -1
- package/dist/cjs/components/MainMenu/utils/index.js +0 -1
- package/dist/cjs/components/PathBreadcrumbs/styles.module.css +3 -0
- package/dist/cjs/constants.d.ts +2 -0
- package/dist/cjs/constants.js +2 -0
- package/dist/cjs/style.css +18 -3
- package/dist/esm/components/MainMenu/helperComponents/Content/Content.js +7 -8
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/ContentToolbar/styles.module.css +1 -0
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.d.ts +3 -3
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.js +2 -2
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +3 -3
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +8 -2
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +1 -0
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.d.ts +1 -1
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +6 -3
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/styles.module.css +13 -3
- package/dist/esm/components/MainMenu/types.d.ts +14 -9
- package/dist/esm/components/MainMenu/utils/getLinkEmblem.d.ts +1 -1
- package/dist/esm/components/MainMenu/utils/getLinkEmblem.js +1 -9
- package/dist/esm/components/MainMenu/utils/index.d.ts +0 -1
- package/dist/esm/components/MainMenu/utils/index.js +0 -1
- package/dist/esm/components/PathBreadcrumbs/styles.module.css +3 -0
- package/dist/esm/constants.d.ts +2 -0
- package/dist/esm/constants.js +2 -0
- package/dist/esm/style.css +18 -3
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +26 -26
- package/src/components/MainMenu/helperComponents/Content/Content.tsx +8 -12
- package/src/components/MainMenu/helperComponents/Content/helperComponents/ContentToolbar/styles.module.scss +1 -0
- package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.tsx +11 -8
- package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.tsx +28 -4
- package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.scss +14 -7
- package/src/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.tsx +26 -4
- package/src/components/MainMenu/helperComponents/MenuDesktop/styles.module.scss +13 -3
- package/src/components/MainMenu/types.ts +15 -9
- package/src/components/MainMenu/utils/getLinkEmblem.tsx +3 -18
- package/src/components/MainMenu/utils/index.ts +0 -1
- package/src/components/PathBreadcrumbs/styles.module.scss +4 -0
- package/src/constants.ts +2 -0
- package/dist/cjs/components/MainMenu/utils/getAvatarNameFromLabel.d.ts +0 -14
- package/dist/cjs/components/MainMenu/utils/getAvatarNameFromLabel.js +0 -24
- package/dist/esm/components/MainMenu/utils/getAvatarNameFromLabel.d.ts +0 -14
- package/dist/esm/components/MainMenu/utils/getAvatarNameFromLabel.js +0 -21
- package/src/components/MainMenu/utils/getAvatarNameFromLabel.ts +0 -24
|
@@ -19,8 +19,7 @@ export function Content({ searchValue, search, rightTop, segments, searchGroups
|
|
|
19
19
|
const { t } = headerLocale.useTranslations();
|
|
20
20
|
const showDescription = useDeferredValue(preferences?.showDescription.value ?? false);
|
|
21
21
|
const segmentPrefsById = useMemo(() => new Map((segmentPrefs ?? []).map(prefs => [prefs.id, prefs])), [segmentPrefs]);
|
|
22
|
-
const
|
|
23
|
-
const defaultSegmentId = visibleSegments[0]?.id ?? segments[0]?.id ?? '';
|
|
22
|
+
const defaultSegmentId = activeSegmentId ?? segments[0]?.id ?? '';
|
|
24
23
|
const [segmentId = defaultSegmentId, setSegmentId] = useValueControl({
|
|
25
24
|
value: activeSegmentId,
|
|
26
25
|
defaultValue: defaultSegmentId,
|
|
@@ -29,10 +28,10 @@ export function Content({ searchValue, search, rightTop, segments, searchGroups
|
|
|
29
28
|
const isSearching = Boolean(searchValue);
|
|
30
29
|
const enableServiceDrag = Boolean(favorite) && !isMobile && !isSearching;
|
|
31
30
|
useEffect(() => {
|
|
32
|
-
if (!
|
|
31
|
+
if (!segments.some(segment => segment.id === segmentId) && defaultSegmentId) {
|
|
33
32
|
setSegmentId(defaultSegmentId);
|
|
34
33
|
}
|
|
35
|
-
}, [defaultSegmentId, segmentId, setSegmentId,
|
|
34
|
+
}, [defaultSegmentId, segmentId, setSegmentId, segments]);
|
|
36
35
|
const handleLinkClick = useCallback(({ disabled, onClick }, e) => {
|
|
37
36
|
if (disabled) {
|
|
38
37
|
e?.preventDefault();
|
|
@@ -73,23 +72,23 @@ export function Content({ searchValue, search, rightTop, segments, searchGroups
|
|
|
73
72
|
}
|
|
74
73
|
onExpandedChange([...new Set([...expandedIds, ...visibleIds])]);
|
|
75
74
|
}, [allGroupsExpanded, expandedIds, onExpandedChange, visibleGroups]);
|
|
76
|
-
const segmentItems = useMemo(() =>
|
|
75
|
+
const segmentItems = useMemo(() => segments.map(segment => ({
|
|
77
76
|
value: segment.id,
|
|
78
77
|
label: segment.label,
|
|
79
78
|
icon: segment.icon,
|
|
80
|
-
})), [
|
|
79
|
+
})), [segments]);
|
|
81
80
|
const hasCards = visibleGroups.length > 0;
|
|
82
81
|
const cards = (() => {
|
|
83
82
|
if (loading) {
|
|
84
83
|
return Array.from({ length: 5 }).map((_, index) => _jsx(SortableGroupSkeleton, { isMobile: isMobile }, index));
|
|
85
84
|
}
|
|
86
85
|
if (hasCards) {
|
|
87
|
-
return (_jsx(SortableContext, { items: visibleGroups.map(({ id }) => id), strategy: verticalListSortingStrategy, children: _jsx(Accordion, { selectionMode: 'multiple', expanded: expandedIds, onExpandedChange: onExpandedChange, children: visibleGroups.map(({ id, label, items, favoritesEnabled = true, blockColor, highlight }) => (_jsx(SortableGroup, { id: id, label: label, items: items, isExpanded: expandedIds.includes(id), blockColor: resolveGroupBlockColor(blockColor, preferences?.showGroupsColors?.value), showDescription: showDescription, isMobile: isMobile, enableServiceDrag: enableServiceDrag, favorite: favoritesEnabled ? favorite : undefined, onServiceClick: handleLinkClick, highlight: highlight }, id))) }) }));
|
|
86
|
+
return (_jsx(SortableContext, { items: visibleGroups.map(({ id }) => id), strategy: verticalListSortingStrategy, children: _jsx(Accordion, { selectionMode: 'multiple', expanded: expandedIds, onExpandedChange: onExpandedChange, children: visibleGroups.map(({ id, label, icon, items, favoritesEnabled = true, blockColor, highlight }) => (_jsx(SortableGroup, { id: id, icon: icon, label: label, items: items, isExpanded: expandedIds.includes(id), blockColor: resolveGroupBlockColor(blockColor, preferences?.showGroupsColors?.value), showDescription: showDescription, isMobile: isMobile, enableServiceDrag: enableServiceDrag, favorite: favoritesEnabled ? favorite : undefined, onServiceClick: handleLinkClick, highlight: highlight }, id))) }) }));
|
|
88
87
|
}
|
|
89
88
|
return (_jsx(InfoBlock, { size: 'm', icon: {
|
|
90
89
|
icon: SearchSVG,
|
|
91
90
|
appearance: 'neutral',
|
|
92
91
|
}, content: isSearching ? t('noDataFound') : t('noData'), "data-test-id": isSearching ? TEST_IDS.noDataFound : TEST_IDS.noData }));
|
|
93
92
|
})();
|
|
94
|
-
return (_jsxs(_Fragment, { children: [search, _jsxs("div", { className: cn(styles.content, className), "data-mobile": isMobile || undefined, "data-empty": !hasCards || undefined, children: [!isSearching && (_jsxs(_Fragment, { children: [isMobile && rightTop, _jsx(ContentToolbar, { segment: segmentId, onSegmentChange: setSegmentId, segmentItems: segmentItems, allGroupsExpanded: allGroupsExpanded, onToggleAllGroupsExpanded: handleToggleAllGroupsExpanded, preferences: preferences, isMobile: isMobile }), !isMobile && rightTop] })), cards, footer] })] }));
|
|
93
|
+
return (_jsxs(_Fragment, { children: [search, _jsxs("div", { className: cn(styles.content, className), "data-mobile": isMobile || undefined, "data-empty": (!loading && !hasCards) || undefined, children: [!isSearching && (_jsxs(_Fragment, { children: [isMobile && rightTop, _jsx(ContentToolbar, { segment: segmentId, onSegmentChange: setSegmentId, segmentItems: segmentItems, allGroupsExpanded: allGroupsExpanded, onToggleAllGroupsExpanded: handleToggleAllGroupsExpanded, preferences: preferences, isMobile: isMobile }), !isMobile && rightTop] })), cards, footer] })] }));
|
|
95
94
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { LinksGroupBlockColor, LinksGroupTitle } from '../../../../types.js';
|
|
1
|
+
import { LinksGroup, LinksGroupBlockColor, LinksGroupTitle } from '../../../../types.js';
|
|
2
2
|
import { SortableGroupCardsProps } from './components/index.js';
|
|
3
|
-
export type SortableGroupProps = Omit<SortableGroupCardsProps, 'groupId'> & {
|
|
3
|
+
export type SortableGroupProps = Omit<SortableGroupCardsProps, 'groupId'> & Pick<LinksGroup, 'icon'> & {
|
|
4
4
|
id: string;
|
|
5
5
|
label: LinksGroupTitle;
|
|
6
6
|
isExpanded?: boolean;
|
|
7
7
|
blockColor?: LinksGroupBlockColor;
|
|
8
8
|
highlight?: boolean;
|
|
9
9
|
};
|
|
10
|
-
export declare function SortableGroup({ id, label, items, isExpanded, showDescription, isMobile, enableServiceDrag, favorite, onServiceClick, blockColor, highlight, }: SortableGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function SortableGroup({ id, icon, label, items, isExpanded, showDescription, isMobile, enableServiceDrag, favorite, onServiceClick, blockColor, highlight, }: SortableGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
11
11
|
export declare function SortableGroupDragPreview({ id, label, items, isExpanded, showDescription, isMobile, favorite, blockColor, highlight, }: Omit<SortableGroupProps, 'enableServiceDrag'>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -7,7 +7,7 @@ import { useThemeAppearance } from '@cloud-ru/ds-theme';
|
|
|
7
7
|
import { TEST_IDS } from '../../constants.js';
|
|
8
8
|
import { SortableGroupCards, SortableGroupHeader } from './components/index.js';
|
|
9
9
|
import styles from './styles.module.css';
|
|
10
|
-
export function SortableGroup({ id, label, items, isExpanded, showDescription, isMobile, enableServiceDrag, favorite, onServiceClick, blockColor, highlight, }) {
|
|
10
|
+
export function SortableGroup({ id, icon, label, items, isExpanded, showDescription, isMobile, enableServiceDrag, favorite, onServiceClick, blockColor, highlight, }) {
|
|
11
11
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
12
12
|
id,
|
|
13
13
|
disabled: !enableServiceDrag,
|
|
@@ -21,7 +21,7 @@ export function SortableGroup({ id, label, items, isExpanded, showDescription, i
|
|
|
21
21
|
transition,
|
|
22
22
|
};
|
|
23
23
|
const { colorScheme } = useThemeAppearance().appearance;
|
|
24
|
-
return (_jsxs(DragGhost, { innerRef: setNodeRef, id: id, style: style, className: styles.group, dragging: isDragging, mode: DRAG_MODE.Dynamic, "data-test-id": `${TEST_IDS.groupCard}-${id}`, children: [_jsx("div", { className: styles.decoration, "data-color-scheme": colorScheme, "data-is-highlighted": highlight || undefined, children: _jsx("div", { className: styles.decorationBackground, children: _jsx("div", { className: styles.colorMarker, "data-block-color": blockColor }) }) }), _jsx(Accordion.CollapseBlockTertiary, { id: id, showChevron: false, afterTitle: _jsx(SortableGroupHeader, { label: label, isExpanded: isExpanded, enableServiceDrag: enableServiceDrag, attributes: attributes, listeners: listeners, isMobile: isMobile }), children: _jsx(SortableGroupCards, { groupId: id, items: items, showDescription: showDescription, isMobile: isMobile, enableServiceDrag: enableServiceDrag, favorite: favorite, onServiceClick: onServiceClick }) })] }));
|
|
24
|
+
return (_jsxs(DragGhost, { innerRef: setNodeRef, id: id, style: style, className: styles.group, dragging: isDragging, mode: DRAG_MODE.Dynamic, "data-test-id": `${TEST_IDS.groupCard}-${id}`, children: [_jsx("div", { className: styles.decoration, "data-color-scheme": colorScheme, "data-is-highlighted": highlight || undefined, children: _jsx("div", { className: styles.decorationBackground, children: _jsx("div", { className: styles.colorMarker, "data-block-color": blockColor }) }) }), _jsx(Accordion.CollapseBlockTertiary, { id: id, showChevron: false, afterTitle: _jsx(SortableGroupHeader, { label: label, icon: icon, isExpanded: isExpanded, enableServiceDrag: enableServiceDrag, attributes: attributes, listeners: listeners, isMobile: isMobile }), children: _jsx(SortableGroupCards, { groupId: id, items: items, showDescription: showDescription, isMobile: isMobile, enableServiceDrag: enableServiceDrag, favorite: favorite, onServiceClick: onServiceClick }) })] }));
|
|
25
25
|
}
|
|
26
26
|
export function SortableGroupDragPreview({ id, label, items, isExpanded, showDescription, isMobile, favorite, blockColor, highlight, }) {
|
|
27
27
|
const { colorScheme } = useThemeAppearance().appearance;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { LinksGroupTitle } from '../../../../../types.js';
|
|
1
|
+
import { LinksGroup, LinksGroupTitle } from '../../../../../types.js';
|
|
2
2
|
import { SortableGroupDragHandleProps } from './SortableGroupDragHandle.js';
|
|
3
|
-
export type SortableGroupHeaderProps = {
|
|
3
|
+
export type SortableGroupHeaderProps = Pick<LinksGroup, 'icon'> & {
|
|
4
4
|
label: LinksGroupTitle;
|
|
5
5
|
isExpanded?: boolean;
|
|
6
6
|
enableServiceDrag?: boolean;
|
|
7
7
|
isMobile?: boolean;
|
|
8
8
|
} & SortableGroupDragHandleProps;
|
|
9
|
-
export declare function SortableGroupHeader({ label, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }: SortableGroupHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function SortableGroupHeader({ label, icon, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }: SortableGroupHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -2,8 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Button } from '@cloud-ru/ds-button';
|
|
3
3
|
import { ChevronDownSVG, ChevronUpSVG } from '@cloud-ru/ds-icons/interface/system';
|
|
4
4
|
import { Typography } from '@cloud-ru/ds-typography';
|
|
5
|
+
import { TitleClickable } from '@cloud-ru/ds-uikit-product-title-clickable';
|
|
6
|
+
import { getLinkEmblem } from '../../../../../utils/index.js';
|
|
5
7
|
import styles from '../styles.module.css';
|
|
6
8
|
import { SortableGroupDragHandle } from './SortableGroupDragHandle.js';
|
|
7
|
-
export function SortableGroupHeader({ label, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }) {
|
|
8
|
-
|
|
9
|
+
export function SortableGroupHeader({ label, icon, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }) {
|
|
10
|
+
const handleLabelClick = e => {
|
|
11
|
+
e.stopPropagation();
|
|
12
|
+
label?.onClick?.(e);
|
|
13
|
+
};
|
|
14
|
+
return (_jsxs("div", { className: styles.header, "data-expanded": isExpanded || undefined, children: [_jsx(Typography, { variant: 'title', size: 'm', className: styles.headerTitle, "data-test-id": 'header__drawer-menu__group-card-title', children: label.onClick || label.href ? (_jsx(TitleClickable, { ...(label.href ? { as: 'a', href: label.href } : { as: 'div' }), onClick: handleLabelClick, title: label.text, before: getLinkEmblem({ icon }) })) : (label.text) }), (enableServiceDrag || !isMobile) && (_jsxs("div", { className: styles.headerActions, "data-always-visible": isMobile || undefined, children: [enableServiceDrag && _jsx(SortableGroupDragHandle, { attributes: attributes, listeners: listeners }), !isMobile && (_jsx(Button, { view: 'elevated', appearance: 'neutral', size: 's', icon: isExpanded ? _jsx(ChevronUpSVG, {}) : _jsx(ChevronDownSVG, {}), "data-test-id": 'header__drawer-menu__group-card-collapse' }))] }))] }));
|
|
9
15
|
}
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
overflow-x:clip;
|
|
51
51
|
display:flex;
|
|
52
52
|
flex-direction:column;
|
|
53
|
+
width:100%;
|
|
53
54
|
min-width:0;
|
|
54
55
|
padding:var(--sn-primitive-dimension-4, 4px) var(--sn-primitive-dimension-8, 8px) var(--sn-primitive-dimension-8, 8px) var(--sn-primitive-dimension-12, 12px);
|
|
55
56
|
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { MainMenuProps } from '../../types.js';
|
|
2
|
-
export declare function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platformGroups, segments, segmentPrefs, activeSegmentId, onActiveSegmentChange, onSegmentOrderChange, onSegmentExpandedChange, favorite, search, preferences, logo, rightTop, leftTop, defaultWidth, onWidthChangeEnd, draggerTooltip, loading, }: MainMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platformGroups, segments, segmentPrefs, activeSegmentId, onActiveSegmentChange, onSegmentOrderChange, onSegmentExpandedChange, favorite, search, preferences, logo, rightTop, leftTop, leftBottom, defaultWidth, onWidthChangeEnd, draggerTooltip, loading, }: MainMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import { createElement as _createElement } from "react";
|
|
1
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { Divider } from '@cloud-ru/ds-divider';
|
|
3
4
|
import { DrawerCustom } from '@cloud-ru/ds-drawer';
|
|
4
|
-
import { List } from '@cloud-ru/ds-list';
|
|
5
5
|
import { Scroll } from '@cloud-ru/ds-scroll';
|
|
6
|
+
import { CardServiceLight } from '@cloud-ru/ds-uikit-product-card-predefined';
|
|
6
7
|
import { useValueControl } from '@cloud-ru/ds-utils';
|
|
7
8
|
import { useCallback, useEffect, useMemo } from 'react';
|
|
8
9
|
import { TEST_IDS } from '../../../../constants.js';
|
|
9
10
|
import { MainMenuDndContext, useMainMenuDnd } from '../../hooks/useMainMenuDnd.js';
|
|
10
11
|
import { useMenuItems } from '../../hooks/useMenuItems.js';
|
|
12
|
+
import { getLinkEmblem } from '../../utils/index.js';
|
|
11
13
|
import { Content } from '../Content/index.js';
|
|
12
14
|
import { Favorites } from '../Favorites/index.js';
|
|
13
15
|
import { MenuHeaderBrand } from '../MenuHeaderBrand/index.js';
|
|
@@ -15,7 +17,7 @@ import { MountAnimation } from '../MountAnimation/index.js';
|
|
|
15
17
|
import { Search } from '../Search/index.js';
|
|
16
18
|
import { MENU_WIDTH_MAX, MENU_WIDTH_MIN } from './constants.js';
|
|
17
19
|
import styles from './styles.module.css';
|
|
18
|
-
export function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platformGroups, segments, segmentPrefs, activeSegmentId, onActiveSegmentChange, onSegmentOrderChange, onSegmentExpandedChange, favorite, search, preferences, logo, rightTop, leftTop, defaultWidth = MENU_WIDTH_MAX, onWidthChangeEnd, draggerTooltip, loading, }) {
|
|
20
|
+
export function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platformGroups, segments, segmentPrefs, activeSegmentId, onActiveSegmentChange, onSegmentOrderChange, onSegmentExpandedChange, favorite, search, preferences, logo, rightTop, leftTop, leftBottom, defaultWidth = MENU_WIDTH_MAX, onWidthChangeEnd, draggerTooltip, loading, }) {
|
|
19
21
|
const [open = false, setOpen] = useValueControl({ value: openProp, onChange: setOpenProp });
|
|
20
22
|
const { scrollRef, searchRef, resultItems } = useMenuItems({
|
|
21
23
|
segments,
|
|
@@ -35,6 +37,7 @@ export function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems
|
|
|
35
37
|
return () => cancelAnimationFrame(frameId);
|
|
36
38
|
}, [open, hasSearch, searchRef]);
|
|
37
39
|
const isNeedRightBlock = segments && segments.some(segment => segment.items.length > 0);
|
|
40
|
+
const hasBottomItems = Boolean(settingItems?.length) || Boolean(leftBottom);
|
|
38
41
|
const allServiceGroups = useMemo(() => segments?.flatMap(segment => segment.items) ?? [], [segments]);
|
|
39
42
|
const mainMenuDnd = useMainMenuDnd({
|
|
40
43
|
favorite,
|
|
@@ -44,7 +47,7 @@ export function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems
|
|
|
44
47
|
const handleCloseDrawer = useCallback(() => {
|
|
45
48
|
setOpen(false);
|
|
46
49
|
}, [setOpen]);
|
|
47
|
-
const menu = (_jsxs("div", { className: styles.menu, children: [_jsxs("div", { className: styles.menuHeader, children: [_jsx(MenuHeaderBrand, { logo: logo, onClose: handleCloseDrawer, className: styles.menuHeaderBrand }), isNeedRightBlock && search && (_jsxs(_Fragment, { children: [_jsx(Divider, { orientation: 'vertical' }), _jsx(Search, { ...search, ref: searchRef })] }))] }), _jsx(Divider, {}), _jsxs("div", { className: styles.menuBody, children: [_jsxs(MountAnimation, { className: styles.left, "data-test-id": TEST_IDS.mainMenu.left, type: 'slide-right', children: [leftTop && _jsx("div", { className: styles.leftTop, children: leftTop }), isNeedRightBlock && favorite && _jsx(Favorites, { favorite: favorite, allServiceGroups: allServiceGroups }),
|
|
50
|
+
const menu = (_jsxs("div", { className: styles.menu, children: [_jsxs("div", { className: styles.menuHeader, children: [_jsx(MenuHeaderBrand, { logo: logo, onClose: handleCloseDrawer, className: styles.menuHeaderBrand }), isNeedRightBlock && search && (_jsxs(_Fragment, { children: [_jsx(Divider, { orientation: 'vertical' }), _jsx(Search, { ...search, ref: searchRef })] }))] }), _jsx(Divider, {}), _jsxs("div", { className: styles.menuBody, children: [_jsxs(MountAnimation, { className: styles.left, "data-test-id": TEST_IDS.mainMenu.left, type: 'slide-right', children: [leftTop && _jsx("div", { className: styles.leftTop, children: leftTop }), isNeedRightBlock && favorite && _jsx(Favorites, { favorite: favorite, allServiceGroups: allServiceGroups }), hasBottomItems ? (_jsxs("div", { className: styles.leftBottom, "data-test-id": TEST_IDS.mainMenu.leftBottom, children: [_jsx("div", { className: styles.leftBottomItems, "data-test-id": TEST_IDS.mainMenu.leftBottomItems, children: settingItems?.map(item => (_jsxs(_Fragment, { children: [item.dividerBefore && _jsx(Divider, { orientation: 'horizontal', className: styles.leftBottomDivider }), _createElement(CardServiceLight, { ...(item.href ? { href: item.href, as: 'a' } : { as: 'button', type: 'button' }), key: item.id, title: item.label, icon: getLinkEmblem(item), onClick: item.onClick, "data-test-id": `header__drawer-menu__setting-${item.id}` })] }))) }), leftBottom] })) : null] }), isNeedRightBlock && (_jsxs(_Fragment, { children: [_jsx(MountAnimation, { type: 'fade-in', children: _jsx(Divider, { orientation: 'vertical' }) }), _jsx(MountAnimation, { type: 'fade-slide-up-right', className: styles.right, "data-test-id": TEST_IDS.mainMenu.right, children: _jsx(Scroll, { paddingAbsolute: true, className: styles.scroll, ref: scrollRef, barHideStrategy: 'never', overflow: { x: 'hidden' }, children: _jsx(Content, { onClose: handleCloseDrawer, className: styles.rightContent, searchValue: search?.value, rightTop: rightTop, favorite: favorite, segments: segments, searchGroups: resultItems, segmentPrefs: segmentPrefs, activeSegmentId: activeSegmentId, onActiveSegmentChange: onActiveSegmentChange, onSegmentOrderChange: onSegmentOrderChange, onSegmentExpandedChange: onSegmentExpandedChange, preferences: preferences, loading: loading }) }) })] }))] })] }));
|
|
48
51
|
return (_jsx(DrawerCustom, { open: open, onClose: handleCloseDrawer, width: isNeedRightBlock ? 'm' : 's', position: 'left', className: styles.drawer, rootClassName: styles.drawerRoot, "data-test-id": TEST_IDS.mainMenu.drawer, "data-small": !isNeedRightBlock || undefined, disableMotions: true, showButtonClosed: false, resizable: isNeedRightBlock
|
|
49
52
|
? {
|
|
50
53
|
min: MENU_WIDTH_MIN,
|
|
@@ -43,9 +43,18 @@
|
|
|
43
43
|
min-height:0;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
.
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
.leftBottomItems{
|
|
47
|
+
width:100%;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.leftBottom{
|
|
51
|
+
display:flex;
|
|
52
|
+
flex-direction:column;
|
|
53
|
+
gap:var(--sn-primitive-dimension-8, 8px);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.leftBottomDivider{
|
|
57
|
+
margin:var(--sn-primitive-dimension-2, 2px) 0;
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
.right{
|
|
@@ -63,6 +72,7 @@
|
|
|
63
72
|
display:flex;
|
|
64
73
|
flex-direction:column;
|
|
65
74
|
gap:var(--sn-primitive-dimension-4, 4px);
|
|
75
|
+
width:100%;
|
|
66
76
|
min-width:0;
|
|
67
77
|
padding:var(--sn-primitive-dimension-16, 16px);
|
|
68
78
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseItemProps
|
|
1
|
+
import { BaseItemProps } from '@cloud-ru/ds-list';
|
|
2
2
|
import { SearchProps as SearchPropsSnack } from '@cloud-ru/ds-search';
|
|
3
3
|
import { CardServiceLightProps } from '@cloud-ru/ds-uikit-product-card-predefined';
|
|
4
4
|
import { JSXElementConstructor, MouseEvent, ReactNode } from 'react';
|
|
@@ -19,12 +19,7 @@ export type InnerLink = {
|
|
|
19
19
|
* остаётся только первое по приоритету сегментов (см. {@link MainMenuProps.segments}).
|
|
20
20
|
*/
|
|
21
21
|
id: string;
|
|
22
|
-
/**
|
|
23
|
-
* Иконка карточки.
|
|
24
|
-
*
|
|
25
|
-
* Если не задана, вместо иконки рендерится `Avatar` с двухбуквенным текстом по `label`
|
|
26
|
-
* (см. `getAvatarNameFromLabel`).
|
|
27
|
-
*/
|
|
22
|
+
/** Иконка карточки. */
|
|
28
23
|
icon?: JSXElementConstructor<{
|
|
29
24
|
size?: number;
|
|
30
25
|
className?: string;
|
|
@@ -53,9 +48,11 @@ export type InnerLink = {
|
|
|
53
48
|
type TitleStatic = {
|
|
54
49
|
text: string;
|
|
55
50
|
onClick?: never;
|
|
51
|
+
href?: never;
|
|
56
52
|
};
|
|
57
53
|
type TitleClickable = {
|
|
58
54
|
text: string;
|
|
55
|
+
href?: string;
|
|
59
56
|
onClick?(e?: MouseEvent<HTMLElement>): void;
|
|
60
57
|
};
|
|
61
58
|
export type LinksGroupTitle = TitleStatic | TitleClickable;
|
|
@@ -71,6 +68,10 @@ export type LinksGroup = {
|
|
|
71
68
|
id: string;
|
|
72
69
|
/** Заголовок группы в сетке карточек и в боковой навигации. */
|
|
73
70
|
label: LinksGroupTitle;
|
|
71
|
+
icon?: JSXElementConstructor<{
|
|
72
|
+
size?: number;
|
|
73
|
+
className?: string;
|
|
74
|
+
}>;
|
|
74
75
|
/**
|
|
75
76
|
* Синонимы заголовка группы для fuzzy-поиска.
|
|
76
77
|
*/
|
|
@@ -202,12 +203,16 @@ export type MainMenuPreferencesProps = {
|
|
|
202
203
|
*/
|
|
203
204
|
showGroupsColors?: MainMenuToggleProps;
|
|
204
205
|
};
|
|
206
|
+
export type MainMenuSettingsItem = Pick<InnerLink, 'id' | 'label' | 'icon' | 'onClick' | 'href' | 'hidden'> & {
|
|
207
|
+
dividerBefore?: boolean;
|
|
208
|
+
};
|
|
205
209
|
export type MainMenuProps = {
|
|
206
210
|
disabled?: boolean;
|
|
207
211
|
open?: boolean;
|
|
208
212
|
setOpen?(open: boolean): void;
|
|
209
213
|
logo?: ReactNode;
|
|
210
214
|
leftTop?: ReactNode;
|
|
215
|
+
leftBottom?: ReactNode;
|
|
211
216
|
rightTop?: ReactNode;
|
|
212
217
|
/**
|
|
213
218
|
* Сегменты правой панели (сетка карточек) — только каталог.
|
|
@@ -245,10 +250,10 @@ export type MainMenuProps = {
|
|
|
245
250
|
/**
|
|
246
251
|
* Пункты левой колонки (desktop) / нижней части списка (mobile).
|
|
247
252
|
*
|
|
248
|
-
* Плоский список
|
|
253
|
+
* Плоский список (`dividerBefore` для разделителей).
|
|
249
254
|
* Не связан с сегментами правой панели и не меняется при сортировке групп в сегментах.
|
|
250
255
|
*/
|
|
251
|
-
settingItems?:
|
|
256
|
+
settingItems?: MainMenuSettingsItem[];
|
|
252
257
|
/**
|
|
253
258
|
* Платформенные группы (например «Облачные продукты», «Другие продукты»).
|
|
254
259
|
*
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { CardServiceLightProps } from '@cloud-ru/ds-uikit-product-card-predefined';
|
|
2
2
|
import { InnerLink } from '../types.js';
|
|
3
|
-
export declare function getLinkEmblem(link: InnerLink): CardServiceLightProps['icon'];
|
|
3
|
+
export declare function getLinkEmblem(link: Pick<InnerLink, 'icon'>): CardServiceLightProps['icon'];
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Avatar } from '@cloud-ru/ds-avatar';
|
|
3
1
|
import { createElement } from 'react';
|
|
4
|
-
import { getAvatarNameFromLabel } from './getAvatarNameFromLabel.js';
|
|
5
|
-
function createAvatarIcon(displayName) {
|
|
6
|
-
return function LinkAvatarIcon({ className }) {
|
|
7
|
-
return (_jsx(Avatar, { name: displayName, showTwoSymbols: true, shape: 'squared', appearance: 'neutral', size: 's', className: className }));
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
2
|
export function getLinkEmblem(link) {
|
|
11
3
|
if (!link.icon) {
|
|
12
|
-
return
|
|
4
|
+
return undefined;
|
|
13
5
|
}
|
|
14
6
|
return createElement(link.icon);
|
|
15
7
|
}
|
package/dist/esm/constants.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export declare const TEST_IDS: {
|
|
|
10
10
|
readonly search: "header__drawer-menu__search";
|
|
11
11
|
readonly left: "header__drawer-menu__left";
|
|
12
12
|
readonly right: "header__drawer-menu__right";
|
|
13
|
+
readonly leftBottom: "header__drawer-menu__left-bottom";
|
|
14
|
+
readonly leftBottomItems: "header__drawer-menu__left-bottom-items";
|
|
13
15
|
};
|
|
14
16
|
readonly userMenu: {
|
|
15
17
|
readonly root: "header__user-menu";
|
package/dist/esm/constants.js
CHANGED
|
@@ -10,6 +10,8 @@ export const TEST_IDS = {
|
|
|
10
10
|
search: 'header__drawer-menu__search',
|
|
11
11
|
left: 'header__drawer-menu__left',
|
|
12
12
|
right: 'header__drawer-menu__right',
|
|
13
|
+
leftBottom: 'header__drawer-menu__left-bottom',
|
|
14
|
+
leftBottomItems: 'header__drawer-menu__left-bottom-items',
|
|
13
15
|
},
|
|
14
16
|
userMenu: {
|
|
15
17
|
root: 'header__user-menu',
|
package/dist/esm/style.css
CHANGED
|
@@ -157,6 +157,7 @@
|
|
|
157
157
|
gap:var(--sn-primitive-dimension-8, 8px);
|
|
158
158
|
align-items:center;
|
|
159
159
|
justify-content:space-between;
|
|
160
|
+
width:100%;
|
|
160
161
|
min-width:0;
|
|
161
162
|
min-height:var(--sn-primitive-dimension-32, 32px);
|
|
162
163
|
}
|
|
@@ -297,6 +298,7 @@
|
|
|
297
298
|
overflow-x:clip;
|
|
298
299
|
display:flex;
|
|
299
300
|
flex-direction:column;
|
|
301
|
+
width:100%;
|
|
300
302
|
min-width:0;
|
|
301
303
|
padding:var(--sn-primitive-dimension-4, 4px) var(--sn-primitive-dimension-8, 8px) var(--sn-primitive-dimension-8, 8px) var(--sn-primitive-dimension-12, 12px);
|
|
302
304
|
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
@@ -646,9 +648,18 @@
|
|
|
646
648
|
min-height:0;
|
|
647
649
|
}
|
|
648
650
|
|
|
649
|
-
.
|
|
650
|
-
|
|
651
|
-
|
|
651
|
+
.leftBottomItems{
|
|
652
|
+
width:100%;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.leftBottom{
|
|
656
|
+
display:flex;
|
|
657
|
+
flex-direction:column;
|
|
658
|
+
gap:var(--sn-primitive-dimension-8, 8px);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
.leftBottomDivider{
|
|
662
|
+
margin:var(--sn-primitive-dimension-2, 2px) 0;
|
|
652
663
|
}
|
|
653
664
|
|
|
654
665
|
.right{
|
|
@@ -666,6 +677,7 @@
|
|
|
666
677
|
display:flex;
|
|
667
678
|
flex-direction:column;
|
|
668
679
|
gap:var(--sn-primitive-dimension-4, 4px);
|
|
680
|
+
width:100%;
|
|
669
681
|
min-width:0;
|
|
670
682
|
padding:var(--sn-primitive-dimension-16, 16px);
|
|
671
683
|
}
|
|
@@ -827,7 +839,10 @@
|
|
|
827
839
|
min-width:0;
|
|
828
840
|
}
|
|
829
841
|
.breadcrumbs{
|
|
842
|
+
display:flex;
|
|
843
|
+
align-items:center;
|
|
830
844
|
min-width:0;
|
|
845
|
+
height:100%;
|
|
831
846
|
padding:0 var(--sn-primitive-dimension-8, 8px) !important;
|
|
832
847
|
}
|
|
833
848
|
.container{
|